Merge tag 'csky-for-linus-4.20-fixup-dtb' of https://github.com/c-sky/csky-linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 1 Nov 2018 16:04:30 +0000 (09:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 1 Nov 2018 16:04:30 +0000 (09:04 -0700)
Pull csky dtb fixups from Guo Ren:
 "These fix the csky dtb Kbuild to follow the new Devicetree dtb build
  rules"

* tag 'csky-for-linus-4.20-fixup-dtb' of https://github.com/c-sky/csky-linux:
  csky: use common dtb build rules
  csky: remove builtin-dtb Kbuild

2867 files changed:
.mailmap
Documentation/ABI/testing/sysfs-bus-iio
Documentation/ABI/testing/sysfs-platform-lg-laptop [new file with mode: 0644]
Documentation/admin-guide/mm/memory-hotplug.rst
Documentation/arm/Samsung/Bootloader-interface.txt
Documentation/core-api/boot-time-mm.rst
Documentation/devicetree/bindings/arm/amlogic.txt
Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/fsl.txt
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt [deleted file]
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
Documentation/devicetree/bindings/arm/rockchip.txt
Documentation/devicetree/bindings/arm/scu.txt
Documentation/devicetree/bindings/arm/shmobile.txt
Documentation/devicetree/bindings/arm/syna.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/tegra.txt
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
Documentation/devicetree/bindings/arm/ux500/boards.txt
Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
Documentation/devicetree/bindings/clock/at91-clock.txt
Documentation/devicetree/bindings/clock/hi3670-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/imx6q-clock.txt
Documentation/devicetree/bindings/clock/ingenic,cgu.txt
Documentation/devicetree/bindings/clock/qcom,camcc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Documentation/devicetree/bindings/clock/qcom,hfpll.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,krait-cc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
Documentation/devicetree/bindings/firmware/qcom,scm.txt
Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-designware.txt
Documentation/devicetree/bindings/i2c/i2c-rcar.txt
Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
Documentation/devicetree/bindings/iio/accel/adxl372.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/mcp3911.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt
Documentation/devicetree/bindings/iio/dac/ad5758.txt
Documentation/devicetree/bindings/iio/dac/ltc1660.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
Documentation/devicetree/bindings/iio/light/bh1750.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/light/tsl2772.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt
Documentation/devicetree/bindings/media/cedrus.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/fsl-pxp.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/adv748x.txt
Documentation/devicetree/bindings/media/i2c/adv7604.txt
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt [deleted file]
Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
Documentation/devicetree/bindings/media/rcar_vin.txt
Documentation/devicetree/bindings/media/renesas,ceu.txt
Documentation/devicetree/bindings/media/rockchip-vpu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/video-interfaces.txt
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
Documentation/devicetree/bindings/net/dsa/b53.txt
Documentation/devicetree/bindings/net/marvell,prestera.txt
Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
Documentation/devicetree/bindings/power/actions,owl-sps.txt
Documentation/devicetree/bindings/power/renesas,apmu.txt
Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt [new file with mode: 0644]
Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt
Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
Documentation/devicetree/bindings/reset/qcom,pdc-global.txt [new file with mode: 0644]
Documentation/devicetree/bindings/reset/renesas,rst.txt
Documentation/devicetree/bindings/serial/renesas,sci-serial.txt
Documentation/devicetree/bindings/serial/uniphier-uart.txt
Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
Documentation/devicetree/bindings/soc/rockchip/grf.txt
Documentation/devicetree/bindings/sram/sunxi-sram.txt
Documentation/devicetree/bindings/timer/renesas,tmu.txt
Documentation/devicetree/bindings/trivial-devices.txt
Documentation/devicetree/bindings/usb/dwc2.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/filesystems/ceph.txt
Documentation/filesystems/nfs/rpc-cache.txt
Documentation/filesystems/pohmelfs/design_notes.txt [deleted file]
Documentation/filesystems/pohmelfs/info.txt [deleted file]
Documentation/filesystems/pohmelfs/network_protocol.txt [deleted file]
Documentation/laptops/lg-laptop.rst [new file with mode: 0644]
Documentation/media/kapi/cec-core.rst
Documentation/media/kapi/mc-core.rst
Documentation/media/kapi/v4l2-subdev.rst
Documentation/media/uapi/cec/cec-func-poll.rst
Documentation/media/uapi/cec/cec-ioc-receive.rst
Documentation/media/uapi/mediactl/media-controller.rst
Documentation/media/uapi/mediactl/media-funcs.rst
Documentation/media/uapi/mediactl/media-ioc-device-info.rst
Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst
Documentation/media/uapi/mediactl/media-ioc-enum-links.rst
Documentation/media/uapi/mediactl/media-ioc-g-topology.rst
Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst [new file with mode: 0644]
Documentation/media/uapi/mediactl/media-ioc-setup-link.rst
Documentation/media/uapi/mediactl/media-request-ioc-queue.rst [new file with mode: 0644]
Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst [new file with mode: 0644]
Documentation/media/uapi/mediactl/request-api.rst [new file with mode: 0644]
Documentation/media/uapi/mediactl/request-func-close.rst [new file with mode: 0644]
Documentation/media/uapi/mediactl/request-func-ioctl.rst [new file with mode: 0644]
Documentation/media/uapi/mediactl/request-func-poll.rst [new file with mode: 0644]
Documentation/media/uapi/v4l/biblio.rst
Documentation/media/uapi/v4l/buffer.rst
Documentation/media/uapi/v4l/colorspaces-defs.rst
Documentation/media/uapi/v4l/colorspaces-details.rst
Documentation/media/uapi/v4l/extended-controls.rst
Documentation/media/uapi/v4l/func-poll.rst
Documentation/media/uapi/v4l/meta-formats.rst
Documentation/media/uapi/v4l/pixfmt-compressed.rst
Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst [new file with mode: 0644]
Documentation/media/uapi/v4l/pixfmt-reserved.rst
Documentation/media/uapi/v4l/vidioc-create-bufs.rst
Documentation/media/uapi/v4l/vidioc-cropcap.rst
Documentation/media/uapi/v4l/vidioc-dqevent.rst
Documentation/media/uapi/v4l/vidioc-g-crop.rst
Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
Documentation/media/uapi/v4l/vidioc-qbuf.rst
Documentation/media/uapi/v4l/vidioc-queryctrl.rst
Documentation/media/uapi/v4l/vidioc-reqbufs.rst
Documentation/media/videodev2.h.rst.exceptions
Documentation/serial/driver
Documentation/serial/serial-iso7816.txt [new file with mode: 0644]
Documentation/trace/kprobetrace.rst
Documentation/xilinx/eemi.txt [new file with mode: 0644]
MAINTAINERS
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/processor.h
arch/alpha/include/uapi/asm/ioctls.h
arch/alpha/kernel/core_apecs.c
arch/alpha/kernel/core_cia.c
arch/alpha/kernel/core_irongate.c
arch/alpha/kernel/core_lca.c
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/core_mcpcia.c
arch/alpha/kernel/core_t2.c
arch/alpha/kernel/core_titan.c
arch/alpha/kernel/core_tsunami.c
arch/alpha/kernel/core_wildfire.c
arch/alpha/kernel/pci-noop.c
arch/alpha/kernel/pci.c
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/setup.c
arch/alpha/kernel/sys_nautilus.c
arch/alpha/mm/init.c
arch/alpha/mm/numa.c
arch/arc/Kconfig
arch/arc/include/asm/processor.h
arch/arc/kernel/unwind.c
arch/arc/mm/highmem.c
arch/arc/mm/init.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-bone-common.dtsi
arch/arm/boot/dts/am335x-boneblack-common.dtsi
arch/arm/boot/dts/am335x-chiliboard.dts
arch/arm/boot/dts/am335x-cm-t335.dts
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-igep0033.dtsi
arch/arm/boot/dts/am335x-lxm.dts
arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/am335x-moxa-uc-2101.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts
arch/arm/boot/dts/am335x-nano.dts
arch/arm/boot/dts/am335x-osd3358-sm-red.dts
arch/arm/boot/dts/am335x-pdu001.dts
arch/arm/boot/dts/am335x-pepper.dts
arch/arm/boot/dts/am335x-sancloud-bbe.dts
arch/arm/boot/dts/am335x-shc.dts
arch/arm/boot/dts/am3517-evm-ui.dtsi [new file with mode: 0644]
arch/arm/boot/dts/am3517-evm.dts
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-cm-t43.dts
arch/arm/boot/dts/am437x-gp-evm.dts
arch/arm/boot/dts/am437x-idk-evm.dts
arch/arm/boot/dts/am437x-sk-evm.dts
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/am571x-idk.dts
arch/arm/boot/dts/am572x-idk-common.dtsi
arch/arm/boot/dts/am572x-idk.dts
arch/arm/boot/dts/am57xx-cl-som-am57x.dts
arch/arm/boot/dts/am57xx-idk-common.dtsi
arch/arm/boot/dts/arm-realview-eb.dtsi
arch/arm/boot/dts/arm-realview-pb1176.dts
arch/arm/boot/dts/arm-realview-pb11mp.dts
arch/arm/boot/dts/arm-realview-pbx.dtsi
arch/arm/boot/dts/armada-385-db-88f6820-amc.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-388-clearfog.dtsi
arch/arm/boot/dts/armada-xp-98dx3236.dtsi
arch/arm/boot/dts/armada-xp-98dx3336.dtsi
arch/arm/boot/dts/armada-xp-98dx4251.dtsi
arch/arm/boot/dts/armada-xp-db-dxbc2.dts
arch/arm/boot/dts/armada-xp-db-xc3-24g4xg.dts
arch/arm/boot/dts/aspeed-bmc-arm-stardragon4800-rep2.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-quanta-q71l.dts
arch/arm/boot/dts/aspeed-g4.dtsi
arch/arm/boot/dts/aspeed-g5.dtsi
arch/arm/boot/dts/at91-dvk_su60_somc.dtsi
arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi
arch/arm/boot/dts/at91-nattis-2-natte-2.dts
arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/at91-sama5d3_xplained.dts
arch/arm/boot/dts/at91-sama5d4_xplained.dts
arch/arm/boot/dts/at91-tse850-3.dts
arch/arm/boot/dts/at91-vinco.dts
arch/arm/boot/dts/at91sam9260ek.dts
arch/arm/boot/dts/at91sam9261ek.dts
arch/arm/boot/dts/at91sam9g20ek_common.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9x5cm.dtsi
arch/arm/boot/dts/bcm-hr2.dtsi
arch/arm/boot/dts/bcm-nsp.dtsi
arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm283x-rpi-lan7515.dtsi
arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/boot/dts/bcm958625hr.dts
arch/arm/boot/dts/da850-evm.dts
arch/arm/boot/dts/da850-lego-ev3.dts
arch/arm/boot/dts/dm8148-evm.dts
arch/arm/boot/dts/dm8148-t410.dts
arch/arm/boot/dts/dove-cubox.dts
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/dra62x-j5eco-evm.dts
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/dra71-evm.dts
arch/arm/boot/dts/dra72-evm-revc.dts
arch/arm/boot/dts/dra72-evm.dts
arch/arm/boot/dts/dra76-evm.dts
arch/arm/boot/dts/exynos3250-artik5.dtsi
arch/arm/boot/dts/exynos4210-origen.dts
arch/arm/boot/dts/exynos4210-trats.dts
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4412-midas.dtsi
arch/arm/boot/dts/exynos4412-odroid-common.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-pinctrl.dtsi
arch/arm/boot/dts/exynos5250-snow-rev5.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5410-odroidxu.dts
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5422-odroid-core.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
arch/arm/boot/dts/exynos5422-odroidxu3.dts
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/gr-peach-audiocamerashield.dtsi
arch/arm/boot/dts/hip04.dtsi
arch/arm/boot/dts/imx1.dtsi
arch/arm/boot/dts/imx23-evk.dts
arch/arm/boot/dts/imx23-olinuxino.dts
arch/arm/boot/dts/imx23-sansa.dts
arch/arm/boot/dts/imx23-stmp378x_devb.dts
arch/arm/boot/dts/imx23-xfi3.dts
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx28-apf28dev.dts
arch/arm/boot/dts/imx28-apx4devkit.dts
arch/arm/boot/dts/imx28-cfa10036.dts
arch/arm/boot/dts/imx28-duckbill-2-485.dts
arch/arm/boot/dts/imx28-duckbill-2-enocean.dts
arch/arm/boot/dts/imx28-duckbill-2-spi.dts
arch/arm/boot/dts/imx28-duckbill-2.dts
arch/arm/boot/dts/imx28-duckbill.dts
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx28-m28cu3.dts
arch/arm/boot/dts/imx28-m28evk.dts
arch/arm/boot/dts/imx28-sps1.dts
arch/arm/boot/dts/imx28-ts4600.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx31.dtsi
arch/arm/boot/dts/imx35.dtsi
arch/arm/boot/dts/imx50.dtsi
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51-zii-rdu1.dts
arch/arm/boot/dts/imx51-zii-scu2-mezz.dts
arch/arm/boot/dts/imx51-zii-scu3-esb.dts
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-ppd.dts
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
arch/arm/boot/dts/imx6dl-icore-mipi.dts
arch/arm/boot/dts/imx6dl-icore-rqs.dts
arch/arm/boot/dts/imx6dl-icore.dts
arch/arm/boot/dts/imx6dl-riotboard.dts
arch/arm/boot/dts/imx6q-apalis-eval.dts
arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
arch/arm/boot/dts/imx6q-apalis-ixora.dts
arch/arm/boot/dts/imx6q-icore-mipi.dts
arch/arm/boot/dts/imx6q-icore-ofcap10.dts
arch/arm/boot/dts/imx6q-icore-ofcap12.dts
arch/arm/boot/dts/imx6q-icore-rqs.dts
arch/arm/boot/dts/imx6q-icore.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/imx6qdl-apalis.dtsi
arch/arm/boot/dts/imx6qdl-icore-1.5.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi
arch/arm/boot/dts/imx6qdl-icore.dtsi
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/imx6qdl-wandboard.dtsi
arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/imx6sll.dtsi
arch/arm/boot/dts/imx6sx-sdb.dtsi
arch/arm/boot/dts/imx6sx.dtsi
arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-geam.dts
arch/arm/boot/dts/imx6ul-isiot-emmc.dts
arch/arm/boot/dts/imx6ul-isiot-nand.dts
arch/arm/boot/dts/imx6ul-isiot.dtsi
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/imx6ull-14x14-evk.dts
arch/arm/boot/dts/imx6ull-pinfunc.h
arch/arm/boot/dts/imx6ull.dtsi
arch/arm/boot/dts/imx6ulz-14x14-evk.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ulz.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/imx7s-warp.dts
arch/arm/boot/dts/imx7s.dtsi
arch/arm/boot/dts/imx7ulp-pinfunc.h
arch/arm/boot/dts/iwg20d-q7-common.dtsi
arch/arm/boot/dts/keystone-k2g.dtsi
arch/arm/boot/dts/lpc32xx.dtsi
arch/arm/boot/dts/ls1021a-qds.dts
arch/arm/boot/dts/ls1021a-twr.dts
arch/arm/boot/dts/ls1021a.dtsi
arch/arm/boot/dts/meson8.dtsi
arch/arm/boot/dts/meson8b-ec100.dts [new file with mode: 0644]
arch/arm/boot/dts/meson8b-odroidc1.dts
arch/arm/boot/dts/meson8b.dtsi
arch/arm/boot/dts/mt7623.dtsi
arch/arm/boot/dts/omap2.dtsi
arch/arm/boot/dts/omap2430.dtsi
arch/arm/boot/dts/omap3-beagle-xm.dts
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/omap3-gta04a3.dts
arch/arm/boot/dts/omap3-gta04a4.dts
arch/arm/boot/dts/omap3-gta04a5.dts
arch/arm/boot/dts/omap3-gta04a5one.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-n9.dts
arch/arm/boot/dts/omap5-board-common.dtsi
arch/arm/boot/dts/orion5x-linkstation.dtsi
arch/arm/boot/dts/owl-s500-cubieboard6.dts
arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts
arch/arm/boot/dts/owl-s500-guitar.dtsi
arch/arm/boot/dts/owl-s500.dtsi
arch/arm/boot/dts/pxa25x.dtsi
arch/arm/boot/dts/pxa27x.dtsi
arch/arm/boot/dts/pxa2xx.dtsi
arch/arm/boot/dts/qcom-apq8064.dtsi
arch/arm/boot/dts/qcom-ipq4019.dtsi
arch/arm/boot/dts/qcom-ipq8064-ap148.dts
arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
arch/arm/boot/dts/qcom-ipq8064.dtsi
arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/r8a7743-iwg20d-q7-dbcm-ca.dts
arch/arm/boot/dts/r8a7743-iwg20d-q7.dts
arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts
arch/arm/boot/dts/r8a77470.dtsi
arch/arm/boot/dts/r8a7778-bockw.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen.dts
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/r8a7790-stout.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/r8a7792.dtsi
arch/arm/boot/dts/r8a7793-gose.dts
arch/arm/boot/dts/r8a7793.dtsi
arch/arm/boot/dts/r8a7794-silk.dts
arch/arm/boot/dts/r8a7794.dtsi
arch/arm/boot/dts/r9a06g032.dtsi
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk3188-radxarock.dts
arch/arm/boot/dts/rk3188.dtsi
arch/arm/boot/dts/rk3288-tinker-s.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-tinker.dts
arch/arm/boot/dts/rk3288-tinker.dtsi [new file with mode: 0644]
arch/arm/boot/dts/s5pv210.dtsi
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/sama5d4.dtsi
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria10.dtsi
arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts [new file with mode: 0644]
arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts [deleted file]
arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href-family-pinctrl.dtsi
arch/arm/boot/dts/ste-href.dtsi
arch/arm/boot/dts/ste-hrefprev60.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/ste-u300.dts
arch/arm/boot/dts/stih410-b2260.dts
arch/arm/boot/dts/stihxxx-b2120.dtsi
arch/arm/boot/dts/stm32429i-eval.dts
arch/arm/boot/dts/stm32f429.dtsi
arch/arm/boot/dts/stm32f469-disco.dts
arch/arm/boot/dts/stm32f746-disco.dts
arch/arm/boot/dts/stm32f769-disco.dts
arch/arm/boot/dts/stm32h743.dtsi
arch/arm/boot/dts/stm32mp157c-ev1.dts
arch/arm/boot/dts/stm32mp157c.dtsi
arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
arch/arm/boot/dts/sun5i.dtsi
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a33.dtsi
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
arch/arm/boot/dts/sun8i-a83t.dtsi
arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus-v1.2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts
arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3.dtsi
arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
arch/arm/boot/dts/sun8i-r40.dtsi
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
arch/arm/boot/dts/sun9i-a80.dtsi
arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/boot/dts/tegra124-apalis-eval.dts
arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts
arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
arch/arm/boot/dts/tegra124-apalis.dtsi
arch/arm/boot/dts/tegra20-colibri-eval-v3.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra20-colibri-iris.dts
arch/arm/boot/dts/tegra20-colibri.dtsi
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30-apalis-eval.dts
arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra30-apalis.dtsi
arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
arch/arm/boot/dts/tegra30-colibri.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/uniphier-ld4-ref.dts
arch/arm/boot/dts/uniphier-ld4.dtsi
arch/arm/boot/dts/uniphier-ld6b-ref.dts
arch/arm/boot/dts/uniphier-pinctrl.dtsi
arch/arm/boot/dts/uniphier-pro4-ace.dts
arch/arm/boot/dts/uniphier-pro4-ref.dts
arch/arm/boot/dts/uniphier-pro4-sanji.dts
arch/arm/boot/dts/uniphier-pro4.dtsi
arch/arm/boot/dts/uniphier-pro5.dtsi
arch/arm/boot/dts/uniphier-pxs2-gentil.dts
arch/arm/boot/dts/uniphier-pxs2-vodka.dts
arch/arm/boot/dts/uniphier-pxs2.dtsi
arch/arm/boot/dts/uniphier-sld8-ref.dts
arch/arm/boot/dts/uniphier-sld8.dtsi
arch/arm/boot/dts/versatile-ab.dts
arch/arm/boot/dts/vf500.dtsi
arch/arm/boot/dts/vf610-twr.dts
arch/arm/boot/dts/vf610-zii-cfu1.dts
arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
arch/arm/boot/dts/vf610.dtsi
arch/arm/boot/dts/vfxxx.dtsi
arch/arm/boot/dts/zynq-zc702.dts
arch/arm/boot/dts/zynq-zc770-xm010.dts
arch/arm/boot/dts/zynq-zc770-xm013.dts
arch/arm/common/Kconfig
arch/arm/common/Makefile
arch/arm/common/krait-l2-accessors.c [new file with mode: 0644]
arch/arm/configs/bcm2835_defconfig
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mxs_defconfig
arch/arm/configs/qcom_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/include/asm/krait-l2-accessors.h [new file with mode: 0644]
arch/arm/include/asm/processor.h
arch/arm/kernel/devtree.c
arch/arm/kernel/setup.c
arch/arm/mach-at91/pm.c
arch/arm/mach-davinci/include/mach/clock.h [deleted file]
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/firmware.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-imx/anatop.c
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/mmdc.c
arch/arm/mach-imx/mxc.h
arch/arm/mach-imx/pm-imx6.c
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-omap1/ams-delta-fiq-handler.S
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/include/mach/board-ams-delta.h
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-s3c24xx/mach-gta02.c
arch/arm/mach-s3c24xx/mach-mini2440.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/headsmp-scu.S
arch/arm/mach-shmobile/headsmp.S
arch/arm/mach-shmobile/platsmp-scu.c
arch/arm/mach-shmobile/platsmp.c
arch/arm/mach-shmobile/pm-rcar-gen2.c
arch/arm/mach-shmobile/pm-rmobile.c
arch/arm/mach-shmobile/pm-rmobile.h
arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
arch/arm/mach-shmobile/setup-r7s9210.c [new file with mode: 0644]
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-rcar-gen2.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-shmobile/suspend.c
arch/arm/mach-shmobile/timer.c
arch/arm/mach-u300/Kconfig
arch/arm/mach-u300/Makefile
arch/arm/mach-u300/dummyspichip.c [deleted file]
arch/arm/mach-zynq/slcr.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/plat-samsung/Kconfig
arch/arm/xen/mm.c
arch/arm/xen/p2m.c
arch/arm64/Kconfig
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/actions/Makefile
arch/arm64/boot/dts/actions/s700-cubieboard7.dts
arch/arm64/boot/dts/actions/s700.dtsi
arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
arch/arm64/boot/dts/actions/s900.dtsi
arch/arm64/boot/dts/allwinner/Makefile
arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h5-bananapi-m2-plus-v1.2.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h5-bananapi-m2-plus.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.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/altera/socfpga_stratix10_socdk.dts
arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi
arch/arm64/boot/dts/amlogic/Makefile
arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
arch/arm64/boot/dts/amlogic/meson-axg.dtsi
arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12a.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gx.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
arch/arm64/boot/dts/arm/juno.dts
arch/arm64/boot/dts/broadcom/Makefile
arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts [new file with mode: 0644]
arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi
arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
arch/arm64/boot/dts/hisilicon/Makefile
arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts [new file with mode: 0644]
arch/arm64/boot/dts/hisilicon/hi3670.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/hisilicon/hi6220-coresight.dtsi
arch/arm64/boot/dts/hisilicon/hi6220.dtsi
arch/arm64/boot/dts/lg/lg1312.dtsi
arch/arm64/boot/dts/lg/lg1313.dtsi
arch/arm64/boot/dts/marvell/Makefile
arch/arm64/boot/dts/marvell/armada-372x.dtsi
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi
arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
arch/arm64/boot/dts/marvell/armada-ap806.dtsi
arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi
arch/arm64/boot/dts/marvell/armada-common.dtsi
arch/arm64/boot/dts/marvell/armada-cp110.dtsi
arch/arm64/boot/dts/mediatek/Makefile
arch/arm64/boot/dts/mediatek/mt2712e.dtsi
arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts [new file with mode: 0644]
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
arch/arm64/boot/dts/mediatek/mt7622.dtsi
arch/arm64/boot/dts/nvidia/tegra186.dtsi
arch/arm64/boot/dts/nvidia/tegra194.dtsi
arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
arch/arm64/boot/dts/nvidia/tegra210.dtsi
arch/arm64/boot/dts/qcom/Makefile
arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
arch/arm64/boot/dts/qcom/apq8096-db820c.dts
arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
arch/arm64/boot/dts/qcom/msm8916.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/msm8998-mtp.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8998.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm8916.dtsi
arch/arm64/boot/dts/qcom/pm8994.dtsi
arch/arm64/boot/dts/qcom/pm8998.dtsi
arch/arm64/boot/dts/qcom/pmi8998.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sdm845-mtp.dts
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/renesas/Makefile
arch/arm64/boot/dts/renesas/r8a774a1.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
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-m3ulcb.dts
arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7796.dtsi
arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a77965-m3nulcb.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts
arch/arm64/boot/dts/renesas/r8a77965.dtsi
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/px30-evb.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/px30.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3399-ficus.dts
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-rock960.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts
arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts
arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
arch/arm64/boot/dts/synaptics/as370.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am65-main.dtsi
arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am65.dtsi
arch/arm64/boot/dts/ti/k3-am654-base-board.dts
arch/arm64/configs/defconfig
arch/arm64/include/asm/processor.h
arch/arm64/kernel/acpi.c
arch/arm64/kernel/acpi_numa.c
arch/arm64/kernel/setup.c
arch/arm64/mm/dma-mapping.c
arch/arm64/mm/init.c
arch/arm64/mm/kasan_init.c
arch/arm64/mm/mmu.c
arch/arm64/mm/numa.c
arch/c6x/Kconfig
arch/c6x/include/asm/processor.h
arch/c6x/kernel/setup.c
arch/c6x/mm/dma-coherent.c
arch/c6x/mm/init.c
arch/csky/Kconfig
arch/csky/include/asm/processor.h
arch/csky/kernel/setup.c
arch/csky/mm/highmem.c
arch/csky/mm/init.c
arch/h8300/Kconfig
arch/h8300/include/asm/processor.h
arch/h8300/kernel/setup.c
arch/h8300/mm/init.c
arch/hexagon/Kconfig
arch/hexagon/include/asm/processor.h
arch/hexagon/kernel/dma.c
arch/hexagon/kernel/setup.c
arch/hexagon/mm/init.c
arch/ia64/Kconfig
arch/ia64/include/asm/processor.h
arch/ia64/kernel/crash.c
arch/ia64/kernel/efi.c
arch/ia64/kernel/ia64_ksyms.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/signal.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/topology.c
arch/ia64/kernel/unwind.c
arch/ia64/mm/contig.c
arch/ia64/mm/discontig.c
arch/ia64/mm/init.c
arch/ia64/mm/numa.c
arch/ia64/mm/tlb.c
arch/ia64/pci/pci.c
arch/ia64/sn/kernel/bte.c
arch/ia64/sn/kernel/io_common.c
arch/ia64/sn/kernel/setup.c
arch/m68k/Kconfig
arch/m68k/atari/stram.c
arch/m68k/coldfire/m54xx.c
arch/m68k/emu/nfeth.c
arch/m68k/include/asm/processor.h
arch/m68k/kernel/setup_mm.c
arch/m68k/kernel/setup_no.c
arch/m68k/kernel/sun3-head.S
arch/m68k/kernel/uboot.c
arch/m68k/mm/init.c
arch/m68k/mm/mcfmmu.c
arch/m68k/mm/motorola.c
arch/m68k/mm/sun3mmu.c
arch/m68k/sun3/config.c
arch/m68k/sun3/dvma.c
arch/m68k/sun3/mmu_emu.c
arch/m68k/sun3/sun3dvma.c
arch/m68k/sun3x/dvma.c
arch/microblaze/Kconfig
arch/microblaze/include/asm/processor.h
arch/microblaze/mm/consistent.c
arch/microblaze/mm/init.c
arch/microblaze/pci/pci-common.c
arch/mips/Kconfig
arch/mips/ar7/memory.c
arch/mips/ath79/setup.c
arch/mips/bcm63xx/prom.c
arch/mips/bcm63xx/setup.c
arch/mips/bmips/setup.c
arch/mips/cavium-octeon/dma-octeon.c
arch/mips/dec/prom/memory.c
arch/mips/emma/common/prom.c
arch/mips/fw/arc/memory.c
arch/mips/include/asm/processor.h
arch/mips/include/uapi/asm/ioctls.h
arch/mips/jazz/jazzdma.c
arch/mips/kernel/crash.c
arch/mips/kernel/crash_dump.c
arch/mips/kernel/prom.c
arch/mips/kernel/setup.c
arch/mips/kernel/traps.c
arch/mips/kernel/vpe.c
arch/mips/kvm/commpage.c
arch/mips/kvm/dyntrans.c
arch/mips/kvm/emulate.c
arch/mips/kvm/interrupt.c
arch/mips/kvm/mips.c
arch/mips/lantiq/prom.c
arch/mips/lasat/prom.c
arch/mips/loongson64/common/init.c
arch/mips/loongson64/loongson-3/numa.c
arch/mips/mm/init.c
arch/mips/mm/pgtable-32.c
arch/mips/mti-malta/malta-memory.c
arch/mips/netlogic/xlp/dt.c
arch/mips/pci/pci-legacy.c
arch/mips/pci/pci.c
arch/mips/ralink/of.c
arch/mips/rb532/prom.c
arch/mips/sgi-ip27/ip27-memory.c
arch/mips/sibyte/common/cfe.c
arch/mips/sibyte/swarm/setup.c
arch/mips/txx9/rbtx4938/prom.c
arch/nds32/Kconfig
arch/nds32/include/asm/processor.h
arch/nds32/kernel/setup.c
arch/nds32/mm/highmem.c
arch/nds32/mm/init.c
arch/nios2/Kconfig
arch/nios2/include/asm/processor.h
arch/nios2/kernel/prom.c
arch/nios2/kernel/setup.c
arch/nios2/mm/init.c
arch/openrisc/Kconfig
arch/openrisc/include/asm/processor.h
arch/openrisc/kernel/setup.c
arch/openrisc/mm/init.c
arch/openrisc/mm/ioremap.c
arch/parisc/Kconfig
arch/parisc/include/asm/processor.h
arch/parisc/include/uapi/asm/ioctls.h
arch/parisc/include/uapi/asm/posix_types.h
arch/parisc/kernel/entry.S
arch/parisc/mm/init.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/processor.h
arch/powerpc/include/uapi/asm/ioctls.h
arch/powerpc/kernel/dt_cpu_ftrs.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/lib/alloc.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/ppc_mmu_32.c
arch/powerpc/platforms/pasemi/iommu.c
arch/powerpc/platforms/powermac/nvram.c
arch/powerpc/platforms/powernv/memtrace.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/ps3/setup.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/sysdev/dart_iommu.c
arch/powerpc/sysdev/msi_bitmap.c
arch/riscv/Kconfig
arch/riscv/include/asm/elf.h
arch/riscv/include/asm/processor.h
arch/riscv/kernel/cpufeature.c
arch/riscv/mm/init.c
arch/s390/Kconfig
arch/s390/include/asm/processor.h
arch/s390/kernel/crash_dump.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/topology.c
arch/s390/kernel/vdso.c
arch/s390/mm/extmem.c
arch/s390/mm/init.c
arch/s390/mm/vmem.c
arch/s390/numa/mode_emu.c
arch/s390/numa/numa.c
arch/s390/numa/toptree.c
arch/sh/Kconfig
arch/sh/include/asm/processor_32.h
arch/sh/include/asm/processor_64.h
arch/sh/include/uapi/asm/ioctls.h
arch/sh/mm/init.c
arch/sh/mm/ioremap_fixed.c
arch/sparc/Kconfig
arch/sparc/include/asm/processor_32.h
arch/sparc/include/asm/processor_64.h
arch/sparc/include/uapi/asm/ioctls.h
arch/sparc/kernel/mdesc.c
arch/sparc/kernel/prom_32.c
arch/sparc/kernel/prom_64.c
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/smp_64.c
arch/sparc/mm/init_32.c
arch/sparc/mm/init_64.c
arch/sparc/mm/srmmu.c
arch/um/Kconfig
arch/um/drivers/line.c
arch/um/drivers/net_kern.c
arch/um/drivers/port_user.c
arch/um/drivers/vector_kern.c
arch/um/drivers/vector_user.c
arch/um/include/shared/aio.h [deleted file]
arch/um/kernel/initrd.c
arch/um/kernel/irq.c
arch/um/kernel/mem.c
arch/um/kernel/physmem.c
arch/um/kernel/trap.c
arch/um/os-Linux/Makefile
arch/um/os-Linux/aio.c [deleted file]
arch/um/os-Linux/skas/process.c
arch/unicore32/Kconfig
arch/unicore32/include/asm/processor.h
arch/unicore32/kernel/hibernate.c
arch/unicore32/kernel/setup.c
arch/unicore32/mm/init.c
arch/unicore32/mm/mmu.c
arch/x86/Kconfig
arch/x86/include/asm/iosf_mbi.h
arch/x86/include/asm/kexec.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/ptrace.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/e820.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-swiotlb.c
arch/x86/kernel/pvclock.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/tce_64.c
arch/x86/mm/amdtopology.c
arch/x86/mm/fault.c
arch/x86/mm/highmem_32.c
arch/x86/mm/init.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/kasan_init_64.c
arch/x86/mm/kaslr.c
arch/x86/mm/numa.c
arch/x86/mm/numa_32.c
arch/x86/mm/numa_64.c
arch/x86/mm/numa_emulation.c
arch/x86/mm/pageattr-test.c
arch/x86/mm/pageattr.c
arch/x86/mm/pat.c
arch/x86/mm/physaddr.c
arch/x86/pci/i386.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/efi/quirks.c
arch/x86/platform/intel/iosf_mbi.c
arch/x86/platform/olpc/olpc_dt.c
arch/x86/power/hibernate_32.c
arch/x86/um/asm/processor_32.h
arch/x86/um/asm/processor_64.h
arch/x86/um/shared/sysdep/ptrace_32.h
arch/x86/xen/enlighten.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/p2m.c
arch/x86/xen/platform-pci-unplug.c
arch/x86/xen/spinlock.c
arch/x86/xen/xen-pvh.S
arch/xtensa/Kconfig
arch/xtensa/include/asm/processor.h
arch/xtensa/include/uapi/asm/ioctls.h
arch/xtensa/kernel/pci.c
arch/xtensa/mm/cache.c
arch/xtensa/mm/init.c
arch/xtensa/mm/kasan_init.c
arch/xtensa/mm/mmu.c
arch/xtensa/platforms/iss/network.c
arch/xtensa/platforms/iss/setup.c
block/blk-settings.c
block/bounce.c
drivers/acpi/Kconfig
drivers/acpi/acpi_memhotplug.c
drivers/acpi/numa.c
drivers/acpi/pmic/intel_pmic_xpower.c
drivers/acpi/tables.c
drivers/base/memory.c
drivers/base/platform.c
drivers/block/rbd.c
drivers/bus/imx-weim.c
drivers/bus/ti-sysc.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/actions/Kconfig
drivers/clk/actions/Makefile
drivers/clk/actions/owl-common.c
drivers/clk/actions/owl-common.h
drivers/clk/actions/owl-reset.c [new file with mode: 0644]
drivers/clk/actions/owl-reset.h [new file with mode: 0644]
drivers/clk/actions/owl-s700.c
drivers/clk/actions/owl-s900.c
drivers/clk/at91/Makefile
drivers/clk/at91/at91sam9260.c [new file with mode: 0644]
drivers/clk/at91/at91sam9rl.c [new file with mode: 0644]
drivers/clk/at91/at91sam9x5.c [new file with mode: 0644]
drivers/clk/at91/clk-audio-pll.c
drivers/clk/at91/clk-generated.c
drivers/clk/at91/clk-h32mx.c
drivers/clk/at91/clk-i2s-mux.c
drivers/clk/at91/clk-main.c
drivers/clk/at91/clk-master.c
drivers/clk/at91/clk-peripheral.c
drivers/clk/at91/clk-pll.c
drivers/clk/at91/clk-plldiv.c
drivers/clk/at91/clk-programmable.c
drivers/clk/at91/clk-slow.c
drivers/clk/at91/clk-smd.c
drivers/clk/at91/clk-system.c
drivers/clk/at91/clk-usb.c
drivers/clk/at91/clk-utmi.c
drivers/clk/at91/dt-compat.c [new file with mode: 0644]
drivers/clk/at91/pmc.c
drivers/clk/at91/pmc.h
drivers/clk/at91/sama5d2.c [new file with mode: 0644]
drivers/clk/at91/sama5d4.c [new file with mode: 0644]
drivers/clk/axs10x/pll_clock.c
drivers/clk/bcm/clk-kona-setup.c
drivers/clk/clk-asm9260.c
drivers/clk/clk-bulk.c
drivers/clk/clk-cdce925.c
drivers/clk/clk-devres.c
drivers/clk/clk-fixed-factor.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-gpio.c
drivers/clk/clk-hsdk-pll.c
drivers/clk/clk-max77686.c
drivers/clk/clk-nomadik.c
drivers/clk/clk-npcm7xx.c
drivers/clk/clk-palmas.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-s2mps11.c
drivers/clk/clk-scmi.c
drivers/clk/clk-scpi.c
drivers/clk/clk-si5351.c
drivers/clk/clk-stm32f4.c
drivers/clk/clk-stm32h7.c
drivers/clk/clk-stm32mp1.c
drivers/clk/clk-tango4.c
drivers/clk/clk.c
drivers/clk/davinci/psc.c
drivers/clk/hisilicon/Kconfig
drivers/clk/hisilicon/Makefile
drivers/clk/hisilicon/clk-hi3670.c [new file with mode: 0644]
drivers/clk/hisilicon/reset.c
drivers/clk/imx/clk-cpu.c
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk-imx6sl.c
drivers/clk/imx/clk-imx6sll.c
drivers/clk/imx/clk-imx6sx.c
drivers/clk/imx/clk-imx6ul.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk.h
drivers/clk/ingenic/Kconfig [new file with mode: 0644]
drivers/clk/ingenic/Makefile
drivers/clk/ingenic/jz4725b-cgu.c [new file with mode: 0644]
drivers/clk/keystone/Kconfig
drivers/clk/keystone/gate.c
drivers/clk/keystone/pll.c
drivers/clk/mediatek/clk-mt2701.c
drivers/clk/meson/axg-audio.c
drivers/clk/meson/axg.c
drivers/clk/meson/axg.h
drivers/clk/meson/clk-pll.c
drivers/clk/meson/clkc.h
drivers/clk/meson/gxbb.c
drivers/clk/meson/gxbb.h
drivers/clk/meson/meson8b.c
drivers/clk/meson/meson8b.h
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/mvebu/ap806-system-controller.c
drivers/clk/mvebu/armada-370.c
drivers/clk/mvebu/armada-375.c
drivers/clk/mvebu/armada-37xx-periph.c
drivers/clk/mvebu/armada-37xx-tbg.c
drivers/clk/mvebu/armada-37xx-xtal.c
drivers/clk/mvebu/armada-38x.c
drivers/clk/mvebu/armada-39x.c
drivers/clk/mvebu/armada-xp.c
drivers/clk/mvebu/clk-corediv.c
drivers/clk/mvebu/clk-cpu.c
drivers/clk/mvebu/common.c
drivers/clk/mvebu/common.h
drivers/clk/mvebu/cp110-system-controller.c
drivers/clk/mvebu/dove.c
drivers/clk/mvebu/kirkwood.c
drivers/clk/mvebu/mv98dx3236.c
drivers/clk/mvebu/orion.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/camcc-sdm845.c [new file with mode: 0644]
drivers/clk/qcom/clk-alpha-pll.c
drivers/clk/qcom/clk-branch.c
drivers/clk/qcom/clk-hfpll.c [new file with mode: 0644]
drivers/clk/qcom/clk-hfpll.h [new file with mode: 0644]
drivers/clk/qcom/clk-krait.c [new file with mode: 0644]
drivers/clk/qcom/clk-krait.h [new file with mode: 0644]
drivers/clk/qcom/clk-rcg.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/gcc-ipq806x.c
drivers/clk/qcom/gcc-msm8960.c
drivers/clk/qcom/gcc-msm8996.c
drivers/clk/qcom/gcc-qcs404.c [new file with mode: 0644]
drivers/clk/qcom/gcc-sdm660.c [new file with mode: 0644]
drivers/clk/qcom/gcc-sdm845.c
drivers/clk/qcom/hfpll.c [new file with mode: 0644]
drivers/clk/qcom/kpss-xcc.c [new file with mode: 0644]
drivers/clk/qcom/krait-cc.c [new file with mode: 0644]
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/clk-div6.c
drivers/clk/renesas/clk-emev2.c
drivers/clk/renesas/clk-mstp.c
drivers/clk/renesas/clk-r8a73a4.c
drivers/clk/renesas/clk-r8a7740.c
drivers/clk/renesas/clk-r8a7778.c
drivers/clk/renesas/clk-r8a7779.c
drivers/clk/renesas/clk-rcar-gen2.c
drivers/clk/renesas/clk-rz.c
drivers/clk/renesas/clk-sh73a0.c
drivers/clk/renesas/r7s9210-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a7743-cpg-mssr.c
drivers/clk/renesas/r8a7745-cpg-mssr.c
drivers/clk/renesas/r8a774a1-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a774c0-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a7790-cpg-mssr.c
drivers/clk/renesas/r8a7791-cpg-mssr.c
drivers/clk/renesas/r8a7792-cpg-mssr.c
drivers/clk/renesas/r8a7794-cpg-mssr.c
drivers/clk/renesas/r8a7795-cpg-mssr.c
drivers/clk/renesas/r8a7796-cpg-mssr.c
drivers/clk/renesas/r8a77965-cpg-mssr.c
drivers/clk/renesas/r8a77970-cpg-mssr.c
drivers/clk/renesas/r8a77980-cpg-mssr.c
drivers/clk/renesas/r8a77990-cpg-mssr.c
drivers/clk/renesas/r8a77995-cpg-mssr.c
drivers/clk/renesas/r9a06g032-clocks.c
drivers/clk/renesas/rcar-gen2-cpg.c
drivers/clk/renesas/rcar-gen2-cpg.h
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/renesas/rcar-gen3-cpg.h
drivers/clk/renesas/rcar-usb2-clock-sel.c
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/rockchip/clk-ddr.c
drivers/clk/rockchip/clk-rk3188.c
drivers/clk/rockchip/clk-rk3288.c
drivers/clk/rockchip/clk-rk3328.c
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-cpu.h
drivers/clk/samsung/clk-exynos-audss.c
drivers/clk/samsung/clk-exynos3250.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/samsung/clk-exynos5250.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-exynos5433.c
drivers/clk/samsung/clk-s3c2410.c
drivers/clk/samsung/clk-s3c2412.c
drivers/clk/samsung/clk-s3c2443.c
drivers/clk/samsung/clk-s3c64xx.c
drivers/clk/samsung/clk-s5pv210.c
drivers/clk/samsung/clk.c
drivers/clk/samsung/clk.h
drivers/clk/st/clkgen-fsyn.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.h
drivers/clk/sunxi-ng/ccu-sun50i-h6.c
drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
drivers/clk/sunxi-ng/ccu_nkmp.c
drivers/clk/sunxi-ng/ccu_nkmp.h
drivers/clk/sunxi-ng/ccu_nm.c
drivers/clk/sunxi-ng/ccu_nm.h
drivers/clk/sunxi/clk-mod0.c
drivers/clk/sunxi/clk-sun9i-core.c
drivers/clk/sunxi/clk-sunxi.c
drivers/clk/tegra/clk-dfll.c
drivers/clk/tegra/clk-tegra210.c
drivers/clk/ti/Makefile
drivers/clk/ti/apll.c
drivers/clk/ti/clk-33xx-compat.c [new file with mode: 0644]
drivers/clk/ti/clk-33xx.c
drivers/clk/ti/clk-43xx-compat.c [new file with mode: 0644]
drivers/clk/ti/clk-43xx.c
drivers/clk/ti/clk-7xx-compat.c [new file with mode: 0644]
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/clk-dra7-atl.c
drivers/clk/ti/clk.c
drivers/clk/ti/clkctrl.c
drivers/clk/ti/clock.h
drivers/clk/ti/composite.c
drivers/clk/ti/divider.c
drivers/clk/ti/dpll.c
drivers/clk/ti/dpll3xxx.c
drivers/clk/ti/fapll.c
drivers/clk/ti/fixed-factor.c
drivers/clk/ti/gate.c
drivers/clk/ti/interface.c
drivers/clk/ti/mux.c
drivers/clk/zynq/clkc.c
drivers/clk/zynqmp/Kconfig [new file with mode: 0644]
drivers/clk/zynqmp/Makefile [new file with mode: 0644]
drivers/clk/zynqmp/clk-gate-zynqmp.c [new file with mode: 0644]
drivers/clk/zynqmp/clk-mux-zynqmp.c [new file with mode: 0644]
drivers/clk/zynqmp/clk-zynqmp.h [new file with mode: 0644]
drivers/clk/zynqmp/clkc.c [new file with mode: 0644]
drivers/clk/zynqmp/divider.c [new file with mode: 0644]
drivers/clk/zynqmp/pll.c [new file with mode: 0644]
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/arm_big_little_dt.c [deleted file]
drivers/cpufreq/intel_pstate.c
drivers/cpuidle/governors/menu.c
drivers/edac/Kconfig
drivers/edac/Makefile
drivers/edac/qcom_edac.c [new file with mode: 0644]
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/arm_scmi/base.c
drivers/firmware/arm_scmi/clock.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/arm_scmi/power.c
drivers/firmware/arm_scmi/sensors.c
drivers/firmware/dcdbas.c [deleted file]
drivers/firmware/dcdbas.h [deleted file]
drivers/firmware/dell_rbu.c [deleted file]
drivers/firmware/dmi_scan.c
drivers/firmware/efi/apple-properties.c
drivers/firmware/efi/memmap.c
drivers/firmware/imx/Kconfig [new file with mode: 0644]
drivers/firmware/imx/Makefile [new file with mode: 0644]
drivers/firmware/imx/imx-scu.c [new file with mode: 0644]
drivers/firmware/imx/misc.c [new file with mode: 0644]
drivers/firmware/iscsi_ibft_find.c
drivers/firmware/memmap.c
drivers/firmware/meson/meson_sm.c
drivers/firmware/qcom_scm.c
drivers/firmware/tegra/bpmp.c
drivers/firmware/ti_sci.c
drivers/firmware/xilinx/Kconfig [new file with mode: 0644]
drivers/firmware/xilinx/Makefile [new file with mode: 0644]
drivers/firmware/xilinx/zynqmp-debug.c [new file with mode: 0644]
drivers/firmware/xilinx/zynqmp-debug.h [new file with mode: 0644]
drivers/firmware/xilinx/zynqmp.c [new file with mode: 0644]
drivers/gpu/ipu-v3/ipu-csi.c
drivers/hid/Kconfig
drivers/hid/hid-asus.c
drivers/hid/hid-input.c
drivers/hid/hid-picolcd_cir.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-aspeed.c
drivers/i2c/busses/i2c-designware-baytrail.c
drivers/i2c/busses/i2c-designware-common.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-master.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-mt65xx.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-qcom-geni.c
drivers/i2c/busses/i2c-qup.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-synquacer.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/busses/i2c-uniphier-f.c
drivers/i2c/busses/i2c-zx2967.c
drivers/i2c/i2c-core-base.c
drivers/i2c/muxes/i2c-mux-gpmux.c
drivers/i2c/muxes/i2c-mux-ltc4306.c
drivers/i2c/muxes/i2c-mux-mlxcpld.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/iio/accel/Kconfig
drivers/iio/accel/Makefile
drivers/iio/accel/adxl345_i2c.c
drivers/iio/accel/adxl372.c [new file with mode: 0644]
drivers/iio/accel/adxl372.h [new file with mode: 0644]
drivers/iio/accel/adxl372_i2c.c [new file with mode: 0644]
drivers/iio/accel/adxl372_spi.c [new file with mode: 0644]
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/ad7298.c
drivers/iio/adc/ad7476.c
drivers/iio/adc/ad7793.c
drivers/iio/adc/ad7887.c
drivers/iio/adc/ad7923.c
drivers/iio/adc/ad799x.c
drivers/iio/adc/at91_adc.c
drivers/iio/adc/envelope-detector.c
drivers/iio/adc/fsl-imx25-gcq.c
drivers/iio/adc/max9611.c
drivers/iio/adc/mcp3911.c [new file with mode: 0644]
drivers/iio/adc/meson_saradc.c
drivers/iio/adc/qcom-pm8xxx-xoadc.c
drivers/iio/adc/qcom-spmi-adc5.c [new file with mode: 0644]
drivers/iio/adc/qcom-vadc-common.c
drivers/iio/adc/qcom-vadc-common.h
drivers/iio/adc/rcar-gyroadc.c
drivers/iio/adc/sc27xx_adc.c
drivers/iio/adc/ti-ads7950.c
drivers/iio/amplifiers/ad8366.c
drivers/iio/chemical/bme680.h
drivers/iio/chemical/bme680_core.c
drivers/iio/dac/Kconfig
drivers/iio/dac/Makefile
drivers/iio/dac/ad5064.c
drivers/iio/dac/ad5446.c
drivers/iio/dac/ad5504.c
drivers/iio/dac/ad5686.c
drivers/iio/dac/ad5758.c
drivers/iio/dac/ad5791.c
drivers/iio/dac/dpot-dac.c
drivers/iio/dac/ltc1660.c [new file with mode: 0644]
drivers/iio/dac/max517.c
drivers/iio/dac/max5821.c
drivers/iio/dac/mcp4725.c
drivers/iio/dac/mcp4922.c
drivers/iio/dac/ti-dac5571.c
drivers/iio/frequency/ad9523.c
drivers/iio/frequency/adf4350.c
drivers/iio/health/max30102.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
drivers/iio/imu/st_lsm6dsx/Kconfig
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
drivers/iio/light/bh1750.c
drivers/iio/light/max44000.c
drivers/iio/light/tsl2772.c
drivers/iio/magnetometer/hmc5843.h
drivers/iio/multiplexer/iio-mux.c
drivers/iio/potentiometer/max5481.c
drivers/iio/potentiometer/mcp4018.c
drivers/iio/potentiometer/mcp4531.c
drivers/iio/pressure/ms5611.h
drivers/iio/pressure/ms5611_core.c
drivers/iio/pressure/ms5611_i2c.c
drivers/iio/pressure/ms5611_spi.c
drivers/iio/proximity/Kconfig
drivers/iio/proximity/Makefile
drivers/iio/proximity/isl29501.c
drivers/iio/proximity/vl53l0x-i2c.c [new file with mode: 0644]
drivers/iio/trigger/iio-trig-sysfs.c
drivers/iommu/mtk_iommu.c
drivers/iommu/mtk_iommu_v1.c
drivers/macintosh/smu.c
drivers/mailbox/Kconfig
drivers/mailbox/bcm-flexrm-mailbox.c
drivers/mailbox/mtk-cmdq-mailbox.c
drivers/mailbox/qcom-apcs-ipc-mailbox.c
drivers/mailbox/ti-msgmgr.c
drivers/media/Makefile
drivers/media/cec/Makefile
drivers/media/cec/cec-adap.c
drivers/media/cec/cec-api.c
drivers/media/cec/cec-core.c
drivers/media/cec/cec-edid.c [deleted file]
drivers/media/cec/cec-pin.c
drivers/media/common/b2c2/flexcop-i2c.c
drivers/media/common/cx2341x.c
drivers/media/common/saa7146/saa7146_fops.c
drivers/media/common/saa7146/saa7146_video.c
drivers/media/common/siano/smscoreapi.c
drivers/media/common/siano/smsir.c
drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
drivers/media/common/videobuf2/videobuf2-core.c
drivers/media/common/videobuf2/videobuf2-v4l2.c
drivers/media/dvb-core/dmxdev.c
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvb_vb2.c
drivers/media/dvb-core/dvbdev.c
drivers/media/dvb-frontends/Kconfig
drivers/media/dvb-frontends/Makefile
drivers/media/dvb-frontends/au8522_decoder.c
drivers/media/dvb-frontends/au8522_priv.h
drivers/media/dvb-frontends/cx24123.c
drivers/media/dvb-frontends/cxd2099.c
drivers/media/dvb-frontends/cxd2099.h
drivers/media/dvb-frontends/cxd2820r_core.c
drivers/media/dvb-frontends/dibx000_common.c
drivers/media/dvb-frontends/drx39xyj/drxj.c
drivers/media/dvb-frontends/lgdt330x.c
drivers/media/dvb-frontends/lnbh29.c [new file with mode: 0644]
drivers/media/dvb-frontends/lnbh29.h [new file with mode: 0644]
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/dvb-frontends/mt312.c
drivers/media/dvb-frontends/mxl5xx.c
drivers/media/dvb-frontends/mxl5xx.h
drivers/media/dvb-frontends/mxl5xx_defs.h
drivers/media/dvb-frontends/mxl5xx_regs.h
drivers/media/dvb-frontends/rtl2832_sdr.c
drivers/media/dvb-frontends/s5h1420.c
drivers/media/dvb-frontends/stv0910.c
drivers/media/dvb-frontends/stv0910.h
drivers/media/dvb-frontends/stv0910_regs.h
drivers/media/dvb-frontends/stv6111.c
drivers/media/dvb-frontends/stv6111.h
drivers/media/dvb-frontends/tc90522.c
drivers/media/dvb-frontends/ts2020.c
drivers/media/dvb-frontends/zd1301_demod.c
drivers/media/dvb-frontends/zl10039.c
drivers/media/firewire/firedtv-fe.c
drivers/media/i2c/Kconfig
drivers/media/i2c/Makefile
drivers/media/i2c/ad5820.c
drivers/media/i2c/adv7180.c
drivers/media/i2c/adv748x/adv748x-afe.c
drivers/media/i2c/adv748x/adv748x-core.c
drivers/media/i2c/adv748x/adv748x-csi2.c
drivers/media/i2c/adv748x/adv748x-hdmi.c
drivers/media/i2c/adv748x/adv748x.h
drivers/media/i2c/adv7511.c
drivers/media/i2c/adv7604.c
drivers/media/i2c/adv7842.c
drivers/media/i2c/ak881x.c
drivers/media/i2c/cs53l32a.c
drivers/media/i2c/cx25840/cx25840-ir.c
drivers/media/i2c/dw9714.c
drivers/media/i2c/dw9807-vcm.c
drivers/media/i2c/imx274.c
drivers/media/i2c/imx319.c [new file with mode: 0644]
drivers/media/i2c/imx355.c [new file with mode: 0644]
drivers/media/i2c/lm3560.c
drivers/media/i2c/lm3646.c
drivers/media/i2c/m5mols/m5mols_core.c
drivers/media/i2c/max2175.c
drivers/media/i2c/max2175.h
drivers/media/i2c/msp3400-driver.c
drivers/media/i2c/msp3400-driver.h
drivers/media/i2c/mt9m111.c
drivers/media/i2c/mt9t112.c
drivers/media/i2c/mt9v032.c
drivers/media/i2c/noon010pc30.c
drivers/media/i2c/ov13858.c
drivers/media/i2c/ov2640.c
drivers/media/i2c/ov2659.c
drivers/media/i2c/ov2680.c
drivers/media/i2c/ov2685.c
drivers/media/i2c/ov5640.c
drivers/media/i2c/ov5645.c
drivers/media/i2c/ov5647.c
drivers/media/i2c/ov5670.c
drivers/media/i2c/ov5695.c
drivers/media/i2c/ov6650.c
drivers/media/i2c/ov7251.c
drivers/media/i2c/ov7670.c
drivers/media/i2c/ov772x.c
drivers/media/i2c/ov7740.c
drivers/media/i2c/ov9650.c
drivers/media/i2c/rj54n1cb0c.c
drivers/media/i2c/s5c73m3/s5c73m3-core.c
drivers/media/i2c/s5k4ecgx.c
drivers/media/i2c/s5k5baf.c
drivers/media/i2c/s5k6aa.c
drivers/media/i2c/saa7115.c
drivers/media/i2c/saa7127.c
drivers/media/i2c/smiapp/smiapp-core.c
drivers/media/i2c/soc_camera/Makefile
drivers/media/i2c/soc_camera/mt9m001.c [deleted file]
drivers/media/i2c/soc_camera/mt9t112.c [deleted file]
drivers/media/i2c/soc_camera/mt9v022.c [deleted file]
drivers/media/i2c/soc_camera/ov5642.c [deleted file]
drivers/media/i2c/soc_camera/ov772x.c [deleted file]
drivers/media/i2c/soc_camera/ov9640.c [deleted file]
drivers/media/i2c/soc_camera/ov9740.c [deleted file]
drivers/media/i2c/soc_camera/rj54n1cb0c.c [deleted file]
drivers/media/i2c/soc_camera/soc_mt9m001.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_mt9t112.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_mt9v022.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_ov5642.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_ov772x.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_ov9640.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_ov9740.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_rj54n1cb0c.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/soc_tw9910.c [new file with mode: 0644]
drivers/media/i2c/soc_camera/tw9910.c [deleted file]
drivers/media/i2c/sr030pc30.c
drivers/media/i2c/tc358743.c
drivers/media/i2c/tda1997x.c
drivers/media/i2c/tvaudio.c
drivers/media/i2c/tvp514x.c
drivers/media/i2c/tvp5150.c
drivers/media/i2c/tvp5150_reg.h
drivers/media/i2c/tvp7002.c
drivers/media/i2c/video-i2c.c
drivers/media/media-device.c
drivers/media/media-entity.c
drivers/media/media-request.c [new file with mode: 0644]
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/bt8xx/bttv-i2c.c
drivers/media/pci/bt8xx/bttv-input.c
drivers/media/pci/bt8xx/dvb-bt8xx.c
drivers/media/pci/cobalt/cobalt-alsa-main.c
drivers/media/pci/cobalt/cobalt-alsa-pcm.c
drivers/media/pci/cobalt/cobalt-v4l2.c
drivers/media/pci/cx18/cx18-alsa-main.c
drivers/media/pci/cx18/cx18-alsa-pcm.c
drivers/media/pci/cx18/cx18-cards.c
drivers/media/pci/cx18/cx18-driver.c
drivers/media/pci/cx18/cx18-i2c.c
drivers/media/pci/cx18/cx18-ioctl.c
drivers/media/pci/cx23885/altera-ci.c
drivers/media/pci/cx23885/cx23885-417.c
drivers/media/pci/cx23885/cx23885-alsa.c
drivers/media/pci/cx23885/cx23885-dvb.c
drivers/media/pci/cx23885/cx23885-i2c.c
drivers/media/pci/cx23885/cx23885-ioctl.c
drivers/media/pci/cx23885/cx23885-video.c
drivers/media/pci/cx23885/cx23888-ir.c
drivers/media/pci/cx25821/cx25821-alsa.c
drivers/media/pci/cx25821/cx25821-i2c.c
drivers/media/pci/cx25821/cx25821-video.c
drivers/media/pci/cx88/cx88-alsa.c
drivers/media/pci/cx88/cx88-blackbird.c
drivers/media/pci/cx88/cx88-cards.c
drivers/media/pci/cx88/cx88-i2c.c
drivers/media/pci/cx88/cx88-input.c
drivers/media/pci/cx88/cx88-video.c
drivers/media/pci/cx88/cx88-vp3054-i2c.c
drivers/media/pci/ddbridge/ddbridge-ci.c
drivers/media/pci/ddbridge/ddbridge-ci.h
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/ddbridge/ddbridge-hw.c
drivers/media/pci/ddbridge/ddbridge-hw.h
drivers/media/pci/ddbridge/ddbridge-i2c.c
drivers/media/pci/ddbridge/ddbridge-i2c.h
drivers/media/pci/ddbridge/ddbridge-io.h
drivers/media/pci/ddbridge/ddbridge-main.c
drivers/media/pci/ddbridge/ddbridge-max.c
drivers/media/pci/ddbridge/ddbridge-max.h
drivers/media/pci/ddbridge/ddbridge-regs.h
drivers/media/pci/ddbridge/ddbridge-sx8.c
drivers/media/pci/ddbridge/ddbridge.h
drivers/media/pci/dm1105/dm1105.c
drivers/media/pci/dt3155/dt3155.c
drivers/media/pci/intel/ipu3/ipu3-cio2.c
drivers/media/pci/ivtv/ivtv-alsa-main.c
drivers/media/pci/ivtv/ivtv-alsa-pcm.c
drivers/media/pci/ivtv/ivtv-cards.c
drivers/media/pci/ivtv/ivtv-i2c.c
drivers/media/pci/ivtv/ivtv-ioctl.c
drivers/media/pci/ivtv/ivtv-streams.c
drivers/media/pci/ivtv/ivtv-yuv.c
drivers/media/pci/ivtv/ivtvfb.c
drivers/media/pci/meye/meye.c
drivers/media/pci/ngene/ngene-i2c.c
drivers/media/pci/pluto2/pluto2.c
drivers/media/pci/pt1/pt1.c
drivers/media/pci/pt3/pt3.c
drivers/media/pci/saa7134/saa7134-alsa.c
drivers/media/pci/saa7134/saa7134-cards.c
drivers/media/pci/saa7134/saa7134-core.c
drivers/media/pci/saa7134/saa7134-empress.c
drivers/media/pci/saa7134/saa7134-go7007.c
drivers/media/pci/saa7134/saa7134-i2c.c
drivers/media/pci/saa7134/saa7134-input.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/saa7134/saa7134.h
drivers/media/pci/saa7146/mxb.c
drivers/media/pci/saa7164/saa7164-core.c
drivers/media/pci/saa7164/saa7164-dvb.c
drivers/media/pci/saa7164/saa7164-encoder.c
drivers/media/pci/saa7164/saa7164-i2c.c
drivers/media/pci/saa7164/saa7164-vbi.c
drivers/media/pci/smipcie/smipcie-main.c
drivers/media/pci/solo6x10/solo6x10-g723.c
drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
drivers/media/pci/solo6x10/solo6x10-v4l2.c
drivers/media/pci/sta2x11/sta2x11_vip.c
drivers/media/pci/ttpci/av7110.c
drivers/media/pci/ttpci/av7110_av.c
drivers/media/pci/ttpci/av7110_v4l.c
drivers/media/pci/ttpci/budget-core.c
drivers/media/pci/tw5864/tw5864-video.c
drivers/media/pci/tw68/tw68-video.c
drivers/media/pci/tw686x/tw686x-audio.c
drivers/media/pci/tw686x/tw686x-video.c
drivers/media/platform/Kconfig
drivers/media/platform/Makefile
drivers/media/platform/am437x/am437x-vpfe.c
drivers/media/platform/atmel/atmel-isc.c
drivers/media/platform/atmel/atmel-isi.c
drivers/media/platform/cadence/cdns-csi2rx.c
drivers/media/platform/cadence/cdns-csi2tx.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/davinci/isif.c
drivers/media/platform/davinci/vpbe_display.c
drivers/media/platform/davinci/vpbe_venc.c
drivers/media/platform/davinci/vpfe_capture.c
drivers/media/platform/davinci/vpif_capture.c
drivers/media/platform/davinci/vpif_display.c
drivers/media/platform/exynos-gsc/gsc-core.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/exynos4-is/common.c
drivers/media/platform/exynos4-is/fimc-capture.c
drivers/media/platform/exynos4-is/fimc-is-i2c.c
drivers/media/platform/exynos4-is/fimc-is.c
drivers/media/platform/exynos4-is/fimc-isp-video.c
drivers/media/platform/exynos4-is/fimc-lite.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/exynos4-is/media-dev.h
drivers/media/platform/exynos4-is/mipi-csis.c
drivers/media/platform/fsl-viu.c
drivers/media/platform/imx-pxp.c [new file with mode: 0644]
drivers/media/platform/imx-pxp.h [new file with mode: 0644]
drivers/media/platform/m2m-deinterlace.c
drivers/media/platform/marvell-ccic/cafe-driver.c
drivers/media/platform/marvell-ccic/mcam-core.c
drivers/media/platform/marvell-ccic/mmp-driver.c
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
drivers/media/platform/mtk-vpu/mtk_vpu.c
drivers/media/platform/mx2_emmaprp.c
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/omap3isp/ispccdc.c
drivers/media/platform/omap3isp/ispccp2.c
drivers/media/platform/omap3isp/ispcsi2.c
drivers/media/platform/omap3isp/isppreview.c
drivers/media/platform/omap3isp/ispresizer.c
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/pxa_camera.c
drivers/media/platform/qcom/camss/camss-video.c
drivers/media/platform/qcom/camss/camss.c
drivers/media/platform/qcom/camss/camss.h
drivers/media/platform/qcom/venus/helpers.c
drivers/media/platform/qcom/venus/vdec.c
drivers/media/platform/qcom/venus/venc.c
drivers/media/platform/rcar-vin/rcar-core.c
drivers/media/platform/rcar-vin/rcar-csi2.c
drivers/media/platform/rcar-vin/rcar-v4l2.c
drivers/media/platform/rcar_drif.c
drivers/media/platform/rcar_fdp1.c
drivers/media/platform/rcar_jpu.c
drivers/media/platform/renesas-ceu.c
drivers/media/platform/rockchip/rga/rga.c
drivers/media/platform/s3c-camif/camif-capture.c
drivers/media/platform/s3c-camif/camif-core.c
drivers/media/platform/s5p-jpeg/jpeg-core.c
drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
drivers/media/platform/sh_veu.c
drivers/media/platform/sh_vou.c
drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
drivers/media/platform/soc_camera/soc_camera.c
drivers/media/platform/soc_camera/soc_camera_platform.c
drivers/media/platform/soc_camera/soc_mediabus.c
drivers/media/platform/soc_camera/soc_scale_crop.c
drivers/media/platform/sti/bdisp/bdisp-v4l2.c
drivers/media/platform/sti/delta/delta-v4l2.c
drivers/media/platform/sti/hva/hva-v4l2.c
drivers/media/platform/stm32/stm32-dcmi.c
drivers/media/platform/ti-vpe/cal.c
drivers/media/platform/via-camera.c
drivers/media/platform/vicodec/Kconfig
drivers/media/platform/vicodec/Makefile
drivers/media/platform/vicodec/codec-fwht.c [new file with mode: 0644]
drivers/media/platform/vicodec/codec-fwht.h [new file with mode: 0644]
drivers/media/platform/vicodec/codec-v4l2-fwht.c [new file with mode: 0644]
drivers/media/platform/vicodec/codec-v4l2-fwht.h [new file with mode: 0644]
drivers/media/platform/vicodec/vicodec-codec.c [deleted file]
drivers/media/platform/vicodec/vicodec-codec.h [deleted file]
drivers/media/platform/vicodec/vicodec-core.c
drivers/media/platform/video-mux.c
drivers/media/platform/vim2m.c
drivers/media/platform/vimc/vimc-capture.c
drivers/media/platform/vimc/vimc-common.c
drivers/media/platform/vimc/vimc-core.c
drivers/media/platform/vimc/vimc-sensor.c
drivers/media/platform/vivid/vivid-cec.c
drivers/media/platform/vivid/vivid-core.c
drivers/media/platform/vivid/vivid-core.h
drivers/media/platform/vivid/vivid-ctrls.c
drivers/media/platform/vivid/vivid-kthread-cap.c
drivers/media/platform/vivid/vivid-kthread-out.c
drivers/media/platform/vivid/vivid-osd.c
drivers/media/platform/vivid/vivid-radio-common.c
drivers/media/platform/vivid/vivid-radio-rx.c
drivers/media/platform/vivid/vivid-radio-tx.c
drivers/media/platform/vivid/vivid-rds-gen.c
drivers/media/platform/vivid/vivid-sdr-cap.c
drivers/media/platform/vivid/vivid-vbi-cap.c
drivers/media/platform/vivid/vivid-vbi-out.c
drivers/media/platform/vivid/vivid-vid-cap.c
drivers/media/platform/vivid/vivid-vid-common.c
drivers/media/platform/vivid/vivid-vid-out.c
drivers/media/platform/vsp1/vsp1_brx.c
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_entity.c
drivers/media/platform/vsp1/vsp1_histo.c
drivers/media/platform/vsp1/vsp1_lif.c
drivers/media/platform/vsp1/vsp1_regs.h
drivers/media/platform/vsp1/vsp1_rpf.c
drivers/media/platform/vsp1/vsp1_sru.c
drivers/media/platform/vsp1/vsp1_uds.c
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/vsp1/vsp1_wpf.c
drivers/media/platform/xilinx/xilinx-dma.c
drivers/media/platform/xilinx/xilinx-tpg.c
drivers/media/platform/xilinx/xilinx-vipp.c
drivers/media/platform/xilinx/xilinx-vipp.h
drivers/media/radio/dsbr100.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-isa.c
drivers/media/radio/radio-keene.c
drivers/media/radio/radio-ma901.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-miropcm20.c
drivers/media/radio/radio-mr800.c
drivers/media/radio/radio-raremono.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-shark.c
drivers/media/radio/radio-shark2.c
drivers/media/radio/radio-si476x.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/radio-tea5777.c
drivers/media/radio/radio-timb.c
drivers/media/radio/radio-wl1273.c
drivers/media/radio/si470x/radio-si470x-common.c
drivers/media/radio/si470x/radio-si470x-i2c.c
drivers/media/radio/si470x/radio-si470x-usb.c
drivers/media/radio/si4713/radio-platform-si4713.c
drivers/media/radio/si4713/radio-usb-si4713.c
drivers/media/radio/tea575x.c
drivers/media/radio/tef6862.c
drivers/media/radio/wl128x/fmdrv_v4l2.c
drivers/media/rc/ati_remote.c
drivers/media/rc/ene_ir.c
drivers/media/rc/fintek-cir.c
drivers/media/rc/igorplugusb.c
drivers/media/rc/iguanair.c
drivers/media/rc/imon_raw.c
drivers/media/rc/ir-hix5hd2.c
drivers/media/rc/ir-imon-decoder.c
drivers/media/rc/ir-mce_kbd-decoder.c
drivers/media/rc/ir-rc6-decoder.c
drivers/media/rc/ite-cir.c
drivers/media/rc/keymaps/rc-behold.c
drivers/media/rc/keymaps/rc-delock-61959.c
drivers/media/rc/keymaps/rc-imon-rsc.c
drivers/media/rc/keymaps/rc-it913x-v1.c
drivers/media/rc/keymaps/rc-it913x-v2.c
drivers/media/rc/keymaps/rc-msi-digivox-iii.c
drivers/media/rc/keymaps/rc-pixelview-002t.c
drivers/media/rc/keymaps/rc-pixelview-mk12.c
drivers/media/rc/keymaps/rc-reddo.c
drivers/media/rc/keymaps/rc-terratec-slim.c
drivers/media/rc/keymaps/rc-tivo.c
drivers/media/rc/keymaps/rc-total-media-in-hand.c
drivers/media/rc/mceusb.c
drivers/media/rc/meson-ir.c
drivers/media/rc/mtk-cir.c
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/rc-core-priv.h
drivers/media/rc/rc-ir-raw.c
drivers/media/rc/rc-loopback.c
drivers/media/rc/rc-main.c
drivers/media/rc/redrat3.c
drivers/media/rc/serial_ir.c
drivers/media/rc/sir_ir.c
drivers/media/rc/st_rc.c
drivers/media/rc/streamzap.c
drivers/media/rc/sunxi-cir.c
drivers/media/rc/ttusbir.c
drivers/media/rc/winbond-cir.c
drivers/media/tuners/e4000.c
drivers/media/tuners/fc2580.c
drivers/media/tuners/msi001.c
drivers/media/tuners/mt20xx.c
drivers/media/tuners/si2157.c
drivers/media/tuners/si2157_priv.h
drivers/media/tuners/tuner-simple.c
drivers/media/usb/airspy/airspy.c
drivers/media/usb/au0828/au0828-core.c
drivers/media/usb/au0828/au0828-i2c.c
drivers/media/usb/au0828/au0828-input.c
drivers/media/usb/au0828/au0828-video.c
drivers/media/usb/cpia2/cpia2_v4l.c
drivers/media/usb/cx231xx/cx231xx-417.c
drivers/media/usb/cx231xx/cx231xx-audio.c
drivers/media/usb/cx231xx/cx231xx-input.c
drivers/media/usb/cx231xx/cx231xx-video.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/anysee.c
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
drivers/media/usb/dvb-usb-v2/dvbsky.c
drivers/media/usb/dvb-usb-v2/gl861.c
drivers/media/usb/dvb-usb-v2/lmedm04.c
drivers/media/usb/dvb-usb-v2/mxl111sf.c
drivers/media/usb/dvb-usb-v2/mxl111sf.h
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/zd1301.c
drivers/media/usb/dvb-usb/cxusb.c
drivers/media/usb/dvb-usb/dib0700_devices.c
drivers/media/usb/dvb-usb/dvb-usb-i2c.c
drivers/media/usb/dvb-usb/dw2102.c
drivers/media/usb/dvb-usb/technisat-usb2.c
drivers/media/usb/em28xx/em28xx-audio.c
drivers/media/usb/em28xx/em28xx-cards.c
drivers/media/usb/em28xx/em28xx-i2c.c
drivers/media/usb/em28xx/em28xx-video.c
drivers/media/usb/em28xx/em28xx.h
drivers/media/usb/go7007/go7007-driver.c
drivers/media/usb/go7007/go7007-v4l2.c
drivers/media/usb/go7007/snd-go7007.c
drivers/media/usb/gspca/gspca.c
drivers/media/usb/gspca/sn9c20x.c
drivers/media/usb/gspca/sq930x.c
drivers/media/usb/hackrf/hackrf.c
drivers/media/usb/hdpvr/hdpvr-video.c
drivers/media/usb/msi2500/msi2500.c
drivers/media/usb/pulse8-cec/pulse8-cec.c
drivers/media/usb/pvrusb2/pvrusb2-debug.h
drivers/media/usb/pvrusb2/pvrusb2-hdw.c
drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
drivers/media/usb/pvrusb2/pvrusb2-main.c
drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
drivers/media/usb/pwc/pwc-if.c
drivers/media/usb/pwc/pwc-v4l.c
drivers/media/usb/rainshadow-cec/rainshadow-cec.c
drivers/media/usb/s2255/s2255drv.c
drivers/media/usb/stk1160/stk1160-i2c.c
drivers/media/usb/stk1160/stk1160-v4l.c
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/tm6000/tm6000-alsa.c
drivers/media/usb/tm6000/tm6000-i2c.c
drivers/media/usb/tm6000/tm6000-video.c
drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/usb/usbtv/usbtv-audio.c
drivers/media/usb/usbtv/usbtv-video.c
drivers/media/usb/usbvision/usbvision-core.c
drivers/media/usb/usbvision/usbvision-video.c
drivers/media/usb/usbvision/usbvision.h
drivers/media/usb/uvc/uvc_ctrl.c
drivers/media/usb/uvc/uvc_debugfs.c
drivers/media/usb/uvc/uvc_driver.c
drivers/media/usb/uvc/uvc_entity.c
drivers/media/usb/uvc/uvc_metadata.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/usb/uvc/uvc_v4l2.c
drivers/media/usb/uvc/uvcvideo.h
drivers/media/usb/zr364xx/zr364xx.c
drivers/media/v4l2-core/tuner-core.c
drivers/media/v4l2-core/v4l2-async.c
drivers/media/v4l2-core/v4l2-common.c
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
drivers/media/v4l2-core/v4l2-ctrls.c
drivers/media/v4l2-core/v4l2-dev.c
drivers/media/v4l2-core/v4l2-device.c
drivers/media/v4l2-core/v4l2-dv-timings.c
drivers/media/v4l2-core/v4l2-flash-led-class.c
drivers/media/v4l2-core/v4l2-fwnode.c
drivers/media/v4l2-core/v4l2-ioctl.c
drivers/media/v4l2-core/v4l2-mc.c
drivers/media/v4l2-core/v4l2-mem2mem.c
drivers/media/v4l2-core/v4l2-subdev.c
drivers/memory/atmel-ebi.c
drivers/mfd/cros_ec_dev.h
drivers/misc/eeprom/at24.c
drivers/mtd/ar7part.c
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com90io.c
drivers/of/base.c
drivers/of/fdt.c
drivers/of/of_reserved_mem.c
drivers/of/unittest.c
drivers/platform/chrome/chromeos_tbmc.c
drivers/platform/chrome/cros_ec_lpc.c
drivers/platform/chrome/cros_ec_lpc_mec.c
drivers/platform/chrome/cros_ec_lpc_mec.h [new file with mode: 0644]
drivers/platform/chrome/cros_ec_lpc_reg.c
drivers/platform/chrome/cros_ec_lpc_reg.h [new file with mode: 0644]
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/acerhdf.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/dcdbas.c [new file with mode: 0644]
drivers/platform/x86/dcdbas.h [new file with mode: 0644]
drivers/platform/x86/dell-smbios-smm.c
drivers/platform/x86/dell_rbu.c [new file with mode: 0644]
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel-hid.c
drivers/platform/x86/intel-rst.c
drivers/platform/x86/intel-smartconnect.c
drivers/platform/x86/intel-wmi-thunderbolt.c
drivers/platform/x86/intel_atomisp2_pm.c [new file with mode: 0644]
drivers/platform/x86/intel_bxtwc_tmu.c
drivers/platform/x86/intel_cht_int33fe.c
drivers/platform/x86/intel_chtdc_ti_pwrbtn.c
drivers/platform/x86/intel_int0002_vgpio.c
drivers/platform/x86/intel_ips.c
drivers/platform/x86/intel_ips.h
drivers/platform/x86/intel_menlow.c
drivers/platform/x86/intel_mid_powerbtn.c
drivers/platform/x86/intel_mid_thermal.c
drivers/platform/x86/intel_oaktrail.c
drivers/platform/x86/intel_pmc_core.c
drivers/platform/x86/intel_pmc_core.h
drivers/platform/x86/intel_pmc_ipc.c
drivers/platform/x86/intel_punit_ipc.c
drivers/platform/x86/intel_scu_ipc.c
drivers/platform/x86/intel_scu_ipcutil.c
drivers/platform/x86/intel_telemetry_core.c
drivers/platform/x86/intel_telemetry_debugfs.c
drivers/platform/x86/intel_telemetry_pltdrv.c
drivers/platform/x86/intel_turbo_max_3.c
drivers/platform/x86/lg-laptop.c [new file with mode: 0644]
drivers/platform/x86/mlx-platform.c
drivers/platform/x86/touchscreen_dmi.c
drivers/platform/x86/wmi.c
drivers/remoteproc/Kconfig
drivers/remoteproc/Makefile
drivers/remoteproc/da8xx_remoteproc.c
drivers/remoteproc/qcom_adsp_pil.c [deleted file]
drivers/remoteproc/qcom_q6v5.c
drivers/remoteproc/qcom_q6v5_adsp.c [new file with mode: 0644]
drivers/remoteproc/qcom_q6v5_mss.c [new file with mode: 0644]
drivers/remoteproc/qcom_q6v5_pas.c [new file with mode: 0644]
drivers/remoteproc/qcom_q6v5_pil.c [deleted file]
drivers/remoteproc/remoteproc_core.c
drivers/remoteproc/remoteproc_debugfs.c
drivers/remoteproc/remoteproc_internal.h
drivers/remoteproc/remoteproc_sysfs.c
drivers/remoteproc/remoteproc_virtio.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/core.c
drivers/reset/reset-qcom-pdc.c [new file with mode: 0644]
drivers/rpmsg/qcom_glink_native.c
drivers/rpmsg/qcom_glink_smem.c
drivers/rpmsg/qcom_smd.c
drivers/rpmsg/rpmsg_char.c
drivers/s390/char/fs3270.c
drivers/s390/char/tty3270.c
drivers/s390/cio/cmf.c
drivers/s390/virtio/virtio_ccw.c
drivers/sfi/sfi_core.c
drivers/soc/Makefile
drivers/soc/actions/Kconfig
drivers/soc/actions/Makefile
drivers/soc/actions/owl-sps-helper.c
drivers/soc/actions/owl-sps.c
drivers/soc/amlogic/Kconfig
drivers/soc/amlogic/Makefile
drivers/soc/amlogic/meson-canvas.c [new file with mode: 0644]
drivers/soc/fsl/dpio/dpio-driver.c
drivers/soc/fsl/qbman/Kconfig
drivers/soc/fsl/qbman/bman.c
drivers/soc/fsl/qbman/bman_portal.c
drivers/soc/fsl/qbman/dpaa_sys.h
drivers/soc/fsl/qbman/qman.c
drivers/soc/fsl/qbman/qman_portal.c
drivers/soc/fsl/qe/qe.c
drivers/soc/imx/gpc.c
drivers/soc/imx/gpcv2.c
drivers/soc/mediatek/mtk-pmic-wrap.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/apr.c
drivers/soc/qcom/llcc-slice.c
drivers/soc/qcom/rmtfs_mem.c
drivers/soc/qcom/rpmh-rsc.c
drivers/soc/qcom/smem.c
drivers/soc/qcom/spm.c
drivers/soc/qcom/wcnss_ctrl.c
drivers/soc/renesas/Kconfig
drivers/soc/renesas/Makefile
drivers/soc/renesas/r8a7743-sysc.c
drivers/soc/renesas/r8a7745-sysc.c
drivers/soc/renesas/r8a774a1-sysc.c [new file with mode: 0644]
drivers/soc/renesas/r8a774c0-sysc.c [new file with mode: 0644]
drivers/soc/renesas/r8a7779-sysc.c
drivers/soc/renesas/r8a7790-sysc.c
drivers/soc/renesas/r8a7791-sysc.c
drivers/soc/renesas/r8a7792-sysc.c
drivers/soc/renesas/r8a7794-sysc.c
drivers/soc/renesas/r8a7795-sysc.c
drivers/soc/renesas/r8a7796-sysc.c
drivers/soc/renesas/r8a77970-sysc.c
drivers/soc/renesas/r8a77995-sysc.c
drivers/soc/renesas/rcar-rst.c
drivers/soc/renesas/rcar-sysc.c
drivers/soc/renesas/rcar-sysc.h
drivers/soc/renesas/renesas-soc.c
drivers/soc/tegra/pmc.c
drivers/soc/ti/knav_dma.c
drivers/soc/ti/knav_qmss.h
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/ion/Kconfig
drivers/staging/android/ion/ion.h
drivers/staging/android/ion/ion_system_heap.c
drivers/staging/axis-fifo/axis-fifo.c
drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
drivers/staging/comedi/Kconfig
drivers/staging/comedi/comedi.h
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/comedidev.h
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/Makefile
drivers/staging/comedi/drivers/comedi_test.c
drivers/staging/comedi/drivers/ni_660x.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/comedi/drivers/ni_pcimio.c
drivers/staging/comedi/drivers/ni_routes.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routes.h [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/README [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_route_values.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_route_values.h [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/tools/.gitignore [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/tools/Makefile [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py [new file with mode: 0755]
drivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py [new file with mode: 0755]
drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py [new file with mode: 0755]
drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py [new file with mode: 0644]
drivers/staging/comedi/drivers/ni_stc.h
drivers/staging/comedi/drivers/ni_tio.c
drivers/staging/comedi/drivers/ni_tio.h
drivers/staging/comedi/drivers/ni_tio_internal.h
drivers/staging/comedi/drivers/ni_tiocmd.c
drivers/staging/comedi/drivers/tests/Makefile [new file with mode: 0644]
drivers/staging/comedi/drivers/tests/example_test.c [new file with mode: 0644]
drivers/staging/comedi/drivers/tests/ni_routes_test.c [new file with mode: 0644]
drivers/staging/comedi/drivers/tests/unittest.h [new file with mode: 0644]
drivers/staging/dgnc/Kconfig [deleted file]
drivers/staging/dgnc/Makefile [deleted file]
drivers/staging/dgnc/TODO [deleted file]
drivers/staging/dgnc/dgnc_cls.c [deleted file]
drivers/staging/dgnc/dgnc_cls.h [deleted file]
drivers/staging/dgnc/dgnc_driver.c [deleted file]
drivers/staging/dgnc/dgnc_driver.h [deleted file]
drivers/staging/dgnc/dgnc_tty.c [deleted file]
drivers/staging/dgnc/dgnc_tty.h [deleted file]
drivers/staging/dgnc/digi.h [deleted file]
drivers/staging/emxx_udc/emxx_udc.c
drivers/staging/erofs/Kconfig
drivers/staging/erofs/data.c
drivers/staging/erofs/dir.c
drivers/staging/erofs/erofs_fs.h
drivers/staging/erofs/include/trace/events/erofs.h
drivers/staging/erofs/inode.c
drivers/staging/erofs/internal.h
drivers/staging/erofs/namei.c
drivers/staging/erofs/super.c
drivers/staging/erofs/unzip_vle.c
drivers/staging/erofs/unzip_vle.h
drivers/staging/erofs/unzip_vle_lz4.c
drivers/staging/erofs/utils.c
drivers/staging/erofs/xattr.c
drivers/staging/fbtft/fbtft.h
drivers/staging/fsl-dpaa2/ethsw/ethsw.c
drivers/staging/gasket/Kconfig
drivers/staging/gasket/apex_driver.c
drivers/staging/gasket/gasket_core.c
drivers/staging/gasket/gasket_core.h
drivers/staging/gasket/gasket_interrupt.c
drivers/staging/gasket/gasket_interrupt.h
drivers/staging/gasket/gasket_page_table.c
drivers/staging/gasket/gasket_sysfs.h
drivers/staging/greybus/audio_codec.c
drivers/staging/greybus/loopback.c
drivers/staging/greybus/tools/README.loopback
drivers/staging/greybus/tools/loopback_test.c
drivers/staging/iio/adc/Kconfig
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/adc/ad7280a.c
drivers/staging/iio/adc/ad7606.c
drivers/staging/iio/adc/ad7606.h
drivers/staging/iio/adc/ad7606_par.c
drivers/staging/iio/adc/ad7606_spi.c
drivers/staging/iio/adc/ad7780.c
drivers/staging/iio/cdc/ad7746.c
drivers/staging/iio/frequency/ad9832.c
drivers/staging/iio/frequency/ad9834.c
drivers/staging/iio/impedance-analyzer/ad5933.c
drivers/staging/ks7010/ks_hostif.c
drivers/staging/media/Kconfig
drivers/staging/media/Makefile
drivers/staging/media/bcm2048/radio-bcm2048.c
drivers/staging/media/davinci_vpfe/dm365_ipipe.c
drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
drivers/staging/media/davinci_vpfe/dm365_isif.c
drivers/staging/media/davinci_vpfe/dm365_resizer.c
drivers/staging/media/davinci_vpfe/dm365_resizer.h
drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
drivers/staging/media/davinci_vpfe/vpfe_video.c
drivers/staging/media/imx/TODO
drivers/staging/media/imx/imx-media-capture.c
drivers/staging/media/imx/imx-media-csi.c
drivers/staging/media/imx/imx-media-dev.c
drivers/staging/media/imx/imx-media-fim.c
drivers/staging/media/imx/imx-media-internal-sd.c
drivers/staging/media/imx/imx-media-of.c
drivers/staging/media/imx/imx-media-utils.c
drivers/staging/media/imx/imx-media.h
drivers/staging/media/imx/imx6-mipi-csi2.c
drivers/staging/media/imx074/imx074.c
drivers/staging/media/mt9t031/mt9t031.c
drivers/staging/media/omap4iss/Kconfig
drivers/staging/media/omap4iss/Makefile
drivers/staging/media/omap4iss/iss.c
drivers/staging/media/omap4iss/iss.h
drivers/staging/media/omap4iss/iss_csi2.c
drivers/staging/media/omap4iss/iss_csi2.h
drivers/staging/media/omap4iss/iss_csiphy.c
drivers/staging/media/omap4iss/iss_csiphy.h
drivers/staging/media/omap4iss/iss_ipipe.c
drivers/staging/media/omap4iss/iss_ipipe.h
drivers/staging/media/omap4iss/iss_ipipeif.c
drivers/staging/media/omap4iss/iss_ipipeif.h
drivers/staging/media/omap4iss/iss_regs.h
drivers/staging/media/omap4iss/iss_resizer.c
drivers/staging/media/omap4iss/iss_resizer.h
drivers/staging/media/omap4iss/iss_video.c
drivers/staging/media/omap4iss/iss_video.h
drivers/staging/media/sunxi/Kconfig [new file with mode: 0644]
drivers/staging/media/sunxi/Makefile [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/Kconfig [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/Makefile [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/TODO [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus.c [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus.h [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_dec.c [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_dec.h [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_hw.c [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_hw.h [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_regs.h [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_video.c [new file with mode: 0644]
drivers/staging/media/sunxi/cedrus/cedrus_video.h [new file with mode: 0644]
drivers/staging/media/zoran/zoran_card.c
drivers/staging/media/zoran/zoran_driver.c
drivers/staging/most/cdev/cdev.c
drivers/staging/most/core.c
drivers/staging/most/net/net.c
drivers/staging/most/usb/usb.c
drivers/staging/most/video/video.c
drivers/staging/mt7621-dma/ralink-gdma.c
drivers/staging/mt7621-eth/gsw_mt7621.c
drivers/staging/mt7621-eth/mdio.c
drivers/staging/mt7621-eth/mtk_eth_soc.c
drivers/staging/mt7621-mmc/dbg.c
drivers/staging/mt7621-mmc/dbg.h
drivers/staging/mt7621-mmc/sd.c
drivers/staging/mt7621-pci/pci-mt7621.c
drivers/staging/octeon-usb/octeon-hcd.c
drivers/staging/olpc_dcon/Kconfig
drivers/staging/olpc_dcon/olpc_dcon.c
drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
drivers/staging/pi433/rf69.c
drivers/staging/rtl8188eu/Makefile
drivers/staging/rtl8188eu/TODO
drivers/staging/rtl8188eu/core/rtw_ap.c
drivers/staging/rtl8188eu/core/rtw_cmd.c
drivers/staging/rtl8188eu/core/rtw_debug.c
drivers/staging/rtl8188eu/core/rtw_efuse.c
drivers/staging/rtl8188eu/core/rtw_ieee80211.c
drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
drivers/staging/rtl8188eu/core/rtw_led.c
drivers/staging/rtl8188eu/core/rtw_mlme.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
drivers/staging/rtl8188eu/core/rtw_recv.c
drivers/staging/rtl8188eu/core/rtw_security.c
drivers/staging/rtl8188eu/core/rtw_wlan_util.c
drivers/staging/rtl8188eu/core/rtw_xmit.c
drivers/staging/rtl8188eu/hal/bb_cfg.c
drivers/staging/rtl8188eu/hal/fw.c
drivers/staging/rtl8188eu/hal/hal8188e_rate_adaptive.c
drivers/staging/rtl8188eu/hal/hal_com.c
drivers/staging/rtl8188eu/hal/odm.c
drivers/staging/rtl8188eu/hal/odm_HWConfig.c [deleted file]
drivers/staging/rtl8188eu/hal/odm_hwconfig.c [new file with mode: 0644]
drivers/staging/rtl8188eu/hal/odm_rtl8188e.c
drivers/staging/rtl8188eu/hal/phy.c
drivers/staging/rtl8188eu/hal/pwrseq.c
drivers/staging/rtl8188eu/hal/rf_cfg.c
drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
drivers/staging/rtl8188eu/hal/usb_halinit.c
drivers/staging/rtl8188eu/include/drv_types.h
drivers/staging/rtl8188eu/include/hal_com.h
drivers/staging/rtl8188eu/include/odm_HWConfig.h [deleted file]
drivers/staging/rtl8188eu/include/odm_hwconfig.h [new file with mode: 0644]
drivers/staging/rtl8188eu/include/odm_precomp.h
drivers/staging/rtl8188eu/include/odm_reg.h [deleted file]
drivers/staging/rtl8188eu/include/osdep_service.h
drivers/staging/rtl8188eu/include/phy.h
drivers/staging/rtl8188eu/include/rtw_mlme.h
drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
drivers/staging/rtl8188eu/include/rtw_qos.h [deleted file]
drivers/staging/rtl8188eu/include/wifi.h
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8188eu/os_dep/mlme_linux.c
drivers/staging/rtl8188eu/os_dep/os_intfs.c
drivers/staging/rtl8188eu/os_dep/osdep_service.c
drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
drivers/staging/rtl8188eu/os_dep/xmit_linux.c
drivers/staging/rtl8192e/rtllib_softmac.c
drivers/staging/rtl8192u/ieee80211/dot11d.c
drivers/staging/rtl8192u/ieee80211/dot11d.h
drivers/staging/rtl8192u/ieee80211/ieee80211.h
drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
drivers/staging/rtl8192u/ieee80211/rtl819x_BA.h
drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
drivers/staging/rtl8192u/ieee80211/rtl819x_HT.h
drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
drivers/staging/rtl8192u/ieee80211/rtl819x_TS.h
drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
drivers/staging/rtl8192u/r8180_93cx6.h
drivers/staging/rtl8192u/r8190_rtl8256.c
drivers/staging/rtl8192u/r8190_rtl8256.h
drivers/staging/rtl8192u/r8192U.h
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rtl8192u/r8192U_hw.h
drivers/staging/rtl8192u/r819xU_firmware.c
drivers/staging/rtl8192u/r819xU_firmware.h
drivers/staging/rtl8192u/r819xU_phy.c
drivers/staging/rtl8192u/r819xU_phy.h
drivers/staging/rtl8712/basic_types.h
drivers/staging/rtl8712/drv_types.h
drivers/staging/rtl8712/ethernet.h
drivers/staging/rtl8712/hal_init.c
drivers/staging/rtl8712/ieee80211.c
drivers/staging/rtl8712/ieee80211.h
drivers/staging/rtl8712/mlme_linux.c
drivers/staging/rtl8712/mlme_osdep.h
drivers/staging/rtl8712/mp_custom_oid.h
drivers/staging/rtl8712/os_intfs.c
drivers/staging/rtl8712/osdep_intf.h
drivers/staging/rtl8712/osdep_service.h
drivers/staging/rtl8712/recv_linux.c
drivers/staging/rtl8712/recv_osdep.h
drivers/staging/rtl8712/rtl8712_bitdef.h
drivers/staging/rtl8712/rtl8712_cmd.c
drivers/staging/rtl8712/rtl8712_cmd.h
drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h
drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h
drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h
drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h
drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h
drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h
drivers/staging/rtl8712/rtl8712_efuse.c
drivers/staging/rtl8712/rtl8712_event.h
drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h
drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h
drivers/staging/rtl8712/rtl8712_gp_bitdef.h
drivers/staging/rtl8712/rtl8712_gp_regdef.h
drivers/staging/rtl8712/rtl8712_hal.h
drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h
drivers/staging/rtl8712/rtl8712_io.c
drivers/staging/rtl8712/rtl8712_led.c
drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h
drivers/staging/rtl8712/rtl8712_macsetting_regdef.h
drivers/staging/rtl8712/rtl8712_powersave_bitdef.h
drivers/staging/rtl8712/rtl8712_powersave_regdef.h
drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h
drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h
drivers/staging/rtl8712/rtl8712_recv.c
drivers/staging/rtl8712/rtl8712_recv.h
drivers/staging/rtl8712/rtl8712_regdef.h
drivers/staging/rtl8712/rtl8712_security_bitdef.h
drivers/staging/rtl8712/rtl8712_spec.h
drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h
drivers/staging/rtl8712/rtl8712_syscfg_regdef.h
drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h
drivers/staging/rtl8712/rtl8712_timectrl_regdef.h
drivers/staging/rtl8712/rtl8712_wmac_bitdef.h
drivers/staging/rtl8712/rtl8712_wmac_regdef.h
drivers/staging/rtl8712/rtl8712_xmit.c
drivers/staging/rtl8712/rtl8712_xmit.h
drivers/staging/rtl8712/rtl871x_cmd.c
drivers/staging/rtl8712/rtl871x_cmd.h
drivers/staging/rtl8712/rtl871x_debug.h
drivers/staging/rtl8712/rtl871x_eeprom.c
drivers/staging/rtl8712/rtl871x_eeprom.h
drivers/staging/rtl8712/rtl871x_event.h
drivers/staging/rtl8712/rtl871x_ht.h
drivers/staging/rtl8712/rtl871x_io.c
drivers/staging/rtl8712/rtl871x_io.h
drivers/staging/rtl8712/rtl871x_ioctl_linux.c
drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
drivers/staging/rtl8712/rtl871x_ioctl_rtl.h
drivers/staging/rtl8712/rtl871x_ioctl_set.c
drivers/staging/rtl8712/rtl871x_ioctl_set.h
drivers/staging/rtl8712/rtl871x_led.h
drivers/staging/rtl8712/rtl871x_mlme.c
drivers/staging/rtl8712/rtl871x_mlme.h
drivers/staging/rtl8712/rtl871x_mp.c
drivers/staging/rtl8712/rtl871x_mp.h
drivers/staging/rtl8712/rtl871x_mp_ioctl.c
drivers/staging/rtl8712/rtl871x_mp_ioctl.h
drivers/staging/rtl8712/rtl871x_pwrctrl.c
drivers/staging/rtl8712/rtl871x_pwrctrl.h
drivers/staging/rtl8712/rtl871x_recv.c
drivers/staging/rtl8712/rtl871x_rf.h
drivers/staging/rtl8712/rtl871x_security.c
drivers/staging/rtl8712/rtl871x_security.h
drivers/staging/rtl8712/rtl871x_sta_mgt.c
drivers/staging/rtl8712/rtl871x_wlan_sme.h
drivers/staging/rtl8712/rtl871x_xmit.c
drivers/staging/rtl8712/rtl871x_xmit.h
drivers/staging/rtl8712/sta_info.h
drivers/staging/rtl8712/usb_halinit.c
drivers/staging/rtl8712/usb_intf.c
drivers/staging/rtl8712/usb_ops.c
drivers/staging/rtl8712/usb_ops.h
drivers/staging/rtl8712/usb_ops_linux.c
drivers/staging/rtl8712/usb_osintf.h
drivers/staging/rtl8712/wifi.h
drivers/staging/rtl8712/wlan_bssdef.h
drivers/staging/rtl8712/xmit_linux.c
drivers/staging/rtl8712/xmit_osdep.h
drivers/staging/rtl8723bs/core/rtw_ap.c
drivers/staging/rtl8723bs/core/rtw_debug.c
drivers/staging/rtl8723bs/core/rtw_mlme.c
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
drivers/staging/rtl8723bs/core/rtw_security.c
drivers/staging/rtl8723bs/hal/hal_com_phycfg.c
drivers/staging/rtl8723bs/hal/odm_DIG.c
drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c
drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
drivers/staging/rtl8723bs/include/drv_types.h
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
drivers/staging/rtl8723bs/os_dep/sdio_intf.c
drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c
drivers/staging/rtlwifi/efuse.c
drivers/staging/rtlwifi/halmac/rtl_halmac.c
drivers/staging/rtlwifi/phydm/phydm_adc_sampling.c
drivers/staging/rtlwifi/phydm/phydm_dig.c
drivers/staging/rtlwifi/regd.c
drivers/staging/rtlwifi/wifi.h
drivers/staging/rts5208/ms.c
drivers/staging/rts5208/rtsx_card.c
drivers/staging/rts5208/rtsx_card.h
drivers/staging/rts5208/rtsx_chip.c
drivers/staging/rts5208/rtsx_scsi.c
drivers/staging/rts5208/sd.c
drivers/staging/rts5208/spi.c
drivers/staging/rts5208/xd.c
drivers/staging/sm750fb/ddk750_mode.c
drivers/staging/sm750fb/ddk750_sii164.c
drivers/staging/sm750fb/sm750.c
drivers/staging/speakup/spk_ttyio.c
drivers/staging/vboxvideo/TODO
drivers/staging/vboxvideo/vbox_drv.c
drivers/staging/vboxvideo/vbox_drv.h
drivers/staging/vboxvideo/vbox_fb.c
drivers/staging/vboxvideo/vbox_irq.c
drivers/staging/vboxvideo/vbox_main.c
drivers/staging/vboxvideo/vbox_mode.c
drivers/staging/vboxvideo/vbox_ttm.c
drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c
drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
drivers/staging/vc04_services/bcm2835-camera/TODO
drivers/staging/vc04_services/bcm2835-camera/controls.c
drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
drivers/staging/vc04_services/interface/vchi/connections/connection.h [deleted file]
drivers/staging/vc04_services/interface/vchi/message_drivers/message.h [deleted file]
drivers/staging/vc04_services/interface/vchi/vchi.h
drivers/staging/vc04_services/interface/vchi/vchi_cfg.h
drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h [deleted file]
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion [deleted file]
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
drivers/staging/vt6655/rxtx.c
drivers/staging/wilc1000/Kconfig
drivers/staging/wilc1000/Makefile
drivers/staging/wilc1000/coreconfigurator.c
drivers/staging/wilc1000/host_interface.c
drivers/staging/wilc1000/host_interface.h
drivers/staging/wilc1000/linux_mon.c
drivers/staging/wilc1000/linux_wlan.c
drivers/staging/wilc1000/wilc_debugfs.c [deleted file]
drivers/staging/wilc1000/wilc_sdio.c
drivers/staging/wilc1000/wilc_spi.c
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
drivers/staging/wilc1000/wilc_wfi_netdevice.h
drivers/staging/wilc1000/wilc_wlan.c
drivers/staging/wilc1000/wilc_wlan.h
drivers/staging/wilc1000/wilc_wlan_cfg.c
drivers/staging/wilc1000/wilc_wlan_cfg.h
drivers/staging/wilc1000/wilc_wlan_if.h
drivers/staging/wlan-ng/cfg80211.c
drivers/staging/wlan-ng/hfa384x_usb.c
drivers/staging/wlan-ng/p80211conv.c
drivers/staging/wlan-ng/p80211metadef.h
drivers/staging/wlan-ng/p80211metastruct.h
drivers/staging/wlan-ng/p80211netdev.c
drivers/staging/wlan-ng/p80211req.c
drivers/staging/wlan-ng/prism2fw.c
drivers/staging/wlan-ng/prism2mib.c
drivers/staging/wlan-ng/prism2sta.c
drivers/tee/optee/core.c
drivers/tee/tee_core.c
drivers/thermal/thermal_core.c
drivers/tty/ehv_bytechan.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_of.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/8250/8250_uniphier.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/atmel_serial.h
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c
drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/kgdboc.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/samsung.c
drivers/tty/serial/sc16is7xx.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sn_console.c
drivers/tty/serial/sprd_serial.c
drivers/tty/serial/uartlite.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/tty_buffer.c
drivers/tty/tty_io.c
drivers/tty/tty_port.c
drivers/usb/early/xhci-dbc.c
drivers/usb/gadget/function/uvc_queue.c
drivers/vfio/Kconfig
drivers/vfio/pci/vfio_pci.c
drivers/vfio/pci/vfio_pci_config.c
drivers/video/backlight/as3711_bl.c
drivers/video/fbdev/Kconfig
drivers/video/fbdev/Makefile
drivers/video/fbdev/arcfb.c
drivers/video/fbdev/atmel_lcdfb.c
drivers/video/fbdev/aty/atyfb.h
drivers/video/fbdev/aty/atyfb_base.c
drivers/video/fbdev/aty/mach64_accel.c
drivers/video/fbdev/cg14.c
drivers/video/fbdev/cg3.c
drivers/video/fbdev/clps711xfb.c [deleted file]
drivers/video/fbdev/core/fbmon.c
drivers/video/fbdev/imsttfb.c
drivers/video/fbdev/leo.c
drivers/video/fbdev/mmp/hw/Kconfig
drivers/video/fbdev/mmp/panel/Kconfig
drivers/video/fbdev/offb.c
drivers/video/fbdev/omap/lcd_ams_delta.c
drivers/video/fbdev/omap2/omapfb/dss/Kconfig
drivers/video/fbdev/p9100.c
drivers/video/fbdev/pxa168fb.c
drivers/video/fbdev/sbuslib.c
drivers/video/fbdev/sh7760fb.c
drivers/video/fbdev/sis/init301.c
drivers/video/fbdev/ssd1307fb.c
drivers/video/fbdev/udlfb.c
drivers/video/hdmi.c
drivers/video/of_display_timing.c
drivers/video/vgastate.c
drivers/xen/Kconfig
drivers/xen/balloon.c
drivers/xen/events/events_base.c
drivers/xen/grant-table.c
drivers/xen/swiotlb-xen.c
drivers/xen/xen-balloon.c
drivers/xen/xen-selfballoon.c
drivers/xen/xenbus/xenbus_client.c
fs/9p/acl.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_dir.c
fs/9p/vfs_file.c
fs/btrfs/ctree.c
fs/btrfs/delayed-ref.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/ceph/acl.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/super.c
fs/ceph/super.h
fs/ceph/xattr.c
fs/compat_ioctl.c
fs/cramfs/inode.c
fs/dcache.c
fs/ext2/acl.c
fs/ext2/ext2.h
fs/ext2/super.c
fs/fat/dir.c
fs/fat/fat.h
fs/fat/file.c
fs/fat/inode.c
fs/fat/misc.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/fuse/Makefile
fs/fuse/control.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/fuse/readdir.c [new file with mode: 0644]
fs/hfs/brec.c
fs/hfs/btree.c
fs/hfs/btree.h
fs/hfs/catalog.c
fs/hfs/extent.c
fs/hfs/inode.c
fs/hfsplus/attributes.c
fs/hfsplus/brec.c
fs/hfsplus/btree.c
fs/hfsplus/catalog.c
fs/hfsplus/extents.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/inode.c
fs/inode.c
fs/lockd/host.c
fs/namespace.c
fs/nfs/dns_resolve.c
fs/nfsd/cache.h
fs/nfsd/export.c
fs/nfsd/export.h
fs/nfsd/netns.h
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4idmap.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfscache.c
fs/nfsd/nfsctl.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/nfsd/xdr4.h
fs/nfsd/xdr4cb.h
fs/notify/fanotify/fanotify.c
fs/notify/fanotify/fanotify.h
fs/notify/fanotify/fanotify_user.c
fs/notify/fdinfo.c
fs/notify/fsnotify.c
fs/notify/fsnotify.h
fs/notify/inotify/inotify_user.c
fs/notify/mark.c
fs/proc/kcore.c
fs/proc/page.c
fs/proc/vmcore.c
fs/pstore/Kconfig
fs/reiserfs/Makefile
fs/reiserfs/xattr.c
fs/super.c
fs/udf/balloc.c
fs/udf/super.c
fs/udf/udf_sb.h
include/asm-generic/percpu.h
include/dt-bindings/clock/am3.h
include/dt-bindings/clock/am4.h
include/dt-bindings/clock/at91.h
include/dt-bindings/clock/dra7.h
include/dt-bindings/clock/exynos4.h
include/dt-bindings/clock/hi3670-clock.h [new file with mode: 0644]
include/dt-bindings/clock/imx6qdl-clock.h
include/dt-bindings/clock/imx6sl-clock.h
include/dt-bindings/clock/imx6sll-clock.h
include/dt-bindings/clock/imx6sx-clock.h
include/dt-bindings/clock/imx6ul-clock.h
include/dt-bindings/clock/jz4725b-cgu.h [new file with mode: 0644]
include/dt-bindings/clock/maxim,max77686.h
include/dt-bindings/clock/maxim,max77802.h
include/dt-bindings/clock/qcom,camcc-sdm845.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-msm8960.h
include/dt-bindings/clock/qcom,gcc-msm8996.h
include/dt-bindings/clock/qcom,gcc-qcs404.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-sdm660.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-sdm845.h
include/dt-bindings/clock/r7s72100-clock.h
include/dt-bindings/clock/r7s9210-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7743-cpg-mssr.h
include/dt-bindings/clock/r8a7744-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7745-cpg-mssr.h
include/dt-bindings/clock/r8a774a1-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a774c0-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7790-cpg-mssr.h
include/dt-bindings/clock/r8a7791-cpg-mssr.h
include/dt-bindings/clock/r8a7792-cpg-mssr.h
include/dt-bindings/clock/r8a7793-clock.h
include/dt-bindings/clock/r8a7793-cpg-mssr.h
include/dt-bindings/clock/r8a7794-clock.h
include/dt-bindings/clock/r8a7794-cpg-mssr.h
include/dt-bindings/clock/r8a7795-cpg-mssr.h
include/dt-bindings/clock/r8a7796-cpg-mssr.h
include/dt-bindings/clock/r8a77970-cpg-mssr.h
include/dt-bindings/clock/r8a77995-cpg-mssr.h
include/dt-bindings/clock/renesas-cpg-mssr.h
include/dt-bindings/clock/rk3188-cru-common.h
include/dt-bindings/clock/samsung,s2mps11.h
include/dt-bindings/clock/samsung,s3c64xx-clock.h
include/dt-bindings/clock/sun50i-a64-ccu.h
include/dt-bindings/clock/xlnx,zynqmp-clk.h [new file with mode: 0644]
include/dt-bindings/iio/qcom,spmi-vadc.h
include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h [new file with mode: 0644]
include/dt-bindings/power/owl-s900-powergate.h [new file with mode: 0644]
include/dt-bindings/power/r8a7744-sysc.h [new file with mode: 0644]
include/dt-bindings/power/r8a774a1-sysc.h [new file with mode: 0644]
include/dt-bindings/power/r8a774c0-sysc.h [new file with mode: 0644]
include/dt-bindings/reset/actions,s700-reset.h [new file with mode: 0644]
include/dt-bindings/reset/actions,s900-reset.h [new file with mode: 0644]
include/dt-bindings/reset/qcom,sdm845-pdc.h [new file with mode: 0644]
include/linux/bitmap.h
include/linux/bitops.h
include/linux/bootmem.h [deleted file]
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
include/linux/ceph/msgpool.h
include/linux/ceph/osd_client.h
include/linux/ceph/pagelist.h
include/linux/ceph/rados.h
include/linux/clk-provider.h
include/linux/clk.h
include/linux/clk/renesas.h
include/linux/clk/ti.h
include/linux/compat.h
include/linux/fanotify.h
include/linux/firmware/imx/ipc.h [new file with mode: 0644]
include/linux/firmware/imx/sci.h [new file with mode: 0644]
include/linux/firmware/imx/svc/misc.h [new file with mode: 0644]
include/linux/firmware/imx/types.h [new file with mode: 0644]
include/linux/firmware/meson/meson_sm.h
include/linux/firmware/xlnx-zynqmp.h [new file with mode: 0644]
include/linux/fs.h
include/linux/fsnotify_backend.h
include/linux/hdmi.h
include/linux/hmm.h
include/linux/memblock.h
include/linux/memory_hotplug.h
include/linux/mfd/cros_ec.h
include/linux/mfd/cros_ec_commands.h
include/linux/mfd/cros_ec_lpc_mec.h [deleted file]
include/linux/mfd/cros_ec_lpc_reg.h [deleted file]
include/linux/mm.h
include/linux/mmzone.h
include/linux/of.h
include/linux/percpu-defs.h
include/linux/platform_data/gpio-omap.h
include/linux/platform_data/ti-sysc.h
include/linux/platform_data/x86/asus-wmi.h [new file with mode: 0644]
include/linux/rbtree_augmented.h
include/linux/remoteproc.h
include/linux/reset.h
include/linux/sched/stat.h
include/linux/scmi_protocol.h
include/linux/serial_core.h
include/linux/signal.h
include/linux/soc/amlogic/meson-canvas.h [new file with mode: 0644]
include/linux/soc/qcom/llcc-qcom.h
include/linux/sunrpc/cache.h
include/linux/sunrpc/svc_rdma.h
include/linux/sunrpc/svcauth.h
include/linux/tee_drv.h
include/linux/trace_events.h
include/linux/uprobes.h
include/media/cec.h
include/media/media-device.h
include/media/media-entity.h
include/media/media-request.h [new file with mode: 0644]
include/media/rc-core.h
include/media/rcar-fcp.h
include/media/v4l2-async.h
include/media/v4l2-common.h
include/media/v4l2-ctrls.h
include/media/v4l2-device.h
include/media/v4l2-dv-timings.h
include/media/v4l2-fwnode.h
include/media/v4l2-mc.h
include/media/v4l2-mediabus.h
include/media/v4l2-mem2mem.h
include/media/v4l2-rect.h
include/media/videobuf2-core.h
include/media/videobuf2-v4l2.h
include/media/vsp1.h
include/net/9p/9p.h
include/net/9p/client.h
include/soc/fsl/qman.h
include/soc/tegra/pmc.h
include/uapi/asm-generic/ioctls.h
include/uapi/linux/cec.h
include/uapi/linux/elf-em.h
include/uapi/linux/fanotify.h
include/uapi/linux/fuse.h
include/uapi/linux/media.h
include/uapi/linux/serial.h
include/uapi/linux/v4l2-controls.h
include/uapi/linux/vfio.h
include/uapi/linux/videodev2.h
include/video/udlfb.h
init/do_mounts.c
init/main.c
ipc/ipc_sysctl.c
ipc/util.h
kernel/bounds.c
kernel/dma/direct.c
kernel/dma/swiotlb.c
kernel/events/core.c
kernel/events/uprobes.c
kernel/fail_function.c
kernel/futex.c
kernel/hung_task.c
kernel/locking/qspinlock_paravirt.h
kernel/panic.c
kernel/pid.c
kernel/power/snapshot.c
kernel/printk/printk.c
kernel/profile.c
kernel/sched/core.c
kernel/signal.c
kernel/trace/trace.c
kernel/trace/trace_event_perf.c
kernel/trace/trace_events_hist.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_printk.c
kernel/trace/trace_probe.c
kernel/trace/trace_probe.h
kernel/trace/trace_probe_tmpl.h [new file with mode: 0644]
kernel/trace/trace_stack.c
kernel/trace/trace_uprobe.c
lib/Kconfig
lib/Kconfig.debug
lib/Makefile
lib/bitmap.c
lib/cpumask.c
lib/kstrtox.c
lib/lz4/lz4_decompress.c
lib/lz4/lz4defs.h
lib/parser.c
lib/sg_pool.c
lib/udivmoddi4.c [deleted file]
lib/umoddi3.c [deleted file]
lib/zlib_inflate/inflate.c
mm/Kconfig
mm/Makefile
mm/bootmem.c [deleted file]
mm/gup.c
mm/gup_benchmark.c
mm/hmm.c
mm/hugetlb.c
mm/internal.h
mm/kasan/kasan_init.c
mm/kmemleak.c
mm/memblock.c
mm/memory.c
mm/memory_hotplug.c
mm/nobootmem.c [deleted file]
mm/page_alloc.c
mm/page_ext.c
mm/page_idle.c
mm/page_owner.c
mm/page_poison.c
mm/page_vma_mapped.c
mm/percpu.c
mm/sparse-vmemmap.c
mm/sparse.c
net/9p/Makefile
net/9p/client.c
net/9p/mod.c
net/9p/protocol.c
net/9p/trans_fd.c
net/9p/trans_rdma.c
net/9p/trans_virtio.c
net/9p/trans_xen.c
net/9p/util.c [deleted file]
net/ceph/messenger.c
net/ceph/msgpool.c
net/ceph/osd_client.c
net/ceph/pagelist.c
net/ipv4/inet_hashtables.c
net/ipv4/tcp.c
net/ipv4/udp.c
net/sctp/protocol.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcauth.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/xfrm/xfrm_hash.c
samples/vfio-mdev/mbochs.c
scripts/checkpatch.pl
tools/perf/util/probe-event.c
tools/perf/util/probe-event.h
tools/perf/util/probe-file.c
tools/perf/util/probe-file.h
tools/perf/util/symbol-elf.c
tools/perf/util/symbol.h
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc

index 89f532caf639838d5290cf8328bcedc144bbc276..a76be45fef6ca5b2d23139304ff5ea338bdd1d07 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -160,6 +160,11 @@ Peter Oruba <peter.oruba@amd.com>
 Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
 Praveen BP <praveenbp@ti.com>
 Qais Yousef <qsyousef@gmail.com> <qais.yousef@imgtec.com>
+Oleksij Rempel <linux@rempel-privat.de> <bug-track@fisher-privat.net>
+Oleksij Rempel <linux@rempel-privat.de> <external.Oleksij.Rempel@de.bosch.com>
+Oleksij Rempel <linux@rempel-privat.de> <fixed-term.Oleksij.Rempel@de.bosch.com>
+Oleksij Rempel <linux@rempel-privat.de> <o.rempel@pengutronix.de>
+Oleksij Rempel <linux@rempel-privat.de> <ore@pengutronix.de>
 Rajesh Shah <rajesh.shah@intel.com>
 Ralf Baechle <ralf@linux-mips.org>
 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
index a5b4f223641d909cac3bd09777a9502840530f13..8127a08e366d8f96b05f0dacf71cd55634f68a1d 100644 (file)
@@ -199,7 +199,7 @@ Description:
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_positionrelative_x_raw
 What:          /sys/bus/iio/devices/iio:deviceX/in_positionrelative_y_raw
-KernelVersion: 4.18
+KernelVersion: 4.19
 Contact:       linux-iio@vger.kernel.org
 Description:
                Relative position in direction x or y on a pad (may be
diff --git a/Documentation/ABI/testing/sysfs-platform-lg-laptop b/Documentation/ABI/testing/sysfs-platform-lg-laptop
new file mode 100644 (file)
index 0000000..cf47749
--- /dev/null
@@ -0,0 +1,35 @@
+What:          /sys/devices/platform/lg-laptop/reader_mode
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control reader mode. 1 means on, 0 means off.
+
+What:          /sys/devices/platform/lg-laptop/fn_lock
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control FN lock mode. 1 means on, 0 means off.
+
+What:          /sys/devices/platform/lg-laptop/battery_care_limit
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Maximal battery charge level. Accepted values are 80 or 100.
+
+What:          /sys/devices/platform/lg-laptop/fan_mode
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control fan mode. 1 for performance mode, 0 for silent mode.
+
+What:          /sys/devices/platform/lg-laptop/usb_charge
+Date:          October 2018
+KernelVersion: 4.20
+Contact:       "Matan Ziv-Av <matan@svgalib.org>
+Description:
+        Control USB port charging when device is turned off.
+        1 means on, 0 means off.
index 25157aec5b3190eac1fe6a5a4725be9e1bdb3b75..5c4432c96c4b6d76a6e4c5245e6657a9e2e67382 100644 (file)
@@ -5,7 +5,7 @@ Memory Hotplug
 ==============
 
 :Created:                                                      Jul 28 2007
-:Updated: Add description of notifier of memory hotplug:       Oct 11 2007
+:Updated: Add some details about locking internals:            Aug 20 2018
 
 This document is about memory hotplug including how-to-use and current status.
 Because Memory Hotplug is still under development, contents of this text will
@@ -392,6 +392,46 @@ Need more implementation yet....
  - Notification completion of remove works by OS to firmware.
  - Guard from remove if not yet.
 
+
+Locking Internals
+=================
+
+When adding/removing memory that uses memory block devices (i.e. ordinary RAM),
+the device_hotplug_lock should be held to:
+
+- synchronize against online/offline requests (e.g. via sysfs). This way, memory
+  block devices can only be accessed (.online/.state attributes) by user
+  space once memory has been fully added. And when removing memory, we
+  know nobody is in critical sections.
+- synchronize against CPU hotplug and similar (e.g. relevant for ACPI and PPC)
+
+Especially, there is a possible lock inversion that is avoided using
+device_hotplug_lock when adding memory and user space tries to online that
+memory faster than expected:
+
+- device_online() will first take the device_lock(), followed by
+  mem_hotplug_lock
+- add_memory_resource() will first take the mem_hotplug_lock, followed by
+  the device_lock() (while creating the devices, during bus_add_device()).
+
+As the device is visible to user space before taking the device_lock(), this
+can result in a lock inversion.
+
+onlining/offlining of memory should be done via device_online()/
+device_offline() - to make sure it is properly synchronized to actions
+via sysfs. Holding device_hotplug_lock is advised (to e.g. protect online_type)
+
+When adding/removing/onlining/offlining memory or adding/removing
+heterogeneous/device memory, we should always hold the mem_hotplug_lock in
+write mode to serialise memory hotplug (e.g. access to global/zone
+variables).
+
+In addition, mem_hotplug_lock (in contrast to device_hotplug_lock) in read
+mode allows for a quite efficient get_online_mems/put_online_mems
+implementation, so code accessing memory can protect from that memory
+vanishing.
+
+
 Future Work
 ===========
 
index ed494ac0beb2acc0a7a102224cda6e1055c15a3a..d17ed518a7ea416177a778cb30a3f0f2e0f53dc6 100644 (file)
@@ -26,6 +26,7 @@ Offset        Value                                        Purpose
 0x20          0xfcba0d10 (Magic cookie)                    AFTR
 0x24          exynos_cpu_resume_ns                         AFTR
 0x28 + 4*cpu  0x8 (Magic cookie, Exynos3250)               AFTR
+0x28          0x0 or last value during resume (Exynos542x) System suspend
 
 
 2. Secure mode
index 6e12e89a03e0764e812269c7a4efdcfd7295c69e..e5ec9f1a563dfc9f009dd47f679fc6a74f1f349e 100644 (file)
@@ -5,54 +5,23 @@ Boot time memory management
 Early system initialization cannot use "normal" memory management
 simply because it is not set up yet. But there is still need to
 allocate memory for various data structures, for instance for the
-physical page allocator. To address this, a specialized allocator
-called the :ref:`Boot Memory Allocator <bootmem>`, or bootmem, was
-introduced. Several years later PowerPC developers added a "Logical
-Memory Blocks" allocator, which was later adopted by other
-architectures and renamed to :ref:`memblock <memblock>`. There is also
-a compatibility layer called `nobootmem` that translates bootmem
-allocation interfaces to memblock calls.
+physical page allocator.
 
-The selection of the early allocator is done using
-``CONFIG_NO_BOOTMEM`` and ``CONFIG_HAVE_MEMBLOCK`` kernel
-configuration options. These options are enabled or disabled
-statically by the architectures' Kconfig files.
-
-* Architectures that rely only on bootmem select
-  ``CONFIG_NO_BOOTMEM=n && CONFIG_HAVE_MEMBLOCK=n``.
-* The users of memblock with the nobootmem compatibility layer set
-  ``CONFIG_NO_BOOTMEM=y && CONFIG_HAVE_MEMBLOCK=y``.
-* And for those that use both memblock and bootmem the configuration
-  includes ``CONFIG_NO_BOOTMEM=n && CONFIG_HAVE_MEMBLOCK=y``.
-
-Whichever allocator is used, it is the responsibility of the
-architecture specific initialization to set it up in
-:c:func:`setup_arch` and tear it down in :c:func:`mem_init` functions.
+A specialized allocator called ``memblock`` performs the
+boot time memory management. The architecture specific initialization
+must set it up in :c:func:`setup_arch` and tear it down in
+:c:func:`mem_init` functions.
 
 Once the early memory management is available it offers a variety of
 functions and macros for memory allocations. The allocation request
 may be directed to the first (and probably the only) node or to a
 particular node in a NUMA system. There are API variants that panic
-when an allocation fails and those that don't. And more recent and
-advanced memblock even allows controlling its own behaviour.
-
-.. _bootmem:
-
-Bootmem
-=======
+when an allocation fails and those that don't.
 
-(mostly stolen from Mel Gorman's "Understanding the Linux Virtual
-Memory Manager" `book`_)
+Memblock also offers a variety of APIs that control its own behaviour.
 
-.. _book: https://www.kernel.org/doc/gorman/
-
-.. kernel-doc:: mm/bootmem.c
-   :doc: bootmem overview
-
-.. _memblock:
-
-Memblock
-========
+Memblock Overview
+=================
 
 .. kernel-doc:: mm/memblock.c
    :doc: memblock overview
@@ -61,26 +30,6 @@ Memblock
 Functions and structures
 ========================
 
-Common API
-----------
-
-The functions that are described in this section are available
-regardless of what early memory manager is enabled.
-
-.. kernel-doc:: mm/nobootmem.c
-
-Bootmem specific API
---------------------
-
-These interfaces available only with bootmem, i.e when ``CONFIG_NO_BOOTMEM=n``
-
-.. kernel-doc:: include/linux/bootmem.h
-.. kernel-doc:: mm/bootmem.c
-   :functions:
-
-Memblock specific API
----------------------
-
 Here is the description of memblock data structures, functions and
 macros. Some of them are actually internal, but since they are
 documented it would be silly to omit them. Besides, reading the
index b5c2b5c35766f8db4fb8a3dd66d9cf9b4a395209..4498292b833d0c63b42b9eef486f2467649e0ae4 100644 (file)
@@ -57,12 +57,17 @@ Boards with the Amlogic Meson AXG A113D SoC shall have the following properties:
   Required root node property:
     compatible: "amlogic,a113d", "amlogic,meson-axg";
 
+Boards with the Amlogic Meson G12A S905D2 SoC shall have the following properties:
+  Required root node property:
+    compatible: "amlogic,g12a";
+
 Board compatible values (alphabetically, grouped by SoC):
 
   - "geniatech,atv1200" (Meson6)
 
   - "minix,neo-x8" (Meson8)
 
+  - "endless,ec100" (Meson8b)
   - "hardkernel,odroid-c1" (Meson8b)
   - "tronfy,mxq" (Meson8b)
 
@@ -101,6 +106,8 @@ Board compatible values (alphabetically, grouped by SoC):
 
   - "amlogic,s400" (Meson axg a113d)
 
+  - "amlogic,u200" (Meson g12a s905d2)
+
 Amlogic Meson Firmware registers Interface
 ------------------------------------------
 
index 1e3e29a545e263470fff686f036361ddaf48abfa..0dcc3ea5adff4d5aea7402bc3f3d235a1744f298 100644 (file)
@@ -42,6 +42,14 @@ Raspberry Pi Compute Module
 Required root node properties:
 compatible = "raspberrypi,compute-module", "brcm,bcm2835";
 
+Raspberry Pi Compute Module 3
+Required root node properties:
+compatible = "raspberrypi,3-compute-module", "brcm,bcm2837";
+
+Raspberry Pi Compute Module 3 Lite
+Required root node properties:
+compatible = "raspberrypi,3-compute-module-lite", "brcm,bcm2837";
+
 Raspberry Pi Zero
 Required root node properties:
 compatible = "raspberrypi,model-zero", "brcm,bcm2835";
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
new file mode 100644 (file)
index 0000000..46d0af1
--- /dev/null
@@ -0,0 +1,183 @@
+NXP i.MX System Controller Firmware (SCFW)
+--------------------------------------------------------------------
+
+The System Controller Firmware (SCFW) is a low-level system function
+which runs on a dedicated Cortex-M core to provide power, clock, and
+resource management. It exists on some i.MX8 processors. e.g. i.MX8QM
+(QM, QP), and i.MX8QX (QXP, DX).
+
+The AP communicates with the SC using a multi-ported MU module found
+in the LSIO subsystem. The current definition of this MU module provides
+5 remote AP connections to the SC to support up to 5 execution environments
+(TZ, HV, standard Linux, etc.). The SC side of this MU module interfaces
+with the LSIO DSC IP bus. The SC firmware will communicate with this MU
+using the MSI bus.
+
+System Controller Device Node:
+============================================================
+
+The scu node with the following properties shall be under the /firmware/ node.
+
+Required properties:
+-------------------
+- compatible:  should be "fsl,imx-scu".
+- mbox-names:  should include "tx0", "tx1", "tx2", "tx3",
+                              "rx0", "rx1", "rx2", "rx3".
+- mboxes:      List of phandle of 4 MU channels for tx and 4 MU channels
+               for rx. All 8 MU channels must be in the same MU instance.
+               Cross instances are not allowed. The MU instance can only
+               be one of LSIO MU0~M4 for imx8qxp and imx8qm. Users need
+               to make sure use the one which is not conflict with other
+               execution environments. e.g. ATF.
+               Note:
+               Channel 0 must be "tx0" or "rx0".
+               Channel 1 must be "tx1" or "rx1".
+               Channel 2 must be "tx2" or "rx2".
+               Channel 3 must be "tx3" or "rx3".
+               e.g.
+               mboxes = <&lsio_mu1 0 0
+                         &lsio_mu1 0 1
+                         &lsio_mu1 0 2
+                         &lsio_mu1 0 3
+                         &lsio_mu1 1 0
+                         &lsio_mu1 1 1
+                         &lsio_mu1 1 2
+                         &lsio_mu1 1 3>;
+               See Documentation/devicetree/bindings/mailbox/fsl,mu.txt
+               for detailed mailbox binding.
+
+i.MX SCU Client Device Node:
+============================================================
+
+Client nodes are maintained as children of the relevant IMX-SCU device node.
+
+Power domain bindings based on SCU Message Protocol
+------------------------------------------------------------
+
+This binding for the SCU power domain providers uses the generic power
+domain binding[2].
+
+Required properties:
+- compatible:          Should be "fsl,scu-pd".
+- #address-cells:      Should be 1.
+- #size-cells:         Should be 0.
+
+Required properties for power domain sub nodes:
+- #power-domain-cells: Must be 0.
+
+Optional Properties:
+- reg:                 Resource ID of this power domain.
+                       No exist means uncontrollable by user.
+                       See detailed Resource ID list from:
+                       include/dt-bindings/power/imx-rsrc.h
+- power-domains:       phandle pointing to the parent power domain.
+
+Clock bindings based on SCU Message Protocol
+------------------------------------------------------------
+
+This binding uses the common clock binding[1].
+
+Required properties:
+- compatible:          Should be "fsl,imx8qxp-clock".
+- #clock-cells:                Should be 1. Contains the Clock ID value.
+- clocks:              List of clock specifiers, must contain an entry for
+                       each required entry in clock-names
+- clock-names:         Should include entries "xtal_32KHz", "xtal_24MHz"
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell.
+
+See the full list of clock IDs from:
+include/dt-bindings/clock/imx8qxp-clock.h
+
+Pinctrl bindings based on SCU Message Protocol
+------------------------------------------------------------
+
+This binding uses the i.MX common pinctrl binding[3].
+
+Required properties:
+- compatible:          Should be "fsl,imx8qxp-iomuxc".
+
+Required properties for Pinctrl sub nodes:
+- fsl,pins:            Each entry consists of 3 integers which represents
+                       the mux and config setting for one pin. The first 2
+                       integers <pin_id mux_mode> are specified using a
+                       PIN_FUNC_ID macro, which can be found in
+                       <dt-bindings/pinctrl/pads-imx8qxp.h>.
+                       The last integer CONFIG is the pad setting value like
+                       pull-up on this pin.
+
+                       Please refer to i.MX8QXP Reference Manual for detailed
+                       CONFIG settings.
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/power/power_domain.txt
+[3] Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
+
+Example (imx8qxp):
+-------------
+lsio_mu1: mailbox@5d1c0000 {
+       ...
+       #mbox-cells = <2>;
+};
+
+firmware {
+       scu {
+               compatible = "fsl,imx-scu";
+               mbox-names = "tx0", "tx1", "tx2", "tx3",
+                            "rx0", "rx1", "rx2", "rx3";
+               mboxes = <&lsio_mu1 0 0
+                         &lsio_mu1 0 1
+                         &lsio_mu1 0 2
+                         &lsio_mu1 0 3
+                         &lsio_mu1 1 0
+                         &lsio_mu1 1 1
+                         &lsio_mu1 1 2
+                         &lsio_mu1 1 3>;
+
+               clk: clk {
+                       compatible = "fsl,imx8qxp-clk";
+                       #clock-cells = <1>;
+               };
+
+               iomuxc {
+                       compatible = "fsl,imx8qxp-iomuxc";
+
+                       pinctrl_lpuart0: lpuart0grp {
+                               fsl,pins = <
+                                       SC_P_UART0_RX_ADMA_UART0_RX     0x06000020
+                                       SC_P_UART0_TX_ADMA_UART0_TX     0x06000020
+                               >;
+                       };
+                       ...
+               };
+
+               imx8qx-pm {
+                       compatible = "fsl,scu-pd";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       pd_dma: dma-power-domain {
+                               #power-domain-cells = <0>;
+
+                               pd_dma_lpuart0: dma-lpuart0@57 {
+                                       reg = <SC_R_UART_0>;
+                                       #power-domain-cells = <0>;
+                                       power-domains = <&pd_dma>;
+                               };
+                               ...
+                       };
+                       ...
+               };
+       };
+};
+
+serial@5a060000 {
+       ...
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart0>;
+       clocks = <&clk IMX8QXP_UART0_CLK>,
+                <&clk IMX8QXP_UART0_IPG_CLK>;
+       clock-names = "per", "ipg";
+       power-domains = <&pd_dma_lpuart0>;
+};
index 1e775aaa5c5ba97e389148dbe5eb16620be2b978..5074aeecd3279b7582fb8ae3828195e9edb4bf84 100644 (file)
@@ -57,6 +57,50 @@ i.MX6SLL EVK board
 Required root node properties:
     - compatible = "fsl,imx6sll-evk", "fsl,imx6sll";
 
+i.MX6 Quad Plus SABRE Smart Device Board
+Required root node properties:
+    - compatible = "fsl,imx6qp-sabresd", "fsl,imx6qp";
+
+i.MX6 Quad Plus SABRE Automotive Board
+Required root node properties:
+    - compatible = "fsl,imx6qp-sabreauto", "fsl,imx6qp";
+
+i.MX6 DualLite SABRE Smart Device Board
+Required root node properties:
+    - compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl";
+
+i.MX6 DualLite/Solo SABRE Automotive Board
+Required root node properties:
+    - compatible = "fsl,imx6dl-sabreauto", "fsl,imx6dl";
+
+i.MX6 SoloLite EVK Board
+Required root node properties:
+    - compatible = "fsl,imx6sl-evk", "fsl,imx6sl";
+
+i.MX6 UltraLite 14x14 EVK Board
+Required root node properties:
+    - compatible = "fsl,imx6ul-14x14-evk", "fsl,imx6ul";
+
+i.MX6 UltraLiteLite 14x14 EVK Board
+Required root node properties:
+    - compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
+
+i.MX6 ULZ 14x14 EVK Board
+Required root node properties:
+    - compatible = "fsl,imx6ulz-14x14-evk", "fsl,imx6ull", "fsl,imx6ulz";
+
+i.MX6 SoloX SDB Board
+Required root node properties:
+    - compatible = "fsl,imx6sx-sdb", "fsl,imx6sx";
+
+i.MX6 SoloX Sabre Auto Board
+Required root node properties:
+    - compatible = "fsl,imx6sx-sabreauto", "fsl,imx6sx";
+
+i.MX7 SabreSD Board
+Required root node properties:
+    - compatible = "fsl,imx7d-sdb", "fsl,imx7d";
+
 Generic i.MX boards
 -------------------
 
index 199cd36fe1ba44b4efe750aa72d179d0e1bbc666..a97f643e7d1c760240d918ffe5682e82dc3bdda9 100644 (file)
@@ -8,6 +8,14 @@ HiKey960 Board
 Required root node properties:
        - compatible = "hisilicon,hi3660-hikey960", "hisilicon,hi3660";
 
+Hi3670 SoC
+Required root node properties:
+       - compatible = "hisilicon,hi3670";
+
+HiKey970 Board
+Required root node properties:
+       - compatible = "hisilicon,hi3670-hikey970", "hisilicon,hi3670";
+
 Hi3798cv200 SoC
 Required root node properties:
        - compatible = "hisilicon,hi3798cv200";
index 31f5f9a104cca5f24cd4cd3c240b791530257524..b56a02c10ae6ecd6be666f4fc1c0f61bb11dfd6f 100644 (file)
@@ -45,11 +45,15 @@ Optional Properties:
        debug_messages - Map the Debug message region
 - reg:  register space corresponding to the debug_messages
 - ti,system-reboot-controller: If system reboot can be triggered by SoC reboot
+- ti,host-id: Integer value corresponding to the host ID assigned by Firmware
+       for identification of host processing entities such as virtual
+       machines
 
 Example (K2G):
 -------------
        pmmc: pmmc {
                compatible = "ti,k2g-sci";
+               ti,host-id = <2>;
                mbox-names = "rx", "tx";
                mboxes= <&msgmgr &msgmgr_proxy_pmmc_rx>,
                        <&msgmgr &msgmgr_proxy_pmmc_tx>;
diff --git a/Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt
deleted file mode 100644 (file)
index 3bab184..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-Marvell Berlin SoC Family Device Tree Bindings
----------------------------------------------------------------
-
-Work in progress statement:
-
-Device tree files and bindings applying to Marvell Berlin SoCs and boards are
-considered "unstable". Any Marvell Berlin device tree binding may change at any
-time. Be sure to use a device tree binary and a kernel image generated from the
-same source tree.
-
-Please refer to Documentation/devicetree/bindings/ABI.txt for a definition of a
-stable binding/ABI.
-
----------------------------------------------------------------
-
-Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500
-shall have the following properties:
-
-* Required root node properties:
-compatible: must contain "marvell,berlin"
-
-In addition, the above compatible shall be extended with the specific
-SoC and board used. Currently known SoC compatibles are:
-    "marvell,berlin2"      for Marvell Armada 1500 (BG2, 88DE3100),
-    "marvell,berlin2cd"    for Marvell Armada 1500-mini (BG2CD, 88DE3005)
-    "marvell,berlin2ct"    for Marvell Armada ? (BG2CT, 88DE????)
-    "marvell,berlin2q"     for Marvell Armada 1500-pro (BG2Q, 88DE3114)
-    "marvell,berlin3"      for Marvell Armada ? (BG3, 88DE????)
-
-* Example:
-
-/ {
-       model = "Sony NSZ-GS7";
-       compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin";
-
-       ...
-}
-
-* Marvell Berlin CPU control bindings
-
-CPU control register allows various operations on CPUs, like resetting them
-independently.
-
-Required properties:
-- compatible: should be "marvell,berlin-cpu-ctrl"
-- reg: address and length of the register set
-
-Example:
-
-cpu-ctrl@f7dd0000 {
-       compatible = "marvell,berlin-cpu-ctrl";
-       reg = <0xf7dd0000 0x10000>;
-};
-
-* Marvell Berlin2 chip control binding
-
-Marvell Berlin SoCs have a chip control register set providing several
-individual registers dealing with pinmux, padmux, clock, reset, and secondary
-CPU boot address. Unfortunately, the individual registers are spread among the
-chip control registers, so there should be a single DT node only providing the
-different functions which are described below.
-
-Required properties:
-- compatible:
-       * the first and second values must be:
-               "simple-mfd", "syscon"
-- reg: address and length of following register sets for
-  BG2/BG2CD: chip control register set
-  BG2Q: chip control register set and cpu pll registers
-
-* Marvell Berlin2 system control binding
-
-Marvell Berlin SoCs have a system control register set providing several
-individual registers dealing with pinmux, padmux, and reset.
-
-Required properties:
-- compatible:
-       * the first and second values must be:
-               "simple-mfd", "syscon"
-- reg: address and length of the system control register set
-
-Example:
-
-chip: chip-control@ea0000 {
-       compatible = "simple-mfd", "syscon";
-       reg = <0xea0000 0x400>;
-
-       /* sub-device nodes */
-};
-
-sysctrl: system-controller@d000 {
-       compatible = "simple-mfd", "syscon";
-       reg = <0xd000 0x100>;
-
-       /* sub-device nodes */
-};
index b404d592ce58a6f129b6d652482b85c2ebbab21f..4e4a3c0ab9abbaf8f301e519282fb5a7d8bccbbd 100644 (file)
@@ -10,6 +10,7 @@ Required Properties:
        - "mediatek,mt2712-apmixedsys", "syscon"
        - "mediatek,mt6797-apmixedsys"
        - "mediatek,mt7622-apmixedsys"
+       - "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
        - "mediatek,mt8135-apmixedsys"
        - "mediatek,mt8173-apmixedsys"
 - #clock-cells: Must be 1
index 34a69ba67f13f0f90fabb67de3d1ab3de1c4b6be..d1606b2c3e63b82f613516992340522d30f83632 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-audsys", "syscon"
        - "mediatek,mt7622-audsys", "syscon"
+       - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
 - #clock-cells: Must be 1
 
 The AUDSYS controller uses the common clk binding from
index 4010e37c53a0218554edfb5885262a168ba73108..149567a382150730eaf2ba9d85120590bcb3dc26 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be:
        - "mediatek,mt2701-bdpsys", "syscon"
        - "mediatek,mt2712-bdpsys", "syscon"
+       - "mediatek,mt7623-bdpsys", "mediatek,mt2701-bdpsys", "syscon"
 - #clock-cells: Must be 1
 
 The bdpsys controller uses the common clk binding from
index 8f5335b480aca6377826138aa39ad4153e98eb46..f17cfe64255d4ba94be373548963c4c8c6d29d46 100644 (file)
@@ -8,6 +8,7 @@ Required Properties:
 - compatible: Should be:
        - "mediatek,mt2701-ethsys", "syscon"
        - "mediatek,mt7622-ethsys", "syscon"
+       - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
 - #clock-cells: Must be 1
 - #reset-cells: Must be 1
 
index f5629d64cef2d2dfa218dabb7646abd50b135a08..323905af82c3138cf911ea81083b53c51fd9e938 100644 (file)
@@ -9,6 +9,7 @@ Required Properties:
 - compatible: Should be:
        - "mediatek,mt2701-hifsys", "syscon"
        - "mediatek,mt7622-hifsys", "syscon"
+       - "mediatek,mt7623-hifsys", "mediatek,mt2701-hifsys", "syscon"
 - #clock-cells: Must be 1
 
 The hifsys controller uses the common clk binding from
index 868bd51a98befcb5d901bf67995525e9dceb8173..3f99672163e37dac2e556d3c9f02534fa0ee01cc 100644 (file)
@@ -9,6 +9,7 @@ Required Properties:
        - "mediatek,mt2701-imgsys", "syscon"
        - "mediatek,mt2712-imgsys", "syscon"
        - "mediatek,mt6797-imgsys", "syscon"
+       - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon"
        - "mediatek,mt8173-imgsys", "syscon"
 - #clock-cells: Must be 1
 
index 566f153f9f83b29ef7677ea7cd8412486e4154d4..89f4272a14416b49da202fa4a82f5741f1b2345c 100644 (file)
@@ -11,6 +11,7 @@ Required Properties:
        - "mediatek,mt2712-infracfg", "syscon"
        - "mediatek,mt6797-infracfg", "syscon"
        - "mediatek,mt7622-infracfg", "syscon"
+       - "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
        - "mediatek,mt8135-infracfg", "syscon"
        - "mediatek,mt8173-infracfg", "syscon"
 - #clock-cells: Must be 1
index 4eb8bbe15c01cd4828a75a9acb1d8913e231e515..15d977afad3130e0849e3f9139ded0ccd4ddf9a7 100644 (file)
@@ -9,6 +9,7 @@ Required Properties:
        - "mediatek,mt2701-mmsys", "syscon"
        - "mediatek,mt2712-mmsys", "syscon"
        - "mediatek,mt6797-mmsys", "syscon"
+       - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon"
        - "mediatek,mt8173-mmsys", "syscon"
 - #clock-cells: Must be 1
 
index fb58ca8c2770b5924baf3b624fb6828260553a0d..6755514deb80595c4d7ed4b981374ee0a86eda09 100644 (file)
@@ -10,6 +10,7 @@ Required Properties:
        - "mediatek,mt2701-pericfg", "syscon"
        - "mediatek,mt2712-pericfg", "syscon"
        - "mediatek,mt7622-pericfg", "syscon"
+       - "mediatek,mt7623-pericfg", "mediatek,mt2701-pericfg", "syscon"
        - "mediatek,mt8135-pericfg", "syscon"
        - "mediatek,mt8173-pericfg", "syscon"
 - #clock-cells: Must be 1
index 24014a7e2332370202fcbf2ffc31ede87df571f8..d849465b8c99b06c192f8f423584aedf8d1c8333 100644 (file)
@@ -10,6 +10,7 @@ Required Properties:
        - "mediatek,mt2712-topckgen", "syscon"
        - "mediatek,mt6797-topckgen"
        - "mediatek,mt7622-topckgen"
+       - "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
        - "mediatek,mt8135-topckgen"
        - "mediatek,mt8173-topckgen"
 - #clock-cells: Must be 1
index ea40d05089f8306b2b15e2b0cd304ef61b8f8602..3212afc753c8d1f8e03c8d8c999c010bb98d4092 100644 (file)
@@ -9,6 +9,7 @@ Required Properties:
        - "mediatek,mt2701-vdecsys", "syscon"
        - "mediatek,mt2712-vdecsys", "syscon"
        - "mediatek,mt6797-vdecsys", "syscon"
+       - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon"
        - "mediatek,mt8173-vdecsys", "syscon"
 - #clock-cells: Must be 1
 
index 1333db9acfee11aa47b9972ac9e41b0e081966ec..7f696362a4a1da1274f244745997bf89b13b8a10 100644 (file)
@@ -21,10 +21,29 @@ PROPERTIES
                    the register region. An optional second element specifies
                    the base address and size of the alias register region.
 
+- clocks:
+        Usage: required
+        Value type: <prop-encoded-array>
+        Definition: reference to the pll parents.
+
+- clock-names:
+        Usage: required
+        Value type: <stringlist>
+        Definition: must be "pll8_vote", "pxo".
+
+- clock-output-names:
+       Usage: optional
+       Value type: <string>
+       Definition: Name of the output clock. Typically acpuX_aux where X is a
+                   CPU number starting at 0.
+
 Example:
 
        clock-controller@2088000 {
                compatible = "qcom,kpss-acc-v2";
                reg = <0x02088000 0x1000>,
                      <0x02008000 0x1000>;
+               clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>;
+               clock-names = "pll8_vote", "pxo";
+               clock-output-names = "acpu0_aux";
        };
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt
new file mode 100644 (file)
index 0000000..e628758
--- /dev/null
@@ -0,0 +1,44 @@
+Krait Processor Sub-system (KPSS) Global Clock Controller (GCC)
+
+PROPERTIES
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: should be one of the following. The generic compatible
+                       "qcom,kpss-gcc" should also be included.
+                       "qcom,kpss-gcc-ipq8064", "qcom,kpss-gcc"
+                       "qcom,kpss-gcc-apq8064", "qcom,kpss-gcc"
+                       "qcom,kpss-gcc-msm8974", "qcom,kpss-gcc"
+                       "qcom,kpss-gcc-msm8960", "qcom,kpss-gcc"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: base address and size of the register region
+
+- clocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: reference to the pll parents.
+
+- clock-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "pll8_vote", "pxo".
+
+- clock-output-names:
+       Usage: required
+       Value type: <string>
+       Definition: Name of the output clock. Typically acpu_l2_aux indicating
+                   an L2 cache auxiliary clock.
+
+Example:
+
+       l2cc: clock-controller@2011000 {
+               compatible = "qcom,kpss-gcc-ipq8064", "qcom,kpss-gcc";
+               reg = <0x2011000 0x1000>;
+               clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>;
+               clock-names = "pll8_vote", "pxo";
+               clock-output-names = "acpu_l2_aux";
+       };
index 5e85749262aee881f720be668b0ad8bd63e54f52..eaee06b2d8f2346829d8d25ddc67658b336f4772 100644 (file)
@@ -16,11 +16,26 @@ Properties:
 - reg:
        Usage: required
        Value Type: <prop-encoded-array>
-       Definition: Start address and the the size of the register region.
+       Definition: The first element specifies the llcc base start address and
+                   the size of the register region. The second element specifies
+                   the llcc broadcast base address and size of the register region.
+
+- reg-names:
+        Usage: required
+        Value Type: <stringlist>
+        Definition: Register region names. Must be "llcc_base", "llcc_broadcast_base".
+
+- interrupts:
+       Usage: required
+       Definition: The interrupt is associated with the llcc edac device.
+                       It's used for llcc cache single and double bit error detection
+                       and reporting.
 
 Example:
 
        cache-controller@1100000 {
                compatible = "qcom,sdm845-llcc";
-               reg = <0x1100000 0x250000>;
+               reg = <0x1100000 0x200000>, <0x1300000 0x50000> ;
+               reg-names = "llcc_base", "llcc_broadcast_base";
+               interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
        };
index acfd3c773dd0e40e6ec22ec7566fb433fe90c995..0cc71236d639c5b0ee234ec3bd960ab732fa7071 100644 (file)
@@ -5,6 +5,10 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "vamrs,ficus", "rockchip,rk3399";
 
+- 96boards RK3399 Rock960 (ROCK960 Consumer Edition)
+    Required root node properties:
+      - compatible = "vamrs,rock960", "rockchip,rk3399";
+
 - Amarula Vyasa RK3288 board
     Required root node properties:
       - compatible = "amarula,vyasa-rk3288", "rockchip,rk3288";
@@ -13,6 +17,10 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "asus,rk3288-tinker", "rockchip,rk3288";
 
+- Asus Tinker board S
+    Required root node properties:
+      - compatible = "asus,rk3288-tinker-s", "rockchip,rk3288";
+
 - Kylin RK3036 board:
     Required root node properties:
       - compatible = "rockchip,kylin-rk3036", "rockchip,rk3036";
@@ -59,6 +67,10 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328";
 
+- Firefly ROC-RK3399-PC board:
+    Required root node properties:
+      - compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399";
+
 - ChipSPARK PopMetal-RK3288 board:
     Required root node properties:
       - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288";
@@ -160,6 +172,10 @@ Rockchip platforms device tree bindings
     Required root node properties:
     - compatible = "pine64,rock64", "rockchip,rk3328";
 
+- Pine64 RockPro64 board:
+    Required root node properties:
+    - compatible = "pine64,rockpro64", "rockchip,rk3399";
+
 - Rockchip PX3 Evaluation board:
     Required root node properties:
       - compatible = "rockchip,px3-evb", "rockchip,px3", "rockchip,rk3188";
@@ -168,6 +184,10 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "rockchip,px5-evb", "rockchip,px5", "rockchip,rk3368";
 
+- Rockchip PX30 Evaluation board:
+    Required root node properties:
+      - compatible = "rockchip,px30-evb", "rockchip,px30";
+
 - Rockchip RV1108 Evaluation board
     Required root node properties:
       - compatible = "rockchip,rv1108-evb", "rockchip,rv1108";
index 08a587875996b47cf25dd20f7bd7cde81f61d5ff..74d0a780ce511998914fd0efe1ba82adf7a20867 100644 (file)
@@ -22,7 +22,7 @@ References:
 
 Example:
 
-scu@a04100000 {
+scu@a0410000 {
        compatible = "arm,cortex-a9-scu";
        reg = <0xa0410000 0x100>;
 };
index 89b4a389fbc7cb3e886a7ecab2ac240adb3592f7..f5e0f82fd5031efb1570361eabf2d096769ef7f5 100644 (file)
@@ -7,6 +7,8 @@ SoCs:
     compatible = "renesas,emev2"
   - RZ/A1H (R7S72100)
     compatible = "renesas,r7s72100"
+  - RZ/A2 (R7S9210)
+    compatible = "renesas,r7s9210"
   - SH-Mobile AG5 (R8A73A00/SH73A0)
     compatible = "renesas,sh73a0"
   - R-Mobile APE6 (R8A73A40)
@@ -23,6 +25,10 @@ SoCs:
     compatible = "renesas,r8a7745"
   - RZ/G1C (R8A77470)
     compatible = "renesas,r8a77470"
+  - RZ/G2M (R8A774A1)
+    compatible = "renesas,r8a774a1"
+  - RZ/G2E (RA8774C0)
+    compatible = "renesas,r8a774c0"
   - R-Car M1A (R8A77781)
     compatible = "renesas,r8a7778"
   - R-Car H1 (R8A77790)
@@ -107,6 +113,8 @@ Boards:
     compatible = "renesas,lager", "renesas,r8a7790"
   - M3ULCB (R-Car Starter Kit Pro, RTP0RC7796SKBX0010SA09 (M3 ES1.0))
     compatible = "renesas,m3ulcb", "renesas,r8a7796"
+  - M3NULCB (R-Car Starter Kit Pro, RTP0RC77965SKBX010SA00 (M3-N ES1.1))
+    compatible = "renesas,m3nulcb", "renesas,r8a77965"
   - Marzen (R0P7779A00010S)
     compatible = "renesas,marzen", "renesas,r8a7779"
   - Porter (M2-LCDP)
@@ -143,12 +151,12 @@ Boards:
     compatible = "renesas,wheat", "renesas,r8a7792"
 
 
-Most Renesas ARM SoCs have a Product Register that allows to retrieve SoC
-product and revision information.  If present, a device node for this register
-should be added.
+Most Renesas ARM SoCs have a Product Register or Boundary Scan ID Register that
+allows to retrieve SoC product and revision information.  If present, a device
+node for this register should be added.
 
 Required properties:
-  - compatible: Must be "renesas,prr".
+  - compatible: Must be "renesas,prr" or "renesas,bsid"
   - reg: Base address and length of the register block.
 
 
diff --git a/Documentation/devicetree/bindings/arm/syna.txt b/Documentation/devicetree/bindings/arm/syna.txt
new file mode 100644 (file)
index 0000000..2face46
--- /dev/null
@@ -0,0 +1,105 @@
+Synaptics SoC Device Tree Bindings
+
+According to https://www.synaptics.com/company/news/conexant-marvell
+Synaptics has acquired the Multimedia Solutions Business of Marvell, so
+berlin SoCs are now Synaptics' SoCs now.
+
+---------------------------------------------------------------
+
+Work in progress statement:
+
+Device tree files and bindings applying to Marvell Berlin SoCs and boards are
+considered "unstable". Any Marvell Berlin device tree binding may change at any
+time. Be sure to use a device tree binary and a kernel image generated from the
+same source tree.
+
+Please refer to Documentation/devicetree/bindings/ABI.txt for a definition of a
+stable binding/ABI.
+
+---------------------------------------------------------------
+
+Boards with the Synaptics AS370 SoC shall have the following properties:
+  Required root node property:
+    compatible: "syna,as370"
+
+Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500
+shall have the following properties:
+
+* Required root node properties:
+compatible: must contain "marvell,berlin"
+
+In addition, the above compatible shall be extended with the specific
+SoC and board used. Currently known SoC compatibles are:
+    "marvell,berlin2"      for Marvell Armada 1500 (BG2, 88DE3100),
+    "marvell,berlin2cd"    for Marvell Armada 1500-mini (BG2CD, 88DE3005)
+    "marvell,berlin2ct"    for Marvell Armada ? (BG2CT, 88DE????)
+    "marvell,berlin2q"     for Marvell Armada 1500-pro (BG2Q, 88DE3114)
+    "marvell,berlin3"      for Marvell Armada ? (BG3, 88DE????)
+
+* Example:
+
+/ {
+       model = "Sony NSZ-GS7";
+       compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin";
+
+       ...
+}
+
+* Marvell Berlin CPU control bindings
+
+CPU control register allows various operations on CPUs, like resetting them
+independently.
+
+Required properties:
+- compatible: should be "marvell,berlin-cpu-ctrl"
+- reg: address and length of the register set
+
+Example:
+
+cpu-ctrl@f7dd0000 {
+       compatible = "marvell,berlin-cpu-ctrl";
+       reg = <0xf7dd0000 0x10000>;
+};
+
+* Marvell Berlin2 chip control binding
+
+Marvell Berlin SoCs have a chip control register set providing several
+individual registers dealing with pinmux, padmux, clock, reset, and secondary
+CPU boot address. Unfortunately, the individual registers are spread among the
+chip control registers, so there should be a single DT node only providing the
+different functions which are described below.
+
+Required properties:
+- compatible:
+       * the first and second values must be:
+               "simple-mfd", "syscon"
+- reg: address and length of following register sets for
+  BG2/BG2CD: chip control register set
+  BG2Q: chip control register set and cpu pll registers
+
+* Marvell Berlin2 system control binding
+
+Marvell Berlin SoCs have a system control register set providing several
+individual registers dealing with pinmux, padmux, and reset.
+
+Required properties:
+- compatible:
+       * the first and second values must be:
+               "simple-mfd", "syscon"
+- reg: address and length of the system control register set
+
+Example:
+
+chip: chip-control@ea0000 {
+       compatible = "simple-mfd", "syscon";
+       reg = <0xea0000 0x400>;
+
+       /* sub-device nodes */
+};
+
+sysctrl: system-controller@d000 {
+       compatible = "simple-mfd", "syscon";
+       reg = <0xd000 0x100>;
+
+       /* sub-device nodes */
+};
index 32f62bb7006d4480a5ba22de62619b319eab3a3d..c59b15f64346ffbccece72040482d52f2f3ba83e 100644 (file)
@@ -47,12 +47,17 @@ board-specific compatible values:
   nvidia,ventana
   toradex,apalis_t30
   toradex,apalis_t30-eval
+  toradex,apalis_t30-v1.1
+  toradex,apalis_t30-v1.1-eval
   toradex,apalis-tk1
   toradex,apalis-tk1-eval
-  toradex,colibri_t20-512
+  toradex,apalis-tk1-v1.2
+  toradex,apalis-tk1-v1.2-eval
+  toradex,colibri_t20
+  toradex,colibri_t20-eval-v3
+  toradex,colibri_t20-iris
   toradex,colibri_t30
   toradex,colibri_t30-eval-v3
-  toradex,iris
 
 Trusted Foundations
 -------------------------------------------
index 5a3bf7c5a7a01ea5325c3b803d5f5d9f5bbc48ae..c9fd6d1de57ee198dbb024bbfe09e73abd10b265 100644 (file)
@@ -34,3 +34,96 @@ Board DTS:
        pmc@c360000 {
                nvidia,invert-interrupt;
        };
+
+== Pad Control ==
+
+On Tegra SoCs a pad is a set of pins which are configured as a group.
+The pin grouping is a fixed attribute of the hardware. The PMC can be
+used to set pad power state and signaling voltage. A pad can be either
+in active or power down mode. The support for power state and signaling
+voltage configuration varies depending on the pad in question. 3.3 V and
+1.8 V signaling voltages are supported on pins where software
+controllable signaling voltage switching is available.
+
+Pad configurations are described with pin configuration nodes which
+are placed under the pmc node and they are referred to by the pinctrl
+client properties. For more information see
+Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt.
+
+The following pads are present on Tegra186:
+csia           csib            dsi             mipi-bias
+pex-clk-bias   pex-clk3        pex-clk2        pex-clk1
+usb0           usb1            usb2            usb-bias
+uart           audio           hsic            dbg
+hdmi-dp0       hdmi-dp1        pex-cntrl       sdmmc2-hv
+sdmmc4         cam             dsib            dsic
+dsid           csic            csid            csie
+dsif           spi             ufs             dmic-hv
+edp            sdmmc1-hv       sdmmc3-hv       conn
+audio-hv       ao-hv
+
+Required pin configuration properties:
+  - pins: A list of strings, each of which contains the name of a pad
+         to be configured.
+
+Optional pin configuration properties:
+  - low-power-enable: Configure the pad into power down mode
+  - low-power-disable: Configure the pad into active mode
+  - power-source: Must contain either TEGRA_IO_PAD_VOLTAGE_1V8 or
+    TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages.
+    The values are defined in
+    include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h.
+
+Note: The power state can be configured on all of the above pads except
+      for ao-hv. Following pads have software configurable signaling
+      voltages: sdmmc2-hv, dmic-hv, sdmmc1-hv, sdmmc3-hv, audio-hv,
+      ao-hv.
+
+Pad configuration state example:
+       pmc: pmc@7000e400 {
+               compatible = "nvidia,tegra186-pmc";
+               reg = <0 0x0c360000 0 0x10000>,
+                     <0 0x0c370000 0 0x10000>,
+                     <0 0x0c380000 0 0x10000>,
+                     <0 0x0c390000 0 0x10000>;
+               reg-names = "pmc", "wake", "aotag", "scratch";
+
+               ...
+
+               sdmmc1_3v3: sdmmc1-3v3 {
+                       pins = "sdmmc1-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc1_1v8: sdmmc1-1v8 {
+                       pins = "sdmmc1-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
+
+               hdmi_off: hdmi-off {
+                       pins = "hdmi";
+                       low-power-enable;
+               }
+
+               hdmi_on: hdmi-on {
+                       pins = "hdmi";
+                       low-power-disable;
+               }
+       };
+
+Pinctrl client example:
+       sdmmc1: sdhci@3400000 {
+               ...
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc1_3v3>;
+               pinctrl-1 = <&sdmmc1_1v8>;
+       };
+
+       ...
+
+       sor0: sor@15540000 {
+               ...
+               pinctrl-0 = <&hdmi_off>;
+               pinctrl-1 = <&hdmi_on>;
+               pinctrl-names = "hdmi-on", "hdmi-off";
+       };
index a74b37b07e5c1576492245a9d70ed89f5cf89234..cb12f33a247f5463befb24c6541b4c513de90b6a 100644 (file)
@@ -195,3 +195,106 @@ Example:
                power-domains = <&pd_audio>;
                ...
        };
+
+== Pad Control ==
+
+On Tegra SoCs a pad is a set of pins which are configured as a group.
+The pin grouping is a fixed attribute of the hardware. The PMC can be
+used to set pad power state and signaling voltage. A pad can be either
+in active or power down mode. The support for power state and signaling
+voltage configuration varies depending on the pad in question. 3.3 V and
+1.8 V signaling voltages are supported on pins where software
+controllable signaling voltage switching is available.
+
+The pad configuration state nodes are placed under the pmc node and they
+are referred to by the pinctrl client properties. For more information
+see Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt.
+The pad name should be used as the value of the pins property in pin
+configuration nodes.
+
+The following pads are present on Tegra124 and Tegra132:
+audio          bb              cam             comp
+csia           csb             cse             dsi
+dsib           dsic            dsid            hdmi
+hsic           hv              lvds            mipi-bias
+nand           pex-bias        pex-clk1        pex-clk2
+pex-cntrl      sdmmc1          sdmmc3          sdmmc4
+sys_ddc                uart            usb0            usb1
+usb2           usb_bias
+
+The following pads are present on Tegra210:
+audio          audio-hv        cam             csia
+csib           csic            csid            csie
+csif           dbg             debug-nonao     dmic
+dp             dsi             dsib            dsic
+dsid           emmc            emmc2           gpio
+hdmi           hsic            lvds            mipi-bias
+pex-bias       pex-clk1        pex-clk2        pex-cntrl
+sdmmc1         sdmmc3          spi             spi-hv
+uart           usb0            usb1            usb2
+usb3           usb-bias
+
+Required pin configuration properties:
+  - pins: Must contain name of the pad(s) to be configured.
+
+Optional pin configuration properties:
+  - low-power-enable: Configure the pad into power down mode
+  - low-power-disable: Configure the pad into active mode
+  - power-source: Must contain either TEGRA_IO_PAD_VOLTAGE_1V8
+    or TEGRA_IO_PAD_VOLTAGE_3V3 to select between signaling voltages.
+    The values are defined in
+    include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h.
+
+Note: The power state can be configured on all of the Tegra124 and
+      Tegra132 pads. None of the Tegra124 or Tegra132 pads support
+      signaling voltage switching.
+
+Note: All of the listed Tegra210 pads except pex-cntrl support power
+      state configuration. Signaling voltage switching is supported on
+      following Tegra210 pads: audio, audio-hv, cam, dbg, dmic, gpio,
+      pex-cntrl, sdmmc1, sdmmc3, spi, spi-hv, and uart.
+
+Pad configuration state example:
+       pmc: pmc@7000e400 {
+               compatible = "nvidia,tegra210-pmc";
+               reg = <0x0 0x7000e400 0x0 0x400>;
+               clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
+               clock-names = "pclk", "clk32k_in";
+
+               ...
+
+               sdmmc1_3v3: sdmmc1-3v3 {
+                       pins = "sdmmc1";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc1_1v8: sdmmc1-1v8 {
+                       pins = "sdmmc1";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
+
+               hdmi_off: hdmi-off {
+                       pins = "hdmi";
+                       low-power-enable;
+               }
+
+               hdmi_on: hdmi-on {
+                       pins = "hdmi";
+                       low-power-disable;
+               }
+       };
+
+Pinctrl client example:
+       sdmmc1: sdhci@700b0000 {
+               ...
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc1_3v3>;
+               pinctrl-1 = <&sdmmc1_1v8>;
+       };
+       ...
+       sor@54540000 {
+               ...
+               pinctrl-0 = <&hdmi_off>;
+               pinctrl-1 = <&hdmi_on>;
+               pinctrl-names = "hdmi-on", "hdmi-off";
+       };
index 0fa429534f4910f79193ed177d8da974ee9caf24..89408de55bfd2a6253000e5f7ff8b5d776bba99f 100644 (file)
@@ -60,7 +60,7 @@ Example:
                              <0xa0410100 0x100>;
                };
 
-               scu@a04100000 {
+               scu@a0410000 {
                        compatible = "arm,cortex-a9-scu";
                        reg = <0xa0410000 0x100>;
                };
index d1e60d2973874b9ffbc140cee9e7f34c2cfbe9d4..2ef86ae96df8cb1ad98b39d92f8b7e7213a67134 100644 (file)
@@ -13,6 +13,7 @@ Required Properties:
   region.
 - clocks: Reference to the parent clocks ("hosc", "losc")
 - #clock-cells: should be 1.
+- #reset-cells: should be 1.
 
 Each clock is assigned an identifier, and client nodes can use this identifier
 to specify the clock which they consume.
@@ -36,6 +37,7 @@ Example: Clock Management Unit node:
                 reg = <0x0 0xe0160000 0x0 0x1000>;
                 clocks = <&hosc>, <&losc>;
                 #clock-cells = <1>;
+                #reset-cells = <1>;
         };
 
 Example: UART controller node that consumes clock generated by the clock
index 8f8f95056f3d4d456fd62726055052a1e60277d5..e9f70fcdfe804bd6d85dffb9627e0d7eef41be7d 100644 (file)
@@ -4,6 +4,8 @@ This binding uses the common clock binding[1].
 
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 
+Slow Clock controller:
+
 Required properties:
 - compatible : shall be one of the following:
        "atmel,at91sam9x5-sckc" or
@@ -16,84 +18,6 @@ Required properties:
 
        "atmel,at91sam9x5-clk-slow-rc-osc":
                at91 internal slow RC oscillator
-
-       "atmel,<chip>-pmc":
-               at91 PMC (Power Management Controller)
-               All at91 specific clocks (clocks defined below) must be child
-               node of the PMC node.
-               <chip> can be: at91rm9200, at91sam9260, at91sam9261,
-               at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9x5,
-               sama5d2, sama5d3 or sama5d4.
-
-       "atmel,at91sam9x5-clk-slow" (under sckc node)
-       or
-       "atmel,at91sam9260-clk-slow" (under pmc node):
-               at91 slow clk
-
-       "atmel,at91rm9200-clk-main-osc"
-       "atmel,at91sam9x5-clk-main-rc-osc"
-               at91 main clk sources
-
-       "atmel,at91sam9x5-clk-main"
-       "atmel,at91rm9200-clk-main":
-               at91 main clock
-
-       "atmel,at91rm9200-clk-master" or
-       "atmel,at91sam9x5-clk-master":
-               at91 master clock
-
-       "atmel,at91sam9x5-clk-peripheral" or
-       "atmel,at91rm9200-clk-peripheral":
-               at91 peripheral clocks
-
-       "atmel,at91rm9200-clk-pll" or
-       "atmel,at91sam9g45-clk-pll" or
-       "atmel,at91sam9g20-clk-pllb" or
-       "atmel,sama5d3-clk-pll":
-               at91 pll clocks
-
-       "atmel,at91sam9x5-clk-plldiv":
-               at91 plla divisor
-
-       "atmel,at91rm9200-clk-programmable" or
-       "atmel,at91sam9g45-clk-programmable" or
-       "atmel,at91sam9x5-clk-programmable":
-               at91 programmable clocks
-
-       "atmel,at91sam9x5-clk-smd":
-               at91 SMD (Soft Modem) clock
-
-       "atmel,at91rm9200-clk-system":
-               at91 system clocks
-
-       "atmel,at91rm9200-clk-usb" or
-       "atmel,at91sam9x5-clk-usb" or
-       "atmel,at91sam9n12-clk-usb":
-               at91 usb clock
-
-       "atmel,at91sam9x5-clk-utmi":
-               at91 utmi clock
-
-       "atmel,sama5d4-clk-h32mx":
-               at91 h32mx clock
-
-       "atmel,sama5d2-clk-generated":
-               at91 generated clock
-
-       "atmel,sama5d2-clk-audio-pll-frac":
-               at91 audio fractional pll
-
-       "atmel,sama5d2-clk-audio-pll-pad":
-               at91 audio pll CLK_AUDIO output pin
-
-       "atmel,sama5d2-clk-audio-pll-pmc"
-               at91 audio pll output on AUDIOPLLCLK that feeds the PMC
-               and can be used by peripheral clock or generic clock
-
-       "atmel,sama5d2-clk-i2s-mux" (under pmc node):
-               at91 I2S clock source selection
-
-Required properties for SCKC node:
 - reg : defines the IO memory reserved for the SCKC.
 - #size-cells : shall be 0 (reg is used to encode clk id).
 - #address-cells : shall be 1 (reg is used to encode clk id).
@@ -109,428 +33,30 @@ For example:
                /* put at91 slow clocks here */
        };
 
+Power Management Controller (PMC):
 
-Required properties for internal slow RC oscillator:
-- #clock-cells : from common clock binding; shall be set to 0.
-- clock-frequency : define the internal RC oscillator frequency.
-
-Optional properties:
-- clock-accuracy : define the internal RC oscillator accuracy.
-
-For example:
-       slow_rc_osc: slow_rc_osc {
-               compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
-               clock-frequency = <32768>;
-               clock-accuracy = <50000000>;
-       };
-
-Required properties for slow oscillator:
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall encode the main osc source clk sources (see atmel datasheet).
+Required properties:
+- compatible : shall be "atmel,<chip>-pmc", "syscon":
+       <chip> can be: at91rm9200, at91sam9260, at91sam9261,
+       at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15,
+       at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5,
+       sama5d2, sama5d3 or sama5d4.
+- #clock-cells : from common clock binding; shall be set to 2. The first entry
+  is the type of the clock (core, system, peripheral or generated) and the
+  second entry its index as provided by the datasheet
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names: Must include the following entries: "slow_clk", "main_xtal"
 
 Optional properties:
 - atmel,osc-bypass : boolean property. Set this when a clock signal is directly
   provided on XIN.
 
 For example:
-       slow_osc: slow_osc {
-               compatible = "atmel,at91rm9200-clk-slow-osc";
-               #clock-cells = <0>;
-               clocks = <&slow_xtal>;
-       };
-
-Required properties for slow clock:
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall encode the slow clk sources (see atmel datasheet).
-
-For example:
-       clk32k: slck {
-               compatible = "atmel,at91sam9x5-clk-slow";
-               #clock-cells = <0>;
-               clocks = <&slow_rc_osc &slow_osc>;
-       };
-
-Required properties for PMC node:
-- reg : defines the IO memory reserved for the PMC.
-- #size-cells : shall be 0 (reg is used to encode clk id).
-- #address-cells : shall be 1 (reg is used to encode clk id).
-- interrupts : shall be set to PMC interrupt line.
-- interrupt-controller : tell that the PMC is an interrupt controller.
-- #interrupt-cells : must be set to 1. The first cell encodes the interrupt id,
-       and reflect the bit position in the PMC_ER/DR/SR registers.
-       You can use the dt macros defined in dt-bindings/clock/at91.h.
-       0 (AT91_PMC_MOSCS) -> main oscillator ready
-       1 (AT91_PMC_LOCKA) -> PLL A ready
-       2 (AT91_PMC_LOCKB) -> PLL B ready
-       3 (AT91_PMC_MCKRDY) -> master clock ready
-       6 (AT91_PMC_LOCKU) -> UTMI PLL clock ready
-       8 .. 15 (AT91_PMC_PCKRDY(id)) -> programmable clock ready
-       16 (AT91_PMC_MOSCSELS) -> main oscillator selected
-       17 (AT91_PMC_MOSCRCS) -> RC main oscillator stabilized
-       18 (AT91_PMC_CFDEV) -> clock failure detected
-
-For example:
-       pmc: pmc@fffffc00 {
-               compatible = "atmel,sama5d3-pmc";
-               interrupts = <1 4 7>;
-               interrupt-controller;
-               #interrupt-cells = <2>;
-               #size-cells = <0>;
-               #address-cells = <1>;
-
-               /* put at91 clocks here */
-       };
-
-Required properties for main clock internal RC oscillator:
-- interrupts : shall be set to "<0>".
-- clock-frequency : define the internal RC oscillator frequency.
-
-Optional properties:
-- clock-accuracy : define the internal RC oscillator accuracy.
-
-For example:
-       main_rc_osc: main_rc_osc {
-               compatible = "atmel,at91sam9x5-clk-main-rc-osc";
-               interrupt-parent = <&pmc>;
-               interrupts = <0>;
-               clock-frequency = <12000000>;
-               clock-accuracy = <50000000>;
-       };
-
-Required properties for main clock oscillator:
-- interrupts : shall be set to "<0>".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall encode the main osc source clk sources (see atmel datasheet).
-
-Optional properties:
-- atmel,osc-bypass : boolean property. Specified if a clock signal is provided
-  on XIN.
-
-  clock signal is directly provided on XIN pin.
-
-For example:
-       main_osc: main_osc {
-               compatible = "atmel,at91rm9200-clk-main-osc";
-               interrupt-parent = <&pmc>;
-               interrupts = <0>;
-               #clock-cells = <0>;
-               clocks = <&main_xtal>;
-       };
-
-Required properties for main clock:
-- interrupts : shall be set to "<0>".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall encode the main clk sources (see atmel datasheet).
-
-For example:
-       main: mainck {
-               compatible = "atmel,at91sam9x5-clk-main";
-               interrupt-parent = <&pmc>;
-               interrupts = <0>;
-               #clock-cells = <0>;
-               clocks = <&main_rc_osc &main_osc>;
-       };
-
-Required properties for master clock:
-- interrupts : shall be set to "<3>".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the master clock sources (see atmel datasheet) phandles.
-       e.g. "<&ck32k>, <&main>, <&plla>, <&pllb>".
-- atmel,clk-output-range : minimum and maximum clock frequency (two u32
-                          fields).
-          e.g. output = <0 133000000>; <=> 0 to 133MHz.
-- atmel,clk-divisors : master clock divisors table (four u32 fields).
-               0 <=> reserved value.
-               e.g. divisors = <1 2 4 6>;
-- atmel,master-clk-have-div3-pres : some SoC use the reserved value 7 in the
-                                   PRES field as CLOCK_DIV3 (e.g sam9x5).
-
-For example:
-       mck: mck {
-               compatible = "atmel,at91rm9200-clk-master";
-               interrupt-parent = <&pmc>;
-               interrupts = <3>;
-               #clock-cells = <0>;
-               atmel,clk-output-range = <0 133000000>;
-               atmel,clk-divisors = <1 2 4 0>;
-       };
-
-Required properties for peripheral clocks:
-- #size-cells : shall be 0 (reg is used to encode clk id).
-- #address-cells : shall be 1 (reg is used to encode clk id).
-- clocks : shall be the master clock phandle.
-       e.g. clocks = <&mck>;
-- name: device tree node describing a specific peripheral clock.
-       * #clock-cells : from common clock binding; shall be set to 0.
-       * reg: peripheral id. See Atmel's datasheets to get a full
-         list of peripheral ids.
-       * atmel,clk-output-range : minimum and maximum clock frequency
-         (two u32 fields). Only valid on at91sam9x5-clk-peripheral
-         compatible IPs.
-
-For example:
-       periph: periphck {
-               compatible = "atmel,at91sam9x5-clk-peripheral";
-               #size-cells = <0>;
-               #address-cells = <1>;
-               clocks = <&mck>;
-
-               ssc0_clk {
-                       #clock-cells = <0>;
-                       reg = <2>;
-                       atmel,clk-output-range = <0 133000000>;
-               };
-
-               usart0_clk {
-                       #clock-cells = <0>;
-                       reg = <3>;
-                       atmel,clk-output-range = <0 66000000>;
-               };
-       };
-
-
-Required properties for pll clocks:
-- interrupts : shall be set to "<1>".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the main clock phandle.
-- reg : pll id.
-       0 -> PLL A
-       1 -> PLL B
-- atmel,clk-input-range : minimum and maximum source clock frequency (two u32
-                         fields).
-         e.g. input = <1 32000000>; <=> 1 to 32MHz.
-- #atmel,pll-clk-output-range-cells : number of cells reserved for pll output
-                                     range description. Sould be set to 2, 3
-                                     or 4.
-       * 1st and 2nd cells represent the frequency range (min-max).
-       * 3rd cell is optional and represents the OUT field value for the given
-         range.
-       * 4th cell is optional and represents the ICPLL field (PLLICPR
-         register)
-- atmel,pll-clk-output-ranges : pll output frequency ranges + optional parameter
-                               depending on #atmel,pll-output-range-cells
-                               property value.
-
-For example:
-       plla: pllack {
-               compatible = "atmel,at91sam9g45-clk-pll";
-               interrupt-parent = <&pmc>;
-               interrupts = <1>;
-               #clock-cells = <0>;
-               clocks = <&main>;
-               reg = <0>;
-               atmel,clk-input-range = <2000000 32000000>;
-               #atmel,pll-clk-output-range-cells = <4>;
-               atmel,pll-clk-output-ranges = <74500000 800000000 0 0
-                                              69500000 750000000 1 0
-                                              64500000 700000000 2 0
-                                              59500000 650000000 3 0
-                                              54500000 600000000 0 1
-                                              49500000 550000000 1 1
-                                              44500000 500000000 2 1
-                                              40000000 450000000 3 1>;
-       };
-
-Required properties for plldiv clocks (plldiv = pll / 2):
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the plla clock phandle.
-
-The pll divisor is equal to 2 and cannot be changed.
-
-For example:
-       plladiv: plladivck {
-               compatible = "atmel,at91sam9x5-clk-plldiv";
-               #clock-cells = <0>;
-               clocks = <&plla>;
-       };
-
-Required properties for programmable clocks:
-- #size-cells : shall be 0 (reg is used to encode clk id).
-- #address-cells : shall be 1 (reg is used to encode clk id).
-- clocks : shall be the programmable clock source phandles.
-       e.g. clocks = <&clk32k>, <&main>, <&plla>, <&pllb>;
-- name: device tree node describing a specific prog clock.
-       * #clock-cells : from common clock binding; shall be set to 0.
-       * reg : programmable clock id (register offset from  PCKx
-                        register).
-       * interrupts : shall be set to "<(8 + id)>".
-
-For example:
-       prog: progck {
-               compatible = "atmel,at91sam9g45-clk-programmable";
-               #size-cells = <0>;
-               #address-cells = <1>;
-               interrupt-parent = <&pmc>;
-               clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>;
-
-               prog0 {
-                       #clock-cells = <0>;
-                       reg = <0>;
-                       interrupts = <8>;
-               };
-
-               prog1 {
-                       #clock-cells = <0>;
-                       reg = <1>;
-                       interrupts = <9>;
-               };
-       };
-
-
-Required properties for smd clock:
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the smd clock source phandles.
-       e.g. clocks = <&plladiv>, <&utmi>;
-
-For example:
-       smd: smdck {
-               compatible = "atmel,at91sam9x5-clk-smd";
-               #clock-cells = <0>;
-               clocks = <&plladiv>, <&utmi>;
-       };
-
-Required properties for system clocks:
-- #size-cells : shall be 0 (reg is used to encode clk id).
-- #address-cells : shall be 1 (reg is used to encode clk id).
-- name: device tree node describing a specific system clock.
-       * #clock-cells : from common clock binding; shall be set to 0.
-       * reg: system clock id (bit position in SCER/SCDR/SCSR registers).
-             See Atmel's datasheet to get a full list of system clock ids.
-
-For example:
-       system: systemck {
-               compatible = "atmel,at91rm9200-clk-system";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ddrck {
-                       #clock-cells = <0>;
-                       reg = <2>;
-                       clocks = <&mck>;
-               };
-
-               uhpck {
-                       #clock-cells = <0>;
-                       reg = <6>;
-                       clocks = <&usb>;
-               };
-
-               udpck {
-                       #clock-cells = <0>;
-                       reg = <7>;
-                       clocks = <&usb>;
-               };
-       };
-
-
-Required properties for usb clock:
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the smd clock source phandles.
-       e.g. clocks = <&pllb>;
-- atmel,clk-divisors (only available for "atmel,at91rm9200-clk-usb"):
-       usb clock divisor table.
-       e.g. divisors = <1 2 4 0>;
-
-For example:
-       usb: usbck {
-               compatible = "atmel,at91sam9x5-clk-usb";
-               #clock-cells = <0>;
-               clocks = <&plladiv>, <&utmi>;
-       };
-
-       usb: usbck {
-               compatible = "atmel,at91rm9200-clk-usb";
-               #clock-cells = <0>;
-               clocks = <&pllb>;
-               atmel,clk-divisors = <1 2 4 0>;
-       };
-
-
-Required properties for utmi clock:
-- interrupts : shall be set to "<AT91_PMC_LOCKU IRQ_TYPE_LEVEL_HIGH>".
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the main clock source phandle.
-
-For example:
-       utmi: utmick {
-               compatible = "atmel,at91sam9x5-clk-utmi";
-               interrupt-parent = <&pmc>;
-               interrupts = <AT91_PMC_LOCKU IRQ_TYPE_LEVEL_HIGH>;
-               #clock-cells = <0>;
-               clocks = <&main>;
-       };
-
-Required properties for 32 bits bus Matrix clock (h32mx clock):
-- #clock-cells : from common clock binding; shall be set to 0.
-- clocks : shall be the master clock source phandle.
-
-For example:
-       h32ck: h32mxck {
-               #clock-cells = <0>;
-               compatible = "atmel,sama5d4-clk-h32mx";
-               clocks = <&mck>;
-       };
-
-Required properties for generated clocks:
-- #size-cells : shall be 0 (reg is used to encode clk id).
-- #address-cells : shall be 1 (reg is used to encode clk id).
-- clocks : shall be the generated clock source phandles.
-       e.g. clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
-- name: device tree node describing a specific generated clock.
-       * #clock-cells : from common clock binding; shall be set to 0.
-       * reg: peripheral id. See Atmel's datasheets to get a full
-         list of peripheral ids.
-       * atmel,clk-output-range : minimum and maximum clock frequency
-         (two u32 fields).
-
-For example:
-       gck {
-               compatible = "atmel,sama5d2-clk-generated";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
-
-               tcb0_gclk: tcb0_gclk {
-                       #clock-cells = <0>;
-                       reg = <35>;
-                       atmel,clk-output-range = <0 83000000>;
-               };
-
-               pwm_gclk: pwm_gclk {
-                       #clock-cells = <0>;
-                       reg = <38>;
-                       atmel,clk-output-range = <0 83000000>;
-               };
-       };
-
-Required properties for I2S mux clocks:
-- #size-cells : shall be 0 (reg is used to encode I2S bus id).
-- #address-cells : shall be 1 (reg is used to encode I2S bus id).
-- name: device tree node describing a specific mux clock.
-       * #clock-cells : from common clock binding; shall be set to 0.
-       * clocks : shall be the mux clock parent phandles; shall be 2 phandles:
-         peripheral and generated clock; the first phandle shall belong to the
-         peripheral clock and the second one shall belong to the generated
-         clock; "clock-indices" property can be user to specify
-         the correct order.
-       * reg: I2S bus id of the corresponding mux clock.
-         e.g. reg = <0>; for i2s0, reg = <1>; for i2s1
-
-For example:
-       i2s_clkmux {
-               compatible = "atmel,sama5d2-clk-i2s-mux";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               i2s0muxck: i2s0_muxclk {
-                       clocks = <&i2s0_clk>, <&i2s0_gclk>;
-                       #clock-cells = <0>;
-                       reg = <0>;
-               };
-
-               i2s1muxck: i2s1_muxclk {
-                       clocks = <&i2s1_clk>, <&i2s1_gclk>;
-                       #clock-cells = <0>;
-                       reg = <1>;
-               };
+       pmc: pmc@f0018000 {
+               compatible = "atmel,sama5d4-pmc", "syscon";
+               reg = <0xf0018000 0x120>;
+               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+               #clock-cells = <2>;
+               clocks = <&clk32k>, <&main_xtal>;
+               clock-names = "slow_clk", "main_xtal";
        };
diff --git a/Documentation/devicetree/bindings/clock/hi3670-clock.txt b/Documentation/devicetree/bindings/clock/hi3670-clock.txt
new file mode 100644 (file)
index 0000000..66f3697
--- /dev/null
@@ -0,0 +1,43 @@
+* Hisilicon Hi3670 Clock Controller
+
+The Hi3670 clock controller generates and supplies clock to various
+controllers within the Hi3670 SoC.
+
+Required Properties:
+
+- compatible: the compatible should be one of the following strings to
+       indicate the clock controller functionality.
+
+       - "hisilicon,hi3670-crgctrl"
+       - "hisilicon,hi3670-pctrl"
+       - "hisilicon,hi3670-pmuctrl"
+       - "hisilicon,hi3670-sctrl"
+       - "hisilicon,hi3670-iomcu"
+       - "hisilicon,hi3670-media1-crg"
+       - "hisilicon,hi3670-media2-crg"
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in <dt-bindings/clock/hi3670-clock.h>.
+
+Examples:
+       crg_ctrl: clock-controller@fff35000 {
+               compatible = "hisilicon,hi3670-crgctrl", "syscon";
+               reg = <0x0 0xfff35000 0x0 0x1000>;
+               #clock-cells = <1>;
+       };
+
+       uart0: serial@fdf02000 {
+               compatible = "arm,pl011", "arm,primecell";
+               reg = <0x0 0xfdf02000 0x0 0x1000>;
+               interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&crg_ctrl HI3670_CLK_GATE_UART0>,
+                        <&crg_ctrl HI3670_PCLK>;
+               clock-names = "uartclk", "apb_pclk";
+       };
index a45ca67a9d5f26f72844e9cee49ffd434f9cd9c4..e1308346e00daf0fe58d66cb427d99a1889837c6 100644 (file)
@@ -6,6 +6,14 @@ Required properties:
 - interrupts: Should contain CCM interrupt
 - #clock-cells: Should be <1>
 
+Optional properties:
+- fsl,pmic-stby-poweroff: Configure CCM to assert PMIC_STBY_REQ signal
+  on power off.
+  Use this property if the SoC should be powered off by external power
+  management IC (PMIC) triggered via PMIC_STBY_REQ signal.
+  Boards that are designed to initiate poweroff on PMIC_ON_REQ signal should
+  be using "syscon-poweroff" driver instead.
+
 The clock consumer should specify the desired clock by having the clock
 ID in its "clocks" phandle cell.  See include/dt-bindings/clock/imx6qdl-clock.h
 for the full list of i.MX6 Quad and DualLite clock IDs.
index f8d4134ae4095682182be5313148ddb2394ec017..ba5a442026b71d65e7bda99bd801ec35bc5fed57 100644 (file)
@@ -6,8 +6,11 @@ to provide many different clock signals derived from only 2 external source
 clocks.
 
 Required properties:
-- compatible : Should be "ingenic,<soctype>-cgu".
-  For example "ingenic,jz4740-cgu" or "ingenic,jz4780-cgu".
+- compatible : Should be one of:
+  * ingenic,jz4740-cgu
+  * ingenic,jz4725b-cgu
+  * ingenic,jz4770-cgu
+  * ingenic,jz4780-cgu
 - reg : The address & length of the CGU registers.
 - clocks : List of phandle & clock specifiers for clocks external to the CGU.
   Two such external clocks should be specified - first the external crystal
diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt b/Documentation/devicetree/bindings/clock/qcom,camcc.txt
new file mode 100644 (file)
index 0000000..c5eb669
--- /dev/null
@@ -0,0 +1,18 @@
+Qualcomm Camera Clock & Reset Controller Binding
+------------------------------------------------
+
+Required properties :
+- compatible : shall contain "qcom,sdm845-camcc".
+- reg : shall contain base register location and length.
+- #clock-cells : from common clock binding, shall contain 1.
+- #reset-cells : from common reset binding, shall contain 1.
+- #power-domain-cells : from generic power domain binding, shall contain 1.
+
+Example:
+       camcc: clock-controller@ad00000 {
+               compatible = "qcom,sdm845-camcc";
+               reg = <0xad00000 0x10000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+               #power-domain-cells = <1>;
+       };
index 664ea1fd6c76a18ce158b4fc01b536ba31dfeeda..52d9345c9927b80c40acba737f20f83f4fcbc8e7 100644 (file)
@@ -19,6 +19,9 @@ Required properties :
                        "qcom,gcc-msm8996"
                        "qcom,gcc-msm8998"
                        "qcom,gcc-mdm9615"
+                       "qcom,gcc-qcs404"
+                       "qcom,gcc-sdm630"
+                       "qcom,gcc-sdm660"
                        "qcom,gcc-sdm845"
 
 - reg : shall contain base register location and length
diff --git a/Documentation/devicetree/bindings/clock/qcom,hfpll.txt b/Documentation/devicetree/bindings/clock/qcom,hfpll.txt
new file mode 100644 (file)
index 0000000..ec02a02
--- /dev/null
@@ -0,0 +1,60 @@
+High-Frequency PLL (HFPLL)
+
+PROPERTIES
+
+- compatible:
+       Usage: required
+       Value type: <string>:
+               shall contain only one of the following. The generic
+               compatible "qcom,hfpll" should be also included.
+
+                        "qcom,hfpll-ipq8064", "qcom,hfpll"
+                        "qcom,hfpll-apq8064", "qcom,hfpll"
+                        "qcom,hfpll-msm8974", "qcom,hfpll"
+                        "qcom,hfpll-msm8960", "qcom,hfpll"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: address and size of HPLL registers. An optional second
+                   element specifies the address and size of the alias
+                   register region.
+
+- clocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: reference to the xo clock.
+
+- clock-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "xo".
+
+- clock-output-names:
+       Usage: required
+       Value type: <string>
+       Definition: Name of the PLL. Typically hfpllX where X is a CPU number
+                   starting at 0. Otherwise hfpll_Y where Y is more specific
+                   such as "l2".
+
+Example:
+
+1) An HFPLL for the L2 cache.
+
+       clock-controller@f9016000 {
+               compatible = "qcom,hfpll-ipq8064", "qcom,hfpll";
+               reg = <0xf9016000 0x30>;
+               clocks = <&xo_board>;
+               clock-names = "xo";
+               clock-output-names = "hfpll_l2";
+       };
+
+2) An HFPLL for CPU0. This HFPLL has the alias register region.
+
+       clock-controller@f908a000 {
+               compatible = "qcom,hfpll-ipq8064", "qcom,hfpll";
+               reg = <0xf908a000 0x30>, <0xf900a000 0x30>;
+               clocks = <&xo_board>;
+               clock-names = "xo";
+               clock-output-names = "hfpll0";
+       };
diff --git a/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
new file mode 100644 (file)
index 0000000..030ba60
--- /dev/null
@@ -0,0 +1,34 @@
+Krait Clock Controller
+
+PROPERTIES
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be one of:
+                       "qcom,krait-cc-v1"
+                       "qcom,krait-cc-v2"
+
+- #clock-cells:
+       Usage: required
+       Value type: <u32>
+       Definition: must be 1
+
+- clocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: reference to the clock parents of hfpll, secondary muxes.
+
+- clock-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb".
+
+Example:
+
+       kraitcc: clock-controller {
+               compatible = "qcom,krait-cc-v1";
+               clocks = <&hfpll0>, <&hfpll1>, <&acpu0_aux>, <&acpu1_aux>, <qsb>;
+               clock-names = "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb";
+               #clock-cells = <1>;
+       };
index db542abadb75bf0ca395ac0910506bce458fecee..916a601b76a7704931df7797e48f52276e4fd674 100644 (file)
@@ -13,9 +13,13 @@ They provide the following functionalities:
 
 Required Properties:
   - compatible: Must be one of:
+      - "renesas,r7s9210-cpg-mssr" for the r7s9210 SoC (RZ/A2)
       - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M)
+      - "renesas,r8a7744-cpg-mssr" for the r8a7744 SoC (RZ/G1N)
       - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E)
       - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C)
+      - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M)
+      - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E)
       - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2)
       - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W)
       - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H)
@@ -35,12 +39,13 @@ Required Properties:
   - clocks: References to external parent clocks, one entry for each entry in
     clock-names
   - clock-names: List of external parent clock names. Valid names are:
-      - "extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7792,
-                r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970,
-                r8a77980, r8a77990, r8a77995)
-      - "extalr" (r8a7795, r8a7796, r8a77965, r8a77970, r8a77980)
-      - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793,
-                    r8a7794)
+      - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1,
+                r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794,
+                r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990,
+                r8a77995)
+      - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980)
+      - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791,
+                    r8a7793, r8a7794)
 
   - #clock-cells: Must be 2
       - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
index fcf6979c0b6d3e0ba95f22ea70e56d103ac77d1e..41f133a4e2fa72014b37083437fdf99b09710172 100644 (file)
@@ -7,16 +7,23 @@ assorted actions.
 
 Required properties:
 - compatible: must contain one of the following:
- * "qcom,scm-apq8064" for APQ8064 platforms
- * "qcom,scm-msm8660" for MSM8660 platforms
- * "qcom,scm-msm8690" for MSM8690 platforms
- * "qcom,scm-msm8996" for MSM8996 platforms
- * "qcom,scm-ipq4019" for IPQ4019 platforms
- * "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc)
-- clocks: One to three clocks may be required based on compatible.
- * No clock required for "qcom,scm-msm8996", "qcom,scm-ipq4019"
- * Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960"
- * Core, iface, and bus clocks required for "qcom,scm"
+ * "qcom,scm-apq8064"
+ * "qcom,scm-apq8084"
+ * "qcom,scm-msm8660"
+ * "qcom,scm-msm8916"
+ * "qcom,scm-msm8960"
+ * "qcom,scm-msm8974"
+ * "qcom,scm-msm8996"
+ * "qcom,scm-msm8998"
+ * "qcom,scm-ipq4019"
+ * "qcom,scm-sdm845"
+ and:
+ * "qcom,scm"
+- clocks: Specifies clocks needed by the SCM interface, if any:
+ * core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660" and
+   "qcom,scm-msm8960"
+ * core, iface and bus clocks required for "qcom,scm-apq8084",
+   "qcom,scm-msm8916" and "qcom,scm-msm8974"
 - clock-names: Must contain "core" for the core clock, "iface" for the interface
   clock and "bus" for the bus clock per the requirements of the compatible.
 - qcom,dload-mode: phandle to the TCSR hardware block and offset of the
@@ -26,8 +33,10 @@ Example for MSM8916:
 
        firmware {
                scm {
-                       compatible = "qcom,scm";
-                       clocks = <&gcc GCC_CRYPTO_CLK> , <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>;
+                       compatible = "qcom,msm8916", "qcom,scm";
+                       clocks = <&gcc GCC_CRYPTO_CLK> ,
+                                <&gcc GCC_CRYPTO_AXI_CLK>,
+                                <&gcc GCC_CRYPTO_AHB_CLK>;
                        clock-names = "core", "bus", "iface";
                };
        };
diff --git a/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt b/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
new file mode 100644 (file)
index 0000000..614bac5
--- /dev/null
@@ -0,0 +1,82 @@
+-----------------------------------------------------------------
+Device Tree Bindings for the Xilinx Zynq MPSoC Firmware Interface
+-----------------------------------------------------------------
+
+The zynqmp-firmware node describes the interface to platform firmware.
+ZynqMP has an interface to communicate with secure firmware. Firmware
+driver provides an interface to firmware APIs. Interface APIs can be
+used by any driver to communicate to PMUFW(Platform Management Unit).
+These requests include clock management, pin control, device control,
+power management service, FPGA service and other platform management
+services.
+
+Required properties:
+ - compatible: Must contain:   "xlnx,zynqmp-firmware"
+ - method:     The method of calling the PM-API firmware layer.
+               Permitted values are:
+                 - "smc" : SMC #0, following the SMCCC
+                 - "hvc" : HVC #0, following the SMCCC
+
+--------------------------------------------------------------------------
+Device Tree Clock bindings for the Zynq Ultrascale+ MPSoC controlled using
+Zynq MPSoC firmware interface
+--------------------------------------------------------------------------
+The clock controller is a h/w block of Zynq Ultrascale+ MPSoC clock
+tree. It reads required input clock frequencies from the devicetree and acts
+as clock provider for all clock consumers of PS clocks.
+
+See clock_bindings.txt for more information on the generic clock bindings.
+
+Required properties:
+ - #clock-cells:       Must be 1
+ - compatible:         Must contain:   "xlnx,zynqmp-clk"
+ - clocks:             List of clock specifiers which are external input
+                       clocks to the given clock controller. Please refer
+                       the next section to find the input clocks for a
+                       given controller.
+ - clock-names:                List of clock names which are exteral input clocks
+                       to the given clock controller. Please refer to the
+                       clock bindings for more details.
+
+Input clocks for zynqmp Ultrascale+ clock controller:
+
+The Zynq UltraScale+ MPSoC has one primary and four alternative reference clock
+inputs. These required clock inputs are:
+ - pss_ref_clk (PS reference clock)
+ - video_clk (reference clock for video system )
+ - pss_alt_ref_clk (alternative PS reference clock)
+ - aux_ref_clk
+ - gt_crx_ref_clk (transceiver reference clock)
+
+The following strings are optional parameters to the 'clock-names' property in
+order to provide an optional (E)MIO clock source:
+ - swdt0_ext_clk
+ - swdt1_ext_clk
+ - gem0_emio_clk
+ - gem1_emio_clk
+ - gem2_emio_clk
+ - gem3_emio_clk
+ - mio_clk_XX          # with XX = 00..77
+ - mio_clk_50_or_51    #for the mux clock to gem tsu from 50 or 51
+
+
+Output clocks are registered based on clock information received
+from firmware. Output clocks indexes are mentioned in
+include/dt-bindings/clock/xlnx,zynqmp-clk.h.
+
+-------
+Example
+-------
+
+firmware {
+       zynqmp_firmware: zynqmp-firmware {
+               compatible = "xlnx,zynqmp-firmware";
+               method = "smc";
+               zynqmp_clk: clock-controller {
+                       #clock-cells = <1>;
+                       compatible = "xlnx,zynqmp-clk";
+                       clocks = <&pss_ref_clk>, <&video_clk>, <&pss_alt_ref_clk>, <&aux_ref_clk>, <&gt_crx_ref_clk>;
+                       clock-names = "pss_ref_clk", "video_clk", "pss_alt_ref_clk","aux_ref_clk", "gt_crx_ref_clk";
+               };
+       };
+};
index fbb0a6d8b9643540e4f5c2e084216b5e66560b2e..3e4bcc2fb6f71f7d81646ebe01a0f7a44396a46f 100644 (file)
@@ -3,6 +3,7 @@
 Required properties :
 
  - compatible : should be "snps,designware-i2c"
+                or "mscc,ocelot-i2c" with "snps,designware-i2c" for fallback
  - reg : Offset and length of the register set for the device
  - interrupts : <IRQ> where IRQ is the interrupt number.
 
@@ -11,8 +12,12 @@ Recommended properties :
  - clock-frequency : desired I2C bus clock frequency in Hz.
 
 Optional properties :
+ - reg : for "mscc,ocelot-i2c", a second register set to configure the SDA hold
+   time, named ICPU_CFG:TWI_DELAY in the datasheet.
+
  - i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds.
-   This option is only supported in hardware blocks version 1.11a or newer.
+   This option is only supported in hardware blocks version 1.11a or newer and
+   on Microsemi SoCs ("mscc,ocelot-i2c" compatible).
 
  - i2c-scl-falling-time-ns : should contain the SCL falling time in nanoseconds.
    This value which is by default 300ns is used to compute the tLOW period.
index 39cd21d95810628b259f22247aebc654cb0e7fa6..30c0485b167b4d9db9a240423d04ab004005ab91 100644 (file)
@@ -3,7 +3,9 @@ I2C for R-Car platforms
 Required properties:
 - compatible:
        "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC.
+       "renesas,i2c-r8a7744" if the device is a part of a R8A7744 SoC.
        "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC.
+       "renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC.
        "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC.
        "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
        "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
index 872673adff5aae3db366d1e202b8f4a5118ce825..d81b626436550e48129bb964bda0c141be99e1ee 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
                        - "renesas,iic-r8a73a4" (R-Mobile APE6)
                        - "renesas,iic-r8a7740" (R-Mobile A1)
                        - "renesas,iic-r8a7743" (RZ/G1M)
+                       - "renesas,iic-r8a7744" (RZ/G1N)
                        - "renesas,iic-r8a7745" (RZ/G1E)
                        - "renesas,iic-r8a774a1" (RZ/G2M)
                        - "renesas,iic-r8a7790" (R-Car H2)
diff --git a/Documentation/devicetree/bindings/iio/accel/adxl372.txt b/Documentation/devicetree/bindings/iio/accel/adxl372.txt
new file mode 100644 (file)
index 0000000..a289964
--- /dev/null
@@ -0,0 +1,33 @@
+Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer
+
+http://www.analog.com/media/en/technical-documentation/data-sheets/adxl372.pdf
+
+Required properties:
+ - compatible : should be "adi,adxl372"
+ - reg: the I2C address or SPI chip select number for the device
+
+Required properties for SPI bus usage:
+ - spi-max-frequency: Max SPI frequency to use
+
+Optional properties:
+ - interrupts: interrupt mapping for IRQ as documented in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example for a I2C device node:
+
+       accelerometer@53 {
+               compatible = "adi,adxl372";
+               reg = <0x53>;
+               interrupt-parent = <&gpio>;
+               interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+       };
+
+Example for a SPI device node:
+
+       accelerometer@0 {
+               compatible = "adi,adxl372";
+               reg = <0>;
+               spi-max-frequency = <1000000>;
+               interrupt-parent = <&gpio>;
+               interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+       };
diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3911.txt b/Documentation/devicetree/bindings/iio/adc/mcp3911.txt
new file mode 100644 (file)
index 0000000..3071f48
--- /dev/null
@@ -0,0 +1,30 @@
+* Microchip MCP3911 Dual channel analog front end (ADC)
+
+Required properties:
+ - compatible: Should be "microchip,mcp3911"
+ - reg: SPI chip select number for the device
+
+Recommended properties:
+ - spi-max-frequency: Definition as per
+        Documentation/devicetree/bindings/spi/spi-bus.txt.
+        Max frequency for this chip is 20MHz.
+
+Optional properties:
+ - clocks: Phandle and clock identifier for sampling clock
+ - interrupt-parent: Phandle to the parent interrupt controller
+ - interrupts: IRQ line for the ADC
+ - microchip,device-addr: Device address when multiple MCP3911 chips are present on the
+       same SPI bus. Valid values are 0-3. Defaults to 0.
+ - vref-supply: Phandle to the external reference voltage supply.
+
+Example:
+adc@0 {
+       compatible = "microchip,mcp3911";
+       reg = <0>;
+       interrupt-parent = <&gpio5>;
+       interrupts = <15 IRQ_TYPE_EDGE_RISING>;
+       spi-max-frequency = <20000000>;
+       microchip,device-addr = <0>;
+       vref-supply = <&vref_reg>;
+       clocks = <&xtal>;
+};
index 0fb46137f9369c5c5e94080356e326e450551c06..b3c86f4ac7cdb95ee6674017aecc45fa422294a9 100644 (file)
@@ -1,7 +1,9 @@
-Qualcomm's SPMI PMIC voltage ADC
+Qualcomm's SPMI PMIC ADC
 
-SPMI PMIC voltage ADC (VADC) provides interface to clients to read
-voltage. The VADC is a 15-bit sigma-delta ADC.
+- SPMI PMIC voltage ADC (VADC) provides interface to clients to read
+  voltage. The VADC is a 15-bit sigma-delta ADC.
+- SPMI PMIC5 voltage ADC (ADC) provides interface to clients to read
+  voltage. The VADC is a 16-bit sigma-delta ADC.
 
 VADC node:
 
@@ -9,11 +11,13 @@ VADC node:
     Usage: required
     Value type: <string>
     Definition: Should contain "qcom,spmi-vadc".
+                Should contain "qcom,spmi-adc5" for PMIC5 ADC driver.
+                Should contain "qcom,spmi-adc-rev2" for PMIC rev2 ADC driver.
 
 - reg:
     Usage: required
     Value type: <prop-encoded-array>
-    Definition: VADC base address and length in the SPMI PMIC register map.
+    Definition: VADC base address in the SPMI PMIC register map.
 
 - #address-cells:
     Usage: required
@@ -45,13 +49,26 @@ Channel node properties:
     Definition: ADC channel number.
             See include/dt-bindings/iio/qcom,spmi-vadc.h
 
+- label:
+    Usage: required for "qcom,spmi-adc5" and "qcom,spmi-adc-rev2"
+    Value type: <empty>
+    Definition: ADC input of the platform as seen in the schematics.
+            For thermistor inputs connected to generic AMUX or GPIO inputs
+            these can vary across platform for the same pins. Hence select
+            the platform schematics name for this channel.
+
 - qcom,decimation:
     Usage: optional
     Value type: <u32>
     Definition: This parameter is used to decrease ADC sampling rate.
             Quicker measurements can be made by reducing decimation ratio.
-            Valid values are 512, 1024, 2048, 4096.
-            If property is not found, default value of 512 will be used.
+            - For compatible property "qcom,spmi-vadc", valid values are
+              512, 1024, 2048, 4096. If property is not found, default value
+              of 512 will be used.
+            - For compatible property "qcom,spmi-adc5", valid values are 250, 420
+              and 840. If property is not found, default value of 840 is used.
+            - For compatible property "qcom,spmi-adc-rev2", valid values are 256,
+              512 and 1024. If property is not present, default value is 1024.
 
 - qcom,pre-scaling:
     Usage: optional
@@ -66,21 +83,38 @@ Channel node properties:
 - qcom,ratiometric:
     Usage: optional
     Value type: <empty>
-    Definition: Channel calibration type. If this property is specified
-            VADC will use the VDD reference (1.8V) and GND for channel
-            calibration. If property is not found, channel will be
-            calibrated with 0.625V and 1.25V reference channels, also
-            known as absolute calibration.
+    Definition: Channel calibration type.
+            - For compatible property "qcom,spmi-vadc", if this property is
+              specified VADC will use the VDD reference (1.8V) and GND for
+              channel calibration. If property is not found, channel will be
+              calibrated with 0.625V and 1.25V reference channels, also
+              known as absolute calibration.
+            - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2",
+              if this property is specified VADC will use the VDD reference
+              (1.875V) and GND for channel calibration. If property is not found,
+              channel will be calibrated with 0V and 1.25V reference channels,
+              also known as absolute calibration.
 
 - qcom,hw-settle-time:
     Usage: optional
     Value type: <u32>
     Definition: Time between AMUX getting configured and the ADC starting
-            conversion. Delay = 100us * (value) for value < 11, and
-            2ms * (value - 10) otherwise.
-            Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800,
-            900 us and 1, 2, 4, 6, 8, 10 ms
-            If property is not found, channel will use 0us.
+            conversion. The 'hw_settle_time' is an index used from valid values
+            and programmed in hardware to achieve the hardware settling delay.
+            - For compatible property "qcom,spmi-vadc" and "qcom,spmi-adc-rev2",
+              Delay = 100us * (hw_settle_time) for hw_settle_time < 11,
+              and 2ms * (hw_settle_time - 10) otherwise.
+              Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800,
+              900 us and 1, 2, 4, 6, 8, 10 ms.
+              If property is not found, channel will use 0us.
+            - For compatible property "qcom,spmi-adc5", delay = 15us for
+              value 0, 100us * (value) for values < 11,
+              and 2ms * (value - 10) otherwise.
+              Valid values are: 15, 100, 200, 300, 400, 500, 600, 700, 800,
+              900 us and 1, 2, 4, 6, 8, 10 ms
+              Certain controller digital versions have valid values of
+              15, 100, 200, 300, 400, 500, 600, 700, 1, 2, 4, 8, 16, 32, 64, 128 ms
+              If property is not found, channel will use 15us.
 
 - qcom,avg-samples:
     Usage: optional
@@ -89,13 +123,18 @@ Channel node properties:
             Averaging provides the option to obtain a single measurement
             from the ADC that is an average of multiple samples. The value
             selected is 2^(value).
-            Valid values are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
-            If property is not found, 1 sample will be used.
+            - For compatible property "qcom,spmi-vadc", valid values
+              are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
+              If property is not found, 1 sample will be used.
+            - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2",
+              valid values are: 1, 2, 4, 8, 16
+              If property is not found, 1 sample will be used.
 
 NOTE:
 
-Following channels, also known as reference point channels, are used for
-result calibration and their channel configuration nodes should be defined:
+For compatible property "qcom,spmi-vadc" following channels, also known as
+reference point channels, are used for result calibration and their channel
+configuration nodes should be defined:
 VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
 VADC_GND_REF and VADC_VDD_VADC.
 
@@ -104,7 +143,7 @@ Example:
        /* VADC node */
        pmic_vadc: vadc@3100 {
                compatible = "qcom,spmi-vadc";
-               reg = <0x3100 0x100>;
+               reg = <0x3100>;
                interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
                #address-cells = <1>;
                #size-cells = <0>;
index 8aad960de50bebdecd95ebbc899a4f9844804184..b4daa15dcf15f07d2fa2690e159d0501c27c6900 100644 (file)
@@ -12,6 +12,8 @@ Required properties:
 - interrupts: The interrupt number for the ADC device.
 - #io-channel-cells: Number of cells in an IIO specifier.
 - hwlocks: Reference to a phandle of a hwlock provider node.
+- nvmem-cells: A phandle to the calibration cells provided by eFuse device.
+- nvmem-cell-names: Should be "big_scale_calib", "small_scale_calib".
 
 Example:
 
@@ -32,5 +34,7 @@ Example:
                        interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
                        #io-channel-cells = <1>;
                        hwlocks = <&hwlock 4>;
+                       nvmem-cells = <&adc_big_scale>, <&adc_small_scale>;
+                       nvmem-cell-names = "big_scale_calib", "small_scale_calib";
                };
        };
index bba01a5cab1bad1a4ce5ca43f8fbe9ddd8fe3bf6..2f607f41f9d3139c1cebd4ef7a8c80a1abf4ea74 100644 (file)
@@ -50,6 +50,9 @@ Required properties:
 
 Optional properties:
 
+ - reset-gpios : GPIO spec for the RESET pin. If specified, it will be
+                asserted during driver probe.
+
  - adi,dc-dc-ilim-microamp: The dc-to-dc converter current limit
                   The following values are currently supported [uA]:
                        * 150000
@@ -71,6 +74,8 @@ AD5758 Example:
                spi-max-frequency = <1000000>;
                spi-cpha;
 
+               reset-gpios = <&gpio 22 0>;
+
                adi,dc-dc-mode = <2>;
                adi,range-microvolt = <0 10000000>;
                adi,dc-dc-ilim-microamp = <200000>;
diff --git a/Documentation/devicetree/bindings/iio/dac/ltc1660.txt b/Documentation/devicetree/bindings/iio/dac/ltc1660.txt
new file mode 100644 (file)
index 0000000..c5b5f22
--- /dev/null
@@ -0,0 +1,21 @@
+* Linear Technology Micropower octal 8-Bit and 10-Bit DACs
+
+Required properties:
+ - compatible: Must be one of the following:
+               "lltc,ltc1660"
+               "lltc,ltc1665"
+ - reg: SPI chip select number for the device
+ - vref-supply: Phandle to the voltage reference supply
+
+Recommended properties:
+ - spi-max-frequency: Definition as per
+        Documentation/devicetree/bindings/spi/spi-bus.txt.
+        Max frequency for this chip is 5 MHz.
+
+Example:
+dac@0 {
+       compatible = "lltc,ltc1660";
+       reg = <0>;
+       spi-max-frequency = <5000000>;
+       vref-supply = <&vref_reg>;
+};
index b2f27da847b88a23fd6c6642a9ee5f3f0a6789ba..6ab9a9d196b06f3600b1ad183dadfb5b194250c3 100644 (file)
@@ -20,6 +20,7 @@ Required properties:
   bindings.
 
 Optional properties:
+ - vddio-supply: regulator phandle for VDDIO supply
  - mount-matrix: an optional 3x3 mounting rotation matrix
  - i2c-gate node.  These devices also support an auxiliary i2c bus.  This is
    simple enough to be described using the i2c-gate binding. See
index ea2d6e0ae4c593be794ee2a948943dc6cc91fb04..879322ad50fdd2dcee6a30808e687f8994e3e2b7 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
   "st,lsm6dsl"
   "st,lsm6dsm"
   "st,ism330dlc"
+  "st,lsm6dso"
 - reg: i2c address of the sensor / spi cs line
 
 Optional properties:
diff --git a/Documentation/devicetree/bindings/iio/light/bh1750.txt b/Documentation/devicetree/bindings/iio/light/bh1750.txt
new file mode 100644 (file)
index 0000000..1e76857
--- /dev/null
@@ -0,0 +1,18 @@
+ROHM BH1750 - ALS, Ambient light sensor
+
+Required properties:
+
+- compatible: Must be one of:
+    "rohm,bh1710"
+    "rohm,bh1715"
+    "rohm,bh1721"
+    "rohm,bh1750"
+    "rohm,bh1751"
+- reg: the I2C address of the sensor
+
+Example:
+
+light-sensor@23 {
+       compatible = "rohm,bh1750";
+       reg = <0x23>;
+};
diff --git a/Documentation/devicetree/bindings/iio/light/tsl2772.txt b/Documentation/devicetree/bindings/iio/light/tsl2772.txt
new file mode 100644 (file)
index 0000000..1c5e6f1
--- /dev/null
@@ -0,0 +1,42 @@
+* AMS/TAOS ALS and proximity sensor
+
+Required properties:
+
+  - compatible: Should be one of
+               "amstaos,tsl2571"
+               "amstaos,tsl2671"
+               "amstaos,tmd2671"
+               "amstaos,tsl2771"
+               "amstaos,tmd2771"
+               "amstaos,tsl2572"
+               "amstaos,tsl2672"
+               "amstaos,tmd2672"
+               "amstaos,tsl2772"
+               "amstaos,tmd2772"
+               "avago,apds9930"
+  - reg: the I2C address of the device
+
+Optional properties:
+
+  - amstaos,proximity-diodes - proximity diodes to enable. <0>, <1>, or <0 1>
+                               are the only valid values.
+  - led-max-microamp - current for the proximity LED. Must be 100000, 50000,
+                       25000, or 13000.
+  - vdd-supply: phandle to the regulator that provides power to the sensor.
+  - vddio-supply: phandle to the regulator that provides power to the bus.
+  - interrupts: the sole interrupt generated by the device
+
+  Refer to interrupt-controller/interrupts.txt for generic interrupt client
+  node bindings.
+
+Example:
+
+tsl2772@39 {
+       compatible = "amstaos,tsl2772";
+       reg = <0x39>;
+       interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
+       vdd-supply = <&pm8941_l17>;
+       vddio-supply = <&pm8941_lvs1>;
+       amstaos,proximity-diodes = <0>;
+       led-max-microamp = <100000>;
+};
diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
new file mode 100644 (file)
index 0000000..aac5f62
--- /dev/null
@@ -0,0 +1,12 @@
+ST VL53L0X ToF ranging sensor
+
+Required properties:
+       - compatible: must be "st,vl53l0x"
+       - reg: i2c address where to find the device
+
+Example:
+
+vl53l0x@29 {
+       compatible = "st,vl53l0x";
+       reg = <0x29>;
+};
index df5db732138d10658b5d659f25ca1ea3df28e025..6922db598deface3f76f32e605499cf096060968 100644 (file)
@@ -41,6 +41,8 @@ Required properties:
 - compatible : must be one of the following string:
        "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW.
        "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW.
+       "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.
 - reg : m4u register base and size.
 - interrupts : the interrupt of m4u.
@@ -51,7 +53,7 @@ Required properties:
        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,
+       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.
 
index 6e8a9ab0fdaebb9919168b2923c45c88cdc8c197..1232fc9fc709c6dafddf00518e48f599a6927e9f 100644 (file)
@@ -11,6 +11,7 @@ platforms.
                    "qcom,msm8916-apcs-kpss-global",
                    "qcom,msm8996-apcs-hmss-global"
                    "qcom,msm8998-apcs-hmss-global"
+                   "qcom,qcs404-apcs-apps-global"
                    "qcom,sdm845-apss-shared"
 
 - reg:
diff --git a/Documentation/devicetree/bindings/media/cedrus.txt b/Documentation/devicetree/bindings/media/cedrus.txt
new file mode 100644 (file)
index 0000000..a089a0c
--- /dev/null
@@ -0,0 +1,54 @@
+Device-tree bindings for the VPU found in Allwinner SoCs, referred to as the
+Video Engine (VE) in Allwinner literature.
+
+The VPU can only access the first 256 MiB of DRAM, that are DMA-mapped starting
+from the DRAM base. This requires specific memory allocation and handling.
+
+Required properties:
+- compatible           : must be one of the following compatibles:
+                       - "allwinner,sun4i-a10-video-engine"
+                       - "allwinner,sun5i-a13-video-engine"
+                       - "allwinner,sun7i-a20-video-engine"
+                       - "allwinner,sun8i-a33-video-engine"
+                       - "allwinner,sun8i-h3-video-engine"
+- reg                  : register base and length of VE;
+- clocks               : list of clock specifiers, corresponding to entries in
+                         the clock-names property;
+- clock-names          : should contain "ahb", "mod" and "ram" entries;
+- resets               : phandle for reset;
+- interrupts           : VE interrupt number;
+- allwinner,sram       : SRAM region to use with the VE.
+
+Optional properties:
+- memory-region                : CMA pool to use for buffers allocation instead of the
+                         default CMA pool.
+
+Example:
+
+reserved-memory {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges;
+
+       /* Address must be kept in the lower 256 MiBs of DRAM for VE. */
+       cma_pool: cma@4a000000 {
+               compatible = "shared-dma-pool";
+               size = <0x6000000>;
+               alloc-ranges = <0x4a000000 0x6000000>;
+               reusable;
+               linux,cma-default;
+       };
+};
+
+video-codec@1c0e000 {
+       compatible = "allwinner,sun7i-a20-video-engine";
+       reg = <0x01c0e000 0x1000>;
+
+       clocks = <&ccu CLK_AHB_VE>, <&ccu CLK_VE>,
+                <&ccu CLK_DRAM_VE>;
+       clock-names = "ahb", "mod", "ram";
+
+       resets = <&ccu RST_VE>;
+       interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+       allwinner,sram = <&ve_sram 1>;
+};
diff --git a/Documentation/devicetree/bindings/media/fsl-pxp.txt b/Documentation/devicetree/bindings/media/fsl-pxp.txt
new file mode 100644 (file)
index 0000000..2477e7f
--- /dev/null
@@ -0,0 +1,26 @@
+Freescale Pixel Pipeline
+========================
+
+The Pixel Pipeline (PXP) is a memory-to-memory graphics processing engine
+that supports scaling, colorspace conversion, alpha blending, rotation, and
+pixel conversion via lookup table. Different versions are present on various
+i.MX SoCs from i.MX23 to i.MX7.
+
+Required properties:
+- compatible: should be "fsl,<soc>-pxp", where SoC can be one of imx23, imx28,
+  imx6dl, imx6sl, imx6ul, imx6sx, imx6ull, or imx7d.
+- reg: the register base and size for the device registers
+- interrupts: the PXP interrupt, two interrupts for imx6ull and imx7d.
+- clock-names: should be "axi"
+- clocks: the PXP AXI clock
+
+Example:
+
+pxp@21cc000 {
+       compatible = "fsl,imx6ull-pxp";
+       reg = <0x021cc000 0x4000>;
+       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                    <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+       clock-names = "axi";
+       clocks = <&clks IMX6UL_CLK_PXP>;
+};
index 21ffb5ed818302ff4fb709a213aebfc1d4980b1f..5dddc95f9cc46084783ffc76580af7c918ba2dcb 100644 (file)
@@ -10,7 +10,11 @@ Required Properties:
     - "adi,adv7481" for the ADV7481
     - "adi,adv7482" for the ADV7482
 
-  - reg: I2C slave address
+  - reg: I2C slave addresses
+    The ADV748x has up to twelve 256-byte maps that can be accessed via the
+    main I2C ports. Each map has it own I2C address and acts as a standard
+    slave device on the I2C bus. The main address is mandatory, others are
+    optional and remain at default values if not specified.
 
 Optional Properties:
 
@@ -18,6 +22,11 @@ Optional Properties:
                     "intrq3". All interrupts are optional. The "intrq3" interrupt
                     is only available on the adv7481
   - interrupts: Specify the interrupt lines for the ADV748x
+  - reg-names : Names of maps with programmable addresses.
+               It shall contain all maps needing a non-default address.
+               Possible map names are:
+                 "main", "dpll", "cp", "hdmi", "edid", "repeater",
+                 "infoframe", "cbus", "cec", "sdp", "txa", "txb"
 
 The device node must contain one 'port' child node per device input and output
 port, in accordance with the video interface bindings defined in
@@ -47,7 +56,10 @@ Example:
 
        video-receiver@70 {
                compatible = "adi,adv7482";
-               reg = <0x70>;
+               reg = <0x70 0x71 0x72 0x73 0x74 0x75
+                      0x60 0x61 0x62 0x63 0x64 0x65>;
+               reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
+                           "infoframe", "cbus", "cec", "sdp", "txa", "txb";
 
                #address-cells = <1>;
                #size-cells = <0>;
@@ -73,7 +85,7 @@ Example:
                        };
                };
 
-               port@10 {
+               port@a {
                        reg = <10>;
 
                        adv7482_txa: endpoint {
@@ -83,7 +95,7 @@ Example:
                        };
                };
 
-               port@11 {
+               port@b {
                        reg = <11>;
 
                        adv7482_txb: endpoint {
index dcf57e7c60eba95b701dd929d1698e198953fbf6..b3e688b77a38cb6d1f8424fa8127ec1ce348ac14 100644 (file)
@@ -66,7 +66,7 @@ Example:
                 * other maps will retain their default addresses.
                 */
                reg = <0x4c>, <0x66>;
-               reg-names "main", "edid";
+               reg-names "main", "edid";
 
                reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
                hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;
diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt
new file mode 100644 (file)
index 0000000..c4701f1
--- /dev/null
@@ -0,0 +1,9 @@
+Dongwoon Anatech DW9807 voice coil lens driver
+
+DW9807 is a 10-bit DAC with current sink capability. It is intended for
+controlling voice coil lenses.
+
+Mandatory properties:
+
+- compatible: "dongwoon,dw9807-vcm"
+- reg: I2C slave address
diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807.txt
deleted file mode 100644 (file)
index c4701f1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Dongwoon Anatech DW9807 voice coil lens driver
-
-DW9807 is a 10-bit DAC with current sink capability. It is intended for
-controlling voice coil lenses.
-
-Mandatory properties:
-
-- compatible: "dongwoon,dw9807-vcm"
-- reg: I2C slave address
index 3813947b4d4f02bfd27ccaf126f64e0ecb933ce2..044b11913c49b8fa5ef2843b6bb7d42d0583f6d6 100644 (file)
@@ -5,6 +5,7 @@ Mediatek JPEG Decoder is the JPEG decode hardware present in Mediatek SoCs
 Required properties:
 - compatible : must be one of the following string:
        "mediatek,mt8173-jpgdec"
+       "mediatek,mt7623-jpgdec", "mediatek,mt2701-jpgdec"
        "mediatek,mt2701-jpgdec"
 - reg : physical base address of the jpeg decoder registers and length of
   memory mapped region.
index 2f420050d57f75883dd964d08b818e4a37cc856b..d329a4e8ac58ed6d2d83c05330f6e3741c19eaf0 100644 (file)
@@ -11,6 +11,7 @@ on Gen3 platforms to a CSI-2 receiver.
 
  - compatible: Must be one or more of the following
    - "renesas,vin-r8a7743" for the R8A7743 device
+   - "renesas,vin-r8a7744" for the R8A7744 device
    - "renesas,vin-r8a7745" for the R8A7745 device
    - "renesas,vin-r8a7778" for the R8A7778 device
    - "renesas,vin-r8a7779" for the R8A7779 device
index 8a7a616e9019b12f2e498b0bfa16ec12958622ad..3e2a2652eb19a64e355c33dac6f508506150cd2a 100644 (file)
@@ -17,15 +17,19 @@ Required properties:
 The CEU supports a single parallel input and should contain a single 'port'
 subnode with a single 'endpoint'. Connection to input devices are modeled
 according to the video interfaces OF bindings specified in:
-Documentation/devicetree/bindings/media/video-interfaces.txt
+[1] Documentation/devicetree/bindings/media/video-interfaces.txt
 
 Optional endpoint properties applicable to parallel input bus described in
 the above mentioned "video-interfaces.txt" file are supported.
 
-- hsync-active: Active state of the HSYNC signal, 0/1 for LOW/HIGH respectively.
-  If property is not present, default is active high.
-- vsync-active: Active state of the VSYNC signal, 0/1 for LOW/HIGH respectively.
-  If property is not present, default is active high.
+- hsync-active: See [1] for description. If property is not present,
+  default is active high.
+- vsync-active: See [1] for description. If property is not present,
+  default is active high.
+- bus-width: See [1] for description. Accepted values are '8' and '16'.
+  If property is not present, default is '8'.
+- field-even-active: See [1] for description. If property is not present,
+  an even field is identified by a logic 0 (active-low signal).
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.txt b/Documentation/devicetree/bindings/media/rockchip-vpu.txt
new file mode 100644 (file)
index 0000000..35dc464
--- /dev/null
@@ -0,0 +1,29 @@
+device-tree bindings for rockchip VPU codec
+
+Rockchip (Video Processing Unit) present in various Rockchip platforms,
+such as RK3288 and RK3399.
+
+Required properties:
+- compatible: value should be one of the following
+               "rockchip,rk3288-vpu";
+               "rockchip,rk3399-vpu";
+- interrupts: encoding and decoding interrupt specifiers
+- interrupt-names: should be "vepu" and "vdpu"
+- clocks: phandle to VPU aclk, hclk clocks
+- clock-names: should be "aclk" and "hclk"
+- power-domains: phandle to power domain node
+- iommus: phandle to a iommu node
+
+Example:
+SoC-specific DT entry:
+       vpu: video-codec@ff9a0000 {
+               compatible = "rockchip,rk3288-vpu";
+               reg = <0x0 0xff9a0000 0x0 0x800>;
+               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "vepu", "vdpu";
+               clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
+               clock-names = "aclk", "hclk";
+               power-domains = <&power RK3288_PD_VIDEO>;
+               iommus = <&vpu_mmu>;
+       };
index baf9d9756b3cf27b8fe4533ece6e3c7c1ef4ed64..f884ada0bffc881fea18c800645de72ab5bf7806 100644 (file)
@@ -100,10 +100,12 @@ Optional endpoint properties
   slave device (data source) by the master device (data sink). In the master
   mode the data source device is also the source of the synchronization signals.
 - bus-type: data bus type. Possible values are:
-  0 - autodetect based on other properties (MIPI CSI-2 D-PHY, parallel or Bt656)
   1 - MIPI CSI-2 C-PHY
   2 - MIPI CSI1
   3 - CCP2
+  4 - MIPI CSI-2 D-PHY
+  5 - Parallel
+  6 - Bt.656
 - bus-width: number of data lines actively used, valid for the parallel busses.
 - data-shift: on the parallel data busses, if bus-width is used to specify the
   number of data lines, data-shift can be used to specify which data lines are
index 615abdd0eb0de6db2a35ee61b727f71d31c5cee2..e937ddd871a6bffe58f4c536eea311f4be445349 100644 (file)
@@ -17,6 +17,7 @@ Required properties:
 - compatible : must be one of :
        "mediatek,mt2701-smi-common"
        "mediatek,mt2712-smi-common"
+       "mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common"
        "mediatek,mt8173-smi-common"
 - reg : the register and size of the SMI block.
 - power-domains : a phandle to the power domain of this local arbiter.
index 083155cdc2a0e787df4510b919bf8d97ec1cce15..94eddcae77ab5f08af6b13885c3a3122cd53ce41 100644 (file)
@@ -6,6 +6,7 @@ Required properties:
 - compatible : must be one of :
                "mediatek,mt2701-smi-larb"
                "mediatek,mt2712-smi-larb"
+               "mediatek,mt7623-smi-larb", "mediatek,mt2701-smi-larb"
                "mediatek,mt8173-smi-larb"
 - reg : the register and size of this local arbiter.
 - mediatek,smi : a phandle to the smi_common node.
@@ -16,7 +17,7 @@ Required properties:
            the register.
   - "smi" : It's the clock for transfer data and command.
 
-Required property for mt2701 and mt2712:
+Required property for mt2701, mt2712 and mt7623:
 - mediatek,larb-id :the hardware id of this larb.
 
 Example:
index 1811e1972a7a1c9a162d51b5997bf36279a8a3ac..5201bc15fdd67c1df1ba1b49715d4563cc14dbbd 100644 (file)
@@ -46,6 +46,42 @@ Required properties:
       "brcm,bcm6328-switch"
       "brcm,bcm6368-switch" and the mandatory "brcm,bcm63xx-switch"
 
+Required properties for BCM585xx/586xx/88312 SoCs:
+
+ - reg: a total of 3 register base addresses, the first one must be the
+   Switch Register Access block base, the second is the port 5/4 mux
+   configuration register and the third one is the SGMII configuration
+   and status register base address.
+
+ - interrupts: a total of 13 interrupts must be specified, in the following
+   order: port 0-5, 7-8 link status change, then the integrated PHY interrupt,
+   then the timestamping interrupt and the sleep timer interrupts for ports
+   5,7,8.
+
+Optional properties for BCM585xx/586xx/88312 SoCs:
+
+  - reg-names: a total of 3 names matching the 3 base register address, must
+    be in the following order:
+       "srab"
+       "mux_config"
+       "sgmii_config"
+
+  - interrupt-names: a total of 13 names matching the 13 interrupts specified
+    must be in the following order:
+       "link_state_p0"
+       "link_state_p1"
+       "link_state_p2"
+       "link_state_p3"
+       "link_state_p4"
+       "link_state_p5"
+       "link_state_p7"
+       "link_state_p8"
+       "phy"
+       "ts"
+       "imp_sleep_timer_p5"
+       "imp_sleep_timer_p7"
+       "imp_sleep_timer_p8"
+
 See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional
 required and optional properties.
 
index c329608fa887b1fad655f7c778ca539b4c5d36c6..83370ebf5b8959d5fb8c90ed3344e50daf224415 100644 (file)
@@ -2,7 +2,7 @@ Marvell Prestera Switch Chip bindings
 -------------------------------------
 
 Required properties:
-- compatible: one of the following
+- compatible: must be "marvell,prestera" and one of the following
        "marvell,prestera-98dx3236",
        "marvell,prestera-98dx3336",
        "marvell,prestera-98dx4251",
@@ -21,7 +21,7 @@ switch {
        ranges = <0 MBUS_ID(0x03, 0x00) 0 0x100000>;
 
        packet-processor@0 {
-               compatible = "marvell,prestera-98dx3236";
+               compatible = "marvell,prestera-98dx3236", "marvell,prestera";
                reg = <0 0x4000000>;
                interrupts = <33>, <34>, <35>;
                dfx = <&dfx>;
index e319fe5e205ac5d32af9726285afe942848f934c..99c4ba6a3f61d4e7a8a0701033a50489a47d91c4 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
   "allwinner,sun8i-a83t-sid"
   "allwinner,sun8i-h3-sid"
   "allwinner,sun50i-a64-sid"
+  "allwinner,sun50i-h5-sid"
 
 - reg: Should contain registers location and length
 
index 78edd63641e87230dabd23465978e1b52c4a65d6..a3571937b0195f327cf53e16ed1abf69cbb820fb 100644 (file)
@@ -3,11 +3,13 @@ Actions Semi Owl Smart Power System (SPS)
 Required properties:
 - compatible          :  "actions,s500-sps" for S500
                          "actions,s700-sps" for S700
+                         "actions,s900-sps" for S900
 - reg                 :  Offset and length of the register set for the device.
 - #power-domain-cells :  Must be 1.
                          See macros in:
                           include/dt-bindings/power/owl-s500-powergate.h for S500
                           include/dt-bindings/power/owl-s700-powergate.h for S700
+                          include/dt-bindings/power/owl-s900-powergate.h for S900
 
 
 Example:
index f747f95eee582419178f2b5fb5ca500b2c9bb137..5f24586c8cf33fcf4bdb6a6e681783e9121df4a9 100644 (file)
@@ -8,7 +8,9 @@ Required properties:
 - compatible: Should be "renesas,<soctype>-apmu", "renesas,apmu" as fallback.
              Examples with soctypes are:
                - "renesas,r8a7743-apmu" (RZ/G1M)
+               - "renesas,r8a7744-apmu" (RZ/G1N)
                - "renesas,r8a7745-apmu" (RZ/G1E)
+               - "renesas,r8a77470-apmu" (RZ/G1C)
                - "renesas,r8a7790-apmu" (R-Car H2)
                - "renesas,r8a7791-apmu" (R-Car M2-W)
                - "renesas,r8a7792-apmu" (R-Car V2H)
index 180ae65be753ae43ecc39a294a3a7163bdb517d5..eae2a880155a5a7f8774c7428c38b88c4b3b2975 100644 (file)
@@ -8,8 +8,11 @@ and various coprocessors.
 Required properties:
   - compatible: Must contain exactly one of the following:
       - "renesas,r8a7743-sysc" (RZ/G1M)
+      - "renesas,r8a7744-sysc" (RZ/G1N)
       - "renesas,r8a7745-sysc" (RZ/G1E)
       - "renesas,r8a77470-sysc" (RZ/G1C)
+      - "renesas,r8a774a1-sysc" (RZ/G2M)
+      - "renesas,r8a774c0-sysc" (RZ/G2E)
       - "renesas,r8a7779-sysc" (R-Car H1)
       - "renesas,r8a7790-sysc" (R-Car H2)
       - "renesas,r8a7791-sysc" (R-Car M2-W)
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp-pil.txt
new file mode 100644 (file)
index 0000000..a842a78
--- /dev/null
@@ -0,0 +1,126 @@
+Qualcomm Technology Inc. ADSP Peripheral Image Loader
+
+This document defines the binding for a component that loads and boots firmware
+on the Qualcomm Technology Inc. ADSP Hexagon core.
+
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be one of:
+                   "qcom,sdm845-adsp-pil"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: must specify the base address and size of the qdsp6ss register
+
+- interrupts-extended:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: must list the watchdog, fatal IRQs ready, handover and
+                   stop-ack IRQs
+
+- interrupt-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack"
+
+- clocks:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition:  List of 8 phandle and clock specifier pairs for the adsp.
+
+- clock-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: List of clock input name strings sorted in the same
+                   order as the clocks property. Definition must have
+                   "xo", "sway_cbcr", "lpass_aon", "lpass_ahbs_aon_cbcr",
+                   "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", "qdsp6ss_sleep"
+                   and "qdsp6ss_core".
+
+- power-domains:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to cx power domain node.
+
+- resets:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to the list of 2 reset-controller for the adsp.
+
+- reset-names:
+        Usage: required
+        Value type: <stringlist>
+        Definition: must be "pdc_sync" and "cc_lpass"
+
+- qcom,halt-regs:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: a phandle reference to a syscon representing TCSR followed
+                       by the offset within syscon for lpass halt register.
+
+- memory-region:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to the reserved-memory for the ADSP
+
+- qcom,smem-states:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to the smem state for requesting the ADSP to
+                   shut down
+
+- qcom,smem-state-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "stop"
+
+
+= SUBNODES
+The adsp node may have an subnode named "glink-edge" that describes the
+communication edge, channels and devices related to the ADSP.
+See ../soc/qcom/qcom,glink.txt for details on how to describe these.
+
+= EXAMPLE
+The following example describes the resources needed to boot control the
+ADSP, as it is found on SDM845 boards.
+
+       remoteproc@17300000 {
+               compatible = "qcom,sdm845-adsp-pil";
+               reg = <0x17300000 0x40c>;
+
+               interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+                       <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                       <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                       <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                       <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+               interrupt-names = "wdog", "fatal", "ready",
+                       "handover", "stop-ack";
+
+               clocks = <&rpmhcc RPMH_CXO_CLK>,
+                       <&gcc GCC_LPASS_SWAY_CLK>,
+                       <&lpasscc LPASS_AUDIO_WRAPPER_AON_CLK>,
+                       <&lpasscc LPASS_Q6SS_AHBS_AON_CLK>,
+                       <&lpasscc LPASS_Q6SS_AHBM_AON_CLK>,
+                       <&lpasscc LPASS_QDSP6SS_XO_CLK>,
+                       <&lpasscc LPASS_QDSP6SS_SLEEP_CLK>,
+                       <&lpasscc LPASS_QDSP6SS_CORE_CLK>;
+               clock-names = "xo", "sway_cbcr", "lpass_aon",
+                       "lpass_ahbs_aon_cbcr",
+                       "lpass_ahbm_aon_cbcr", "qdsp6ss_xo",
+                       "qdsp6ss_sleep", "qdsp6ss_core";
+
+               power-domains = <&rpmhpd SDM845_CX>;
+
+               resets = <&pdc_reset PDC_AUDIO_SYNC_RESET>,
+                        <&aoss_reset AOSS_CC_LPASS_RESTART>;
+               reset-names = "pdc_sync", "cc_lpass";
+
+               qcom,halt-regs = <&tcsr_mutex_regs 0x22000>;
+
+               memory-region = <&pil_adsp_mem>;
+
+               qcom,smem-states = <&adsp_smp2p_out 0>;
+               qcom,smem-state-names = "stop";
+       };
index 728e4193f7a689e1cc406ba2cb29e29534c93283..9c0cff3a5ed8506dd164b42316ec83d63eac404f 100644 (file)
@@ -10,6 +10,11 @@ on the Qualcomm ADSP Hexagon core.
                    "qcom,msm8974-adsp-pil"
                    "qcom,msm8996-adsp-pil"
                    "qcom,msm8996-slpi-pil"
+                   "qcom,qcs404-adsp-pas"
+                   "qcom,qcs404-cdsp-pas"
+                   "qcom,qcs404-wcss-pas"
+                   "qcom,sdm845-adsp-pas"
+                   "qcom,sdm845-cdsp-pas"
 
 - interrupts-extended:
        Usage: required
index 601dd9f389aa927c5dcf5aa1ebd5d032d3e9619e..9ff5b0309417cc49aa5b8c0adf97b801f01d53c3 100644 (file)
@@ -53,13 +53,17 @@ on the Qualcomm Hexagon core.
        Definition: reference to the reset-controller for the modem sub-system
                    reference to the list of 3 reset-controllers for the
                    wcss sub-system
+                   reference to the list of 2 reset-controllers for the modem
+                   sub-system on SDM845 SoCs
 
 - reset-names:
        Usage: required
        Value type: <stringlist>
        Definition: must be "mss_restart" for the modem sub-system
-       Definition: must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset"
-                   for the wcss syb-system
+                   must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset"
+                   for the wcss sub-system
+                   must be "mss_restart", "pdc_reset" for the modem
+                   sub-system on SDM845 SoCs
 
 - cx-supply:
 - mss-supply:
diff --git a/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt b/Documentation/devicetree/bindings/reset/qcom,pdc-global.txt
new file mode 100644 (file)
index 0000000..a62a492
--- /dev/null
@@ -0,0 +1,52 @@
+PDC Global
+======================================
+
+This binding describes a reset-controller found on PDC-Global (Power Domain
+Controller) block for Qualcomm Technologies Inc SDM845 SoCs.
+
+Required properties:
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be:
+                   "qcom,sdm845-pdc-global"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: must specify the base address and size of the register
+                   space.
+
+- #reset-cells:
+       Usage: required
+       Value type: <uint>
+       Definition: must be 1; cell entry represents the reset index.
+
+Example:
+
+pdc_reset: reset-controller@b2e0000 {
+       compatible = "qcom,sdm845-pdc-global";
+       reg = <0xb2e0000 0x20000>;
+       #reset-cells = <1>;
+};
+
+PDC reset clients
+======================================
+
+Device nodes that need access to reset lines should
+specify them as a reset phandle in their corresponding node as
+specified in reset.txt.
+
+For a list of all valid reset indices see
+<dt-bindings/reset/qcom,sdm845-pdc.h>
+
+Example:
+
+modem-pil@4080000 {
+       ...
+
+       resets = <&pdc_reset PDC_MODEM_SYNC_RESET>;
+       reset-names = "pdc_reset";
+
+       ...
+};
index 67e83b02e10b63e33615e7f516618cfe238c84c3..b03c48a1150eae4d4690d25dc83fa4cea8db15cb 100644 (file)
@@ -16,8 +16,11 @@ Required properties:
                  - "renesas,<soctype>-rst" for R-Car Gen2 and Gen3, and RZ/G
                Examples with soctypes are:
                  - "renesas,r8a7743-rst" (RZ/G1M)
+                 - "renesas,r8a7744-rst" (RZ/G1N)
                  - "renesas,r8a7745-rst" (RZ/G1E)
                  - "renesas,r8a77470-rst" (RZ/G1C)
+                 - "renesas,r8a774a1-rst" (RZ/G2M)
+                 - "renesas,r8a774c0-rst" (RZ/G2E)
                  - "renesas,r8a7778-reset-wdt" (R-Car M1A)
                  - "renesas,r8a7779-reset-wdt" (R-Car H1)
                  - "renesas,r8a7790-rst" (R-Car H2)
index eaca9da79d83af982a79abe8e1b911f944a64ed1..e52e16c6bc57af9b1f6ce9b36d1630e69443f755 100644 (file)
@@ -14,6 +14,10 @@ Required properties:
     - "renesas,scifa-r8a7743" for R8A7743 (RZ/G1M) SCIFA compatible UART.
     - "renesas,scifb-r8a7743" for R8A7743 (RZ/G1M) SCIFB compatible UART.
     - "renesas,hscif-r8a7743" for R8A7743 (RZ/G1M) HSCIF compatible UART.
+    - "renesas,scif-r8a7744" for R8A7744 (RZ/G1N) SCIF compatible UART.
+    - "renesas,scifa-r8a7744" for R8A7744 (RZ/G1N) SCIFA compatible UART.
+    - "renesas,scifb-r8a7744" for R8A7744 (RZ/G1N) SCIFB compatible UART.
+    - "renesas,hscif-r8a7744" for R8A7744 (RZ/G1N) HSCIF compatible UART.
     - "renesas,scif-r8a7745" for R8A7745 (RZ/G1E) SCIF compatible UART.
     - "renesas,scifa-r8a7745" for R8A7745 (RZ/G1E) SCIFA compatible UART.
     - "renesas,scifb-r8a7745" for R8A7745 (RZ/G1E) SCIFB compatible UART.
@@ -50,6 +54,8 @@ Required properties:
     - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART.
     - "renesas,scif-r8a77980" for R8A77980 (R-Car V3H) SCIF compatible UART.
     - "renesas,hscif-r8a77980" for R8A77980 (R-Car V3H) HSCIF compatible UART.
+    - "renesas,scif-r8a77990" for R8A77990 (R-Car E3) SCIF compatible UART.
+    - "renesas,hscif-r8a77990" for R8A77990 (R-Car E3) HSCIF compatible UART.
     - "renesas,scif-r8a77995" for R8A77995 (R-Car D3) SCIF compatible UART.
     - "renesas,hscif-r8a77995" for R8A77995 (R-Car D3) HSCIF compatible UART.
     - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART.
index 0b3892a7a528ce34b9f4e4626e19c6a388a6573b..7a1bf02bb86984eb54d2a679641ebc25243f5f8d 100644 (file)
@@ -7,7 +7,7 @@ Required properties:
 - clocks: phandle to the input clock.
 
 Optional properties:
-- fifo-size: the RX/TX FIFO size.  Defaults to 64 if not specified.
+-auto-flow-control: enable automatic flow control support.
 
 Example:
        aliases {
@@ -19,5 +19,4 @@ Example:
                reg = <0x54006800 0x40>;
                interrupts = <0 33 4>;
                clocks = <&uart_clk>;
-               fifo-size = <64>;
        };
diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt b/Documentation/devicetree/bindings/soc/amlogic/amlogic,canvas.txt
new file mode 100644 (file)
index 0000000..436d210
--- /dev/null
@@ -0,0 +1,29 @@
+Amlogic Canvas
+================================
+
+A canvas is a collection of metadata that describes a pixel buffer.
+Those metadata include: width, height, phyaddr, wrapping, block mode
+and endianness.
+
+Many IPs within Amlogic SoCs rely on canvas indexes to read/write pixel data
+rather than use the phy addresses directly. For instance, this is the case for
+the video decoders and the display.
+
+Amlogic SoCs have 256 canvas.
+
+Device Tree Bindings:
+---------------------
+
+Video Lookup Table
+--------------------------
+
+Required properties:
+- compatible: "amlogic,canvas"
+- reg: Base physical address and size of the canvas registers.
+
+Example:
+
+canvas: video-lut@48 {
+       compatible = "amlogic,canvas";
+       reg = <0x0 0x48 0x0 0x14>;
+};
index f9987c30f0d52c75eeafdbf3d3c50982ebd9b5f6..5a2ef1726e2a20d4651950c5095ce8f109ed0013 100644 (file)
@@ -19,10 +19,12 @@ IP Pairing
 Required properties in pwrap device node.
 - compatible:
        "mediatek,mt2701-pwrap" for MT2701/7623 SoCs
+       "mediatek,mt6765-pwrap" for MT6765 SoCs
        "mediatek,mt6797-pwrap" for MT6797 SoCs
        "mediatek,mt7622-pwrap" for MT7622 SoCs
        "mediatek,mt8135-pwrap" for MT8135 SoCs
        "mediatek,mt8173-pwrap" for MT8173 SoCs
+       "mediatek,mt8183-pwrap" for MT8183 SoCs
 - interrupts: IRQ for pwrap in SOC
 - reg-names: Must include the following entries:
   "pwrap": Main registers base
index 7dc5ce858a0ee3a6659cc0be7a0d3194f7a6fa3e..46e27cd69f18faac4015ecf3a151bda89aed8ed3 100644 (file)
@@ -13,6 +13,7 @@ On RK3328 SoCs, the GRF adds a section for USB2PHYGRF,
 Required Properties:
 
 - compatible: GRF should be one of the following:
+   - "rockchip,px30-grf", "syscon": for px30
    - "rockchip,rk3036-grf", "syscon": for rk3036
    - "rockchip,rk3066-grf", "syscon": for rk3066
    - "rockchip,rk3188-grf", "syscon": for rk3188
@@ -23,6 +24,7 @@ Required Properties:
    - "rockchip,rk3399-grf", "syscon": for rk3399
    - "rockchip,rv1108-grf", "syscon": for rv1108
 - compatible: PMUGRF should be one of the following:
+   - "rockchip,px30-pmugrf", "syscon": for px30
    - "rockchip,rk3368-pmugrf", "syscon": for rk3368
    - "rockchip,rk3399-pmugrf", "syscon": for rk3399
 - compatible: SGRF should be one of the following
index c51ade86578c6508bf29c11af8653c68211d2ac3..62dd0748f0efc1a035f5516210925df1d9056ca1 100644 (file)
@@ -18,6 +18,7 @@ Required properties:
     - "allwinner,sun8i-h3-system-control"
     - "allwinner,sun50i-a64-sram-controller" (deprecated)
     - "allwinner,sun50i-a64-system-control"
+    - "allwinner,sun50i-h6-system-control", "allwinner,sun50i-a64-system-control"
 - reg : sram controller register offset + length
 
 SRAM nodes
@@ -54,6 +55,9 @@ The valid sections compatible for H3 are:
 The valid sections compatible for A64 are:
     - allwinner,sun50i-a64-sram-c
 
+The valid sections compatible for H6 are:
+    - allwinner,sun50i-h6-sram-c, allwinner,sun50i-a64-sram-c
+
 Devices using SRAM sections
 ---------------------------
 
index cd5f20bf2582e742c426018d91d31c652767d7fd..4ddff85837da3f3fdf420affd68e516833dbe1fa 100644 (file)
@@ -12,6 +12,8 @@ Required Properties:
     - "renesas,tmu-r8a7740" for the r8a7740 TMU
     - "renesas,tmu-r8a7778" for the r8a7778 TMU
     - "renesas,tmu-r8a7779" for the r8a7779 TMU
+    - "renesas,tmu-r8a77970" for the r8a77970 TMU
+    - "renesas,tmu-r8a77980" for the r8a77980 TMU
     - "renesas,tmu" for any TMU.
       This is a fallback for the above renesas,tmu-* entries
 
index 69c934aec13bbeb1b82d5ca24ef44875528fa544..6ab001fa1ed4617a7db9858637b85f7ad19f11f2 100644 (file)
@@ -21,16 +21,6 @@ adi,adt7490          +/-1C TDM Extended Temp Range I.C
 adi,adxl345            Three-Axis Digital Accelerometer
 adi,adxl346            Three-Axis Digital Accelerometer (backward-compatibility value "adi,adxl345" must be listed too)
 ams,iaq-core           AMS iAQ-Core VOC Sensor
-amstaos,tsl2571                AMS/TAOS ALS and proximity sensor
-amstaos,tsl2671                AMS/TAOS ALS and proximity sensor
-amstaos,tmd2671                AMS/TAOS ALS and proximity sensor
-amstaos,tsl2771                AMS/TAOS ALS and proximity sensor
-amstaos,tmd2771                AMS/TAOS ALS and proximity sensor
-amstaos,tsl2572                AMS/TAOS ALS and proximity sensor
-amstaos,tsl2672                AMS/TAOS ALS and proximity sensor
-amstaos,tmd2672                AMS/TAOS ALS and proximity sensor
-amstaos,tsl2772                AMS/TAOS ALS and proximity sensor
-amstaos,tmd2772                AMS/TAOS ALS and proximity sensor
 at,24c08               i2c serial eeprom  (24cxx)
 atmel,at97sc3204t      i2c trusted platform module (TPM)
 capella,cm32181                CM32181: Ambient Light Sensor
index 46da5f1844608fa85c9a88a947fe50643392a7f1..6dc3c4a344830be628a0d815f23d0a5306279999 100644 (file)
@@ -6,6 +6,7 @@ Required properties:
   - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC.
   - hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC.
   - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc;
+  - "rockchip,px30-usb", "rockchip,rk3066-usb", "snps,dwc2": for px30 Soc;
   - "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc;
   - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc;
   - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs;
index 14818137a029fb858d81c0654406646de849e71f..4b1a2a8fcc16185cd5fae518e0e2fb953becac6f 100644 (file)
@@ -115,6 +115,7 @@ elan        Elan Microelectronic Corp.
 embest Shenzhen Embest Technology Co., Ltd.
 emmicro        EM Microelectronic
 emtrion        emtrion GmbH
+endless        Endless Mobile, Inc.
 energymicro    Silicon Laboratories (formerly Energy Micro AS)
 engicam        Engicam S.r.l.
 epcos  EPCOS AG
@@ -301,6 +302,7 @@ pine64      Pine64
 pixcir  PIXCIR MICROELECTRONICS Co., Ltd
 plathome       Plat'Home Co., Ltd.
 plda   PLDA
+plx    Broadcom Corporation (formerly PLX Technology)
 portwell       Portwell Inc.
 poslab Poslab Technology Co., Ltd.
 powervr        PowerVR (deprecated, use img)
index 8bf62240e10d35a7dc99fac14f86afeb14313490..1177052701e138e22d63319e8c96001077b90660 100644 (file)
@@ -151,6 +151,11 @@ Mount Options
         Report overall filesystem usage in statfs instead of using the root
         directory quota.
 
+  nocopyfrom
+        Don't use the RADOS 'copy-from' operation to perform remote object
+        copies.  Currently, it's only used in copy_file_range, which will revert
+        to the default VFS implementation if this option is used.
+
 More Information
 ================
 
index ebcaaee2161684b99f5d6c0f5866bea805f6c405..c4dac829db0f60cab1ea7b7c88eb2c700489bf08 100644 (file)
@@ -84,7 +84,7 @@ Creating a Cache
                A message from user space has arrived to fill out a
                cache entry.  It is in 'buf' of length 'len'.
                cache_parse should parse this, find the item in the
-               cache with sunrpc_cache_lookup, and update the item
+               cache with sunrpc_cache_lookup_rcu, and update the item
                with sunrpc_cache_update.
 
 
@@ -95,7 +95,7 @@ Creating a Cache
 Using a cache
 -------------
 
-To find a value in a cache, call sunrpc_cache_lookup passing a pointer
+To find a value in a cache, call sunrpc_cache_lookup_rcu passing a pointer
 to the cache_head in a sample item with the 'key' fields filled in.
 This will be passed to ->match to identify the target entry.  If no
 entry is found, a new entry will be create, added to the cache, and
@@ -116,7 +116,7 @@ item does become valid, the deferred copy of the request will be
 revisited (->revisit).  It is expected that this method will
 reschedule the request for processing.
 
-The value returned by sunrpc_cache_lookup can also be passed to
+The value returned by sunrpc_cache_lookup_rcu can also be passed to
 sunrpc_cache_update to set the content for the item.  A second item is
 passed which should hold the content.  If the item found by _lookup
 has valid data, then it is discarded and a new item is created.  This
diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt
deleted file mode 100644 (file)
index 106d17f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-POHMELFS: Parallel Optimized Host Message Exchange Layered File System.
-
-               Evgeniy Polyakov <zbr@ioremap.net>
-
-Homepage: http://www.ioremap.net/projects/pohmelfs
-
-POHMELFS first began as a network filesystem with coherent local data and
-metadata caches but is now evolving into a parallel distributed filesystem.
-
-Main features of this FS include:
- * Locally coherent cache for data and metadata with (potentially) byte-range locks.
-       Since all Linux filesystems lock the whole inode during writing, algorithm
-       is very simple and does not use byte-ranges, although they are sent in
-       locking messages.
- * Completely async processing of all events except creation of hard and symbolic
-       links, and rename events.
-       Object creation and data reading and writing are processed asynchronously.
- * Flexible object architecture optimized for network processing.
-       Ability to create long paths to objects and remove arbitrarily huge
-       directories with a single network command.
-       (like removing the whole kernel tree via a single network command).
- * Very high performance.
- * Fast and scalable multithreaded userspace server. Being in userspace it works
-       with any underlying filesystem and still is much faster than async in-kernel NFS one.
- * Client is able to switch between different servers (if one goes down, client
-       automatically reconnects to second and so on).
- * Transactions support. Full failover for all operations.
-       Resending transactions to different servers on timeout or error.
- * Read request (data read, directory listing, lookup requests) balancing between multiple servers.
- * Write requests are replicated to multiple servers and completed only when all of them are acked.
- * Ability to add and/or remove servers from the working set at run-time.
- * Strong authentication and possible data encryption in network channel.
- * Extended attributes support.
-
-POHMELFS is based on transactions, which are potentially long-standing objects that live
-in the client's memory. Each transaction contains all the information needed to process a given
-command (or set of commands, which is frequently used during data writing: single transactions
-can contain creation and data writing commands). Transactions are committed by all the servers
-to which they are sent and, in case of failures, are eventually resent or dropped with an error.
-For example, reading will return an error if no servers are available.
-
-POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is
-possible to detach replies from requests and, if the command requires data to be received, the
-caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different
-servers and async threads will pick up replies in parallel, find appropriate transactions in the
-system and put the data where it belongs (like the page or inode cache).
-
-The main feature of POHMELFS is writeback data and the metadata cache.
-Only a few non-performance critical operations use the write-through cache and
-are synchronous: hard and symbolic link creation, and object rename. Creation,
-removal of objects and data writing are asynchronous and are sent to
-the server during system writeback. Only one writer at a time is allowed for any
-given inode, which is guarded by an appropriate locking protocol.
-Because of this feature, POHMELFS is extremely fast at metadata intensive
-workloads and can fully utilize the bandwidth to the servers when doing bulk
-data transfers.
-
-POHMELFS clients operate with a working set of servers and are capable of balancing read-only
-operations (like lookups or directory listings) between them according to IO priorities.
-Administrators can add or remove servers from the set at run-time via special commands (described
-in Documentation/filesystems/pohmelfs/info.txt file). Writes are replicated to all servers, which
-are connected with write permission turned on. IO priority and permissions can be changed in
-run-time.
-
-POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
-One can select any kernel supported cipher, encryption mode, hash type and operation mode
-(hmac or digest). It is also possible to use both or neither (default). Crypto configuration
-is checked during mount time and, if the server does not support it, appropriate capabilities
-will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified).
-Crypto performance heavily depends on the number of crypto threads, which asynchronously perform
-crypto operations and send the resulting data to server or submit it up the stack. This number
-can be controlled via a mount option.
diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt
deleted file mode 100644 (file)
index db2e413..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-POHMELFS usage information.
-
-Mount options.
-All but index, number of crypto threads and maximum IO size can changed via remount.
-
-idx=%u
- Each mountpoint is associated with a special index via this option.
- Administrator can add or remove servers from the given index, so all mounts,
- which were attached to it, are updated.
- Default it is 0.
-
-trans_scan_timeout=%u
- This timeout, expressed in milliseconds, specifies time to scan transaction
- trees looking for stale requests, which have to be resent, or if number of
- retries exceed specified limit, dropped with error.
- Default is 5 seconds.
-
-drop_scan_timeout=%u
- Internal timeout, expressed in milliseconds, which specifies how frequently
- inodes marked to be dropped are freed. It also specifies how frequently
- the system checks that servers have to be added or removed from current working set.
- Default is 1 second.
-
-wait_on_page_timeout=%u
- Number of milliseconds to wait for reply from remote server for data reading command.
- If this timeout is exceeded, reading returns an error.
- Default is 5 seconds.
-
-trans_retries=%u
- This is the number of times that a transaction will be resent to a server that did
- not answer for the last @trans_scan_timeout milliseconds.
- When the number of resends exceeds this limit, the transaction is completed with error.
- Default is 5 resends.
-
-crypto_thread_num=%u
- Number of crypto processing threads. Threads are used both for RX and TX traffic.
- Default is 2, or no threads if crypto operations are not supported.
-
-trans_max_pages=%u
- Maximum number of pages in a single transaction. This parameter also controls
- the number of pages,  allocated for crypto processing (each crypto thread has
- pool of pages, the number of which is equal to 'trans_max_pages'.
- Default is 100 pages.
-
-crypto_fail_unsupported
- If specified, mount will fail if the server does not support requested crypto operations.
- By default mount will disable non-matching crypto operations.
-
-mcache_timeout=%u
- Maximum number of milliseconds to wait for the mcache objects to be processed.
- Mcache includes locks (given lock should be granted by server), attributes (they should be
- fully received in the given timeframe).
- Default is 5 seconds.
-
-Usage examples.
-
-Add server server1.net:1025 into the working set with index $idx
-with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
-$cfg A add -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
-
-Mount filesystem with given index $idx to /mnt mountpoint.
-Client will connect to all servers specified in the working set via previous command:
-mount -t pohmel -o idx=$idx q /mnt
-
-Change permissions to read-only (-I 1 option, '-I 2' - write-only, 3 - rw):
-$cfg A modify -a server1.net -p 1025 -i $idx -I 1
-
-Change IO priority to 123 (node with the highest priority gets read requests).
-$cfg A modify -a server1.net -p 1025 -i $idx -P 123
-
-One can check currect status of all connections in the mountstats file:
-# cat /proc/$PID/mountstats
-...
-device none mounted on /mnt with fstype pohmel
-idx addr(:port) socket_type protocol active priority permissions
-0 server1.net:1026 1 6 1 250 1
-0 server2.net:1025 1 6 1 123 3
-
-Server installation.
-
-Creating a server, which listens at port 1025 and 0.0.0.0 address.
-Working root directory (note, that server chroots there, so you have to have appropriate permissions)
-is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there
-are appropriate key files.
-Number of working threads is set to 10.
-
-# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key
-
- -A 6                   - listen on ipv6 address. Default: Disabled.
- -r root                 - path to root directory. Default: /tmp.
- -a addr                 - listen address. Default: 0.0.0.0.
- -p port                 - listen port. Default: 1025.
- -w workers              - number of workers per connected client. Default: 1.
- -K file                - hash key size. Default: none.
- -k file                - cipher key size. Default: none.
- -h                      - this help.
-
-Number of worker threads specifies how many workers will be created for each client.
-Bulk single-client transafers usually are better handled with smaller number (like 1-3).
diff --git a/Documentation/filesystems/pohmelfs/network_protocol.txt b/Documentation/filesystems/pohmelfs/network_protocol.txt
deleted file mode 100644 (file)
index c680b4b..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-POHMELFS network protocol.
-
-Basic structure used in network communication is following command:
-
-struct netfs_cmd
-{
-       __u16                   cmd;    /* Command number */
-       __u16                   csize;  /* Attached crypto information size */
-       __u16                   cpad;   /* Attached padding size */
-       __u16                   ext;    /* External flags */
-       __u32                   size;   /* Size of the attached data */
-       __u32                   trans;  /* Transaction id */
-       __u64                   id;     /* Object ID to operate on. Used for feedback.*/
-       __u64                   start;  /* Start of the object. */
-       __u64                   iv;     /* IV sequence */
-       __u8                    data[0];
-};
-
-Commands can be embedded into transaction command (which in turn has own command),
-so one can extend protocol as needed without breaking backward compatibility as long
-as old commands are supported. All string lengths include tail 0 byte.
-
-All commands are transferred over the network in big-endian. CPU endianness is used at the end peers.
-
-@cmd - command number, which specifies command to be processed. Following
-       commands are used currently:
-
-       NETFS_READDIR   = 1,    /* Read directory for given inode number */
-       NETFS_READ_PAGE,        /* Read data page from the server */
-       NETFS_WRITE_PAGE,       /* Write data page to the server */
-       NETFS_CREATE,           /* Create directory entry */
-       NETFS_REMOVE,           /* Remove directory entry */
-       NETFS_LOOKUP,           /* Lookup single object */
-       NETFS_LINK,             /* Create a link */
-       NETFS_TRANS,            /* Transaction */
-       NETFS_OPEN,             /* Open intent */
-       NETFS_INODE_INFO,       /* Metadata cache coherency synchronization message */
-       NETFS_PAGE_CACHE,       /* Page cache invalidation message */
-       NETFS_READ_PAGES,       /* Read multiple contiguous pages in one go */
-       NETFS_RENAME,           /* Rename object */
-       NETFS_CAPABILITIES,     /* Capabilities of the client, for example supported crypto */
-       NETFS_LOCK,             /* Distributed lock message */
-       NETFS_XATTR_SET,        /* Set extended attribute */
-       NETFS_XATTR_GET,        /* Get extended attribute */
-
-@ext - external flags. Used by different commands to specify some extra arguments
-       like partial size of the embedded objects or creation flags.
-
-@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached,
-       but size of the requested data is incorporated here. It does not include size of the command
-       header (struct netfs_cmd) itself.
-
-@id - id of the object this command operates on. Each command can use it for own purpose.
-
-@start - start of the object this command operates on. Each command can use it for own purpose.
-
-@csize, @cpad - size and padding size of the (attached if needed) crypto information.
-
-Command specifications.
-
-@NETFS_READDIR
-This command is used to sync content of the remote dir to the client.
-
-@ext - length of the path to object.
-@size - the same.
-@id - local inode number of the directory to read.
-@start - zero.
-
-
-@NETFS_READ_PAGE
-This command is used to read data from remote server.
-Data size does not exceed local page cache size.
-
-@id - inode number.
-@start - first byte offset.
-@size - number of bytes to read plus length of the path to object.
-@ext - object path length.
-
-
-@NETFS_CREATE
-Used to create object.
-It does not require that all directories on top of the object were
-already created, it will create them automatically. Each object has
-associated @netfs_path_entry data structure, which contains creation
-mode (permissions and type) and length of the name as long as name itself.
-
-@start - 0
-@size - size of the all data structures needed to create a path
-@id - local inode number
-@ext - 0
-
-
-@NETFS_REMOVE
-Used to remove object.
-
-@ext - length of the path to object.
-@size - the same.
-@id - local inode number.
-@start - zero.
-
-
-@NETFS_LOOKUP
-Lookup information about object on server.
-
-@ext - length of the path to object.
-@size - the same.
-@id - local inode number of the directory to look object in.
-@start - local inode number of the object to look at.
-
-
-@NETFS_LINK
-Create hard of symlink.
-Command is sent as "object_path|target_path".
-
-@size - size of the above string.
-@id - parent local inode number.
-@start - 1 for symlink, 0 for hardlink.
-@ext - size of the "object_path" above.
-
-
-@NETFS_TRANS
-Transaction header.
-
-@size - incorporates all embedded command sizes including theirs header sizes.
-@start - transaction generation number - unique id used to find transaction.
-@ext - transaction flags. Unused at the moment.
-@id - 0.
-
-
-@NETFS_OPEN
-Open intent for given transaction.
-
-@id - local inode number.
-@start - 0.
-@size - path length to the object.
-@ext - open flags (O_RDWR and so on).
-
-
-@NETFS_INODE_INFO
-Metadata update command.
-It is sent to servers when attributes of the object are changed and received
-when data or metadata were updated. It operates with the following structure:
-
-struct netfs_inode_info
-{
-       unsigned int            mode;
-       unsigned int            nlink;
-       unsigned int            uid;
-       unsigned int            gid;
-       unsigned int            blocksize;
-       unsigned int            padding;
-       __u64                   ino;
-       __u64                   blocks;
-       __u64                   rdev;
-       __u64                   size;
-       __u64                   version;
-};
-
-It effectively mirrors stat(2) returned data.
-
-
-@ext - path length to the object.
-@size - the same plus size of the netfs_inode_info structure.
-@id - local inode number.
-@start - 0.
-
-
-@NETFS_PAGE_CACHE
-Command is only received by clients. It contains information about
-page to be marked as not up-to-date.
-
-@id - client's inode number.
-@start - last byte of the page to be invalidated. If it is not equal to
-       current inode size, it will be vmtruncated().
-@size - 0
-@ext - 0
-
-
-@NETFS_READ_PAGES
-Used to read multiple contiguous pages in one go.
-
-@start - first byte of the contiguous region to read.
-@size - contains of two fields: lower 8 bits are used to represent page cache shift
-       used by client, another 3 bytes are used to get number of pages.
-@id - local inode number.
-@ext - path length to the object.
-
-
-@NETFS_RENAME
-Used to rename object.
-Attached data is formed into following string: "old_path|new_path".
-
-@id - local inode number.
-@start - parent inode number.
-@size - length of the above string.
-@ext - length of the old path part.
-
-
-@NETFS_CAPABILITIES
-Used to exchange crypto capabilities with server.
-If crypto capabilities are not supported by server, then client will disable it
-or fail (if 'crypto_fail_unsupported' mount options was specified).
-
-@id - superblock index. Used to specify crypto information for group of servers.
-@size - size of the attached capabilities structure.
-@start - 0.
-@size - 0.
-@scsize - 0.
-
-@NETFS_LOCK
-Used to send lock request/release messages. Although it sends byte range request
-and is capable of flushing pages based on that, it is not used, since all Linux
-filesystems lock the whole inode.
-
-@id - lock generation number.
-@start - start of the locked range.
-@size - size of the locked range.
-@ext - lock type: read/write. Not used actually. 15'th bit is used to determine,
-       if it is lock request (1) or release (0).
-
-@NETFS_XATTR_SET
-@NETFS_XATTR_GET
-Used to set/get extended attributes for given inode.
-@id - attribute generation number or xattr setting type
-@start - size of the attribute (request or attached)
-@size - name length, path len and data size for given attribute
-@ext - path length for given object
diff --git a/Documentation/laptops/lg-laptop.rst b/Documentation/laptops/lg-laptop.rst
new file mode 100644 (file)
index 0000000..e486fe7
--- /dev/null
@@ -0,0 +1,81 @@
+.. SPDX-License-Identifier: GPL-2.0+
+LG Gram laptop extra features
+=============================
+
+By Matan Ziv-Av <matan@svgalib.org>
+
+
+Hotkeys
+-------
+
+The following FN keys are ignored by the kernel without this driver:
+- FN-F1 (LG control panel)   - Generates F15
+- FN-F5 (Touchpad toggle)    - Generates F13
+- FN-F6 (Airplane mode)      - Generates RFKILL
+- FN-F8 (Keyboard backlight) - Generates F16.
+  This key also changes keyboard backlight mode.
+- FN-F9 (Reader mode)        - Generates F14
+
+The rest of the FN key work without a need for a special driver.
+
+
+Reader mode
+-----------
+
+Writing 0/1 to /sys/devices/platform/lg-laptop/reader_mode disables/enables
+reader mode. In this mode the screen colors change (blue color reduced),
+and the reader mode indicator LED (on F9 key) turns on.
+
+
+FN Lock
+-------
+
+Writing 0/1 to /sys/devices/platform/lg-laptop/fn_lock disables/enables
+FN lock.
+
+
+Battery care limit
+------------------
+
+Writing 80/100 to /sys/devices/platform/lg-laptop/battery_care_limit
+sets the maximum capacity to charge the battery. Limiting the charge
+reduces battery capacity loss over time.
+
+This value is reset to 100 when the kernel boots.
+
+
+Fan mode
+--------
+
+Writing 1/0 to /sys/devices/platform/lg-laptop/fan_mode disables/enables
+the fan silent mode.
+
+
+USB charge
+----------
+
+Writing 0/1 to /sys/devices/platform/lg-laptop/usb_charge disables/enables
+charging another device from the USB port while the device is turned off.
+
+This value is reset to 0 when the kernel boots.
+
+
+LEDs
+~~~~
+
+The are two LED devices supported by the driver:
+
+Keyboard backlight
+------------------
+
+A led device named kbd_led controls the keyboard backlight. There are three
+lighting level: off (0), low (127) and high (255).
+
+The keyboard backlight is also controlled by the key combination FN-F8
+which cycles through those levels.
+
+
+Touchpad indicator LED
+----------------------
+
+On the F5 key. Controlled by led device names tpad_led.
index 1d989c5443705e4f413eaf57165b9981bf904639..bca1d9d1d22317357cc9929a6eac8e9f9f82afa4 100644 (file)
@@ -268,6 +268,10 @@ to 1, if the hardware does support retry then either set these counters to
 0 if the hardware provides no feedback of which errors occurred and how many
 times, or fill in the correct values as reported by the hardware.
 
+Be aware that calling these functions can immediately start a new transmit
+if there is one pending in the queue. So make sure that the hardware is in
+a state where new transmits can be started *before* calling these functions.
+
 The cec_transmit_attempt_done() function is a helper for cases where the
 hardware never retries, so the transmit is always for just a single
 attempt. It will call cec_transmit_done() in turn, filling in 1 for the
index 0c05503eaf1fa6c7c0a109cfac1460cc0c4afe2b..69362b3135c2375412b23a130b27bfa2b1d9de7b 100644 (file)
@@ -262,3 +262,5 @@ in the end provide a way to use driver-specific callbacks.
 .. kernel-doc:: include/media/media-devnode.h
 
 .. kernel-doc:: include/media/media-entity.h
+
+.. kernel-doc:: include/media/media-request.h
index e1f0b726e438f96303ccc2bb3df727e7ff166be2..1280e05b662b1136ca8f157012d4a844f4ebebba 100644 (file)
@@ -247,20 +247,28 @@ performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
 registered this way are stored in a global list of subdevices, ready to be
 picked up by bridge drivers.
 
-Bridge drivers in turn have to register a notifier object with an array of
-subdevice descriptors that the bridge device needs for its operation. This is
+Bridge drivers in turn have to register a notifier object. This is
 performed using the :c:func:`v4l2_async_notifier_register` call. To
 unregister the notifier the driver has to call
 :c:func:`v4l2_async_notifier_unregister`. The former of the two functions
-takes two arguments: a pointer to struct :c:type:`v4l2_device` and a pointer to
-struct :c:type:`v4l2_async_notifier`. The latter contains a pointer to an array
-of pointers to subdevice descriptors of type struct :c:type:`v4l2_async_subdev`
-type. The V4L2 core will then use these descriptors to match asynchronously
-registered
-subdevices to them. If a match is detected the ``.bound()`` notifier callback
-is called. After all subdevices have been located the .complete() callback is
-called. When a subdevice is removed from the system the .unbind() method is
-called. All three callbacks are optional.
+takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
+pointer to struct :c:type:`v4l2_async_notifier`.
+
+Before registering the notifier, bridge drivers must do two things:
+first, the notifier must be initialized using the
+:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
+begin to form a list of subdevice descriptors that the bridge device
+needs for its operation. Subdevice descriptors are added to the notifier
+using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
+takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
+and a pointer to the subdevice descripter, which is of type struct
+:c:type:`v4l2_async_subdev`.
+
+The V4L2 core will then use these descriptors to match asynchronously
+registered subdevices to them. If a match is detected the ``.bound()``
+notifier callback is called. After all subdevices have been located the
+.complete() callback is called. When a subdevice is removed from the
+system the .unbind() method is called. All three callbacks are optional.
 
 V4L2 sub-device userspace API
 -----------------------------
index d49f1ee0742ddeeb28d12c99ff6673ed8bcc95b3..c698c969635c5732b3cb4ca6d4993807283e8519 100644 (file)
@@ -74,4 +74,5 @@ is returned, and the ``errno`` variable is set appropriately:
     The call was interrupted by a signal.
 
 ``EINVAL``
-    The ``nfds`` argument is greater than ``OPEN_MAX``.
+    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
+    ``getrlimit()`` to obtain this value.
index e964074cd15b757a00dd4c3cd6e519b920f46879..b25e48afaa0877199953e0de0a9f0fcbd2676b91 100644 (file)
@@ -16,10 +16,10 @@ CEC_RECEIVE, CEC_TRANSMIT - Receive or transmit a CEC message
 Synopsis
 ========
 
-.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg *argp )
+.. c:function:: int ioctl( int fd, CEC_RECEIVE, struct cec_msg \*argp )
     :name: CEC_RECEIVE
 
-.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg *argp )
+.. c:function:: int ioctl( int fd, CEC_TRANSMIT, struct cec_msg \*argp )
     :name: CEC_TRANSMIT
 
 Arguments
@@ -272,6 +272,19 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
       - The transmit failed after one or more retries. This status bit is
        mutually exclusive with :ref:`CEC_TX_STATUS_OK <CEC-TX-STATUS-OK>`.
        Other bits can still be set to explain which failures were seen.
+    * .. _`CEC-TX-STATUS-ABORTED`:
+
+      - ``CEC_TX_STATUS_ABORTED``
+      - 0x40
+      - The transmit was aborted due to an HDMI disconnect, or the adapter
+        was unconfigured, or a transmit was interrupted, or the driver
+       returned an error when attempting to start a transmit.
+    * .. _`CEC-TX-STATUS-TIMEOUT`:
+
+      - ``CEC_TX_STATUS_TIMEOUT``
+      - 0x80
+      - The transmit timed out. This should not normally happen and this
+       indicates a driver problem.
 
 
 .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
@@ -300,6 +313,14 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
       - The message was received successfully but the reply was
        ``CEC_MSG_FEATURE_ABORT``. This status is only set if this message
        was the reply to an earlier transmitted message.
+    * .. _`CEC-RX-STATUS-ABORTED`:
+
+      - ``CEC_RX_STATUS_ABORTED``
+      - 0x08
+      - The wait for a reply to an earlier transmitted message was aborted
+        because the HDMI cable was disconnected, the adapter was unconfigured
+       or the :ref:`CEC_TRANSMIT <CEC_RECEIVE>` that waited for a
+       reply was interrupted.
 
 
 
index 0eea4f9a07d5409fc4496f3382c68ada3a6ab37f..66aff38cd4994d6a75ae76b73339f7786f809621 100644 (file)
@@ -21,6 +21,7 @@ Part IV - Media Controller API
     media-controller-intro
     media-controller-model
     media-types
+    request-api
     media-funcs
     media-header
 
index 076856501cdb34feb0afd2724f2551587d59b599..260f9dcadcdecb795b6d1ad4a4b84a421d7fbcc6 100644 (file)
@@ -16,3 +16,9 @@ Function Reference
     media-ioc-enum-entities
     media-ioc-enum-links
     media-ioc-setup-link
+    media-ioc-request-alloc
+    request-func-close
+    request-func-ioctl
+    request-func-poll
+    media-request-ioc-queue
+    media-request-ioc-reinit
index 649cb3d9e05829ba2ad6f5ba8a5ab9739f337178..c6f224e404b79ce46b2f908aeaff03caa2437629 100644 (file)
@@ -26,6 +26,7 @@ Arguments
     File descriptor returned by :ref:`open() <media-func-open>`.
 
 ``argp``
+    Pointer to struct :c:type:`media_device_info`.
 
 
 Description
index fc2e39c070c9a041ae72f55312562aa832eac1f7..02738640e34e82f1edad0cb47b968f41039f15b5 100644 (file)
@@ -26,6 +26,7 @@ Arguments
     File descriptor returned by :ref:`open() <media-func-open>`.
 
 ``argp``
+    Pointer to struct :c:type:`media_entity_desc`.
 
 
 Description
index f158c134e9b0ea1ca24a218a169a0bf62d8b5fc3..b89aaae373df5af9252338eca2fbe81a5a2018de 100644 (file)
@@ -26,6 +26,7 @@ Arguments
     File descriptor returned by :ref:`open() <media-func-open>`.
 
 ``argp``
+    Pointer to struct :c:type:`media_links_enum`.
 
 
 Description
index bac128c7eda922c392512b000a5e3181a3400747..4e1c59238371a274012e9bb995376160193cd03a 100644 (file)
@@ -26,6 +26,7 @@ Arguments
     File descriptor returned by :ref:`open() <media-func-open>`.
 
 ``argp``
+    Pointer to struct :c:type:`media_v2_topology`.
 
 
 Description
diff --git a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst
new file mode 100644 (file)
index 0000000..0f8b318
--- /dev/null
@@ -0,0 +1,66 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_ioc_request_alloc:
+
+*****************************
+ioctl MEDIA_IOC_REQUEST_ALLOC
+*****************************
+
+Name
+====
+
+MEDIA_IOC_REQUEST_ALLOC - Allocate a request
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, MEDIA_IOC_REQUEST_ALLOC, int *argp )
+    :name: MEDIA_IOC_REQUEST_ALLOC
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <media-func-open>`.
+
+``argp``
+    Pointer to an integer.
+
+
+Description
+===========
+
+If the media device supports :ref:`requests <media-request-api>`, then
+this ioctl can be used to allocate a request. If it is not supported, then
+``errno`` is set to ``ENOTTY``. A request is accessed through a file descriptor
+that is returned in ``*argp``.
+
+If the request was successfully allocated, then the request file descriptor
+can be passed to the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
+:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls.
+
+In addition, the request can be queued by calling
+:ref:`MEDIA_REQUEST_IOC_QUEUE` and re-initialized by calling
+:ref:`MEDIA_REQUEST_IOC_REINIT`.
+
+Finally, the file descriptor can be :ref:`polled <request-func-poll>` to wait
+for the request to complete.
+
+The request will remain allocated until all the file descriptors associated
+with it are closed by :ref:`close() <request-func-close>` and the driver no
+longer uses the request internally. See also
+:ref:`here <media-request-life-time>` for more information.
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+ENOTTY
+    The driver has no support for requests.
index ae5194940100e2d5bef9822b8d50993ab20e9bc7..e345e7dc9ad78971db1eee485383b9b7be1a1440 100644 (file)
@@ -26,6 +26,7 @@ Arguments
     File descriptor returned by :ref:`open() <media-func-open>`.
 
 ``argp``
+    Pointer to struct :c:type:`media_link_desc`.
 
 
 Description
diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst
new file mode 100644 (file)
index 0000000..6dd2d7f
--- /dev/null
@@ -0,0 +1,78 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_request_ioc_queue:
+
+*****************************
+ioctl MEDIA_REQUEST_IOC_QUEUE
+*****************************
+
+Name
+====
+
+MEDIA_REQUEST_IOC_QUEUE - Queue a request
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_QUEUE )
+    :name: MEDIA_REQUEST_IOC_QUEUE
+
+
+Arguments
+=========
+
+``request_fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+
+Description
+===========
+
+If the media device supports :ref:`requests <media-request-api>`, then
+this request ioctl can be used to queue a previously allocated request.
+
+If the request was successfully queued, then the file descriptor can be
+:ref:`polled <request-func-poll>` to wait for the request to complete.
+
+If the request was already queued before, then ``EBUSY`` is returned.
+Other errors can be returned if the contents of the request contained
+invalid or inconsistent data, see the next section for a list of
+common error codes. On error both the request and driver state are unchanged.
+
+Once a request is queued, then the driver is required to gracefully handle
+errors that occur when the request is applied to the hardware. The
+exception is the ``EIO`` error which signals a fatal error that requires
+the application to stop streaming to reset the hardware state.
+
+It is not allowed to mix queuing requests with queuing buffers directly
+(without a request). ``EBUSY`` will be returned if the first buffer was
+queued directly and you next try to queue a request, or vice versa.
+
+A request must contain at least one buffer, otherwise this ioctl will
+return an ``ENOENT`` error.
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EBUSY
+    The request was already queued or the application queued the first
+    buffer directly, but later attempted to use a request. It is not permitted
+    to mix the two APIs.
+ENOENT
+    The request did not contain any buffers. All requests are required
+    to have at least one buffer. This can also be returned if some required
+    configuration is missing in the request.
+ENOMEM
+    Out of memory when allocating internal data structures for this
+    request.
+EINVAL
+    The request has invalid data.
+EIO
+    The hardware is in a bad state. To recover, the application needs to
+    stop streaming to reset the hardware state and then try to restart
+    streaming.
diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst b/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst
new file mode 100644 (file)
index 0000000..febe888
--- /dev/null
@@ -0,0 +1,51 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media_request_ioc_reinit:
+
+******************************
+ioctl MEDIA_REQUEST_IOC_REINIT
+******************************
+
+Name
+====
+
+MEDIA_REQUEST_IOC_REINIT - Re-initialize a request
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_REINIT )
+    :name: MEDIA_REQUEST_IOC_REINIT
+
+
+Arguments
+=========
+
+``request_fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+Description
+===========
+
+If the media device supports :ref:`requests <media-request-api>`, then
+this request ioctl can be used to re-initialize a previously allocated
+request.
+
+Re-initializing a request will clear any existing data from the request.
+This avoids having to :ref:`close() <request-func-close>` a completed
+request and allocate a new request. Instead the completed request can just
+be re-initialized and it is ready to be used again.
+
+A request can only be re-initialized if it either has not been queued
+yet, or if it was queued and completed. Otherwise it will set ``errno``
+to ``EBUSY``. No other error codes can be returned.
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately.
+
+EBUSY
+    The request is queued but not yet completed.
diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst
new file mode 100644 (file)
index 0000000..5f4a230
--- /dev/null
@@ -0,0 +1,252 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _media-request-api:
+
+Request API
+===========
+
+The Request API has been designed to allow V4L2 to deal with requirements of
+modern devices (stateless codecs, complex camera pipelines, ...) and APIs
+(Android Codec v2). One such requirement is the ability for devices belonging to
+the same pipeline to reconfigure and collaborate closely on a per-frame basis.
+Another is support of stateless codecs, which require controls to be applied
+to specific frames (aka 'per-frame controls') in order to be used efficiently.
+
+While the initial use-case was V4L2, it can be extended to other subsystems
+as well, as long as they use the media controller.
+
+Supporting these features without the Request API is not always possible and if
+it is, it is terribly inefficient: user-space would have to flush all activity
+on the media pipeline, reconfigure it for the next frame, queue the buffers to
+be processed with that configuration, and wait until they are all available for
+dequeuing before considering the next frame. This defeats the purpose of having
+buffer queues since in practice only one buffer would be queued at a time.
+
+The Request API allows a specific configuration of the pipeline (media
+controller topology + configuration for each media entity) to be associated with
+specific buffers. This allows user-space to schedule several tasks ("requests")
+with different configurations in advance, knowing that the configuration will be
+applied when needed to get the expected result. Configuration values at the time
+of request completion are also available for reading.
+
+Usage
+=====
+
+The Request API extends the Media Controller API and cooperates with
+subsystem-specific APIs to support request usage. At the Media Controller
+level, requests are allocated from the supporting Media Controller device
+node. Their life cycle is then managed through the request file descriptors in
+an opaque way. Configuration data, buffer handles and processing results
+stored in requests are accessed through subsystem-specific APIs extended for
+request support, such as V4L2 APIs that take an explicit ``request_fd``
+parameter.
+
+Request Allocation
+------------------
+
+User-space allocates requests using :ref:`MEDIA_IOC_REQUEST_ALLOC`
+for the media device node. This returns a file descriptor representing the
+request. Typically, several such requests will be allocated.
+
+Request Preparation
+-------------------
+
+Standard V4L2 ioctls can then receive a request file descriptor to express the
+fact that the ioctl is part of said request, and is not to be applied
+immediately. See :ref:`MEDIA_IOC_REQUEST_ALLOC` for a list of ioctls that
+support this. Configurations set with a ``request_fd`` parameter are stored
+instead of being immediately applied, and buffers queued to a request do not
+enter the regular buffer queue until the request itself is queued.
+
+Request Submission
+------------------
+
+Once the configuration and buffers of the request are specified, it can be
+queued by calling :ref:`MEDIA_REQUEST_IOC_QUEUE` on the request file descriptor.
+A request must contain at least one buffer, otherwise ``ENOENT`` is returned.
+A queued request cannot be modified anymore.
+
+.. caution::
+   For :ref:`memory-to-memory devices <codec>` you can use requests only for
+   output buffers, not for capture buffers. Attempting to add a capture buffer
+   to a request will result in an ``EACCES`` error.
+
+If the request contains configurations for multiple entities, individual drivers
+may synchronize so the requested pipeline's topology is applied before the
+buffers are processed. Media controller drivers do a best effort implementation
+since perfect atomicity may not be possible due to hardware limitations.
+
+.. caution::
+
+   It is not allowed to mix queuing requests with directly queuing buffers:
+   whichever method is used first locks this in place until
+   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called or the device is
+   :ref:`closed <func-close>`. Attempts to directly queue a buffer when earlier
+   a buffer was queued via a request or vice versa will result in an ``EBUSY``
+   error.
+
+Controls can still be set without a request and are applied immediately,
+regardless of whether a request is in use or not.
+
+.. caution::
+
+   Setting the same control through a request and also directly can lead to
+   undefined behavior!
+
+User-space can :ref:`poll() <request-func-poll>` a request file descriptor in
+order to wait until the request completes. A request is considered complete
+once all its associated buffers are available for dequeuing and all the
+associated controls have been updated with the values at the time of completion.
+Note that user-space does not need to wait for the request to complete to
+dequeue its buffers: buffers that are available halfway through a request can
+be dequeued independently of the request's state.
+
+A completed request contains the state of the device after the request was
+executed. User-space can query that state by calling
+:ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with the request file
+descriptor. Calling :ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
+request that has been queued but not yet completed will return ``EBUSY``
+since the control values might be changed at any time by the driver while the
+request is in flight.
+
+.. _media-request-life-time:
+
+Recycling and Destruction
+-------------------------
+
+Finally, a completed request can either be discarded or be reused. Calling
+:ref:`close() <request-func-close>` on a request file descriptor will make
+that file descriptor unusable and the request will be freed once it is no
+longer in use by the kernel. That is, if the request is queued and then the
+file descriptor is closed, then it won't be freed until the driver completed
+the request.
+
+The :ref:`MEDIA_REQUEST_IOC_REINIT` will clear a request's state and make it
+available again. No state is retained by this operation: the request is as
+if it had just been allocated.
+
+Example for a Codec Device
+--------------------------
+
+For use-cases such as :ref:`codecs <codec>`, the request API can be used
+to associate specific controls to
+be applied by the driver for the OUTPUT buffer, allowing user-space
+to queue many such buffers in advance. It can also take advantage of requests'
+ability to capture the state of controls when the request completes to read back
+information that may be subject to change.
+
+Put into code, after obtaining a request, user-space can assign controls and one
+OUTPUT buffer to it:
+
+.. code-block:: c
+
+       struct v4l2_buffer buf;
+       struct v4l2_ext_controls ctrls;
+       int req_fd;
+       ...
+       if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
+               return errno;
+       ...
+       ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+       ctrls.request_fd = req_fd;
+       if (ioctl(codec_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
+               return errno;
+       ...
+       buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
+       buf.request_fd = req_fd;
+       if (ioctl(codec_fd, VIDIOC_QBUF, &buf))
+               return errno;
+
+Note that it is not allowed to use the Request API for CAPTURE buffers
+since there are no per-frame settings to report there.
+
+Once the request is fully prepared, it can be queued to the driver:
+
+.. code-block:: c
+
+       if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
+               return errno;
+
+User-space can then either wait for the request to complete by calling poll() on
+its file descriptor, or start dequeuing CAPTURE buffers. Most likely, it will
+want to get CAPTURE buffers as soon as possible and this can be done using a
+regular :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`:
+
+.. code-block:: c
+
+       struct v4l2_buffer buf;
+
+       memset(&buf, 0, sizeof(buf));
+       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       if (ioctl(codec_fd, VIDIOC_DQBUF, &buf))
+               return errno;
+
+Note that this example assumes for simplicity that for every OUTPUT buffer
+there will be one CAPTURE buffer, but this does not have to be the case.
+
+We can then, after ensuring that the request is completed via polling the
+request file descriptor, query control values at the time of its completion via
+a call to :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
+This is particularly useful for volatile controls for which we want to
+query values as soon as the capture buffer is produced.
+
+.. code-block:: c
+
+       struct pollfd pfd = { .events = POLLPRI, .fd = req_fd };
+       poll(&pfd, 1, -1);
+       ...
+       ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+       ctrls.request_fd = req_fd;
+       if (ioctl(codec_fd, VIDIOC_G_EXT_CTRLS, &ctrls))
+               return errno;
+
+Once we don't need the request anymore, we can either recycle it for reuse with
+:ref:`MEDIA_REQUEST_IOC_REINIT`...
+
+.. code-block:: c
+
+       if (ioctl(req_fd, MEDIA_REQUEST_IOC_REINIT))
+               return errno;
+
+... or close its file descriptor to completely dispose of it.
+
+.. code-block:: c
+
+       close(req_fd);
+
+Example for a Simple Capture Device
+-----------------------------------
+
+With a simple capture device, requests can be used to specify controls to apply
+for a given CAPTURE buffer.
+
+.. code-block:: c
+
+       struct v4l2_buffer buf;
+       struct v4l2_ext_controls ctrls;
+       int req_fd;
+       ...
+       if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
+               return errno;
+       ...
+       ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+       ctrls.request_fd = req_fd;
+       if (ioctl(camera_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
+               return errno;
+       ...
+       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
+       buf.request_fd = req_fd;
+       if (ioctl(camera_fd, VIDIOC_QBUF, &buf))
+               return errno;
+
+Once the request is fully prepared, it can be queued to the driver:
+
+.. code-block:: c
+
+       if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
+               return errno;
+
+User-space can then dequeue buffers, wait for the request completion, query
+controls and recycle the request as in the M2M example above.
diff --git a/Documentation/media/uapi/mediactl/request-func-close.rst b/Documentation/media/uapi/mediactl/request-func-close.rst
new file mode 100644 (file)
index 0000000..098d7f2
--- /dev/null
@@ -0,0 +1,49 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _request-func-close:
+
+***************
+request close()
+***************
+
+Name
+====
+
+request-close - Close a request file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+
+
+.. c:function:: int close( int fd )
+    :name: req-close
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+
+Description
+===========
+
+Closes the request file descriptor. Resources associated with the request
+are freed once all file descriptors associated with the request are closed
+and the driver has completed the request.
+See :ref:`here <media-request-life-time>` for more information.
+
+
+Return Value
+============
+
+:ref:`close() <request-func-close>` returns 0 on success. On error, -1 is
+returned, and ``errno`` is set appropriately. Possible error codes are:
+
+EBADF
+    ``fd`` is not a valid open file descriptor.
diff --git a/Documentation/media/uapi/mediactl/request-func-ioctl.rst b/Documentation/media/uapi/mediactl/request-func-ioctl.rst
new file mode 100644 (file)
index 0000000..ff7b072
--- /dev/null
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _request-func-ioctl:
+
+***************
+request ioctl()
+***************
+
+Name
+====
+
+request-ioctl - Control a request file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/ioctl.h>
+
+
+.. c:function:: int ioctl( int fd, int cmd, void *argp )
+    :name: req-ioctl
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
+
+``cmd``
+    The request ioctl command code as defined in the media.h header file, for
+    example :ref:`MEDIA_REQUEST_IOC_QUEUE`.
+
+``argp``
+    Pointer to a request-specific structure.
+
+
+Description
+===========
+
+The :ref:`ioctl() <request-func-ioctl>` function manipulates request
+parameters. The argument ``fd`` must be an open file descriptor.
+
+The ioctl ``cmd`` code specifies the request function to be called. It
+has encoded in it whether the argument is an input, output or read/write
+parameter, and the size of the argument ``argp`` in bytes.
+
+Macros and structures definitions specifying request ioctl commands and
+their parameters are located in the media.h header file. All request ioctl
+commands, their respective function and parameters are specified in
+:ref:`media-user-func`.
+
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+Command-specific error codes are listed in the individual command
+descriptions.
+
+When an ioctl that takes an output or read/write parameter fails, the
+parameter remains unmodified.
diff --git a/Documentation/media/uapi/mediactl/request-func-poll.rst b/Documentation/media/uapi/mediactl/request-func-poll.rst
new file mode 100644 (file)
index 0000000..8519125
--- /dev/null
@@ -0,0 +1,77 @@
+.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _request-func-poll:
+
+**************
+request poll()
+**************
+
+Name
+====
+
+request-poll - Wait for some event on a file descriptor
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <sys/poll.h>
+
+
+.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
+   :name: request-poll
+
+Arguments
+=========
+
+``ufds``
+   List of file descriptor events to be watched
+
+``nfds``
+   Number of file descriptor events at the \*ufds array
+
+``timeout``
+   Timeout to wait for events
+
+
+Description
+===========
+
+With the :c:func:`poll() <request-func-poll>` function applications can wait
+for a request to complete.
+
+On success :c:func:`poll() <request-func-poll>` returns the number of file
+descriptors that have been selected (that is, file descriptors for which the
+``revents`` field of the respective struct :c:type:`pollfd`
+is non-zero). Request file descriptor set the ``POLLPRI`` flag in ``revents``
+when the request was completed.  When the function times out it returns
+a value of zero, on failure it returns -1 and the ``errno`` variable is
+set appropriately.
+
+Attempting to poll for a request that is not yet queued will
+set the ``POLLERR`` flag in ``revents``.
+
+
+Return Value
+============
+
+On success, :c:func:`poll() <request-func-poll>` returns the number of
+structures which have non-zero ``revents`` fields, or zero if the call
+timed out. On error -1 is returned, and the ``errno`` variable is set
+appropriately:
+
+``EBADF``
+    One or more of the ``ufds`` members specify an invalid file
+    descriptor.
+
+``EFAULT``
+    ``ufds`` references an inaccessible memory area.
+
+``EINTR``
+    The call was interrupted by a signal.
+
+``EINVAL``
+    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
+    ``getrlimit()`` to obtain this value.
index 1cedcfc043273d9fa16c5d39c25a29b4f8f3667a..386d6cf83e9cab74e741b2251c8e48e26f35418c 100644 (file)
@@ -226,16 +226,6 @@ xvYCC
 
 :author:    International Electrotechnical Commission (http://www.iec.ch)
 
-.. _adobergb:
-
-AdobeRGB
-========
-
-
-:title:     Adobe© RGB (1998) Color Image Encoding Version 2005-05
-
-:author:    Adobe Systems Incorporated (http://www.adobe.com)
-
 .. _oprgb:
 
 opRGB
index e2c85ddc990b7ce548c461179eae3262b7038915..2e266d32470ae5169a7b6bc1f1aa48c0ad6863bc 100644 (file)
@@ -306,10 +306,23 @@ struct v4l2_buffer
       - A place holder for future extensions. Drivers and applications
        must set this to 0.
     * - __u32
-      - ``reserved``
+      - ``request_fd``
       -
-      - A place holder for future extensions. Drivers and applications
-       must set this to 0.
+      - The file descriptor of the request to queue the buffer to. If the flag
+        ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be
+       queued to this request. If the flag is not set, then this field will
+       be ignored.
+
+       The ``V4L2_BUF_FLAG_REQUEST_FD`` flag and this field are only used by
+       :ref:`ioctl VIDIOC_QBUF <VIDIOC_QBUF>` and ignored by other ioctls that
+       take a :c:type:`v4l2_buffer` as argument.
+
+       Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls
+       other than :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`.
+
+       If the device does not support requests, then ``EACCES`` will be returned.
+       If requests are supported but an invalid request file descriptor is
+       given, then ``EINVAL`` will be returned.
 
 
 
@@ -514,6 +527,11 @@ Buffer Flags
        streaming may continue as normal and the buffer may be reused
        normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is
        called.
+    * .. _`V4L2-BUF-FLAG-IN-REQUEST`:
+
+      - ``V4L2_BUF_FLAG_IN_REQUEST``
+      - 0x00000080
+      - This buffer is part of a request that hasn't been queued yet.
     * .. _`V4L2-BUF-FLAG-KEYFRAME`:
 
       - ``V4L2_BUF_FLAG_KEYFRAME``
@@ -589,6 +607,11 @@ Buffer Flags
        the format. Any Any subsequent call to the
        :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
        but return an ``EPIPE`` error code.
+    * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
+
+      - ``V4L2_BUF_FLAG_REQUEST_FD``
+      - 0x00800000
+      - The ``request_fd`` field contains a valid file descriptor.
     * .. _`V4L2-BUF-FLAG-TIMESTAMP-MASK`:
 
       - ``V4L2_BUF_FLAG_TIMESTAMP_MASK``
index 410907fe9415e729be39d6ee9bfc978ea9278b33..f24615544792b2c20ee2325e815dfe52fb79e275 100644 (file)
@@ -51,8 +51,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum
       - See :ref:`col-rec709`.
     * - ``V4L2_COLORSPACE_SRGB``
       - See :ref:`col-srgb`.
-    * - ``V4L2_COLORSPACE_ADOBERGB``
-      - See :ref:`col-adobergb`.
+    * - ``V4L2_COLORSPACE_OPRGB``
+      - See :ref:`col-oprgb`.
     * - ``V4L2_COLORSPACE_BT2020``
       - See :ref:`col-bt2020`.
     * - ``V4L2_COLORSPACE_DCI_P3``
@@ -90,8 +90,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum
       - Use the Rec. 709 transfer function.
     * - ``V4L2_XFER_FUNC_SRGB``
       - Use the sRGB transfer function.
-    * - ``V4L2_XFER_FUNC_ADOBERGB``
-      - Use the AdobeRGB transfer function.
+    * - ``V4L2_XFER_FUNC_OPRGB``
+      - Use the opRGB transfer function.
     * - ``V4L2_XFER_FUNC_SMPTE240M``
       - Use the SMPTE 240M transfer function.
     * - ``V4L2_XFER_FUNC_NONE``
index b5d551b9cc8f819fc7ee8c70299da3b307eed686..09fabf4cd4126b320c4e26d311e064cdaee17841 100644 (file)
@@ -290,15 +290,14 @@ Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range
 170M/BT.601. The Y'CbCr quantization is limited range.
 
 
-.. _col-adobergb:
+.. _col-oprgb:
 
-Colorspace Adobe RGB (V4L2_COLORSPACE_ADOBERGB)
+Colorspace opRGB (V4L2_COLORSPACE_OPRGB)
 ===============================================
 
-The :ref:`adobergb` standard defines the colorspace used by computer
-graphics that use the AdobeRGB colorspace. This is also known as the
-:ref:`oprgb` standard. The default transfer function is
-``V4L2_XFER_FUNC_ADOBERGB``. The default Y'CbCr encoding is
+The :ref:`oprgb` standard defines the colorspace used by computer
+graphics that use the opRGB colorspace. The default transfer function is
+``V4L2_XFER_FUNC_OPRGB``. The default Y'CbCr encoding is
 ``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited
 range.
 
@@ -312,7 +311,7 @@ The chromaticities of the primary colors and the white reference are:
 
 .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
 
-.. flat-table:: Adobe RGB Chromaticities
+.. flat-table:: opRGB Chromaticities
     :header-rows:  1
     :stub-columns: 0
     :widths:       1 1 2
index 9f7312bf33651c733ef8a675bceac7a9b44581fa..65a1d873196b6e741fc57da5658bebdc1a8f9d25 100644 (file)
@@ -1497,6 +1497,182 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
 
 
 
+.. _v4l2-mpeg-mpeg2:
+
+``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
+    Specifies the slice parameters (as extracted from the bitstream) for the
+    associated MPEG-2 slice data. This includes the necessary parameters for
+    configuring a stateless hardware decoding pipeline for MPEG-2.
+    The bitstream parameters are defined according to :ref:`mpeg2part2`.
+
+.. c:type:: v4l2_ctrl_mpeg2_slice_params
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_slice_params
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u32
+      - ``bit_size``
+      - Size (in bits) of the current slice data.
+    * - __u32
+      - ``data_bit_offset``
+      - Offset (in bits) to the video data in the current slice data.
+    * - struct :c:type:`v4l2_mpeg2_sequence`
+      - ``sequence``
+      - Structure with MPEG-2 sequence metadata, merging relevant fields from
+       the sequence header and sequence extension parts of the bitstream.
+    * - struct :c:type:`v4l2_mpeg2_picture`
+      - ``picture``
+      - Structure with MPEG-2 picture metadata, merging relevant fields from
+       the picture header and picture coding extension parts of the bitstream.
+    * - __u8
+      - ``quantiser_scale_code``
+      - Code used to determine the quantization scale to use for the IDCT.
+    * - __u8
+      - ``backward_ref_index``
+      - Index for the V4L2 buffer to use as backward reference, used with
+       B-coded and P-coded frames.
+    * - __u8
+      - ``forward_ref_index``
+      - Index for the V4L2 buffer to use as forward reference, used with
+       B-coded frames.
+
+.. c:type:: v4l2_mpeg2_sequence
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_mpeg2_sequence
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u16
+      - ``horizontal_size``
+      - The width of the displayable part of the frame's luminance component.
+    * - __u16
+      - ``vertical_size``
+      - The height of the displayable part of the frame's luminance component.
+    * - __u32
+      - ``vbv_buffer_size``
+      - Used to calculate the required size of the video buffering verifier,
+       defined (in bits) as: 16 * 1024 * vbv_buffer_size.
+    * - __u8
+      - ``profile_and_level_indication``
+      - The current profile and level indication as extracted from the
+       bitstream.
+    * - __u8
+      - ``progressive_sequence``
+      - Indication that all the frames for the sequence are progressive instead
+       of interlaced.
+    * - __u8
+      - ``chroma_format``
+      - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4).
+
+.. c:type:: v4l2_mpeg2_picture
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_mpeg2_picture
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``picture_coding_type``
+      - Picture coding type for the frame covered by the current slice
+       (V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or
+       V4L2_MPEG2_PICTURE_CODING_TYPE_B).
+    * - __u8
+      - ``f_code[2][2]``
+      - Motion vector codes.
+    * - __u8
+      - ``intra_dc_precision``
+      - Precision of Discrete Cosine transform (0: 8 bits precision,
+       1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision).
+    * - __u8
+      - ``picture_structure``
+      - Picture structure (1: interlaced top field, 2: interlaced bottom field,
+       3: progressive frame).
+    * - __u8
+      - ``top_field_first``
+      - If set to 1 and interlaced stream, top field is output first.
+    * - __u8
+      - ``frame_pred_frame_dct``
+      - If set to 1, only frame-DCT and frame prediction are used.
+    * - __u8
+      - ``concealment_motion_vectors``
+      -  If set to 1, motion vectors are coded for intra macroblocks.
+    * - __u8
+      - ``q_scale_type``
+      - This flag affects the inverse quantization process.
+    * - __u8
+      - ``intra_vlc_format``
+      - This flag affects the decoding of transform coefficient data.
+    * - __u8
+      - ``alternate_scan``
+      - This flag affects the decoding of transform coefficient data.
+    * - __u8
+      - ``repeat_first_field``
+      - This flag affects the decoding process of progressive frames.
+    * - __u8
+      - ``progressive_frame``
+      - Indicates whether the current frame is progressive.
+
+``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)``
+    Specifies quantization matrices (as extracted from the bitstream) for the
+    associated MPEG-2 slice data.
+
+.. c:type:: v4l2_ctrl_mpeg2_quantization
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_mpeg2_quantization
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``load_intra_quantiser_matrix``
+      - One bit to indicate whether to load the ``intra_quantiser_matrix`` data.
+    * - __u8
+      - ``load_non_intra_quantiser_matrix``
+      - One bit to indicate whether to load the ``non_intra_quantiser_matrix``
+       data.
+    * - __u8
+      - ``load_chroma_intra_quantiser_matrix``
+      - One bit to indicate whether to load the
+       ``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV
+       formats.
+    * - __u8
+      - ``load_chroma_non_intra_quantiser_matrix``
+      - One bit to indicate whether to load the
+       ``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0
+       YUV formats.
+    * - __u8
+      - ``intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for intra-coded frames, in zigzag
+       scanning order. It is relevant for both luma and chroma components,
+       although it can be superseded by the chroma-specific matrix for
+       non-4:2:0 YUV formats.
+    * - __u8
+      - ``non_intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for non-intra-coded frames, in
+       zigzag scanning order. It is relevant for both luma and chroma
+       components, although it can be superseded by the chroma-specific matrix
+       for non-4:2:0 YUV formats.
+    * - __u8
+      - ``chroma_intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for the chominance component of
+       intra-coded frames, in zigzag scanning order. Only relevant for
+       non-4:2:0 YUV formats.
+    * - __u8
+      - ``chroma_non_intra_quantiser_matrix[64]``
+      - The quantization matrix coefficients for the chrominance component of
+       non-intra-coded frames, in zigzag scanning order. Only relevant for
+       non-4:2:0 YUV formats.
 
 MFC 5.1 MPEG Controls
 ---------------------
index 360bc6523ae27e23e323e51441958ea31c636491..967fe8920729c5721594fb75244432c24e478611 100644 (file)
@@ -113,4 +113,5 @@ EINTR
     The call was interrupted by a signal.
 
 EINVAL
-    The ``nfds`` argument is greater than ``OPEN_MAX``.
+    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
+    ``getrlimit()`` to obtain this value.
index 0c4e1ecf58792275d9ee2c192dbbf0d309bf8573..cf971d5ad9ea7d7d52ea4668b65572c96ad76b57 100644 (file)
@@ -12,6 +12,7 @@ These formats are used for the :ref:`metadata` interface only.
 .. toctree::
     :maxdepth: 1
 
+    pixfmt-meta-d4xx
     pixfmt-meta-uvc
     pixfmt-meta-vsp1-hgo
     pixfmt-meta-vsp1-hgt
index d382e7a5c38e03f08e785623cc259f424bc9d9d0..ba0f6c49d9bf6bf3492c4d82bb82a7108ec28183 100644 (file)
@@ -60,6 +60,22 @@ Compressed Formats
       - ``V4L2_PIX_FMT_MPEG2``
       - 'MPG2'
       - MPEG2 video elementary stream.
+    * .. _V4L2-PIX-FMT-MPEG2-SLICE:
+
+      - ``V4L2_PIX_FMT_MPEG2_SLICE``
+      - 'MG2S'
+      - MPEG-2 parsed slice data, as extracted from the MPEG-2 bitstream.
+       This format is adapted for stateless video decoders that implement a
+       MPEG-2 pipeline (using the :ref:`codec` and :ref:`media-request-api`).
+       Metadata associated with the frame to decode is required to be passed
+       through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and
+       quantization matrices can optionally be specified through the
+       ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION`` control.
+       See the :ref:`associated Codec Control IDs <v4l2-mpeg-mpeg2>`.
+       Exactly one output and one capture buffer must be provided for use with
+       this pixel format. The output buffer must contain the appropriate number
+       of macroblocks to decode a full corresponding frame to the matching
+       capture buffer.
     * .. _V4L2-PIX-FMT-MPEG4:
 
       - ``V4L2_PIX_FMT_MPEG4``
@@ -101,4 +117,4 @@ Compressed Formats
       - 'FWHT'
       - Video elementary stream using a codec based on the Fast Walsh Hadamard
         Transform. This codec is implemented by the vicodec ('Virtual Codec')
-       driver. See the vicodec-codec.h header for more details.
+       driver. See the codec-fwht.h header for more details.
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst b/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst
new file mode 100644 (file)
index 0000000..63bf1a2
--- /dev/null
@@ -0,0 +1,210 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _v4l2-meta-fmt-d4xx:
+
+*******************************
+V4L2_META_FMT_D4XX ('D4XX')
+*******************************
+
+Intel D4xx UVC Cameras Metadata
+
+
+Description
+===========
+
+Intel D4xx (D435 and other) cameras include per-frame metadata in their UVC
+payload headers, following the Microsoft(R) UVC extension proposal [1_]. That
+means, that the private D4XX metadata, following the standard UVC header, is
+organised in blocks. D4XX cameras implement several standard block types,
+proposed by Microsoft, and several proprietary ones. Supported standard metadata
+types are MetadataId_CaptureStats (ID 3), MetadataId_CameraExtrinsics (ID 4),
+and MetadataId_CameraIntrinsics (ID 5). For their description see [1_]. This
+document describes proprietary metadata types, used by D4xx cameras.
+
+V4L2_META_FMT_D4XX buffers follow the metadata buffer layout of
+V4L2_META_FMT_UVC with the only difference, that it also includes proprietary
+payload header data. D4xx cameras use bulk transfers and only send one payload
+per frame, therefore their headers cannot be larger than 255 bytes.
+
+Below are proprietary Microsoft style metadata types, used by D4xx cameras,
+where all fields are in little endian order:
+
+.. flat-table:: D4xx metadata
+    :widths: 1 4
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Field
+      - Description
+    * - :cspan:`1` *Depth Control*
+    * - __u32 ID
+      - 0x80000000
+    * - __u32 Size
+      - Size in bytes (currently 56)
+    * - __u32 Version
+      - Version of this structure. The documentation herein corresponds to
+        version xxx. The version number will be incremented when new fields are
+        added.
+    * - __u32 Flags
+      - A bitmask of flags: see [2_] below
+    * - __u32 Gain
+      - Gain value in internal units, same as the V4L2_CID_GAIN control, used to
+       capture the frame
+    * - __u32 Exposure
+      - Exposure time (in microseconds) used to capture the frame
+    * - __u32 Laser power
+      - Power of the laser LED 0-360, used for depth measurement
+    * - __u32 AE mode
+      - 0: manual; 1: automatic exposure
+    * - __u32 Exposure priority
+      - Exposure priority value: 0 - constant frame rate
+    * - __u32 AE ROI left
+      - Left border of the AE Region of Interest (all ROI values are in pixels
+       and lie between 0 and maximum width or height respectively)
+    * - __u32 AE ROI right
+      - Right border of the AE Region of Interest
+    * - __u32 AE ROI top
+      - Top border of the AE Region of Interest
+    * - __u32 AE ROI bottom
+      - Bottom border of the AE Region of Interest
+    * - __u32 Preset
+      - Preset selector value, default: 0, unless changed by the user
+    * - __u32 Laser mode
+      - 0: off, 1: on
+    * - :cspan:`1` *Capture Timing*
+    * - __u32 ID
+      - 0x80000001
+    * - __u32 Size
+      - Size in bytes (currently 40)
+    * - __u32 Version
+      - Version of this structure. The documentation herein corresponds to
+        version xxx. The version number will be incremented when new fields are
+        added.
+    * - __u32 Flags
+      - A bitmask of flags: see [3_] below
+    * - __u32 Frame counter
+      - Monotonically increasing counter
+    * - __u32 Optical time
+      - Time in microseconds from the beginning of a frame till its middle
+    * - __u32 Readout time
+      - Time, used to read out a frame in microseconds
+    * - __u32 Exposure time
+      - Frame exposure time in microseconds
+    * - __u32 Frame interval
+      - In microseconds = 1000000 / framerate
+    * - __u32 Pipe latency
+      - Time in microseconds from start of frame to data in USB buffer
+    * - :cspan:`1` *Configuration*
+    * - __u32 ID
+      - 0x80000002
+    * - __u32 Size
+      - Size in bytes (currently 40)
+    * - __u32 Version
+      - Version of this structure. The documentation herein corresponds to
+        version xxx. The version number will be incremented when new fields are
+        added.
+    * - __u32 Flags
+      - A bitmask of flags: see [4_] below
+    * - __u8 Hardware type
+      - Camera hardware version [5_]
+    * - __u8 SKU ID
+      - Camera hardware configuration [6_]
+    * - __u32 Cookie
+      - Internal synchronisation
+    * - __u16 Format
+      - Image format code [7_]
+    * - __u16 Width
+      - Width in pixels
+    * - __u16 Height
+      - Height in pixels
+    * - __u16 Framerate
+      - Requested frame rate per second
+    * - __u16 Trigger
+      - Byte 0: bit 0: depth and RGB are synchronised, bit 1: external trigger
+
+.. _1:
+
+[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5
+
+.. _2:
+
+[2] Depth Control flags specify which fields are valid: ::
+
+  0x00000001 Gain
+  0x00000002 Exposure
+  0x00000004 Laser power
+  0x00000008 AE mode
+  0x00000010 Exposure priority
+  0x00000020 AE ROI
+  0x00000040 Preset
+
+.. _3:
+
+[3] Capture Timing flags specify which fields are valid: ::
+
+  0x00000001 Frame counter
+  0x00000002 Optical time
+  0x00000004 Readout time
+  0x00000008 Exposure time
+  0x00000010 Frame interval
+  0x00000020 Pipe latency
+
+.. _4:
+
+[4] Configuration flags specify which fields are valid: ::
+
+  0x00000001 Hardware type
+  0x00000002 SKU ID
+  0x00000004 Cookie
+  0x00000008 Format
+  0x00000010 Width
+  0x00000020 Height
+  0x00000040 Framerate
+  0x00000080 Trigger
+  0x00000100 Cal count
+
+.. _5:
+
+[5] Camera model: ::
+
+  0 DS5
+  1 IVCAM2
+
+.. _6:
+
+[6] 8-bit camera hardware configuration bitfield: ::
+
+  [1:0] depthCamera
+       00: no depth
+       01: standard depth
+       10: wide depth
+       11: reserved
+  [2]   depthIsActive - has a laser projector
+  [3]   RGB presence
+  [4]   Inertial Measurement Unit (IMU) presence
+  [5]   projectorType
+       0: HPTG
+       1: Princeton
+  [6]   0: a projector, 1: an LED
+  [7]   reserved
+
+.. _7:
+
+[7] Image format codes per video streaming interface:
+
+Depth: ::
+
+  1 Z16
+  2 Z
+
+Left sensor: ::
+
+  1 Y8
+  2 UYVY
+  3 R8L8
+  4 Calibration
+  5 W10
+
+Fish Eye sensor: ::
+
+  1 RAW8
index 38af1472a4b452aa4042b8c79709ddaa1e9228db..0c399858bda2e58477a3a97b1100ada9205502d2 100644 (file)
@@ -243,7 +243,20 @@ please make a proposal on the linux-media mailing list.
        It is an opaque intermediate format and the MDP hardware must be
        used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``,
        ``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``.
-
+    * .. _V4L2-PIX-FMT-SUNXI-TILED-NV12:
+
+      - ``V4L2_PIX_FMT_SUNXI_TILED_NV12``
+      - 'ST12'
+      - Two-planar NV12-based format used by the video engine found on Allwinner
+       (codenamed sunxi) platforms, with 32x32 tiles for the luminance plane
+       and 32x64 tiles for the chrominance plane. The data in each tile is
+       stored in linear order, within the tile bounds. Each tile follows the
+       previous one linearly in memory (from left to right, top to bottom).
+
+       The associated buffer dimensions are aligned to match an integer number
+       of tiles, resulting in 32-aligned resolutions for the luminance plane
+       and 16-aligned resolutions for the chrominance plane (with 2x2
+       subsampling).
 
 .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
 
index a39e18d69511ff3b995452db4803838974df03ed..eadf6f757fbfecb1ffa7b7e5b21bb0ddcdaafe55 100644 (file)
@@ -102,7 +102,19 @@ than the number requested.
       - ``format``
       - Filled in by the application, preserved by the driver.
     * - __u32
-      - ``reserved``\ [8]
+      - ``capabilities``
+      - Set by the driver. If 0, then the driver doesn't support
+        capabilities. In that case all you know is that the driver is
+       guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support
+       other :c:type:`v4l2_memory` types. It will not support any others
+       capabilities. See :ref:`here <v4l2-buf-capabilities>` for a list of the
+       capabilities.
+
+       If you want to just query the capabilities without making any
+       other changes, then set ``count`` to 0, ``memory`` to
+       ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type.
+    * - __u32
+      - ``reserved``\ [7]
       - A place holder for future extensions. Drivers and applications
        must set the array to zero.
 
index a65dbec6b20b843ffcc019b76b86e5bd83027b67..0a7b8287fd3885b429932d465714d47e88f96a87 100644 (file)
@@ -58,7 +58,7 @@ overlay devices.
       - Type of the data stream, set by the application. Only these types
        are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
        ``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
-       ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note above.
+       ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below.
     * - struct :ref:`v4l2_rect <v4l2-rect-crop>`
       - ``bounds``
       - Defines the window within capturing or output is possible, this
index cb3565f367933f0b983f2d292400856ac6f50fd2..04416b6943c0bd53ab9f4d72b65e9f4c751032bc 100644 (file)
@@ -379,7 +379,17 @@ call.
       - 0x0001
       - This event gets triggered when a resolution change is detected at
        an input. This can come from an input connector or from a video
-       decoder.
+       decoder. Applications will have to query the new resolution (if
+       any, the signal may also have been lost).
+
+       *Important*: even if the new video timings appear identical to the old
+       ones, receiving this event indicates that there was an issue with the
+       video signal and you must stop and restart streaming
+       (:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
+       followed by :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`). The reason is
+       that many devices are not able to recover from a temporary loss of
+       signal and so restarting streaming I/O is required in order for the
+       hardware to synchronize to the video signal.
 
 
 Return Value
index a6ed43ba9ca398090af3e017e405fd5fe35d410c..b95ba6743cbd7297f0a6609ba0c2186f9fbadb3a 100644 (file)
@@ -84,7 +84,7 @@ When cropping is not supported then no parameters are changed and
       - Type of the data stream, set by the application. Only these types
        are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
        ``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
-       ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note above.
+       ``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note below.
     * - struct :c:type:`v4l2_rect`
       - ``c``
       - Cropping rectangle. The same co-ordinate system as for struct
index 1a034e825161b0c3cbc4ca6b0bea113382439871..35cba2c8d4595d4431add09979c86203d1f65878 100644 (file)
@@ -257,14 +257,19 @@ EBUSY
        will also be cleared. This is a read-only flag, applications must
        not set this.
     * - ``V4L2_DV_FL_REDUCED_FPS``
-      - CEA-861 specific: only valid for video transmitters, the flag is
-       cleared by receivers. It is also only valid for formats with the
-       ``V4L2_DV_FL_CAN_REDUCE_FPS`` flag set, for other formats the
-       flag will be cleared by the driver. If the application sets this
-       flag, then the pixelclock used to set up the transmitter is
-       divided by 1.001 to make it compatible with NTSC framerates. If
-       the transmitter can't generate such frequencies, then the flag
-       will also be cleared.
+      - CEA-861 specific: only valid for video transmitters or video
+        receivers that have the ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS``
+       set. This flag is cleared otherwise. It is also only valid for
+       formats with the ``V4L2_DV_FL_CAN_REDUCE_FPS`` flag set, for other
+       formats the flag will be cleared by the driver.
+
+       If the application sets this flag for a transmitter, then the
+       pixelclock used to set up the transmitter is divided by 1.001 to
+       make it compatible with NTSC framerates. If the transmitter can't
+       generate such frequencies, then the flag will be cleared.
+
+       If a video receiver detects that the format uses a reduced framerate,
+       then it will set this flag to signal this to the application.
     * - ``V4L2_DV_FL_HALF_LINE``
       - Specific to interlaced formats: if set, then the vertical
        backporch of field 1 (aka the odd field) is really one half-line
@@ -294,3 +299,9 @@ EBUSY
       - If set, then the hdmi_vic field is valid and contains the Video
         Identification Code as per the HDMI standard (HDMI Vendor Specific
        InfoFrame).
+    * - ``V4L2_DV_FL_CAN_DETECT_REDUCED_FPS``
+      - CEA-861 specific: only valid for video receivers, the flag is
+        cleared by transmitters.
+        If set, then the hardware can detect the difference between
+       regular framerates and framerates reduced by 1000/1001. E.g.:
+       60 vs 59.94 Hz, 30 vs 29.97 Hz or 24 vs 23.976 Hz.
index 2011c2b2ee675e1b94e9763a736f9c990e790968..d9930fe776cf811143553ed84aa5cfad1b36b27c 100644 (file)
@@ -95,6 +95,25 @@ appropriate. In the first case the new value is set in struct
 is inappropriate (e.g. the given menu index is not supported by the menu
 control), then this will also result in an ``EINVAL`` error code error.
 
+If ``request_fd`` is set to a not-yet-queued :ref:`request <media-request-api>`
+file descriptor and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``,
+then the controls are not applied immediately when calling
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, but instead are applied by
+the driver for the buffer associated with the same request.
+If the device does not support requests, then ``EACCES`` will be returned.
+If requests are supported but an invalid request file descriptor is given,
+then ``EINVAL`` will be returned.
+
+An attempt to call :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
+request that has already been queued will result in an ``EBUSY`` error.
+
+If ``request_fd`` is specified and ``which`` is set to
+``V4L2_CTRL_WHICH_REQUEST_VAL`` during a call to
+:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, then it will return the
+values of the controls at the time of request completion.
+If the request is not yet completed, then this will result in an
+``EACCES`` error.
+
 The driver will only set/get these controls if all control values are
 correct. This prevents the situation where only some of the controls
 were set/get. Only low-level errors (e. g. a failed i2c command) can
@@ -209,13 +228,17 @@ still cause this situation.
       - ``which``
       - Which value of the control to get/set/try.
        ``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the
-       control and ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default
-       value of the control.
+       control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default
+       value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that
+       these controls have to be retrieved from a request or tried/set for
+       a request. In the latter case the ``request_fd`` field contains the
+       file descriptor of the request that should be used. If the device
+       does not support requests, then ``EACCES`` will be returned.
 
        .. note::
 
-          You can only get the default value of the control,
-          you cannot set or try it.
+          When using ``V4L2_CTRL_WHICH_DEF_VAL`` be aware that you can only
+          get the default value of the control, you cannot set or try it.
 
        For backwards compatibility you can also use a control class here
        (see :ref:`ctrl-class`). In that case all controls have to
@@ -272,8 +295,15 @@ still cause this situation.
        then you can call :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` to try to discover the
        actual control that failed the validation step. Unfortunately,
        there is no ``TRY`` equivalent for :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
+    * - __s32
+      - ``request_fd``
+      - File descriptor of the request to be used by this operation. Only
+       valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``.
+       If the device does not support requests, then ``EACCES`` will be returned.
+       If requests are supported but an invalid request file descriptor is
+       given, then ``EINVAL`` will be returned.
     * - __u32
-      - ``reserved``\ [2]
+      - ``reserved``\ [1]
       - Reserved for future extensions.
 
        Drivers and applications must set the array to zero.
@@ -347,11 +377,14 @@ appropriately. The generic error codes are described at the
 
 EINVAL
     The struct :c:type:`v4l2_ext_control` ``id`` is
-    invalid, the struct :c:type:`v4l2_ext_controls`
+    invalid, or the struct :c:type:`v4l2_ext_controls`
     ``which`` is invalid, or the struct
     :c:type:`v4l2_ext_control` ``value`` was
     inappropriate (e.g. the given menu index is not supported by the
-    driver). This error code is also returned by the
+    driver), or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL``
+    but the given ``request_fd`` was invalid or ``V4L2_CTRL_WHICH_REQUEST_VAL``
+    is not supported by the kernel.
+    This error code is also returned by the
     :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls if two or
     more control values are in conflict.
 
@@ -362,7 +395,9 @@ ERANGE
 EBUSY
     The control is temporarily not changeable, possibly because another
     applications took over control of the device function this control
-    belongs to.
+    belongs to, or (if the ``which`` field was set to
+    ``V4L2_CTRL_WHICH_REQUEST_VAL``) the request was queued but not yet
+    completed.
 
 ENOSPC
     The space reserved for the control's payload is insufficient. The
@@ -370,5 +405,9 @@ ENOSPC
     and this error code is returned.
 
 EACCES
-    Attempt to try or set a read-only control or to get a write-only
-    control.
+    Attempt to try or set a read-only control, or to get a write-only
+    control, or to get a control from a request that has not yet been
+    completed.
+
+    Or the ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the
+    device does not support requests.
index 9e448a4aa3aa917df34192b1a00089f8d37de37b..753b3b5946b1a88bf403ba5211e7ae1c9ff9c6a6 100644 (file)
@@ -65,7 +65,7 @@ To enqueue a :ref:`memory mapped <mmap>` buffer applications set the
 with a pointer to this structure the driver sets the
 ``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears
 the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an
-EINVAL error code.
+``EINVAL`` error code.
 
 To enqueue a :ref:`user pointer <userp>` buffer applications set the
 ``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to
@@ -98,6 +98,28 @@ dequeued, until the :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
 :ref:`VIDIOC_REQBUFS` ioctl is called, or until the
 device is closed.
 
+The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify
+the file descriptor of a :ref:`request <media-request-api>`, if requests are
+in use. Setting it means that the buffer will not be passed to the driver
+until the request itself is queued. Also, the driver will apply any
+settings associated with the request for this buffer. This field will
+be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set.
+If the device does not support requests, then ``EACCES`` will be returned.
+If requests are supported but an invalid request file descriptor is given,
+then ``EINVAL`` will be returned.
+
+.. caution::
+   It is not allowed to mix queuing requests with queuing buffers directly.
+   ``EBUSY`` will be returned if the first buffer was queued directly and
+   then the application tries to queue a request, or vice versa. After
+   closing the file descriptor, calling
+   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or calling :ref:`VIDIOC_REQBUFS`
+   the check for this will be reset.
+
+   For :ref:`memory-to-memory devices <codec>` you can specify the
+   ``request_fd`` only for output buffers, not for capture buffers. Attempting
+   to specify this for a capture buffer will result in an ``EACCES`` error.
+
 Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
 (capturing) or displayed (output) buffer from the driver's outgoing
 queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
@@ -133,7 +155,9 @@ EAGAIN
 EINVAL
     The buffer ``type`` is not supported, or the ``index`` is out of
     bounds, or no buffers have been allocated yet, or the ``userptr`` or
-    ``length`` are invalid.
+    ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was
+    set but the the given ``request_fd`` was invalid, or ``m.fd`` was
+    an invalid DMABUF file descriptor.
 
 EIO
     ``VIDIOC_DQBUF`` failed due to an internal error. Can also indicate
@@ -153,3 +177,12 @@ EPIPE
     ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem
     codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already
     dequeued and no new buffers are expected to become available.
+
+EACCES
+    The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not
+    support requests for the given buffer type.
+
+EBUSY
+    The first buffer was queued via a request, but the application now tries
+    to queue it directly, or vice versa (it is not permitted to mix the two
+    APIs).
index 5bd26e8c9a1a0ef2cba6e6b6d5d2e05a2236b598..258f5813f281c89f43211501aeb9acdd478f17b4 100644 (file)
@@ -424,8 +424,18 @@ See also the examples in :ref:`control`.
       - any
       - An unsigned 32-bit valued control ranging from minimum to maximum
        inclusive. The step value indicates the increment between values.
-
-
+    * - ``V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2
+       slice parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_MPEG2_QUANTIZATION``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
+       quantization matrices for stateless video decoders.
 
 .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
 
index 316f52c8a310b2c6f7fe3a4892b21035681af87a..d4bbbb0c60e80c94cadf94d928c60a0dcfec7adc 100644 (file)
@@ -88,10 +88,50 @@ any DMA in progress, an implicit
        ``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See
        :c:type:`v4l2_memory`.
     * - __u32
-      - ``reserved``\ [2]
+      - ``capabilities``
+      - Set by the driver. If 0, then the driver doesn't support
+        capabilities. In that case all you know is that the driver is
+       guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support
+       other :c:type:`v4l2_memory` types. It will not support any others
+       capabilities.
+
+       If you want to query the capabilities with a minimum of side-effects,
+       then this can be called with ``count`` set to 0, ``memory`` set to
+       ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will
+       free any previously allocated buffers, so this is typically something
+       that will be done at the start of the application.
+    * - __u32
+      - ``reserved``\ [1]
       - A place holder for future extensions. Drivers and applications
        must set the array to zero.
 
+.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
+
+.. _v4l2-buf-capabilities:
+.. _V4L2-BUF-CAP-SUPPORTS-MMAP:
+.. _V4L2-BUF-CAP-SUPPORTS-USERPTR:
+.. _V4L2-BUF-CAP-SUPPORTS-DMABUF:
+.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
+
+.. cssclass:: longtable
+
+.. flat-table:: V4L2 Buffer Capabilities Flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       3 1 4
+
+    * - ``V4L2_BUF_CAP_SUPPORTS_MMAP``
+      - 0x00000001
+      - This buffer type supports the ``V4L2_MEMORY_MMAP`` streaming mode.
+    * - ``V4L2_BUF_CAP_SUPPORTS_USERPTR``
+      - 0x00000002
+      - This buffer type supports the ``V4L2_MEMORY_USERPTR`` streaming mode.
+    * - ``V4L2_BUF_CAP_SUPPORTS_DMABUF``
+      - 0x00000004
+      - This buffer type supports the ``V4L2_MEMORY_DMABUF`` streaming mode.
+    * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS``
+      - 0x00000008
+      - This buffer type supports :ref:`requests <media-request-api>`.
 
 Return Value
 ============
index ca9f0edc579e664a3cd18c3d7c6b6a45e9d65d0e..1ec425a7c3642e66a6b250c1223129b3b09eab5a 100644 (file)
@@ -56,7 +56,8 @@ replace symbol V4L2_MEMORY_USERPTR :c:type:`v4l2_memory`
 # Documented enum v4l2_colorspace
 replace symbol V4L2_COLORSPACE_470_SYSTEM_BG :c:type:`v4l2_colorspace`
 replace symbol V4L2_COLORSPACE_470_SYSTEM_M :c:type:`v4l2_colorspace`
-replace symbol V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace`
+replace symbol V4L2_COLORSPACE_OPRGB :c:type:`v4l2_colorspace`
+replace define V4L2_COLORSPACE_ADOBERGB :c:type:`v4l2_colorspace`
 replace symbol V4L2_COLORSPACE_BT2020 :c:type:`v4l2_colorspace`
 replace symbol V4L2_COLORSPACE_DCI_P3 :c:type:`v4l2_colorspace`
 replace symbol V4L2_COLORSPACE_DEFAULT :c:type:`v4l2_colorspace`
@@ -69,7 +70,8 @@ replace symbol V4L2_COLORSPACE_SRGB :c:type:`v4l2_colorspace`
 
 # Documented enum v4l2_xfer_func
 replace symbol V4L2_XFER_FUNC_709 :c:type:`v4l2_xfer_func`
-replace symbol V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func`
+replace symbol V4L2_XFER_FUNC_OPRGB :c:type:`v4l2_xfer_func`
+replace define V4L2_XFER_FUNC_ADOBERGB :c:type:`v4l2_xfer_func`
 replace symbol V4L2_XFER_FUNC_DCI_P3 :c:type:`v4l2_xfer_func`
 replace symbol V4L2_XFER_FUNC_DEFAULT :c:type:`v4l2_xfer_func`
 replace symbol V4L2_XFER_FUNC_NONE :c:type:`v4l2_xfer_func`
@@ -129,6 +131,8 @@ replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
 
 # V4L2 capability defines
 replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
@@ -278,6 +282,7 @@ replace define V4L2_DV_BT_STD_SDI dv-bt-standards
 
 replace define V4L2_DV_FL_REDUCED_BLANKING dv-bt-standards
 replace define V4L2_DV_FL_CAN_REDUCE_FPS dv-bt-standards
+replace define V4L2_DV_FL_CAN_DETECT_REDUCED_FPS dv-bt-standards
 replace define V4L2_DV_FL_REDUCED_FPS dv-bt-standards
 replace define V4L2_DV_FL_HALF_LINE dv-bt-standards
 replace define V4L2_DV_FL_IS_CE_VIDEO dv-bt-standards
@@ -514,6 +519,7 @@ ignore define V4L2_CTRL_DRIVER_PRIV
 ignore define V4L2_CTRL_MAX_DIMS
 ignore define V4L2_CTRL_WHICH_CUR_VAL
 ignore define V4L2_CTRL_WHICH_DEF_VAL
+ignore define V4L2_CTRL_WHICH_REQUEST_VAL
 ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS
 ignore define V4L2_CID_MAX_CTRLS
 
index da193e092fc3d5314164cf0dc0aae075addcd0d8..86e47c19a9240524e9f06bc4e135824ac43e5f0e 100644 (file)
@@ -7,7 +7,7 @@ This document is meant as a brief overview of some aspects of the new serial
 driver.  It is not complete, any questions you have should be directed to
 <rmk@arm.linux.org.uk>
 
-The reference implementation is contained within amba_pl011.c.
+The reference implementation is contained within amba-pl011.c.
 
 
 
diff --git a/Documentation/serial/serial-iso7816.txt b/Documentation/serial/serial-iso7816.txt
new file mode 100644 (file)
index 0000000..3193d24
--- /dev/null
@@ -0,0 +1,83 @@
+                        ISO7816 SERIAL COMMUNICATIONS
+
+1. INTRODUCTION
+
+  ISO/IEC7816 is a series of standards specifying integrated circuit cards (ICC)
+  also known as smart cards.
+
+2. HARDWARE-RELATED CONSIDERATIONS
+
+  Some CPUs/UARTs (e.g., Microchip AT91) contain a built-in mode capable of
+  handling communication with a smart card.
+
+  For these microcontrollers, the Linux driver should be made capable of
+  working in both modes, and proper ioctls (see later) should be made
+  available at user-level to allow switching from one mode to the other, and
+  vice versa.
+
+3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL
+
+  The Linux kernel provides the serial_iso7816 structure (see [1]) to handle
+  ISO7816 communications. This data structure is used to set and configure
+  ISO7816 parameters in ioctls.
+
+  Any driver for devices capable of working both as RS232 and ISO7816 should
+  implement the iso7816_config callback in the uart_port structure. The
+  serial_core calls iso7816_config to do the device specific part in response
+  to TIOCGISO7816 and TIOCSISO7816 ioctls (see below). The iso7816_config
+  callback receives a pointer to struct serial_iso7816.
+
+4. USAGE FROM USER-LEVEL
+
+  From user-level, ISO7816 configuration can be get/set using the previous
+  ioctls. For instance, to set ISO7816 you can use the following code:
+
+       #include <linux/serial.h>
+
+       /* Include definition for ISO7816 ioctls: TIOCSISO7816 and TIOCGISO7816 */
+       #include <sys/ioctl.h>
+
+       /* Open your specific device (e.g., /dev/mydevice): */
+       int fd = open ("/dev/mydevice", O_RDWR);
+       if (fd < 0) {
+               /* Error handling. See errno. */
+       }
+
+       struct serial_iso7816 iso7816conf;
+
+       /* Reserved fields as to be zeroed */
+       memset(&iso7816conf, 0, sizeof(iso7816conf));
+
+       /* Enable ISO7816 mode: */
+       iso7816conf.flags |= SER_ISO7816_ENABLED;
+
+       /* Select the protocol: */
+       /* T=0 */
+       iso7816conf.flags |= SER_ISO7816_T(0);
+       /* or T=1 */
+       iso7816conf.flags |= SER_ISO7816_T(1);
+
+       /* Set the guard time: */
+       iso7816conf.tg = 2;
+
+       /* Set the clock frequency*/
+       iso7816conf.clk = 3571200;
+
+       /* Set transmission factors: */
+       iso7816conf.sc_fi = 372;
+       iso7816conf.sc_di = 1;
+
+       if (ioctl(fd_usart, TIOCSISO7816, &iso7816conf) < 0) {
+               /* Error handling. See errno. */
+       }
+
+       /* Use read() and write() syscalls here... */
+
+       /* Close the device when finished: */
+       if (close (fd) < 0) {
+               /* Error handling. See errno. */
+       }
+
+5. REFERENCES
+
+ [1]    include/uapi/linux/serial.h
index 8bfc75c908061710ec3e406c7497000b08a80050..47e765c2f2c379851393084405aa8f45f52b5944 100644 (file)
@@ -45,16 +45,18 @@ Synopsis of kprobe_events
   @SYM[+|-offs]        : Fetch memory at SYM +|- offs (SYM should be a data symbol)
   $stackN      : Fetch Nth entry of stack (N >= 0)
   $stack       : Fetch stack address.
-  $retval      : Fetch return value.(*)
+  $argN                : Fetch the Nth function argument. (N >= 1) (\*1)
+  $retval      : Fetch return value.(\*2)
   $comm                : Fetch current task comm.
-  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
+  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(\*3)
   NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
   FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
                  (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
                  (x8/x16/x32/x64), "string" and bitfield are supported.
 
-  (*) only for return probe.
-  (**) this is useful for fetching a field of data structures.
+  (\*1) only for the probe on function entry (offs == 0).
+  (\*2) only for return probe.
+  (\*3) this is useful for fetching a field of data structures.
 
 Types
 -----
@@ -64,14 +66,27 @@ respectively. 'x' prefix implies it is unsigned. Traced arguments are shown
 in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32'
 or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and
 x86-64 uses x64).
+These value types can be an array. To record array data, you can add '[N]'
+(where N is a fixed number, less than 64) to the base type.
+E.g. 'x16[4]' means an array of x16 (2bytes hex) with 4 elements.
+Note that the array can be applied to memory type fetchargs, you can not
+apply it to registers/stack-entries etc. (for example, '$stack1:x8[8]' is
+wrong, but '+8($stack):x8[8]' is OK.)
 String type is a special type, which fetches a "null-terminated" string from
 kernel space. This means it will fail and store NULL if the string container
 has been paged out.
+The string array type is a bit different from other types. For other base
+types, <base-type>[1] is equal to <base-type> (e.g. +0(%di):x32[1] is same
+as +0(%di):x32.) But string[1] is not equal to string. The string type itself
+represents "char array", but string array type represents "char * array".
+So, for example, +0(%di):string[1] is equal to +0(+0(%di)):string.
 Bitfield is another special type, which takes 3 parameters, bit-width, bit-
 offset, and container-size (usually 32). The syntax is::
 
  b<bit-width>@<bit-offset>/<container-size>
 
+Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG)
+which shows given pointer in "symbol+offset" style.
 For $comm, the default type is "string"; any other type is invalid.
 
 
diff --git a/Documentation/xilinx/eemi.txt b/Documentation/xilinx/eemi.txt
new file mode 100644 (file)
index 0000000..0ab686c
--- /dev/null
@@ -0,0 +1,67 @@
+---------------------------------------------------------------------
+Xilinx Zynq MPSoC EEMI Documentation
+---------------------------------------------------------------------
+
+Xilinx Zynq MPSoC Firmware Interface
+-------------------------------------
+The zynqmp-firmware node describes the interface to platform firmware.
+ZynqMP has an interface to communicate with secure firmware. Firmware
+driver provides an interface to firmware APIs. Interface APIs can be
+used by any driver to communicate with PMC(Platform Management Controller).
+
+Embedded Energy Management Interface (EEMI)
+----------------------------------------------
+The embedded energy management interface is used to allow software
+components running across different processing clusters on a chip or
+device to communicate with a power management controller (PMC) on a
+device to issue or respond to power management requests.
+
+EEMI ops is a structure containing all eemi APIs supported by Zynq MPSoC.
+The zynqmp-firmware driver maintain all EEMI APIs in zynqmp_eemi_ops
+structure. Any driver who want to communicate with PMC using EEMI APIs
+can call zynqmp_pm_get_eemi_ops().
+
+Example of EEMI ops:
+
+       /* zynqmp-firmware driver maintain all EEMI APIs */
+       struct zynqmp_eemi_ops {
+               int (*get_api_version)(u32 *version);
+               int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out);
+       };
+
+       static const struct zynqmp_eemi_ops eemi_ops = {
+               .get_api_version = zynqmp_pm_get_api_version,
+               .query_data = zynqmp_pm_query_data,
+       };
+
+Example of EEMI ops usage:
+
+       static const struct zynqmp_eemi_ops *eemi_ops;
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       eemi_ops = zynqmp_pm_get_eemi_ops();
+       if (!eemi_ops)
+               return -ENXIO;
+
+       ret = eemi_ops->query_data(qdata, ret_payload);
+
+IOCTL
+------
+IOCTL API is for device control and configuration. It is not a system
+IOCTL but it is an EEMI API. This API can be used by master to control
+any device specific configuration. IOCTL definitions can be platform
+specific. This API also manage shared device configuration.
+
+The following IOCTL IDs are valid for device control:
+- IOCTL_SET_PLL_FRAC_MODE      8
+- IOCTL_GET_PLL_FRAC_MODE      9
+- IOCTL_SET_PLL_FRAC_DATA      10
+- IOCTL_GET_PLL_FRAC_DATA      11
+
+Refer EEMI API guide [0] for IOCTL specific parameters and other EEMI APIs.
+
+References
+----------
+[0] Embedded Energy Management Interface (EEMI) API guide:
+    https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf
index 11b7d81f883ae19ef7c83b30bb7bbef5877caa14..245ba32f53649a6897816da12439cd1cc4a5b737 100644 (file)
@@ -376,7 +376,7 @@ F:  drivers/platform/x86/i2c-multi-instantiate.c
 ACPI PMIC DRIVERS
 M:     "Rafael J. Wysocki" <rjw@rjwysocki.net>
 M:     Len Brown <lenb@kernel.org>
-R:     Andy Shevchenko <andy@infradead.org>
+R:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 R:     Mika Westerberg <mika.westerberg@linux.intel.com>
 L:     linux-acpi@vger.kernel.org
 Q:     https://patchwork.kernel.org/project/linux-acpi/list/
@@ -549,6 +549,15 @@ W: http://ez.analog.com/community/linux-device-drivers
 S:     Supported
 F:     drivers/input/misc/adxl34x.c
 
+ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
+M:     Stefan Popa <stefan.popa@analog.com>
+W:     http://ez.analog.com/community/linux-device-drivers
+S:     Supported
+F:     drivers/iio/accel/adxl372.c
+F:     drivers/iio/accel/adxl372_spi.c
+F:     drivers/iio/accel/adxl372_i2c.c
+F:     Documentation/devicetree/bindings/iio/accel/adxl372.txt
+
 AF9013 MEDIA DRIVER
 M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
@@ -662,6 +671,13 @@ L: linux-crypto@vger.kernel.org
 S:     Maintained
 F:     drivers/crypto/sunxi-ss/
 
+ALLWINNER VPU DRIVER
+M:     Maxime Ripard <maxime.ripard@bootlin.com>
+M:     Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/staging/media/sunxi/cedrus/
+
 ALPHA PORT
 M:     Richard Henderson <rth@twiddle.net>
 M:     Ivan Kokshaysky <ink@jurassic.park.msu.ru>
@@ -1078,6 +1094,29 @@ F:       arch/arm/include/asm/arch_timer.h
 F:     arch/arm64/include/asm/arch_timer.h
 F:     drivers/clocksource/arm_arch_timer.c
 
+ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT
+M:     Linus Walleij <linus.walleij@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     Documentation/devicetree/bindings/arm/arm-boards
+F:     Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
+F:     Documentation/devicetree/bindings/clock/arm-integrator.txt
+F:     Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.txt
+F:     Documentation/devicetree/bindings/mtd/arm-versatile.txt
+F:     arch/arm/mach-integrator/
+F:     arch/arm/mach-realview/
+F:     arch/arm/mach-versatile/
+F:     arch/arm/plat-versatile/
+F:     arch/arm/boot/dts/arm-realview-*
+F:     arch/arm/boot/dts/integrator*
+F:     arch/arm/boot/dts/versatile*
+F:     drivers/clk/versatile/
+F:     drivers/i2c/busses/i2c-versatile.c
+F:     drivers/irqchip/irq-versatile-fpga.c
+F:     drivers/mtd/maps/physmap_of_versatile.c
+F:     drivers/power/reset/arm-versatile-reboot.c
+F:     drivers/soc/versatile/
+
 ARM HDLCD DRM DRIVER
 M:     Liviu Dudau <liviu.dudau@arm.com>
 S:     Supported
@@ -1150,12 +1189,26 @@ S:      Odd Fixes
 F:     drivers/mmc/host/mmci.*
 F:     include/linux/amba/mmci.h
 
+ARM PRIMECELL SSP PL022 SPI DRIVER
+M:     Linus Walleij <linus.walleij@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     Documentation/devicetree/bindings/spi/spi_pl022.txt
+F:     drivers/spi/spi-pl022.c
+
 ARM PRIMECELL UART PL010 AND PL011 DRIVERS
 M:     Russell King <linux@armlinux.org.uk>
 S:     Odd Fixes
 F:     drivers/tty/serial/amba-pl01*.c
 F:     include/linux/amba/serial.h
 
+ARM PRIMECELL VIC PL190/PL192 DRIVER
+M:     Linus Walleij <linus.walleij@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     Documentation/devicetree/bindings/interrupt-controller/arm,vic.txt
+F:     drivers/irqchip/irq-vic.c
+
 ARM SMMU DRIVERS
 M:     Will Deacon <will.deacon@arm.com>
 R:     Robin Murphy <robin.murphy@arm.com>
@@ -1175,18 +1228,25 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
 
 ARM/ACTIONS SEMI ARCHITECTURE
 M:     Andreas Färber <afaerber@suse.de>
+R:     Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 N:     owl
 F:     arch/arm/mach-actions/
 F:     arch/arm/boot/dts/owl-*
 F:     arch/arm64/boot/dts/actions/
+F:     drivers/clk/actions/
 F:     drivers/clocksource/timer-owl*
+F:     drivers/dma/owl-dma.c
+F:     drivers/i2c/busses/i2c-owl.c
 F:     drivers/pinctrl/actions/*
 F:     drivers/soc/actions/
 F:     include/dt-bindings/power/owl-*
 F:     include/linux/soc/actions/
 F:     Documentation/devicetree/bindings/arm/actions.txt
+F:     Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
+F:     Documentation/devicetree/bindings/dma/owl-dma.txt
+F:     Documentation/devicetree/bindings/i2c/i2c-owl.txt
 F:     Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
 F:     Documentation/devicetree/bindings/power/actions,owl-sps.txt
 F:     Documentation/devicetree/bindings/timer/actions,owl-timer.txt
@@ -1462,7 +1522,9 @@ F:        arch/arm/mach-mxs/
 F:     arch/arm/boot/dts/imx*
 F:     arch/arm/configs/imx*_defconfig
 F:     drivers/clk/imx/
+F:     drivers/firmware/imx/
 F:     drivers/soc/imx/
+F:     include/linux/firmware/imx/
 F:     include/soc/imx/
 
 ARM/FREESCALE VYBRID ARM ARCHITECTURE
@@ -1599,12 +1661,10 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
 ARM/LPC18XX ARCHITECTURE
-M:     Joachim Eastwood <manabian@gmail.com>
+M:     Vladimir Zapolskiy <vz@mleia.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/boot/dts/lpc43*
-F:     drivers/clk/nxp/clk-lpc18xx*
-F:     drivers/clocksource/timer-lpc32xx.c
 F:     drivers/i2c/busses/i2c-lpc2k.c
 F:     drivers/memory/pl172.c
 F:     drivers/mtd/spi-nor/nxp-spifi.c
@@ -1703,9 +1763,10 @@ S:       Odd Fixes
 ARM/Microchip (AT91) SoC support
 M:     Nicolas Ferre <nicolas.ferre@microchip.com>
 M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.linux4sam.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git
 S:     Supported
 N:     at91
 N:     atmel
@@ -2085,22 +2146,24 @@ F:      include/linux/remoteproc/st_slim_rproc.h
 ARM/STM32 ARCHITECTURE
 M:     Maxime Coquelin <mcoquelin.stm32@gmail.com>
 M:     Alexandre Torgue <alexandre.torgue@st.com>
+L:     linux-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers)
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git stm32-next
 N:     stm32
+N:     stm
 F:     arch/arm/boot/dts/stm32*
 F:     arch/arm/mach-stm32/
 F:     drivers/clocksource/armv7m_systick.c
 
-ARM/Synaptics Berlin SoC support
+ARM/Synaptics SoC support
 M:     Jisheng Zhang <Jisheng.Zhang@synaptics.com>
 M:     Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-berlin/
 F:     arch/arm/boot/dts/berlin*
-F:     arch/arm64/boot/dts/marvell/berlin*
+F:     arch/arm64/boot/dts/synaptics/
 
 ARM/TANGO ARCHITECTURE
 M:     Marc Gonzalez <marc.w.gonzalez@free.fr>
@@ -2264,7 +2327,6 @@ F:        arch/arm/mach-pxa/include/mach/z2.h
 
 ARM/ZTE ARCHITECTURE
 M:     Jun Nie <jun.nie@linaro.org>
-M:     Baoyou Xie <baoyou.xie@linaro.org>
 M:     Shawn Guo <shawnguo@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -2472,42 +2534,6 @@ F:       drivers/atm/
 F:     include/linux/atm*
 F:     include/uapi/linux/atm*
 
-ATMEL AT91 / AT32 MCI DRIVER
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-S:     Maintained
-F:     drivers/mmc/host/atmel-mci.c
-
-ATMEL AT91 SAMA5D2-Compatible Shutdown Controller
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-S:     Supported
-F:     drivers/power/reset/at91-sama5d2_shdwc.c
-
-ATMEL Audio ALSA driver
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
-S:     Supported
-F:     sound/soc/atmel
-
-ATMEL I2C DRIVER
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-L:     linux-i2c@vger.kernel.org
-S:     Supported
-F:     drivers/i2c/busses/i2c-at91.c
-
-ATMEL ISI DRIVER
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-L:     linux-media@vger.kernel.org
-S:     Supported
-F:     drivers/media/platform/atmel/atmel-isi.c
-F:     include/media/atmel-isi.h
-
-ATMEL LCDFB DRIVER
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-L:     linux-fbdev@vger.kernel.org
-S:     Maintained
-F:     drivers/video/fbdev/atmel_lcdfb.c
-F:     include/video/atmel_lcdc.h
-
 ATMEL MACB ETHERNET DRIVER
 M:     Nicolas Ferre <nicolas.ferre@microchip.com>
 S:     Supported
@@ -2520,43 +2546,6 @@ S:       Maintained
 F:     Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F:     drivers/input/touchscreen/atmel_mxt_ts.c
 
-ATMEL SAMA5D2 ADC DRIVER
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-L:     linux-iio@vger.kernel.org
-S:     Supported
-F:     drivers/iio/adc/at91-sama5d2_adc.c
-
-ATMEL SDMMC DRIVER
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-L:     linux-mmc@vger.kernel.org
-S:     Supported
-F:     drivers/mmc/host/sdhci-of-at91.c
-
-ATMEL SPI DRIVER
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-S:     Supported
-F:     drivers/spi/spi-atmel.*
-
-ATMEL SSC DRIVER
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
-F:     drivers/misc/atmel-ssc.c
-F:     include/linux/atmel-ssc.h
-
-ATMEL 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
-
-ATMEL USBA UDC DRIVER
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
-F:     drivers/usb/gadget/udc/atmel_usba_udc.*
-
 ATMEL WIRELESS DRIVER
 M:     Simon Kelley <simon@thekelleys.org.uk>
 L:     linux-wireless@vger.kernel.org
@@ -2565,13 +2554,6 @@ W:       http://atmelwlandriver.sourceforge.net/
 S:     Maintained
 F:     drivers/net/wireless/atmel/atmel*
 
-ATMEL XDMA DRIVER
-M:     Ludovic Desroches <ludovic.desroches@microchip.com>
-L:     linux-arm-kernel@lists.infradead.org
-L:     dmaengine@vger.kernel.org
-S:     Supported
-F:     drivers/dma/at_xdmac.c
-
 ATOMIC INFRASTRUCTURE
 M:     Will Deacon <will.deacon@arm.com>
 M:     Peter Zijlstra <peterz@infradead.org>
@@ -3185,7 +3167,7 @@ F:        drivers/gpio/gpio-bt8xx.c
 
 BTRFS FILE SYSTEM
 M:     Chris Mason <clm@fb.com>
-M:     Josef Bacik <jbacik@fb.com>
+M:     Josef Bacik <josef@toxicpanda.com>
 M:     David Sterba <dsterba@suse.com>
 L:     linux-btrfs@vger.kernel.org
 W:     http://btrfs.wiki.kernel.org/
@@ -3848,7 +3830,6 @@ W:        http://www.arm.com/products/processors/technologies/biglittleprocessing.php
 S:     Maintained
 F:     drivers/cpufreq/arm_big_little.h
 F:     drivers/cpufreq/arm_big_little.c
-F:     drivers/cpufreq/arm_big_little_dt.c
 
 CPU POWER MONITORING SUBSYSTEM
 M:     Thomas Renninger <trenn@suse.com>
@@ -4226,6 +4207,12 @@ M:       Pali Rohár <pali.rohar@gmail.com>
 S:     Maintained
 F:     drivers/platform/x86/dell-rbtn.*
 
+DELL REMOTE BIOS UPDATE DRIVER
+M:     Stuart Hayes <stuart.w.hayes@gmail.com>
+L:     platform-driver-x86@vger.kernel.org
+S:     Maintained
+F:     drivers/platform/x86/dell_rbu.c
+
 DELL LAPTOP SMM DRIVER
 M:     Pali Rohár <pali.rohar@gmail.com>
 S:     Maintained
@@ -4233,10 +4220,11 @@ F:      drivers/hwmon/dell-smm-hwmon.c
 F:     include/uapi/linux/i8k.h
 
 DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
-M:     Doug Warzecha <Douglas_Warzecha@dell.com>
+M:     Stuart Hayes <stuart.w.hayes@gmail.com>
+L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     Documentation/dcdbas.txt
-F:     drivers/firmware/dcdbas.*
+F:     drivers/platform/x86/dcdbas.*
 
 DELL WMI NOTIFICATIONS DRIVER
 M:     Matthew Garrett <mjg59@srcf.ucam.org>
@@ -4388,13 +4376,6 @@ L:       linux-gpio@vger.kernel.org
 S:     Maintained
 F:     drivers/gpio/gpio-gpio-mm.c
 
-DIGI NEO AND CLASSIC PCI PRODUCTS
-M:     Lidza Louina <lidza.louina@gmail.com>
-M:     Mark Hounschell <markh@compro.net>
-L:     driverdev-devel@linuxdriverproject.org
-S:     Maintained
-F:     drivers/staging/dgnc/
-
 DIOLAN U2C-12 I2C DRIVER
 M:     Guenter Roeck <linux@roeck-us.net>
 L:     linux-i2c@vger.kernel.org
@@ -4544,13 +4525,15 @@ L:      linux-media@vger.kernel.org
 T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/i2c/dw9714.c
+F:     Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt
 
 DONGWOON DW9807 LENS VOICE COIL DRIVER
 M:     Sakari Ailus <sakari.ailus@linux.intel.com>
 L:     linux-media@vger.kernel.org
 T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
-F:     drivers/media/i2c/dw9807.c
+F:     drivers/media/i2c/dw9807-vcm.c
+F:     Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt
 
 DOUBLETALK DRIVER
 M:     "James R. Van Zandt" <jrv@vanzandt.mv.com>
@@ -5397,6 +5380,14 @@ L:       linux-edac@vger.kernel.org
 S:     Maintained
 F:     drivers/edac/ti_edac.c
 
+EDAC-QCOM
+M:     Channagoud Kadabi <ckadabi@codeaurora.org>
+M:     Venkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>
+L:     linux-arm-msm@vger.kernel.org
+L:     linux-edac@vger.kernel.org
+S:     Maintained
+F:     drivers/edac/qcom_edac.c
+
 EDIROL UA-101/UA-1000 DRIVER
 M:     Clemens Ladisch <clemens@ladisch.de>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -5675,10 +5666,9 @@ F:       Documentation/fault-injection/
 F:     lib/fault-inject.c
 
 FBTFT Framebuffer drivers
-M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+S:     Orphan
 L:     dri-devel@lists.freedesktop.org
 L:     linux-fbdev@vger.kernel.org
-S:     Maintained
 F:     drivers/staging/fbtft/
 
 FC0011 TUNER DRIVER
@@ -7364,6 +7354,12 @@ L:       alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
 F:     sound/soc/intel/
 
+INTEL ATOMISP2 DUMMY / POWER-MANAGEMENT DRIVER
+M:     Hans de Goede <hdegoede@redhat.com>
+L:     platform-driver-x86@vger.kernel.org
+S:     Maintained
+F:     drivers/platform/x86/intel_atomisp2_pm.c
+
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:     Intel SCU Linux support <intel-linux-scu@intel.com>
 M:     Artur Paszkiewicz <artur.paszkiewicz@intel.com>
@@ -7550,7 +7546,6 @@ M:        Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
 M:     Vishwanath Somayaji <vishwanath.somayaji@intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
-F:     arch/x86/include/asm/pmc_core.h
 F:     drivers/platform/x86/intel_pmc_core*
 
 INTEL PMC/P-Unit IPC DRIVER
@@ -7594,7 +7589,8 @@ F:        drivers/infiniband/hw/i40iw/
 F:     include/uapi/rdma/i40iw-abi.h
 
 INTEL TELEMETRY DRIVER
-M:     Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
+M:     Rajneesh Bhardwaj <rajneesh.bhardwaj@linux.intel.com>
+M:     "David E. Box" <david.e.box@linux.intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     arch/x86/include/asm/intel_telemetry.h
@@ -7737,7 +7733,6 @@ IPX NETWORK LAYER
 L:     netdev@vger.kernel.org
 S:     Obsolete
 F:     include/uapi/linux/ipx.h
-F:     drivers/staging/ipx/
 
 IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
 M:     Marc Zyngier <marc.zyngier@arm.com>
@@ -8328,6 +8323,14 @@ W:       http://legousb.sourceforge.net/
 S:     Maintained
 F:     drivers/usb/misc/legousbtower.c
 
+LG LAPTOP EXTRAS
+M:     Matan Ziv-Av <matan@svgalib.org>
+L:     platform-driver-x86@vger.kernel.org
+S:     Maintained
+F:     Documentation/ABI/testing/sysfs-platform-lg-laptop
+F:     Documentation/laptops/lg-laptop.rst
+F:     drivers/platform/x86/lg-laptop.c
+
 LG2160 MEDIA DRIVER
 M:     Michael Krufky <mkrufky@linuxtv.org>
 L:     linux-media@vger.kernel.org
@@ -8716,6 +8719,13 @@ L:       linux-scsi@vger.kernel.org
 S:     Maintained
 F:     drivers/scsi/sym53c8xx_2/
 
+LTC1660 DAC DRIVER
+M:     Marcus Folkesson <marcus.folkesson@gmail.com>
+L:     linux-iio@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/iio/dac/ltc1660.txt
+F:     drivers/iio/dac/ltc1660.c
+
 LTC4261 HARDWARE MONITOR DRIVER
 M:     Guenter Roeck <linux@roeck-us.net>
 L:     linux-hwmon@vger.kernel.org
@@ -8880,7 +8890,7 @@ S:        Maintained
 F:     drivers/net/phy/marvell10g.c
 
 MARVELL MVNETA ETHERNET DRIVER
-M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M:     Thomas Petazzoni <thomas.petazzoni@bootlin.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/marvell/mvneta.*
@@ -9079,11 +9089,10 @@ F:      drivers/media/dvb-frontends/cxd2880/*
 F:     drivers/media/spi/cxd2880*
 
 MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES
-M:     Daniel Scheller <d.scheller.oss@gmail.com>
 L:     linux-media@vger.kernel.org
 W:     https://linuxtv.org
 T:     git git://linuxtv.org/media_tree.git
-S:     Maintained
+S:     Orphan
 F:     drivers/media/pci/ddbridge/*
 
 MEDIA DRIVERS FOR FREESCALE IMX
@@ -9098,6 +9107,13 @@ F:       drivers/staging/media/imx/
 F:     include/linux/imx-media.h
 F:     include/media/imx.h
 
+MEDIA DRIVER FOR FREESCALE IMX PXP
+M:     Philipp Zabel <p.zabel@pengutronix.de>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/platform/imx-pxp.[ch]
+
 MEDIA DRIVERS FOR HELENE
 M:     Abylay Ospan <aospan@netup.ru>
 L:     linux-media@vger.kernel.org
@@ -9128,11 +9144,10 @@ S:      Supported
 F:     drivers/media/dvb-frontends/lnbh25*
 
 MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS
-M:     Daniel Scheller <d.scheller.oss@gmail.com>
 L:     linux-media@vger.kernel.org
 W:     https://linuxtv.org
 T:     git git://linuxtv.org/media_tree.git
-S:     Maintained
+S:     Orphan
 F:     drivers/media/dvb-frontends/mxl5xx*
 
 MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
@@ -9175,7 +9190,7 @@ F:        drivers/media/platform/rcar-fcp.c
 F:     include/media/rcar-fcp.h
 
 MEDIA DRIVERS FOR RENESAS - FDP1
-M:     Kieran Bingham <kieran@bingham.xyz>
+M:     Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
 L:     linux-media@vger.kernel.org
 L:     linux-renesas-soc@vger.kernel.org
 T:     git git://linuxtv.org/media_tree.git
@@ -9195,6 +9210,7 @@ F:        drivers/media/platform/rcar-vin/
 
 MEDIA DRIVERS FOR RENESAS - VSP1
 M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+M:     Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
 L:     linux-media@vger.kernel.org
 L:     linux-renesas-soc@vger.kernel.org
 T:     git git://linuxtv.org/media_tree.git
@@ -9203,19 +9219,17 @@ F:      Documentation/devicetree/bindings/media/renesas,vsp1.txt
 F:     drivers/media/platform/vsp1/
 
 MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs
-M:     Daniel Scheller <d.scheller.oss@gmail.com>
 L:     linux-media@vger.kernel.org
 W:     https://linuxtv.org
 T:     git git://linuxtv.org/media_tree.git
-S:     Maintained
+S:     Orphan
 F:     drivers/media/dvb-frontends/stv0910*
 
 MEDIA DRIVERS FOR ST STV6111 TUNER ICs
-M:     Daniel Scheller <d.scheller.oss@gmail.com>
 L:     linux-media@vger.kernel.org
 W:     https://linuxtv.org
 T:     git git://linuxtv.org/media_tree.git
-S:     Maintained
+S:     Orphan
 F:     drivers/media/dvb-frontends/stv6111*
 
 MEDIA DRIVERS FOR STM32 - DCMI
@@ -9601,14 +9615,20 @@ T:      git git://git.monstr.eu/linux-2.6-microblaze.git
 S:     Supported
 F:     arch/microblaze/
 
-MICROCHIP / ATMEL AT91 SERIAL DRIVER
+MICROCHIP AT91 SERIAL DRIVER
 M:     Richard Genoud <richard.genoud@gmail.com>
 S:     Maintained
 F:     drivers/tty/serial/atmel_serial.c
 F:     drivers/tty/serial/atmel_serial.h
 F:     Documentation/devicetree/bindings/mfd/atmel-usart.txt
 
-MICROCHIP / ATMEL DMA DRIVER
+MICROCHIP AUDIO ASOC DRIVERS
+M:     Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Supported
+F:     sound/soc/atmel
+
+MICROCHIP DMA DRIVER
 M:     Ludovic Desroches <ludovic.desroches@microchip.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     dmaengine@vger.kernel.org
@@ -9616,27 +9636,35 @@ S:      Supported
 F:     drivers/dma/at_hdmac.c
 F:     drivers/dma/at_hdmac_regs.h
 F:     include/linux/platform_data/dma-atmel.h
+F:     Documentation/devicetree/bindings/dma/atmel-dma.txt
+F:     include/dt-bindings/dma/at91.h
 
-MICROCHIP / ATMEL ECC DRIVER
+MICROCHIP ECC DRIVER
 M:     Tudor Ambarus <tudor.ambarus@microchip.com>
 L:     linux-crypto@vger.kernel.org
 S:     Maintained
 F:     drivers/crypto/atmel-ecc.*
 
-MICROCHIP / ATMEL ISC DRIVER
-M:     Songjun Wu <songjun.wu@microchip.com>
+MICROCHIP I2C DRIVER
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+L:     linux-i2c@vger.kernel.org
+S:     Supported
+F:     drivers/i2c/busses/i2c-at91.c
+
+MICROCHIP ISC DRIVER
+M:     Eugen Hristev <eugen.hristev@microchip.com>
 L:     linux-media@vger.kernel.org
 S:     Supported
 F:     drivers/media/platform/atmel/atmel-isc.c
 F:     drivers/media/platform/atmel/atmel-isc-regs.h
 F:     devicetree/bindings/media/atmel-isc.txt
 
-MICROCHIP / ATMEL NAND DRIVER
-M:     Josh Wu <rainyfeeling@outlook.com>
-L:     linux-mtd@lists.infradead.org
+MICROCHIP ISI DRIVER
+M:     Eugen Hristev <eugen.hristev@microchip.com>
+L:     linux-media@vger.kernel.org
 S:     Supported
-F:     drivers/mtd/nand/raw/atmel/*
-F:     Documentation/devicetree/bindings/mtd/atmel-nand.txt
+F:     drivers/media/platform/atmel/atmel-isi.c
+F:     include/media/atmel-isi.h
 
 MICROCHIP AT91 USART MFD DRIVER
 M:     Radu Pirea <radu_nicolae.pirea@upb.ro>
@@ -9670,6 +9698,80 @@ L:       netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/microchip/lan743x_*
 
+MICROCHIP LCDFB DRIVER
+M:     Nicolas Ferre <nicolas.ferre@microchip.com>
+L:     linux-fbdev@vger.kernel.org
+S:     Maintained
+F:     drivers/video/fbdev/atmel_lcdfb.c
+F:     include/video/atmel_lcdc.h
+
+MICROCHIP MMC/SD/SDIO MCI DRIVER
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+S:     Maintained
+F:     drivers/mmc/host/atmel-mci.c
+
+MICROCHIP MCP3911 ADC DRIVER
+M:     Marcus Folkesson <marcus.folkesson@gmail.com>
+M:     Kent Gustavsson <kent@minoris.se>
+L:     linux-iio@vger.kernel.org
+S:     Supported
+F:     drivers/iio/adc/mcp3911.c
+F:     Documentation/devicetree/bindings/iio/adc/mcp3911.txt
+
+MICROCHIP NAND DRIVER
+M:     Tudor Ambarus <tudor.ambarus@microchip.com>
+L:     linux-mtd@lists.infradead.org
+S:     Supported
+F:     drivers/mtd/nand/raw/atmel/*
+F:     Documentation/devicetree/bindings/mtd/atmel-nand.txt
+
+MICROCHIP PWM DRIVER
+M:     Claudiu Beznea <claudiu.beznea@microchip.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-pwm@vger.kernel.org
+S:     Supported
+F:     drivers/pwm/pwm-atmel.c
+F:     Documentation/devicetree/bindings/pwm/atmel-pwm.txt
+
+MICROCHIP SAMA5D2-COMPATIBLE ADC DRIVER
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+M:     Eugen Hristev <eugen.hristev@microchip.com>
+L:     linux-iio@vger.kernel.org
+S:     Supported
+F:     drivers/iio/adc/at91-sama5d2_adc.c
+F:     Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
+F:     include/dt-bindings/iio/adc/at91-sama5d2_adc.h
+
+MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER
+M:     Nicolas Ferre <nicolas.ferre@microchip.com>
+S:     Supported
+F:     drivers/power/reset/at91-sama5d2_shdwc.c
+
+MICROCHIP SPI DRIVER
+M:     Nicolas Ferre <nicolas.ferre@microchip.com>
+S:     Supported
+F:     drivers/spi/spi-atmel.*
+
+MICROCHIP SSC DRIVER
+M:     Nicolas Ferre <nicolas.ferre@microchip.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+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)
+S:     Supported
+F:     drivers/usb/gadget/udc/atmel_usba_udc.*
+
 MICROCHIP USB251XB DRIVER
 M:     Richard Leitner <richard.leitner@skidata.com>
 L:     linux-usb@vger.kernel.org
@@ -9677,6 +9779,13 @@ S:       Maintained
 F:     drivers/usb/misc/usb251xb.c
 F:     Documentation/devicetree/bindings/usb/usb251xb.txt
 
+MICROCHIP XDMA DRIVER
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+L:     linux-arm-kernel@lists.infradead.org
+L:     dmaengine@vger.kernel.org
+S:     Supported
+F:     drivers/dma/at_xdmac.c
+
 MICROSEMI MIPS SOCS
 M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
 L:     linux-mips@linux-mips.org
@@ -10060,11 +10169,6 @@ NATSEMI ETHERNET DRIVER (DP8381x)
 S:     Orphan
 F:     drivers/net/ethernet/natsemi/natsemi.c
 
-NCP FILESYSTEM
-M:     Petr Vandrovec <petr@vandrovec.name>
-S:     Obsolete
-F:     drivers/staging/ncpfs/
-
 NCR 5380 SCSI DRIVERS
 M:     Finn Thain <fthain@telegraphics.com.au>
 M:     Michael Schmitz <schmitzmic@gmail.com>
@@ -11165,7 +11269,7 @@ S:      Maintained
 F:     drivers/firmware/pcdp.*
 
 PCI DRIVER FOR AARDVARK (Marvell Armada 3700)
-M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M:     Thomas Petazzoni <thomas.petazzoni@bootlin.com>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -11197,7 +11301,7 @@ F:      Documentation/devicetree/bindings/pci/versatile.txt
 F:     drivers/pci/controller/pci-versatile.c
 
 PCI DRIVER FOR ARMADA 8K
-M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M:     Thomas Petazzoni <thomas.petazzoni@bootlin.com>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org
 S:     Maintained
@@ -11266,7 +11370,7 @@ F:      Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
 F:     drivers/pci/controller/pcie-mobiveil.c
 
 PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
-M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M:     Thomas Petazzoni <thomas.petazzoni@bootlin.com>
 M:     Jason Cooper <jason@lakedaemon.net>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -12532,6 +12636,12 @@ S:     Supported
 F:     drivers/i2c/busses/i2c-rcar.c
 F:     drivers/i2c/busses/i2c-sh_mobile.c
 
+RENESAS RIIC DRIVER
+M:     Chris Brandt <chris.brandt@renesas.com>
+S:     Supported
+F:     Documentation/devicetree/bindings/i2c/i2c-riic.txt
+F:     drivers/i2c/busses/i2c-riic.c
+
 RENESAS USB PHY DRIVER
 M:     Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
 L:     linux-renesas-soc@vger.kernel.org
@@ -13171,6 +13281,12 @@ L:     linux-mmc@vger.kernel.org
 S:     Maintained
 F:     drivers/mmc/host/sdhci-pci-dwc-mshc.c
 
+SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) MICROCHIP DRIVER
+M:     Ludovic Desroches <ludovic.desroches@microchip.com>
+L:     linux-mmc@vger.kernel.org
+S:     Supported
+F:     drivers/mmc/host/sdhci-of-at91.c
+
 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
 M:     Ben Dooks <ben-linux@fluff.org>
 M:     Jaehoon Chung <jh80.chung@samsung.com>
@@ -13709,6 +13825,20 @@ S:     Maintained
 F:     drivers/media/i2c/imx274.c
 F:     Documentation/devicetree/bindings/media/i2c/imx274.txt
 
+SONY IMX319 SENSOR DRIVER
+M:     Bingbu Cao <bingbu.cao@intel.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/i2c/imx319.c
+
+SONY IMX355 SENSOR DRIVER
+M:     Tianshu Qiu <tian.shu.qiu@intel.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/i2c/imx355.c
+
 SONY MEMORYSTICK CARD SUPPORT
 M:     Alex Dubov <oakad@yahoo.com>
 W:     http://tifmxx.berlios.de/
@@ -13911,6 +14041,13 @@ L:     linux-i2c@vger.kernel.org
 S:     Maintained
 F:     drivers/i2c/busses/i2c-stm32*
 
+ST VL53L0X ToF RANGER(I2C) IIO DRIVER
+M:     Song Qiang <songqiang1304521@gmail.com>
+L:     linux-iio@vger.kernel.org
+S:     Maintained
+F:     drivers/iio/proximity/vl53l0x-i2c.c
+F:     Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt
+
 STABLE BRANCH
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     stable@vger.kernel.org
@@ -13930,11 +14067,6 @@ L:     linux-erofs@lists.ozlabs.org
 S:     Maintained
 F:     drivers/staging/erofs/
 
-STAGING - FLARION FT1000 DRIVERS
-M:     Marek Belisko <marek.belisko@gmail.com>
-S:     Odd Fixes
-F:     drivers/staging/ft1000/
-
 STAGING - INDUSTRIAL IO
 M:     Jonathan Cameron <jic23@kernel.org>
 L:     linux-iio@vger.kernel.org
@@ -14026,7 +14158,7 @@ F:      sound/soc/sti/
 STI CEC DRIVER
 M:     Benjamin Gaignard <benjamin.gaignard@linaro.org>
 S:     Maintained
-F:     drivers/staging/media/st-cec/
+F:     drivers/media/platform/sti/cec/
 F:     Documentation/devicetree/bindings/media/stih-cec.txt
 
 STK1160 USB VIDEO CAPTURE DRIVER
@@ -14578,7 +14710,6 @@ F:      Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 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:     include/dt-bindings/genpd/k2g.h
 F:     drivers/soc/ti/ti_sci_pm_domains.c
 F:     Documentation/devicetree/bindings/reset/ti,sci-reset.txt
 F:     Documentation/devicetree/bindings/clock/ti,sci-clk.txt
@@ -15685,7 +15816,7 @@ M:      Marek Szyprowski <m.szyprowski@samsung.com>
 M:     Kyungmin Park <kyungmin.park@samsung.com>
 L:     linux-media@vger.kernel.org
 S:     Maintained
-F:     drivers/media/v4l2-core/videobuf2-*
+F:     drivers/media/common/videobuf2/*
 F:     include/media/videobuf2-*
 
 VIMC VIRTUAL MEDIA CONTROLLER DRIVER
@@ -16214,6 +16345,7 @@ F:      arch/arm64/include/asm/xen/
 XEN HYPERVISOR INTERFACE
 M:     Boris Ostrovsky <boris.ostrovsky@oracle.com>
 M:     Juergen Gross <jgross@suse.com>
+R:     Stefano Stabellini <sstabellini@kernel.org>
 L:     xen-devel@lists.xenproject.org (moderated for non-subscribers)
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git
 S:     Supported
index 9d329608913e2d14392fb44328225a01075a92ba..ed27fd26262764fc44092d639030aa7b19f53ea8 100644 (file)
@@ -290,6 +290,13 @@ config HAVE_RSEQ
          This symbol should be selected by an architecture if it
          supports an implementation of restartable sequences.
 
+config HAVE_FUNCTION_ARG_ACCESS_API
+       bool
+       help
+         This symbol should be selected by an architecure if it supports
+         the API needed to access function arguments from pt_regs,
+         declared in asm/ptrace.h
+
 config HAVE_CLK
        bool
        help
index 620b0a711ee41bab77a949b7ce6b4845fb169172..5b4f8836345381017ff54770f44180115a81c7e4 100644 (file)
@@ -31,8 +31,6 @@ config ALPHA
        select ODD_RT_SIGACTION
        select OLD_SIGSUSPEND
        select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67
-       select HAVE_MEMBLOCK
-       select NO_BOOTMEM
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index cb05d045efe3b84098d1882a937a861209d97eb5..6100431da07a3bfaf4c822d7af7ad02cb2994854 100644 (file)
 
 #include <linux/personality.h> /* for ADDR_LIMIT_32BIT */
 
-/*
- * Returns current instruction pointer ("program counter").
- */
-#define current_text_addr() \
-  ({ void *__pc; __asm__ ("br %0,.+4" : "=r"(__pc)); __pc; })
-
 /*
  * We have a 42-bit user address space: 4TB user VM...
  */
index 3729d92d3fa854599a99ba57c56aa33b40b4e0c8..1e9121c9b3c74c16d129ce6fac97f614080dca94 100644 (file)
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
index 1bf3eef34c22f6c1203ff7bcde4ec8f0f2f3822f..6df765ff2b1090cb5a7300e7880098f2abb316e7 100644 (file)
@@ -346,7 +346,8 @@ apecs_init_arch(void)
         * Window 1 is direct access 1GB at 1GB
         * Window 2 is scatter-gather 8MB at 8MB (for isa)
         */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
+                                      SMP_CACHE_BYTES);
        hose->sg_pci = NULL;
        __direct_map_base = 0x40000000;
        __direct_map_size = 0x40000000;
index 4b38386f6e62c7d2dc495c372b711d49a473fd0e..867e8730b0c5c4819a19983efa19522a0984f760 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/ptrace.h>
 #include <asm/mce.h>
@@ -331,7 +331,7 @@ cia_prepare_tbia_workaround(int window)
        long i;
 
        /* Use minimal 1K map. */
-       ppte = __alloc_bootmem(CIA_BROKEN_TBIA_SIZE, 32768, 0);
+       ppte = memblock_alloc_from(CIA_BROKEN_TBIA_SIZE, 32768, 0);
        pte = (virt_to_phys(ppte) >> (PAGE_SHIFT - 1)) | 1;
 
        for (i = 0; i < CIA_BROKEN_TBIA_SIZE / sizeof(unsigned long); ++i)
index f70986683fc6150eeebefde4d1d0742d35d7adb6..a9fd133a7fb2aad635d4d2782be5569e10251e2d 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/initrd.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 
 #include <asm/ptrace.h>
@@ -234,8 +233,7 @@ albacore_init_arch(void)
                        unsigned long size;
 
                        size = initrd_end - initrd_start;
-                       free_bootmem_node(NODE_DATA(0), __pa(initrd_start),
-                                         PAGE_ALIGN(size));
+                       memblock_free(__pa(initrd_start), PAGE_ALIGN(size));
                        if (!move_initrd(pci_mem))
                                printk("irongate_init_arch: initrd too big "
                                       "(%ldK)\ndisabling initrd\n",
index 81c0c43635b0710753ec6aaf9470abb651fece79..57e0750419f2900c0c59aae7194dff847cbea3a3 100644 (file)
@@ -275,7 +275,8 @@ lca_init_arch(void)
         * Note that we do not try to save any of the DMA window CSRs
         * before setting them, since we cannot read those CSRs on LCA.
         */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
+                                      SMP_CACHE_BYTES);
        hose->sg_pci = NULL;
        __direct_map_base = 0x40000000;
        __direct_map_size = 0x40000000;
index bdebb8c206f10d99f4ca0d6dd5d6e678c7008398..c1d0c18c71ca4c7d8523094d4ba4568418754336 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/rtc.h>
 #include <linux/module.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/ptrace.h>
 #include <asm/smp.h>
@@ -82,7 +82,7 @@ mk_resource_name(int pe, int port, char *str)
        char *name;
        
        sprintf(tmp, "PCI %s PE %d PORT %d", str, pe, port);
-       name = alloc_bootmem(strlen(tmp) + 1);
+       name = memblock_alloc(strlen(tmp) + 1, SMP_CACHE_BYTES);
        strcpy(name, tmp);
 
        return name;
@@ -117,7 +117,7 @@ alloc_io7(unsigned int pe)
                return NULL;
        }
 
-       io7 = alloc_bootmem(sizeof(*io7));
+       io7 = memblock_alloc(sizeof(*io7), SMP_CACHE_BYTES);
        io7->pe = pe;
        raw_spin_lock_init(&io7->irq_lock);
 
index b1549db54260fe99f6f6a3f36f35dfee22f3d87b..74b1d018124c3a75c7318929a0a6d102f11acff3 100644 (file)
@@ -364,9 +364,11 @@ mcpcia_startup_hose(struct pci_controller *hose)
         * Window 1 is scatter-gather (up to) 1GB at 1GB (for pci)
         * Window 2 is direct access 2GB at 2GB
         */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
+                                      SMP_CACHE_BYTES);
        hose->sg_pci = iommu_arena_new(hose, 0x40000000,
-                                      size_for_memory(0x40000000), 0);
+                                      size_for_memory(0x40000000),
+                                      SMP_CACHE_BYTES);
 
        __direct_map_base = 0x80000000;
        __direct_map_size = 0x80000000;
index 2c00b61ca379e309b41cebad1cbe264b4b4640c5..98d5b6ff8a769632a12304bb165b1e9d06c96d45 100644 (file)
@@ -351,7 +351,7 @@ t2_sg_map_window2(struct pci_controller *hose,
 
        /* Note we can only do 1 SG window, as the other is for direct, so
           do an ISA SG area, especially for the floppy. */
-       hose->sg_isa = iommu_arena_new(hose, base, length, 0);
+       hose->sg_isa = iommu_arena_new(hose, base, length, SMP_CACHE_BYTES);
        hose->sg_pci = NULL;
 
        temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20);
index 132b06bdf9031f7105b81738325110f33a37bb6f..2a2820fb1be63daa7ddf77aa66143dda4151e7fb 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/ptrace.h>
 #include <asm/smp.h>
@@ -316,10 +316,12 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index)
         * Window 1 is direct access 1GB at 2GB
         * Window 2 is scatter-gather 1GB at 3GB
         */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
+                                      SMP_CACHE_BYTES);
        hose->sg_isa->align_entry = 8; /* 64KB for ISA */
 
-       hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x40000000, 0);
+       hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x40000000,
+                                      SMP_CACHE_BYTES);
        hose->sg_pci->align_entry = 4; /* Titan caches 4 PTEs at a time */
 
        port->wsba[0].csr = hose->sg_isa->dma_base | 3;
index e7c956ea46b64497e3a7cb70928a37e758225375..fc1ab73f23ded12f73fea93c16dff3f99780abc7 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/ptrace.h>
 #include <asm/smp.h>
@@ -319,12 +319,14 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
         * NOTE: we need the align_entry settings for Acer devices on ES40,
         * specifically floppy and IDE when memory is larger than 2GB.
         */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
+       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
+                                      SMP_CACHE_BYTES);
        /* Initially set for 4 PTEs, but will be overridden to 64K for ISA. */
         hose->sg_isa->align_entry = 4;
 
        hose->sg_pci = iommu_arena_new(hose, 0x40000000,
-                                      size_for_memory(0x40000000), 0);
+                                      size_for_memory(0x40000000),
+                                      SMP_CACHE_BYTES);
         hose->sg_pci->align_entry = 4; /* Tsunami caches 4 PTEs at a time */
 
        __direct_map_base = 0x80000000;
index cad36fc6ed7de05b4db8046ac9d9b0b5733ad955..353c03d1544202348bf5513c4b28977f6021142a 100644 (file)
@@ -111,8 +111,10 @@ wildfire_init_hose(int qbbno, int hoseno)
          * ??? We ought to scale window 3 memory.
          *
          */
-        hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
-        hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0);
+       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
+                                      SMP_CACHE_BYTES);
+       hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000,
+                                      SMP_CACHE_BYTES);
 
        pci = WILDFIRE_pci(qbbno, hoseno);
 
index c7c5879869d35092d45fcb9c35a1245f916fbdf4..091cff3c68fd47cfa860761eade0587b8df43408 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/gfp.h>
 #include <linux/capability.h>
 #include <linux/mm.h>
@@ -33,7 +33,7 @@ alloc_pci_controller(void)
 {
        struct pci_controller *hose;
 
-       hose = alloc_bootmem(sizeof(*hose));
+       hose = memblock_alloc(sizeof(*hose), SMP_CACHE_BYTES);
 
        *hose_tail = hose;
        hose_tail = &hose->next;
@@ -44,7 +44,7 @@ alloc_pci_controller(void)
 struct resource * __init
 alloc_resource(void)
 {
-       return alloc_bootmem(sizeof(struct resource));
+       return memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
 }
 
 SYSCALL_DEFINE3(pciconfig_iobase, long, which, unsigned long, bus,
index c668c3b7a1673276d2d3371a5ecb94bb2640decb..97098127df8389e70a3e74e243728d090744b87e 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/module.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
@@ -392,7 +392,7 @@ alloc_pci_controller(void)
 {
        struct pci_controller *hose;
 
-       hose = alloc_bootmem(sizeof(*hose));
+       hose = memblock_alloc(sizeof(*hose), SMP_CACHE_BYTES);
 
        *hose_tail = hose;
        hose_tail = &hose->next;
@@ -403,7 +403,7 @@ alloc_pci_controller(void)
 struct resource * __init
 alloc_resource(void)
 {
-       return alloc_bootmem(sizeof(struct resource));
+       return memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
 }
 
 
index 6923b0d9c1e195d1751d19e4335271b40d3c0226..46e08e0d91818b97d7193e4b045e4aa86904f013 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/gfp.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
@@ -74,26 +74,26 @@ iommu_arena_new_node(int nid, struct pci_controller *hose, dma_addr_t base,
 
 #ifdef CONFIG_DISCONTIGMEM
 
-       arena = alloc_bootmem_node(NODE_DATA(nid), sizeof(*arena));
+       arena = memblock_alloc_node(sizeof(*arena), align, nid);
        if (!NODE_DATA(nid) || !arena) {
                printk("%s: couldn't allocate arena from node %d\n"
                       "    falling back to system-wide allocation\n",
                       __func__, nid);
-               arena = alloc_bootmem(sizeof(*arena));
+               arena = memblock_alloc(sizeof(*arena), SMP_CACHE_BYTES);
        }
 
-       arena->ptes = __alloc_bootmem_node(NODE_DATA(nid), mem_size, align, 0);
+       arena->ptes = memblock_alloc_node(sizeof(*arena), align, nid);
        if (!NODE_DATA(nid) || !arena->ptes) {
                printk("%s: couldn't allocate arena ptes from node %d\n"
                       "    falling back to system-wide allocation\n",
                       __func__, nid);
-               arena->ptes = __alloc_bootmem(mem_size, align, 0);
+               arena->ptes = memblock_alloc_from(mem_size, align, 0);
        }
 
 #else /* CONFIG_DISCONTIGMEM */
 
-       arena = alloc_bootmem(sizeof(*arena));
-       arena->ptes = __alloc_bootmem(mem_size, align, 0);
+       arena = memblock_alloc(sizeof(*arena), SMP_CACHE_BYTES);
+       arena->ptes = memblock_alloc_from(mem_size, align, 0);
 
 #endif /* CONFIG_DISCONTIGMEM */
 
index 4f0d94471bc9adab6904e126f9ff6142a4328947..a37fd990bd5548933d89ce3949341f9e8a17d008 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/pci.h>
 #include <linux/seq_file.h>
@@ -294,7 +293,7 @@ move_initrd(unsigned long mem_limit)
        unsigned long size;
 
        size = initrd_end - initrd_start;
-       start = __alloc_bootmem(PAGE_ALIGN(size), PAGE_SIZE, 0);
+       start = memblock_alloc_from(PAGE_ALIGN(size), PAGE_SIZE, 0);
        if (!start || __pa(start) + size > mem_limit) {
                initrd_start = initrd_end = 0;
                return NULL;
index ff4f54b86c7f5628e42b519c6115913fde5bf371..cd9a112d67ff10cb1e4e360ef8793dabadea3f8b 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/reboot.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/bitops.h>
 
 #include <asm/ptrace.h>
index 9d74520298abb3bc6d04302a8a0ce1fdaf171b23..a42fc5c4db893fdafa5825347600f1baff9890db 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/init.h>
-#include <linux/bootmem.h> /* max_low_pfn */
+#include <linux/memblock.h> /* max_low_pfn */
 #include <linux/vmalloc.h>
 #include <linux/gfp.h>
 
@@ -282,7 +282,7 @@ mem_init(void)
 {
        set_max_mapnr(max_low_pfn);
        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-       free_all_bootmem();
+       memblock_free_all();
        mem_init_print_info(NULL);
 }
 
index 26cd925d19b16bfbd7efbf7aad085119f27445ea..74846553e3f18682a958bf6373923830f2b8168a 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/swap.h>
 #include <linux/initrd.h>
index e98c6b8e6186ed0a2da278860f3ecaa904014759..c9e2a1323536313c8ee0e10906db67902c846674 100644 (file)
@@ -37,14 +37,12 @@ config ARC
        select HAVE_KERNEL_LZMA
        select HAVE_KPROBES
        select HAVE_KRETPROBES
-       select HAVE_MEMBLOCK
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_OPROFILE
        select HAVE_PERF_EVENTS
        select HANDLE_DOMAIN_IRQ
        select IRQ_DOMAIN
        select MODULES_USE_ELF_RELA
-       select NO_BOOTMEM
        select OF
        select OF_EARLY_FLATTREE
        select OF_RESERVED_MEM
index 8ee41e9881690b648bf1d4e5c385ddeef0a860c2..10346d6cf9265f47d311f68aec0f9e81efff787c 100644 (file)
@@ -98,14 +98,6 @@ extern void start_thread(struct pt_regs * regs, unsigned long pc,
 
 extern unsigned int get_wchan(struct task_struct *p);
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- * Should the PC register be read instead ? This macro does not seem to
- * be used in many places so this wont be all that bad.
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 #endif /* !__ASSEMBLY__ */
 
 /*
index 183391d4d33a4138d04418da4b90d61efe38c6c4..d34f69eb1a955f593925d3f6e187206cdaa3ff20 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <linux/sched.h>
 #include <linux/module.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/sort.h>
 #include <linux/slab.h>
 #include <linux/stop_machine.h>
@@ -181,8 +181,8 @@ static void init_unwind_hdr(struct unwind_table *table,
  */
 static void *__init unw_hdr_alloc_early(unsigned long sz)
 {
-       return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
-                                      MAX_DMA_ADDRESS);
+       return memblock_alloc_from_nopanic(sz, sizeof(unsigned int),
+                                          MAX_DMA_ADDRESS);
 }
 
 static void *unw_hdr_alloc(unsigned long sz)
index 77ff64a874a1b4649d79e579054febd4dfdbb605..48e70015181048640e083e4c1f8b1deb9a02b95d 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/highmem.h>
 #include <asm/processor.h>
@@ -123,7 +123,7 @@ static noinline pte_t * __init alloc_kmap_pgtable(unsigned long kvaddr)
        pud_k = pud_offset(pgd_k, kvaddr);
        pmd_k = pmd_offset(pud_k, kvaddr);
 
-       pte_k = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+       pte_k = (pte_t *)memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
        pmd_populate_kernel(&init_mm, pmd_k, pte_k);
        return pte_k;
 }
index ba145065c579bfff5af1d0ca4e569a8b8c49da32..f8fe5668b30fd98412c8fbf45433d3b8718158d4 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/initrd.h>
@@ -218,7 +217,7 @@ void __init mem_init(void)
                free_highmem_page(pfn_to_page(tmp));
 #endif
 
-       free_all_bootmem();
+       memblock_free_all();
        mem_init_print_info(NULL);
 }
 
index e8cd55a5b04c0570a4ed66b522446b8eee4d202d..91be74d8df658ccd5a4701fe7438053115dceeb9 100644 (file)
@@ -82,7 +82,6 @@ config ARM
        select HAVE_KERNEL_XZ
        select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
        select HAVE_KRETPROBES if (HAVE_KPROBES)
-       select HAVE_MEMBLOCK
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NMI
        select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
@@ -100,7 +99,6 @@ config ARM
        select IRQ_FORCED_THREADING
        select MODULES_USE_ELF_REL
        select NEED_DMA_MAP_STATE
-       select NO_BOOTMEM
        select OF_EARLY_FLATTREE if OF
        select OF_RESERVED_MEM if OF
        select OLD_SIGACTION
@@ -701,6 +699,7 @@ config ARCH_VIRT
        select ARM_GIC_V3_ITS if PCI
        select ARM_PSCI
        select HAVE_ARM_ARCH_TIMER
+       select ARCH_SUPPORTS_BIG_ENDIAN
 
 #
 # This is sorted alphabetically by mach-* pathname.  However, plat-*
index a810fa8ba4041f3d6333aef30c28c2c32c00ec5d..d6a49f59ecd924909d232a5e5d5d31b138d05df9 100644 (file)
@@ -947,12 +947,13 @@ choice
 
        config DEBUG_RCAR_GEN2_SCIF0
                bool "Kernel low-level debugging messages via SCIF0 on R-Car Gen2 and RZ/G1"
-               depends on ARCH_R8A7743 || ARCH_R8A7790 || ARCH_R8A7791 || \
-                       ARCH_R8A7792 || ARCH_R8A7793
+               depends on ARCH_R8A7743 || ARCH_R8A7744 || ARCH_R8A7790 || \
+                       ARCH_R8A7791 || ARCH_R8A7792 || ARCH_R8A7793
                help
                  Say Y here if you want kernel low-level debugging support
-                 via SCIF0 on Renesas RZ/G1M (R8A7743), R-Car H2 (R8A7790),
-                 M2-W (R8A7791), V2H (R8A7792), or M2-N (R8A7793).
+                 via SCIF0 on Renesas RZ/G1M (R8A7743), RZ/G1N (R8A7744),
+                 R-Car H2 (R8A7790), M2-W (R8A7791), V2H (R8A7792), or
+                 M2-N (R8A7793).
 
        config DEBUG_RCAR_GEN2_SCIF1
                bool "Kernel low-level debugging messages via SCIF1 on R8A77470"
index b5bd3de87c331ed9f7e85d43767c46c3831dfbcc..b0e966d625b929da7f631fd5db049f37e6206400 100644 (file)
@@ -81,6 +81,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
        bcm2836-rpi-2-b.dtb \
        bcm2837-rpi-3-b.dtb \
        bcm2837-rpi-3-b-plus.dtb \
+       bcm2837-rpi-cm3-io3.dtb \
        bcm2835-rpi-zero.dtb \
        bcm2835-rpi-zero-w.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
@@ -321,6 +322,7 @@ dtb-$(CONFIG_MACH_MESON6) += \
        meson6-atv1200.dtb
 dtb-$(CONFIG_MACH_MESON8) += \
        meson8-minix-neo-x8.dtb \
+       meson8b-ec100.dtb \
        meson8b-mxq.dtb \
        meson8b-odroidc1.dtb \
        meson8m2-mxiii-plus.dtb
@@ -548,6 +550,7 @@ dtb-$(CONFIG_SOC_IMX6SX) += \
 dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ul-14x14-evk.dtb \
        imx6ul-ccimx6ulsbcexpress.dtb \
+       imx6ul-ccimx6ulsbcpro.dtb \
        imx6ul-geam.dtb \
        imx6ul-isiot-emmc.dtb \
        imx6ul-isiot-nand.dtb \
@@ -559,7 +562,8 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ul-tx6ul-mainboard.dtb \
        imx6ull-14x14-evk.dtb \
        imx6ull-colibri-eval-v3.dtb \
-       imx6ull-colibri-wifi-eval-v3.dtb
+       imx6ull-colibri-wifi-eval-v3.dtb \
+       imx6ulz-14x14-evk.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
        imx7d-cl-som-imx7.dtb \
        imx7d-colibri-emmc-eval-v3.dtb \
@@ -649,6 +653,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
        omap3-gta04a3.dtb \
        omap3-gta04a4.dtb \
        omap3-gta04a5.dtb \
+       omap3-gta04a5one.dtb \
        omap3-ha.dtb \
        omap3-ha-lcd.dtb \
        omap3-igep0020.dtb \
@@ -706,6 +711,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
        am335x-evmsk.dtb \
        am335x-icev2.dtb \
        am335x-lxm.dtb \
+       am335x-moxa-uc-2101.dtb \
        am335x-moxa-uc-8100-me-t.dtb \
        am335x-nano.dtb \
        am335x-pdu001.dtb \
@@ -864,6 +870,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3288-r89.dtb \
        rk3288-rock2-square.dtb \
        rk3288-tinker.dtb \
+       rk3288-tinker-s.dtb \
        rk3288-veyron-brain.dtb \
        rk3288-veyron-jaq.dtb \
        rk3288-veyron-jerry.dtb \
@@ -892,7 +899,7 @@ dtb-$(CONFIG_ARCH_SOCFPGA) += \
        socfpga_arria10_socdk_sdmmc.dtb \
        socfpga_cyclone5_mcvevk.dtb \
        socfpga_cyclone5_socdk.dtb \
-       socfpga_cyclone5_de0_sockit.dtb \
+       socfpga_cyclone5_de0_nano_soc.dtb \
        socfpga_cyclone5_sockit.dtb \
        socfpga_cyclone5_socrates.dtb \
        socfpga_cyclone5_sodia.dtb \
@@ -1033,6 +1040,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
        sun8i-h2-plus-orangepi-r1.dtb \
        sun8i-h2-plus-orangepi-zero.dtb \
        sun8i-h3-bananapi-m2-plus.dtb \
+       sun8i-h3-bananapi-m2-plus-v1.2.dtb \
        sun8i-h3-beelink-x2.dtb \
        sun8i-h3-libretech-all-h3-cc.dtb \
        sun8i-h3-nanopi-m1.dtb  \
@@ -1046,6 +1054,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
        sun8i-h3-orangepi-pc-plus.dtb \
        sun8i-h3-orangepi-plus.dtb \
        sun8i-h3-orangepi-plus2e.dtb \
+       sun8i-h3-orangepi-zero-plus2.dtb \
        sun8i-r16-bananapi-m2m.dtb \
        sun8i-r16-nintendo-nes-classic.dtb \
        sun8i-r16-nintendo-super-nes-classic.dtb \
@@ -1061,6 +1070,7 @@ dtb-$(CONFIG_ARCH_TANGO) += \
        tango4-vantage-1172.dtb
 dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
        tegra20-harmony.dtb \
+       tegra20-colibri-eval-v3.dtb \
        tegra20-colibri-iris.dtb \
        tegra20-medcom-wide.dtb \
        tegra20-paz00.dtb \
@@ -1071,6 +1081,7 @@ dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
        tegra20-ventana.dtb
 dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += \
        tegra30-apalis-eval.dtb \
+       tegra30-apalis-v1.1-eval.dtb \
        tegra30-beaver.dtb \
        tegra30-cardhu-a02.dtb \
        tegra30-cardhu-a04.dtb \
@@ -1149,6 +1160,7 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
 dtb-$(CONFIG_MACH_ARMADA_375) += \
        armada-375-db.dtb
 dtb-$(CONFIG_MACH_ARMADA_38X) += \
+       armada-385-db-88f6820-amc.dtb \
        armada-385-db-ap.dtb \
        armada-385-linksys-caiman.dtb \
        armada-385-linksys-cobra.dtb \
@@ -1199,6 +1211,8 @@ dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
 dtb-$(CONFIG_ARCH_ASPEED) += \
        aspeed-ast2500-evb.dtb \
        aspeed-bmc-arm-centriq2400-rep.dtb \
+       aspeed-bmc-arm-stardragon4800-rep2.dtb \
+       aspeed-bmc-facebook-tiogapass.dtb \
        aspeed-bmc-intel-s2600wf.dtb \
        aspeed-bmc-opp-lanyang.dtb \
        aspeed-bmc-opp-palmetto.dtb \
index 73b514dddf65b281b0c3093f40b05496240b5455..9e5e75ea87f5ec69bc6dd1a235108673a324def9 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "mii";
 };
 
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &mmc1 {
index 325daae40278a11fca64fa96d74fd64e991da546..e543c2bee8c2b714a58088d315b128c2c1fb034e 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <dt-bindings/display/tda998x.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 &ldo3_reg {
        regulator-min-microvolt = <1800000>;
 };
 
 &i2c0 {
-       tda19988: tda19988 {
+       tda19988: tda19988@70 {
                compatible = "nxp,tda998x";
                reg = <0x70>;
+               nxp,calib-gpios = <&gpio1 25 0>;
+               interrupts-extended = <&gpio1 25 IRQ_TYPE_LEVEL_LOW>;
 
                pinctrl-names = "default", "off";
                pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
index 59431b23594489dd3f211c0be1a93c031d3c0c46..9c2a947aacf5c7e54ddb9c36c4e78ec948fb3347 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rmii";
 };
 
index 947c81b7aaafbf4b79bcdb84cb8490f5a430b9a9..c4d3e1f1a95e73a6bc345ee4863027b2a561cb74 100644 (file)
@@ -486,10 +486,14 @@ status = "okay";
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
 };
 
index c87d01297a013b60b8752594b13b89392ce95e7a..98ec9c3e49ba1e5eb9f7d2d63f761171eaf289d9 100644 (file)
        pinctrl-0 = <&cpsw_default>;
        pinctrl-1 = <&cpsw_sleep>;
        status = "okay";
+       slaves = <1>;
 };
 
 &davinci_mdio {
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
-};
 
-&cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
-       phy-mode = "rgmii-txid";
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
-&cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+&cpsw_emac0 {
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
 };
 
index bf1a40e45c97b1b3a0cbbfa6ea583509f4e5bb8a..245868f58fe301eae182359f3b2ed0f8358d1c7e 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii-txid";
        dual_emac_res_vlan = <2>;
 };
index a5769a8f5fc81b001140ee08c2a379ed7db11613..55b4c94cfafb278a3c8f873ff0dc1ef5c64082aa 100644 (file)
 
 &davinci_mdio {
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rmii";
+
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rmii";
 };
 
index 1d6c6fa703e4e36c7e2852038472a9cab7885042..481edcfaf121e16144123b3fbf0ed38699d5b770 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <5>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rmii";
        dual_emac_res_vlan = <2>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <4>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rmii";
        dual_emac_res_vlan = <3>;
 };
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@5 {
+               reg = <5>;
+       };
+
+       ethphy1: ethernet-phy@4 {
+               reg = <4>;
+       };
 };
 
 &mmc1 {
diff --git a/arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi b/arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi
new file mode 100644 (file)
index 0000000..14f7819
--- /dev/null
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MOXA Inc. - https://www.moxa.com/
+ *
+ * Authors: SZ Lin (林上智) <sz.lin@moxa.com>
+ *          Wes Huang (黃淵河) <wes.huang@moxa.com>
+ *          Fero JD Zhou (周俊達) <FeroJD.Zhou@moxa.com>
+ */
+
+#include "am33xx.dtsi"
+
+/ {
+       vbat: vbat-regulator {
+               compatible = "regulator-fixed";
+       };
+
+       /* Power supply provides a fixed 3.3V @3A */
+       vmmcsd_fixed: vmmcsd-regulator {
+             compatible = "regulator-fixed";
+             regulator-name = "vmmcsd_fixed";
+             regulator-min-microvolt = <3300000>;
+             regulator-max-microvolt = <3300000>;
+             regulator-boot-on;
+       };
+
+       buttons: push_button {
+               compatible = "gpio-keys";
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_sda.i2c0_sda */
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)       /* i2c0_scl.i2c0_scl */
+               >;
+       };
+
+       push_button_pins: pinmux_push_button {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* lcd_hsync.gpio2_23 */
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
+               >;
+       };
+
+       mmc1_pins_default: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       /* eMMC */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad12.mmc1_dat0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad13.mmc1_dat1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad14.mmc1_dat2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad15.mmc1_dat3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad8.mmc1_dat4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad9.mmc1_dat5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad10.mmc1_dat6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1)       /* gpmc_ad11.mmc1_dat7 */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2)       /* gpmc_csn2.mmc1_cmd */
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2)       /* gpmc_csn1.mmc1_clk */
+               >;
+       };
+
+       spi0_pins: pinmux_spi0 {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0)        /* spi0_sclk.spi0_sclk */
+                       AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE0)        /* spi0_cs0.spi0_cs0 */
+                       AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0)        /* spi0_d0.spi0_d0 */
+                       AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0)        /* spi0_d1.spi0_d1 */
+               >;
+       };
+};
+
+&uart0 {
+       /* Console */
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       eeprom: eeprom@50 {
+               compatible = "atmel,24c16";
+               pagesize = <16>;
+               reg = <0x50>;
+       };
+
+       rtc_wdt: rtc_wdt@68 {
+               compatible = "dallas,ds1374";
+               reg = <0x68>;
+       };
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_ctrl_mod {
+       status = "okay";
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&cppi41dma  {
+       status = "okay";
+};
+
+/* Power */
+&vbat {
+       regulator-name = "vbat";
+       regulator-min-microvolt = <5000000>;
+       regulator-max-microvolt = <5000000>;
+};
+
+&mac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cpsw_default>;
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&davinci_mdio_default>;
+       status = "okay";
+};
+
+&cpsw_emac0 {
+       status = "okay";
+};
+
+&cpsw_emac1 {
+       status = "okay";
+};
+
+&phy_sel {
+       reg= <0x44e10650 0xf5>;
+       rmii-clock-ext;
+};
+
+&sham {
+       status = "okay";
+};
+
+&aes {
+       status = "okay";
+};
+
+&gpio0 {
+       ti,no-reset-on-init;
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       vmmc-supply = <&vmmcsd_fixed>;
+       bus-width = <8>;
+       pinctrl-0 = <&mmc1_pins_default>;
+       ti,non-removable;
+       status = "okay";
+};
+
+&buttons {
+       pinctrl-names = "default";
+       pinctrl-0 = <&push_button_pins>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       button@0 {
+               label = "push_button";
+               linux,code = <0x100>;
+               gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
+       };
+};
+
+/* SPI Busses */
+&spi0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi0_pins>;
+
+       m25p80@0 {
+               compatible = "mx25l6405d";
+               spi-max-frequency = <40000000>;
+
+               reg = <0>;
+               spi-cpol;
+               spi-cpha;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       /* reg : The partition's offset and size within the mtd bank. */
+                       partitions@0 {
+                               label = "MLO";
+                               reg = <0x0 0x80000>;
+                       };
+
+                       partitions@1 {
+                               label = "U-Boot";
+                               reg = <0x80000 0x100000>;
+                       };
+
+                       partitions@2 {
+                               label = "U-Boot Env";
+                               reg = <0x180000 0x40000>;
+                       };
+               };
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi1_pins>;
+
+       tpm_spi_tis@0 {
+               compatible = "tcg,tpm_tis-spi";
+               reg = <0>;
+               spi-max-frequency = <500000>;
+       };
+};
diff --git a/arch/arm/boot/dts/am335x-moxa-uc-2101.dts b/arch/arm/boot/dts/am335x-moxa-uc-2101.dts
new file mode 100644 (file)
index 0000000..48aee6d
--- /dev/null
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MOXA Inc. - https://www.moxa.com/
+ *
+ * Authors: SZ Lin (林上智) <sz.lin@moxa.com>
+ *          Wes Huang (黃淵河) <wes.huang@moxa.com>
+ *          Fero JD Zhou (周俊達) <FeroJD.Zhou@moxa.com>
+ */
+
+/dts-v1/;
+
+#include "am335x-moxa-uc-2100-common.dtsi"
+
+/ {
+       model = "Moxa UC-2101";
+       compatible = "moxa,uc-2101", "ti,am33xx";
+
+       leds {
+               compatible = "gpio-leds";
+               led1 {
+                       label = "UC2100:GREEN:USER";
+                       gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1)     /* mii1_crs.rmii1_crs_dv */
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1)       /* mii1_rxerr.rmii1_rxerr */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txen.rmii1_txen */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txd1.rmii1_txd1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1)    /* mii1_txd0.rmii1_txd0 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1)       /* mii1_rxd1.rmii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1)       /* mii1_rxd0.rmii1_rxd0 */
+                       AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mii1_refclk.rmii1_refclk */
+               >;
+       };
+
+       spi1_pins: pinmux_spi1 {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x964, PIN_INPUT_PULLUP | MUX_MODE4)        /* ecap0_in_pwm0_out.spi1_sclk */
+                       AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE4)        /* uart1_ctsn.spi1_cs0 */
+                       AM33XX_IOPAD(0x968, PIN_INPUT_PULLUP | MUX_MODE4)        /* uart0_ctsn.spi1_d0 */
+                       AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE4)        /* uart0_rtsn.spi1_d1 */
+               >;
+       };
+};
+
+&davinci_mdio {
+       phy0: ethernet-phy@4 {
+               reg = <4>;
+       };
+};
+
+&cpsw_emac0 {
+       status = "okay";
+       phy-handle = <&phy0>;
+       phy-mode = "rmii";
+};
+
+&cpsw_emac1 {
+       status = "disabled";
+};
index f82233cd18e0bf5b7ddd9c673a15bd28dd7d1994..5a58efc0c87433b5c2cc576ef1b27ce29568e53b 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&davinci_mdio_default>;
        status = "okay";
+
+       ethphy0: ethernet-phy@4 {
+               reg = <4>;
+       };
+
+       ethphy1: ethernet-phy@5 {
+               reg = <5>;
+       };
 };
 
 &cpsw_emac0 {
        status = "okay";
-       phy_id = <&davinci_mdio>, <4>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rmii";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
        status = "okay";
-       phy_id = <&davinci_mdio>, <5>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rmii";
        dual_emac_res_vlan = <2>;
 };
index 946d7069f41711df7d691b29ea56f64930996c44..9c9143ed40037f04e63eec7c7e5e014083dd281d 100644 (file)
 
 &davinci_mdio {
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "mii";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "mii";
        dual_emac_res_vlan = <2>;
 };
index 4d969013f99a6180a1e841de8e736e61c6cf3b7e..85cd1d0a73ca4542d29fb473ca310a796bb10f5c 100644 (file)
                invensense,key = [4e cc 7e eb f6 1e 35 22 00 34 0d 65 32 e9 94 89];*/
        };
 
-       bmp280: pressure@78 {
+       bmp280: pressure@76 {
                compatible = "bosch,bmp280";
                reg = <0x76>;
        };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <4>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
 };
 
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@4 {
+               reg = <4>;
+       };
 };
 
 &mmc1 {
index 1ad530a39a957228e6e334ea9b04515789edec19..6dd9d487aaebc58329a0c8e108bb9243535cc017 100644 (file)
        ti,pindir-d0-out-d1-in;
        status = "okay";
 
-       cfaf240320a032t {
+       display-controller@0 {
                compatible = "orisetech,otm3225a";
                reg = <0>;
                spi-max-frequency = <1000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&davinci_mdio_default>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "mii";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "mii";
        dual_emac_res_vlan = <2>;
 };
index 9fb7426070ce0dc9402520c3ee5210ae31e6e6da..6be79b8349ac88547e415a796cdc6a5e769a766c 100644 (file)
 /* Ethernet */
 &cpsw_emac0 {
        status = "okay";
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
 &cpsw_emac1 {
        status = "okay";
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
 };
 
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&mdio_pins>;
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &mac {
index 7b8e7417a11e68b397b1018faa90ebc21027417c..35527fdf56cc8896178b055ebee6f63e6cad6845 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
 };
 
index 4f6a286ea293fa64710acb1e4585749c73cda3d9..1d925ed2b102c79be2053ac8a519999c736890ae 100644 (file)
        status = "okay";
        slaves = <1>;
        cpsw_emac0: slave@4a100200  {
-               phy_id = <&davinci_mdio>, <0>;
                phy-mode = "mii";
                phy-handle = <&ethernetphy0>;
        };
diff --git a/arch/arm/boot/dts/am3517-evm-ui.dtsi b/arch/arm/boot/dts/am3517-evm-ui.dtsi
new file mode 100644 (file)
index 0000000..e841918
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2018 Logic PD, Inc - http://www.logicpd.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       codec1 {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "tlv320aic23-hifi";
+
+               simple-audio-card,widgets =
+                       "Microphone", "Mic In",
+                       "Line", "Line In",
+                       "Line", "Line Out";
+
+               simple-audio-card,routing =
+                       "Line Out", "LOUT",
+                       "Line Out", "ROUT",
+                       "LLINEIN", "Line In",
+                       "RLINEIN", "Line In",
+                       "MICIN", "Mic In";
+
+               simple-audio-card,format = "i2s";
+               simple-audio-card,bitclock-master = <&sound_master>;
+               simple-audio-card,frame-master = <&sound_master>;
+
+               simple-audio-card,cpu {
+                       sound-dai = <&mcbsp1>;
+               };
+
+               sound_master: simple-audio-card,codec {
+                       sound-dai = <&tlv320aic23_1>;
+                       system-clock-frequency = <12000000>;
+               };
+       };
+
+       codec2 {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "tlv320aic23-hifi";
+
+               simple-audio-card,widgets =
+                       "Microphone", "Mic In",
+                       "Line", "Line In",
+                       "Line", "Line Out";
+
+               simple-audio-card,routing =
+                       "Line Out", "LOUT",
+                       "Line Out", "ROUT",
+                       "LLINEIN", "Line In",
+                       "RLINEIN", "Line In",
+                       "MICIN", "Mic In";
+
+               simple-audio-card,format = "i2s";
+               simple-audio-card,bitclock-master = <&sound_master2>;
+               simple-audio-card,frame-master = <&sound_master2>;
+
+               simple-audio-card,cpu {
+                       sound-dai = <&mcbsp2>;
+               };
+
+               sound_master2: simple-audio-card,codec {
+                       sound-dai = <&tlv320aic23_2>;
+                       system-clock-frequency = <12000000>;
+               };
+       };
+
+       expander-keys {
+               compatible = "gpio-keys-polled";
+               poll-interval = <100>;
+
+               record {
+                       label = "Record";
+                       /* linux,code = <BTN_0>; */
+                       gpios = <&tca6416_2 15 GPIO_ACTIVE_LOW>;
+               };
+
+               play {
+                       label = "Play";
+                       linux,code = <KEY_PLAY>;
+                       gpios = <&tca6416_2 14 GPIO_ACTIVE_LOW>;
+               };
+
+               Stop {
+                       label = "Stop";
+                       linux,code = <KEY_STOP>;
+                       gpios = <&tca6416_2 13 GPIO_ACTIVE_LOW>;
+               };
+
+               fwd {
+                       label = "FWD";
+                       linux,code = <KEY_FASTFORWARD>;
+                       gpios = <&tca6416_2 12 GPIO_ACTIVE_LOW>;
+               };
+
+               rwd {
+                       label = "RWD";
+                       linux,code = <KEY_REWIND>;
+                       gpios = <&tca6416_2 11 GPIO_ACTIVE_LOW>;
+               };
+
+               shift {
+                       label = "Shift";
+                       linux,code = <KEY_LEFTSHIFT>;
+                       gpios = <&tca6416_2 10 GPIO_ACTIVE_LOW>;
+               };
+
+               Mode {
+                       label = "Mode";
+                       linux,code = <BTN_MODE>;
+                       gpios = <&tca6416_2 9 GPIO_ACTIVE_LOW>;
+               };
+
+               Menu {
+                       label = "Menu";
+                       linux,code = <KEY_MENU>;
+                       gpios = <&tca6416_2 8 GPIO_ACTIVE_LOW>;
+               };
+
+               Up {
+                       label = "Up";
+                       linux,code = <KEY_UP>;
+                       gpios = <&tca6416_2 7 GPIO_ACTIVE_LOW>;
+               };
+
+               Down {
+                       label = "Down";
+                       linux,code = <KEY_DOWN>;
+                       gpios = <&tca6416_2 6 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&i2c2 {
+       /* Audio codecs */
+       tlv320aic23_1: codec@1a {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1a>;
+               #sound-dai-cells= <0>;
+               status = "okay";
+       };
+
+       tlv320aic23_2: codec@1b {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1b>;
+               #sound-dai-cells= <0>;
+               status = "okay";
+       };
+};
+
+&i2c3 {
+       /* Audio codecs */
+       tlv320aic23_3: codec@1a {
+               compatible = "ti,tlv320aic23";
+               reg = <0x1a>;
+               #sound-dai-cells= <0>;
+               status = "okay";
+       };
+
+       /* GPIO Expanders */
+       tca6416_2: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               vcc-supply = <&vdd_io_reg>;
+       };
+
+       tca6416_3: gpio@21 {
+               compatible = "ti,tca6416";
+               reg = <0x21>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               vcc-supply = <&vdd_io_reg>;
+       };
+
+       /* TVP5146 Analog Video decoder input */
+       tvp5146@5c {
+               compatible = "ti,tvp5146m2";
+               reg = <0x5c>;
+       };
+};
+
+&mcbsp1 {
+       status = "ok";
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp1_pins>;
+};
+
+&mcbsp2 {
+       status = "ok";
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp2_pins>;
+};
+
+&omap3_pmx_core {
+       mcbsp1_pins: pinmux_mcbsp1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE0)       /* mcbsp1_dx.mcbsp1_dx */
+                       OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT | MUX_MODE0)        /* mcbsp1_dx.mcbsp1_dr */
+                       OMAP3_CORE1_IOPAD(0x2196, PIN_INPUT | MUX_MODE0)        /* mcbsp_clks.mcbsp1_fsx */
+                       OMAP3_CORE1_IOPAD(0x2198, PIN_INPUT | MUX_MODE0)        /* mcbsp1_clkx.mcbsp1_clkx */
+               >;
+       };
+
+       mcbsp2_pins: pinmux_mcbsp2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0)        /* mcbsp2_fsx.mcbsp2_fsx */
+                       OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0)        /* mcbsp2_clkx.mcbsp2_clkx */
+                       OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0)        /* mcbsp2_dr.mcbsp2.dr */
+                       OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0)       /* mcbsp2_dx.mcbsp2_dx */
+               >;
+       };
+};
index 1d158cfda15f2653fe829aa4faf610f5a926f883..d4d33cd7adad73c793c382c9b15026745a9b355b 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "am3517.dtsi"
 #include "am3517-som.dtsi"
+#include "am3517-evm-ui.dtsi"
 #include <dt-bindings/input/input.h>
 
 / {
index d4b7c59eec6853f2f836b5b3ffd686988ad0f6b1..a68e89dae7a17d0257a90ae7fddebdf0173e189f 100644 (file)
                        };
                };
 
-               qspi: qspi@47900000 {
+               qspi: spi@47900000 {
                        compatible = "ti,am4372-qspi";
                        reg = <0x47900000 0x100>,
                              <0x30000000 0x4000000>;
index bff5abe69bdb6836f6597a047ef6a12ac227aa6d..4fcf647815a2f763cb75571e4f4ed4d8960e5235 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&davinci_mdio_default>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii-txid";
        dual_emac_res_vlan = <2>;
 };
index 5b97c20c5ed49c2de9432742442a322e4e127728..601bf4daaeb76dd2afaa41186cc4fd1e15b03a52 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
index 20132477a87114e45f2f8a317c32e6f807b47085..bb285409473ea6fb93ff63154cc1c4b8ff83c7de 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
index d4be3fd0b6f4094643ef98660e0f2dbcb5edca9d..088cba09d34da2307a77906f8cf3118f2574e8f1 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@4 {
+               reg = <4>;
+       };
+
+       ethphy1: ethernet-phy@5 {
+               reg = <5>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <4>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <5>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
        dual_emac_res_vlan = <2>;
 };
index 6502d33976532ceddf12c8f780dead8b703d0dfc..4ea753b3ee432f699ca80851dc7ecba87d75310a 100644 (file)
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
        status = "okay";
+
+       ethphy0: ethernet-phy@16 {
+               reg = <16>;
+       };
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <16>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rmii";
 };
 
index d9a2049a1ea8ad49163c8028d85ab9af45a0af0b..6432309b39e3854eb225a64d5766e9164d88ff2c 100644 (file)
                        linux,default-trigger = "mmc0";
                };
        };
+
+       idk-leds {
+               status = "disabled";
+               compatible = "gpio-leds";
+               red0-led {
+                       label = "idk:red0";
+                       gpios = <&gpio6 19 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green0-led {
+                       label = "idk:green0";
+                       gpios = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue0-led {
+                       label = "idk:blue0";
+                       gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red1-led {
+                       label = "idk:red1";
+                       gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green1-led {
+                       label = "idk:green1";
+                       gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue1-led {
+                       label = "idk:blue1";
+                       gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red2-led {
+                       label = "idk:red2";
+                       gpios = <&gpio7 9 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green2-led {
+                       label = "idk:green2";
+                       gpios = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue2-led {
+                       label = "idk:blue2";
+                       gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red3-led {
+                       label = "idk:red3";
+                       gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green3-led {
+                       label = "idk:green3";
+                       gpios = <&gpio7 25 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue3-led {
+                       label = "idk:blue3";
+                       gpios = <&gpio7 24 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
 };
 
 &extcon_usb2 {
        vbus-gpio = <&gpio7 22 GPIO_ACTIVE_HIGH>;
 };
 
+&sn65hvs882 {
+       load-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
+};
+
 &mailbox5 {
        status = "okay";
        mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
        pinctrl-1 = <&mmc2_pins_hs>;
        pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>;
 };
-
-&cpu0 {
-       vdd-supply = <&smps12_reg>;
-};
index 784639ddf4513a316971ec181b3a1ade74fe18f1..a064f13b38802d1483796a7e5c5e93c8e03bb640 100644 (file)
                        linux,default-trigger = "mmc0";
                };
        };
+
+       idk-leds {
+               status = "disabled";
+               compatible = "gpio-leds";
+               red0-led {
+                       label = "idk:red0";
+                       gpios = <&gpio6 19 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green0-led {
+                       label = "idk:green0";
+                       gpios = <&gpio3 9 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue0-led {
+                       label = "idk:blue0";
+                       gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red1-led {
+                       label = "idk:red1";
+                       gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green1-led {
+                       label = "idk:green1";
+                       gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue1-led {
+                       label = "idk:blue1";
+                       gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red2-led {
+                       label = "idk:red2";
+                       gpios = <&gpio7 9 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green2-led {
+                       label = "idk:green2";
+                       gpios = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue2-led {
+                       label = "idk:blue2";
+                       gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red3-led {
+                       label = "idk:red3";
+                       gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               green3-led {
+                       label = "idk:green3";
+                       gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               blue3-led {
+                       label = "idk:blue3";
+                       gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
 };
 
 &extcon_usb2 {
index 3ef9111d0e8baafd530c7b09f6db1c42895d61cc..b2fb6e097be7607ddd1613a75c8290b26f9fe121 100644 (file)
@@ -36,7 +36,3 @@
        pinctrl-1 = <&mmc2_pins_hs>;
        pinctrl-2 = <&mmc2_pins_ddr_rev20>;
 };
-
-&cpu0 {
-       vdd-supply = <&smps12_reg>;
-};
index 203266f884807e3a2cced5c35c56e6d92fc69bf9..4748ce8747ad865074debf76adaac141247af017 100644 (file)
        };
 
        /* touch controller */
-       ads7846@0 {
+       touchscreen@1 {
                pinctrl-names = "default";
                pinctrl-0 = <&ads7846_pins>;
 
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii-txid";
        dual_emac_res_vlan = <0>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii-txid";
        dual_emac_res_vlan = <1>;
 };
        pinctrl-names = "default", "sleep";
        pinctrl-0 = <&davinci_mdio_pins_default>;
        pinctrl-1 = <&davinci_mdio_pins_sleep>;
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
 };
 
 &usb2_phy1 {
index c9063ffca524c8022f97930964d7b03f4de38c4c..f7bd26458915fbb1656c62e9668bda4a8d0ad6a3 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
        dual_emac_res_vlan = <2>;
 };
 
+&davinci_mdio {
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &usb2_phy1 {
        phy-supply = <&ldousb_reg>;
 };
                };
        };
 };
+
+&cpu0 {
+       vdd-supply = <&smps12_reg>;
+};
index a917cf8825ca8b43bc3cd02a5395d6fbe77a2721..0e4c7c4c8c0930c81a6e8f1925a9cf0343a4b76e 100644 (file)
                        clock-names = "uartclk", "apb_pclk";
                };
 
-               ssp: ssp@1000d000 {
+               ssp: spi@1000d000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x1000d000 0x1000>;
                        clocks = <&sspclk>, <&pclk>;
index f935b72d3d96458a99f1a101d98ec7d620f60c4e..f2a1d25eb6cf3f1249bcc2166bee7f86a75b2a6d 100644 (file)
                        clock-names = "apb_pclk";
                };
 
-               pb1176_ssp: ssp@1010b000 {
+               pb1176_ssp: spi@1010b000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x1010b000 0x1000>;
                        interrupt-parent = <&intc_dc1176>;
index 36203288de4267d6b41d01375027da7d099b473e..7f9cbdf33a51009ffea23fa488ec8f1e6abe7914 100644 (file)
                        clock-names = "uartclk", "apb_pclk";
                };
 
-               ssp@1000d000 {
+               spi@1000d000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x1000d000 0x1000>;
                        interrupt-parent = <&intc_pb11mp>;
index 10868ba3277f52d1eef2be37df09b101187d9fcf..a5676697ff3b7dee101d3f56e92379bc6c6b3e64 100644 (file)
                        clock-names = "uartclk", "apb_pclk";
                };
 
-               ssp: ssp@1000d000 {
+               ssp: spi@1000d000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x1000d000 0x1000>;
                        clocks = <&sspclk>, <&pclk>;
diff --git a/arch/arm/boot/dts/armada-385-db-88f6820-amc.dts b/arch/arm/boot/dts/armada-385-db-88f6820-amc.dts
new file mode 100644 (file)
index 0000000..7881df3
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device Tree file for Marvell Armada 385 AMC board
+ * (DB-88F6820-AMC)
+ *
+ * Copyright (C) 2017 Allied Telesis Labs
+ */
+
+/dts-v1/;
+#include "armada-385.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Marvell Armada 385 AMC";
+       compatible = "marvell,a385-db-amc", "marvell,armada385", "marvell,armada380";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       aliases {
+               ethernet0 = &eth0;
+               ethernet1 = &eth1;
+               spi1 = &spi1;
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x80000000>; /* 2GB */
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+       };
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       status = "okay";
+};
+
+&uart0 {
+       /*
+        * Exported on the micro USB connector CON3
+        * through an FTDI
+        */
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+       status = "okay";
+};
+
+
+&eth0 {
+       pinctrl-names = "default";
+       /*
+        * The Reference Clock 0 is used to provide a
+        * clock to the PHY
+        */
+       pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+       status = "okay";
+       phy = <&phy0>;
+       phy-mode = "rgmii-id";
+};
+
+&eth2 {
+       status = "okay";
+       phy = <&phy1>;
+       phy-mode = "sgmii";
+};
+
+&usb0 {
+       status = "okay";
+};
+
+
+
+&mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mdio_pins>;
+
+       phy0: ethernet-phy@1 {
+               reg = <1>;
+       };
+
+       phy1: ethernet-phy@0 {
+               reg = <0>;
+       };
+};
+
+&nand_controller {
+       status = "okay";
+
+       nand@0 {
+               reg = <0>;
+               label = "pxa3xx_nand-0";
+               nand-rb = <0>;
+               nand-on-flash-bbt;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       partition@0 {
+                               reg = <0x00000000 0x40000000>;
+                               label = "user";
+                       };
+               };
+       };
+};
+
+&pciec {
+       status = "okay";
+};
+
+&pcie1 {
+       /* Port 0, Lane 0 */
+       status = "okay";
+};
+
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi1_pins>;
+       status = "okay";
+
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>; /* Chip select 0 */
+               spi-max-frequency = <50000000>;
+               m25p,fast-read;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       partition@0 {
+                               reg = <0x00000000 0x00100000>;
+                               label = "u-boot";
+                       };
+                       partition@100000 {
+                               reg = <0x00100000 0x00040000>;
+                               label = "u-boot-env";
+                       };
+               };
+       };
+};
+
+&refclk {
+       clock-frequency = <20000000>;
+};
index 7c6ad2afb0947afc85ea34ff5d470df9bfbd3ef9..1b0d0680c8b6207ddb9717dfd320e8069c6d6d65 100644 (file)
@@ -48,7 +48,7 @@
                                             &clearfog_sdhci_cd_pins>;
                                pinctrl-names = "default";
                                status = "okay";
-                               vmmc = <&reg_3p3v>;
+                               vmmc-supply = <&reg_3p3v>;
                                wp-inverted;
                        };
 
index 8d708cc224958865a3c208b1ec29c03118c0852f..59753470cd34733dd44fb0398b7275bc2553b8eb 100644 (file)
                                };
                        };
 
-                       nand: nand@d0000 {
+                       nand_controller: nand-controller@d0000 {
                                clocks = <&dfx_coredivclk 0>;
                        };
 
                        ranges = <0 MBUS_ID(0x03, 0x00) 0 0x100000>;
 
                        pp0: packet-processor@0 {
-                               compatible = "marvell,prestera-98dx3236";
+                               compatible = "marvell,prestera-98dx3236", "marvell,prestera";
                                reg = <0 0x4000000>;
                                interrupts = <33>, <34>, <35>;
                                dfx = <&dfx>;
index 2f5fc67dd6dcc696ce3a471eb8662296170d9541..1d9d8a8ea60ca155461604a00d07bfac5a88ab31 100644 (file)
@@ -35,5 +35,5 @@
 };
 
 &pp0 {
-       compatible = "marvell,prestera-98dx3336";
+       compatible = "marvell,prestera-98dx3336", "marvell,prestera";
 };
index 7a9e8839880b07a7d839d5e3c53e558819c81321..48ffdc72bfc752d99431319979aba8c64bb7ae89 100644 (file)
@@ -49,6 +49,6 @@
 };
 
 &pp0 {
-       compatible = "marvell,prestera-98dx4251";
+       compatible = "marvell,prestera-98dx4251", "marvell,prestera";
        interrupts = <33>, <34>, <35>, <36>;
 };
index f42fc6118b7c296c582c6a2f56d904f929f40237..8a3aa616bbd006f25d37446cc11323e6f235ef26 100644 (file)
        status = "okay";
 };
 
-&nand {
+&nand_controller {
        status = "okay";
-       label = "pxa3xx_nand-0";
-       num-cs = <1>;
-       marvell,nand-keep-config;
-       nand-on-flash-bbt;
-       nand-ecc-strength = <4>;
-       nand-ecc-step-size = <512>;
+
+       nand@0 {
+               reg = <0>;
+               label = "pxa3xx_nand-0";
+               nand-rb = <0>;
+               marvell,nand-keep-config;
+               nand-on-flash-bbt;
+               nand-ecc-strength = <4>;
+               nand-ecc-step-size = <512>;
+       };
 };
 
 &sdio {
index 8432f517e346124cb82e0c2eed896680c022891f..df048050615f5124d2af71f25f6b407c9c43663f 100644 (file)
        status = "okay";
 };
 
-&nand {
+&nand_controller {
        status = "okay";
-       label = "pxa3xx_nand-0";
-       num-cs = <1>;
-       marvell,nand-keep-config;
-       nand-on-flash-bbt;
-       nand-ecc-strength = <4>;
-       nand-ecc-step-size = <512>;
+
+       nand@0 {
+               reg = <0>;
+               label = "pxa3xx_nand-0";
+               nand-rb = <0>;
+               marvell,nand-keep-config;
+               nand-on-flash-bbt;
+               nand-ecc-strength = <4>;
+               nand-ecc-step-size = <512>;
+       };
 };
 
 &spi0 {
diff --git a/arch/arm/boot/dts/aspeed-bmc-arm-stardragon4800-rep2.dts b/arch/arm/boot/dts/aspeed-bmc-arm-stardragon4800-rep2.dts
new file mode 100644 (file)
index 0000000..bdfd8c9
--- /dev/null
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+       model = "HXT StarDragon 4800 REP2 AST2520";
+       compatible = "hxt,stardragon4800-rep2-bmc", "aspeed,ast2500";
+
+       chosen {
+               stdout-path = &uart5;
+               bootargs = "console=ttyS4,115200 earlyprintk";
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x40000000>;
+       };
+
+       iio-hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+                                               <&adc 4>, <&adc 5>, <&adc 6>, <&adc 8>;
+       };
+
+       iio-hwmon-battery {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 7>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               system_fault1 {
+                       label = "System_fault1";
+                       gpios = <&gpio ASPEED_GPIO(I, 3) GPIO_ACTIVE_LOW>;
+               };
+
+               system_fault2 {
+                       label = "System_fault2";
+                       gpios = <&gpio ASPEED_GPIO(I, 2) GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+#include "openbmc-flash-layout.dtsi"
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+       flash@0 {
+               status = "okay";
+       };
+};
+
+&spi2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi2ck_default
+                       &pinctrl_spi2miso_default
+                       &pinctrl_spi2mosi_default
+                       &pinctrl_spi2cs0_default>;
+};
+
+&uart3 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd3_default &pinctrl_rxd3_default>;
+       current-speed = <115200>;
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&mac0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+};
+
+&mac1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii2_default>;
+       use-ncsi;
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+
+       tmp421@1e {
+               compatible = "ti,tmp421";
+               reg = <0x1e>;
+       };
+       tmp421@2a {
+               compatible = "ti,tmp421";
+               reg = <0x2a>;
+       };
+       tmp421@1c {
+               compatible = "ti,tmp421";
+               reg = <0x1c>;
+       };
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2c6 {
+       status = "okay";
+
+       tmp421@1f {
+               compatible = "ti,tmp421";
+               reg = <0x1f>;
+       };
+       nvt210@4c {
+               compatible = "nvt210";
+               reg = <0x4c>;
+       };
+       eeprom@50 {
+               compatible = "atmel,24c128";
+               reg = <0x50>;
+               pagesize = <128>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c8 {
+       status = "okay";
+
+       pca9641@70 {
+               compatible = "nxp,pca9641";
+               reg = <0x70>;
+               i2c-arb {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       eeprom@50 {
+                               compatible = "atmel,24c02";
+                               reg = <0x50>;
+                       };
+                       dps650ab@58 {
+                               compatible = "dps650ab";
+                               reg = <0x58>;
+                       };
+               };
+       };
+};
+
+&i2c9 {
+       status = "okay";
+};
+
+&vuart {
+       status = "okay";
+};
+
+&gfx {
+       status = "okay";
+};
+
+&pinctrl {
+       aspeed,external-nodes = <&gfx &lhc>;
+};
+
+&gpio {
+       pin_gpio_c7 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(C, 7) GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "BIOS_SPI_MUX_S";
+       };
+       pin_gpio_d1 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "PHY2_RESET_N";
+       };
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
new file mode 100644 (file)
index 0000000..f8e7b71
--- /dev/null
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Facebook Inc.
+// Author: Vijay Khemka <vijaykhemka@fb.com>
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+       model = "Facebook TiogaPass BMC";
+       compatible = "facebook,tiogapass-bmc", "aspeed,ast2500";
+       aliases {
+               serial0 = &uart1;
+               serial4 = &uart5;
+       };
+       chosen {
+               stdout-path = &uart5;
+               bootargs = "console=ttyS4,115200 earlyprintk";
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+       };
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+#include "openbmc-flash-layout.dtsi"
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "pnor";
+       };
+};
+
+&uart1 {
+       // Host Console
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                    &pinctrl_rxd1_default>;
+};
+
+&uart5 {
+       // BMC Console
+       status = "okay";
+};
+
+&mac0 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii1_default>;
+       use-ncsi;
+};
+
+&i2c0 {
+       status = "okay";
+       //Airmax Conn B, CPU0 PIROM, CPU1 PIROM
+};
+
+&i2c1 {
+       status = "okay";
+       //X24 Riser
+};
+
+&i2c2 {
+       status = "okay";
+       // Mezz Management SMBus
+};
+
+&i2c3 {
+       status = "okay";
+       // SMBus to Board ID EEPROM
+};
+
+&i2c4 {
+       status = "okay";
+       // BMC Debug Header
+};
+
+&i2c5 {
+       status = "okay";
+       // CPU Voltage regulators
+};
+
+&i2c6 {
+       status = "okay";
+       tpm@20 {
+               compatible = "infineon,slb9645tt";
+               reg = <0x20>;
+       };
+       tmp421@4e {
+               compatible = "ti,tmp421";
+               reg = <0x4e>;
+       };
+       tmp421@4f {
+               compatible = "ti,tmp421";
+               reg = <0x4f>;
+       };
+       eeprom@54 {
+               compatible = "atmel,24c64";
+               reg = <0x54>;
+               pagesize = <32>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+       //HSC, AirMax Conn A
+};
+
+&i2c8 {
+       status = "okay";
+       //Mezz Sensor SMBus
+};
+
+&i2c9 {
+       status = "okay";
+       //USB Debug Connector
+};
+
+&pwm_tacho {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>;
+       fan@0 {
+               reg = <0x00>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+       };
+
+       fan@1 {
+               reg = <0x00>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x01>;
+       };
+};
index 76aa6ea1f9883460f3a311addc6ba09b09a8fb6a..385c0f4b69ee40551d5370acd0eb0321cf754dbb 100644 (file)
@@ -7,6 +7,25 @@
        model = "Quanta Q71L BMC";
        compatible = "quanta,q71l-bmc", "aspeed,ast2400";
 
+       aliases {
+               i2c14 = &i2c_pcie2;
+               i2c15 = &i2c_pcie3;
+               i2c16 = &i2c_pcie6;
+               i2c17 = &i2c_pcie7;
+               i2c18 = &i2c_pcie1;
+               i2c19 = &i2c_pcie4;
+               i2c20 = &i2c_pcie5;
+               i2c21 = &i2c_pcie8;
+               i2c22 = &i2c_pcie9;
+               i2c23 = &i2c_pcie10;
+               i2c24 = &i2c_ssd1;
+               i2c25 = &i2c_ssd2;
+               i2c26 = &i2c_psu4;
+               i2c27 = &i2c_psu1;
+               i2c28 = &i2c_psu3;
+               i2c29 = &i2c_psu2;
+       };
+
        chosen {
                stdout-path = &uart5;
                bootargs = "console=ttyS4,115200 earlyprintk";
                        &pinctrl_ddcclk_default &pinctrl_ddcdat_default>;
 };
 
+&ibt {
+       status = "okay";
+};
+
 &lpc_snoop {
        status = "okay";
        snoop-ports = <0x80>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0>;
+
+                       psu@59 {
+                               compatible = "pmbus";
+                               reg = <0x59>;
+                       };
                };
 
                i2c_psu1: i2c@1 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <1>;
+
+                       psu@58 {
+                               compatible = "pmbus";
+                               reg = <0x58>;
+                       };
                };
 
                i2c_psu3: i2c@2 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <2>;
+
+                       psu@58 {
+                               compatible = "pmbus";
+                               reg = <0x58>;
+                       };
                };
 
                i2c_psu2: i2c@3 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <3>;
+
+                       psu@59 {
+                               compatible = "pmbus";
+                               reg = <0x59>;
+                       };
                };
        };
 
        status = "okay";
 };
 
+&adc {
+       status = "okay";
+};
+
 &pwm_tacho {
        status = "okay";
 
index b23a983f95a5379f9224d3dd602a1e2ee0df094d..69f6b9d2e7e7de67ad887ff844bd6d315a87e7a6 100644 (file)
                                status = "disabled";
                        };
 
-                       i2c: i2c@1e78a000 {
+                       i2c: bus@1e78a000 {
                                compatible = "simple-bus";
                                #address-cells = <1>;
                                #size-cells = <1>;
index 87fdc146ff525af94c8db648f8f46b8c3c1084d4..d107459fc0f89417f7d7adde30d0155da86dc929 100644 (file)
                                status = "disabled";
                        };
 
-                       i2c: i2c@1e78a000 {
+                       i2c: bus@1e78a000 {
                                compatible = "simple-bus";
                                #address-cells = <1>;
                                #size-cells = <1>;
index bb86f17ed5ed1ba476056c434039ebf142f2bc6b..21876da7c44250c752c28983e894fa2f536352cc 100644 (file)
@@ -70,9 +70,9 @@
 &i2c1 {
        status = "okay";
 
-       eeprom@87 {
+       eeprom@57 {
                compatible = "giantec,gt24c32a", "atmel,24c32";
-               reg = <87>;
+               reg = <0x57>;
                pagesize = <32>;
        };
 };
index 4b9176dc5d029ff025f400b434e89868da7b1191..df0f0cc575c181006936cba2a78f03a61d3f5e9a 100644 (file)
@@ -59,9 +59,9 @@
 &i2c1 {
        status = "okay";
 
-       ft5426@56 {
+       ft5426@38 {
                compatible = "focaltech,ft5426", "edt,edt-ft5406";
-               reg = <56>;
+               reg = <0x38>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_lcd_ctp_int>;
 
index af9f38456d04e7a41964f400504f799140c6c760..911d2c7c1500ff831bc98ae6f9730de4f2638ad1 100644 (file)
        compatible = "axentia,nattis-2", "axentia,natte-2", "axentia,linea",
                     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
 
-       ahb {
-               apb {
-                       pinctrl@fffff200 {
-                               nattis {
-                                       pinctrl_usba_vbus: usba_vbus {
-                                               atmel,pins =
-                                                       <AT91_PIOD 28
-                                                        AT91_PERIPH_GPIO
-                                                        AT91_PINCTRL_DEGLITCH>;
-                                       };
-
-                                       pinctrl_mmc0_cd: mmc0_cd {
-                                               atmel,pins =
-                                                       <AT91_PIOD 5
-                                                        AT91_PERIPH_GPIO
-                                                        AT91_PINCTRL_PULL_UP_DEGLITCH>;
-                                       };
-
-                                       pinctrl_lcd_prlud0: lcd_prlud0 {
-                                               atmel,pins =
-                                                       <AT91_PIOA 21
-                                                        AT91_PERIPH_GPIO
-                                                        AT91_PINCTRL_OUTPUT_VAL(0)>;
-                                       };
-
-                                       pinctrl_lcd_hipow0: lcd_hipow0 {
-                                               atmel,pins =
-                                                       <AT91_PIOA 23
-                                                        AT91_PERIPH_GPIO
-                                                        AT91_PINCTRL_OUTPUT_VAL(0)>;
-                                       };
-                               };
-                       };
-
-                       watchdog@fffffe40 {
-                               status = "okay";
-                       };
-               };
-       };
-
        gpio-keys {
                compatible = "gpio-keys";
 
        };
 
        panel: panel {
-               compatible = "sharp,lq150x1lg11";
+               compatible = "sharp,lq150x1lg11", "panel-lvds";
+
                backlight = <&panel_bl>;
                power-supply = <&panel_reg>;
 
+               width-mm = <304>;
+               height-mm = <228>;
+
+               data-mapping = "jeida-18";
+
+               panel-timing {
+                       // 1024x768 @ 60Hz (typical)
+                       clock-frequency = <50000000 65000000 80000000>;
+                       hactive = <1024>;
+                       vactive = <768>;
+                       hfront-porch = <48 88 88>;
+                       hback-porch = <96 168 168>;
+                       hsync-len = <32 64 64>;
+                       vsync-len = <3 13 74>;
+                       vfront-porch = <3 13 74>;
+                       vback-porch = <3 12 74>;
+               };
+
                port {
                        panel_input: endpoint {
                                remote-endpoint = <&lvds_encoder_output>;
        };
 
        lvds-encoder {
-               compatible = "lvds-encoder";
+               compatible = "ti,ds90c185", "lvds-encoder";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_lvds_prlud0 &pinctrl_lvds_hipow0>;
 
                ports {
                        #address-cells = <1>;
        };
 };
 
+&pinctrl {
+       nattis {
+               pinctrl_usba_vbus: usba_vbus {
+                       atmel,pins = <AT91_PIOD 28 AT91_PERIPH_GPIO
+                                     AT91_PINCTRL_DEGLITCH>;
+               };
+
+               pinctrl_mmc0_cd: mmc0_cd {
+                       atmel,pins = <AT91_PIOD  5 AT91_PERIPH_GPIO
+                                     AT91_PINCTRL_PULL_UP_DEGLITCH>;
+               };
+
+               pinctrl_lvds_prlud0: lvds_prlud0 {
+                       atmel,pins = <AT91_PIOA 21 AT91_PERIPH_GPIO
+                                     (AT91_PINCTRL_OUTPUT |
+                                      AT91_PINCTRL_OUTPUT_VAL(0))>;
+               };
+
+               pinctrl_lvds_hipow0: lvds_hipow0 {
+                       atmel,pins = <AT91_PIOA 23 AT91_PERIPH_GPIO
+                                     (AT91_PINCTRL_OUTPUT |
+                                      AT91_PINCTRL_OUTPUT_VAL(0))>;
+               };
+       };
+};
+
+&watchdog {
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
 
 
        hlcdc-display-controller {
                pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_lcd_base
-                            &pinctrl_lcd_rgb565
-                            &pinctrl_lcd_prlud0
-                            &pinctrl_lcd_hipow0>;
+               pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb565>;
 
                port@0 {
                        hlcdc_output: endpoint {
                                remote-endpoint = <&lvds_encoder_input>;
+                               bus-width = <16>;
                        };
                };
        };
                reg = <0>;
                bus-width = <4>;
                cd-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+               cd-inverted;
        };
 };
 
index e86e0c00eb6b19ed7ac104a76d2d65fe6811bda4..363a43d77424272529a39fff8346616281e7a0da 100644 (file)
                                status = "okay";
                        };
 
+                       adc: adc@fc030000 {
+                               vddana-supply = <&vddana>;
+                               vref-supply = <&advref>;
+
+                               status = "disabled";
+                       };
+
                        pinctrl@fc038000 {
 
                                pinctrl_can1_default: can1_default {
                        linux,default-trigger = "heartbeat";
                };
        };
+
+       vddin_3v3: fixed-regulator-vddin_3v3 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "VDDIN_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               status = "okay";
+       };
+
+       vddana: fixed-regulator-vddana {
+               compatible = "regulator-fixed";
+
+               regulator-name = "VDDANA";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vddin_3v3>;
+               status = "okay";
+       };
+
+       advref: fixed-regulator-advref {
+               compatible = "regulator-fixed";
+
+               regulator-name = "advref";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vddana>;
+               status = "okay";
+       };
 };
index 3b1baa8605a77e8f724724550e5ec123df608732..2214bfe7aa205f624c7ad485ae88f0d3ef8a15fa 100644 (file)
                                                        reg = <0x40000 0xc0000>;
                                                };
 
-                                               bootloaderenv@0x100000 {
-                                                       label = "bootloader env";
+                                               bootloaderenvred@0x100000 {
+                                                       label = "bootloader env redundant";
                                                        reg = <0x100000 0x40000>;
                                                };
 
-                                               bootloaderenvred@0x140000 {
-                                                       label = "bootloader env redundant";
+                                               bootloaderenv@0x140000 {
+                                                       label = "bootloader env";
                                                        reg = <0x140000 0x40000>;
                                                };
 
index fcc85d70f36ec6009c5c2ba0a59167f3479f278f..518e2b095ccfdadff77444b1c4baf621478d55fc 100644 (file)
                                status = "okay";
                        };
 
+                       i2s0: i2s@f8050000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_i2s0_default>;
+                               status = "disabled"; /* conflict with can0 */
+                       };
+
                        can0: can@f8054000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_can0_default>;
                                        bias-disable;
                                };
 
+                               pinctrl_i2s0_default: i2s0_default {
+                                       pinmux = <PIN_PC1__I2SC0_CK>,
+                                                <PIN_PC2__I2SC0_MCK>,
+                                                <PIN_PC3__I2SC0_WS>,
+                                                <PIN_PC4__I2SC0_DI0>,
+                                                <PIN_PC5__I2SC0_DO0>;
+                                       bias-disable;
+                               };
+
+                               pinctrl_i2s1_default: i2s1_default {
+                                       pinmux = <PIN_PA15__I2SC1_CK>,
+                                                <PIN_PA14__I2SC1_MCK>,
+                                                <PIN_PA16__I2SC1_WS>,
+                                                <PIN_PA17__I2SC1_DI0>,
+                                                <PIN_PA18__I2SC1_DO0>;
+                                       bias-disable;
+                               };
+
                                pinctrl_key_gpio_default: key_gpio_default {
                                        pinmux = <PIN_PB9__GPIO>;
                                        bias-pull-up;
                                status = "okay";
                        };
 
+                       i2s1: i2s@fc04c000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_i2s1_default>;
+                               status = "disabled"; /* conflict with spi0, sdmmc1 */
+                       };
+
                        can1: can@fc050000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_can1_default>;
index 02c1d2958d7809e597c630fc15270f4da965311f..322a744e4363374e4dbc10f6c54d0cbd59a2320c 100644 (file)
 
                                                bootloader@40000 {
                                                        label = "bootloader";
-                                                       reg = <0x40000 0x80000>;
+                                                       reg = <0x40000 0xc0000>;
                                                };
 
-                                               bootloaderenv@c0000 {
+                                               bootloaderenvred@100000 {
+                                                       label = "bootloader env redundant";
+                                                       reg = <0x100000 0x40000>;
+                                               };
+
+                                               bootloaderenv@140000 {
                                                        label = "bootloader env";
-                                                       reg = <0xc0000 0xc0000>;
+                                                       reg = <0x140000 0x40000>;
                                                };
 
                                                dtb@180000 {
index 4b7c762d5f2236678f769808e60233ba6b66aa3a..43aef56ac74a3e5aeb34a5bf0376fb82f29fc3c2 100644 (file)
 
                                                bootloader@40000 {
                                                        label = "bootloader";
-                                                       reg = <0x40000 0x80000>;
+                                                       reg = <0x40000 0xc0000>;
                                                };
 
-                                               bootloaderenv@c0000 {
+                                               bootloaderenvred@100000 {
+                                                       label = "bootloader env redundant";
+                                                       reg = <0x100000 0x40000>;
+                                               };
+
+                                               bootloaderenv@140000 {
                                                        label = "bootloader env";
-                                                       reg = <0xc0000 0xc0000>;
+                                                       reg = <0x140000 0x40000>;
                                                };
 
                                                dtb@180000 {
 
                                                rootfs@800000 {
                                                        label = "rootfs";
-                                                       reg = <0x800000 0x0f800000>;
+                                                       reg = <0x800000 0x1f800000>;
                                                };
                                        };
                                };
index 2fbec69d9cd68f62ac1140e3e52a96a0fa3097ff..fe8876eaf917930d46709edf98463b77b5ce1aa4 100644 (file)
        compatible = "axentia,tse850v3", "axentia,linea",
                     "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
 
-       ahb {
-               apb {
-                       pinctrl@fffff200 {
-                               tse850 {
-                                       pinctrl_usba_vbus: usba-vbus {
-                                               atmel,pins =
-                                                       <AT91_PIOC 31
-                                                        AT91_PERIPH_GPIO
-                                                        AT91_PINCTRL_DEGLITCH>;
-                                       };
-                               };
-                       };
-
-                       watchdog@fffffe40 {
-                               status = "okay";
-                       };
-               };
-       };
-
        sck: oscillator {
                compatible = "fixed-clock";
 
        };
 };
 
+&pinctrl {
+       tse850 {
+               pinctrl_usba_vbus: usba-vbus {
+                       atmel,pins = <AT91_PIOC 31 AT91_PERIPH_GPIO
+                                     AT91_PINCTRL_DEGLITCH>;
+               };
+       };
+};
+
+&watchdog {
+       status = "okay";
+};
+
 &usart0 {
        status = "okay";
 
index 1be9889a2b3a1eb7c40a7c74287910b4f4c616ed..430277291e025fb17c31cebf49173ffaadab55ea 100644 (file)
                        i2c2: i2c@f8024000 {
                                status = "okay";
 
-                               rtc1: rtc@64 {
+                               rtc1: rtc@32 {
                                        compatible = "epson,rx8900";
                                        reg = <0x32>;
                                };
index d2b865f6029322e296133e97e7df4aa3b5127c3c..07d1b571e6017b27a29b7acb7d5e72499baba1c4 100644 (file)
 
                        spi0: spi@fffc8000 {
                                cs-gpios = <0>, <&pioC 11 0>, <0>, <0>;
-                               mtd_dataflash@0 {
+                               mtd_dataflash@1 {
                                        compatible = "atmel,at45", "atmel,dataflash";
                                        spi-max-frequency = <50000000>;
                                        reg = <1>;
index a29fc0494076244576166cc8bf40c123296fac9e..a57f2d435dcae8324c7001942098e55e0aabe267 100644 (file)
                                        spi-max-frequency = <15000000>;
                                };
 
-                               tsc2046@0 {
+                               tsc2046@2 {
                                        reg = <2>;
                                        compatible = "ti,ads7843";
                                        interrupts-extended = <&pioC 2 IRQ_TYPE_EDGE_BOTH>;
index 71df3adfc7ca1b5684b39947588f6831de90111d..ec1f17ab6753b64211e0030b6725a0099d2c5590 100644 (file)
 
                        spi0: spi@fffc8000 {
                                cs-gpios = <0>, <&pioC 11 0>, <0>, <0>;
-                               mtd_dataflash@0 {
+                               mtd_dataflash@1 {
                                        compatible = "atmel,at45", "atmel,dataflash";
                                        spi-max-frequency = <50000000>;
                                        reg = <1>;
index 1ee25a475be87ff452287d1adfda8e1644a71a27..d16db1fa7e15c69dba0060dfc647211e440f607d 100644 (file)
                                        };
                                };
 
-                               uart1 {
+                               usart1 {
                                        pinctrl_usart1: usart1-0 {
                                                atmel,pins =
                                                        <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE
index 4908ee07e62876967eb946a95b80e02797a8acf9..c4cc9cc945faf5c6982f68f2de8fca013abf778c 100644 (file)
 
                                                uboot@40000 {
                                                        label = "u-boot";
-                                                       reg = <0x40000 0x80000>;
+                                                       reg = <0x40000 0xc0000>;
                                                };
 
-                                               ubootenv@c0000 {
+                                               ubootenvred@100000 {
+                                                       label = "U-Boot Env Redundant";
+                                                       reg = <0x100000 0x40000>;
+                                               };
+
+                                               ubootenv@140000 {
                                                        label = "U-Boot Env";
-                                                       reg = <0xc0000 0x140000>;
+                                                       reg = <0x140000 0x40000>;
+                                               };
+
+                                               dtb@180000 {
+                                                       label = "device tree";
+                                                       reg = <0x180000 0x80000>;
                                                };
 
                                                kernel@200000 {
 
                                                rootfs@800000 {
                                                        label = "rootfs";
-                                                       reg = <0x800000 0x1f800000>;
+                                                       reg = <0x800000 0x0f800000>;
                                                };
                                        };
                                };
index 3084a7c957339f0edc2fef97d203b08635c96790..e4d49731287f693ae94c39239b5d51bac1bfc46c 100644 (file)
                        reg = <0x33000 0x14>;
                };
 
-               qspi: qspi@27200 {
+               qspi: spi@27200 {
                        compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi";
                        reg = <0x027200 0x184>,
                              <0x027000 0x124>,
index 09ba8504632284532e3b17c6d1531e2d732fadc4..2fd111d9d59c56e087fc1af317806a2d1f438435 100644 (file)
                        brcm,nand-has-wp;
                };
 
-               qspi: qspi@27200 {
+               qspi: spi@27200 {
                        compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi";
                        reg = <0x027200 0x184>,
                              <0x027000 0x124>,
 
                srab: srab@36000 {
                        compatible = "brcm,nsp-srab";
-                       reg = <0x36000 0x1000>;
+                       reg = <0x36000 0x1000>,
+                             <0x3f308 0x8>,
+                             <0x3f410 0xc>;
+                       reg-names = "srab", "mux_config", "sgmii";
+                       interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "link_state_p0",
+                                         "link_state_p1",
+                                         "link_state_p2",
+                                         "link_state_p3",
+                                         "link_state_p4",
+                                         "link_state_p5",
+                                         "link_state_p7",
+                                         "link_state_p8",
+                                         "phy",
+                                         "ts",
+                                         "imp_sleep_timer_p5",
+                                         "imp_sleep_timer_p7",
+                                         "imp_sleep_timer_p8";
                        #address-cells = <1>;
                        #size-cells = <0>;
 
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts b/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
new file mode 100644 (file)
index 0000000..6c8233a
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2837-rpi-cm3.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
+
+/ {
+       compatible = "raspberrypi,3-compute-module", "brcm,bcm2837";
+       model = "Raspberry Pi Compute Module 3 IO board V3.0";
+};
+
+&gpio {
+       /*
+        * This is based on the official GPU firmware DT blob.
+        *
+        * Legend:
+        * "NC" = not connected (no rail from the SoC)
+        * "FOO" = GPIO line named "FOO" on the schematic
+        * "FOO_N" = GPIO line named "FOO" on schematic, active low
+        */
+       gpio-line-names = "GPIO0",
+                         "GPIO1",
+                         "GPIO2",
+                         "GPIO3",
+                         "GPIO4",
+                         "GPIO5",
+                         "GPIO6",
+                         "GPIO7",
+                         "GPIO8",
+                         "GPIO9",
+                         "GPIO10",
+                         "GPIO11",
+                         "GPIO12",
+                         "GPIO13",
+                         "GPIO14",
+                         "GPIO15",
+                         "GPIO16",
+                         "GPIO17",
+                         "GPIO18",
+                         "GPIO19",
+                         "GPIO20",
+                         "GPIO21",
+                         "GPIO22",
+                         "GPIO23",
+                         "GPIO24",
+                         "GPIO25",
+                         "GPIO26",
+                         "GPIO27",
+                         "GPIO28",
+                         "GPIO29",
+                         "GPIO30",
+                         "GPIO31",
+                         "GPIO32",
+                         "GPIO33",
+                         "GPIO34",
+                         "GPIO35",
+                         "GPIO36",
+                         "GPIO37",
+                         "GPIO38",
+                         "GPIO39",
+                         "GPIO40",
+                         "GPIO41",
+                         "GPIO42",
+                         "GPIO43",
+                         "GPIO44",
+                         "GPIO45",
+                         "GPIO46",
+                         "GPIO47",
+                         /* Used by eMMC */
+                         "SD_CLK_R",
+                         "SD_CMD_R",
+                         "SD_DATA0_R",
+                         "SD_DATA1_R",
+                         "SD_DATA2_R",
+                         "SD_DATA3_R";
+
+       pinctrl-0 = <&gpioout &alt0>;
+};
+
+&hdmi {
+       hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_gpio14>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
new file mode 100644 (file)
index 0000000..7b7ab6a
--- /dev/null
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2837.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+       memory {
+               reg = <0 0x40000000>;
+       };
+
+       reg_3v3: fixed-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_1v8: fixed-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+};
+
+&firmware {
+       expgpio: gpio {
+               compatible = "raspberrypi,firmware-gpio";
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-line-names = "HDMI_HPD_N",
+                                 "EMMC_EN_N",
+                                 "NC",
+                                 "NC",
+                                 "NC",
+                                 "NC",
+                                 "NC",
+                                 "NC";
+               status = "okay";
+       };
+};
+
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       vmmc-supply = <&reg_3v3>;
+       vqmmc-supply = <&reg_1v8>;
+       status = "okay";
+};
index 9403da0990d07b8f021096ff01b86d660aa36efb..70bece63f9a741d5f4cc4f501905bcab46b8b9c1 100644 (file)
@@ -1,4 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/net/microchip-lan78xx.h>
+
 / {
        aliases {
                ethernet0 = &ethernet;
                        ethernet: ethernet@1 {
                                compatible = "usb424,7800";
                                reg = <1>;
+
+                               mdio {
+                                       #address-cells = <0x1>;
+                                       #size-cells = <0x0>;
+                                       eth_phy: ethernet-phy@1 {
+                                               reg = <1>;
+                                               microchip,led-modes = <
+                                                       LAN78XX_LINK_1000_ACTIVITY
+                                                       LAN78XX_LINK_10_100_ACTIVITY
+                                               >;
+                                       };
+                               };
                        };
                };
        };
index 5f663f848db1fabb66c0fd8eb376f9601481296a..189cc3dcd6ef869065ea3dc9b633d92d062c6efd 100644 (file)
 
 &spi_nor {
        status = "okay";
+
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               boot@0 {
+                       label = "boot";
+                       reg = <0x000000 0x040000>;
+                       read-only;
+               };
+
+               os-image@100000 {
+                       label = "os-image";
+                       reg = <0x040000 0x200000>;
+                       compatible = "brcm,trx";
+               };
+
+               rootfs@240000 {
+                       label = "rootfs";
+                       reg = <0x240000 0xc00000>;
+               };
+
+               nvram@ff0000 {
+                       label = "nvram";
+                       reg = <0xff0000 0x010000>;
+               };
+       };
 };
 
 &usb2 {
index 2033411240c78ce9ffdf0c70d36a7b9b3dbfb703..4cb10f88a95eafc1e51c501d4591704a4256a971 100644 (file)
 &usb3_phy {
        status = "okay";
 };
+
+&nandcs {
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               boot@0 {
+                       label = "boot";
+                       reg = <0x00000000 0x00080000>;
+                       read-only;
+               };
+
+               nvram@80000 {
+                       label = "nvram";
+                       reg = <0x00080000 0x00180000>;
+               };
+
+               firmware@200000 {
+                       label = "firmware";
+                       reg = <0x00200000 0x07cc0000>;
+                       compatible = "brcm,trx";
+               };
+
+               asus@7ec0000 {
+                       label = "asus";
+                       reg = <0x07ec0000 0x00140000>;
+                       read-only;
+               };
+       };
+};
index c7143a9daa1a961c1c013ec688c5c15c9dd4d127..b527d2ff987ed36b4564245974375b84b9617f06 100644 (file)
 
 &spi_nor {
        status = "okay";
+
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               boot@0 {
+                       label = "boot";
+                       reg = <0x000000 0x040000>;
+                       read-only;
+               };
+
+               os-image@100000 {
+                       label = "os-image";
+                       reg = <0x040000 0x200000>;
+                       compatible = "brcm,trx";
+               };
+
+               rootfs@240000 {
+                       label = "rootfs";
+                       reg = <0x240000 0xc00000>;
+               };
+
+               nvram@ff0000 {
+                       label = "nvram";
+                       reg = <0xff0000 0x010000>;
+               };
+       };
 };
 
 &usb3_phy {
index e5a2d62daf9267c990c9a79bc9ae466568f1bd9a..925a7c9ce5b7f42bdd21525b566bd3bc5c7aa240 100644 (file)
                        reg = <0>;
                        #address-cells = <1>;
                        #size-cells = <1>;
+
+                       partitions {
+                               compatible = "brcm,bcm947xx-cfe-partitions";
+                       };
                };
        };
 };
index bc607d11eef8e958f654ced7c22e7a409a5fbdff..7a5c188c2676a140aeb542750b25463b0c2d71b3 100644 (file)
                        compatible = "jedec,spi-nor";
                        reg = <0>;
                        spi-max-frequency = <20000000>;
-                       linux,part-probe = "ofpart", "bcm47xxpart";
                        status = "disabled";
+
+                       partitions {
+                               compatible = "brcm,bcm947xx-cfe-partitions";
+                       };
                };
        };
 
index ea3fc194f8f37ea4bea411922372eac32e82852e..a53a2f629d74198a5c3f4e5d27f0ba5954c0950a 100644 (file)
                open-source;
                priority = <200>;
        };
+
+       /* Hardware I2C block cannot do more than 63 bytes per transfer,
+        * which would prevent reading from a SFP's EEPROM (256 byte).
+        */
+       i2c1: i2c {
+               compatible = "i2c-gpio";
+               sda-gpios = <&gpioa 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&gpioa 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       };
+
+       sfp: sfp {
+               compatible = "sff,sfp";
+               i2c-bus = <&i2c1>;
+               mod-def0-gpios = <&gpioa 28 GPIO_ACTIVE_LOW>;
+               los-gpios = <&gpioa 24 GPIO_ACTIVE_HIGH>;
+               tx-fault-gpios = <&gpioa 30 GPIO_ACTIVE_HIGH>;
+               tx-disable-gpios = <&gpioa 26 GPIO_ACTIVE_HIGH>;
+       };
 };
 
 &amac0 {
                        reg = <4>;
                };
 
+               port@5 {
+                       label = "sfp";
+                       phy-mode = "sgmii";
+                       reg = <5>;
+                       sfp = <&sfp>;
+                       managed = "in-band-status";
+               };
+
                port@8 {
                        ethernet = <&amac2>;
                        label = "cpu";
index f9b75790584503a70a4a4a95c2cc04b70cf6e9e0..a3c9b346721d4fa3422c703b7204ba70e6466f21 100644 (file)
                gpio-controller;
                #gpio-cells = <2>;
        };
+       tca6416_bb: gpio@21 {
+               compatible = "ti,tca6416";
+               reg = <0x21>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
 };
 
 &wdt {
index c4729d0e6c196e73b635d8499ec8f2108429ee31..66fcadf0ba9105aec70aefcbacc6f38416b7749f 100644 (file)
                compatible = "ti,ads7957";
                reg = <3>;
                #io-channel-cells = <1>;
-               spi-max-frequency = <10000000>;
+               spi-max-frequency = <1000000>;
+               ti,spi-wdelay = <63>;
                vref-supply = <&adc_ref>;
        };
 };
index 85d7b5148b0ac6c6fc0009b72dac20c89ee16271..2d201719ba6968618ca6b4377c9e4efc281f9bd8 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
 };
 
+&davinci_mdio {
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &gpmc {
        ranges = <0 0 0x04000000 0x01000000>;   /* CS0: 16MB for NAND */
 
index c46a227b543dd9af35afabe29bf0f33890df1fd5..63301bcacf19ac00e0172de02f3b25f46c05aed8 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
 };
 
+&davinci_mdio {
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc1 {
        status = "disabled";
 };
index 580e3cbcfbf7cf8fe83a6479a147d763bafa46b3..3e1584e787aec8c59e02cf0d4e05a6d240dffc0a 100644 (file)
@@ -87,7 +87,7 @@
        status = "okay";
        clock-frequency = <100000>;
 
-       si5351: clock-generator {
+       si5351: clock-generator@60 {
                compatible = "silabs,si5351a-msop";
                reg = <0x60>;
                #address-cells = <1>;
index 4a0a5115b298436dc76180bc74f1d1372d3163a5..250ad0535e8cc642429dc45a2c9401f987bebf41 100644 (file)
                                  0xffffe000 MBUS_ID(0x03, 0x01) 0 0x0000800   /* CESA SRAM  2k */
                                  0xfffff000 MBUS_ID(0x0d, 0x00) 0 0x0000800>; /* PMU  SRAM  2k */
 
-                       spi0: spi-ctrl@10600 {
+                       spi0: spi@10600 {
                                compatible = "marvell,orion-spi";
                                #address-cells = <1>;
                                #size-cells = <0>;
                                status = "disabled";
                        };
 
-                       i2c: i2c-ctrl@11000 {
+                       i2c: i2c@11000 {
                                compatible = "marvell,mv64xxx-i2c";
                                reg = <0x11000 0x20>;
                                #address-cells = <1>;
                                status = "disabled";
                        };
 
-                       spi1: spi-ctrl@14600 {
+                       spi1: spi@14600 {
                                compatible = "marvell,orion-spi";
                                #address-cells = <1>;
                                #size-cells = <0>;
index 31b824ad5d29fa822ffba094a8151fd0789369dc..906aedde045d434a18cb92b7a31b33f7b7051209 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
 };
 
+&davinci_mdio {
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+
+       ethphy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &gpmc {
        ranges = <0 0 0x04000000 0x01000000>;   /* CS0: 16MB for NAND */
 
index 6ed5f915627000010fe9883259c18cb132fd7c96..cc079064a23b1362782b8fb6d6e4fb472cdeab54 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <2>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <3>;
+       phy-handle = <&ethphy1>;
        phy-mode = "rgmii";
        dual_emac_res_vlan = <2>;
 };
 
+&davinci_mdio {
+       ethphy0: ethernet-phy@2 {
+               reg = <2>;
+       };
+
+       ethphy1: ethernet-phy@3 {
+               reg = <3>;
+       };
+};
+
 &dcan1 {
        status = "ok";
        pinctrl-names = "default", "sleep", "active";
index a0ddf497e8cddcd2fd1c906244167bc373be93e3..7ce24b282d421a585b2b264f219d0c541576492c 100644 (file)
                                                <0 0 0 2 &pcie1_intc 2>,
                                                <0 0 0 3 &pcie1_intc 3>,
                                                <0 0 0 4 &pcie1_intc 4>;
+                               ti,syscon-unaligned-access = <&scm_conf1 0x14 1>;
                                status = "disabled";
                                pcie1_intc: interrupt-controller {
                                        interrupt-controller;
                                ti,hwmods = "pcie1";
                                phys = <&pcie1_phy>;
                                phy-names = "pcie-phy0";
-                               ti,syscon-unaligned-access = <&scm_conf1 0x14 2>;
+                               ti,syscon-unaligned-access = <&scm_conf1 0x14 1>;
                                status = "disabled";
                        };
                };
                                                <0 0 0 2 &pcie2_intc 2>,
                                                <0 0 0 3 &pcie2_intc 3>,
                                                <0 0 0 4 &pcie2_intc 4>;
+                               ti,syscon-unaligned-access = <&scm_conf1 0x14 2>;
                                pcie2_intc: interrupt-controller {
                                        interrupt-controller;
                                        #address-cells = <0>;
                        status = "disabled";
                };
 
-               qspi: qspi@4b300000 {
+               qspi: spi@4b300000 {
                        compatible = "ti,dra7xxx-qspi";
                        reg = <0x4b300000 0x100>,
                              <0x5c000000 0x4000000>;
index c471bf3277b4fd2aeb6077eb3ad4470c14b87187..82cc7ec37af0a3204f32241642568f31272e7be8 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <2>;
+       phy-handle = <&dp83867_0>;
        phy-mode = "rgmii-id";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <3>;
+       phy-handle = <&dp83867_1>;
        phy-mode = "rgmii-id";
        dual_emac_res_vlan = <2>;
 };
index bf588d00728d1973c3426f09421dc5c2bbb5bbe0..fafc2a4d7bb90082f2b0f0b8ed22d9954fc6e3a4 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <2>;
+       phy-handle = <&dp83867_0>;
        phy-mode = "rgmii-id";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <3>;
+       phy-handle = <&dp83867_1>;
        phy-mode = "rgmii-id";
        dual_emac_res_vlan = <2>;
 };
index c572693b16657b69565b3581ac39c9bd8298cba2..154b0a0ceb18e1f4a684ac660d8bed92fd7044a2 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <3>;
+       phy-handle = <&ethphy0>;
        phy-mode = "rgmii";
 };
 
+&davinci_mdio {
+       ethphy0: ethernet-phy@3 {
+               reg = <3>;
+       };
+};
+
 &mmc1 {
        pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104";
        pinctrl-0 = <&mmc1_pins_default>;
index 5a46163d465f5180b0b220c1feea4fc40e6a54a3..8a57895fd8f3c5c1e64a09df9df80eeb2d86aace 100644 (file)
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <2>;
+       phy-handle = <&dp83867_0>;
        phy-mode = "rgmii-id";
        dual_emac_res_vlan = <1>;
 };
 
 &cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <3>;
+       phy-handle = <&dp83867_1>;
        phy-mode = "rgmii-id";
        dual_emac_res_vlan = <2>;
 };
index 620b50c19ead93b65ef43794ec3f50d732a0a2db..7c22cbf6f3d41f1d2e1e82538f23899de60be426 100644 (file)
@@ -69,6 +69,8 @@
                compatible = "samsung,s2mps14-pmic";
                interrupt-parent = <&gpx3>;
                interrupts = <5 IRQ_TYPE_NONE>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&s2mps14_irq>;
                reg = <0x66>;
 
                s2mps14_osc: clocks {
                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV3>;
                samsung,pin-val = <1>;
        };
+
+       s2mps14_irq: s2mps14-irq {
+               samsung,pins = "gpx3-5";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
 };
 
 &rtc {
index 2ab99f9f3d0ac2769bf1c504f3926707f59cc012..dd9ec05eb0f795437999b505253f82d1d375b479 100644 (file)
                reg = <0x66>;
                interrupt-parent = <&gpx0>;
                interrupts = <4 IRQ_TYPE_NONE>, <3 IRQ_TYPE_NONE>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&max8997_irq>;
 
                max8997,pmic-buck1-dvs-voltage = <1350000>;
                max8997,pmic-buck2-dvs-voltage = <1100000>;
        };
 };
 
+&pinctrl_1 {
+       max8997_irq: max8997-irq {
+               samsung,pins = "gpx0-3", "gpx0-4";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+};
+
 &sdhci_0 {
        bus-width = <4>;
        pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_cd>;
index 6f1d76cb795157b9947a52e538a1aba8c1595ea7..f9bbc6315cd956699a1691d909e0a48ae117c0fa 100644 (file)
                             regulator-max-microvolt = <1800000>;
                        };
 
+                       tflash_reg: LDO17 {
+                            regulator-name = "VTF_2.8V";
+                            regulator-min-microvolt = <2800000>;
+                            regulator-max-microvolt = <2800000>;
+                       };
+
                        vddq_reg: LDO21 {
                             regulator-name = "VDDQ_M1M2_1.2V";
                             regulator-min-microvolt = <1200000>;
        status = "okay";
 };
 
+&sdhci_2 {
+       bus-width = <4>;
+       pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+       pinctrl-names = "default";
+       vmmc-supply = <&tflash_reg>;
+       cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
 &serial_0 {
        status = "okay";
 };
index 4e6ff97e1ec41840aed2c4705ee1041c1c50aed1..5c3d98654f137bf793cf51c135b2bc41c34a9ae4 100644 (file)
 
        pmic@66 {
                compatible = "national,lp3974";
+               interrupts-extended = <&gpx0 7 0>, <&gpx2 7 0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&lp3974_irq>;
                reg = <0x66>;
 
                max8998,pmic-buck1-default-dvs-idx = <0>;
 };
 
 &pinctrl_1 {
+       lp3974_irq: lp3974-irq {
+               samsung,pins = "gpx0-7", "gpx2-7";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+
        hdmi_hpd: hdmi-hpd {
                samsung,pins = "gpx3-7";
                samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
        pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
        pinctrl-names = "default";
        vmmc-supply = <&ldo5_reg>;
-       cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
 
index c0476c290977439a0274e7ef3ddfbe795c21099f..aed2f2e2b0d1ba9c56fa8784933f997f30ab4400 100644 (file)
 
 &sdhci_2 {
        bus-width = <4>;
-       cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
        pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sdhci2_cd>;
        pinctrl-names = "default";
        vmmc-supply = <&ldo21_reg>;
index a09e46c9dbc04cbedfc626604339d9f4343f242c..2caa3132f34e0644b7faaf6c589084c0b5ff7641 100644 (file)
        pinctrl-names = "default";
        vmmc-supply = <&ldo21_reg>;
        vqmmc-supply = <&ldo4_reg>;
-       cd-gpios = <&gpk2 2 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpk2 2 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
 
index 7a8a5c55701a894359c748562d156c9c52109ff5..7d1f2dc59038d69693697593a2fd3ee649978362 100644 (file)
                };
        };
 
+       panel: panel {
+               compatible = "boe,hv070wsa-100";
+               power-supply = <&vcc_3v3_reg>;
+               enable-gpios = <&gpd1 3 GPIO_ACTIVE_HIGH>;
+               port {
+                       panel_ep: endpoint {
+                               remote-endpoint = <&bridge_out_ep>;
+                       };
+               };
+       };
+
        regulators {
                compatible = "simple-bus";
                #address-cells = <1>;
                        reg = <2>;
                        regulator-name = "hdmi-en";
                };
+
+               vcc_1v2_reg: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "VCC_1V2";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               vcc_1v8_reg: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "VCC_1V8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               vcc_3v3_reg: regulator@5 {
+                       compatible = "regulator-fixed";
+                       reg = <5>;
+                       regulator-name = "VCC_3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
        };
 
        fixed-rate-clocks {
        cpu0-supply = <&buck2_reg>;
 };
 
+&dsi_0 {
+       vddcore-supply = <&ldo8_reg>;
+       vddio-supply = <&ldo10_reg>;
+       samsung,pll-clock-frequency = <24000000>;
+       samsung,burst-clock-frequency = <320000000>;
+       samsung,esc-clock-frequency = <10000000>;
+       status = "okay";
+
+       bridge@0 {
+               reg = <0>;
+               compatible = "toshiba,tc358764";
+               vddc-supply = <&vcc_1v2_reg>;
+               vddio-supply = <&vcc_1v8_reg>;
+               vddlvds-supply = <&vcc_3v3_reg>;
+               reset-gpios = <&gpd1 6 GPIO_ACTIVE_LOW>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               port@1 {
+                       reg = <1>;
+                       bridge_out_ep: endpoint {
+                               remote-endpoint = <&panel_ep>;
+                       };
+               };
+       };
+};
+
 &dp {
        status = "okay";
        samsung,color-space = <0>;
 };
 
 &hdmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_hpd>;
        status = "okay";
-       ddc = <&i2c_2>;
-       hpd-gpios = <&gpx3 7 GPIO_ACTIVE_LOW>;
+       ddc = <&i2c_ddc>;
+       hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
        vdd_osc-supply = <&ldo10_reg>;
        vdd_pll-supply = <&ldo8_reg>;
        vdd-supply = <&ldo8_reg>;
                reg = <0x66>;
                interrupt-parent = <&gpx3>;
                interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&s5m8767_irq>;
 
                vinb1-supply = <&main_dc_reg>;
                vinb2-supply = <&main_dc_reg>;
        };
 };
 
-&i2c_2 {
-       status = "okay";
-       /* used by HDMI DDC */
-       samsung,i2c-sda-delay = <100>;
-       samsung,i2c-max-bus-freq = <66000>;
-};
-
 &i2c_3 {
        status = "okay";
 
        cap-sd-highspeed;
 };
 
+&pinctrl_0 {
+       s5m8767_irq: s5m8767-irq {
+               samsung,pins = "gpx3-2";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+};
+
 &rtc {
        status = "okay";
 };
        status = "okay";
        samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
 };
+
+&soc {
+       /*
+        * For unknown reasons HDMI-DDC does not work with Exynos I2C
+        * controllers. Lets use software I2C over GPIO pins as a workaround.
+        */
+       i2c_ddc: i2c-gpio {
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_gpio_bus>;
+               status = "okay";
+               compatible = "i2c-gpio";
+               gpios = <&gpa0 6 0 /* sda */
+                        &gpa0 7 0 /* scl */
+                       >;
+               i2c-gpio,delay-us = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
index 6ff6dea29d4490f13bdf457b1ee7ecfb96929cfa..d31a68672bfacb3a2f6575c26790db05b5498d6c 100644 (file)
                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
        };
 
+       i2c2_gpio_bus: i2c2-gpio-bus {
+               samsung,pins = "gpa0-6", "gpa0-7";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+               samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+       };
+
        uart2_data: uart2-data {
                samsung,pins = "gpa1-0", "gpa1-1";
                samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
                samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
        };
+
+       hdmi_hpd: hdmi-hpd {
+               samsung,pins = "gpx3-7";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
 };
 
 &pinctrl_1 {
index 0348b1c49a691d373792d2433cf26463803c7b70..7cbfc6f1f4b8fde1c52d9ad3203cfe4504c2aa42 100644 (file)
 
                samsung,model = "Snow-I2S-MAX98090";
                samsung,audio-codec = <&max98090>;
+
+               cpu {
+                       sound-dai = <&i2s0 0>;
+               };
+
+               codec {
+                       sound-dai = <&max98090 0>, <&hdmi>;
+               };
        };
 };
 
@@ -31,6 +39,9 @@
                interrupt-parent = <&gpx0>;
                pinctrl-names = "default";
                pinctrl-0 = <&max98090_irq>;
+               clocks = <&pmu_system_controller 0>;
+               clock-names = "mclk";
+               #sound-dai-cells = <1>;
        };
 };
 
index da163a40af1598c5f2755d588ccf0a5598b578fe..5044f754e6e59afc40fe70d141ce548f07b7ccd2 100644 (file)
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0>;
-                       clock-frequency = <1700000000>;
                        clocks = <&clock CLK_ARM_CLK>;
                        clock-names = "cpu";
-                       clock-latency = <140000>;
-
-                       operating-points = <
-                               1700000 1300000
-                               1600000 1250000
-                               1500000 1225000
-                               1400000 1200000
-                               1300000 1150000
-                               1200000 1125000
-                               1100000 1100000
-                               1000000 1075000
-                                900000 1050000
-                                800000 1025000
-                                700000 1012500
-                                600000 1000000
-                                500000  975000
-                                400000  950000
-                                300000  937500
-                                200000  925000
-                       >;
+                       operating-points-v2 = <&cpu0_opp_table>;
                        #cooling-cells = <2>; /* min followed by max */
                };
                cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <1>;
-                       clock-frequency = <1700000000>;
                        clocks = <&clock CLK_ARM_CLK>;
                        clock-names = "cpu";
-                       clock-latency = <140000>;
-
-                       operating-points = <
-                               1700000 1300000
-                               1600000 1250000
-                               1500000 1225000
-                               1400000 1200000
-                               1300000 1150000
-                               1200000 1125000
-                               1100000 1100000
-                               1000000 1075000
-                                900000 1050000
-                                800000 1025000
-                                700000 1012500
-                                600000 1000000
-                                500000  975000
-                                400000  950000
-                                300000  937500
-                                200000  925000
-                       >;
+                       operating-points-v2 = <&cpu0_opp_table>;
                        #cooling-cells = <2>; /* min followed by max */
                };
        };
 
+       cpu0_opp_table: opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-200000000 {
+                       opp-hz = /bits/ 64 <200000000>;
+                       opp-microvolt = <925000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-300000000 {
+                       opp-hz = /bits/ 64 <300000000>;
+                       opp-microvolt = <937500>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-400000000 {
+                       opp-hz = /bits/ 64 <400000000>;
+                       opp-microvolt = <950000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <975000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-600000000 {
+                       opp-hz = /bits/ 64 <600000000>;
+                       opp-microvolt = <1000000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-700000000 {
+                       opp-hz = /bits/ 64 <700000000>;
+                       opp-microvolt = <1012500>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-800000000 {
+                       opp-hz = /bits/ 64 <800000000>;
+                       opp-microvolt = <1025000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-900000000 {
+                       opp-hz = /bits/ 64 <900000000>;
+                       opp-microvolt = <1050000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <1075000>;
+                       clock-latency-ns = <140000>;
+                       opp-suspend;
+               };
+               opp-1100000000 {
+                       opp-hz = /bits/ 64 <1100000000>;
+                       opp-microvolt = <1100000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <1125000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1300000000 {
+                       opp-hz = /bits/ 64 <1300000000>;
+                       opp-microvolt = <1150000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1400000000 {
+                       opp-hz = /bits/ 64 <1400000000>;
+                       opp-microvolt = <1200000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1500000000 {
+                       opp-hz = /bits/ 64 <1500000000>;
+                       opp-microvolt = <1225000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1600000000 {
+                       opp-hz = /bits/ 64 <1600000000>;
+                       opp-microvolt = <1250000>;
+                       clock-latency-ns = <140000>;
+               };
+               opp-1700000000 {
+                       opp-hz = /bits/ 64 <1700000000>;
+                       opp-microvolt = <1300000>;
+                       clock-latency-ns = <140000>;
+               };
+       };
+
        soc: soc {
                sysram@2020000 {
                        compatible = "mmio-sram";
                        #phy-cells = <0>;
                };
 
+               mipi_phy: video-phy@10040710 {
+                       compatible = "samsung,s5pv210-mipi-video-phy";
+                       reg = <0x10040710 0x100>;
+                       #phy-cells = <1>;
+                       syscon = <&pmu_system_controller>;
+               };
+
+               dsi_0: dsi@14500000 {
+                       compatible = "samsung,exynos4210-mipi-dsi";
+                       reg = <0x14500000 0x10000>;
+                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                       samsung,power-domain = <&pd_disp1>;
+                       phys = <&mipi_phy 3>;
+                       phy-names = "dsim";
+                       clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI1>;
+                       clock-names = "bus_clk", "sclk_mipi";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                adc: adc@12d10000 {
                        compatible = "samsung,exynos-adc-v1";
                        reg = <0x12D10000 0x100>;
index a2046f5f998c1127e722f2ecf34751e05bdac8ba..434a7591ff6397e5f1e397690ecd46f6277e7786 100644 (file)
        samsung,dw-mshc-sdr-timing = <0 4>;
        samsung,dw-mshc-ddr-timing = <0 2>;
        pinctrl-names = "default";
-       pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+       pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4 &sd2_wp>;
        bus-width = <4>;
        cap-sd-highspeed;
        vmmc-supply = <&ldo21_reg>;
                samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
        };
 
+       sd2_wp: sd2-wp {
+               samsung,pins = "gpm5-0";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+               /* Pin is floating so be sure to disable write-protect */
+               samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+       };
+
        pmic_dvs_3: pmic-dvs-3 {
                samsung,pins = "gpx0-0";
                samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
index 57c2332bf28247b354592c0dbe839fa5a8ed6560..f78db6809cca4b3659e1eb8fe490b581afabf4c5 100644 (file)
 
 &clock_audss {
        assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>;
-       assigned-clock-parents = <&clock CLK_FOUT_EPLL>;
+       assigned-clock-parents = <&clock CLK_MAU_EPLL>;
 };
 
 &cpu0 {
                                regulator-name = "vdd_1v35";
                                regulator-min-microvolt = <1350000>;
                                regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
                                regulator-name = "vdd_2v";
                                regulator-min-microvolt = <2000000>;
                                regulator-max-microvolt = <2000000>;
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
                                regulator-name = "vdd_1v8";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
index 2f4f40882daba05c1436091f332f80f7f65d8244..2fac4baf1eb49a82411d5b5a4d962a811bad31fa 100644 (file)
                                regulator-always-on;
                        };
 
+                       ldo2_reg: LDO2 {
+                               regulator-name = "vdd_ldo2";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+
                        ldo3_reg: LDO3 {
                                regulator-name = "vddq_mmc0";
                                regulator-min-microvolt = <1800000>;
                        };
 
                        ldo12_reg: LDO12 {
+                               /* Unused */
                                regulator-name = "vdd_ldo12";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <2375000>;
                        };
 
                        ldo13_reg: LDO13 {
                                regulator-max-microvolt = <2800000>;
                        };
 
+                       ldo14_reg: LDO14 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo14";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
                        ldo15_reg: LDO15 {
                                regulator-name = "vdd_ldo15";
                                regulator-min-microvolt = <3300000>;
                        };
 
                        ldo16_reg: LDO16 {
+                               /* Unused */
                                regulator-name = "vdd_ldo16";
-                               regulator-min-microvolt = <2200000>;
-                               regulator-max-microvolt = <2200000>;
-                               regulator-always-on;
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
                        };
 
                        ldo17_reg: LDO17 {
                                regulator-max-microvolt = <2800000>;
                        };
 
-                       ldo24_reg: LDO24 {
-                               regulator-name = "tsp_io";
-                               regulator-min-microvolt = <2800000>;
-                               regulator-max-microvolt = <2800000>;
+                       ldo20_reg: LDO20 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo20";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo21_reg: LDO21 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo21";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo22_reg: LDO22 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo22";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <2375000>;
+                       };
+
+                       ldo23_reg: LDO23 {
+                               regulator-name = "vdd_mifs";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
                                regulator-always-on;
                        };
 
+                       ldo24_reg: LDO24 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo24";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo25_reg: LDO25 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo25";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
                        ldo26_reg: LDO26 {
+                               /* Used on XU3, XU3-Lite and XU4 */
                                regulator-name = "vdd_ldo26";
-                               regulator-min-microvolt = <3000000>;
-                               regulator-max-microvolt = <3000000>;
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo27_reg: LDO27 {
+                               regulator-name = "vdd_g3ds";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
                                regulator-always-on;
                        };
 
+                       ldo28_reg: LDO28 {
+                               /* Used on XU3 */
+                               regulator-name = "vdd_ldo28";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo29_reg: LDO29 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo29";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo30_reg: LDO30 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo30";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo31_reg: LDO31 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo31";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo32_reg: LDO32 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo32";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo33_reg: LDO33 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo33";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo34_reg: LDO34 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo34";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo35_reg: LDO35 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo35";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <2375000>;
+                       };
+
+                       ldo36_reg: LDO36 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo36";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo37_reg: LDO37 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo37";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
+                       ldo38_reg: LDO38 {
+                               /* Unused */
+                               regulator-name = "vdd_ldo38";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3950000>;
+                       };
+
                        buck1_reg: BUCK1 {
                                regulator-name = "vdd_mif";
                                regulator-min-microvolt = <800000>;
index 96e281c0a118ad0d84fd25707640060a5dddb6c5..e522edb2bb82d9a235ab59635a68d6cf15ae173a 100644 (file)
        status = "okay";
 };
 
+&ldo26_reg {
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-always-on;
+};
+
 &mixer {
        status = "okay";
 };
index 0322f281912cb5c9949d7676d004029bd64cf894..db0bc17a667bdf6432e51dbf742501153449a01f 100644 (file)
        };
 };
 
+&ldo28_reg {
+       regulator-name = "dp_p3v3";
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+};
+
 &pwm {
        /*
         * PWM 0 -- fan
index d80ab9085da19330b877643345e24cb50439d89c..e0f470fe54c81da83728a1e9b7611dd2d0d3ad28 100644 (file)
 
 &clock_audss {
        assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>;
-       assigned-clock-parents = <&clock CLK_FOUT_EPLL>;
+       assigned-clock-parents = <&clock CLK_MAU_EPLL>;
 };
 
 &cpu0 {
                                regulator-name = "vdd_1v35";
                                regulator-min-microvolt = <1350000>;
                                regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
                                regulator-name = "vdd_2v";
                                regulator-min-microvolt = <2000000>;
                                regulator-max-microvolt = <2000000>;
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
                                regulator-name = "vdd_1v8";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
index e31a9e3c18a225ef27610828722b08ae75821fa1..8d77579807ecf84cef67aeda3931507cf31c89e1 100644 (file)
 
        port {
                ceu_in: endpoint {
-                       hsync-active = <1>;
-                       vsync-active = <1>;
-                       bus-width = <8>;
-                       pclk-sample = <1>;
                        remote-endpoint = <&mt9v111_out>;
                };
        };
index 44044f2751151c6a244036de3d665da9da4bd32f..0f917b272ff36976ee1881abb1514f1b0d7d8e65 100644 (file)
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               port {
-                       etb0_in_port: endpoint@0 {
-                               slave-mode;
-                               remote-endpoint = <&replicator0_out_port0>;
+               in-ports {
+                       port {
+                               etb0_in_port: endpoint@0 {
+                                       remote-endpoint = <&replicator0_out_port0>;
+                               };
                        };
                };
        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               port {
-                       etb1_in_port: endpoint@0 {
-                               slave-mode;
-                               remote-endpoint = <&replicator1_out_port0>;
+               in-ports {
+                       port {
+                               etb1_in_port: endpoint@0 {
+                                       remote-endpoint = <&replicator1_out_port0>;
+                               };
                        };
                };
        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               port {
-                       etb2_in_port: endpoint@0 {
-                               slave-mode;
-                               remote-endpoint = <&replicator2_out_port0>;
+               in-ports {
+                       port {
+                               etb2_in_port: endpoint@0 {
+                                       remote-endpoint = <&replicator2_out_port0>;
+                               };
                        };
                };
        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               port {
-                       etb3_in_port: endpoint@0 {
-                               slave-mode;
-                               remote-endpoint = <&replicator3_out_port0>;
+               in-ports {
+                       port {
+                               etb3_in_port: endpoint@0 {
+                                       remote-endpoint = <&replicator3_out_port0>;
+                               };
                        };
                };
        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               port {
-                       tpiu_in_port: endpoint@0 {
-                               slave-mode;
-                               remote-endpoint = <&funnel4_out_port0>;
+               in-ports {
+                       port {
+                               tpiu_in_port: endpoint@0 {
+                                       remote-endpoint = <&funnel4_out_port0>;
+                               };
                        };
                };
        };
                 */
                compatible = "arm,coresight-replicator";
 
-               ports {
+               out-ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
                                        remote-endpoint = <&funnel4_in_port0>;
                                };
                        };
+               };
 
-                       /* replicator input port */
-                       port@2 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                replicator0_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&funnel0_out_port0>;
                                };
                        };
                 */
                compatible = "arm,coresight-replicator";
 
-               ports {
+               out-ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
                                        remote-endpoint = <&funnel4_in_port1>;
                                };
                        };
+               };
 
-                       /* replicator input port */
-                       port@2 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                replicator1_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&funnel1_out_port0>;
                                };
                        };
                 */
                compatible = "arm,coresight-replicator";
 
-               ports {
+               out-ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
-                       /* replicator output ports */
                        port@0 {
                                reg = <0>;
                                replicator2_out_port0: endpoint {
                                        remote-endpoint = <&funnel4_in_port2>;
                                };
                        };
+               };
 
-                       /* replicator input port */
-                       port@2 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                replicator2_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&funnel2_out_port0>;
                                };
                        };
                 */
                compatible = "arm,coresight-replicator";
 
-               ports {
+               out-ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
-                       /* replicator output ports */
                        port@0 {
                                reg = <0>;
                                replicator3_out_port0: endpoint {
                                        remote-endpoint = <&funnel4_in_port3>;
                                };
                        };
+               };
 
-                       /* replicator input port */
-                       port@2 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                replicator3_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&funnel3_out_port0>;
                                };
                        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* funnel output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                funnel0_out_port0: endpoint {
                                        remote-endpoint =
                                                <&replicator0_in_port0>;
                                };
                        };
+               };
 
-                       /* funnel input ports */
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                funnel0_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm0_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                funnel0_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm1_out_port>;
                                };
                        };
 
-                       port@3 {
+                       port@2 {
                                reg = <2>;
                                funnel0_in_port2: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm2_out_port>;
                                };
                        };
 
-                       port@4 {
+                       port@3 {
                                reg = <3>;
                                funnel0_in_port3: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm3_out_port>;
                                };
                        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* funnel output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                funnel1_out_port0: endpoint {
                                        remote-endpoint =
                                                <&replicator1_in_port0>;
                                };
                        };
+               };
 
-                       /* funnel input ports */
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                funnel1_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm4_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                funnel1_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm5_out_port>;
                                };
                        };
 
-                       port@3 {
+                       port@2 {
                                reg = <2>;
                                funnel1_in_port2: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm6_out_port>;
                                };
                        };
 
-                       port@4 {
+                       port@3 {
                                reg = <3>;
                                funnel1_in_port3: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm7_out_port>;
                                };
                        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* funnel output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                funnel2_out_port0: endpoint {
                                        remote-endpoint =
                                                <&replicator2_in_port0>;
                                };
                        };
+               };
 
-                       /* funnel input ports */
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                funnel2_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm8_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                funnel2_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm9_out_port>;
                                };
                        };
 
-                       port@3 {
+                       port@2 {
                                reg = <2>;
                                funnel2_in_port2: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm10_out_port>;
                                };
                        };
 
-                       port@4 {
+                       port@3 {
                                reg = <3>;
                                funnel2_in_port3: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm11_out_port>;
                                };
                        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* funnel output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                funnel3_out_port0: endpoint {
                                        remote-endpoint =
                                                <&replicator3_in_port0>;
                                };
                        };
+               };
 
-                       /* funnel input ports */
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                funnel3_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm12_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                funnel3_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm13_out_port>;
                                };
                        };
 
-                       port@3 {
+                       port@2 {
                                reg = <2>;
                                funnel3_in_port2: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm14_out_port>;
                                };
                        };
 
-                       port@4 {
+                       port@3 {
                                reg = <3>;
                                funnel3_in_port3: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&ptm15_out_port>;
                                };
                        };
 
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* funnel output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                funnel4_out_port0: endpoint {
                                        remote-endpoint = <&tpiu_in_port>;
                                };
                        };
+               };
 
-                       /* funnel input ports */
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                funnel4_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint =
                                                <&replicator0_out_port1>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                funnel4_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint =
                                                <&replicator1_out_port1>;
                                };
                        };
 
-                       port@3 {
+                       port@2 {
                                reg = <2>;
                                funnel4_in_port2: endpoint {
-                                       slave-mode;
                                        remote-endpoint =
                                                <&replicator2_out_port1>;
                                };
                        };
 
-                       port@4 {
+                       port@3 {
                                reg = <3>;
                                funnel4_in_port3: endpoint {
-                                       slave-mode;
                                        remote-endpoint =
                                                <&replicator3_out_port1>;
                                };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU0>;
-               port {
-                       ptm0_out_port: endpoint {
-                               remote-endpoint = <&funnel0_in_port0>;
+               out-ports {
+                       port {
+                               ptm0_out_port: endpoint {
+                                       remote-endpoint = <&funnel0_in_port0>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU1>;
-               port {
-                       ptm1_out_port: endpoint {
-                               remote-endpoint = <&funnel0_in_port1>;
+               out-ports {
+                       port {
+                               ptm1_out_port: endpoint {
+                                       remote-endpoint = <&funnel0_in_port1>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU2>;
-               port {
-                       ptm2_out_port: endpoint {
-                               remote-endpoint = <&funnel0_in_port2>;
+               out-ports {
+                       port {
+                               ptm2_out_port: endpoint {
+                                       remote-endpoint = <&funnel0_in_port2>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU3>;
-               port {
-                       ptm3_out_port: endpoint {
-                               remote-endpoint = <&funnel0_in_port3>;
+               out-ports {
+                       port {
+                               ptm3_out_port: endpoint {
+                                       remote-endpoint = <&funnel0_in_port3>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU4>;
-               port {
-                       ptm4_out_port: endpoint {
-                               remote-endpoint = <&funnel1_in_port0>;
+               out-ports {
+                       port {
+                               ptm4_out_port: endpoint {
+                                       remote-endpoint = <&funnel1_in_port0>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU5>;
-               port {
-                       ptm5_out_port: endpoint {
-                               remote-endpoint = <&funnel1_in_port1>;
+               out-ports {
+                       port {
+                               ptm5_out_port: endpoint {
+                                       remote-endpoint = <&funnel1_in_port1>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU6>;
-               port {
-                       ptm6_out_port: endpoint {
-                               remote-endpoint = <&funnel1_in_port2>;
+               out-ports {
+                       port {
+                               ptm6_out_port: endpoint {
+                                       remote-endpoint = <&funnel1_in_port2>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU7>;
-               port {
-                       ptm7_out_port: endpoint {
-                               remote-endpoint = <&funnel1_in_port3>;
+               out-ports {
+                       port {
+                               ptm7_out_port: endpoint {
+                                       remote-endpoint = <&funnel1_in_port3>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU8>;
-               port {
-                       ptm8_out_port: endpoint {
-                               remote-endpoint = <&funnel2_in_port0>;
+               out-ports {
+                       port {
+                               ptm8_out_port: endpoint {
+                                       remote-endpoint = <&funnel2_in_port0>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU9>;
-               port {
-                       ptm9_out_port: endpoint {
-                               remote-endpoint = <&funnel2_in_port1>;
+               out-ports {
+                       port {
+                               ptm9_out_port: endpoint {
+                                       remote-endpoint = <&funnel2_in_port1>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU10>;
-               port {
-                       ptm10_out_port: endpoint {
-                               remote-endpoint = <&funnel2_in_port2>;
+               out-ports {
+                       port {
+                               ptm10_out_port: endpoint {
+                                       remote-endpoint = <&funnel2_in_port2>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU11>;
-               port {
-                       ptm11_out_port: endpoint {
-                               remote-endpoint = <&funnel2_in_port3>;
+               out-ports {
+                       port {
+                               ptm11_out_port: endpoint {
+                                       remote-endpoint = <&funnel2_in_port3>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU12>;
-               port {
-                       ptm12_out_port: endpoint {
-                               remote-endpoint = <&funnel3_in_port0>;
+               out-ports {
+                       port {
+                               ptm12_out_port: endpoint {
+                                       remote-endpoint = <&funnel3_in_port0>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU13>;
-               port {
-                       ptm13_out_port: endpoint {
-                               remote-endpoint = <&funnel3_in_port1>;
+               out-ports {
+                       port {
+                               ptm13_out_port: endpoint {
+                                       remote-endpoint = <&funnel3_in_port1>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU14>;
-               port {
-                       ptm14_out_port: endpoint {
-                               remote-endpoint = <&funnel3_in_port2>;
+               out-ports {
+                       port {
+                               ptm14_out_port: endpoint {
+                                       remote-endpoint = <&funnel3_in_port2>;
+                               };
                        };
                };
        };
                clocks = <&clk_375m>;
                clock-names = "apb_pclk";
                cpu = <&CPU15>;
-               port {
-                       ptm15_out_port: endpoint {
-                               remote-endpoint = <&funnel3_in_port3>;
+               out-ports {
+                       port {
+                               ptm15_out_port: endpoint {
+                                       remote-endpoint = <&funnel3_in_port3>;
+                               };
                        };
                };
        };
index 3edc7b5550d88d67d21132231dba61d9bcdc1fcc..b00ece16b8539ff429d5352ec81f3f76b5539f58 100644 (file)
                        reg = <0x00210000 0x10000>;
                        ranges;
 
-                       cspi1: cspi@213000 {
+                       cspi1: spi@213000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx1-cspi";
                                status = "disabled";
                        };
 
-                       cspi2: cspi@219000 {
+                       cspi2: spi@219000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx1-cspi";
index ad2ae25b7b4dbeb5fb714dee5af9182166d51457..98efe1aeb26a505185e71080f7919a174d3a7c9c 100644 (file)
@@ -58,7 +58,7 @@
                                status = "okay";
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
index e9351774c61999ce25e7eede7928b270292f1b65..31b1e3581ac040852abfa74a36b5937197869772 100644 (file)
@@ -25,7 +25,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
@@ -59,7 +59,7 @@
                                };
                        };
 
-                       ssp1: ssp@80034000 {
+                       ssp1: spi@80034000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx23-spi";
index 67de7863ad795718d03cabd590e070a70d508f7b..faf701b2adb29a6675eec35711f5afdb3a4f3fba 100644 (file)
@@ -55,7 +55,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
@@ -65,7 +65,7 @@
                                status = "okay";
                        };
 
-                       ssp1: ssp@80034000 {
+                       ssp1: spi@80034000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc1_8bit_pins_a>;
index 95c7b918f6d6093145fd6b26f15021bdf8217327..2ff6cdf71a55b49043da937ff0064256e933c010 100644 (file)
@@ -22,7 +22,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
index 9616e500b9961657c8c21f8293a8e91e1f5a1e77..db53089fb7fb8f24ed989e0d1b4e47b648144418 100644 (file)
@@ -54,7 +54,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
@@ -64,7 +64,7 @@
                                status = "okay";
                        };
 
-                       ssp1: ssp@80034000 {
+                       ssp1: spi@80034000 {
                                compatible = "fsl,imx23-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc1_4bit_pins_a>;
index 71bfd2b15609ae5a1b48b9b309b421f88abbd058..ea259927eef614a530a238273ec8fe97e37ab36e 100644 (file)
@@ -93,7 +93,7 @@
                                status = "disabled";
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                reg = <0x80010000 0x2000>;
                                interrupts = <15>;
                                clocks = <&clks 33>;
                                status = "disabled";
                        };
 
-                       ssp1: ssp@80034000 {
+                       ssp1: spi@80034000 {
                                reg = <0x80034000 0x2000>;
                                interrupts = <2>;
                                clocks = <&clks 33>;
index 85c15ee63272775f2b0025ef2175f64e2b4c36d3..b25309d26ea569561284100c77a721398a7bf0c2 100644 (file)
                                status = "disabled";
                        };
 
-                       spi1: cspi@43fa4000 {
+                       spi1: spi@43fa4000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                        reg = <0x50000000 0x40000>;
                        ranges;
 
-                       spi3: cspi@50004000 {
+                       spi3: spi@50004000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                status = "disabled";
                        };
 
-                       spi2: cspi@50010000 {
+                       spi2: spi@50010000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
index 753d88df1627405953c75116599c7235bd39095b..151b0eb17dda5d475fe10bb661f18f857b05da28 100644 (file)
                                status = "disabled";
                        };
 
-                       cspi1: cspi@1000e000 {
+                       cspi1: spi@1000e000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx27-cspi";
                                status = "disabled";
                        };
 
-                       cspi2: cspi@1000f000 {
+                       cspi2: spi@1000f000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx27-cspi";
                                status = "disabled";
                        };
 
-                       cspi3: cspi@10017000 {
+                       cspi3: spi@10017000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx27-cspi";
index c4fadbc1b40040f4626a8cea728ab8301eb0568b..8df5ec47037657796aa8ebb0d0996df35506f80f 100644 (file)
@@ -18,7 +18,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a
@@ -27,7 +27,7 @@
                                status = "okay";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-spi";
                                pinctrl-names = "default";
                                pinctrl-0 = <&spi2_pins_a>;
index 96faa53ba44c6d72a8d0d806c56e9c8cda11ef8c..6c9b498305c05461fe79bbf2493b0cad01c69d46 100644 (file)
@@ -18,7 +18,7 @@
                                status = "okay";
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_sck_cfg>;
@@ -26,7 +26,7 @@
                                status = "okay";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc2_4bit_pins_apx4 &mmc2_sck_cfg_apx4>;
index e54f5aba70914a30a06c555d8c802ac68add4bf9..8337ca21e28174a9a32174374497328b65e7a9db 100644 (file)
@@ -66,7 +66,7 @@
 
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a
index 97084e463d7cd82ae7a4fbd6f671924867d7b7cb..f4f2b3d16c8e166d060bc45dc8aadd8e136e45bb 100644 (file)
@@ -25,7 +25,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_8bit_pins_a
@@ -36,7 +36,7 @@
                                non-removable;
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc2_4bit_pins_b
index 22215337f72a47af306d7b26fb6e021224c04084..71d0fcbc2d8c38295b7052bc4af2af4c3e316b00 100644 (file)
@@ -26,7 +26,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_8bit_pins_a
@@ -37,7 +37,7 @@
                                non-removable;
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc2_4bit_pins_b
index 13e7b134da9ea649ba42f4409ae5369261bb9e49..6580ec6e26babee168acec5edf22c66e3721974e 100644 (file)
@@ -29,7 +29,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_8bit_pins_a
@@ -40,7 +40,7 @@
                                non-removable;
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-spi";
                                pinctrl-names = "default";
                                pinctrl-0 = <&spi2_pins_a>;
index 88556c93b00f96e6f6fdae2373db21d7a4c3b190..693634edae99c9ffccf32aba3beccfa0784bd8cd 100644 (file)
@@ -25,7 +25,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_8bit_pins_a
@@ -36,7 +36,7 @@
                                non-removable;
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc2_4bit_pins_b
index f286bfe699bee17135649b425d6081600bfa54af..16f524428ed701c3bef7f8081357ce4afc3466ac 100644 (file)
@@ -24,7 +24,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a
@@ -34,7 +34,7 @@
                                status = "okay";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-spi";
                                pinctrl-names = "default";
                                pinctrl-0 = <&spi2_pins_a>;
index 93ab5bdfe068a11a75276ebeaa4d31a99e473e67..5778300f44e8b7133a6b53a2d10e152338e8c052 100644 (file)
                                status = "okay";
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_8bit_pins_a
                                status = "okay";
                        };
 
-                       ssp1: ssp@80012000 {
+                       ssp1: spi@80012000 {
                                compatible = "fsl,imx28-mmc";
                                bus-width = <8>;
                                wp-gpios = <&gpio0 28 0>;
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx28-spi";
index 3bb5ffc644d6f4080daf9e2be0399e2a8aef3d40..8883d36a51b5218b14090fe7c77af5d0ea964852 100644 (file)
@@ -41,7 +41,7 @@
                                };
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a
@@ -52,7 +52,7 @@
                                status = "okay";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc2_4bit_pins_a
index 7d97a0ce74a3808509c19e66b057d9ee67220b1f..893886d17b2da82e759c2790d3e2e626e65d36db 100644 (file)
@@ -18,7 +18,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_8bit_pins_a
@@ -30,7 +30,7 @@
                                status = "okay";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx28-spi";
index 2393e83979e0d2c4e627265fd6515aae87c94987..ea9212f6ecdad5e0a3e8c345cb61ce4c5689d0c7 100644 (file)
@@ -40,7 +40,7 @@
 
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a>;
@@ -48,7 +48,7 @@
                                status = "okay";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx28-spi";
index f8a09a8c2c36adc91a31c95d3304cdc74ed2a720..dccdd6bcd0b2ba95d3216f90dadba52075395fb3 100644 (file)
@@ -25,7 +25,7 @@
 
        apb@80000000 {
                apbh@80000000 {
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                compatible = "fsl,imx28-mmc";
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a
index 5107fdc482ea000d84fc7b15add34bd22be97d2d..2b7efb659fc0b8325375d5c8b77a6f56b9846dce 100644 (file)
                                status = "disabled";
                        };
 
-                       ssp0: ssp@80010000 {
+                       ssp0: spi@80010000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x80010000 0x2000>;
                                status = "disabled";
                        };
 
-                       ssp1: ssp@80012000 {
+                       ssp1: spi@80012000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x80012000 0x2000>;
                                status = "disabled";
                        };
 
-                       ssp2: ssp@80014000 {
+                       ssp2: spi@80014000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x80014000 0x2000>;
                                status = "disabled";
                        };
 
-                       ssp3: ssp@80016000 {
+                       ssp3: spi@80016000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x80016000 0x2000>;
index ca1419ca303c3d5994a73b5bdddc9e69428dac55..af7afccf5f2fbaf9dae3ee049c3773a37216663b 100644 (file)
                                status = "disabled";
                        };
 
-                       spi2: cspi@50010000 {
+                       spi2: spi@50010000 {
                                compatible = "fsl,imx31-cspi";
                                reg = <0x50010000 0x4000>;
                                interrupts = <13>;
                                #clock-cells = <1>;
                        };
 
-                       spi3: cspi@53f84000 {
+                       spi3: spi@53f84000 {
                                compatible = "fsl,imx31-cspi";
                                reg = <0x53f84000 0x4000>;
                                interrupts = <17>;
index 1c50b785cad473afc0d4ef28c266664ac8a63ba9..a1c3d28e8771c23eaa3b385e3ef901958ee57adb 100644 (file)
                                status = "disabled";
                        };
 
-                       spi1: cspi@43fa4000 {
+                       spi1: spi@43fa4000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx35-cspi";
                                status = "disabled";
                        };
 
-                       spi2: cspi@50010000 {
+                       spi2: spi@50010000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx35-cspi";
index 7fae2ffb76fe2e63ecb4fe8a515b61a65dd99421..95b7fba58300fffd08508538798fbfa2f8bfcebe 100644 (file)
                                        status = "disabled";
                                };
 
-                               ecspi1: ecspi@50010000 {
+                               ecspi1: spi@50010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
                                status = "disabled";
                        };
 
-                       ecspi2: ecspi@63fac000 {
+                       ecspi2: spi@63fac000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx50-ecspi", "fsl,imx51-ecspi";
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx50.bin";
                        };
 
-                       cspi: cspi@63fc0000 {
+                       cspi: spi@63fc0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx50-cspi", "fsl,imx35-cspi";
index ba60b0cb3cc13ba08c9c414d7b8c317cc936ad7e..35ee1b4247c3a1266086edaddfff1095077d17b4 100644 (file)
                reg = <0>;
                interrupt-parent = <&gpio1>;
                interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+               fsl,mc13xxx-uses-adc;
                fsl,mc13xxx-uses-rtc;
 
                regulators {
index 469cce2c03573b5f32d6534ef753b34b4547cd5d..e45a15ceb94bc4f88a4e89029dd5c18fb7e81853 100644 (file)
        };
 
        ds1341: rtc@68 {
-               compatible = "maxim,ds1341";
+               compatible = "dallas,ds1341";
                reg = <0x68>;
        };
 
index 26cf08549df401e61325ceb017fea2a7848cefa8..243d1c8cab0a13c52f80593e7dec76df104389cd 100644 (file)
        vcc-supply = <&vusb2_reg>;
 };
 
+&vpu {
+       status = "disabled";
+};
+
+&wdog1 {
+       status = "disabled";
+};
+
 &iomuxc {
        pinctrl_ecspi1: ecspi1grp {
                fsl,pins = <
index e6ebac8f43e4fbfe64a18d8254ebe80d374ebf7a..14b207778114a9dee5e72d98b1888ab13e4844a2 100644 (file)
        vcc-supply = <&vusb2_reg>;
 };
 
+&vpu {
+       status = "disabled";
+};
+
 &wdog1 {
        status = "disabled";
 };
index 5c4ba91e43ba4b2e797d3d34dea32093f9a1f0e6..67d462715048f28da7ec9caec5af01ab4741816d 100644 (file)
                                        status = "disabled";
                                };
 
-                               ecspi1: ecspi@70010000 {
+                               ecspi1: spi@70010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx51-ecspi";
                                status = "disabled";
                        };
 
-                       ecspi2: ecspi@83fac000 {
+                       ecspi2: spi@83fac000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx51-ecspi";
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
                        };
 
-                       cspi: cspi@83fc0000 {
+                       cspi: spi@83fc0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
                                status = "disabled";
                        };
 
-                       vpu@83ff4000 {
+                       vpu: vpu@83ff4000 {
                                compatible = "fsl,imx51-vpu", "cnm,codahx4";
                                reg = <0x83ff4000 0x1000>;
                                interrupts = <9>;
index cdb90bee7b4a2b3d4d68681cc68c0c0efea7efae..b560ff88459bf1b74a0c093f3bdc15d2118c0182 100644 (file)
 &ecspi2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_ecspi2>;
-       num-chipselects = <1>;
        cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
        status = "okay";
 
index 6386185ae23403089e4cb9a5a7e6c559d5637750..207eb557c90ebd28b8643e6c3fa579f50abe398e 100644 (file)
                                        status = "disabled";
                                };
 
-                               ecspi1: ecspi@50010000 {
+                               ecspi1: spi@50010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
                                status = "disabled";
                        };
 
-                       ecspi2: ecspi@63fac000 {
+                       ecspi2: spi@63fac000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
                        };
 
-                       cspi: cspi@63fc0000 {
+                       cspi: spi@63fc0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
index 9de45a7173561949a095a22a1cfcff7c9c459c25..d08e0402793bc05e17de67c177e1fdc3794df584 100644 (file)
 &ecspi4 {
        status = "okay";
 
-       mcp251x0: mcp251x@1 {
+       mcp251x0: mcp251x@0 {
                compatible = "microchip,mcp2515";
                reg = <0>;
                clocks = <&clk16m>;
index bf53f0552aa17cd5f5525ff5e8e0ee0f0a80deed..e43bccb78ab2ba44130603fb102254a3081ca858 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2018 Engicam S.r.l.
  * Copyright (C) 2018 Amarula Solutions B.V.
index 1281bc39b7ab87a430b5edaaacf187b82526186d..73d710d34b9d51d18f41d653be9e9f0fe08a7eeb 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 971f9fc39c66c8ec22f7acf63970b7699587b29d..80fa60607ab1631e1ef55fe37ca3474a94e7c724 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index dd3226fe5ecd57e606b6b1eca6090c9634b43837..8e51491e68cfdc68c83cb29f6e21be8f24398a2e 100644 (file)
        status = "okay";
 };
 
+&clks {
+       fsl,pmic-stby-poweroff;
+};
+
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
                reg = <0x08>;
                interrupt-parent = <&gpio5>;
                interrupts = <16 8>;
+               fsl,pmic-stby-poweroff;
 
                regulators {
                        reg_vddcore: sw1ab {                            /* VDDARM_IN */
index 707ac9a46115f02bd6307413a1bbd7935a7d7799..0edd3043d9c1e1e06bf45152d31d5cba5f62dc79 100644 (file)
 };
 
 &pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_reset_moci>;
        /* active-high meaning opposite of regular PERST# active-low polarity */
        reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
        reset-gpio-active-high;
index 4e1c8feaef82207805d102d0aa724db06ae4e39e..b94bb687be6b31b4f5af88f168b618b6d798cef6 100644 (file)
 };
 
 &pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_reset_moci>;
        /* active-high meaning opposite of regular PERST# active-low polarity */
        reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
        reset-gpio-active-high;
index 469e3d0e28276e78c26a000ae3f9cda004706bd1..302fd6adc8a7d63fc318c1a9ebb1cc87aa4817ba 100644 (file)
 };
 
 &pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_reset_moci>;
        /* active-high meaning opposite of regular PERST# active-low polarity */
        reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
        reset-gpio-active-high;
index 95b2efda17b42ebb6cb0203a941c8ebd3b4be8b7..d51745268dbf256b190deef2660194b80e4bfd01 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2017 Engicam S.r.l.
  * Copyright (C) 2017 Amarula Solutions B.V.
@@ -8,10 +8,10 @@
 /dts-v1/;
 
 #include "imx6q.dtsi"
-#include "imx6qdl-icore.dtsi"
+#include "imx6qdl-icore-1.5.dtsi"
 
 / {
-       model = "Engicam i.CoreM6 Quad/Dual MIPI Starter Kit";
+       model = "Engicam i.CoreM6 1.5 Quad/Dual MIPI Starter Kit";
        compatible = "engicam,imx6-icore", "fsl,imx6q";
 };
 
index 49b60ca20e6d68ab2a576c3c50700194eade0e03..81cc346dd149364e0a0862b97b3fb1f40cb78176 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 6e27c8143f82157e8e0d98becd3805d857cca9bd..241811c52b624625c7a44cbd46558b78d5f5b154 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index b81f48c6a8c68a9eab475e989db3297d73cf39ac..cf6ba724f4979a37255a2586422a34d02137889b 100644 (file)
@@ -1,42 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2015 Amarula Solutions B.V.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
+ * Copyright (C) 2015 Engicam S.r.l.
  */
 
 /dts-v1/;
index 5613dd9dc4693a6638475018b1017ad0bf3cfe38..fe28c3cf54c0377227dc23e7ff9d5710f0dbca70 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 0193ee6fe964a4be2a12e1b56374272293f16d2c..8381d24eff7d0d9961cc195df6c5373c47124ff1 100644 (file)
 
                aips-bus@2000000 { /* AIPS1 */
                        spba-bus@2000000 {
-                               ecspi5: ecspi@2018000 {
+                               ecspi5: spi@2018000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
index 05f07ea3e8c8051338dfec9db3977e095ae19431..3dc99dd8dde178e612546490ef24b6b613a5fc83 100644 (file)
 };
 
 &iomuxc {
-       /* pins used on module */
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_reset_moci>;
-
        pinctrl_apalis_gpio1: gpio2io04grp {
                fsl,pins = <
                        MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x130b0
diff --git a/arch/arm/boot/dts/imx6qdl-icore-1.5.dtsi b/arch/arm/boot/dts/imx6qdl-icore-1.5.dtsi
new file mode 100644 (file)
index 0000000..d91d46b
--- /dev/null
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Jacopo Mondi <jacopo@jmondi.org>
+ */
+
+#include "imx6qdl-icore.dtsi"
+
+&iomuxc {
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN      0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0b0
+                       MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN       0x1b0b0
+                       MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1     0x1b0b0
+                       MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0     0x1b0b0
+                       MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1     0x1b0b0
+                       MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0     0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_GPIO_17__GPIO7_IO12          0x1b0b0
+               >;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+       clocks = <&clks IMX6QDL_CLK_ENET>,
+                <&clks IMX6QDL_CLK_ENET>,
+                <&clks IMX6QDL_CLK_ENET_REF>;
+       phy-mode = "rmii";
+       status = "okay";
+};
index acc3b11fba2a77e440a1afae95eae28b3438a650..ba93026ecee8810a551c073709aa96b8e1c20ca5 100644 (file)
@@ -1,42 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2015 Amarula Solutions B.V.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
+ * Copyright (C) 2015 Engicam S.r.l.
  */
 
 #include <dt-bindings/gpio/gpio.h>
 };
 
 &iomuxc {
-       pinctrl_audmux: audmux {
+       pinctrl_audmux: audmuxgrp {
                fsl,pins = <
                        MX6QDL_PAD_DISP0_DAT20__AUD4_TXC  0x130b0
                        MX6QDL_PAD_DISP0_DAT21__AUD4_TXD  0x110b0
index 9ce993776160df74623b6e20e568b4945bc85eaf..84d03c65f4c87eb283f3378c027a880b46814ac9 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/gpio/gpio.h>
 };
 
 &iomuxc {
-       pinctrl_audmux: audmux {
+       pinctrl_audmux: audmuxgrp {
                fsl,pins = <
                        MX6QDL_PAD_DISP0_DAT20__AUD4_TXC  0x130b0
                        MX6QDL_PAD_DISP0_DAT21__AUD4_TXD  0x110b0
                >;
        };
 
-       pinctrl_gpmi_nand: gpmi-nand {
+       pinctrl_gpmi_nand: gpminandgrp {
                fsl,pins = <
                        MX6QDL_PAD_NANDF_CLE__NAND_CLE     0xb0b1
                        MX6QDL_PAD_NANDF_ALE__NAND_ALE     0xb0b1
index 9f11f1fcc3e6caac35c38c5b81038b3a1a152078..a6dc5c42c632ba1d84375c62b077fad4a1b361f2 100644 (file)
@@ -4,6 +4,7 @@
 // Copyright 2011 Linaro Ltd.
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
        chosen {
                };
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
+
+               home {
+                       label = "Home";
+                       gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOME>;
+                       wakeup-source;
+               };
+
+               back {
+                       label = "Back";
+                       gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_BACK>;
+                       wakeup-source;
+               };
+
+               program {
+                       label = "Program";
+                       gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_PROGRAM>;
+                       wakeup-source;
+               };
+
+               volume-up {
+                       label = "Volume Up";
+                       gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+                       wakeup-source;
+               };
+
+               volume-down {
+                       label = "Volume Down";
+                       gpios = <&gpio5 14 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       wakeup-source;
+               };
+       };
+
        clocks {
                codec_osc: anaclk2 {
                        compatible = "fixed-clock";
                VLC-supply = <&reg_audio>;
        };
 
+       touchscreen@4 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_egalax_int>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <28 IRQ_TYPE_EDGE_FALLING>;
+               wakeup-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>;
+       };
 };
 
 &i2c3 {
                        >;
                };
 
+               pinctrl_egalax_int: egalax-intgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_EB0__GPIO2_IO28          0xb0b1
+                       >;
+               };
+
                pinctrl_enet: enetgrp {
                        fsl,pins = <
                                MX6QDL_PAD_KEY_COL1__ENET_MDIO          0x1b0b0
                        >;
                };
 
+               pinctrl_gpio_keys: gpiokeysgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__GPIO1_IO11          0x1b0b0
+                               MX6QDL_PAD_SD2_DAT3__GPIO1_IO12         0x1b0b0
+                               MX6QDL_PAD_SD4_DAT4__GPIO2_IO12         0x1b0b0
+                               MX6QDL_PAD_SD4_DAT7__GPIO2_IO15         0x1b0b0
+                               MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14      0x1b0b0
+                       >;
+               };
+
                pinctrl_gpio_leds: gpioledsgrp {
                        fsl,pins = <
                                MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15      0x80000000
index 381bf61fcd284ad3c7052e799f9051901af0c6d8..b7d5fb4214046b387965bc16d2b39f42319b4c81 100644 (file)
@@ -8,6 +8,10 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
+       chosen {
+               stdout-path = &uart1;
+       };
+
        sound {
                compatible = "fsl,imx6-wandboard-sgtl5000",
                             "fsl,imx-audio-sgtl5000";
index 7fff3717cf7c09ae29d130756b3f33856d7ef819..85e79a33bcd434c32db994528463543668c239d6 100644 (file)
        status = "okay";
 };
 
+&snvs_rtc {
+       status = "disabled";
+};
+
 &ssi1 {
        status = "okay";
 };
index 61d2d26afbf4d90474dcae54930bb036ba13412b..e4daf150881a9e2c9f5d5283e470edd8c586b13a 100644 (file)
                                        status = "disabled";
                                };
 
-                               ecspi1: ecspi@2008000 {
+                               ecspi1: spi@2008000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi2: ecspi@200c000 {
+                               ecspi2: spi@200c000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi3: ecspi@2010000 {
+                               ecspi3: spi@2010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi4: ecspi@2014000 {
+                               ecspi4: spi@2014000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
index 7a4f5dace9026b0075507f46107c95bba1ab6397..7a3ae7160c129305d3e131fe6e59530d7c64e1f0 100644 (file)
                                        status = "disabled";
                                };
 
-                               ecspi1: ecspi@2008000 {
+                               ecspi1: spi@2008000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi2: ecspi@200c000 {
+                               ecspi2: spi@200c000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi3: ecspi@2010000 {
+                               ecspi3: spi@2010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi4: ecspi@2014000 {
+                               ecspi4: spi@2014000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
index 000e6136a9d6c1bfbe2cd825b5a1d19cc9ee07a6..ed9a980bce8501fcca0c3d357a8440cb8debd59d 100644 (file)
                                reg = <0x0209c000 0x4000>;
                                interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPIO1>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 94 7>, <&iomuxc 7 25 25>;
                        };
 
                        gpio2: gpio@20a0000 {
                                reg = <0x020a0000 0x4000>;
                                interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPIO2>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 50 32>;
                        };
 
                        gpio3: gpio@20a4000 {
                                reg = <0x020a4000 0x4000>;
                                interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPIO3>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 82 12>, <&iomuxc 12 103 4>,
+                                             <&iomuxc 16 101 2>, <&iomuxc 18 5 1>,
+                                             <&iomuxc 21 6 11>;
                        };
 
                        gpio4: gpio@20a8000 {
                                reg = <0x020a8000 0x4000>;
                                interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPIO4>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 17 8>, <&iomuxc 8 107 8>,
+                                             <&iomuxc 16 151 1>, <&iomuxc 17 149 1>,
+                                             <&iomuxc 18 146 1>, <&iomuxc 19 144 1>,
+                                             <&iomuxc 20 142 1>, <&iomuxc 21 143 1>,
+                                             <&iomuxc 22 150 1>, <&iomuxc 23 148 1>,
+                                             <&iomuxc 24 147 1>, <&iomuxc 25 145 1>,
+                                             <&iomuxc 26 152 1>, <&iomuxc 27 125 1>,
+                                             <&iomuxc 28 131 1>, <&iomuxc 29 134 1>,
+                                             <&iomuxc 30 129 1>, <&iomuxc 31 133 1>;
                        };
 
                        gpio5: gpio@20ac000 {
                                reg = <0x020ac000 0x4000>;
                                interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPIO5>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 135 1>, <&iomuxc 1 128 1>,
+                                             <&iomuxc 2 132 1>, <&iomuxc 3 130 1>,
+                                             <&iomuxc 4 127 1>, <&iomuxc 5 126 1>,
+                                             <&iomuxc 6 120 1>, <&iomuxc 7 123 1>,
+                                             <&iomuxc 8 118 1>, <&iomuxc 9 122 1>,
+                                             <&iomuxc 10 124 1>, <&iomuxc 11 117 1>,
+                                             <&iomuxc 12 121 1>, <&iomuxc 13 119 1>,
+                                             <&iomuxc 14 116 1>, <&iomuxc 15 115 1>,
+                                             <&iomuxc 16 140 2>, <&iomuxc 18 136 1>,
+                                             <&iomuxc 19 138 1>, <&iomuxc 20 139 1>,
+                                             <&iomuxc 21 137 1>;
                        };
 
                        gpio6: gpio@20b0000 {
                                reg = <0x020b0000 0x4000>;
                                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPIO6>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
index f8f31872fa144d83b29c227a921125c482ebc4bf..53b3408b5fab1845248b2b7ff078eba462f730ab 100644 (file)
                        label = "Volume Up";
                        gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_VOLUMEUP>;
+                       wakeup-source;
                };
 
                volume-down {
                        label = "Volume Down";
                        gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_VOLUMEDOWN>;
+                       wakeup-source;
                };
        };
 
index 844caa39364ffeaabc18093bcf3cf87d6b4c7c32..95a3c1cb877db4fc307da0342306698b2d9a46dd 100644 (file)
                                        status = "disabled";
                                };
 
-                               ecspi1: ecspi@2008000 {
+                               ecspi1: spi@2008000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi2: ecspi@200c000 {
+                               ecspi2: spi@200c000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi3: ecspi@2010000 {
+                               ecspi3: spi@2010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi4: ecspi@2014000 {
+                               ecspi4: spi@2014000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
                                status = "disabled";
                        };
 
-                       qspi1: qspi@21e0000 {
+                       qspi1: spi@21e0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6sx-qspi";
                                status = "disabled";
                        };
 
-                       qspi2: qspi@21e4000 {
+                       qspi2: spi@21e4000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6sx-qspi";
                                status = "disabled";
                        };
 
-                       ecspi5: ecspi@228c000 {
+                       ecspi5: spi@228c000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6sx-ecspi", "fsl,imx51-ecspi";
diff --git a/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts b/arch/arm/boot/dts/imx6ul-ccimx6ulsbcpro.dts
new file mode 100644 (file)
index 0000000..11966d1
--- /dev/null
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Digi International's ConnectCore6UL SBC Pro board device tree source
+ *
+ * Copyright 2018 Digi International, Inc.
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "imx6ul.dtsi"
+#include "imx6ul-ccimx6ulsom.dtsi"
+
+/ {
+       model = "Digi International ConnectCore 6UL SBC Pro.";
+       compatible = "digi,ccimx6ulsbcpro", "digi,ccimx6ulsom", "fsl,imx6ul";
+
+       lcd_backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm5 0 50000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               status = "okay";
+       };
+
+       reg_usb_otg1_vbus: regulator-usb-otg1 {
+               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;
+       };
+};
+
+&adc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc1>;
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       xceiver-supply = <&ext_3v3>;
+       status = "okay";
+};
+
+/* CAN2 is multiplexed with UART2 RTS/CTS */
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       xceiver-supply = <&ext_3v3>;
+       status = "disabled";
+};
+
+&ecspi1 {
+       cs-gpios = <&gpio3 26 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1_master>;
+       status = "okay";
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy0>;
+       status = "okay";
+};
+
+&fec2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_mdio>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy1>;
+       phy-reset-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <26>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       smsc,disable-energy-detect;
+                       reg = <0>;
+               };
+
+               ethphy1: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       smsc,disable-energy-detect;
+                       reg = <1>;
+               };
+       };
+};
+
+&gpio5 {
+       emmc-usd-mux {
+               gpio-hog;
+               gpios = <1 GPIO_ACTIVE_LOW>;
+               output-high;
+       };
+};
+
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lcdif_dat0_17
+                    &pinctrl_lcdif_clken
+                    &pinctrl_lcdif_hvsync>;
+       lcd-supply = <&ldo4_ext>;       /* BU90T82 LVDS bridge power */
+       status = "okay";
+};
+
+&ldo4_ext {
+       regulator-max-microvolt = <1800000>;
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&pwm3 {
+       status = "okay";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>;
+       status = "okay";
+};
+
+&pwm5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm5>;
+       status = "okay";
+};
+
+&pwm6 {
+       status = "okay";
+};
+
+&pwm7 {
+       status = "okay";
+};
+
+&pwm8 {
+       status = "okay";
+};
+
+&sai2 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&pinctrl_sai2>;
+       pinctrl-1 = <&pinctrl_sai2_sleep>;
+       assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
+                         <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>,
+                         <&clks IMX6UL_CLK_SAI2>;
+       assigned-clock-rates = <0>, <786432000>, <12288000>;
+       assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
+       status = "okay";
+};
+
+/* UART2 RTS/CTS muxed with CAN2 */
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_4wires>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+/* UART3 RTS/CTS muxed with CAN 1 */
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3_2wires>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg1 {
+       dr_mode = "otg";
+       vbus-supply = <&reg_usb_otg1_vbus>;
+       pinctrl-0 = <&pinctrl_usbotg1>;
+       status = "okay";
+};
+
+&usbotg2 {
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+/* USDHC2 (microSD conflicts with eMMC) */
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       no-1-8-v;
+       broken-cd;      /* no carrier detect line (use polling) */
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_adc1: adc1grp {
+               fsl,pins = <
+                       /* EXP_GPIO_2 -> GPIO1_3/ADC1_IN3 */
+                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0xb0
+               >;
+       };
+
+       pinctrl_ecspi1_master: ecspi1grp1 {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK       0x10b0
+                       MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI       0x10b0
+                       MX6UL_PAD_LCD_DATA23__ECSPI1_MISO       0x10b0
+                       MX6UL_PAD_LCD_DATA21__GPIO3_IO26        0x10b0
+               >;
+       };
+
+       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  0x40017051
+               >;
+       };
+
+       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  0x40017051
+               >;
+       };
+
+       pinctrl_enet2_mdio: mdioenet2grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET2_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET2_MDIO        0x1b0b0
+               >;
+       };
+
+       pinctrl_flexcan1: flexcan1grp{
+               fsl,pins = <
+                       MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX      0x1b020
+                       MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX      0x1b020
+               >;
+       };
+       pinctrl_flexcan2: flexcan2grp{
+               fsl,pins = <
+                       MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX      0x1b020
+                       MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX      0x1b020
+               >;
+       };
+
+       pinctrl_lcdif_dat0_17: lcdifdatgrp0-17 {
+               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
+               >;
+       };
+
+       pinctrl_lcdif_clken: lcdifctrlgrp1 {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_CLK__LCDIF_CLK            0x17050
+                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE      0x79
+               >;
+       };
+
+       pinctrl_lcdif_hvsync: lcdifctrlgrp2 {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC        0x79
+                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC        0x79
+               >;
+       };
+
+       pinctrl_pwm4: pwm4grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO05__PWM4_OUT          0x110b0
+               >;
+       };
+
+       pinctrl_pwm5: pwm5grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_DQS__PWM5_OUT            0x110b0
+               >;
+       };
+
+       pinctrl_sai2: sai2grp {
+               fsl,pins = <
+                       MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA     0x11088
+                       MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA        0x11088
+                       MX6UL_PAD_JTAG_TMS__SAI2_MCLK           0x17088
+                       MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK        0x17088
+                       MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC        0x17088
+                       /* Interrupt */
+                       MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x10b0
+               >;
+       };
+
+       pinctrl_sai2_sleep: sai2grp-sleep {
+               fsl,pins = <
+                       MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15       0x3000
+                       MX6UL_PAD_JTAG_TCK__GPIO1_IO14          0x3000
+                       MX6UL_PAD_JTAG_TMS__GPIO1_IO11          0x3000
+                       MX6UL_PAD_JTAG_TDO__GPIO1_IO12          0x3000
+                       /* Interrupt */
+                       MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x3000
+               >;
+       };
+
+       pinctrl_uart2_4wires: uart2grp-4wires {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX   0x1b0b1
+                       MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS    0x1b0b1
+                       MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3_2wires: uart3grp-2wires {
+               fsl,pins = <
+                       MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_HSYNC__USDHC2_CMD         0x17059
+                       MX6UL_PAD_CSI_VSYNC__USDHC2_CLK         0x10039
+                       MX6UL_PAD_CSI_DATA00__USDHC2_DATA0      0x17059
+                       MX6UL_PAD_CSI_DATA01__USDHC2_DATA1      0x17059
+                       MX6UL_PAD_CSI_DATA02__USDHC2_DATA2      0x17059
+                       MX6UL_PAD_CSI_DATA03__USDHC2_DATA3      0x17059
+                       /* Mux selector between eMMC/SD# */
+                       MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01      0x79
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x17059
+                       MX6UL_PAD_GPIO1_IO04__GPIO1_IO04        0x17059
+                       MX6UL_PAD_GPIO1_IO01__USB_OTG1_OC       0x17059
+               >;
+       };
+};
index d81d20f8fc8ddae18938210eddd846d354fea800..e22ec5be2b78f8a9758cbadf234f876482872508 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
                >;
        };
 
-       pinctrl_gpmi_nand: gpmi-nand {
+       pinctrl_gpmi_nand: gpminandgrp {
                fsl,pins = <
                        MX6UL_PAD_NAND_CLE__RAWNAND_CLE         0xb0b1
                        MX6UL_PAD_NAND_ALE__RAWNAND_ALE         0xb0b1
index f5b422898e61dd22ed1c13a3357a62fb2209f8f1..1df3e376ae2c505278701526b4366fa338dab52f 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
 };
 
 &usdhc2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc2>;
-       cd-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
-       bus-width = <8>;
-       no-1-8-v;
        status = "okay";
 };
-
-&iomuxc {
-       pinctrl_usdhc2: usdhc2grp {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK      0x17070
-                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD      0x10070
-                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0  0x17070
-                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1  0x17070
-                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2  0x17070
-                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3  0x17070
-                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4  0x17070
-                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5  0x17070
-                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6  0x17070
-                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7  0x17070
-                       MX6UL_PAD_NAND_ALE__USDHC2_RESET_B   0x17070
-               >;
-       };
-};
index de15e1c75dd1ddf606976d0f3571fdf6bb1c10e7..8c26d4d1a7bf6ead800996641633e1c2fb29e060 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
 };
 
 &gpmi {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpmi_nand>;
-       nand-on-flash-bbt;
        status = "okay";
 };
-
-&iomuxc {
-       pinctrl_gpmi_nand: gpmi-nand {
-               fsl,pins = <
-                       MX6UL_PAD_NAND_CLE__RAWNAND_CLE         0xb0b1
-                       MX6UL_PAD_NAND_ALE__RAWNAND_ALE         0xb0b1
-                       MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B       0xb0b1
-                       MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
-                       MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B     0xb0b1
-                       MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B       0xb0b1
-                       MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B       0xb0b1
-                       MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00   0xb0b1
-                       MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01   0xb0b1
-                       MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02   0xb0b1
-                       MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03   0xb0b1
-                       MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04   0xb0b1
-                       MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05   0xb0b1
-                       MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06   0xb0b1
-                       MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07   0xb0b1
-               >;
-       };
-};
index cd99285511544cc7862dd27d1da71ecf28de1a0c..b1fa3f0a684d0feb9fcf901b1c166f8bf3f51bc7 100644 (file)
@@ -1,43 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Amarula Solutions B.V.
  * Copyright (C) 2016 Engicam S.r.l.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/gpio/gpio.h>
        };
 };
 
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       nand-on-flash-bbt;
+       status = "disabled";
+};
+
 &i2c1 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
        status = "okay";
 };
 
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       cd-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+       bus-width = <8>;
+       no-1-8-v;
+       status = "disabled";
+};
+
 &iomuxc {
        pinctrl_enet1: enet1grp {
                fsl,pins = <
                >;
        };
 
+       pinctrl_gpmi_nand: gpminandgrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_CLE__RAWNAND_CLE         0xb0b1
+                       MX6UL_PAD_NAND_ALE__RAWNAND_ALE         0xb0b1
+                       MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B       0xb0b1
+                       MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
+                       MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B     0xb0b1
+                       MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B       0xb0b1
+                       MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B       0xb0b1
+                       MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00   0xb0b1
+                       MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01   0xb0b1
+                       MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02   0xb0b1
+                       MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03   0xb0b1
+                       MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04   0xb0b1
+                       MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05   0xb0b1
+                       MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06   0xb0b1
+                       MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07   0xb0b1
+               >;
+       };
+
        pinctrl_i2c1: i2c1grp {
                fsl,pins = <
                        MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
                        MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
                >;
        };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK      0x17070
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD      0x10070
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0  0x17070
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1  0x17070
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2  0x17070
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3  0x17070
+                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4  0x17070
+                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5  0x17070
+                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6  0x17070
+                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7  0x17070
+                       MX6UL_PAD_NAND_ALE__USDHC2_RESET_B   0x17070
+               >;
+       };
 };
index 6dc0b569acdf4c803cf0b13667788716028dd159..083d3446c41d0cd49a3c4dc042538ed810ae34f0 100644 (file)
@@ -89,6 +89,8 @@
                                      "pll1_sys";
                        arm-supply = <&reg_arm>;
                        soc-supply = <&reg_soc>;
+                       nvmem-cells = <&cpu_speed_grade>;
+                       nvmem-cell-names = "speed_grade";
                };
        };
 
                compatible = "arm,cortex-a7-pmu";
                interrupt-parent = <&gpc>;
                interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
-               status = "disabled";
        };
 
        soc {
                                reg = <0x02000000 0x40000>;
                                ranges;
 
-                               ecspi1: ecspi@2008000 {
+                               ecspi1: spi@2008000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi2: ecspi@200c000 {
+                               ecspi2: spi@200c000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi3: ecspi@2010000 {
+                               ecspi3: spi@2010000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi4: ecspi@2014000 {
+                               ecspi4: spi@2014000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
                                reg = <0x021b0000 0x4000>;
                        };
 
+                       weim: weim@21b8000 {
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
+                               reg = <0x021b8000 0x4000>;
+                               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_EIM>;
+                               fsl,weim-cs-gpr = <&gpr>;
+                               status = "disabled";
+                       };
+
                        ocotp: ocotp-ctrl@21bc000 {
                                #address-cells = <1>;
                                #size-cells = <1>;
                                tempmon_temp_grade: temp-grade@20 {
                                        reg = <0x20 4>;
                                };
+
+                               cpu_speed_grade: speed-grade@10 {
+                                       reg = <0x10 4>;
+                               };
                        };
 
                        lcdif: lcdif@21c8000 {
                                status = "disabled";
                        };
 
-                       qspi: qspi@21e0000 {
+                       qspi: spi@21e0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx6ul-qspi", "fsl,imx6sx-qspi";
index 30ef60344af36216bcb8021ebef831beadb6eec0..0ba64546c13b323bcd52033c5fe0e1340df943b9 100644 (file)
@@ -45,7 +45,7 @@
 #include "imx6ul-14x14-evk.dtsi"
 
 / {
-       model = "Freescale i.MX6 UlltraLite 14x14 EVK Board";
+       model = "Freescale i.MX6 UltraLiteLite 14x14 EVK Board";
        compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
 };
 
index fdc46bb09cc1afe647ac2e931caace08f0e0655b..a282a31a4bae00569701840357cc6b20d37fcac1 100644 (file)
  * The pin function ID is a tuple of
  * <mux_reg conf_reg input_reg mux_mode input_val>
  */
+/* signals common for i.MX6UL and i.MX6ULL */
+#undef MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX
+#define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX                    0x00BC 0x0348 0x0644 0x0 0x6
+#undef MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX
+#define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX                    0x00C0 0x034C 0x0644 0x0 0x7
+#undef MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS
+#define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS                     0x00CC 0x0358 0x0640 0x1 0x5
+#undef MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS
+#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS                  0x00D0 0x035C 0x0640 0x1 0x6
+#undef MX6UL_PAD_CSI_DATA02__UART5_DCE_RTS
+#define MX6UL_PAD_CSI_DATA02__UART5_DCE_RTS                      0x01EC 0x0478 0x0640 0x8 0x7
+
+/* signals for i.MX6ULL only */
+#define MX6ULL_PAD_UART1_TX_DATA__UART5_DCE_TX                    0x0084 0x0310 0x0000 0x9 0x0
 #define MX6ULL_PAD_UART1_TX_DATA__UART5_DTE_RX                    0x0084 0x0310 0x0644 0x9 0x4
 #define MX6ULL_PAD_UART1_RX_DATA__UART5_DCE_RX                    0x0088 0x0314 0x0644 0x9 0x5
-#define MX6ULL_PAD_UART1_CTS_B__UART5_DCE_RTS                     0x008C 0x0318 0x0640 0x9 0x3
-#define MX6ULL_PAD_UART1_RTS_B__UART5_DTE_RTS                     0x0090 0x031C 0x0640 0x9 0x4
-#define MX6ULL_PAD_UART5_TX_DATA__UART5_DTE_RX                    0x00BC 0x0348 0x0644 0x0 0x6
-#define MX6ULL_PAD_UART5_RX_DATA__UART5_DCE_RX                    0x00C0 0x034C 0x0644 0x0 0x7
-#define MX6ULL_PAD_ENET1_RX_EN__UART5_DCE_RTS                     0x00CC 0x0358 0x0640 0x1 0x5
-#define MX6ULL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS                  0x00D0 0x035C 0x0640 0x1 0x6
+#define MX6ULL_PAD_UART1_RX_DATA__UART5_DTE_TX                    0x0088 0x0314 0x0000 0x9 0x0
+#define MX6ULL_PAD_UART1_CTS_B__UART5_DCE_CTS                     0x008C 0x0318 0x0000 0x9 0x0
+#define MX6ULL_PAD_UART1_CTS_B__UART5_DTE_RTS                     0x008C 0x0318 0x0640 0x9 0x3
+#define MX6ULL_PAD_UART1_RTS_B__UART5_DCE_RTS                     0x0090 0x031C 0x0640 0x9 0x4
+#define MX6ULL_PAD_UART1_RTS_B__UART5_DTE_CTS                     0x0090 0x031C 0x0000 0x9 0x0
+#define MX6ULL_PAD_UART4_RX_DATA__EPDC_PWRCTRL01                  0x00B8 0x0344 0x0000 0x9 0x0
+#define MX6ULL_PAD_UART5_TX_DATA__EPDC_PWRCTRL02                  0x00BC 0x0348 0x0000 0x9 0x0
+#define MX6ULL_PAD_UART5_RX_DATA__EPDC_PWRCTRL03                  0x00C0 0x034C 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_DATA0__EPDC_SDCE04                    0x00C4 0x0350 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_DATA1__EPDC_SDCE05                    0x00C8 0x0354 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_EN__EPDC_SDCE06                       0x00CC 0x0358 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_DATA0__EPDC_SDCE07                    0x00D0 0x035C 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_DATA1__EPDC_SDCE08                    0x00D4 0x0360 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_EN__EPDC_SDCE09                       0x00D8 0x0364 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_TX_CLK__EPDC_SDOED                       0x00DC 0x0368 0x0000 0x9 0x0
+#define MX6ULL_PAD_ENET1_RX_ER__EPDC_SDOEZ                        0x00E0 0x036C 0x0000 0x9 0x0
 #define MX6ULL_PAD_ENET2_RX_DATA0__EPDC_SDDO08                    0x00E4 0x0370 0x0000 0x9 0x0
 #define MX6ULL_PAD_ENET2_RX_DATA1__EPDC_SDDO09                    0x00E8 0x0374 0x0000 0x9 0x0
 #define MX6ULL_PAD_ENET2_RX_EN__EPDC_SDDO10                       0x00EC 0x0378 0x0000 0x9 0x0
@@ -48,6 +72,8 @@
 #define MX6ULL_PAD_LCD_DATA16__EPDC_GDCLK                         0x0158 0x03E4 0x0000 0x9 0x0
 #define MX6ULL_PAD_LCD_DATA17__EPDC_GDSP                          0x015C 0x03E8 0x0000 0x9 0x0
 #define MX6ULL_PAD_LCD_DATA21__EPDC_SDCE1                         0x016C 0x03F8 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA22__EPDC_SDCE02                        0x0170 0x03FC 0x0000 0x9 0x0
+#define MX6ULL_PAD_LCD_DATA23__EPDC_SDCE03                        0x0174 0x0400 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_MCLK__ESAI_TX3_RX2                         0x01D4 0x0460 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_PIXCLK__ESAI_TX2_RX3                       0x01D8 0x0464 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_VSYNC__ESAI_TX4_RX1                        0x01DC 0x0468 0x0000 0x9 0x0
@@ -55,7 +81,6 @@
 #define MX6ULL_PAD_CSI_DATA00__ESAI_TX_HF_CLK                     0x01E4 0x0470 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_DATA01__ESAI_RX_HF_CLK                     0x01E8 0x0474 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_DATA02__ESAI_RX_FS                         0x01EC 0x0478 0x0000 0x9 0x0
-#define MX6ULL_PAD_CSI_DATA02__UART5_DCE_RTS                      0x01EC 0x0478 0x0640 0x8 0x7
 #define MX6ULL_PAD_CSI_DATA03__ESAI_RX_CLK                        0x01F0 0x047C 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS                         0x01F4 0x0480 0x0000 0x9 0x0
 #define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK                        0x01F8 0x0484 0x0000 0x9 0x0
index cd1776a7015ac0dc6d10630eb45bc93f816b0aae..796ed35d4ac9ae194cce80414f1eb09fd718ba02 100644 (file)
@@ -22,7 +22,7 @@
        >;
        fsl,soc-operating-points = <
                /* KHz  uV */
-               900000  1175000
+               900000  1250000
                792000  1175000
                528000  1175000
                396000  1175000
diff --git a/arch/arm/boot/dts/imx6ulz-14x14-evk.dts b/arch/arm/boot/dts/imx6ulz-14x14-evk.dts
new file mode 100644 (file)
index 0000000..6f1af24
--- /dev/null
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2018 NXP.
+
+/dts-v1/;
+
+#include "imx6ulz.dtsi"
+#include "imx6ul-14x14-evk.dtsi"
+
+/delete-node/ &fec1;
+/delete-node/ &fec2;
+/delete-node/ &lcdif;
+/delete-node/ &tsc;
+
+/ {
+       model = "Freescale i.MX6 ULZ 14x14 EVK Board";
+       compatible = "fsl,imx6ulz-14x14-evk", "fsl,imx6ull", "fsl,imx6ulz";
+
+       /delete-node/ panel;
+};
diff --git a/arch/arm/boot/dts/imx6ulz.dtsi b/arch/arm/boot/dts/imx6ulz.dtsi
new file mode 100644 (file)
index 0000000..ae6d7e5
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2018 NXP.
+
+#include "imx6ull.dtsi"
+
+/ {
+       aliases {
+               /delete-property/ ethernet0;
+               /delete-property/ ethernet1;
+               /delete-property/ i2c2;
+               /delete-property/ i2c3;
+               /delete-property/ serial4;
+               /delete-property/ serial5;
+               /delete-property/ serial6;
+               /delete-property/ serial7;
+               /delete-property/ spi2;
+               /delete-property/ spi3;
+       };
+};
+
+/delete-node/ &adc1;
+/delete-node/ &can1;
+/delete-node/ &can2;
+/delete-node/ &ecspi3;
+/delete-node/ &ecspi4;
+/delete-node/ &epit2;
+/delete-node/ &gpt2;
+/delete-node/ &i2c3;
+/delete-node/ &i2c4;
+/delete-node/ &pwm5;
+/delete-node/ &pwm6;
+/delete-node/ &pwm7;
+/delete-node/ &pwm8;
+/delete-node/ &uart5;
+/delete-node/ &uart6;
+/delete-node/ &uart7;
+/delete-node/ &uart8;
index c9b3c60b0eb22fe3ac4f8ab05f1a17209e96ee5d..f1bafdaa7e1a53e9166c98587eaefa74671cf1c5 100644 (file)
                        label = "Volume Up";
                        gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_VOLUMEUP>;
+                       wakeup-source;
                };
 
                volume-down {
                        label = "Volume Down";
                        gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_VOLUMEDOWN>;
+                       wakeup-source;
                };
        };
 
index efbdeaaa8dcd11d892c1c28abd8aede0f20345f7..826224bf7f4fe8f8320671a15845c37beb06cdd4 100644 (file)
@@ -20,6 +20,7 @@
                        reg = <1>;
                        clock-frequency = <996000000>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       cpu-idle-states = <&cpu_sleep_wait>;
                };
        };
 
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       port {
-                               etm1_out_port: endpoint {
-                                       remote-endpoint = <&ca_funnel_in_port1>;
+                       out-ports {
+                               port {
+                                       etm1_out_port: endpoint {
+                                               remote-endpoint = <&ca_funnel_in_port1>;
+                                       };
                                };
                        };
                };
        };
 };
 
-&ca_funnel_ports {
+&ca_funnel_in_ports {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
        port@1 {
                reg = <1>;
                ca_funnel_in_port1: endpoint {
-                       slave-mode;
                        remote-endpoint = <&etm1_out_port>;
                };
        };
index fa390da636de761fabe196c9c16e2b41b26ba41d..f7ba2c0a24adcc03e5bbc50d40da6158e5564aaf 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2016 NXP Semiconductors.
  * Author: Fabio Estevam <fabio.estevam@nxp.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
        status = "okay";
 };
 
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+};
+
 &i2c4 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
                >;
        };
 
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX7D_PAD_I2C3_SDA__I2C3_SDA     0x4000007f
+                       MX7D_PAD_I2C3_SCL__I2C3_SCL     0x4000007f
+               >;
+       };
+
        pinctrl_i2c4: i2c4grp {
                fsl,pins = <
                        MX7D_PAD_I2C4_SCL__I2C4_SCL     0x4000007f
index a052198f6e9631484a7e6d08907110a427db3dc1..aa8df7d93b2e26d3fcd81c1c3bf13d41b52ff07f 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
+               idle-states {
+                       entry-method = "psci";
+
+                       cpu_sleep_wait: cpu-sleep-wait {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010000>;
+                               local-timer-stop;
+                               entry-latency-us = <100>;
+                               exit-latency-us = <50>;
+                               min-residency-us = <1000>;
+                       };
+               };
+
                cpu0: cpu@0 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
@@ -61,6 +74,7 @@
                        clock-frequency = <792000000>;
                        clock-latency = <61036>; /* two CLK32 periods */
                        clocks = <&clks IMX7D_CLK_ARM>;
+                       cpu-idle-states = <&cpu_sleep_wait>;
                };
        };
 
                 */
                compatible = "arm,coresight-replicator";
 
-               ports {
+               out-ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
                                /* replicator output ports */
                                        remote-endpoint = <&etr_in_port>;
                                };
                        };
+               };
 
-                       /* replicator input port */
-                       port@2 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                replicator_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&etf_out_port>;
                                };
                        };
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       ca_funnel_ports: ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               /* funnel input ports */
-                               port@0 {
-                                       reg = <0>;
+                       ca_funnel_in_ports: in-ports {
+                               port {
                                        ca_funnel_in_port0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm0_out_port>;
                                        };
                                };
 
-                               /* funnel output port */
-                               port@2 {
-                                       reg = <0>;
+                               /* the other input ports are not connect to anything */
+                       };
+
+                       out-ports {
+                               port {
                                        ca_funnel_out_port0: endpoint {
                                                remote-endpoint = <&hugo_funnel_in_port0>;
                                        };
                                };
 
-                               /* the other input ports are not connect to anything */
                        };
                };
 
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       port {
-                               etm0_out_port: endpoint {
-                                       remote-endpoint = <&ca_funnel_in_port0>;
+                       out-ports {
+                               port {
+                                       etm0_out_port: endpoint {
+                                               remote-endpoint = <&ca_funnel_in_port0>;
+                                       };
                                };
                        };
                };
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
-                               /* funnel input ports */
                                port@0 {
                                        reg = <0>;
                                        hugo_funnel_in_port0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&ca_funnel_out_port0>;
                                        };
                                };
                                port@1 {
                                        reg = <1>;
                                        hugo_funnel_in_port1: endpoint {
-                                               slave-mode; /* M4 input */
+                                               /* M4 input */
                                        };
                                };
+                               /* the other input ports are not connect to anything */
+                       };
 
-                               port@2 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        hugo_funnel_out_port0: endpoint {
                                                remote-endpoint = <&etf_in_port>;
                                        };
                                };
-
-                               /* the other input ports are not connect to anything */
                        };
                };
 
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        etf_in_port: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&hugo_funnel_out_port0>;
                                        };
                                };
+                       };
 
-                               port@1 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        etf_out_port: endpoint {
                                                remote-endpoint = <&replicator_in_port0>;
                                        };
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       port {
-                               etr_in_port: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out_port1>;
+                       in-ports {
+                               port {
+                                       etr_in_port: endpoint {
+                                               remote-endpoint = <&replicator_out_port1>;
+                                       };
                                };
                        };
                };
                        clocks = <&clks IMX7D_MAIN_AXI_ROOT_CLK>;
                        clock-names = "apb_pclk";
 
-                       port {
-                               tpiu_in_port: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out_port0>;
+                       in-ports {
+                               port {
+                                       tpiu_in_port: endpoint {
+                                               remote-endpoint = <&replicator_out_port0>;
+                                       };
                                };
                        };
                };
                                        clock-names = "snvs-rtc";
                                };
 
-                               snvs_poweroff: snvs-poweroff {
-                                       compatible = "syscon-poweroff";
-                                       regmap = <&snvs>;
-                                       offset = <0x38>;
-                                       value = <0x60>;
-                                       mask = <0x60>;
-                               };
-
                                snvs_pwrkey: snvs-powerkey {
                                        compatible = "fsl,sec-v4.0-pwrkey";
                                        regmap = <&snvs>;
                                status = "disabled";
                        };
 
-                       ecspi4: ecspi@30630000 {
+                       ecspi4: spi@30630000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
                                reg = <0x30800000 0x100000>;
                                ranges;
 
-                               ecspi1: ecspi@30820000 {
+                               ecspi1: spi@30820000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi2: ecspi@30830000 {
+                               ecspi2: spi@30830000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
                                        status = "disabled";
                                };
 
-                               ecspi3: ecspi@30840000 {
+                               ecspi3: spi@30840000 {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        compatible = "fsl,imx7d-ecspi", "fsl,imx51-ecspi";
                                status = "disabled";
                        };
 
+                       mu0a: mailbox@30aa0000 {
+                               compatible = "fsl,imx7s-mu", "fsl,imx6sx-mu";
+                               reg = <0x30aa0000 0x10000>;
+                               interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX7D_MU_ROOT_CLK>;
+                               #mbox-cells = <2>;
+                               status = "disabled";
+                       };
+
+                       mu0b: mailbox@30ab0000 {
+                               compatible = "fsl,imx7s-mu", "fsl,imx6sx-mu";
+                               reg = <0x30ab0000 0x10000>;
+                               interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX7D_MU_ROOT_CLK>;
+                               #mbox-cells = <2>;
+                               fsl,mu-side-b;
+                               status = "disabled";
+                       };
+
                        usbotg1: usb@30b10000 {
                                compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
                                reg = <0x30b10000 0x200>;
index fe511775b518cea36ce072d7817f607d366d4908..85f6b017803a0ea5fb4c02dc7a0415c79981e44d 100644 (file)
 #define IMX7ULP_PAD_PTC13__LPI2C7_SDA                                0x0034 0x030c 0x5 0x1
 #define IMX7ULP_PAD_PTC13__TPM7_CLKIN                                0x0034 0x02f4 0x6 0x1
 #define IMX7ULP_PAD_PTC13__FB_AD13                                   0x0034 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC13__USB0_ID                                   0x0034 0x0338 0xb 0x1
 #define IMX7ULP_PAD_PTC14__PTC14                                     0x0038 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTC14__TRACE_D1                                  0x0038 0x0000 0xa 0x0
 #define IMX7ULP_PAD_PTC14__FXIO1_D10                                 0x0038 0x022c 0x2 0x1
 #define IMX7ULP_PAD_PTC16__LPSPI3_SIN                                0x0040 0x0324 0x3 0x1
 #define IMX7ULP_PAD_PTC16__TPM7_CH2                                  0x0040 0x02e4 0x6 0x1
 #define IMX7ULP_PAD_PTC16__FB_ALE_FB_CS1_B_FB_TS_B                   0x0040 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC16__USB1_OC2                                  0x0040 0x0334 0xb 0x1
 #define IMX7ULP_PAD_PTC17__PTC17                                     0x0044 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTC17__FXIO1_D13                                 0x0044 0x0238 0x2 0x1
 #define IMX7ULP_PAD_PTC17__LPSPI3_SOUT                               0x0044 0x0328 0x3 0x1
 #define IMX7ULP_PAD_PTC18__LPSPI3_SCK                                0x0048 0x0320 0x3 0x1
 #define IMX7ULP_PAD_PTC18__TPM6_CH0                                  0x0048 0x02d0 0x6 0x1
 #define IMX7ULP_PAD_PTC18__FB_OE_B                                   0x0048 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC18__USB0_ID                                   0x0048 0x0338 0xb 0x2
+#define IMX7ULP_PAD_PTC18__VIU_DE                                    0x0048 0x033c 0xc 0x1
 #define IMX7ULP_PAD_PTC19__PTC19                                     0x004c 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTC19__FXIO1_D15                                 0x004c 0x0240 0x2 0x1
 #define IMX7ULP_PAD_PTC19__LPSPI3_PCS0                               0x004c 0x0310 0x3 0x1
 #define IMX7ULP_PAD_PTC19__TPM6_CH1                                  0x004c 0x02d4 0x6 0x1
 #define IMX7ULP_PAD_PTC19__FB_A16                                    0x004c 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTC19__USB0_ID                                   0x004c 0x0338 0xa 0x3
+#define IMX7ULP_PAD_PTC19__USB1_PWR2                                 0x004c 0x0000 0xb 0x0
+#define IMX7ULP_PAD_PTC19__VIU_DE                                    0x004c 0x033c 0xc 0x3
 #define IMX7ULP_PAD_PTD0__PTD0                                       0x0080 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTD0__SDHC0_RESET_B                              0x0080 0x0000 0x8 0x0
 #define IMX7ULP_PAD_PTD1__PTD1                                       0x0084 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE5__LPI2C5_SDA                                 0x0114 0x02c0 0x5 0x2
 #define IMX7ULP_PAD_PTE5__TPM5_CH0                                   0x0114 0x02c4 0x6 0x2
 #define IMX7ULP_PAD_PTE5__SDHC1_D2                                   0x0114 0x0000 0x8 0x0
+#define IMX7ULP_PAD_PTE5__VIU_DE                                     0x0114 0x033c 0xc 0x2
 #define IMX7ULP_PAD_PTE6__PTE6                                       0x0118 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE6__FXIO1_D25                                  0x0118 0x0000 0x2 0x0
 #define IMX7ULP_PAD_PTE6__LPSPI2_SCK                                 0x0118 0x02ac 0x3 0x2
 #define IMX7ULP_PAD_PTE6__TPM7_CH3                                   0x0118 0x02e8 0x6 0x2
 #define IMX7ULP_PAD_PTE6__SDHC1_D4                                   0x0118 0x0000 0x8 0x0
 #define IMX7ULP_PAD_PTE6__FB_A17                                     0x0118 0x0000 0x9 0x0
+#define IMX7ULP_PAD_PTE6__USB0_OC                                    0x0118 0x0330 0xb 0x1
 #define IMX7ULP_PAD_PTE7__PTE7                                       0x011c 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE7__TRACE_D7                                   0x011c 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE7__USB0_PWR                                   0x011c 0x0000 0xb 0x0
 #define IMX7ULP_PAD_PTE7__VIU_FID                                    0x011c 0x0000 0xc 0x0
 #define IMX7ULP_PAD_PTE7__FXIO1_D24                                  0x011c 0x0000 0x2 0x0
 #define IMX7ULP_PAD_PTE7__LPSPI2_PCS0                                0x011c 0x029c 0x3 0x2
 #define IMX7ULP_PAD_PTE11__FB_A20                                    0x012c 0x0000 0x9 0x0
 #define IMX7ULP_PAD_PTE12__PTE12                                     0x0130 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE12__TRACE_D2                                  0x0130 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE12__USB1_OC2                                  0x0130 0x0334 0xb 0x2
 #define IMX7ULP_PAD_PTE12__VIU_D20                                   0x0130 0x0000 0xc 0x0
 #define IMX7ULP_PAD_PTE12__FXIO1_D19                                 0x0130 0x0000 0x2 0x0
 #define IMX7ULP_PAD_PTE12__LPSPI3_SIN                                0x0130 0x0324 0x3 0x2
 #define IMX7ULP_PAD_PTE12__FB_A21                                    0x0130 0x0000 0x9 0x0
 #define IMX7ULP_PAD_PTE13__PTE13                                     0x0134 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE13__TRACE_D1                                  0x0134 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE13__USB1_PWR2                                 0x0134 0x0000 0xb 0x0
 #define IMX7ULP_PAD_PTE13__VIU_D21                                   0x0134 0x0000 0xc 0x0
 #define IMX7ULP_PAD_PTE13__FXIO1_D18                                 0x0134 0x0000 0x2 0x0
 #define IMX7ULP_PAD_PTE13__LPSPI3_SOUT                               0x0134 0x0328 0x3 0x2
 #define IMX7ULP_PAD_PTE13__FB_A22                                    0x0134 0x0000 0x9 0x0
 #define IMX7ULP_PAD_PTE14__PTE14                                     0x0138 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE14__TRACE_D0                                  0x0138 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE14__USB0_OC                                   0x0138 0x0330 0xb 0x2
 #define IMX7ULP_PAD_PTE14__VIU_D22                                   0x0138 0x0000 0xc 0x0
 #define IMX7ULP_PAD_PTE14__FXIO1_D17                                 0x0138 0x0000 0x2 0x0
 #define IMX7ULP_PAD_PTE14__LPSPI3_SCK                                0x0138 0x0320 0x3 0x2
 #define IMX7ULP_PAD_PTE14__FB_A23                                    0x0138 0x0000 0x9 0x0
 #define IMX7ULP_PAD_PTE15__PTE15                                     0x013c 0x0000 0x1 0x0
 #define IMX7ULP_PAD_PTE15__TRACE_CLKOUT                              0x013c 0x0000 0xa 0x0
+#define IMX7ULP_PAD_PTE15__USB0_PWR                                  0x013c 0x0000 0xb 0x0
 #define IMX7ULP_PAD_PTE15__VIU_D23                                   0x013c 0x0000 0xc 0x0
 #define IMX7ULP_PAD_PTE15__FXIO1_D16                                 0x013c 0x0000 0x2 0x0
 #define IMX7ULP_PAD_PTE15__LPSPI3_PCS0                               0x013c 0x0310 0x3 0x2
 #define IMX7ULP_PAD_PTE15__TPM6_CH1                                  0x013c 0x02d4 0x6 0x2
 #define IMX7ULP_PAD_PTE15__FB_A24                                    0x013c 0x0000 0x9 0x0
 #define IMX7ULP_PAD_PTF0__PTF0                                       0x0180 0x0000 0x1 0x0
-#define IMX7ULP_PAD_PTF0__VIU_DE                                     0x0180 0x0000 0xc 0x0
+#define IMX7ULP_PAD_PTF0__VIU_DE                                     0x0180 0x033c 0xc 0x0
 #define IMX7ULP_PAD_PTF0__LPUART4_CTS_B                              0x0180 0x0244 0x4 0x3
 #define IMX7ULP_PAD_PTF0__LPI2C4_SCL                                 0x0180 0x0278 0x5 0x3
 #define IMX7ULP_PAD_PTF0__TPM4_CLKIN                                 0x0180 0x0298 0x6 0x3
index 5cae74eb6cddfb41c9d53317c24d389321af0750..ca9154dd8052b43de8ed9e945b6896260c1db1f9 100644 (file)
        clock-frequency = <100000000>;
 };
 
-&pciec {
-       status = "okay";
-};
-
 &pfc {
        can0_pins: can0 {
                groups = "can0_data_d";
index 738b44cf2b0bbdd5eb398af5fff2d6eb60095b53..1c833105d6c5495f6ec2116d888f82b44dce4371 100644 (file)
                        clock-names = "fck", "mmchsdb_fck";
                };
 
-               qspi: qspi@2940000 {
+               qspi: spi@2940000 {
                        compatible = "ti,k2g-qspi", "cdns,qspi-nor";
                        #address-cells = <1>;
                        #size-cells = <0>;
index abff7ef7c9cd6a571a5966ff75f473215c737233..b7303a4e4236f35f370153645989fabb0366d0a6 100644 (file)
                         * ssp0 and spi1 are shared pins;
                         * enable one in your board dts, as needed.
                         */
-                       ssp0: ssp@20084000 {
+                       ssp0: spi@20084000 {
                                compatible = "arm,pl022", "arm,primecell";
                                reg = <0x20084000 0x1000>;
                                interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
                         * ssp1 and spi2 are shared pins;
                         * enable one in your board dts, as needed.
                         */
-                       ssp1: ssp@2008c000 {
+                       ssp1: spi@2008c000 {
                                compatible = "arm,pl022", "arm,primecell";
                                reg = <0x2008c000 0x1000>;
                                interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;
index 499f41a2c6f0af40c235c5098cd871d7cec4ea92..923a25760516562db04c715235d5e4a427969914 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
                #size-cells = <1>;
                compatible = "cfi-flash";
                reg = <0x0 0x0 0x8000000>;
+               big-endian;
                bank-width = <2>;
                device-width = <1>;
        };
index f0c949d748331939be497ddb4d93c2364a85347e..8b48c3c7cd216131aecaca4f21a49c8eea842734 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
                #size-cells = <1>;
                compatible = "cfi-flash";
                reg = <0x0 0x0 0x8000000>;
+               big-endian;
                bank-width = <2>;
                device-width = <1>;
        };
index f18490548c785eed2b4909bc6f8d258135e0ebba..bdd6e66a79ad097c3487a157ec0f87f104078cf8 100644 (file)
                        big-endian;
                };
 
-               qspi: quadspi@1550000 {
+               qspi: spi@1550000 {
                        compatible = "fsl,ls1021a-qspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
-               dspi0: dspi@2100000 {
+               dspi0: spi@2100000 {
                        compatible = "fsl,ls1021a-v1.0-dspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
-               dspi1: dspi@2110000 {
+               dspi1: spi@2110000 {
                        compatible = "fsl,ls1021a-v1.0-dspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
                        clocks = <&clockgen 4 1>;
+                       dma-names = "tx", "rx";
+                       dmas = <&edma0 1 39>, <&edma0 1 38>;
                        status = "disabled";
                };
 
                        interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
                        clocks = <&clockgen 4 1>;
+                       dma-names = "tx", "rx";
+                       dmas = <&edma0 1 37>, <&edma0 1 36>;
                        status = "disabled";
                };
 
                        interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
                        clocks = <&clockgen 4 1>;
+                       dma-names = "tx", "rx";
+                       dmas = <&edma0 1 35>, <&edma0 1 34>;
                        status = "disabled";
                };
 
index d77dcf890cfc82b5c05c88149694f8687e14072c..7162e0ca05b0a5d477fd1369f127e8bef67e8413 100644 (file)
                #clock-cells = <1>;
                #reset-cells = <1>;
                compatible = "amlogic,meson8-clkc";
-               reg = <0x8000 0x4>, <0x4000 0x460>;
+               reg = <0x8000 0x4>, <0x4000 0x400>;
        };
 
        reset: reset-controller@4404 {
diff --git a/arch/arm/boot/dts/meson8b-ec100.dts b/arch/arm/boot/dts/meson8b-ec100.dts
new file mode 100644 (file)
index 0000000..0872f6e
--- /dev/null
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+#include "meson8b.dtsi"
+
+/ {
+       model = "Endless Computers Endless Mini";
+       compatible = "endless,ec100", "amlogic,meson8b";
+
+       aliases {
+               serial0 = &uart_AO;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x40000000 0x40000000>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys-polled";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               poll-interval = <100>;
+
+               pal-switch {
+                       label = "pal";
+                       linux,input-type = <EV_SW>;
+                       linux,code = <KEY_SWITCHVIDEOMODE>;
+                       gpios = <&gpio GPIOH_7 GPIO_ACTIVE_LOW>;
+               };
+
+               ntsc-switch {
+                       label = "ntsc";
+                       linux,input-type = <EV_SW>;
+                       linux,code = <KEY_SWITCHVIDEOMODE>;
+                       gpios = <&gpio GPIOH_8 GPIO_ACTIVE_HIGH>;
+               };
+
+               power-button {
+                       label = "power";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio GPIOH_9 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       gpio-poweroff {
+               compatible = "gpio-poweroff";
+               /*
+                * shutdown is managed by the EC (embedded micro-controller)
+                * which is configured through GPIOAO_2 (poweroff GPIO) and
+                * GPIOAO_7 (power LED, which has to go LOW as well).
+                */
+               gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
+               timeout-ms = <20000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               power {
+                       label = "ec100:red:power";
+                       /*
+                        * Needs to go LOW (together with the poweroff GPIO)
+                        * during shutdown to allow the EC (embedded
+                        * micro-controller) to shutdown the system. Setting
+                        * the output to LOW signals the EC to start a
+                        * "breathing"/pulsing effect until the power is fully
+                        * turned off.
+                        */
+                       gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+               };
+       };
+
+       usb_vbus: regulator-usb-vbus {
+               compatible = "regulator-fixed";
+
+               regulator-name = "USB_VBUS";
+
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vcc_5v: regulator-vcc5v {
+               compatible = "regulator-fixed";
+
+               regulator-name = "VCC5V";
+
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               gpio = <&gpio GPIODV_29 GPIO_ACTIVE_LOW>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vcck: regulator-vcck {
+               compatible = "pwm-regulator";
+
+               regulator-name = "VCCK";
+               regulator-min-microvolt = <860000>;
+               regulator-max-microvolt = <1140000>;
+
+               pwms = <&pwm_cd 0 1148 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vcc_1v8: regulator-vcc1v8 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "VCC1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       vcc_3v3: regulator-vcc3v3 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "VCC3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vcck>;
+};
+
+&ethmac {
+       status = "okay";
+
+       pinctrl-0 = <&eth_rmii_pins>;
+       pinctrl-names = "default";
+
+       phy-handle = <&eth_phy0>;
+       phy-mode = "rmii";
+
+       snps,reset-gpio = <&gpio GPIOH_4 0>;
+       snps,reset-delays-us = <0 10000 1000000>;
+       snps,reset-active-low;
+
+       mdio {
+               compatible = "snps,dwmac-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               eth_phy0: ethernet-phy@0 {
+                       /* IC Plus IP101A/G (0x02430c54) */
+                       reg = <0>;
+               };
+       };
+};
+
+&i2c_A {
+       status = "okay";
+       pinctrl-0 = <&i2c_a_pins>;
+       pinctrl-names = "default";
+
+       rt5640: codec@1c {
+               compatible = "realtek,rt5640";
+               reg = <0x1c>;
+               interrupt-parent = <&gpio_intc>;
+               interrupts = <13 IRQ_TYPE_EDGE_BOTH>; /* GPIOAO_13 */
+               realtek,in1-differential;
+       };
+};
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vcc_1v8>;
+};
+
+&sdio {
+       status = "okay";
+
+       pinctrl-0 = <&sd_b_pins>;
+       pinctrl-names = "default";
+
+       /* SD card */
+       sd_card_slot: slot@1 {
+               compatible = "mmc-slot";
+               reg = <1>;
+               status = "okay";
+
+               bus-width = <4>;
+               no-sdio;
+               cap-mmc-highspeed;
+               cap-sd-highspeed;
+               disable-wp;
+
+               cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+               cd-inverted;
+
+               vmmc-supply = <&vcc_3v3>;
+       };
+};
+
+&pwm_cd {
+       status = "okay";
+       pinctrl-0 = <&pwm_c1_pins>;
+       pinctrl-names = "default";
+       clocks = <&clkc CLKID_XTAL>;
+       clock-names = "clkin0";
+};
+
+/* exposed through the pin headers labeled "URDUG1" on the top of the PCB */
+&uart_AO {
+       status = "okay";
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
+};
+
+/*
+ * connected to the Bluetooth part of the RTL8723BS SDIO wifi / Bluetooth
+ * combo chip. This is only available on the variant with 2GB RAM.
+ */
+&uart_B {
+       status = "okay";
+       pinctrl-0 = <&uart_b0_pins>, <&uart_b0_cts_rts_pins>;
+       pinctrl-names = "default";
+       uart-has-rtscts;
+};
+
+&usb1 {
+       status = "okay";
+       vbus-supply = <&usb_vbus>;
+};
+
+&usb1_phy {
+       status = "okay";
+};
index ef3177d3da3dc85d5cb2d2d786a59d368c4189cd..58669abda2594d4979086695db3af0aee095983b 100644 (file)
                mmc0 = &sd_card_slot;
        };
 
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
        memory {
                reg = <0x40000000 0x40000000>;
        };
                };
        };
 
+       p5v0: regulator-p5v0 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "P5V0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
        tflash_vdd: regulator-tflash_vdd {
                /*
                 * signal name from schematics: TFLASH_VDD_EN
@@ -81,6 +93,8 @@
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
 
+               vin-supply = <&vcc_3v3>;
+
                gpio = <&gpio GPIOY_12 GPIO_ACTIVE_HIGH>;
                enable-active-high;
        };
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <3300000>;
 
+               vin-supply = <&vcc_3v3>;
+
                /*
                 * signal name from schematics: TF_3V3N_1V8_EN
                 */
                states = <3300000 0
                          1800000 1>;
        };
+
+       vcc_1v8: regulator-vcc-1v8 {
+               /*
+                * RICHTEK RT9179 configured for a fixed output voltage of
+                * 1.8V. This supplies not only VCC1V8 but also IOREF_1V8 and
+                * VDD1V8 according to the schematics.
+                */
+               compatible = "regulator-fixed";
+
+               regulator-name = "VCC1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+
+               vin-supply = <&p5v0>;
+       };
+
+       vcc_3v3: regulator-vcc-3v3 {
+               /*
+                * Monolithic Power Systems MP2161 configured for a fixed
+                * output voltage of 3.3V. This supplies not only VCC3V3 but
+                * also VDD3V3 and VDDIO_AO3V3 according to the schematics.
+                */
+               compatible = "regulator-fixed";
+
+               regulator-name = "VCC3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               vin-supply = <&p5v0>;
+       };
+
+       vcck: regulator-vcck {
+               /* Monolithic Power Systems MP2161 */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VCCK";
+               regulator-min-microvolt = <860000>;
+               regulator-max-microvolt = <1140000>;
+
+               vin-supply = <&p5v0>;
+
+               pwms = <&pwm_cd 0 12218 0>;
+               pwm-dutycycle-range = <91 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vddc_ddr: regulator-vddc-ddr {
+               /*
+                * Monolithic Power Systems MP2161 configured for a fixed
+                * output voltage of 1.5V. This supplies not only DDR_VDDC but
+                * also DDR3_1V5 according to the schematics.
+                */
+               compatible = "regulator-fixed";
+
+               regulator-name = "DDR_VDDC";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+
+               vin-supply = <&p5v0>;
+       };
+
+       vdd_rtc: regulator-vdd-rtc {
+               /*
+                * Torex Semiconductor XC6215 configured for a fixed output of
+                * 0.9V.
+                */
+               compatible = "regulator-fixed";
+
+               regulator-name = "VDD_RTC";
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+
+               vin-supply = <&vcc_3v3>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vcck>;
 };
 
 &ethmac {
        pinctrl-names = "default";
 };
 
+&saradc {
+       status = "okay";
+       vref-supply = <&vcc_1v8>;
+};
+
 &sdio {
        status = "okay";
 
        };
 };
 
+&pwm_cd {
+       status = "okay";
+       pinctrl-0 = <&pwm_c1_pins>;
+       pinctrl-names = "default";
+       clocks = <&clkc CLKID_XTAL>;
+       clock-names = "clkin0";
+};
+
 &uart_AO {
        status = "okay";
        pinctrl-0 = <&uart_ao_a_pins>;
index 08f7f6be7254e5e54e0f9bd5ff6790fbfa108dea..cd1ca9dda126bb8467107e715f9ff6402f4a181e 100644 (file)
                #clock-cells = <1>;
                #reset-cells = <1>;
                compatible = "amlogic,meson8b-clkc";
-               reg = <0x8000 0x4>, <0x4000 0x460>;
+               reg = <0x8000 0x4>, <0x4000 0x400>;
        };
 
        reset: reset-controller@4404 {
                        };
                };
 
+               eth_rmii_pins: eth-rmii {
+                       mux {
+                               groups = "eth_tx_en",
+                                        "eth_txd1_0",
+                                        "eth_txd0_0",
+                                        "eth_rx_clk",
+                                        "eth_rx_dv",
+                                        "eth_rxd1",
+                                        "eth_rxd0",
+                                        "eth_mdio_en",
+                                        "eth_mdc";
+                               function = "ethernet";
+                       };
+               };
+
+               i2c_a_pins: i2c-a {
+                       mux {
+                               groups = "i2c_sda_a", "i2c_sck_a";
+                               function = "i2c_a";
+                       };
+               };
+
                sd_b_pins: sd-b {
                        mux {
                                groups = "sd_d0_b", "sd_d1_b", "sd_d2_b",
                                function = "sd_b";
                        };
                };
+
+               pwm_c1_pins: pwm-c1 {
+                       mux {
+                               groups = "pwm_c1";
+                               function = "pwm_c";
+                       };
+               };
+
+               uart_b0_pins: uart-b0 {
+                       mux {
+                               groups = "uart_tx_b0",
+                                      "uart_rx_b0";
+                               function = "uart_b";
+                       };
+               };
+
+               uart_b0_cts_rts_pins: uart-b0-cts-rts {
+                       mux {
+                               groups = "uart_cts_b0",
+                                      "uart_rts_b0";
+                               function = "uart_b";
+                       };
+               };
        };
 };
 
index 1cdc346a05e8be4deca54a1a20631f7312d91b57..d01bdee6f2f3467aaee7bf5eba3cf4f019f7e08d 100644 (file)
@@ -13,6 +13,7 @@
 #include <dt-bindings/power/mt2701-power.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/phy/phy.h>
+#include <dt-bindings/memory/mt2701-larb-port.h>
 #include <dt-bindings/reset/mt2701-resets.h>
 #include <dt-bindings/thermal/thermal.h>
 
                };
        };
 
+       pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 5 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 6 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 7 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
        system_clk: dummy13m {
                compatible = "fixed-clock";
                clock-frequency = <13000000>;
                clock-names = "system-clk", "rtc-clk";
        };
 
+       smi_common: smi@1000c000 {
+               compatible = "mediatek,mt7623-smi-common",
+                            "mediatek,mt2701-smi-common";
+               reg = <0 0x1000c000 0 0x1000>;
+               clocks = <&infracfg CLK_INFRA_SMI>,
+                        <&mmsys CLK_MM_SMI_COMMON>,
+                        <&infracfg CLK_INFRA_SMI>;
+               clock-names = "apb", "smi", "async";
+               power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
+       };
+
        pwrap: pwrap@1000d000 {
                compatible = "mediatek,mt7623-pwrap",
                             "mediatek,mt2701-pwrap";
                reg = <0 0x10200100 0 0x1c>;
        };
 
+       iommu: mmsys_iommu@10205000 {
+               compatible = "mediatek,mt7623-m4u",
+                            "mediatek,mt2701-m4u";
+               reg = <0 0x10205000 0 0x1000>;
+               interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&infracfg CLK_INFRA_M4U>;
+               clock-names = "bclk";
+               mediatek,larbs = <&larb0 &larb1 &larb2>;
+               #iommu-cells = <1>;
+       };
+
        efuse: efuse@10206000 {
                compatible = "mediatek,mt7623-efuse",
                             "mediatek,mt8173-efuse";
                status = "disabled";
        };
 
+       g3dsys: syscon@13000000 {
+               compatible = "mediatek,mt7623-g3dsys",
+                            "mediatek,mt2701-g3dsys",
+                            "syscon";
+               reg = <0 0x13000000 0 0x200>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+       mmsys: syscon@14000000 {
+               compatible = "mediatek,mt7623-mmsys",
+                            "mediatek,mt2701-mmsys",
+                            "syscon";
+               reg = <0 0x14000000 0 0x1000>;
+               #clock-cells = <1>;
+       };
+
+       larb0: larb@14010000 {
+               compatible = "mediatek,mt7623-smi-larb",
+                            "mediatek,mt2701-smi-larb";
+               reg = <0 0x14010000 0 0x1000>;
+               mediatek,smi = <&smi_common>;
+               mediatek,larb-id = <0>;
+               clocks = <&mmsys CLK_MM_SMI_LARB0>,
+                        <&mmsys CLK_MM_SMI_LARB0>;
+               clock-names = "apb", "smi";
+               power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>;
+       };
+
+       imgsys: syscon@15000000 {
+               compatible = "mediatek,mt7623-imgsys",
+                            "mediatek,mt2701-imgsys",
+                            "syscon";
+               reg = <0 0x15000000 0 0x1000>;
+               #clock-cells = <1>;
+       };
+
+       larb2: larb@15001000 {
+               compatible = "mediatek,mt7623-smi-larb",
+                            "mediatek,mt2701-smi-larb";
+               reg = <0 0x15001000 0 0x1000>;
+               mediatek,smi = <&smi_common>;
+               mediatek,larb-id = <2>;
+               clocks = <&imgsys CLK_IMG_SMI_COMM>,
+                        <&imgsys CLK_IMG_SMI_COMM>;
+               clock-names = "apb", "smi";
+               power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
+       };
+
+       jpegdec: jpegdec@15004000 {
+               compatible = "mediatek,mt7623-jpgdec",
+                            "mediatek,mt2701-jpgdec";
+               reg = <0 0x15004000 0 0x1000>;
+               interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW>;
+               clocks =  <&imgsys CLK_IMG_JPGDEC_SMI>,
+                         <&imgsys CLK_IMG_JPGDEC>;
+               clock-names = "jpgdec-smi",
+                             "jpgdec";
+               power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
+               mediatek,larb = <&larb2>;
+               iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
+                        <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
+       };
+
+       vdecsys: syscon@16000000 {
+               compatible = "mediatek,mt7623-vdecsys",
+                            "mediatek,mt2701-vdecsys",
+                            "syscon";
+               reg = <0 0x16000000 0 0x1000>;
+               #clock-cells = <1>;
+       };
+
+       larb1: larb@16010000 {
+               compatible = "mediatek,mt7623-smi-larb",
+                            "mediatek,mt2701-smi-larb";
+               reg = <0 0x16010000 0 0x1000>;
+               mediatek,smi = <&smi_common>;
+               mediatek,larb-id = <1>;
+               clocks = <&vdecsys CLK_VDEC_CKGEN>,
+                        <&vdecsys CLK_VDEC_LARB>;
+               clock-names = "apb", "smi";
+               power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>;
+       };
+
        hifsys: syscon@1a000000 {
                compatible = "mediatek,mt7623-hifsys",
                             "mediatek,mt2701-hifsys",
                power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
                status = "disabled";
        };
+
+       bdpsys: syscon@1c000000 {
+               compatible = "mediatek,mt7623-bdpsys",
+                            "mediatek,mt2701-bdpsys",
+                            "syscon";
+               reg = <0 0x1c000000 0 0x1000>;
+               #clock-cells = <1>;
+       };
 };
 
 &pio {
index f1d6de8b3c193eee0d88b0465f33de4e122ba266..000bf16de6517df2ec0e3713429ca6efde32e285 100644 (file)
                        dma-names = "tx", "rx";
                };
 
-               mcspi1: mcspi@48098000 {
+               mcspi1: spi@48098000 {
                        compatible = "ti,omap2-mcspi";
                        ti,hwmods = "mcspi1";
                        reg = <0x48098000 0x100>;
                                    "tx2", "rx2", "tx3", "rx3";
                };
 
-               mcspi2: mcspi@4809a000 {
+               mcspi2: spi@4809a000 {
                        compatible = "ti,omap2-mcspi";
                        ti,hwmods = "mcspi2";
                        reg = <0x4809a000 0x100>;
index 84635eeb99cd46ae4d7240dfffbe551cb20a6af8..7f57af2f10acb6f02d42fff742d8be754101a042 100644 (file)
                        ti,timer-alwon;
                };
 
-               mcspi3: mcspi@480b8000 {
+               mcspi3: spi@480b8000 {
                        compatible = "ti,omap2-mcspi";
                        ti,hwmods = "mcspi3";
                        reg = <0x480b8000 0x100>;
index d80587de0bbf565d765969b733a769ed45719cc1..9985ee2aae0c7be84080fa55dd68580904151e74 100644 (file)
 
                clocks = <&emu_src_ck>;
                clock-names = "apb_pclk";
-               port {
-                       etb_in: endpoint {
-                               slave-mode;
-                               remote-endpoint = <&etm_out>;
+               in-ports {
+                       port {
+                               etb_in: endpoint {
+                                       remote-endpoint = <&etm_out>;
+                               };
                        };
                };
        };
 
                clocks = <&emu_src_ck>;
                clock-names = "apb_pclk";
-               port {
-                       etm_out: endpoint {
-                               remote-endpoint = <&etb_in>;
+               out-ports {
+                       port {
+                               etm_out: endpoint {
+                                       remote-endpoint = <&etb_in>;
+                               };
                        };
                };
        };
index 3ca8991a6c3e977e2a16bb30444db4478a61ca0d..91bb50ad9a4f6cdd321efd6a8bc7050629c54fff 100644 (file)
 
                clocks = <&emu_src_ck>;
                clock-names = "apb_pclk";
-               port {
-                       etb_in: endpoint {
-                               slave-mode;
-                               remote-endpoint = <&etm_out>;
+               in-ports {
+                       port {
+                               etb_in: endpoint {
+                                       remote-endpoint = <&etm_out>;
+                               };
                        };
                };
        };
 
                clocks = <&emu_src_ck>;
                clock-names = "apb_pclk";
-               port {
-                       etm_out: endpoint {
-                               remote-endpoint = <&etb_in>;
+               out-ports {
+                       port {
+                               etm_out: endpoint {
+                                       remote-endpoint = <&etb_in>;
+                               };
                        };
                };
        };
index ac830b9177763d32a70b8807e02f35cb039efc17..d5fe55392230de6d2dd7877fb527cb36b3fd63f1 100644 (file)
@@ -10,6 +10,7 @@
 /dts-v1/;
 
 #include "omap36xx.dtsi"
+#include <dt-bindings/input/input.h>
 
 / {
        model = "OMAP3 GTA04";
@@ -28,6 +29,7 @@
 
        aliases {
                display0 = &lcd;
+               display1 = &tv0;
        };
 
        /* fixed 26MHz oscillator */
 
                aux-button {
                        label = "aux";
-                       linux,code = <169>;
+                       linux,code = <KEY_PHONE>;
                        gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
                        wakeup-source;
                };
        };
 
+       antenna-detect {
+               compatible = "gpio-keys";
+
+               gps_antenna_button: gps-antenna-button {
+                       label = "GPS_EXT_ANT";
+                       linux,input-type = <EV_SW>;
+                       linux,code = <SW_LINEIN_INSERT>;
+                       gpios = <&gpio5 16 GPIO_ACTIVE_HIGH>; /* GPIO144 */
+                       interrupt-parent = <&gpio5>;
+                       interrupts = <16 IRQ_TYPE_EDGE_BOTH>;
+                       debounce-interval = <10>;
+                       wakeup-source;
+               };
+       };
+
        sound {
                compatible = "ti,omap-twl4030";
                ti,model = "gta04";
@@ -55,7 +72,7 @@
                ti,mcbsp = <&mcbsp2>;
        };
 
-        /* GSM audio */
+       /* GSM audio */
        sound_telephony {
                compatible = "simple-audio-card";
                simple-audio-card,name = "GTA04 voice";
@@ -78,7 +95,7 @@
                #sound-dai-cells = <0>;
        };
 
-       spi_lcd {
+       spi_lcd: spi_lcd {
                compatible = "spi-gpio";
                #address-cells = <0x1>;
                #size-cells = <0x0>;
        };
 
        tv0: connector {
-               compatible = "svideo-connector";
+               compatible = "composite-video-connector";
                label = "tv";
 
                port {
 
        tv_amp: opa362 {
                compatible = "ti,opa362";
-               enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+               enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;    /* GPIO_23 to enable video out amplifier */
 
                ports {
                        #address-cells = <1>;
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&tca6507 0 GPIO_ACTIVE_LOW>;     /* W2CBW003 reset through tca6507 */
        };
+
+       /* devconf0 setup for mcbsp1 clock pins */
+       pinmux_mcbsp1@48002274 {
+               compatible = "pinctrl-single";
+               reg = <0x48002274 4>;   /* CONTROL_DEVCONF0 */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-single,bit-per-mux;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0x7>;   /* MCBSP1 CLK pinmux */
+               #pinctrl-cells = <2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mcbsp1_devconf0_pins>;
+               mcbsp1_devconf0_pins: pinmux_mcbsp1_devconf0_pins {
+                       /*                   offset bits mask */
+                       pinctrl-single,bits = <0x00 0x08 0x1c>; /* set MCBSP1_CLKR */
+               };
+       };
+
+       /* devconf1 setup for tvout pins */
+       pinmux_tv_out@480022d8 {
+               compatible = "pinctrl-single";
+               reg = <0x480022d8 4>;   /* CONTROL_DEVCONF1 */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-single,bit-per-mux;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0x81>;  /* TV out pin control */
+               #pinctrl-cells = <2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tv_acbias_devconf1_pins>;
+               tv_acbias_devconf1_pins: pinmux_tv_acbias_devconf1_pins {
+                       /*                      offset  bits    mask */
+                       pinctrl-single,bits = <0x00 0x40800 0x40800>;   /* set TVOUTBYPASS and TVOUTACEN */
+               };
+       };
 };
 
 &omap3_pmx_core {
                >;
        };
 
-       backlight_pins: backlight_pins_pimnux {
+       backlight_pins: backlight_pins_pinmux {
                pinctrl-single,pins = <
                        OMAP3_CORE1_IOPAD(0x20ba, MUX_MODE3)            /* gpt11/gpio57 */
                >;
        };
 
        dss_dpi_pins: pinmux_dss_dpi_pins {
-               pinctrl-single,pins = <
+               pinctrl-single,pins = <
                        OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0)   /* dss_pclk.dss_pclk */
                        OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0)   /* dss_hsync.dss_hsync */
                        OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0)   /* dss_vsync.dss_vsync */
                >;
        };
 
+       bmp085_pins: pinmux_bmp085_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2136, PIN_INPUT_PULLUP | MUX_MODE4) /* gpio113 */
+               >;
+       };
+
        bma180_pins: pinmux_bma180_pins {
                pinctrl-single,pins = <
                        OMAP3_CORE1_IOPAD(0x213a, PIN_INPUT_PULLUP | MUX_MODE4) /* gpio115 */
                        OMAP3_CORE1_IOPAD(0x2134, PIN_INPUT_PULLUP | MUX_MODE4) /* gpio112 */
                >;
        };
+
+       penirq_pins: pinmux_penirq_pins {
+               pinctrl-single,pins = <
+                       /* here we could enable to wakeup the cpu from suspend by a pen touch */
+                       OMAP3_CORE1_IOPAD(0x2194, PIN_INPUT_PULLUP | MUX_MODE4) /* gpio160 */
+               >;
+       };
+
+       camera_pins: pinmux_camera_pins {
+               pinctrl-single,pins = <
+                       /* set up parallel camera interface */
+                       OMAP3_CORE1_IOPAD(0x210c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_hs */
+                       OMAP3_CORE1_IOPAD(0x210e, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_vs */
+                       OMAP3_CORE1_IOPAD(0x2110, PIN_OUTPUT | MUX_MODE0) /* cam_xclka */
+                       OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_pclk */
+                       OMAP3_CORE1_IOPAD(0x2114, PIN_OUTPUT | MUX_MODE4) /* cam_fld = gpio_98 */
+                       OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d0 */
+                       OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d1 */
+                       OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d2 */
+                       OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d3 */
+                       OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d4 */
+                       OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d5 */
+                       OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d6 */
+                       OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d7 */
+                       OMAP3_CORE1_IOPAD(0x2126, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d8 */
+                       OMAP3_CORE1_IOPAD(0x2128, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d9 */
+                       OMAP3_CORE1_IOPAD(0x212a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d10 */
+                       OMAP3_CORE1_IOPAD(0x212c, PIN_INPUT_PULLDOWN | MUX_MODE0) /* cam_d10 */
+                       OMAP3_CORE1_IOPAD(0x212e, PIN_OUTPUT | MUX_MODE0) /* cam_xclkb */
+                       OMAP3_CORE1_IOPAD(0x2130, PIN_OUTPUT | MUX_MODE4) /* cam_wen = gpio_167 */
+                       OMAP3_CORE1_IOPAD(0x2132, PIN_INPUT_PULLDOWN | MUX_MODE4) /* cam_strobe */
+               >;
+       };
+
+       mcbsp1_pins: pinmux_mcbsp1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x218c, PIN_INPUT | MUX_MODE4)        /* mcbsp1_clkr.mcbsp1_clkr - gpio_156 FM interrupt */
+                       OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE0)       /* mcbsp1_clkr.mcbsp1_fsr */
+                       OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE0)       /* mcbsp1_dx.mcbsp1_dx */
+                       OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT | MUX_MODE0)        /* mcbsp1_dx.mcbsp1_dr */
+                       /* mcbsp_clks is used as PENIRQ */
+                       /* OMAP3_CORE1_IOPAD(0x2194, PIN_INPUT | MUX_MODE0)     /* mcbsp_clks.mcbsp_clks */
+                       OMAP3_CORE1_IOPAD(0x2196, PIN_INPUT | MUX_MODE0)        /* mcbsp_clks.mcbsp1_fsx */
+                       OMAP3_CORE1_IOPAD(0x2198, PIN_INPUT | MUX_MODE0)        /* mcbsp1_clkx.mcbsp1_clkx */
+               >;
+       };
+
+       mcbsp2_pins: pinmux_mcbsp2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0)        /* mcbsp2_fsx.mcbsp2_fsx */
+                       OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0)        /* mcbsp2_fsx.mcbsp2_clkx */
+                       OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0)        /* mcbsp2_dr.mcbsp2_dr */
+                       OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0)       /* mcbsp2_dr.mcbsp2_dx */
+               >;
+       };
+
+       mcbsp3_pins: pinmux_mcbsp3_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x216c, PIN_OUTPUT | MUX_MODE0)       /* mcbsp3_dx.mcbsp3_dx */
+                       OMAP3_CORE1_IOPAD(0x216e, PIN_INPUT | MUX_MODE0)        /* mcbsp3_dx.mcbsp3_dr */
+                       OMAP3_CORE1_IOPAD(0x2170, PIN_INPUT | MUX_MODE0)        /* mcbsp3_clkx.mcbsp3_clkx */
+                       OMAP3_CORE1_IOPAD(0x2172, PIN_INPUT | MUX_MODE0)        /* mcbsp3_clkx.mcbsp3_fsx */
+               >;
+       };
+
+       mcbsp4_pins: pinmux_mcbsp4_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* mcbsp4_clkx.mcbsp4_clkx */
+                       OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* mcbsp4_clkx.mcbsp4_dr */
+                       OMAP3_CORE1_IOPAD(0x218a, PIN_INPUT_PULLDOWN | MUX_MODE0)       /* mcbsp4_dx.mcbsp4_fsx */
+               >;
+       };
 };
 
 &omap3_pmx_core2 {
        bmp085@77 {
                compatible = "bosch,bmp085";
                reg = <0x77>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bmp085_pins>;
                interrupt-parent = <&gpio4>;
                interrupts = <17 IRQ_TYPE_EDGE_RISING>; /* GPIO_113 */
        };
                        reg = <0x4>;
                };
 
-               wifi_reset: wifi_reset@6 {
+               wifi_reset: wifi_reset@6 { /* reference as <&tca_gpios 0 0> since it is currently the only GPIO */
                        reg = <0x6>;
                        compatible = "gpio";
                };
        tsc2007@48 {
                compatible = "ti,tsc2007";
                reg = <0x48>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&penirq_pins>;
                interrupt-parent = <&gpio6>;
                interrupts = <0 IRQ_TYPE_EDGE_FALLING>; /* GPIO_160 */
-               gpios = <&gpio6 0 GPIO_ACTIVE_LOW>;
+               gpios = <&gpio6 0 GPIO_ACTIVE_LOW>;     /* GPIO_160 */
                ti,x-plate-ohms = <600>;
+               touchscreen-size-x = <480>;
+               touchscreen-size-y = <640>;
+               touchscreen-max-pressure = <1000>;
+               touchscreen-fuzz-x = <3>;
+               touchscreen-fuzz-y = <8>;
+               touchscreen-fuzz-pressure = <10>;
+               touchscreen-inverted-y;
        };
 
        /* RFID EEPROM */
        vmmc-supply = <&vmmc1>;
        bus-width = <4>;
        ti,non-removable;
+       broken-cd;      /* hardware has no CD */
 };
 
 &mmc2 {
        status = "disabled";
 };
 
+#define BIT(x) (1 << (x))
+&twl_gpio {
+       /* pullups: BIT(2) */
+       ti,pullups = <BIT(2)>;
+       /*
+        * pulldowns:
+        * BIT(0),  BIT(1), BIT(6), BIT(7), BIT(8), BIT(13)
+        * BIT(15), BIT(16), BIT(17)
+        */
+       ti,pulldowns = <(BIT(0) | BIT(1) | BIT(6) | BIT(7) | BIT(8) |
+                        BIT(13) | BIT(15) | BIT(16) | BIT(17))>;
+};
+
 &twl_keypad {
        status = "disabled";
 };
 &uart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart3_pins>;
+       interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
 };
 
 &charger {
 &vaux2 {
        regulator-min-microvolt = <2800000>;
        regulator-max-microvolt = <2800000>;
-       regulator-always-on;
+       regulator-always-on;    /* we should never switch off while vio is on! */
 };
 
 /* camera */
        regulator-max-microvolt = <3150000>;
 };
 
+/* Needed to power the DPI pins */
+
+&vpll2 {
+       regulator-always-on;
+};
+
 &dss {
        pinctrl-names = "default";
        pinctrl-0 = < &dss_dpi_pins >;
 
        vdda-supply = <&vdac>;
 
+       #address-cells = <1>;
+       #size-cells = <0>;
+
        port {
+               reg = <0>;
                venc_out: endpoint {
                        remote-endpoint = <&opa_in>;
-                       ti,channels = <2>;
+                       ti,channels = <1>;
                        ti,invert-polarity;
                };
        };
                interrupt-parent = <&gpmc>;
                interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
                             <1 IRQ_TYPE_NONE>; /* termcount */
+               ti,nand-ecc-opt = "ham1";
+               rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
                nand-bus-width = <16>;
-               ti,nand-ecc-opt = "bch8";
+               #address-cells = <1>;
+               #size-cells = <1>;
 
-               gpmc,sync-clk-ps = <0>;
+               gpmc,device-width = <2>;
                gpmc,cs-on-ns = <0>;
                gpmc,cs-rd-off-ns = <44>;
                gpmc,cs-wr-off-ns = <44>;
                gpmc,adv-on-ns = <6>;
                gpmc,adv-rd-off-ns = <34>;
                gpmc,adv-wr-off-ns = <44>;
-               gpmc,we-off-ns = <40>;
                gpmc,oe-off-ns = <54>;
+               gpmc,we-off-ns = <40>;
                gpmc,access-ns = <64>;
                gpmc,rd-cycle-ns = <82>;
                gpmc,wr-cycle-ns = <82>;
                gpmc,wr-access-ns = <40>;
                gpmc,wr-data-mux-bus-ns = <0>;
-               gpmc,device-width = <2>;
-
-               #address-cells = <1>;
-               #size-cells = <1>;
+               gpmc,sync-clk-ps = <0>;
 
                x-loader@0 {
                        label = "X-Loader";
 
                bootloaders@80000 {
                        label = "U-Boot";
-                       reg = <0x80000 0x1e0000>;
+                       reg = <0x80000 0x1c0000>;
                };
 
-               bootloaders_env@260000 {
+               bootloaders_env@240000 {
                        label = "U-Boot Env";
-                       reg = <0x260000 0x20000>;
+                       reg = <0x240000 0x40000>;
                };
 
                kernel@280000 {
                        label = "Kernel";
-                       reg = <0x280000 0x400000>;
+                       reg = <0x280000 0x600000>;
                };
 
-               filesystem@680000 {
+               filesystem@880000 {
                        label = "File System";
-                       reg = <0x680000 0xf980000>;
+                       reg = <0x880000 0>;     /* 0 = MTDPART_SIZ_FULL */
                };
        };
 };
 
-&mcbsp2 {
-       status = "okay";
+&mcbsp1 { /* FM Transceiver PCM */
+       status = "ok";
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp1_pins>;
+};
+
+&mcbsp2 { /* TPS65950 I2S */
+       status = "ok";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp2_pins>;
+};
+
+&mcbsp3 { /* Bluetooth PCM */
+       status = "ok";
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp3_pins>;
+};
+
+&mcbsp4 { /* GSM voice PCM */
+       status = "ok";
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcbsp4_pins>;
 };
 
 &hdqw1w {
         pinctrl-0 = <&hdq_pins>;
 };
 
-&mcbsp4 {
-       status = "okay";
+/* image signal processor within OMAP3 SoC */
+&isp {
+       ports {
+               port@0 {
+                       reg = <0>;
+                       parallel_ep: endpoint {
+                               ti,isp-clock-divisor = <1>;
+                               ti,strobe-mode;
+                               bus-width = <8>;/* Used data lines */
+                               data-shift = <2>; /* Lines 9:2 are used */
+                               hsync-active = <0>; /* Active low */
+                               vsync-active = <1>; /* Active high */
+                               data-active = <1>;/* Active high */
+                               pclk-sample = <1>;/* Falling */
+                       };
+               };
+               /* port@1 and port@2 are not used by GTA04 */
+       };
 };
index 3099a892cf5029723189f30d8cab40ba99749b97..cc9244956679069199d12a8b31574d2d846a706a 100644 (file)
@@ -9,7 +9,7 @@
 #include "omap3-gta04.dtsi"
 
 / {
-       model = "Goldelico GTA04A3";
+       model = "Goldelico GTA04A3/Letux 2804";
 };
 
 &i2c2 {
index c918bb1f052931a13a04228c9ba9c5063aa04b9b..77afc711fe4fffb9049807f24af330fabf987264 100644 (file)
@@ -9,5 +9,5 @@
 #include "omap3-gta04.dtsi"
 
 / {
-       model = "Goldelico GTA04A4";
+       model = "Goldelico GTA04A4/Letux 2804";
 };
index 600b6ca5a1bdc03795a85855c6394e6f1f2bf397..bd232b1b24cbe861e204a97cfa5541f6d7080d28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 H. Nikolaus Schaller <hns@goldelico.com>
+ * Copyright (C) 2014-18 H. Nikolaus Schaller <hns@goldelico.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -9,9 +9,132 @@
 #include "omap3-gta04.dtsi"
 
 / {
-       model = "Goldelico GTA04A5";
+       model = "Goldelico GTA04A5/Letux 2804";
 
        sound {
-               ti,jack-det-gpio = <&twl_gpio 2 GPIO_ACTIVE_HIGH>;    /* GTA04A5 only */
+               ti,jack-det-gpio = <&twl_gpio 2 GPIO_ACTIVE_HIGH>;      /* GTA04A5 only */
+       };
+
+       wlan_en: wlan_en_regulator {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_pins>;
+               regulator-name = "wlan-en-regulator";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+
+               gpio = <&gpio5 10 GPIO_ACTIVE_HIGH>;    /* GPIO_138 */
+
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pps_pins>;
+
+               gpios = <&gpio4 18 GPIO_ACTIVE_HIGH>; /* GPIN_114 */
+       };
+
+};
+
+&gpio5 {
+       irda_en {
+               gpio-hog;
+               gpios = <(175-160) GPIO_ACTIVE_HIGH>;
+               output-high;    /* activate gpio_175 to disable IrDA receiver */
+       };
+};
+
+&omap3_pmx_core {
+       bt_pins: pinmux_bt_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE4)       /* mmc2_dat5 = mmc3_dat1 = gpio137 */
+               >;
+       };
+
+       wlan_pins: pinmux_wlan_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE4)       /* mmc2_dat6 = mmc3_dat2 = gpio138 */
+               >;
+       };
+
+       wlan_irq_pin: pinmux_wlan_irq_pin {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE4) /* mmc2_dat7 = mmc3_dat3 = gpio139 */
+               >;
+       };
+
+       irda_pins: pinmux_irda {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21d0, PIN_OUTPUT_PULLUP | MUX_MODE4)        /* mcspi1_cs1 = gpio175 */
+               >;
+       };
+
+       pps_pins: pinmux_pps_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2138, PIN_INPUT | MUX_MODE4) /* gpin114 */
+               >;
+       };
+
+};
+
+/*
+ * for WL183x module see
+ * http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt
+ */
+
+&wifi_pwrseq {
+       /delete-property/ reset-gpios;
+};
+
+&mmc2 {
+       vmmc-supply = <&wlan_en>;
+       bus-width = <4>;
+       cap-power-off-card;
+       non-removable;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&wlan_irq_pin>;
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       /delete-property/ mmc-pwrseq;
+
+       wlcore: wlcore@2 {
+               compatible = "ti,wl1837";
+               reg = <2>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;  /* GPIO_139 */
+               ref-clock-frequency = <26000000>;
+       };
+};
+
+&i2c2 {
+       /delete-node/ bmp085@77;
+       /delete-node/ bma180@41;
+       /delete-node/ itg3200@68;
+       /delete-node/ hmc5843@1e;
+
+       bmg160@69 {
+               compatible = "bosch,bmg160";
+               reg = <0x69>;
+       };
+
+       bmc150@10 {
+               compatible = "bosch,bmc150_accel";
+               reg = <0x10>;
+       };
+
+       bmc150@12 {
+               compatible = "bosch,bmc150_magn";
+               reg = <0x12>;
+       };
+
+       bme280@76 {
+               compatible = "bosch,bme280";
+               reg = <0x76>;
        };
 };
diff --git a/arch/arm/boot/dts/omap3-gta04a5one.dts b/arch/arm/boot/dts/omap3-gta04a5one.dts
new file mode 100644 (file)
index 0000000..9b7bbdc
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014-18 H. Nikolaus Schaller <hns@goldelico.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap3-gta04a5.dts"
+
+&omap3_pmx_core {
+       model = "Goldelico GTA04A5/Letux 2804 with OneNAND";
+
+       gpmc_pins: pinmux_gpmc_pins {
+               pinctrl-single,pins = <
+
+                       /* address lines */
+                       OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a1.gpmc_a1 */
+                       OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a2.gpmc_a2 */
+                       OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0)       /* gpmc_a3.gpmc_a3 */
+
+                       /* data lines, gpmc_d0..d7 not muxable according to TRM */
+                       OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0)        /* gpmc_d8.gpmc_d8 */
+                       OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0)        /* gpmc_d9.gpmc_d9 */
+                       OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0)        /* gpmc_d10.gpmc_d10 */
+                       OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0)        /* gpmc_d11.gpmc_d11 */
+                       OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0)        /* gpmc_d12.gpmc_d12 */
+                       OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0)        /* gpmc_d13.gpmc_d13 */
+                       OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0)        /* gpmc_d14.gpmc_d14 */
+                       OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0)        /* gpmc_d15.gpmc_d15 */
+
+                       /*
+                        * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable
+                        * according to TRM. OneNAND seems to require PIN_INPUT on clock.
+                        */
+                       OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0)       /* gpmc_ncs1.gpmc_ncs1 */
+                       OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0)        /* gpmc_clk.gpmc_clk */
+               >;
+       };
+};
+
+&gpmc {
+       /* switch inherited setup to OneNAND */
+
+       ranges = <0 0 0x04000000 0x1000000>;    /* CS0: 16MB for OneNAND */
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpmc_pins>;
+
+       /delete-node/ nand@0,0;
+
+       onenand@0,0 {
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "ti,omap2-onenand";
+               reg = <0 0 0x20000>;    /* CS0, offset 0, IO size 128K */
+
+               gpmc,sync-read;
+               gpmc,sync-write;
+               gpmc,burst-length = <16>;
+               gpmc,burst-read;
+               gpmc,burst-wrap;
+               gpmc,burst-write;
+               gpmc,device-width = <2>;
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <87>;
+               gpmc,cs-wr-off-ns = <87>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <10>;
+               gpmc,adv-wr-off-ns = <10>;
+               gpmc,oe-on-ns = <15>;
+               gpmc,oe-off-ns = <87>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <87>;
+               gpmc,rd-cycle-ns = <112>;
+               gpmc,wr-cycle-ns = <112>;
+               gpmc,access-ns = <81>;
+               gpmc,page-burst-access-ns = <15>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,clk-activation-ns = <5>;
+               gpmc,wr-data-mux-bus-ns = <30>;
+               gpmc,wr-access-ns = <81>;
+               gpmc,sync-clk-ps = <15000>;
+
+               x-loader@0 {
+                       label = "X-Loader";
+                       reg = <0 0x80000>;
+               };
+
+               bootloaders@80000 {
+                       label = "U-Boot";
+                       reg = <0x80000 0x1c0000>;
+               };
+
+               bootloaders_env@240000 {
+                       label = "U-Boot Env";
+                       reg = <0x240000 0x40000>;
+               };
+
+               kernel@280000 {
+                       label = "Kernel";
+                       reg = <0x280000 0x600000>;
+               };
+
+               filesystem@880000 {
+                       label = "File System";
+                       reg = <0x880000 0>;     /* 0 = MTDPART_SIZ_FULL */
+               };
+
+       };
+};
index ded5fcf084eb786d5c3ef521ec1ffbf535915b3f..1f91646b895162c7771174797ce50bb3194f9220 100644 (file)
@@ -40,7 +40,7 @@
 };
 
 &i2c3 {
-       ak8975@0f {
+       ak8975@f {
                compatible = "asahi-kasei,ak8975";
                reg = <0x0f>;
        };
index ab6f640b282bfc903f115bdb56796447b862b8f8..bf7ca00f4c214af57787e0c31332388f0c576115 100644 (file)
        vbus-supply = <&smps10_out1_reg>;
 };
 
+&dwc3 {
+       dr_mode = "otg";
+};
+
 &mcspi1 {
 
 };
index ebd93df5d07a8a90218c9bc92e062e962e27db3d..b6c9b85951ea695a2b24f6a68e5b039ee7d556fa 100644 (file)
 &i2c {
        status = "okay";
 
-       rtc {
+       rtc@32 {
                compatible = "ricoh,rs5c372a";
                reg = <0x32>;
        };
index ea4e01bce8d14fe005316187b1c4b4c7c809c345..7c96c59b610d19d069975bbf9b9289f438cb6843 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Cubietech CubieBoard6
  *
  * Copyright (c) 2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
index 7be1d2eaf3f06904bbbc33a1b65d1063853a339a..e610d49395d261380cfa94d145f4777d70904eb0 100644 (file)
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016-2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
index 079b2c02cc13c9a7f8e3cf0736ccefbfac9a9385..81cc39871f17dc3f3c3326ae06df888e4e90a12d 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * LeMaker Guitar SoM
  *
  * Copyright (c) 2016-2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 #include "owl-s500.dtsi"
index 43c9980a4260cf1c5b5fa1b23c3dfe84ac4a9252..5ceb6cc4451d282bd68058ac78d798d1977c8525 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Actions Semi S500 SoC
  *
  * Copyright (c) 2016-2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
index 95d59be97213e0392505c4e7afd67d2f99e5e4a6..8494b578717090a6401090ce3c59b25f17f7dab1 100644 (file)
                        #pwm-cells = <1>;
                        clocks = <&clks CLK_PWM1>;
                };
+
+               rtc@40900000 {
+                       clocks = <&clks CLK_OSC32k768>;
+               };
        };
 
        timer@40a00000 {
index 747f750f675d96dd351d8ad5a02213dae10fb6bf..3228ad5fb725f0aa507e56b54f55383b32f22a4b 100644 (file)
@@ -71,7 +71,7 @@
                        clocks = <&clks CLK_PWM1>;
                };
 
-               pwri2c: i2c@40f000180 {
+               pwri2c: i2c@40f00180 {
                        compatible = "mrvl,pxa-i2c";
                        reg = <0x40f00180 0x24>;
                        interrupts = <6>;
 
                        status = "disabled";
                };
+
+               rtc@40900000 {
+                       clocks = <&clks CLK_OSC32k768>;
+               };
        };
 
        clocks {
index a520b4c14ea9f5023b11672c17cb438f256f9067..080d5c5169b5aed17eceef5406442025d3843256 100644 (file)
@@ -9,6 +9,25 @@
 #include "skeleton.dtsi"
 #include "dt-bindings/clock/pxa-clock.h"
 
+#define PMGROUP(pin) #pin
+#define PMMUX(func, pin, af)                   \
+       mux- ## func {                          \
+               groups = PMGROUP(P ## pin);     \
+               function = #af;                 \
+       }
+#define PMMUX_LPM_LOW(func, pin, af)           \
+       mux- ## func {                          \
+               groups = PMGROUP(P ## pin);     \
+               function = #af;                 \
+               low-power-disable;              \
+       }
+#define PMMUX_LPM_HIGH(func, pin, af)          \
+       mux- ## func {                          \
+               groups = PMGROUP(P ## pin);     \
+               function = #af;                 \
+               low-power-enable;               \
+       }
+
 / {
        model = "Marvell PXA2xx family SoC";
        compatible = "marvell,pxa2xx";
@@ -76,7 +95,7 @@
                        };
                };
 
-               ffuart: uart@40100000 {
+               ffuart: serial@40100000 {
                        compatible = "mrvl,pxa-uart";
                        reg = <0x40100000 0x30>;
                        interrupts = <22>;
                        status = "disabled";
                };
 
-               btuart: uart@40200000 {
+               btuart: serial@40200000 {
                        compatible = "mrvl,pxa-uart";
                        reg = <0x40200000 0x30>;
                        interrupts = <21>;
                        status = "disabled";
                };
 
-               stuart: uart@40700000 {
+               stuart: serial@40700000 {
                        compatible = "mrvl,pxa-uart";
                        reg = <0x40700000 0x30>;
                        interrupts = <20>;
                        status = "disabled";
                };
 
-               hwuart: uart@41100000 {
+               hwuart: serial@41100000 {
                        compatible = "mrvl,pxa-uart";
                        reg = <0x41100000 0x30>;
                        interrupts = <7>;
index 4a99c9255104913964cbe9b984d9150bd52d7ef9..48c3cf42761012c274707b2060298d36bea3379f 100644 (file)
                        clocks = <&rpmcc RPM_QDSS_CLK>;
                        clock-names = "apb_pclk";
 
-                       port {
-                               etb_in: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out0>;
+                       in-ports {
+                               port {
+                                       etb_in: endpoint {
+                                               remote-endpoint = <&replicator_out0>;
+                                       };
                                };
                        };
                };
                        clocks = <&rpmcc RPM_QDSS_CLK>;
                        clock-names = "apb_pclk";
 
-                       port {
-                               tpiu_in: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out1>;
+                       in-ports {
+                               port {
+                                       tpiu_in: endpoint {
+                                               remote-endpoint = <&replicator_out1>;
+                                       };
                                };
                        };
                };
                        clocks = <&rpmcc RPM_QDSS_CLK>;
                        clock-names = "apb_pclk";
 
-                       ports {
+                       out-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                                remote-endpoint = <&tpiu_in>;
                                        };
                                };
-                               port@2 {
-                                       reg = <0>;
+                       };
+
+                       in-ports {
+                               port {
                                        replicator_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&funnel_out>;
                                        };
                                };
                        clocks = <&rpmcc RPM_QDSS_CLK>;
                        clock-names = "apb_pclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                port@0 {
                                        reg = <0>;
                                        funnel_in0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm0_out>;
                                        };
                                };
                                port@1 {
                                        reg = <1>;
                                        funnel_in1: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm1_out>;
                                        };
                                };
                                port@4 {
                                        reg = <4>;
                                        funnel_in4: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm2_out>;
                                        };
                                };
                                port@5 {
                                        reg = <5>;
                                        funnel_in5: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm3_out>;
                                        };
                                };
-                               port@8 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        funnel_out: endpoint {
                                                remote-endpoint = <&replicator_in>;
                                        };
 
                        cpu = <&CPU0>;
 
-                       port {
-                               etm0_out: endpoint {
-                                       remote-endpoint = <&funnel_in0>;
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint = <&funnel_in0>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU1>;
 
-                       port {
-                               etm1_out: endpoint {
-                                       remote-endpoint = <&funnel_in1>;
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint = <&funnel_in1>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU2>;
 
-                       port {
-                               etm2_out: endpoint {
-                                       remote-endpoint = <&funnel_in4>;
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint = <&funnel_in4>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU3>;
 
-                       port {
-                               etm3_out: endpoint {
-                                       remote-endpoint = <&funnel_in5>;
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint = <&funnel_in5>;
+                                       };
                                };
                        };
                };
index 78db67337ed4a3ce90a8962f183444296c27fc53..2d56008d8d6b53e8a79f9f6265838a22484c5e73 100644 (file)
                cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
-                       enable-method = "qcom,kpss-acc-v1";
+                       enable-method = "qcom,kpss-acc-v2";
+                       next-level-cache = <&L2>;
                        qcom,acc = <&acc0>;
                        qcom,saw = <&saw0>;
                        reg = <0x0>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
-                       operating-points = <
-                               /* kHz  uV (fixed) */
-                               48000   1100000
-                               200000  1100000
-                               500000  1100000
-                               716000  1100000
-                       >;
                        clock-latency = <256000>;
+                       operating-points-v2 = <&cpu0_opp_table>;
                };
 
                cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
-                       enable-method = "qcom,kpss-acc-v1";
+                       enable-method = "qcom,kpss-acc-v2";
+                       next-level-cache = <&L2>;
                        qcom,acc = <&acc1>;
                        qcom,saw = <&saw1>;
                        reg = <0x1>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
-                       operating-points = <
-                               /* kHz  uV (fixed) */
-                               48000   1100000
-                               200000  1100000
-                               500000  1100000
-                               666000  1100000
-                       >;
                        clock-latency = <256000>;
+                       operating-points-v2 = <&cpu0_opp_table>;
                };
 
                cpu@2 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
-                       enable-method = "qcom,kpss-acc-v1";
+                       enable-method = "qcom,kpss-acc-v2";
+                       next-level-cache = <&L2>;
                        qcom,acc = <&acc2>;
                        qcom,saw = <&saw2>;
                        reg = <0x2>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
-                       operating-points = <
-                               /* kHz  uV (fixed) */
-                               48000   1100000
-                               200000  1100000
-                               500000  1100000
-                               666000  1100000
-                       >;
                        clock-latency = <256000>;
+                       operating-points-v2 = <&cpu0_opp_table>;
                };
 
                cpu@3 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
-                       enable-method = "qcom,kpss-acc-v1";
+                       enable-method = "qcom,kpss-acc-v2";
+                       next-level-cache = <&L2>;
                        qcom,acc = <&acc3>;
                        qcom,saw = <&saw3>;
                        reg = <0x3>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
-                       operating-points = <
-                               /* kHz  uV (fixed) */
-                               48000   1100000
-                               200000  1100000
-                               500000  1100000
-                               666000  1100000
-                       >;
                        clock-latency = <256000>;
+                       operating-points-v2 = <&cpu0_opp_table>;
                };
+
+               L2: l2-cache {
+                       compatible = "cache";
+                       cache-level = <2>;
+               };
+       };
+
+       cpu0_opp_table: opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-48000000 {
+                       opp-hz = /bits/ 64 <48000000>;
+                       clock-latency-ns = <256000>;
+               };
+               opp-200000000 {
+                       opp-hz = /bits/ 64 <200000000>;
+                       clock-latency-ns = <256000>;
+               };
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       clock-latency-ns = <256000>;
+               };
+               opp-716000000 {
+                       opp-hz = /bits/ 64 <716000000>;
+                       clock-latency-ns = <256000>;
+               };
        };
 
        pmu {
                        status = "disabled";
                };
 
-                acc0: clock-controller@b088000 {
-                        compatible = "qcom,kpss-acc-v1";
-                        reg = <0x0b088000 0x1000>, <0xb008000 0x1000>;
-                };
+               acc0: clock-controller@b088000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0x0b088000 0x1000>, <0xb008000 0x1000>;
+               };
 
-                acc1: clock-controller@b098000 {
-                        compatible = "qcom,kpss-acc-v1";
-                        reg = <0x0b098000 0x1000>, <0xb008000 0x1000>;
-                };
+               acc1: clock-controller@b098000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0x0b098000 0x1000>, <0xb008000 0x1000>;
+               };
 
-                acc2: clock-controller@b0a8000 {
-                        compatible = "qcom,kpss-acc-v1";
-                        reg = <0x0b0a8000 0x1000>, <0xb008000 0x1000>;
-                };
+               acc2: clock-controller@b0a8000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0x0b0a8000 0x1000>, <0xb008000 0x1000>;
+               };
 
-                acc3: clock-controller@b0b8000 {
-                        compatible = "qcom,kpss-acc-v1";
-                        reg = <0x0b0b8000 0x1000>, <0xb008000 0x1000>;
-                };
+               acc3: clock-controller@b0b8000 {
+                       compatible = "qcom,kpss-acc-v2";
+                       reg = <0x0b0b8000 0x1000>, <0xb008000 0x1000>;
+               };
 
-                saw0: regulator@b089000 {
-                        compatible = "qcom,saw2";
-                        reg = <0x02089000 0x1000>, <0x0b009000 0x1000>;
+               saw0: regulator@b089000 {
+                       compatible = "qcom,saw2";
+                       reg = <0x0b089000 0x1000>, <0x0b009000 0x1000>;
                         regulator;
-                };
+               };
 
-                saw1: regulator@b099000 {
-                        compatible = "qcom,saw2";
-                        reg = <0x0b099000 0x1000>, <0x0b009000 0x1000>;
-                        regulator;
-                };
+               saw1: regulator@b099000 {
+                       compatible = "qcom,saw2";
+                       reg = <0x0b099000 0x1000>, <0x0b009000 0x1000>;
+                       regulator;
+               };
 
-                saw2: regulator@b0a9000 {
-                        compatible = "qcom,saw2";
-                        reg = <0x0b0a9000 0x1000>, <0x0b009000 0x1000>;
-                        regulator;
-                };
+               saw2: regulator@b0a9000 {
+                       compatible = "qcom,saw2";
+                       reg = <0x0b0a9000 0x1000>, <0x0b009000 0x1000>;
+                       regulator;
+               };
 
-                saw3: regulator@b0b9000 {
-                        compatible = "qcom,saw2";
-                        reg = <0x0b0b9000 0x1000>, <0x0b009000 0x1000>;
-                        regulator;
-                };
+               saw3: regulator@b0b9000 {
+                       compatible = "qcom,saw2";
+                       reg = <0x0b0b9000 0x1000>, <0x0b009000 0x1000>;
+                       regulator;
+               };
 
                blsp1_uart1: serial@78af000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        #size-cells = <2>;
 
                        ranges = <0x81000000 0 0x40200000 0x40200000 0 0x00100000
-                                 0x82000000 0 0x48000000 0x48000000 0 0x10000000>;
+                                 0x82000000 0 0x40300000 0x40300000 0 0x400000>;
 
                        interrupts = <GIC_SPI 141 IRQ_TYPE_EDGE_RISING>;
                        interrupt-names = "msi";
index bcf53e37ed93c9ad5cc9a83d0828660af37e97b8..554c65e7aa0ee433b2d07cc39f61451413987868 100644 (file)
@@ -2,26 +2,8 @@
 #include "qcom-ipq8064-v1.0.dtsi"
 
 / {
-       model = "Qualcomm IPQ8064/AP148";
-       compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
-
-       aliases {
-               serial0 = &gsbi4_serial;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       reserved-memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-               rsvd@41200000 {
-                       reg = <0x41200000 0x300000>;
-                       no-map;
-               };
-       };
+       model = "Qualcomm Technologies, Inc. IPQ8064/AP-148";
+       compatible = "qcom,ipq8064-ap148";
 
        soc {
                pinmux@800000 {
                                bias-disable;
                        };
 
-                       spi_pins: spi_pins {
+                       buttons_pins: buttons_pins {
                                mux {
-                                       pins = "gpio18", "gpio19", "gpio21";
-                                       function = "gsbi5";
-                                       drive-strength = <10>;
-                                       bias-none;
+                                       pins = "gpio54", "gpio65";
+                                       drive-strength = <2>;
+                                       bias-pull-up;
                                };
                        };
                };
 
                gsbi@16300000 {
-                       qcom,mode = <GSBI_PROT_I2C_UART>;
-                       status = "ok";
-                       serial@16340000 {
+                       i2c@16380000 {
                                status = "ok";
-                       };
-
-                       i2c4: i2c@16380000 {
-                               status = "ok";
-
                                clock-frequency = <200000>;
-
                                pinctrl-0 = <&i2c4_pins>;
                                pinctrl-names = "default";
                        };
                };
-
-               gsbi5: gsbi@1a200000 {
-                       qcom,mode = <GSBI_PROT_SPI>;
-                       status = "ok";
-
-                       spi4: spi@1a280000 {
-                               status = "ok";
-                               spi-max-frequency = <50000000>;
-
-                               pinctrl-0 = <&spi_pins>;
-                               pinctrl-names = "default";
-
-                               cs-gpios = <&qcom_pinmux 20 0>;
-
-                               flash: m25p80@0 {
-                                       compatible = "s25fl256s1";
-                                       #address-cells = <1>;
-                                       #size-cells = <1>;
-                                       spi-max-frequency = <50000000>;
-                                       reg = <0>;
-
-                                       partition@0 {
-                                               label = "rootfs";
-                                               reg = <0x0 0x1000000>;
-                                       };
-
-                                       partition@1 {
-                                               label = "scratch";
-                                               reg = <0x1000000 0x1000000>;
-                                       };
-                               };
-                       };
-               };
-
-               sata-phy@1b400000 {
-                       status = "ok";
-               };
-
-               sata@29000000 {
-                       ports-implemented = <0x1>;
-                       status = "ok";
-               };
        };
 };
index e1181194e8d3e03e1036b84fce32e715d96290b1..e239a0486936317547464636e96564d0bab7fc32 100644 (file)
@@ -1,2 +1,127 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "qcom-ipq8064.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Qualcomm Technologies, Inc. IPQ8064-v1.0";
+
+       aliases {
+               serial0 = &gsbi4_serial;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       soc {
+               gsbi@16300000 {
+                       qcom,mode = <GSBI_PROT_I2C_UART>;
+                       status = "ok";
+
+                       serial@16340000 {
+                               status = "ok";
+                       };
+               };
+
+               gsbi5: gsbi@1a200000 {
+                       qcom,mode = <GSBI_PROT_SPI>;
+                       status = "ok";
+
+                       spi4: spi@1a280000 {
+                               status = "ok";
+                               spi-max-frequency = <50000000>;
+
+                               pinctrl-0 = <&spi_pins>;
+                               pinctrl-names = "default";
+
+                               cs-gpios = <&qcom_pinmux 20 0>;
+
+                               flash: m25p80@0 {
+                                       compatible = "s25fl256s1";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       spi-max-frequency = <50000000>;
+                                       reg = <0>;
+
+                                       partition@0 {
+                                               label = "rootfs";
+                                               reg = <0x0 0x1000000>;
+                                       };
+
+                                       partition@1 {
+                                               label = "scratch";
+                                               reg = <0x1000000 0x1000000>;
+                                       };
+                               };
+                       };
+               };
+
+               sata-phy@1b400000 {
+                       status = "ok";
+               };
+
+               sata@29000000 {
+                       ports-implemented = <0x1>;
+                       status = "ok";
+               };
+
+               gpio_keys {
+                       compatible = "gpio-keys";
+                       pinctrl-0 = <&buttons_pins>;
+                       pinctrl-names = "default";
+
+                       button@1 {
+                               label = "reset";
+                               linux,code = <KEY_RESTART>;
+                               gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>;
+                               linux,input-type = <1>;
+                               debounce-interval = <60>;
+                       };
+                       button@2 {
+                               label = "wps";
+                               linux,code = <KEY_WPS_BUTTON>;
+                               gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>;
+                               linux,input-type = <1>;
+                               debounce-interval = <60>;
+                       };
+               };
+
+               leds {
+                       compatible = "gpio-leds";
+                       pinctrl-0 = <&leds_pins>;
+                       pinctrl-names = "default";
+
+                       led@7 {
+                               label = "led_usb1";
+                               gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>;
+                               linux,default-trigger = "usbdev";
+                               default-state = "off";
+                       };
+
+                       led@8 {
+                               label = "led_usb3";
+                               gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
+                               linux,default-trigger = "usbdev";
+                               default-state = "off";
+                       };
+
+                       led@9 {
+                               label = "status_led_fail";
+                               gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>;
+                               default-state = "off";
+                       };
+
+                       led@26 {
+                               label = "sata_led";
+                               gpios = <&qcom_pinmux 26 GPIO_ACTIVE_HIGH>;
+                               default-state = "off";
+                       };
+
+                       led@53 {
+                               label = "status_led_pass";
+                               gpios = <&qcom_pinmux 53 GPIO_ACTIVE_HIGH>;
+                               default-state = "off";
+                       };
+               };
+       };
+};
index 70790ac242d180fa2e2d466c901b6be3efb87862..f793cd1ad6d0d04109eaeb07b1395fb8ba0c63a6 100644 (file)
@@ -2,8 +2,11 @@
 /dts-v1/;
 
 #include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
 #include <dt-bindings/clock/qcom,lcc-ipq806x.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
 #include <dt-bindings/soc/qcom,gsbi.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+
+                       pcie0_pins: pcie0_pinmux {
+                               mux {
+                                       pins = "gpio3";
+                                       function = "pcie1_rst";
+                                       drive-strength = <12>;
+                                       bias-disable;
+                               };
+                       };
+
+                       pcie1_pins: pcie1_pinmux {
+                               mux {
+                                       pins = "gpio48";
+                                       function = "pcie2_rst";
+                                       drive-strength = <12>;
+                                       bias-disable;
+                               };
+                       };
+
+                       pcie2_pins: pcie2_pinmux {
+                               mux {
+                                       pins = "gpio63";
+                                       function = "pcie3_rst";
+                                       drive-strength = <12>;
+                                       bias-disable;
+                               };
+                       };
+
+                       spi_pins: spi_pins {
+                               mux {
+                                       pins = "gpio18", "gpio19", "gpio21";
+                                       function = "gsbi5";
+                                       drive-strength = <10>;
+                                       bias-none;
+                               };
+                       };
+
+                       leds_pins: leds_pins {
+                               mux {
+                                       pins = "gpio7", "gpio8", "gpio9",
+                                              "gpio26", "gpio53";
+                                       function = "gpio";
+                                       drive-strength = <2>;
+                                       bias-pull-down;
+                                       output-low;
+                               };
+                       };
+
+                       buttons_pins: buttons_pins {
+                               mux {
+                                       pins = "gpio54";
+                                       drive-strength = <2>;
+                                       bias-pull-up;
+                               };
+                       };
                };
 
                intc: interrupt-controller@2000000 {
                        #reset-cells = <1>;
                };
 
+               pcie0: pci@1b500000 {
+                       compatible = "qcom,pcie-ipq8064";
+                       reg = <0x1b500000 0x1000
+                              0x1b502000 0x80
+                              0x1b600000 0x100
+                              0x0ff00000 0x100000>;
+                       reg-names = "dbi", "elbi", "parf", "config";
+                       device_type = "pci";
+                       linux,pci-domain = <0>;
+                       bus-range = <0x00 0xff>;
+                       num-lanes = <1>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000   /* downstream I/O */
+                                 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
+
+                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "msi";
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0x7>;
+                       interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                       <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                       <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                       <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+
+                       clocks = <&gcc PCIE_A_CLK>,
+                                <&gcc PCIE_H_CLK>,
+                                <&gcc PCIE_PHY_CLK>,
+                                <&gcc PCIE_AUX_CLK>,
+                                <&gcc PCIE_ALT_REF_CLK>;
+                       clock-names = "core", "iface", "phy", "aux", "ref";
+
+                       assigned-clocks = <&gcc PCIE_ALT_REF_CLK>;
+                       assigned-clock-rates = <100000000>;
+
+                       resets = <&gcc PCIE_ACLK_RESET>,
+                                <&gcc PCIE_HCLK_RESET>,
+                                <&gcc PCIE_POR_RESET>,
+                                <&gcc PCIE_PCI_RESET>,
+                                <&gcc PCIE_PHY_RESET>,
+                                <&gcc PCIE_EXT_RESET>;
+                       reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
+
+                       pinctrl-0 = <&pcie0_pins>;
+                       pinctrl-names = "default";
+
+                       status = "disabled";
+                       perst-gpio = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
+               };
+
+               pcie1: pci@1b700000 {
+                       compatible = "qcom,pcie-ipq8064";
+                       reg = <0x1b700000 0x1000
+                              0x1b702000 0x80
+                              0x1b800000 0x100
+                              0x31f00000 0x100000>;
+                       reg-names = "dbi", "elbi", "parf", "config";
+                       device_type = "pci";
+                       linux,pci-domain = <1>;
+                       bus-range = <0x00 0xff>;
+                       num-lanes = <1>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000   /* downstream I/O */
+                                 0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
+
+                       interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "msi";
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0x7>;
+                       interrupt-map = <0 0 0 1 &intc 0 58 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                       <0 0 0 2 &intc 0 59 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                       <0 0 0 3 &intc 0 60 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                       <0 0 0 4 &intc 0 61 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+
+                       clocks = <&gcc PCIE_1_A_CLK>,
+                                <&gcc PCIE_1_H_CLK>,
+                                <&gcc PCIE_1_PHY_CLK>,
+                                <&gcc PCIE_1_AUX_CLK>,
+                                <&gcc PCIE_1_ALT_REF_CLK>;
+                       clock-names = "core", "iface", "phy", "aux", "ref";
+
+                       assigned-clocks = <&gcc PCIE_1_ALT_REF_CLK>;
+                       assigned-clock-rates = <100000000>;
+
+                       resets = <&gcc PCIE_1_ACLK_RESET>,
+                                <&gcc PCIE_1_HCLK_RESET>,
+                                <&gcc PCIE_1_POR_RESET>,
+                                <&gcc PCIE_1_PCI_RESET>,
+                                <&gcc PCIE_1_PHY_RESET>,
+                                <&gcc PCIE_1_EXT_RESET>;
+                       reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
+
+                       pinctrl-0 = <&pcie1_pins>;
+                       pinctrl-names = "default";
+
+                       status = "disabled";
+                       perst-gpio = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
+               };
+
+               pcie2: pci@1b900000 {
+                       compatible = "qcom,pcie-ipq8064";
+                       reg = <0x1b900000 0x1000
+                              0x1b902000 0x80
+                              0x1ba00000 0x100
+                              0x35f00000 0x100000>;
+                       reg-names = "dbi", "elbi", "parf", "config";
+                       device_type = "pci";
+                       linux,pci-domain = <2>;
+                       bus-range = <0x00 0xff>;
+                       num-lanes = <1>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+
+                       ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000   /* downstream I/O */
+                                 0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */
+
+                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "msi";
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0x7>;
+                       interrupt-map = <0 0 0 1 &intc 0 72 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                       <0 0 0 2 &intc 0 73 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                       <0 0 0 3 &intc 0 74 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                       <0 0 0 4 &intc 0 75 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+
+                       clocks = <&gcc PCIE_2_A_CLK>,
+                                <&gcc PCIE_2_H_CLK>,
+                                <&gcc PCIE_2_PHY_CLK>,
+                                <&gcc PCIE_2_AUX_CLK>,
+                                <&gcc PCIE_2_ALT_REF_CLK>;
+                       clock-names = "core", "iface", "phy", "aux", "ref";
+
+                       assigned-clocks = <&gcc PCIE_2_ALT_REF_CLK>;
+                       assigned-clock-rates = <100000000>;
+
+                       resets = <&gcc PCIE_2_ACLK_RESET>,
+                                <&gcc PCIE_2_HCLK_RESET>,
+                                <&gcc PCIE_2_POR_RESET>,
+                                <&gcc PCIE_2_PCI_RESET>,
+                                <&gcc PCIE_2_PHY_RESET>,
+                                <&gcc PCIE_2_EXT_RESET>;
+                       reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
+
+                       pinctrl-0 = <&pcie2_pins>;
+                       pinctrl-names = "default";
+
+                       status = "disabled";
+                       perst-gpio = <&qcom_pinmux 63 GPIO_ACTIVE_LOW>;
+               };
+
+               vsdcc_fixed: vsdcc-regulator {
+                       compatible = "regulator-fixed";
+                       regulator-name = "SDCC Power";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               sdcc1bam:dma@12402000 {
+                       compatible = "qcom,bam-v1.3.0";
+                       reg = <0x12402000 0x8000>;
+                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc SDC1_H_CLK>;
+                       clock-names = "bam_clk";
+                       #dma-cells = <1>;
+                       qcom,ee = <0>;
+               };
+
+               sdcc3bam:dma@12182000 {
+                       compatible = "qcom,bam-v1.3.0";
+                       reg = <0x12182000 0x8000>;
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc SDC3_H_CLK>;
+                       clock-names = "bam_clk";
+                       #dma-cells = <1>;
+                       qcom,ee = <0>;
+               };
+
+               amba {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       sdcc@12400000 {
+                               status          = "disabled";
+                               compatible      = "arm,pl18x", "arm,primecell";
+                               arm,primecell-periphid = <0x00051180>;
+                               reg             = <0x12400000 0x2000>;
+                               interrupts      = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "cmd_irq";
+                               clocks          = <&gcc SDC1_CLK>, <&gcc SDC1_H_CLK>;
+                               clock-names     = "mclk", "apb_pclk";
+                               bus-width       = <8>;
+                               max-frequency   = <96000000>;
+                               non-removable;
+                               cap-sd-highspeed;
+                               cap-mmc-highspeed;
+                               mmc-ddr-1_8v;
+                               vmmc-supply = <&vsdcc_fixed>;
+                               dmas = <&sdcc1bam 2>, <&sdcc1bam 1>;
+                               dma-names = "tx", "rx";
+                       };
+
+                       sdcc@12180000 {
+                               compatible      = "arm,pl18x", "arm,primecell";
+                               arm,primecell-periphid = <0x00051180>;
+                               status          = "disabled";
+                               reg             = <0x12180000 0x2000>;
+                               interrupts      = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "cmd_irq";
+                               clocks          = <&gcc SDC3_CLK>, <&gcc SDC3_H_CLK>;
+                               clock-names     = "mclk", "apb_pclk";
+                               bus-width       = <8>;
+                               cap-sd-highspeed;
+                               cap-mmc-highspeed;
+                               max-frequency   = <192000000>;
+                               #mmc-ddr-1_8v;
+                               sd-uhs-sdr104;
+                               sd-uhs-ddr50;
+                               vqmmc-supply = <&vsdcc_fixed>;
+                               dmas = <&sdcc3bam 2>, <&sdcc3bam 1>;
+                               dma-names = "tx", "rx";
+                       };
+               };
        };
 };
index c2dc9d09484abd41d43d13a7a70b0f986a926e19..ed8f064d08952bf81343239a8dd47df62818c414 100644 (file)
                                bias-pull-up;
                        };
                };
+
+               i2c3_pins: i2c3 {
+                       mux {
+                               pins = "gpio10", "gpio11";
+                               function = "blsp_i2c3";
+                               drive-strength = <2>;
+                               bias-disable;
+                       };
+               };
+
+               i2c12_pins: i2c12 {
+                       mux {
+                               pins = "gpio87", "gpio88";
+                               function = "blsp_i2c12";
+                               drive-strength = <2>;
+                               bias-disable;
+                       };
+               };
+
+               mpu6515_pin: mpu6515 {
+                       irq {
+                               pins = "gpio73";
+                               function = "gpio";
+                               bias-disable;
+                               input-enable;
+                       };
+               };
        };
 
        sdhci@f9824900 {
                        linux,code = <KEY_VOLUMEDOWN>;
                };
        };
+
+       i2c@f9968000 {
+               status = "ok";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c12_pins>;
+               clock-frequency = <100000>;
+               qcom,src-freq = <50000000>;
+
+               mpu6515@68 {
+                       compatible = "invensense,mpu6515";
+                       reg = <0x68>;
+                       interrupts-extended = <&msmgpio 73 IRQ_TYPE_EDGE_FALLING>;
+                       vddio-supply = <&pm8941_lvs1>;
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mpu6515_pin>;
+
+                       i2c-gate {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               ak8963@f {
+                                       compatible = "asahi-kasei,ak8963";
+                                       reg = <0x0f>;
+                                       // Currently only works in polling mode.
+                                       // gpios = <&msmgpio 61 0>;
+                                       vid-supply = <&pm8941_lvs1>;
+                                       vdd-supply = <&pm8941_l17>;
+                               };
+
+                               bmp280@76 {
+                                       compatible = "bosch,bmp280";
+                                       reg = <0x76>;
+                                       vdda-supply = <&pm8941_lvs1>;
+                                       vddd-supply = <&pm8941_l17>;
+                               };
+                       };
+               };
+       };
+
+       i2c@f9925000 {
+               status = "ok";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c3_pins>;
+               clock-frequency = <100000>;
+               qcom,src-freq = <50000000>;
+
+               avago_apds993@39 {
+                       compatible = "avago,apds9930";
+                       reg = <0x39>;
+                       interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
+                       vdd-supply = <&pm8941_l17>;
+                       vddio-supply = <&pm8941_lvs1>;
+                       led-max-microamp = <100000>;
+                       amstaos,proximity-diodes = <0>;
+               };
+       };
 };
 
 &spmi_bus {
index d9019a49b292d8301b9e39616cc013871319bfb3..aba159d5a95aa3b6f7f1d11f895741d01033df17 100644 (file)
@@ -67,7 +67,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
-               interrupts = <1 9 0xf04>;
+               interrupts = <GIC_PPI 9 0xf04>;
 
                CPU0: cpu@0 {
                        compatible = "qcom,krait";
 
        cpu-pmu {
                compatible = "qcom,krait-pmu";
-               interrupts = <1 7 0xf04>;
+               interrupts = <GIC_PPI 7 0xf04>;
        };
 
        clocks {
 
        timer {
                compatible = "arm,armv7-timer";
-               interrupts = <1 2 0xf08>,
-                            <1 3 0xf08>,
-                            <1 4 0xf08>,
-                            <1 1 0xf08>;
+               interrupts = <GIC_PPI 2 0xf08>,
+                            <GIC_PPI 3 0xf08>,
+                            <GIC_PPI 4 0xf08>,
+                            <GIC_PPI 1 0xf08>;
                clock-frequency = <19200000>;
        };
 
        adsp-pil {
                compatible = "qcom,msm8974-adsp-pil";
 
-               interrupts-extended = <&intc 0 162 IRQ_TYPE_EDGE_RISING>,
+               interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
                                      <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
                                      <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
                                      <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
                qcom,smem = <443>, <429>;
 
                interrupt-parent = <&intc>;
-               interrupts = <0 158 IRQ_TYPE_EDGE_RISING>;
+               interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
 
                qcom,ipc = <&apcs 8 10>;
 
                qcom,smem = <435>, <428>;
 
                interrupt-parent = <&intc>;
-               interrupts = <0 27 IRQ_TYPE_EDGE_RISING>;
+               interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
 
                qcom,ipc = <&apcs 8 14>;
 
                qcom,smem = <451>, <431>;
 
                interrupt-parent = <&intc>;
-               interrupts = <0 143 IRQ_TYPE_EDGE_RISING>;
+               interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
 
                qcom,ipc = <&apcs 8 18>;
 
 
                modem_smsm: modem@1 {
                        reg = <1>;
-                       interrupts = <0 26 IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
 
                        interrupt-controller;
                        #interrupt-cells = <2>;
 
                adsp_smsm: adsp@2 {
                        reg = <2>;
-                       interrupts = <0 157 IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>;
 
                        interrupt-controller;
                        #interrupt-cells = <2>;
 
                wcnss_smsm: wcnss@7 {
                        reg = <7>;
-                       interrupts = <0 144 IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>;
 
                        interrupt-controller;
                        #interrupt-cells = <2>;
 
                        frame@f9021000 {
                                frame-number = <0>;
-                               interrupts = <0 8 0x4>,
-                                            <0 7 0x4>;
+                               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9021000 0x1000>,
                                      <0xf9022000 0x1000>;
                        };
 
                        frame@f9023000 {
                                frame-number = <1>;
-                               interrupts = <0 9 0x4>;
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9023000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9024000 {
                                frame-number = <2>;
-                               interrupts = <0 10 0x4>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9024000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9025000 {
                                frame-number = <3>;
-                               interrupts = <0 11 0x4>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9025000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9026000 {
                                frame-number = <4>;
-                               interrupts = <0 12 0x4>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9026000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9027000 {
                                frame-number = <5>;
-                               interrupts = <0 13 0x4>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9027000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9028000 {
                                frame-number = <6>;
-                               interrupts = <0 14 0x4>;
+                               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9028000 0x1000>;
                                status = "disabled";
                        };
                blsp1_uart1: serial@f991d000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0xf991d000 0x1000>;
-                       interrupts = <0 107 0x0>;
+                       interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
                        clock-names = "core", "iface";
                        status = "disabled";
                blsp1_uart2: serial@f991e000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0xf991e000 0x1000>;
-                       interrupts = <0 108 0x0>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
                        clock-names = "core", "iface";
                        status = "disabled";
                        compatible = "qcom,sdhci-msm-v4";
                        reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
                        reg-names = "hc_mem", "core_mem";
-                       interrupts = <0 123 0>, <0 138 0>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "hc_irq", "pwr_irq";
                        clocks = <&gcc GCC_SDCC1_APPS_CLK>,
                                 <&gcc GCC_SDCC1_AHB_CLK>,
                        compatible = "qcom,sdhci-msm-v4";
                        reg = <0xf9864900 0x11c>, <0xf9864000 0x800>;
                        reg-names = "hc_mem", "core_mem";
-                       interrupts = <GIC_SPI 127 IRQ_TYPE_NONE>,
-                                    <GIC_SPI 224 IRQ_TYPE_NONE>;
+                       interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "hc_irq", "pwr_irq";
                        clocks = <&gcc GCC_SDCC3_APPS_CLK>,
                                 <&gcc GCC_SDCC3_AHB_CLK>,
                        compatible = "qcom,sdhci-msm-v4";
                        reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
                        reg-names = "hc_mem", "core_mem";
-                       interrupts = <0 125 0>, <0 221 0>;
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "hc_irq", "pwr_irq";
                        clocks = <&gcc GCC_SDCC2_APPS_CLK>,
                                 <&gcc GCC_SDCC2_AHB_CLK>,
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
-                       interrupts = <0 208 0>;
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                i2c@f9924000 {
                        status = "disabled";
                        compatible = "qcom,i2c-qup-v2.1.1";
                        reg = <0xf9924000 0x1000>;
-                       interrupts = <0 96 IRQ_TYPE_NONE>;
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
                        clock-names = "core", "iface";
                        #address-cells = <1>;
                        #size-cells = <0>;
                };
 
+               blsp_i2c3: i2c@f9925000 {
+                       status = "disabled";
+                       compatible = "qcom,i2c-qup-v2.1.1";
+                       reg = <0xf9925000 0x1000>;
+                       interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                blsp_i2c8: i2c@f9964000 {
                        status = "disabled";
                        compatible = "qcom,i2c-qup-v2.1.1";
                        reg = <0xf9964000 0x1000>;
-                       interrupts = <0 102 IRQ_TYPE_NONE>;
+                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
                        clock-names = "core", "iface";
                        #address-cells = <1>;
                        status = "disabled";
                        compatible = "qcom,i2c-qup-v2.1.1";
                        reg = <0xf9967000 0x1000>;
-                       interrupts = <0 105 IRQ_TYPE_NONE>;
+                       interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP2_QUP5_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
                        clock-names = "core", "iface";
                        #address-cells = <1>;
                        dma-names = "tx", "rx";
                };
 
+               blsp_i2c12: i2c@f9968000 {
+                       status = "disabled";
+                       compatible = "qcom,i2c-qup-v2.1.1";
+                       reg = <0xf9968000 0x1000>;
+                       interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_QUP6_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                spmi_bus: spmi@fc4cf000 {
                        compatible = "qcom,spmi-pmic-arb";
                        reg-names = "core", "intr", "cnfg";
                              <0xfc4cb000 0x1000>,
                              <0xfc4ca000 0x1000>;
                        interrupt-names = "periph_irq";
-                       interrupts = <0 190 0>;
+                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
                        qcom,ee = <0>;
                        qcom,channel = <0>;
                        #address-cells = <2>;
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       port {
-                               etr_in: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out0>;
+                       in-ports {
+                               port {
+                                       etr_in: endpoint {
+                                               remote-endpoint = <&replicator_out0>;
+                                       };
                                };
                        };
                };
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       port {
-                               tpiu_in: endpoint {
-                                        slave-mode;
-                                        remote-endpoint = <&replicator_out1>;
+                       in-ports {
+                               port {
+                                       tpiu_in: endpoint {
+                                               remote-endpoint = <&replicator_out1>;
+                                       };
                                 };
                        };
                };
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       out-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                                remote-endpoint = <&tpiu_in>;
                                        };
                                };
-                               port@2 {
-                                       reg = <0>;
+                       };
+
+                       in-ports {
+                               port {
                                        replicator_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etf_out>;
                                        };
                                };
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        etf_out: endpoint {
                                                remote-endpoint = <&replicator_in>;
                                        };
                                };
-                               port@1 {
-                                       reg = <0>;
+                       };
+
+                       in-ports {
+                               port {
                                        etf_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&merger_out>;
                                        };
                                };
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                port@1 {
                                        reg = <1>;
                                        merger_in1: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&funnel1_out>;
                                        };
                                };
-                               port@8 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        merger_out: endpoint {
                                                remote-endpoint = <&etf_in>;
                                        };
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                port@5 {
                                        reg = <5>;
                                        funnel1_in5: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&kpss_out>;
                                        };
                                };
-                               port@8 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        funnel1_out: endpoint {
                                                remote-endpoint = <&merger_in1>;
                                        };
                        clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                port@0 {
                                        reg = <0>;
                                        kpss_in0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm0_out>;
                                        };
                                };
                                port@1 {
                                        reg = <1>;
                                        kpss_in1: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm1_out>;
                                        };
                                };
                                port@2 {
                                        reg = <2>;
                                        kpss_in2: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm2_out>;
                                        };
                                };
                                port@3 {
                                        reg = <3>;
                                        kpss_in3: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm3_out>;
                                        };
                                };
-                               port@8 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        kpss_out: endpoint {
                                                remote-endpoint = <&funnel1_in5>;
                                        };
 
                        cpu = <&CPU0>;
 
-                       port {
-                               etm0_out: endpoint {
-                                       remote-endpoint = <&kpss_in0>;
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint = <&kpss_in0>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU1>;
 
-                       port {
-                               etm1_out: endpoint {
-                                       remote-endpoint = <&kpss_in1>;
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint = <&kpss_in1>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU2>;
 
-                       port {
-                               etm2_out: endpoint {
-                                       remote-endpoint = <&kpss_in2>;
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint = <&kpss_in2>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU3>;
 
-                       port {
-                               etm3_out: endpoint {
-                                       remote-endpoint = <&kpss_in3>;
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint = <&kpss_in3>;
+                                       };
                                };
                        };
                };
                compatible = "qcom,smd";
 
                adsp {
-                       interrupts = <0 156 IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
 
                        qcom,ipc = <&apcs 8 8>;
                        qcom,smd-edge = <1>;
                };
 
                modem {
-                       interrupts = <0 25 IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
 
                        qcom,ipc = <&apcs 8 12>;
                        qcom,smd-edge = <0>;
                };
 
                rpm {
-                       interrupts = <0 168 1>;
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
                        qcom,ipc = <&apcs 8 0>;
                        qcom,smd-edge = <15>;
 
index 327545119ee3f04d82ca3412a148e2f8ffd1e602..0d006aea99da1b40692e3aacc9d12816a92e2aac 100644 (file)
@@ -14,3 +14,7 @@
        model = "iW-RainboW-G20D-Q7 RZ/G1M based plus camera daughter board";
        compatible = "iwave,g20d", "iwave,g20m", "renesas,r8a7743";
 };
+
+&pciec {
+       status = "okay";
+};
index b683db4da8b17784d17c9d2e69e73cbd8bf43ad4..498e223a5f93b05928e34db4eeb9796e8846b9c7 100644 (file)
@@ -13,3 +13,7 @@
        model = "iWave Systems RainboW-G20D-Qseven board based on RZ/G1M";
        compatible = "iwave,g20d", "iwave,g20m", "renesas,r8a7743";
 };
+
+&pciec {
+       status = "okay";
+};
index e3585daafdd644a189a7098624558d2bccfdc422..22da819f186be395daae3c4ca1c97a590fa21fff 100644 (file)
@@ -35,6 +35,8 @@
 
        phy3: ethernet-phy@3 {
                reg = <3>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
                micrel,led-mode = <1>;
        };
 };
        clock-frequency = <20000000>;
 };
 
+&pfc {
+       scif1_pins: scif1 {
+               groups = "scif1_data_b";
+               function = "scif1";
+       };
+};
+
 &scif1 {
+       pinctrl-0 = <&scif1_pins>;
+       pinctrl-names = "default";
+
        status = "okay";
 };
index 87d32d3e23de2c177efccb146845e98aefd7f217..9ec78d3d0ca8bf6bff454a57952ba92dfd68c140 100644 (file)
@@ -8,6 +8,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/r8a77470-cpg-mssr.h>
+#include <dt-bindings/power/r8a77470-sysc.h>
 / {
        compatible = "renesas,r8a77470";
        #address-cells = <2>;
@@ -16,6 +17,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
+               enable-method = "renesas,apmu";
 
                cpu0: cpu@0 {
                        device_type = "cpu";
                        reg = <0>;
                        clock-frequency = <1000000000>;
                        clocks = <&cpg CPG_CORE R8A77470_CLK_Z2>;
-                       power-domains = <&sysc 5>;
+                       power-domains = <&sysc R8A77470_PD_CA7_CPU0>;
                        next-level-cache = <&L2_CA7>;
                };
 
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <1>;
+                       clock-frequency = <1000000000>;
+                       clocks = <&cpg CPG_CORE R8A77470_CLK_Z2>;
+                       power-domains = <&sysc R8A77470_PD_CA7_CPU1>;
+                       next-level-cache = <&L2_CA7>;
+               };
 
                L2_CA7: cache-controller-0 {
                        compatible = "cache";
                        cache-unified;
                        cache-level = <2>;
-                       power-domains = <&sysc 21>;
+                       power-domains = <&sysc R8A77470_PD_CA7_SCU>;
                };
        };
 
                #size-cells = <2>;
                ranges;
 
+               gpio0: gpio@e6050000 {
+                       compatible = "renesas,gpio-r8a77470",
+                                    "renesas,rcar-gen2-gpio";
+                       reg = <0 0xe6050000 0 0x50>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 0 23>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 912>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 912>;
+               };
+
+               gpio1: gpio@e6051000 {
+                       compatible = "renesas,gpio-r8a77470",
+                                    "renesas,rcar-gen2-gpio";
+                       reg = <0 0xe6051000 0 0x50>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 32 23>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 911>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 911>;
+               };
+
+               gpio2: gpio@e6052000 {
+                       compatible = "renesas,gpio-r8a77470",
+                                    "renesas,rcar-gen2-gpio";
+                       reg = <0 0xe6052000 0 0x50>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 64 32>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 910>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 910>;
+               };
+
+               gpio3: gpio@e6053000 {
+                       compatible = "renesas,gpio-r8a77470",
+                                    "renesas,rcar-gen2-gpio";
+                       reg = <0 0xe6053000 0 0x50>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 96 30>;
+                       gpio-reserved-ranges = <17 10>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 909>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 909>;
+               };
+
+               gpio4: gpio@e6054000 {
+                       compatible = "renesas,gpio-r8a77470",
+                                    "renesas,rcar-gen2-gpio";
+                       reg = <0 0xe6054000 0 0x50>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 128 26>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 908>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 908>;
+               };
+
+               gpio5: gpio@e6055000 {
+                       compatible = "renesas,gpio-r8a77470",
+                                    "renesas,rcar-gen2-gpio";
+                       reg = <0 0xe6055000 0 0x50>;
+                       interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 160 32>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 907>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 907>;
+               };
+
+               pfc: pin-controller@e6060000 {
+                       compatible = "renesas,pfc-r8a77470";
+                       reg = <0 0xe6060000 0 0x118>;
+               };
+
                cpg: clock-controller@e6150000 {
                        compatible = "renesas,r8a77470-cpg-mssr";
                        reg = <0 0xe6150000 0 0x1000>;
                        #reset-cells = <1>;
                };
 
+               apmu@e6151000 {
+                       compatible = "renesas,r8a77470-apmu", "renesas,apmu";
+                       reg = <0 0xe6151000 0 0x188>;
+                       cpus = <&cpu0 &cpu1>;
+               };
+
                rst: reset-controller@e6160000 {
                        compatible = "renesas,r8a77470-rst";
                        reg = <0 0xe6160000 0 0x100>;
                                     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 407>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                };
 
                        reg = <0 0xe6300000 0 0x20000>;
                };
 
+               i2c4: i2c@e6520000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77470",
+                                    "renesas,rcar-gen2-i2c";
+                       reg = <0 0xe6520000 0 0x40>;
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 927>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
                dmac0: dma-controller@e6700000 {
                        compatible = "renesas,dmac-r8a77470",
                                     "renesas,rcar-dmac";
                                          "ch12", "ch13", "ch14";
                        clocks = <&cpg CPG_MOD 219>;
                        clock-names = "fck";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 219>;
                        #dma-cells = <1>;
                        dma-channels = <15>;
                                          "ch12", "ch13", "ch14";
                        clocks = <&cpg CPG_MOD 218>;
                        clock-names = "fck";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 218>;
                        #dma-cells = <1>;
                        dma-channels = <15>;
                        reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
                        interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 812>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 812>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
                               <&dmac1 0x29>, <&dmac1 0x2a>;
                        dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 721>;
                        status = "disabled";
                };
                        dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
                               <&dmac1 0x2d>, <&dmac1 0x2e>;
                        dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 720>;
                        status = "disabled";
                };
                        dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
                               <&dmac1 0x2b>, <&dmac1 0x2c>;
                        dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 719>;
                        status = "disabled";
                };
                        dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
                               <&dmac1 0x2f>, <&dmac1 0x30>;
                        dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 718>;
                        status = "disabled";
                };
                        dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
                               <&dmac1 0xfb>, <&dmac1 0xfc>;
                        dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 715>;
                        status = "disabled";
                };
                        dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
                               <&dmac1 0xfd>, <&dmac1 0xfe>;
                        dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 714>;
                        status = "disabled";
                };
 
+               sdhi2: sd@ee160000 {
+                       compatible = "renesas,sdhi-r8a77470",
+                                    "renesas,rcar-gen2-sdhi";
+                       reg = <0 0xee160000 0 0x328>;
+                       interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 312>;
+                       dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
+                              <&dmac1 0xd3>, <&dmac1 0xd4>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       max-frequency = <97500000>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 312>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@f1001000 {
                        compatible = "arm,gic-400";
                        #interrupt-cells = <3>;
                        interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
                        clocks = <&cpg CPG_MOD 408>;
                        clock-names = "clk";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        resets = <&cpg 408>;
                };
 
index de808d2ea856b19dffe002ecf7148f58d4bac658..cecb22924ec45c0ebd7357988c8afc63ecf83c1c 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Reference Device Tree Source for the Bock-W board
+ * Reference Device Tree Source for the R-Car M1A (R8A77781) Bock-W board
  *
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
index 1bce16cc6b209e63f808b6d2190a573c071b30fc..05db0ccad7a6b745f172d78288d7a77a4a4a873c 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for Renesas r8a7778
+ * Device Tree Source for the R-Car M1A (R8A77781) SoC
  *
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
index a4d0038363f004d43892966e1e733412df54acc5..abc14e7a4c93ee5e61af3613430c799c1f7d5c98 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the Marzen board
+ * Device Tree Source for the R-Car H1 (R8A77790) Marzen board
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Simon Horman
index 6b997bc016ee8a9e989a38ce476bb1c4f62d9f26..3bc133d9489c61374120d60752ec6755c4c75a71 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for Renesas r8a7779
+ * Device Tree Source for the R-Car H1 (R8A77790) SoC
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Simon Horman
 
        sata: sata@fc600000 {
                compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
-               reg = <0xfc600000 0x2000>;
+               reg = <0xfc600000 0x200000>;
                interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp1_clks R8A7779_CLK_SATA>;
                power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
index a13a92c2664507ee49d1ef8d0b3f5d80dbeffc5d..629da4cee1b971d6259317313f0f683103e1fe83 100644 (file)
                interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
                interrupt-controller;
 
+               onkey {
+                       compatible = "dlg,da9063-onkey";
+               };
+
                rtc {
                        compatible = "dlg,da9063-rtc";
                };
index 0925bdca438feedaa8ee956f8109fcca75dbbe1f..5a2747758f676a4b526231658fb728aae93d2fe9 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7790 SoC
+ * Device Tree Source for the R-Car H2 (R8A77900) SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  * Copyright (C) 2013-2014 Renesas Solutions Corp.
                sata0: sata@ee300000 {
                        compatible = "renesas,sata-r8a7790",
                                     "renesas,rcar-gen2-sata";
-                       reg = <0 0xee300000 0 0x2000>;
+                       reg = <0 0xee300000 0 0x200000>;
                        interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 815>;
                        power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
                sata1: sata@ee500000 {
                        compatible = "renesas,sata-r8a7790",
                                     "renesas,rcar-gen2-sata";
-                       reg = <0 0xee500000 0 0x2000>;
+                       reg = <0 0xee500000 0 0x200000>;
                        interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 814>;
                        power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
index 991ac6feedd5beb6123f7a12f98c8799d89f9565..6f875502453cf40a52df7337e53e4933c7a8053f 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7791 SoC
+ * Device Tree Source for the R-Car M2-W (R8A77910) SoC
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  * Copyright (C) 2013-2014 Renesas Solutions Corp.
                sata0: sata@ee300000 {
                        compatible = "renesas,sata-r8a7791",
                                     "renesas,rcar-gen2-sata";
-                       reg = <0 0xee300000 0 0x2000>;
+                       reg = <0 0xee300000 0 0x200000>;
                        interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 815>;
                        power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
                sata1: sata@ee500000 {
                        compatible = "renesas,sata-r8a7791",
                                     "renesas,rcar-gen2-sata";
-                       reg = <0 0xee500000 0 0x2000>;
+                       reg = <0 0xee500000 0 0x200000>;
                        interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 814>;
                        power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
index 63a978ec81cc09f0a4d989fff7171d893ba07387..8e9eb4b704d32f2a23179435f158030772ca2365 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7792 SoC
+ * Device Tree Source for the R-Car V2H (R8A77920) SoC
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
  */
                du: display@feb00000 {
                        compatible = "renesas,du-r8a7792";
                        reg = <0 0xfeb00000 0 0x40000>;
-                       reg-names = "du";
                        interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 724>,
index 6b2f3a4fd13d646c35e48fc46a7efa31ab42035e..f51601af89a2f4d5324e891a85944a6d57d2b074 100644 (file)
        status = "okay";
 };
 
+&cpu0 {
+       cpu0-supply = <&vdd_dvfs>;
+};
+
 &rwdt {
        timeout-sec = <60>;
        status = "okay";
                        compatible = "dlg,da9063-watchdog";
                };
        };
+
+       vdd_dvfs: regulator@68 {
+               compatible = "dlg,da9210";
+               reg = <0x68>;
+               interrupt-parent = <&irqc0>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+               regulator-min-microvolt = <1000000>;
+               regulator-max-microvolt = <1000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
 };
 
 &i2c4 {
index 620a570307ffcffa0ac2cc42918684882952b4b2..bf05110fac4e23beb7b5dff259d44b317a49c0db 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7793 SoC
+ * Device Tree Source for the R-Car M2-N (R8A77930) SoC
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
  */
index daec965889d3e5fe18e764daaf77758e24aacd0c..60e91ebfa65dc5b3d76cd28218b51aa4fceb8c17 100644 (file)
        clock-frequency = <400000>;
 };
 
+&i2c7 {
+       status = "okay";
+       clock-frequency = <100000>;
+
+       pmic@58 {
+               compatible = "dlg,da9063";
+               reg = <0x58>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-controller;
+
+               onkey {
+                       compatible = "dlg,da9063-onkey";
+               };
+
+               rtc {
+                       compatible = "dlg,da9063-rtc";
+               };
+
+               wdt {
+                       compatible = "dlg,da9063-watchdog";
+               };
+       };
+};
+
 &mmcif0 {
        pinctrl-0 = <&mmcif0_pins>;
        pinctrl-names = "default";
index ea2ca4bdaf1c129c3932644a45bce1145ebabfb6..8d797d34816e3625e1c3a56aa7e6af8cadc219dc 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7794 SoC
+ * Device Tree Source for the R-Car E2 (R8A77940) SoC
  *
  * Copyright (C) 2014 Renesas Electronics Corporation
  * Copyright (C) 2014 Ulrich Hecht
                du: display@feb00000 {
                        compatible = "renesas,du-r8a7794";
                        reg = <0 0xfeb00000 0 0x40000>;
-                       reg-names = "du";
                        interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 724>, <&cpg CPG_MOD 723>;
index afe29c95a006e8fa12d0ed66f5948e8ac1a17262..eaf94976ed6dfd0cbf5eed9a835564b8027a937f 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r9a06g032-sysctrl.h>
 
 / {
        compatible = "renesas,r9a06g032";
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0>;
-                       clocks = <&sysctrl 84>;
+                       clocks = <&sysctrl R9A06G032_CLK_A7MP>;
                };
 
                cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <1>;
-                       clocks = <&sysctrl 84>;
+                       clocks = <&sysctrl R9A06G032_CLK_A7MP>;
                        enable-method = "renesas,r9a06g032-smp";
                        cpu-release-addr = <0 0x4000c204>;
                };
                };
 
                uart0: serial@40060000 {
-                       compatible = "snps,dw-apb-uart";
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart", "snps,dw-apb-uart";
                        reg = <0x40060000 0x400>;
                        interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
-                       clocks = <&sysctrl 146>;
-                       clock-names = "baudclk";
+                       clocks = <&sysctrl R9A06G032_CLK_UART0>, <&sysctrl R9A06G032_HCLK_UART0>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart1: serial@40061000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart", "snps,dw-apb-uart";
+                       reg = <0x40061000 0x400>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART1>, <&sysctrl R9A06G032_HCLK_UART1>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart2: serial@40062000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart", "snps,dw-apb-uart";
+                       reg = <0x40062000 0x400>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART2>, <&sysctrl R9A06G032_HCLK_UART2>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart3: serial@50000000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart";
+                       reg = <0x50000000 0x400>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART3>, <&sysctrl R9A06G032_HCLK_UART3>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart4: serial@50001000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart";
+                       reg = <0x50001000 0x400>;
+                       interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART4>, <&sysctrl R9A06G032_HCLK_UART4>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart5: serial@50002000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart";
+                       reg = <0x50002000 0x400>;
+                       interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART5>, <&sysctrl R9A06G032_HCLK_UART5>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart6: serial@50003000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart";
+                       reg = <0x50003000 0x400>;
+                       interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART6>, <&sysctrl R9A06G032_HCLK_UART6>;
+                       clock-names = "baudclk", "apb_pclk";
+                       status = "disabled";
+               };
+
+               uart7: serial@50004000 {
+                       compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart";
+                       reg = <0x50004000 0x400>;
+                       interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl R9A06G032_CLK_UART7>, <&sysctrl R9A06G032_HCLK_UART7>;
+                       clock-names = "baudclk", "apb_pclk";
                        status = "disabled";
                };
 
index 67f57200d9a06ba1a2dde2b123aca62a1571230e..d560fc4051c5f7a355a0896f0e5d0e76e41acbeb 100644 (file)
                        /* no rts / cts for uart2 */
                };
 
-               spi {
+               spi-pins {
                        spi_txd:spi-txd {
                                rockchip,pins = <1 29 RK_FUNC_3 &pcfg_pull_default>;
                        };
index 45fd2b302dda1d1c3c995149f2386c1d1db97af9..4a2890618f6fcf8d914eef78c4a027e1f70b3ac1 100644 (file)
@@ -93,6 +93,8 @@
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                gpio = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdmmc_pwr>;
                startup-delay-us = <100000>;
                vin-supply = <&vcc_io>;
        };
                };
        };
 
+       sd0 {
+               sdmmc_pwr: sdmmc-pwr {
+                       rockchip,pins = <RK_GPIO3 1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
        usb {
                host_vbus_drv: host-vbus-drv {
                        rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
index aa123f93f181c0d1b01f210fdee5e134518bfdc2..b6f79097373671d8d41f9200ebbf470cfc0b5f19 100644 (file)
                };
        };
 
+       display-subsystem {
+               compatible = "rockchip,display-subsystem";
+               ports = <&vop0_out>, <&vop1_out>;
+       };
+
        sram: sram@10080000 {
                compatible = "mmio-sram";
                reg = <0x10080000 0x8000>;
                };
        };
 
+       vop0: vop@1010c000 {
+               compatible = "rockchip,rk3188-vop";
+               reg = <0x1010c000 0x1000>;
+               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru ACLK_LCDC0>, <&cru DCLK_LCDC0>, <&cru HCLK_LCDC0>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
+               reset-names = "axi", "ahb", "dclk";
+               status = "disabled";
+
+               vop0_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+
+       vop1: vop@1010e000 {
+               compatible = "rockchip,rk3188-vop";
+               reg = <0x1010e000 0x1000>;
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru ACLK_LCDC1>, <&cru DCLK_LCDC1>, <&cru HCLK_LCDC1>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
+               reset-names = "axi", "ahb", "dclk";
+               status = "disabled";
+
+               vop1_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+
        timer3: timer@2000e000 {
                compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
                reg = <0x2000e000 0x20>;
                        };
                };
 
+               lcdc1 {
+                       lcdc1_dclk: lcdc1-dclk {
+                               rockchip,pins = <2 RK_PD0 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       lcdc1_den: lcdc1-den {
+                               rockchip,pins = <2 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       lcdc1_hsync: lcdc1-hsync {
+                               rockchip,pins = <2 RK_PD2 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       lcdc1_vsync: lcdc1-vsync {
+                               rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       lcdc1_rgb24: ldcd1-rgb24 {
+                               rockchip,pins = <2 RK_PA0 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA1 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA2 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA3 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA4 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA5 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA6 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PA7 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB0 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB1 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB2 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB3 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB4 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB5 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PB7 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC0 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC1 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC2 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC3 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC4 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC5 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC6 RK_FUNC_1 &pcfg_pull_none>,
+                                               <2 RK_PC7 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+               };
+
                pwm0 {
                        pwm0_out: pwm0-out {
                                rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-tinker-s.dts b/arch/arm/boot/dts/rk3288-tinker-s.dts
new file mode 100644 (file)
index 0000000..3709392
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ */
+
+/dts-v1/;
+
+#include "rk3288-tinker.dtsi"
+
+/ {
+       model = "Rockchip RK3288 Asus Tinker Board S";
+       compatible = "asus,rk3288-tinker-s", "rockchip,rk3288";
+};
+
+&emmc {
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       disable-wp;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
+       max-frequency = <150000000>;
+       mmc-hs200-1_8v;
+       mmc-ddr-1_8v;
+       status = "okay";
+};
index ceade5962899e64ab1733ed937f669b1ff94c256..1e43527aa196050527c68a8c445746861cd3a0ab 100644 (file)
@@ -5,503 +5,9 @@
 
 /dts-v1/;
 
-#include "rk3288.dtsi"
-#include <dt-bindings/input/input.h>
+#include "rk3288-tinker.dtsi"
 
 / {
-       model = "Rockchip RK3288 Tinker Board";
+       model = "Rockchip RK3288 Asus Tinker Board";
        compatible = "asus,rk3288-tinker", "rockchip,rk3288";
-
-       chosen {
-               stdout-path = "serial2:115200n8";
-       };
-
-       memory {
-               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";
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               autorepeat;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&pwrbtn>;
-
-               button@0 {
-                       gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_POWER>;
-                       label = "GPIO Key Power";
-                       linux,input-type = <1>;
-                       wakeup-source;
-                       debounce-interval = <100>;
-               };
-       };
-
-       gpio-leds {
-               compatible = "gpio-leds";
-
-               act-led {
-                       gpios=<&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger="mmc0";
-               };
-
-               heartbeat-led {
-                       gpios=<&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger="heartbeat";
-               };
-
-               pwr-led {
-                       gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "default-on";
-               };
-       };
-
-       sound {
-               compatible = "simple-audio-card";
-               simple-audio-card,format = "i2s";
-               simple-audio-card,name = "rockchip,tinker-codec";
-               simple-audio-card,mclk-fs = <512>;
-
-               simple-audio-card,codec {
-                       sound-dai = <&hdmi>;
-               };
-
-               simple-audio-card,cpu {
-                       sound-dai = <&i2s>;
-               };
-       };
-
-       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;
-       };
-
-       vcc_sd: sdmmc-regulator {
-               compatible = "regulator-fixed";
-               gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&sdmmc_pwr>;
-               regulator-name = "vcc_sd";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               startup-delay-us = <100000>;
-               vin-supply = <&vcc_io>;
-       };
-};
-
-&cpu0 {
-       cpu0-supply = <&vdd_cpu>;
-};
-
-&gmac {
-       assigned-clocks = <&cru SCLK_MAC>;
-       assigned-clock-parents = <&ext_gmac>;
-       clock_in_out = "input";
-       phy-mode = "rgmii";
-       phy-supply = <&vcc33_lan>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&rgmii_pins>;
-       snps,reset-gpio = <&gpio4 7 0>;
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 1000000>;
-       tx_delay = <0x30>;
-       rx_delay = <0x10>;
-       status = "ok";
-};
-
-&gpu {
-       mali-supply = <&vdd_gpu>;
-       status = "okay";
-};
-
-&hdmi {
-       ddc-i2c-bus = <&i2c5>;
-       status = "okay";
-};
-
-&i2c0 {
-       clock-frequency = <400000>;
-       status = "okay";
-
-       rk808: pmic@1b {
-               compatible = "rockchip,rk808";
-               reg = <0x1b>;
-               interrupt-parent = <&gpio0>;
-               interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
-               #clock-cells = <1>;
-               clock-output-names = "xin32k", "rk808-clkout2";
-               dvs-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>,
-                               <&gpio0 12 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pmic_int &global_pwroff &dvs_1 &dvs_2>;
-               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_sys>;
-               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-ramp-delay = <6000>;
-                               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-ramp-delay = <6000>;
-                               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>;
-                               };
-                       };
-
-                       vcc18_ldo1: LDO_REG1 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-name = "vcc18_ldo1";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcc33_mipi: LDO_REG2 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-name = "vcc33_mipi";
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vdd_10: LDO_REG3 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <1000000>;
-                               regulator-name = "vdd_10";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1000000>;
-                               };
-                       };
-
-                       vcc18_codec: LDO_REG4 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-name = "vcc18_codec";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vccio_sd: LDO_REG5 {
-                               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>;
-                               };
-                       };
-
-                       vcc33_sd: SWITCH_REG1 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-name = "vcc33_sd";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-
-                       vcc33_lan: SWITCH_REG2 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-name = "vcc33_lan";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-               };
-       };
-};
-
-&i2c2 {
-       status = "okay";
-};
-
-&i2c5 {
-       status = "okay";
-};
-
-&i2s {
-       #sound-dai-cells = <0>;
-       status = "okay";
-};
-
-&io_domains {
-       status = "okay";
-
-       sdcard-supply = <&vccio_sd>;
-};
-
-&pinctrl {
-       pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
-               drive-strength = <8>;
-       };
-
-       pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
-               bias-pull-up;
-               drive-strength = <8>;
-       };
-
-       backlight {
-               bl_en: bl-en {
-                       rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       buttons {
-               pwrbtn: pwrbtn {
-                       rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       eth_phy {
-               eth_phy_pwr: eth-phy-pwr {
-                       rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       pmic {
-               pmic_int: pmic-int {
-                       rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO \
-                                       &pcfg_pull_up>;
-               };
-
-               dvs_1: dvs-1 {
-                       rockchip,pins = <RK_GPIO0 11 RK_FUNC_GPIO \
-                                       &pcfg_pull_down>;
-               };
-
-               dvs_2: dvs-2 {
-                       rockchip,pins = <RK_GPIO0 12 RK_FUNC_GPIO \
-                                       &pcfg_pull_down>;
-               };
-       };
-
-       sdmmc {
-               sdmmc_bus4: sdmmc-bus4 {
-                       rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
-                                       <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
-                                       <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
-                                       <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
-               };
-
-               sdmmc_clk: sdmmc-clk {
-                       rockchip,pins = <6 20 RK_FUNC_1 \
-                                       &pcfg_pull_none_drv_8ma>;
-               };
-
-               sdmmc_cmd: sdmmc-cmd {
-                       rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
-               };
-
-               sdmmc_pwr: sdmmc-pwr {
-                       rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       usb {
-               host_vbus_drv: host-vbus-drv {
-                       rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               pwr_3g: pwr-3g {
-                       rockchip,pins = <7 8 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-};
-
-&pwm0 {
-       status = "okay";
-};
-
-&saradc {
-       vref-supply = <&vcc18_ldo1>;
-       status ="okay";
-};
-
-&sdmmc {
-       bus-width = <4>;
-       cap-mmc-highspeed;
-       cap-sd-highspeed;
-       card-detect-delay = <200>;
-       disable-wp;                     /* wp not hooked up */
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
-       status = "okay";
-       vmmc-supply = <&vcc33_sd>;
-       vqmmc-supply = <&vccio_sd>;
-};
-
-&tsadc {
-       rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
-       rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */
-       status = "okay";
-};
-
-&uart0 {
-       status = "okay";
-};
-
-&uart1 {
-       status = "okay";
-};
-
-&uart2 {
-       status = "okay";
-};
-
-&uart3 {
-       status = "okay";
-};
-
-&uart4 {
-       status = "okay";
-};
-
-&usbphy {
-       status = "okay";
-};
-
-&usb_host0_ehci {
-       status = "okay";
-};
-
-&usb_host1 {
-       status = "okay";
-};
-
-&usb_otg {
-       status= "okay";
-};
-
-&vopb {
-       status = "okay";
-};
-
-&vopb_mmu {
-       status = "okay";
-};
-
-&vopl {
-       status = "okay";
-};
-
-&vopl_mmu {
-       status = "okay";
-};
-
-&wdt {
-       status = "okay";
 };
diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi
new file mode 100644 (file)
index 0000000..aa107ee
--- /dev/null
@@ -0,0 +1,502 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ */
+
+#include "rk3288.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       chosen {
+               stdout-path = "serial2:115200n8";
+       };
+
+       memory {
+               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";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               autorepeat;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwrbtn>;
+
+               button@0 {
+                       gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       label = "GPIO Key Power";
+                       linux,input-type = <1>;
+                       wakeup-source;
+                       debounce-interval = <100>;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+
+               act-led {
+                       gpios=<&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger="mmc0";
+               };
+
+               heartbeat-led {
+                       gpios=<&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger="heartbeat";
+               };
+
+               pwr-led {
+                       gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "default-on";
+               };
+       };
+
+       sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,name = "rockchip,tinker-codec";
+               simple-audio-card,mclk-fs = <512>;
+
+               simple-audio-card,codec {
+                       sound-dai = <&hdmi>;
+               };
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s>;
+               };
+       };
+
+       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;
+       };
+
+       vcc_sd: sdmmc-regulator {
+               compatible = "regulator-fixed";
+               gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdmmc_pwr>;
+               regulator-name = "vcc_sd";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <100000>;
+               vin-supply = <&vcc_io>;
+       };
+};
+
+&cpu0 {
+       cpu0-supply = <&vdd_cpu>;
+};
+
+&gmac {
+       assigned-clocks = <&cru SCLK_MAC>;
+       assigned-clock-parents = <&ext_gmac>;
+       clock_in_out = "input";
+       phy-mode = "rgmii";
+       phy-supply = <&vcc33_lan>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       snps,reset-gpio = <&gpio4 7 0>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 10000 1000000>;
+       tx_delay = <0x30>;
+       rx_delay = <0x10>;
+       status = "ok";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c5>;
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+               dvs-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>,
+                               <&gpio0 12 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int &global_pwroff &dvs_1 &dvs_2>;
+               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_sys>;
+               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-ramp-delay = <6000>;
+                               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-ramp-delay = <6000>;
+                               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>;
+                               };
+                       };
+
+                       vcc18_ldo1: LDO_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc18_ldo1";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc33_mipi: LDO_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc33_mipi";
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_10: LDO_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-name = "vdd_10";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc18_codec: LDO_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc18_codec";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG5 {
+                               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>;
+                               };
+                       };
+
+                       vcc33_sd: SWITCH_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc33_sd";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc33_lan: SWITCH_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc33_lan";
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2s {
+       #sound-dai-cells = <0>;
+       status = "okay";
+};
+
+&io_domains {
+       status = "okay";
+
+       sdcard-supply = <&vccio_sd>;
+};
+
+&pinctrl {
+       pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+               drive-strength = <8>;
+       };
+
+       pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+               bias-pull-up;
+               drive-strength = <8>;
+       };
+
+       backlight {
+               bl_en: bl-en {
+                       rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       buttons {
+               pwrbtn: pwrbtn {
+                       rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       eth_phy {
+               eth_phy_pwr: eth-phy-pwr {
+                       rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int: pmic-int {
+                       rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO \
+                                       &pcfg_pull_up>;
+               };
+
+               dvs_1: dvs-1 {
+                       rockchip,pins = <RK_GPIO0 11 RK_FUNC_GPIO \
+                                       &pcfg_pull_down>;
+               };
+
+               dvs_2: dvs-2 {
+                       rockchip,pins = <RK_GPIO0 12 RK_FUNC_GPIO \
+                                       &pcfg_pull_down>;
+               };
+       };
+
+       sdmmc {
+               sdmmc_bus4: sdmmc-bus4 {
+                       rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+                                       <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+                                       <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+                                       <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+               };
+
+               sdmmc_clk: sdmmc-clk {
+                       rockchip,pins = <6 20 RK_FUNC_1 \
+                                       &pcfg_pull_none_drv_8ma>;
+               };
+
+               sdmmc_cmd: sdmmc-cmd {
+                       rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+               };
+
+               sdmmc_pwr: sdmmc-pwr {
+                       rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb {
+               host_vbus_drv: host-vbus-drv {
+                       rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pwr_3g: pwr-3g {
+                       rockchip,pins = <7 8 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcc18_ldo1>;
+       status ="okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       card-detect-delay = <200>;
+       disable-wp;                     /* wp not hooked up */
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+       status = "okay";
+       vmmc-supply = <&vcc33_sd>;
+       vqmmc-supply = <&vccio_sd>;
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart4 {
+       status = "okay";
+};
+
+&usbphy {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host1 {
+       status = "okay";
+};
+
+&usb_otg {
+       status= "okay";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
+
+&wdt {
+       status = "okay";
+};
index 67358562a6ea2df8df87b522c825b16c3f83da60..75f454a210d628cd63fd1238c40067fbbdfda68d 100644 (file)
                        interrupts = <30>;
 
                        wakeup-interrupt-controller {
-                               compatible = "samsung,exynos4210-wakeup-eint";
+                               compatible = "samsung,s5pv210-wakeup-eint";
                                interrupts = <16>;
                                interrupt-parent = <&vic0>;
                        };
index 61f68e5c48e96324eb1c6cfbc26d90ade0d4a89c..843052f14f1cff7d32cf9622ba1ea470c529aa2f 100644 (file)
@@ -47,6 +47,7 @@
 #include <dt-bindings/dma/at91.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/clock/at91.h>
+#include <dt-bindings/iio/adc/at91-sama5d2_adc.h>
 
 / {
        model = "Atmel SAMA5D2 family SoC";
@@ -58,6 +59,8 @@
                serial1 = &uart3;
                tcb0 = &tcb0;
                tcb1 = &tcb1;
+               i2s0 = &i2s0;
+               i2s1 = &i2s1;
        };
 
        cpus {
                clocks = <&mck>;
                clock-names = "apb_pclk";
 
-               port {
-                       etb_in: endpoint {
-                               slave-mode;
-                               remote-endpoint = <&etm_out>;
+               in-ports {
+                       port {
+                               etb_in: endpoint {
+                                       remote-endpoint = <&etm_out>;
+                               };
                        };
                };
        };
                clocks = <&mck>;
                clock-names = "apb_pclk";
 
-               port {
-                       etm_out: endpoint {
-                               remote-endpoint = <&etb_in>;
+               out-ports {
+                       port {
+                               etm_out: endpoint {
+                                       remote-endpoint = <&etb_in>;
+                               };
                        };
                };
        };
                        };
                };
 
-               nand0: nand@80000000 {
-                       compatible = "atmel,sama5d2-nand";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-                       reg = < /* EBI CS3 */
-                               0x80000000 0x08000000
-                               /* SMC PMECC regs */
-                               0xf8014070 0x00000490
-                               /* SMC PMECC Error Location regs */
-                               0xf8014500 0x00000200
-                               /* ROM Galois tables */
-                               0x00040000 0x00018000
-                               >;
-                       interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>;
-                       atmel,nand-addr-offset = <21>;
-                       atmel,nand-cmd-offset = <22>;
-                       atmel,nand-has-dma;
-                       atmel,has-pmecc;
-                       atmel,pmecc-lookup-table-offset = <0x0 0x8000>;
-                       status = "disabled";
-
-                       nfc@c0000000 {
-                               compatible = "atmel,sama5d3-nfc";
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               reg = < /* NFC Command Registers */
-                                       0xc0000000 0x08000000
-                                       /* NFC HSMC regs */
-                                       0xf8014000 0x00000070
-                                       /* NFC SRAM banks */
-                                       0x00100000 0x00100000
-                                       >;
-                               clocks = <&hsmc_clk>;
-                               atmel,write-by-sram;
-                       };
-               };
-
                sdmmc0: sdio-host@a0000000 {
                        compatible = "atmel,sama5d2-sdhci";
                        reg = <0xa0000000 0x300>;
                                                atmel,clk-output-range = <0 100000000>;
                                        };
                                };
+
+                               i2s_clkmux {
+                                       compatible = "atmel,sama5d2-clk-i2s-mux";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       i2s0muxck: i2s0_muxclk {
+                                               clocks = <&i2s0_clk>, <&i2s0_gclk>;
+                                               #clock-cells = <0>;
+                                               reg = <0>;
+                                       };
+
+                                       i2s1muxck: i2s1_muxclk {
+                                               clocks = <&i2s1_clk>, <&i2s1_gclk>;
+                                               #clock-cells = <0>;
+                                               reg = <1>;
+                                       };
+                               };
                        };
 
                        qspi0: spi@f0020000 {
                                clocks = <&clk32k>;
                        };
 
+                       i2s0: i2s@f8050000 {
+                               compatible = "atmel,sama5d2-i2s";
+                               reg = <0xf8050000 0x100>;
+                               interrupts = <54 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(31))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(32))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&i2s0_clk>, <&i2s0_gclk>;
+                               clock-names = "pclk", "gclk";
+                               assigned-clocks = <&i2s0muxck>;
+                               assigned-clock-parents = <&i2s0_gclk>;
+                               status = "disabled";
+                       };
+
                        can0: can@f8054000 {
                                compatible = "bosch,m_can";
                                reg = <0xf8054000 0x4000>, <0x210000 0x4000>;
                                atmel,max-sample-rate-hz = <20000000>;
                                atmel,startup-time-ms = <4>;
                                atmel,trigger-edge-type = <IRQ_TYPE_EDGE_RISING>;
+                               #io-channel-cells = <1>;
+                               status = "disabled";
+                       };
+
+                       resistive_touch: resistive-touch {
+                               compatible = "resistive-adc-touch";
+                               io-channels = <&adc AT91_SAMA5D2_ADC_X_CHANNEL>,
+                                             <&adc AT91_SAMA5D2_ADC_Y_CHANNEL>,
+                                             <&adc AT91_SAMA5D2_ADC_P_CHANNEL>;
+                               io-channel-names = "x", "y", "pressure";
+                               touchscreen-min-pressure = <50000>;
                                status = "disabled";
                        };
 
                                status = "disabled";
                        };
 
+                       i2s1: i2s@fc04c000 {
+                               compatible = "atmel,sama5d2-i2s";
+                               reg = <0xfc04c000 0x100>;
+                               interrupts = <55 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(33))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(34))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&i2s1_clk>, <&i2s1_gclk>;
+                               clock-names = "pclk", "gclk";
+                               assigned-clocks = <&i2s1muxck>;
+                               assigned-parrents = <&i2s1_gclk>;
+                               status = "disabled";
+                       };
+
                        can1: can@fc050000 {
                                compatible = "bosch,m_can";
                                reg = <0xfc050000 0x4000>, <0x210000 0x4000>;
index 92a35a1942b6a1b75c750a8a96eb1cea0e6355b0..7371f2a0460fbf8b8c45a8afc0ac9484bf337b01 100644 (file)
                                };
                        };
 
-                       rstc@fc068600 {
+                       reset_controller: rstc@fc068600 {
                                compatible = "atmel,sama5d3-rstc", "atmel,at91sam9g45-rstc";
                                reg = <0xfc068600 0x10>;
                                clocks = <&clk32k>;
                        };
 
-                       shdwc@fc068610 {
+                       shutdown_controller: shdwc@fc068610 {
                                compatible = "atmel,at91sam9x5-shdwc";
                                reg = <0xfc068610 0x10>;
                                clocks = <&clk32k>;
                                clocks = <&h32ck>;
                        };
 
-                       watchdog@fc068640 {
+                       watchdog: watchdog@fc068640 {
                                compatible = "atmel,sama5d4-wdt";
                                reg = <0xfc068640 0x10>;
                                interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
                        };
 
 
-                       pinctrl@fc06a000 {
+                       pinctrl: pinctrl@fc06a000 {
                                #address-cells = <1>;
                                #size-cells = <1>;
                                compatible = "atmel,sama5d3-pinctrl", "atmel,at91sam9x5-pinctrl", "simple-bus";
index b38f8c24055800c45e1e81aef451f08ac9e27be5..2d300396f0edd49d16ae46b8949801071438d699 100644 (file)
@@ -22,8 +22,6 @@
        #size-cells = <1>;
 
        aliases {
-               ethernet0 = &gmac0;
-               ethernet1 = &gmac1;
                serial0 = &uart0;
                serial1 = &uart1;
                timer0 = &timer0;
                                                clk-gate = <0xa0 9>;
                                        };
 
+                                       nand_ecc_clk: nand_ecc_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-gate-clk";
+                                               clocks = <&nand_x_clk>;
+                                               clk-gate = <0xa0 9>;
+                                       };
+
                                        nand_clk: nand_clk {
                                                #clock-cells = <0>;
                                                compatible = "altr,socfpga-gate-clk";
-                                               clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+                                               clocks = <&nand_x_clk>;
                                                clk-gate = <0xa0 10>;
                                                fixed-divider = <4>;
                                        };
                        reg-names = "nand_data", "denali_reg";
                        interrupts = <0x0 0x90 0x4>;
                        dma-mask = <0xffffffff>;
-                       clocks = <&nand_x_clk>;
+                       clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>;
+                       clock-names = "nand", "nand_x", "ecc";
                        status = "disabled";
                };
 
                        reg = <0xffc08000 0x1000>;
                        clocks = <&l4_sp_clk>;
                        clock-names = "timer";
+                       resets = <&rst SPTIMER0_RESET>;
+                       reset-names = "timer";
                };
 
                timer1: timer1@ffc09000 {
                        reg = <0xffc09000 0x1000>;
                        clocks = <&l4_sp_clk>;
                        clock-names = "timer";
+                       resets = <&rst SPTIMER1_RESET>;
+                       reset-names = "timer";
                };
 
                timer2: timer2@ffd00000 {
                        reg = <0xffd00000 0x1000>;
                        clocks = <&osc1>;
                        clock-names = "timer";
+                       resets = <&rst OSC1TIMER0_RESET>;
+                       reset-names = "timer";
                };
 
                timer3: timer3@ffd01000 {
                        reg = <0xffd01000 0x1000>;
                        clocks = <&osc1>;
                        clock-names = "timer";
+                       resets = <&rst OSC1TIMER1_RESET>;
+                       reset-names = "timer";
                };
 
                uart0: serial0@ffc02000 {
index a4dcb68f4322e2c96dd8bad240bb94b7eb307c9e..59ef13e37536c917ecf5caa5db0e5647fed7fa4d 100644 (file)
                                                clk-gate = <0xC8 11>;
                                        };
 
-                                       nand_clk: nand_clk {
+                                       nand_x_clk: nand_x_clk {
                                                #clock-cells = <0>;
                                                compatible = "altr,socfpga-a10-gate-clk";
                                                clocks = <&l4_mp_clk>;
                                                clk-gate = <0xC8 10>;
                                        };
 
+                                       nand_ecc_clk: nand_ecc_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-a10-gate-clk";
+                                               clocks = <&nand_x_clk>;
+                                               clk-gate = <0xC8 10>;
+                                       };
+
+                                       nand_clk: nand_clk {
+                                               #clock-cells = <0>;
+                                               compatible = "altr,socfpga-a10-gate-clk";
+                                               clocks = <&nand_x_clk>;
+                                               fixed-divider = <4>;
+                                               clk-gate = <0xC8 10>;
+                                       };
+
                                        spi_m_clk: spi_m_clk {
                                                #clock-cells = <0>;
                                                compatible = "altr,socfpga-a10-gate-clk";
                        status = "disabled";
                };
 
-               sdr: sdr@ffc25000 {
+               sdr: sdr@ffcfb100 {
                        compatible = "altr,sdr-ctl", "syscon";
                        reg = <0xffcfb100 0x80>;
                };
                        reg-names = "nand_data", "denali_reg";
                        interrupts = <0 99 4>;
                        dma-mask = <0xffffffff>;
-                       clocks = <&nand_clk>;
+                       clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>;
+                       clock-names = "nand", "nand_x", "ecc";
                        status = "disabled";
                };
 
                timer@ffffc600 {
                        compatible = "arm,cortex-a9-twd-timer";
                        reg = <0xffffc600 0x100>;
-                       interrupts = <1 13 0xf04>;
+                       interrupts = <1 13 0xf01>;
                        clocks = <&mpu_periph_clk>;
                };
 
                        reg = <0xffc02700 0x100>;
                        clocks = <&l4_sp_clk>;
                        clock-names = "timer";
+                       resets = <&rst SPTIMER0_RESET>;
+                       reset-names = "timer";
                };
 
                timer1: timer1@ffc02800 {
                        reg = <0xffc02800 0x100>;
                        clocks = <&l4_sp_clk>;
                        clock-names = "timer";
+                       resets = <&rst SPTIMER1_RESET>;
+                       reset-names = "timer";
                };
 
                timer2: timer2@ffd00000 {
                        reg = <0xffd00000 0x100>;
                        clocks = <&l4_sys_free_clk>;
                        clock-names = "timer";
+                       resets = <&rst L4SYSTIMER0_RESET>;
+                       reset-names = "timer";
                };
 
                timer3: timer3@ffd00100 {
                        reg = <0xffd01000 0x100>;
                        clocks = <&l4_sys_free_clk>;
                        clock-names = "timer";
+                       resets = <&rst L4SYSTIMER1_RESET>;
+                       reset-names = "timer";
                };
 
                uart0: serial0@ffc02000 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts b/arch/arm/boot/dts/socfpga_cyclone5_de0_nano_soc.dts
new file mode 100644 (file)
index 0000000..31b01a9
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "socfpga_cyclone5.dtsi"
+
+/ {
+       model = "Terasic DE-0(Atlas)";
+       compatible = "terasic,de0-atlas", "altr,socfpga-cyclone5", "altr,socfpga";
+
+       chosen {
+               bootargs = "earlyprintk";
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@0 {
+               name = "memory";
+               device_type = "memory";
+               reg = <0x0 0x40000000>; /* 1GB */
+       };
+
+       aliases {
+               ethernet0 = &gmac1;
+       };
+
+       regulator_3_3v: 3-3-v-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               hps0 {
+                       label = "hps_led0";
+                       gpios = <&portb 24 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&gmac1 {
+       status = "okay";
+       phy-mode = "rgmii";
+
+       txd0-skew-ps = <0>; /* -420ps */
+       txd1-skew-ps = <0>; /* -420ps */
+       txd2-skew-ps = <0>; /* -420ps */
+       txd3-skew-ps = <0>; /* -420ps */
+       rxd0-skew-ps = <420>; /* 0ps */
+       rxd1-skew-ps = <420>; /* 0ps */
+       rxd2-skew-ps = <420>; /* 0ps */
+       rxd3-skew-ps = <420>; /* 0ps */
+       txen-skew-ps = <0>; /* -420ps */
+       txc-skew-ps = <1860>; /* 960ps */
+       rxdv-skew-ps = <420>; /* 0ps */
+       rxc-skew-ps = <1680>; /* 780ps */
+
+       max-frame-size = <3800>;
+};
+
+&gpio0 {
+       status = "okay";
+};
+
+&gpio1 {
+       status = "okay";
+};
+
+&gpio2 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+       clock-frequency = <100000>;
+
+       adxl345: adxl345@53 {
+               compatible = "adi,adxl345";
+               reg = <0x53>;
+
+               interrupt-parent = <&portc>;
+               interrupts = <3 2>;
+       };
+};
+
+&mmc0 {
+       vmmc-supply = <&regulator_3_3v>;
+       vqmmc-supply = <&regulator_3_3v>;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
deleted file mode 100644 (file)
index b280e64..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright Altera Corporation (C) 2015. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "socfpga_cyclone5.dtsi"
-
-/ {
-       model = "Terasic DE-0(Atlas)";
-       compatible = "terasic,de0-atlas", "altr,socfpga-cyclone5", "altr,socfpga";
-
-       chosen {
-               bootargs = "earlyprintk";
-               stdout-path = "serial0:115200n8";
-       };
-
-       memory@0 {
-               name = "memory";
-               device_type = "memory";
-               reg = <0x0 0x40000000>; /* 1GB */
-       };
-
-       aliases {
-               ethernet0 = &gmac1;
-       };
-
-       regulator_3_3v: 3-3-v-regulator {
-               compatible = "regulator-fixed";
-               regulator-name = "3.3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               hps0 {
-                       label = "hps_led0";
-                       gpios = <&portb 24 0>;
-                       linux,default-trigger = "heartbeat";
-               };
-       };
-};
-
-&gmac1 {
-       status = "okay";
-       phy-mode = "rgmii";
-
-       txd0-skew-ps = <0>; /* -420ps */
-       txd1-skew-ps = <0>; /* -420ps */
-       txd2-skew-ps = <0>; /* -420ps */
-       txd3-skew-ps = <0>; /* -420ps */
-       rxd0-skew-ps = <420>; /* 0ps */
-       rxd1-skew-ps = <420>; /* 0ps */
-       rxd2-skew-ps = <420>; /* 0ps */
-       rxd3-skew-ps = <420>; /* 0ps */
-       txen-skew-ps = <0>; /* -420ps */
-       txc-skew-ps = <1860>; /* 960ps */
-       rxdv-skew-ps = <420>; /* 0ps */
-       rxc-skew-ps = <1680>; /* 780ps */
-
-       max-frame-size = <3800>;
-};
-
-&gpio0 {
-       status = "okay";
-};
-
-&gpio1 {
-       status = "okay";
-};
-
-&gpio2 {
-       status = "okay";
-};
-
-&i2c0 {
-       status = "okay";
-       clock-frequency = <100000>;
-
-       adxl345: adxl345@0 {
-               compatible = "adi,adxl345";
-               reg = <0x53>;
-
-               interrupt-parent = <&portc>;
-               interrupts = <3 2>;
-       };
-};
-
-&mmc0 {
-       vmmc-supply = <&regulator_3_3v>;
-       vqmmc-supply = <&regulator_3_3v>;
-       status = "okay";
-};
-
-&uart0 {
-       status = "okay";
-};
-
-&usb1 {
-       status = "okay";
-};
index 53bf99eef66de70fba4647fb9592750afffee486..031c721441fffcf97d4c1a3e2803aa1b3d19e124 100644 (file)
        model = "EBV SOCrates";
        compatible = "ebv,socrates", "altr,socfpga-cyclone5", "altr,socfpga";
 
+       aliases {
+               ethernet0 = &gmac1;
+       };
+
        chosen {
-               bootargs = "console=ttyS0,115200";
+               bootargs = "earlyprintk";
+               stdout-path = "serial0:115200n8";
        };
 
        memory@0 {
index f50b19447de6981c377e6d9b7729f23205990700..e61efe16e79cf53f301fd827065f1629508597cb 100644 (file)
@@ -54,7 +54,8 @@
        compatible = "samtec,vining", "altr,socfpga-cyclone5", "altr,socfpga";
 
        chosen {
-               bootargs = "console=ttyS0,115200";
+               bootargs = "earlyprintk";
+               stdout-path = "serial0:115200n8";
        };
 
        memory@0 {
index 2310a4e97768c222ca19fe8f125c5aede36be8d1..e6ed7c0354a233cdba3f8449582a3e1fe647cadd 100644 (file)
 #include <dt-bindings/arm/ux500_pm_domains.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/ste-ab8500.h>
-#include "skeleton.dtsi"
 
 / {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       chosen {
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "apb_pclk", "atclk";
                        cpu = <&CPU0>;
-                       port {
-                               ptm0_out_port: endpoint {
-                                       remote-endpoint = <&funnel_in_port0>;
+                       out-ports {
+                               port {
+                                       ptm0_out_port: endpoint {
+                                               remote-endpoint = <&funnel_in_port0>;
+                                       };
                                };
                        };
                };
                        clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "apb_pclk", "atclk";
                        cpu = <&CPU1>;
-                       port {
-                               ptm1_out_port: endpoint {
-                                       remote-endpoint = <&funnel_in_port1>;
+                       out-ports {
+                               port {
+                                       ptm1_out_port: endpoint {
+                                               remote-endpoint = <&funnel_in_port1>;
+                                       };
                                };
                        };
                };
 
                        clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "apb_pclk", "atclk";
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               /* funnel output ports */
-                               port@0 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        funnel_out_port: endpoint {
                                                remote-endpoint =
                                                        <&replicator_in_port0>;
                                        };
                                };
+                       };
 
-                               /* funnel input ports */
-                               port@1 {
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
                                        reg = <0>;
                                        funnel_in_port0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&ptm0_out_port>;
                                        };
                                };
 
-                               port@2 {
+                               port@1 {
                                        reg = <1>;
                                        funnel_in_port1: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&ptm1_out_port>;
                                        };
                                };
                        clocks = <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "atclk";
 
-                       ports {
+                       out-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
-                               /* replicator output ports */
                                port@0 {
                                        reg = <0>;
                                        replicator_out_port0: endpoint {
                                                remote-endpoint = <&etb_in_port>;
                                        };
                                };
+                       };
 
-                               /* replicator input port */
-                               port@2 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        replicator_in_port0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&funnel_out_port>;
                                        };
                                };
 
                        clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "apb_pclk", "atclk";
-                       port {
-                               tpiu_in_port: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out_port0>;
+                       in-ports {
+                               port {
+                                       tpiu_in_port: endpoint {
+                                               remote-endpoint = <&replicator_out_port0>;
+                                       };
                                };
                        };
                };
 
                        clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "apb_pclk", "atclk";
-                       port {
-                               etb_in_port: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out_port1>;
+                       in-ports {
+                               port {
+                                       etb_in_port: endpoint {
+                                               remote-endpoint = <&replicator_out_port1>;
+                                       };
                                };
                        };
                };
                              <0xa0410100 0x100>;
                };
 
-               scu@a04100000 {
+               scu@a0410000 {
                        compatible = "arm,cortex-a9-scu";
                        reg = <0xa0410000 0x100>;
                };
                };
 
                prcmu: prcmu@80157000 {
-                       compatible = "stericsson,db8500-prcmu";
+                       compatible = "stericsson,db8500-prcmu", "syscon";
                        reg = <0x80157000 0x2000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>;
                        reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
                        interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
                        power-domains = <&pm_domains DOMAIN_VAPE>;
                };
 
-               ssp@80002000 {
+               spi@80002000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80002000 0x1000>;
                        interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                        power-domains = <&pm_domains DOMAIN_VAPE>;
                };
 
-               ssp@80003000 {
+               spi@80003000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80003000 0x1000>;
                        interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
index 5c5cea232743d111f154cd0faa0517b44f6a70ab..1ec193b0c5065b794838705702a99bd48c95586c 100644 (file)
 
                        mcde {
                                lcd_default_mode: lcd_default {
-                                       default_mux {
+                                       default_mux1 {
                                                /* Mux in VSI0 and all the data lines */
                                                function = "lcd";
                                                groups =
                                                "lcdvsi0_a_1", /* VSI0 for LCD */
                                                "lcd_d0_d7_a_1", /* Data lines */
                                                "lcd_d8_d11_a_1", /* TV-out */
-                                               "lcdaclk_b_1", /* Clock line for TV-out */
                                                "lcdvsi1_a_1"; /* VSI1 for HDMI */
                                        };
+                                       default_mux2 {
+                                               function = "lcda";
+                                               groups =
+                                               "lcdaclk_b_1"; /* Clock line for TV-out */
+                                       };
                                        default_cfg1 {
                                                pins =
                                                "GPIO68_E1", /* VSI0 */
index 9e359e4f342e76ebd1fbfab57d1f8f427ece2cd7..feb682a3d3635d907a1abd2f538de42648dc2c1a 100644 (file)
@@ -15,6 +15,7 @@
 
 / {
        memory {
+               device_type = "memory";
                reg = <0x00000000 0x20000000>;
        };
 
index 3f14b4df69b4e4d1ab27bd821eaeeb8d819ef40f..94eeb7f1c947863956561ce5e507bcbc75574bbb 100644 (file)
@@ -57,7 +57,7 @@
                        };
                };
 
-               ssp@80002000 {
+               spi@80002000 {
                        /*
                         * On the first generation boards, this SSP/SPI port was connected
                         * to the AB8500.
index b0b94d05309855f4816a05295cbeb19251bc89e5..2de3ce79e496befac0bb88fa097ad7bf010515b9 100644 (file)
@@ -26,6 +26,7 @@
        };
 
        memory {
+               device_type = "memory";
                reg = <0x00000000 0x20000000>;
        };
 
                        pinctrl-1 = <&i2c3_sleep_mode>;
                };
 
-               ssp@80002000 {
+               spi@80002000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&ssp0_snowball_mode>;
                };
index 62ecb6a2fa39e14aa99daf35782d7b2071852e93..1bd1aba3322f111c67cf672019bb3aac9599d6cd 100644 (file)
                        dma-names = "rx";
                };
 
-               spi: ssp@c0006000 {
+               spi: spi@c0006000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0xc0006000 0x1000>;
                        interrupt-parent = <&vica>;
index 155caa8c002ad95702494ecd686bf9b0be36079f..4ee6d51d8d1ecbe2b4173e66cca524e19860a364 100644 (file)
                compatible = "simple-audio-card";
                simple-audio-card,name = "STI-B2260";
                status = "okay";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               simple-audio-card,dai-link0 {
+               simple-audio-card,dai-link@0 {
+                       reg = <0>;
                        /* DAC */
                        format = "i2s";
                        mclk-fs = <128>;
index 4dedfcb0fcb304c4968b82f815df31892e63f23a..97e05f55fb6e107f4dcca4c561daf7d5c4acb134 100644 (file)
                compatible = "simple-audio-card";
                simple-audio-card,name = "STI-B2120";
                status = "okay";
+               #address-cells = <1>;
+               #size-cells = <0>;
 
-               simple-audio-card,dai-link0 {
+               simple-audio-card,dai-link@0 {
+                       reg = <0>;
                        /* HDMI */
                        format = "i2s";
                        mclk-fs = <128>;
@@ -41,7 +44,8 @@
                        };
                };
 
-               simple-audio-card,dai-link1 {
+               simple-audio-card,dai-link@1 {
+                       reg = <1>;
                        /* DAC */
                        format = "i2s";
                        mclk-fs = <256>;
@@ -55,7 +59,8 @@
                        };
                };
 
-               simple-audio-card,dai-link2 {
+               simple-audio-card,dai-link@2 {
+                       reg = <2>;
                        /* SPDIF */
                        format = "left_j";
                        mclk-fs = <128>;
index 7eb786a2d624763627e40e87673f7f0e5c79790d..ed7d7f46465e49881043b5aeddb47b5138cad72e 100644 (file)
 &sdio {
        status = "okay";
        vmmc-supply = <&mmc_vcard>;
-       cd-gpios = <&stmpegpio 15 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&stmpegpio 15 GPIO_ACTIVE_LOW>;
        pinctrl-names = "default", "opendrain";
        pinctrl-0 = <&sdio_pins>;
        pinctrl-1 = <&sdio_pins_od>;
index e35d782e7e5f2f0281d1c8936bb90ea70b8d83b8..8d6f028ae285ca11beece355c3df4be2fe0f4dbe 100644 (file)
@@ -58,7 +58,7 @@
                        clock-frequency = <0>;
                };
 
-               clk-lse {
+               clk_lse: clk-lse {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
index 3ee768cb86fc96acf9f1e6a214e1348ead71395c..7937b43d77886bf200d4855b071123719cfd9ce2 100644 (file)
 &sdio {
        status = "okay";
        vmmc-supply = <&mmc_vcard>;
-       cd-gpios = <&gpiog 2 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpiog 2 GPIO_ACTIVE_LOW>;
        broken-cd;
        pinctrl-names = "default", "opendrain";
        pinctrl-0 = <&sdio_pins>;
index f9ad71f7c807ce365cc5501e4fdafd4f8476a30f..e3a7bd338d61f0a8cc36dc4a1009e8660407d5e1 100644 (file)
 &sdio1 {
        status = "okay";
        vmmc-supply = <&mmc_vcard>;
-       cd-gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
        pinctrl-names = "default", "opendrain";
        pinctrl-0 = <&sdio_pins_a>;
        pinctrl-1 = <&sdio_pins_od_a>;
index 677276ba4dbe8f5c07f67ed493c839ed4f94f96b..483d896e2bc13376b0a261474ccdb6a56dcbf32d 100644 (file)
 &sdio2 {
        status = "okay";
        vmmc-supply = <&mmc_vcard>;
-       cd-gpios = <&gpioi 15 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpioi 15 GPIO_ACTIVE_LOW>;
        broken-cd;
        pinctrl-names = "default", "opendrain";
        pinctrl-0 = <&sdio_pins_b>;
index 637beffe506700eb869f03e0089bfe63b3776fe9..cbdd69ca9e7a6e5c6215c646d6fa395ac6034dae 100644 (file)
                        interrupt-parent = <&exti>;
                        interrupts = <17 IRQ_TYPE_EDGE_RISING>;
                        interrupt-names = "alarm";
-                       st,syscfg = <&pwrcfg>;
+                       st,syscfg = <&pwrcfg 0x00 0x100>;
                        status = "disabled";
                };
 
index 372bc2ea6b92192422368bf8413fe62849321d08..063ee8ac5dcbd12d763a9d32a62f3185d819ae50 100644 (file)
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "stm32mp157c-ed1.dts"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
                serial0 = &uart4;
                ethernet0 = &ethernet0;
        };
+
+       panel_backlight: panel-backlight {
+               compatible = "gpio-backlight";
+               gpios = <&gpiod 13 GPIO_ACTIVE_LOW>;
+               default-on;
+               status = "okay";
+       };
+};
+
+&cec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cec_pins_a>;
+       status = "okay";
+};
+
+&dsi {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+                       dsi_in: endpoint {
+                               remote-endpoint = <&ltdc_ep0_out>;
+                       };
+               };
+
+               port@1 {
+                       reg = <1>;
+                       dsi_out: endpoint {
+                               remote-endpoint = <&dsi_panel_in>;
+                       };
+               };
+       };
+
+       panel-dsi@0 {
+               compatible = "raydium,rm68200";
+               reg = <0>;
+               reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>;
+               backlight = <&panel_backlight>;
+               status = "okay";
+
+               port {
+                       dsi_panel_in: endpoint {
+                               remote-endpoint = <&dsi_out>;
+                       };
+               };
+       };
 };
 
 &ethernet0 {
        };
 };
 
-&cec {
-       pinctrl-names = "default";
-       pinctrl-0 = <&cec_pins_a>;
-       status = "okay";
-};
-
 &i2c2 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins_a>;
        status = "okay";
 };
 
+&ltdc {
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ltdc_ep0_out: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&dsi_in>;
+               };
+       };
+};
+
 &m_can1 {
        pinctrl-names = "default";
        pinctrl-0 = <&m_can1_pins_a>;
index 185541a5b69fb58127136284f86341845b963af3..c50c36baba758f4364aac78e7f973c2c0b1a65b0 100644 (file)
                        dma-requests = <48>;
                };
 
-               qspi: qspi@58003000 {
+               qspi: spi@58003000 {
                        compatible = "st,stm32f469-qspi";
                        reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
                        reg-names = "qspi", "qspi_mm";
index 8acbaab14fe5179a5649d9b39cb35ae1ea143f3c..d2a2eb8b3f2624a4ac974db1a19c7c120dc1f4be 100644 (file)
@@ -92,7 +92,8 @@
         */
        clock-frequency = <400000>;
 
-       touchscreen: touchscreen {
+       touchscreen: touchscreen@40 {
+               reg = <0x40>;
                interrupt-parent = <&pio>;
                interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>; /* EINT11 (PG11) */
                pinctrl-names = "default";
index 8bfb36651177d715cd213e16fd2bb0dd2686d7f0..9cd65c46720ba43513fd34f014391cc9cc54a602 100644 (file)
                };
        };
 
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* Address must be kept in the lower 256 MiBs of DRAM for VE. */
+               cma_pool: cma@4a000000 {
+                       compatible = "shared-dma-pool";
+                       size = <0x6000000>;
+                       alloc-ranges = <0x4a000000 0x6000000>;
+                       reusable;
+                       linux,cma-default;
+               };
+       };
+
        soc@1c00000 {
                compatible = "simple-bus";
                #address-cells = <1>;
                        };
                };
 
+               video-codec@1c0e000 {
+                       compatible = "allwinner,sun5i-a13-video-engine";
+                       reg = <0x01c0e000 0x1000>;
+                       clocks = <&ccu CLK_AHB_VE>, <&ccu CLK_VE>,
+                                <&ccu CLK_DRAM_VE>;
+                       clock-names = "ahb", "mod", "ram";
+                       resets = <&ccu RST_VE>;
+                       interrupts = <53>;
+                       allwinner,sram = <&ve_sram 1>;
+               };
+
                mmc0: mmc@1c0f000 {
                        compatible = "allwinner,sun5i-a13-mmc";
                        reg = <0x01c0f000 0x1000>;
index 9c52712af24111daeb7e94a8be2ebabcc94c55c9..02e40da9f02801c60ac5097f8821ed3d80677bda 100644 (file)
                reg = <0x40000000 0x80000000>;
        };
 
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* Address must be kept in the lower 256 MiBs of DRAM for VE. */
+               cma_pool: cma@4a000000 {
+                       compatible = "shared-dma-pool";
+                       size = <0x6000000>;
+                       alloc-ranges = <0x4a000000 0x6000000>;
+                       reusable;
+                       linux,cma-default;
+               };
+       };
+
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
                        };
                };
 
+               video-codec@1c0e000 {
+                       compatible = "allwinner,sun7i-a20-video-engine";
+                       reg = <0x01c0e000 0x1000>;
+                       clocks = <&ccu CLK_AHB_VE>, <&ccu CLK_VE>,
+                                <&ccu CLK_DRAM_VE>;
+                       clock-names = "ahb", "mod", "ram";
+                       resets = <&ccu RST_VE>;
+                       interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+                       allwinner,sram = <&ve_sram 1>;
+               };
+
                mmc0: mmc@1c0f000 {
                        compatible = "allwinner,sun7i-a20-mmc";
                        reg = <0x01c0f000 0x1000>;
index 4e92741b24a70e222992f977e94d4f09d4486f41..c1cc8f09dd9abe054ae2e80cf38274ae4fbf25e1 100644 (file)
                reg = <0x40000000 0x80000000>;
        };
 
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /* Address must be kept in the lower 256 MiBs of DRAM for VE. */
+               cma_pool: cma@4a000000 {
+                       compatible = "shared-dma-pool";
+                       size = <0x6000000>;
+                       alloc-ranges = <0x4a000000 0x6000000>;
+                       reusable;
+                       linux,cma-default;
+               };
+       };
+
        sound: sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "sun8i-a33-audio";
                        };
                };
 
+               video-codec@01c0e000 {
+                       compatible = "allwinner,sun8i-a33-video-engine";
+                       reg = <0x01c0e000 0x1000>;
+                       clocks = <&ccu CLK_BUS_VE>, <&ccu CLK_VE>,
+                                <&ccu CLK_DRAM_VE>;
+                       clock-names = "ahb", "mod", "ram";
+                       resets = <&ccu RST_BUS_VE>;
+                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+                       allwinner,sram = <&ve_sram 1>;
+               };
+
                crypto: crypto-engine@1c15000 {
                        compatible = "allwinner,sun4i-a10-crypto";
                        reg = <0x01c15000 0x1000>;
index c7ce4158d6c8bccc3eb1b5322d8fe18a2d3aa34c..742d2946b08be48d205bee2ae6041632b27dccf1 100644 (file)
        status = "okay";
 };
 
+&r_cir {
+       clock-frequency = <3000000>;
+       status = "okay";
+};
+
 &r_rsb {
        status = "okay";
 
index 00a02b037320c75ffe313e1c847f7a19b9d3bd93..5617dd387fd35b4c7359a001834745918ed891c8 100644 (file)
                        reg = <0x1f01c00 0x400>;
                };
 
+               r_cir: ir@1f02000 {
+                       compatible = "allwinner,sun8i-a83t-ir",
+                               "allwinner,sun5i-a13-ir";
+                       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>;
+                       reg = <0x01f02000 0x400>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&r_cir_pin>;
+                       status = "disabled";
+               };
+
                r_pio: pinctrl@1f02c00 {
                        compatible = "allwinner,sun8i-a83t-r-pinctrl";
                        reg = <0x01f02c00 0x400>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 
+                       r_cir_pin: r-cir-pin {
+                               pins = "PL12";
+                               function = "s_cir_rx";
+                       };
+
                        r_rsb_pins: r-rsb-pins {
                                pins = "PL0", "PL1";
                                function = "s_rsb";
diff --git a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus-v1.2.dts b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus-v1.2.dts
new file mode 100644 (file)
index 0000000..fc4a8c3
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Chen-Yu Tsai <wens@csie.org>
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-bananapi-m2-plus-v1.2.dtsi"
+
+/ {
+       model = "Banana Pi BPI-M2-Plus v1.2 H3";
+       compatible = "bananapi,bpi-m2-plus-v1.2", "allwinner,sun8i-h3";
+};
index 30540dc8e0c5fd5c5657ca7ad725769e316bd185..195a75da13f1b87f1c571227781f40a27f4ee488 100644 (file)
 
 /dts-v1/;
 #include "sun8i-h3.dtsi"
-#include "sunxi-common-regulators.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "sunxi-bananapi-m2-plus.dtsi"
 
 / {
-       model = "Banana Pi BPI-M2-Plus";
+       model = "Banana Pi BPI-M2-Plus H3";
        compatible = "sinovoip,bpi-m2-plus", "allwinner,sun8i-h3";
-
-       aliases {
-               ethernet0 = &emac;
-               serial0 = &uart0;
-               serial1 = &uart1;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       connector {
-               compatible = "hdmi-connector";
-               type = "a";
-
-               port {
-                       hdmi_con_in: endpoint {
-                               remote-endpoint = <&hdmi_out_con>;
-                       };
-               };
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               pinctrl-names = "default";
-
-               pwr_led {
-                       label = "bananapi-m2-plus:red:pwr";
-                       gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
-                       default-state = "on";
-               };
-       };
-
-       gpio_keys {
-               compatible = "gpio-keys";
-               pinctrl-names = "default";
-
-               sw4 {
-                       label = "power";
-                       linux,code = <BTN_0>;
-                       gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
-               };
-       };
-
-       reg_gmac_3v3: gmac-3v3 {
-                     compatible = "regulator-fixed";
-                     regulator-name = "gmac-3v3";
-                     regulator-min-microvolt = <3300000>;
-                     regulator-max-microvolt = <3300000>;
-                     startup-delay-us = <100000>;
-                     enable-active-high;
-                     gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
-       };
-
-       wifi_pwrseq: wifi_pwrseq {
-               compatible = "mmc-pwrseq-simple";
-               pinctrl-names = "default";
-               reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
-       };
-};
-
-&de {
-       status = "okay";
-};
-
-&ehci0 {
-       status = "okay";
-};
-
-&ehci1 {
-       status = "okay";
-};
-
-&ehci2 {
-       status = "okay";
-};
-
-&emac {
-       pinctrl-names = "default";
-       pinctrl-0 = <&emac_rgmii_pins>;
-       phy-supply = <&reg_gmac_3v3>;
-       phy-handle = <&ext_rgmii_phy>;
-       phy-mode = "rgmii";
-
-       status = "okay";
-};
-
-&external_mdio {
-       ext_rgmii_phy: ethernet-phy@1 {
-               compatible = "ethernet-phy-ieee802.3-c22";
-               reg = <0>;
-       };
-};
-
-&hdmi {
-       status = "okay";
-};
-
-&hdmi_out {
-       hdmi_out_con: endpoint {
-               remote-endpoint = <&hdmi_con_in>;
-       };
-};
-
-&ir {
-       pinctrl-names = "default";
-       pinctrl-0 = <&ir_pins_a>;
-       status = "okay";
-};
-
-&mmc0 {
-       vmmc-supply = <&reg_vcc3v3>;
-       bus-width = <4>;
-       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
-       status = "okay";
-};
-
-&mmc1 {
-       vmmc-supply = <&reg_vcc3v3>;
-       vqmmc-supply = <&reg_vcc3v3>;
-       mmc-pwrseq = <&wifi_pwrseq>;
-       bus-width = <4>;
-       non-removable;
-       status = "okay";
-
-       brcmf: wifi@1 {
-               reg = <1>;
-               compatible = "brcm,bcm4329-fmac";
-               interrupt-parent = <&pio>;
-               interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */
-               interrupt-names = "host-wake";
-       };
-};
-
-&mmc2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&mmc2_8bit_pins>;
-       vmmc-supply = <&reg_vcc3v3>;
-       vqmmc-supply = <&reg_vcc3v3>;
-       bus-width = <8>;
-       non-removable;
-       status = "okay";
-};
-
-&ohci0 {
-       status = "okay";
-};
-
-&ohci1 {
-       status = "okay";
-};
-
-&ohci2 {
-       status = "okay";
-};
-
-&reg_usb0_vbus {
-       gpio = <&pio 3 11 GPIO_ACTIVE_HIGH>; /* PD11 */
-       status = "okay";
-};
-
-&uart0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
-       status = "okay";
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
-       status = "okay";
-};
-
-&usb_otg {
-       dr_mode = "otg";
-       status = "okay";
-};
-
-&usbphy {
-       usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
-       usb0_vbus-supply = <&reg_usb0_vbus>;
-       /* USB host VBUS is on as long as VCC-IO is on */
-       status = "okay";
 };
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts
new file mode 100644 (file)
index 0000000..c834048
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
+ * Copyright (C) 2018 Diego Rondini <diego.rondini@kynetics.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "sun8i-h3.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "OrangePi Zero Plus2 H3";
+       compatible = "xunlong,orangepi-zero-plus2-h3", "allwinner,sun8i-h3";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       connector {
+               compatible = "hdmi-connector";
+               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>;
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               pinctrl-names = "default";
+               reset-gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
+               post-power-on-delay-ms = <200>;
+       };
+};
+
+&de {
+       status = "okay";
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&mmc0 {
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&mmc1 {
+       vmmc-supply = <&reg_vcc3v3>;
+       vqmmc-supply = <&reg_vcc3v3>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&r_pio>;
+               interrupts = <0 7 IRQ_TYPE_LEVEL_LOW>;  /* PL7 */
+               interrupt-names = "host-wake";
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_8bit_pins>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-hw-reset;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
index f0096074a46786cf36c6a824aa6a7ce8bba824ac..3ecfabb101519c9da0b6de70749f7d4292df1479 100644 (file)
                             <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               cma_pool: cma@4a000000 {
+                       compatible = "shared-dma-pool";
+                       size = <0x6000000>;
+                       alloc-ranges = <0x4a000000 0x6000000>;
+                       reusable;
+                       linux,cma-default;
+               };
+       };
+
        soc {
                system-control@1c00000 {
                        compatible = "allwinner,sun8i-h3-system-control";
                        };
                };
 
+               video-codec@01c0e000 {
+                       compatible = "allwinner,sun8i-h3-video-engine";
+                       reg = <0x01c0e000 0x1000>;
+                       clocks = <&ccu CLK_BUS_VE>, <&ccu CLK_VE>,
+                                <&ccu CLK_DRAM_VE>;
+                       clock-names = "ahb", "mod", "ram";
+                       resets = <&ccu RST_BUS_VE>;
+                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+                       allwinner,sram = <&ve_sram 1>;
+               };
+
                mali: gpu@1c40000 {
                        compatible = "allwinner,sun8i-h3-mali", "arm,mali-400";
                        reg = <0x01c40000 0x10000>;
index c39b9169ea64144e4ecc7aece7b06c9def1c52fe..438b7b44dab3ccedc9efd851a9888aaac958d4da 100644 (file)
        };
 };
 
+&ahci {
+       ahci-supply = <&reg_dldo4>;
+       phy-supply = <&reg_eldo3>;
+       status = "okay";
+};
+
 &de {
        status = "okay";
 };
 &mmc0 {
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
-       cd-gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; /* PH13 */
-       cd-inverted;
+       cd-gpios = <&pio 7 13 GPIO_ACTIVE_LOW>; /* PH13 */
        status = "okay";
 };
 
        regulator-name = "vcc-wifi";
 };
 
+&reg_dldo4 {
+       regulator-min-microvolt = <2500000>;
+       regulator-max-microvolt = <2500000>;
+       regulator-name = "vdd2v5-sata";
+};
+
+&reg_eldo3 {
+       regulator-min-microvolt = <1200000>;
+       regulator-max-microvolt = <1200000>;
+       regulator-name = "vdd1v2-sata";
+};
+
 &tcon_tv0 {
        status = "okay";
 };
index 5f547c161bafd23a3054b6c084599955d753314b..6f4c9ca5a3ee6bf49ec5f73e4ff594d496e1efe6 100644 (file)
                        #size-cells = <0>;
                };
 
+               ahci: sata@1c18000 {
+                       compatible = "allwinner,sun8i-r40-ahci";
+                       reg = <0x01c18000 0x1000>;
+                       interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_SATA>, <&ccu CLK_SATA>;
+                       resets = <&ccu RST_BUS_SATA>;
+                       resets-name = "ahci";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+               };
+
                gmac: ethernet@1c50000 {
                        compatible = "allwinner,sun8i-r40-gmac";
                        syscon = <&ccu>;
index 880096c7e2523aee4174a9ce7fce4d853cf8e882..5e8a95af89b8c3539ff39f902059bdd256a0df43 100644 (file)
@@ -69,7 +69,8 @@
         */
        clock-frequency = <400000>;
 
-       touchscreen: touchscreen@0 {
+       touchscreen: touchscreen@40 {
+               reg = <0x40>;
                interrupt-parent = <&pio>;
                interrupts = <1 5 IRQ_TYPE_EDGE_FALLING>; /* PB5 */
                pinctrl-names = "default";
index 35859d8f3267fd2a1d6fa7e716e97094895f3530..bf97f6244c233f802393133d50456735d18766e7 100644 (file)
@@ -95,7 +95,7 @@
 &i2c0 {
        status = "okay";
 
-       axp22x: pmic@68 {
+       axp22x: pmic@34 {
                compatible = "x-powers,axp221";
                reg = <0x34>;
                interrupt-parent = <&nmi_intc>;
index 25591d6883ef2feb1fa89e28360bdeb14a048d13..d9532fb1ef65071936c047a25274b2b299c30dce 100644 (file)
                        };
                };
 
-               r_rsb: i2c@8003400 {
+               r_rsb: rsb@8003400 {
                        compatible = "allwinner,sun8i-a23-rsb";
                        reg = <0x08003400 0x400>;
                        interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi
new file mode 100644 (file)
index 0000000..53edd1f
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Chen-Yu Tsai <wens@csie.org>
+ */
+
+#include "sunxi-bananapi-m2-plus.dtsi"
+
+/ {
+       /*
+        * Bananapi M2+ v1.2 uses a GPIO line to change the effective
+        * resistance on the CPU regulator's feedback pin.
+        */
+       reg_vdd_cpux: vdd-cpux {
+               compatible = "regulator-gpio";
+               regulator-name = "vdd-cpux";
+               regulator-type = "voltage";
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1300000>;
+               regulator-ramp-delay = <50>; /* 4ms */
+               gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */
+               gpios-states = <0x1>;
+               states = <1100000 0x0
+                         1300000 0x1>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
diff --git a/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi b/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi
new file mode 100644 (file)
index 0000000..b3283ae
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       aliases {
+               ethernet0 = &emac;
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+
+               pwr_led {
+                       label = "bananapi-m2-plus:red:pwr";
+                       gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+                       default-state = "on";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+
+               sw4 {
+                       label = "power";
+                       linux,code = <BTN_0>;
+                       gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       reg_gmac_3v3: gmac-3v3 {
+                     compatible = "regulator-fixed";
+                     regulator-name = "gmac-3v3";
+                     regulator-min-microvolt = <3300000>;
+                     regulator-max-microvolt = <3300000>;
+                     startup-delay-us = <100000>;
+                     enable-active-high;
+                     gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               pinctrl-names = "default";
+               reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+       };
+};
+
+&de {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ehci2 {
+       status = "okay";
+};
+
+&emac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&emac_rgmii_pins>;
+       phy-supply = <&reg_gmac_3v3>;
+       phy-handle = <&ext_rgmii_phy>;
+       phy-mode = "rgmii";
+
+       status = "okay";
+};
+
+&external_mdio {
+       ext_rgmii_phy: ethernet-phy@1 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <1>;
+       };
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&ir {
+       pinctrl-names = "default";
+       pinctrl-0 = <&ir_pins_a>;
+       status = "okay";
+};
+
+&mmc0 {
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+       status = "okay";
+};
+
+&mmc1 {
+       vmmc-supply = <&reg_vcc3v3>;
+       vqmmc-supply = <&reg_vcc3v3>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&pio>;
+               interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */
+               interrupt-names = "host-wake";
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_8bit_pins>;
+       vmmc-supply = <&reg_vcc3v3>;
+       vqmmc-supply = <&reg_vcc3v3>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&ohci2 {
+       status = "okay";
+};
+
+&reg_usb0_vbus {
+       gpio = <&pio 3 11 GPIO_ACTIVE_HIGH>; /* PD11 */
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+       usb0_vbus-supply = <&reg_usb0_vbus>;
+       /* USB host VBUS is on as long as VCC-IO is on */
+       status = "okay";
+};
index fc6131315c47ffe695a4db6cbf0f7e38a8b89221..4b1530ebe4272887f33c85e00669e4781618848e 100644 (file)
                        clock-names = "apb", "ir";
                        resets = <&r_ccu RST_APB0_IR>;
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-                       reg = <0x01f02000 0x40>;
+                       reg = <0x01f02000 0x400>;
                        status = "disabled";
                };
 
index a6ad759dddb479417c517a69ea93c637317f9972..eaee10ef6512ec0b35b6a4163eebd83bd03c230f 100644 (file)
@@ -72,6 +72,7 @@
        host1x@50000000 {
                hdmi@54280000 {
                        status = "okay";
+                       hdmi-supply = <&reg_5v0>;
                };
        };
 
        /*
         * GEN2_I2C: I2C2_SDA/SCL (DDC) on MXM3 pin 205/207 (e.g. display EDID)
         */
-       hdmi_ddc: i2c@7000c400 {
+       i2c@7000c400 {
                status = "okay";
        };
 
        spi@7000d400 {
                status = "okay";
                spi-max-frequency = <50000000>;
-
-               spidev0: spidev@0 {
-                       compatible = "spidev";
-                       reg = <0>;
-                       spi-max-frequency = <50000000>;
-               };
        };
 
        /* SPI4: Apalis SPI2 */
        spi@7000da00 {
                status = "okay";
                spi-max-frequency = <50000000>;
-
-               spidev1: spidev@0 {
-                       compatible = "spidev";
-                       reg = <0>;
-                       spi-max-frequency = <50000000>;
-               };
        };
 
        /* Apalis Serial ATA */
        sata@70020000 {
                status = "okay";
+               target-5v-supply = <&reg_5v0>;
+               target-12v-supply = <&reg_12v0>;
        };
 
        hda@70030000 {
        /* Apalis MMC1 */
        sdhci@700b0000 {
                status = "okay";
+               bus-width = <4>;
                /* MMC1_CD# */
                cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>;
-               bus-width = <4>;
                vqmmc-supply = <&vddio_sdmmc1>;
        };
 
        /* Apalis SD1 */
        sdhci@700b0400 {
                status = "okay";
+               bus-width = <4>;
                /* SD1_CD# */
                cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
-               bus-width = <4>;
                vqmmc-supply = <&vddio_sdmmc3>;
        };
 
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm 3 5000000>; /* BKL1_PWM */
                brightness-levels = <255 231 223 207 191 159 127 0>;
                default-brightness-level = <6>;
                /* BKL1_ON */
                enable-gpios = <&gpio TEGRA_GPIO(BB, 5) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 3 5000000>; /* BKL1_PWM */
        };
 
        gpio-keys {
                };
        };
 
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
        reg_5v0: regulator-5v0 {
                compatible = "regulator-fixed";
                regulator-name = "5V_SW";
                regulator-max-microvolt = <5000000>;
        };
 
+       reg_12v0: regulator-12v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "12V_SW";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
        /* USBO1_EN */
        reg_usbo1_vbus: regulator-usbo1-vbus {
                compatible = "regulator-fixed";
 
 &gpio {
        /* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
-       pex_perst_n {
+       pex-perst-n {
                gpio-hog;
                gpios = <TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
                output-high;
index 8a8d5fa0ecd1e6c88989d507b6a317a1ea36fd9b..7961eb4bd8038490f5a9cd3530c93f6edc5f94fc 100644 (file)
@@ -11,7 +11,8 @@
 / {
        model = "Toradex Apalis TK1 on Apalis Evaluation Board";
        compatible = "toradex,apalis-tk1-v1.2-eval", "toradex,apalis-tk1-eval",
-                    "toradex,apalis-tk1", "nvidia,tegra124";
+                    "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1",
+                    "nvidia,tegra124";
 
        aliases {
                rtc0 = "/i2c@7000c000/rtc@68";
@@ -36,6 +37,7 @@
        host1x@50000000 {
                hdmi@54280000 {
                        status = "okay";
+                       hdmi-supply = <&reg_5v0>;
                };
        };
 
         * I2C4 (DDC): I2C4_SDA/SCL (DDC) on MXM3 pin 205/207
         * (e.g. display EDID)
         */
-       hdmi_ddc: i2c@7000c700 {
+       i2c@7000c700 {
                status = "okay";
        };
 
        spi@7000d400 {
                status = "okay";
                spi-max-frequency = <50000000>;
-
-               spidev0: spidev@0 {
-                       compatible = "spidev";
-                       reg = <0>;
-                       spi-max-frequency = <50000000>;
-               };
        };
 
        /* SPI4: Apalis SPI2 */
        spi@7000da00 {
                status = "okay";
                spi-max-frequency = <50000000>;
-
-               spidev1: spidev@0 {
-                       compatible = "spidev";
-                       reg = <0>;
-                       spi-max-frequency = <50000000>;
-               };
        };
 
        /* Apalis Serial ATA */
        sata@70020000 {
                status = "okay";
+               target-5v-supply = <&reg_5v0>;
+               target-12v-supply = <&reg_12v0>;
        };
 
        hda@70030000 {
        /* Apalis MMC1 */
        sdhci@700b0000 {
                status = "okay";
+               bus-width = <4>;
                /* MMC1_CD# */
                cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>;
-               bus-width = <4>;
                vqmmc-supply = <&vddio_sdmmc1>;
        };
 
        /* Apalis SD1 */
        sdhci@700b0400 {
                status = "okay";
+               bus-width = <4>;
                /* SD1_CD# */
                cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
-               bus-width = <4>;
                vqmmc-supply = <&vddio_sdmmc3>;
        };
 
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm 3 5000000>; /* BKL1_PWM */
                brightness-levels = <255 231 223 207 191 159 127 0>;
                default-brightness-level = <6>;
                /* BKL1_ON */
                enable-gpios = <&gpio TEGRA_GPIO(BB, 5) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 3 5000000>; /* BKL1_PWM */
        };
 
        gpio-keys {
                };
        };
 
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
        reg_5v0: regulator-5v0 {
                compatible = "regulator-fixed";
                regulator-name = "5V_SW";
                regulator-max-microvolt = <5000000>;
        };
 
+       reg_12v0: regulator-12v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "12V_SW";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
        /* USBO1_EN */
        reg_usbo1_vbus: regulator-usbo1-vbus {
                compatible = "regulator-fixed";
 
 &gpio {
        /* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
-       pex_perst_n {
+       pex-perst-n {
                gpio-hog;
                gpios = <TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
                output-high;
index 573aaa50fff1c47f0eae1492bc8ed575a3510f0f..367eb8c86098ebc1ff56ebf3ea53656770f2636a 100644 (file)
  * Compatible for Revisions 2GB: V1.2A
  */
 / {
-       model = "Toradex Apalis TK1";
-       compatible = "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1",
-                    "nvidia,tegra124";
-
        memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
        pcie@1003000 {
                status = "okay";
-               avddio-pex-supply = <&vdd_1v05>;
-               avdd-pex-pll-supply = <&vdd_1v05>;
-               avdd-pll-erefe-supply = <&avdd_1v05>;
-               dvddio-pex-supply = <&vdd_1v05>;
-               hvdd-pex-pll-e-supply = <&reg_3v3>;
-               hvdd-pex-supply = <&reg_3v3>;
-               vddio-pex-ctl-supply = <&reg_3v3>;
+               avddio-pex-supply = <&reg_1v05_vdd>;
+               avdd-pex-pll-supply = <&reg_1v05_vdd>;
+               avdd-pll-erefe-supply = <&reg_1v05_avdd>;
+               dvddio-pex-supply = <&reg_1v05_vdd>;
+               hvdd-pex-pll-e-supply = <&reg_module_3v3>;
+               hvdd-pex-supply = <&reg_module_3v3>;
+               vddio-pex-ctl-supply = <&reg_module_3v3>;
 
                /* Apalis PCIe (additional lane Apalis type specific) */
                pci@1,0 {
                        phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>;
                        phy-names = "pcie-0";
                        status = "okay";
+
+                       pcie@0 {
+                               reg = <0 0 0 0 0>;
+                               local-mac-address = [00 00 00 00 00 00];
+                       };
                };
        };
 
        host1x@50000000 {
                hdmi@54280000 {
-                       pll-supply = <&reg_1v05_avdd_hdmi_pll>;
-                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                        nvidia,ddc-i2c-bus = <&hdmi_ddc>;
                        nvidia,hpd-gpio =
                                <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+                       pll-supply = <&reg_1v05_avdd_hdmi_pll>;
+                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                };
        };
 
                 * Node left disabled on purpose - the bootloader will enable
                 * it after having set the VPR up
                 */
-               vdd-supply = <&vdd_gpu>;
+               vdd-supply = <&reg_vdd_gpu>;
        };
 
-       pinmux: pinmux@70000868 {
+       pinmux@70000868 {
                pinctrl-names = "default";
                pinctrl-0 = <&state_default>;
 
                state_default: pinmux {
                        /* Analogue Audio (On-module) */
-                       dap3_fs_pp0 {
+                       dap3-fs-pp0 {
                                nvidia,pins = "dap3_fs_pp0";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap3_din_pp1 {
+                       dap3-din-pp1 {
                                nvidia,pins = "dap3_din_pp1";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap3_dout_pp2 {
+                       dap3-dout-pp2 {
                                nvidia,pins = "dap3_dout_pp2";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap3_sclk_pp3 {
+                       dap3-sclk-pp3 {
                                nvidia,pins = "dap3_sclk_pp3";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap_mclk1_pw4 {
+                       dap-mclk1-pw4 {
                                nvidia,pins = "dap_mclk1_pw4";
                                nvidia,function = "extperiph1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis CAM1_MCLK */
-                       cam_mclk_pcc0 {
+                       cam-mclk-pcc0 {
                                nvidia,pins = "cam_mclk_pcc0";
                                nvidia,function = "vi_alt3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis Digital Audio */
-                       dap2_fs_pa2 {
+                       dap2-fs-pa2 {
                                nvidia,pins = "dap2_fs_pa2";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap2_sclk_pa3 {
+                       dap2-sclk-pa3 {
                                nvidia,pins = "dap2_sclk_pa3";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap2_din_pa4 {
+                       dap2-din-pa4 {
                                nvidia,pins = "dap2_din_pa4";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap2_dout_pa5 {
+                       dap2-dout-pa5 {
                                nvidia,pins = "dap2_dout_pa5";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       clk3_out_pee0 {
+                       clk3-out-pee0 {
                                nvidia,pins = "clk3_out_pee0";
                                nvidia,function = "extperiph3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis GPIO */
-                       usb_vbus_en0_pn4 {
+                       usb-vbus-en0-pn4 {
                                nvidia,pins = "usb_vbus_en0_pn4";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_DISABLE>;
                        };
-                       usb_vbus_en1_pn5 {
+                       usb-vbus-en1-pn5 {
                                nvidia,pins = "usb_vbus_en1_pn5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_DISABLE>;
                        };
-                       pex_l0_rst_n_pdd1 {
+                       pex-l0-rst-n-pdd1 {
                                nvidia,pins = "pex_l0_rst_n_pdd1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l0_clkreq_n_pdd2 {
+                       pex-l0-clkreq-n-pdd2 {
                                nvidia,pins = "pex_l0_clkreq_n_pdd2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l1_rst_n_pdd5 {
+                       pex-l1-rst-n-pdd5 {
                                nvidia,pins = "pex_l1_rst_n_pdd5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l1_clkreq_n_pdd6 {
+                       pex-l1-clkreq-n-pdd6 {
                                nvidia,pins = "pex_l1_clkreq_n_pdd6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dp_hpd_pff0 {
+                       dp-hpd-pff0 {
                                nvidia,pins = "dp_hpd_pff0";
                                nvidia,function = "dp";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis HDMI1_CEC */
-                       hdmi_cec_pee3 {
+                       hdmi-cec-pee3 {
                                nvidia,pins = "hdmi_cec_pee3";
                                nvidia,function = "cec";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis HDMI1_HPD */
-                       hdmi_int_pn7 {
+                       hdmi-int-pn7 {
                                nvidia,pins = "hdmi_int_pn7";
                                nvidia,function = "rsvd1";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                        };
 
                        /* Apalis I2C1 */
-                       gen1_i2c_scl_pc4 {
+                       gen1-i2c-scl-pc4 {
                                nvidia,pins = "gen1_i2c_scl_pc4";
                                nvidia,function = "i2c1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       gen1_i2c_sda_pc5 {
+                       gen1-i2c-sda-pc5 {
                                nvidia,pins = "gen1_i2c_sda_pc5";
                                nvidia,function = "i2c1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis I2C3 (CAM) */
-                       cam_i2c_scl_pbb1 {
+                       cam-i2c-scl-pbb1 {
                                nvidia,pins = "cam_i2c_scl_pbb1";
                                nvidia,function = "i2c3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       cam_i2c_sda_pbb2 {
+                       cam-i2c-sda-pbb2 {
                                nvidia,pins = "cam_i2c_sda_pbb2";
                                nvidia,function = "i2c3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis I2C4 (DDC) */
-                       ddc_scl_pv4 {
+                       ddc-scl-pv4 {
                                nvidia,pins = "ddc_scl_pv4";
                                nvidia,function = "i2c4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,rcv-sel = <TEGRA_PIN_ENABLE>;
                        };
-                       ddc_sda_pv5 {
+                       ddc-sda-pv5 {
                                nvidia,pins = "ddc_sda_pv5";
                                nvidia,function = "i2c4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis MMC1 */
-                       sdmmc1_cd_n_pv3 { /* CD# GPIO */
+                       sdmmc1-cd-n-pv3 { /* CD# GPIO */
                                nvidia,pins = "sdmmc1_wp_n_pv3";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       clk2_out_pw5 { /* D5 GPIO */
+                       clk2-out-pw5 { /* D5 GPIO */
                                nvidia,pins = "clk2_out_pw5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat3_py4 {
+                       sdmmc1-dat3-py4 {
                                nvidia,pins = "sdmmc1_dat3_py4";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat2_py5 {
+                       sdmmc1-dat2-py5 {
                                nvidia,pins = "sdmmc1_dat2_py5";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat1_py6 {
+                       sdmmc1-dat1-py6 {
                                nvidia,pins = "sdmmc1_dat1_py6";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat0_py7 {
+                       sdmmc1-dat0-py7 {
                                nvidia,pins = "sdmmc1_dat0_py7";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_clk_pz0 {
+                       sdmmc1-clk-pz0 {
                                nvidia,pins = "sdmmc1_clk_pz0";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_cmd_pz1 {
+                       sdmmc1-cmd-pz1 {
                                nvidia,pins = "sdmmc1_cmd_pz1";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       clk2_req_pcc5 { /* D4 GPIO */
+                       clk2-req-pcc5 { /* D4 GPIO */
                                nvidia,pins = "clk2_req_pcc5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_clk_lb_in_pee5 { /* D6 GPIO */
+                       sdmmc3-clk-lb-in-pee5 { /* D6 GPIO */
                                nvidia,pins = "sdmmc3_clk_lb_in_pee5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       usb_vbus_en2_pff1 { /* D7 GPIO */
+                       usb-vbus-en2-pff1 { /* D7 GPIO */
                                nvidia,pins = "usb_vbus_en2_pff1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis SATA1_ACT# */
-                       dap1_dout_pn2 {
+                       dap1-dout-pn2 {
                                nvidia,pins = "dap1_dout_pn2";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis SD1 */
-                       sdmmc3_clk_pa6 {
+                       sdmmc3-clk-pa6 {
                                nvidia,pins = "sdmmc3_clk_pa6";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_cmd_pa7 {
+                       sdmmc3-cmd-pa7 {
                                nvidia,pins = "sdmmc3_cmd_pa7";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat3_pb4 {
+                       sdmmc3-dat3-pb4 {
                                nvidia,pins = "sdmmc3_dat3_pb4";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat2_pb5 {
+                       sdmmc3-dat2-pb5 {
                                nvidia,pins = "sdmmc3_dat2_pb5";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat1_pb6 {
+                       sdmmc3-dat1-pb6 {
                                nvidia,pins = "sdmmc3_dat1_pb6";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat0_pb7 {
+                       sdmmc3-dat0-pb7 {
                                nvidia,pins = "sdmmc3_dat0_pb7";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_cd_n_pv2 { /* CD# GPIO */
+                       sdmmc3-cd-n-pv2 { /* CD# GPIO */
                                nvidia,pins = "sdmmc3_cd_n_pv2";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* Apalis SPDIF */
-                       spdif_out_pk5 {
+                       spdif-out-pk5 {
                                nvidia,pins = "spdif_out_pk5";
                                nvidia,function = "spdif";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       spdif_in_pk6 {
+                       spdif-in-pk6 {
                                nvidia,pins = "spdif_in_pk6";
                                nvidia,function = "spdif";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis SPI1 */
-                       ulpi_clk_py0 {
+                       ulpi-clk-py0 {
                                nvidia,pins = "ulpi_clk_py0";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_dir_py1 {
+                       ulpi-dir-py1 {
                                nvidia,pins = "ulpi_dir_py1";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       ulpi_nxt_py2 {
+                       ulpi-nxt-py2 {
                                nvidia,pins = "ulpi_nxt_py2";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_stp_py3 {
+                       ulpi-stp-py3 {
                                nvidia,pins = "ulpi_stp_py3";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart1_txd_pu0 {
+                       uart1-txd-pu0 {
                                nvidia,pins = "pu0";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart1_rxd_pu1 {
+                       uart1-rxd-pu1 {
                                nvidia,pins = "pu1";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart1_cts_n_pu2 {
+                       uart1-cts-n-pu2 {
                                nvidia,pins = "pu2";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart1_rts_n_pu3 {
+                       uart1-rts-n-pu3 {
                                nvidia,pins = "pu3";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart3_cts_n_pa1 { /* DSR GPIO */
+                       uart3-cts-n-pa1 { /* DSR GPIO */
                                nvidia,pins = "uart3_cts_n_pa1";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart3_rts_n_pc0 { /* DTR GPIO */
+                       uart3-rts-n-pc0 { /* DTR GPIO */
                                nvidia,pins = "uart3_rts_n_pc0";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis UART2 */
-                       uart2_txd_pc2 {
+                       uart2-txd-pc2 {
                                nvidia,pins = "uart2_txd_pc2";
                                nvidia,function = "irda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart2_rxd_pc3 {
+                       uart2-rxd-pc3 {
                                nvidia,pins = "uart2_rxd_pc3";
                                nvidia,function = "irda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart2_cts_n_pj5 {
+                       uart2-cts-n-pj5 {
                                nvidia,pins = "uart2_cts_n_pj5";
                                nvidia,function = "uartb";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart2_rts_n_pj6 {
+                       uart2-rts-n-pj6 {
                                nvidia,pins = "uart2_rts_n_pj6";
                                nvidia,function = "uartb";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis UART3 */
-                       uart3_txd_pw6 {
+                       uart3-txd-pw6 {
                                nvidia,pins = "uart3_txd_pw6";
                                nvidia,function = "uartc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart3_rxd_pw7 {
+                       uart3-rxd-pw7 {
                                nvidia,pins = "uart3_rxd_pw7";
                                nvidia,function = "uartc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis UART4 */
-                       uart4_rxd_pb0 {
+                       uart4-rxd-pb0 {
                                nvidia,pins = "pb0";
                                nvidia,function = "uartd";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart4_txd_pj7 {
+                       uart4-txd-pj7 {
                                nvidia,pins = "pj7";
                                nvidia,function = "uartd";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis USBH_EN */
-                       gen2_i2c_sda_pt6 {
+                       gen2-i2c-sda-pt6 {
                                nvidia,pins = "gen2_i2c_sda_pt6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis USBO1_EN */
-                       gen2_i2c_scl_pt5 {
+                       gen2-i2c-scl-pt5 {
                                nvidia,pins = "gen2_i2c_scl_pt5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis WAKE1_MICO */
-                       pex_wake_n_pdd3 {
+                       pex-wake-n-pdd3 {
                                nvidia,pins = "pex_wake_n_pdd3";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* CORE_PWR_REQ */
-                       core_pwr_req {
+                       core-pwr-req {
                                nvidia,pins = "core_pwr_req";
                                nvidia,function = "pwron";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* CPU_PWR_REQ */
-                       cpu_pwr_req {
+                       cpu-pwr-req {
                                nvidia,pins = "cpu_pwr_req";
                                nvidia,function = "cpu";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* DVFS */
-                       dvfs_pwm_px0 {
+                       dvfs-pwm-px0 {
                                nvidia,pins = "dvfs_pwm_px0";
                                nvidia,function = "cldvfs";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dvfs_clk_px2 {
+                       dvfs-clk-px2 {
                                nvidia,pins = "dvfs_clk_px2";
                                nvidia,function = "cldvfs";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* eMMC */
-                       sdmmc4_dat0_paa0 {
+                       sdmmc4-dat0-paa0 {
                                nvidia,pins = "sdmmc4_dat0_paa0";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat1_paa1 {
+                       sdmmc4-dat1-paa1 {
                                nvidia,pins = "sdmmc4_dat1_paa1";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat2_paa2 {
+                       sdmmc4-dat2-paa2 {
                                nvidia,pins = "sdmmc4_dat2_paa2";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat3_paa3 {
+                       sdmmc4-dat3-paa3 {
                                nvidia,pins = "sdmmc4_dat3_paa3";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat4_paa4 {
+                       sdmmc4-dat4-paa4 {
                                nvidia,pins = "sdmmc4_dat4_paa4";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat5_paa5 {
+                       sdmmc4-dat5-paa5 {
                                nvidia,pins = "sdmmc4_dat5_paa5";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat6_paa6 {
+                       sdmmc4-dat6-paa6 {
                                nvidia,pins = "sdmmc4_dat6_paa6";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat7_paa7 {
+                       sdmmc4-dat7-paa7 {
                                nvidia,pins = "sdmmc4_dat7_paa7";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_clk_pcc4 {
+                       sdmmc4-clk-pcc4 {
                                nvidia,pins = "sdmmc4_clk_pcc4";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_cmd_pt7 {
+                       sdmmc4-cmd-pt7 {
                                nvidia,pins = "sdmmc4_cmd_pt7";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* JTAG_RTCK */
-                       jtag_rtck {
+                       jtag-rtck {
                                nvidia,pins = "jtag_rtck";
                                nvidia,function = "rtck";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* LAN_DEV_OFF# */
-                       ulpi_data5_po6 {
+                       ulpi-data5-po6 {
                                nvidia,pins = "ulpi_data5_po6";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* LAN_RESET# */
-                       kb_row10_ps2 {
+                       kb-row10-ps2 {
                                nvidia,pins = "kb_row10_ps2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* LAN_WAKE# */
-                       ulpi_data4_po5 {
+                       ulpi-data4-po5 {
                                nvidia,pins = "ulpi_data4_po5";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* MCU SPI */
-                       gpio_x4_aud_px4 {
+                       gpio-x4-aud-px4 {
                                nvidia,pins = "gpio_x4_aud_px4";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x5_aud_px5 {
+                       gpio-x5-aud-px5 {
                                nvidia,pins = "gpio_x5_aud_px5";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x6_aud_px6 { /* MCU_CS */
+                       gpio-x6-aud-px6 { /* MCU_CS */
                                nvidia,pins = "gpio_x6_aud_px6";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x7_aud_px7 {
+                       gpio-x7-aud-px7 {
                                nvidia,pins = "gpio_x7_aud_px7";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       gpio_w2_aud_pw2 { /* MCU_CSEZP */
+                       gpio-w2-aud-pw2 { /* MCU_CSEZP */
                                nvidia,pins = "gpio_w2_aud_pw2";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PMIC_CLK_32K */
-                       clk_32k_in {
+                       clk-32k-in {
                                nvidia,pins = "clk_32k_in";
                                nvidia,function = "clk";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PMIC_CPU_OC_INT */
-                       clk_32k_out_pa0 {
+                       clk-32k-out-pa0 {
                                nvidia,pins = "clk_32k_out_pa0";
                                nvidia,function = "soc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PWR_I2C */
-                       pwr_i2c_scl_pz6 {
+                       pwr-i2c-scl-pz6 {
                                nvidia,pins = "pwr_i2c_scl_pz6";
                                nvidia,function = "i2cpwr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       pwr_i2c_sda_pz7 {
+                       pwr-i2c-sda-pz7 {
                                nvidia,pins = "pwr_i2c_sda_pz7";
                                nvidia,function = "i2cpwr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PWR_INT_N */
-                       pwr_int_n {
+                       pwr-int-n {
                                nvidia,pins = "pwr_int_n";
                                nvidia,function = "pmi";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* RESET_OUT_N */
-                       reset_out_n {
+                       reset-out-n {
                                nvidia,pins = "reset_out_n";
                                nvidia,function = "reset_out_n";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* SHIFT_CTRL_DIR_IN */
-                       kb_row0_pr0 {
+                       kb-row0-pr0 {
                                nvidia,pins = "kb_row0_pr0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row1_pr1 {
+                       kb-row1-pr1 {
                                nvidia,pins = "kb_row1_pr1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                        };
 
                        /* Configure level-shifter as output for HDA */
-                       kb_row11_ps3 {
+                       kb-row11-ps3 {
                                nvidia,pins = "kb_row11_ps3";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* SHIFT_CTRL_DIR_OUT */
-                       kb_col5_pq5 {
+                       kb-col5-pq5 {
                                nvidia,pins = "kb_col5_pq5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col6_pq6 {
+                       kb-col6-pq6 {
                                nvidia,pins = "kb_col6_pq6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col7_pq7 {
+                       kb-col7-pq7 {
                                nvidia,pins = "kb_col7_pq7";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* SHIFT_CTRL_OE */
-                       kb_col0_pq0 {
+                       kb-col0-pq0 {
                                nvidia,pins = "kb_col0_pq0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col1_pq1 {
+                       kb-col1-pq1 {
                                nvidia,pins = "kb_col1_pq1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col2_pq2 {
+                       kb-col2-pq2 {
                                nvidia,pins = "kb_col2_pq2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col4_pq4 {
+                       kb-col4-pq4 {
                                nvidia,pins = "kb_col4_pq4";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row2_pr2 {
+                       kb-row2-pr2 {
                                nvidia,pins = "kb_row2_pr2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                        };
 
                        /* TOUCH_INT */
-                       gpio_w3_aud_pw3 {
+                       gpio-w3-aud-pw3 {
                                nvidia,pins = "gpio_w3_aud_pw3";
                                nvidia,function = "spi6";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_fs_pn0 { /* NC */
+                       dap1-fs-pn0 { /* NC */
                                nvidia,pins = "dap1_fs_pn0";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_din_pn1 { /* NC */
+                       dap1-din-pn1 { /* NC */
                                nvidia,pins = "dap1_din_pn1";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_sclk_pn3 { /* NC */
+                       dap1-sclk-pn3 { /* NC */
                                nvidia,pins = "dap1_sclk_pn3";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data7_po0 { /* NC */
+                       ulpi-data7-po0 { /* NC */
                                nvidia,pins = "ulpi_data7_po0";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data0_po1 { /* NC */
+                       ulpi-data0-po1 { /* NC */
                                nvidia,pins = "ulpi_data0_po1";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data1_po2 { /* NC */
+                       ulpi-data1-po2 { /* NC */
                                nvidia,pins = "ulpi_data1_po2";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data2_po3 { /* NC */
+                       ulpi-data2-po3 { /* NC */
                                nvidia,pins = "ulpi_data2_po3";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data3_po4 { /* NC */
+                       ulpi-data3-po4 { /* NC */
                                nvidia,pins = "ulpi_data3_po4";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data6_po7 { /* NC */
+                       ulpi-data6-po7 { /* NC */
                                nvidia,pins = "ulpi_data6_po7";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_fs_pp4 { /* NC */
+                       dap4-fs-pp4 { /* NC */
                                nvidia,pins = "dap4_fs_pp4";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_din_pp5 { /* NC */
+                       dap4-din-pp5 { /* NC */
                                nvidia,pins = "dap4_din_pp5";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_dout_pp6 { /* NC */
+                       dap4-dout-pp6 { /* NC */
                                nvidia,pins = "dap4_dout_pp6";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_sclk_pp7 { /* NC */
+                       dap4-sclk-pp7 { /* NC */
                                nvidia,pins = "dap4_sclk_pp7";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col3_pq3 { /* NC */
+                       kb-col3-pq3 { /* NC */
                                nvidia,pins = "kb_col3_pq3";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row3_pr3 { /* NC */
+                       kb-row3-pr3 { /* NC */
                                nvidia,pins = "kb_row3_pr3";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row4_pr4 { /* NC */
+                       kb-row4-pr4 { /* NC */
                                nvidia,pins = "kb_row4_pr4";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row5_pr5 { /* NC */
+                       kb-row5-pr5 { /* NC */
                                nvidia,pins = "kb_row5_pr5";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row6_pr6 { /* NC */
+                       kb-row6-pr6 { /* NC */
                                nvidia,pins = "kb_row6_pr6";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row7_pr7 { /* NC */
+                       kb-row7-pr7 { /* NC */
                                nvidia,pins = "kb_row7_pr7";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row8_ps0 { /* NC */
+                       kb-row8-ps0 { /* NC */
                                nvidia,pins = "kb_row8_ps0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row9_ps1 { /* NC */
+                       kb-row9-ps1 { /* NC */
                                nvidia,pins = "kb_row9_ps1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row12_ps4 { /* NC */
+                       kb-row12-ps4 { /* NC */
                                nvidia,pins = "kb_row12_ps4";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row13_ps5 { /* NC */
+                       kb-row13-ps5 { /* NC */
                                nvidia,pins = "kb_row13_ps5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row14_ps6 { /* NC */
+                       kb-row14-ps6 { /* NC */
                                nvidia,pins = "kb_row14_ps6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row15_ps7 { /* NC */
+                       kb-row15-ps7 { /* NC */
                                nvidia,pins = "kb_row15_ps7";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row16_pt0 { /* NC */
+                       kb-row16-pt0 { /* NC */
                                nvidia,pins = "kb_row16_pt0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row17_pt1 { /* NC */
+                       kb-row17-pt1 { /* NC */
                                nvidia,pins = "kb_row17_pt1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x1_aud_px1 { /* NC */
+                       gpio-x1-aud-px1 { /* NC */
                                nvidia,pins = "gpio_x1_aud_px1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x3_aud_px3 { /* NC */
+                       gpio-x3-aud-px3 { /* NC */
                                nvidia,pins = "gpio_x3_aud_px3";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       clk3_req_pee1 { /* NC */
+                       clk3-req-pee1 { /* NC */
                                nvidia,pins = "clk3_req_pee1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap_mclk1_req_pee2 { /* NC */
+                       dap-mclk1-req-pee2 { /* NC */
                                nvidia,pins = "dap_mclk1_req_pee2";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                         * SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1
                         * bits being set to 0xfffd according to the TRM!
                         */
-                       sdmmc3_clk_lb_out_pee4 { /* NC */
+                       sdmmc3-clk-lb-out-pee4 { /* NC */
                                nvidia,pins = "sdmmc3_clk_lb_out_pee4";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                sgtl5000: codec@a {
                        compatible = "fsl,sgtl5000";
                        reg = <0x0a>;
-                       VDDA-supply = <&reg_3v3>;
-                       VDDIO-supply = <&vddio_1v8>;
+                       VDDA-supply = <&reg_module_3v3_audio>;
+                       VDDD-supply = <&reg_1v8_vddio>;
+                       VDDIO-supply = <&reg_1v8_vddio>;
                        clocks = <&tegra_car TEGRA124_CLK_EXTERN1>;
                };
 
                        pinctrl-0 = <&as3722_default>;
 
                        as3722_default: pinmux {
-                               gpio2_7 {
+                               gpio2-7 {
                                        pins = "gpio2", /* PWR_EN_+V3.3 */
                                               "gpio7"; /* +V1.6_LPO */
                                        function = "gpio";
                                        bias-pull-up;
                                };
 
-                               gpio0_1_3_4_5_6 {
+                               gpio0-1-3-4-5-6 {
                                        pins = "gpio0", "gpio1", "gpio3",
                                               "gpio4", "gpio5", "gpio6";
                                        bias-high-impedance;
                        };
 
                        regulators {
-                               vsup-sd2-supply = <&reg_3v3>;
-                               vsup-sd3-supply = <&reg_3v3>;
-                               vsup-sd4-supply = <&reg_3v3>;
-                               vsup-sd5-supply = <&reg_3v3>;
-                               vin-ldo0-supply = <&vddio_ddr_1v35>;
-                               vin-ldo1-6-supply = <&reg_3v3>;
-                               vin-ldo2-5-7-supply = <&vddio_1v8>;
-                               vin-ldo3-4-supply = <&reg_3v3>;
-                               vin-ldo9-10-supply = <&reg_3v3>;
-                               vin-ldo11-supply = <&reg_3v3>;
-
-                               vdd_cpu: sd0 {
+                               vsup-sd2-supply = <&reg_module_3v3>;
+                               vsup-sd3-supply = <&reg_module_3v3>;
+                               vsup-sd4-supply = <&reg_module_3v3>;
+                               vsup-sd5-supply = <&reg_module_3v3>;
+                               vin-ldo0-supply = <&reg_1v35_vddio_ddr>;
+                               vin-ldo1-6-supply = <&reg_module_3v3>;
+                               vin-ldo2-5-7-supply = <&reg_1v8_vddio>;
+                               vin-ldo3-4-supply = <&reg_module_3v3>;
+                               vin-ldo9-10-supply = <&reg_module_3v3>;
+                               vin-ldo11-supply = <&reg_module_3v3>;
+
+                               reg_vdd_cpu: sd0 {
                                        regulator-name = "+VDD_CPU_AP";
                                        regulator-min-microvolt = <700000>;
                                        regulator-max-microvolt = <1400000>;
                                        ams,ext-control = <1>;
                                };
 
-                               vddio_ddr_1v35: sd2 {
+                               reg_1v35_vddio_ddr: sd2 {
                                        regulator-name =
                                                "+V1.35_VDDIO_DDR(sd2)";
                                        regulator-min-microvolt = <1350000>;
                                        regulator-boot-on;
                                };
 
-                               vdd_1v05: sd4 {
+                               reg_1v05_vdd: sd4 {
                                        regulator-name = "+V1.05";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                                };
 
-                               vddio_1v8: sd5 {
+                               reg_1v8_vddio: sd5 {
                                        regulator-name = "+V1.8";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
                                };
 
-                               vdd_gpu: sd6 {
+                               reg_vdd_gpu: sd6 {
                                        regulator-name = "+VDD_GPU_AP";
                                        regulator-min-microvolt = <650000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                };
 
-                               avdd_1v05: ldo0 {
+                               reg_1v05_avdd: ldo0 {
                                        regulator-name = "+V1.05_AVDD";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                 * TMP451 temperature sensor
                 * Note: THERM_N directly connected to AS3722 PMIC THERM
                 */
-               temperature-sensor@4c {
+               temp-sensor@4c {
                        compatible = "ti,tmp451";
                        reg = <0x4c>;
                        interrupt-parent = <&gpio>;
                        interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
                        #thermal-sensor-cells = <1>;
+                       vcc-supply = <&reg_module_3v3>;
                };
        };
 
        sata@70020000 {
                phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>;
                phy-names = "sata-0";
-               avdd-supply = <&vdd_1v05>;
-               hvdd-supply = <&reg_3v3>;
-               vddio-supply = <&vdd_1v05>;
+               avdd-supply = <&reg_1v05_vdd>;
+               hvdd-supply = <&reg_module_3v3>;
+               vddio-supply = <&reg_1v05_vdd>;
        };
 
        usb@70090000 {
                       <&{/padctl@7009f000/pads/usb2/lanes/usb2-2}>,
                       <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>;
                phy-names = "usb2-0", "usb3-1", "usb2-1", "usb2-2", "usb3-0";
-               avddio-pex-supply = <&vdd_1v05>;
-               avdd-pll-erefe-supply = <&avdd_1v05>;
-               avdd-pll-utmip-supply = <&vddio_1v8>;
-               avdd-usb-ss-pll-supply = <&vdd_1v05>;
-               avdd-usb-supply = <&reg_3v3>;
-               dvddio-pex-supply = <&vdd_1v05>;
-               hvdd-usb-ss-pll-e-supply = <&reg_3v3>;
-               hvdd-usb-ss-supply = <&reg_3v3>;
+               avddio-pex-supply = <&reg_1v05_vdd>;
+               avdd-pll-erefe-supply = <&reg_1v05_avdd>;
+               avdd-pll-utmip-supply = <&reg_1v8_vddio>;
+               avdd-usb-ss-pll-supply = <&reg_1v05_vdd>;
+               avdd-usb-supply = <&reg_module_3v3>;
+               dvddio-pex-supply = <&reg_1v05_vdd>;
+               hvdd-usb-ss-pll-e-supply = <&reg_module_3v3>;
+               hvdd-usb-ss-supply = <&reg_module_3v3>;
        };
 
        padctl@7009f000 {
 
                                lanes {
                                        usb2-0 {
-                                               nvidia,function = "xusb";
                                                status = "okay";
+                                               nvidia,function = "xusb";
                                        };
 
                                        usb2-1 {
-                                               nvidia,function = "xusb";
                                                status = "okay";
+                                               nvidia,function = "xusb";
                                        };
 
                                        usb2-2 {
-                                               nvidia,function = "xusb";
                                                status = "okay";
+                                               nvidia,function = "xusb";
                                        };
                                };
                        };
 
                                lanes {
                                        pcie-0 {
-                                               nvidia,function = "usb3-ss";
                                                status = "okay";
+                                               nvidia,function = "usb3-ss";
                                        };
 
                                        pcie-1 {
-                                               nvidia,function = "usb3-ss";
                                                status = "okay";
+                                               nvidia,function = "usb3-ss";
                                        };
 
                                        pcie-2 {
-                                               nvidia,function = "pcie";
                                                status = "okay";
+                                               nvidia,function = "pcie";
                                        };
 
                                        pcie-3 {
-                                               nvidia,function = "pcie";
                                                status = "okay";
+                                               nvidia,function = "pcie";
                                        };
 
                                        pcie-4 {
-                                               nvidia,function = "pcie";
                                                status = "okay";
+                                               nvidia,function = "pcie";
                                        };
                                };
                        };
 
                                lanes {
                                        sata-0 {
-                                               nvidia,function = "sata";
                                                status = "okay";
+                                               nvidia,function = "sata";
                                        };
                                };
                        };
                        usb2-0 {
                                status = "okay";
                                mode = "otg";
-
                                vbus-supply = <&reg_usbo1_vbus>;
                        };
 
                        usb2-1 {
                                status = "okay";
                                mode = "host";
-
                                vbus-supply = <&reg_usbh_vbus>;
                        };
 
                        usb2-2 {
                                status = "okay";
                                mode = "host";
-
                                vbus-supply = <&reg_usbh_vbus>;
                        };
 
                        usb3-0 {
-                               nvidia,usb2-companion = <2>;
                                status = "okay";
+                               nvidia,usb2-companion = <2>;
+                               vbus-supply = <&reg_usbh_vbus>;
                        };
 
                        usb3-1 {
-                               nvidia,usb2-companion = <0>;
                                status = "okay";
+                               nvidia,usb2-companion = <0>;
+                               vbus-supply = <&reg_usbo1_vbus>;
                        };
                };
        };
                status = "okay";
                bus-width = <8>;
                non-removable;
+               vmmc-supply = <&reg_module_3v3>; /* VCC */
+               vqmmc-supply = <&reg_1v8_vddio>; /* VCCQ */
+               mmc-ddr-1_8v;
        };
 
        /* CPU DFLL clock */
        clock@70110000 {
                status = "okay";
-               vdd-cpu-supply = <&vdd_cpu>;
                nvidia,i2c-fs-rate = <400000>;
+               vdd-cpu-supply = <&reg_vdd_cpu>;
        };
 
        ahub@70300000 {
                };
        };
 
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               clk32k_in: clock@0 {
-                       compatible = "fixed-clock";
-                       reg = <0>;
-                       #clock-cells = <0>;
-                       clock-frequency = <32768>;
-               };
+       clk32k_in: osc3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
        };
 
        cpus {
                cpu@0 {
-                       vdd-cpu-supply = <&vdd_cpu>;
+                       vdd-cpu-supply = <&reg_vdd_cpu>;
                };
        };
 
                regulator-min-microvolt = <1050000>;
                regulator-max-microvolt = <1050000>;
                gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
-               vin-supply = <&vdd_1v05>;
+               vin-supply = <&reg_1v05_vdd>;
        };
 
        reg_3v3_mxm: regulator-3v3-mxm {
                regulator-boot-on;
        };
 
-       reg_3v3: regulator-3v3 {
+       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&reg_1v05_vdd>;
+       };
+
+       reg_module_3v3: regulator-module-3v3 {
                compatible = "regulator-fixed";
                regulator-name = "+V3.3";
                regulator-min-microvolt = <3300000>;
                vin-supply = <&reg_3v3_mxm>;
        };
 
-       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+       reg_module_3v3_audio: regulator-module-3v3-audio {
                compatible = "regulator-fixed";
-               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-name = "+V3.3_AUDIO_AVDD_S";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               vin-supply = <&vdd_1v05>;
+               regulator-always-on;
        };
 
        sound {
 
 &gpio {
        /* I210 Gigabit Ethernet Controller Reset */
-       lan_reset_n {
+       lan-reset-n {
                gpio-hog;
                gpios = <TEGRA_GPIO(S, 2) GPIO_ACTIVE_HIGH>;
                output-high;
        };
 
        /* Control MXM3 pin 26 Reset Module Output Carrier Input */
-       reset_moci_ctrl {
+       reset-moci-ctrl {
                gpio-hog;
                gpios = <TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
                output-high;
index 0f0d4a4988b90fafb9f4ab39c1825b9b3a635055..13c93cd507d8e44acc900d2e5ef69921ebe55ebd 100644 (file)
  * Compatible for Revisions 2GB: V1.0A, V1.0B, V1.1A
  */
 / {
-       model = "Toradex Apalis TK1";
-       compatible = "toradex,apalis-tk1", "nvidia,tegra124";
-
        memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
        pcie@1003000 {
                status = "okay";
-               avddio-pex-supply = <&vdd_1v05>;
-               avdd-pex-pll-supply = <&vdd_1v05>;
-               avdd-pll-erefe-supply = <&avdd_1v05>;
-               dvddio-pex-supply = <&vdd_1v05>;
-               hvdd-pex-pll-e-supply = <&reg_3v3>;
-               hvdd-pex-supply = <&reg_3v3>;
-               vddio-pex-ctl-supply = <&reg_3v3>;
+               avddio-pex-supply = <&reg_1v05_vdd>;
+               avdd-pex-pll-supply = <&reg_1v05_vdd>;
+               avdd-pll-erefe-supply = <&reg_1v05_avdd>;
+               dvddio-pex-supply = <&reg_1v05_vdd>;
+               hvdd-pex-pll-e-supply = <&reg_module_3v3>;
+               hvdd-pex-supply = <&reg_module_3v3>;
+               vddio-pex-ctl-supply = <&reg_module_3v3>;
 
                /* Apalis PCIe (additional lane Apalis type specific) */
                pci@1,0 {
                        phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>;
                        phy-names = "pcie-0";
                        status = "okay";
+
+                       pcie@0 {
+                               reg = <0 0 0 0 0>;
+                               local-mac-address = [00 00 00 00 00 00];
+                       };
                };
        };
 
        host1x@50000000 {
                hdmi@54280000 {
-                       pll-supply = <&reg_1v05_avdd_hdmi_pll>;
-                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                        nvidia,ddc-i2c-bus = <&hdmi_ddc>;
                        nvidia,hpd-gpio =
                                <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+                       pll-supply = <&reg_1v05_avdd_hdmi_pll>;
+                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                };
        };
 
                 * Node left disabled on purpose - the bootloader will enable
                 * it after having set the VPR up
                 */
-               vdd-supply = <&vdd_gpu>;
+               vdd-supply = <&reg_vdd_gpu>;
        };
 
-       pinmux: pinmux@70000868 {
+       pinmux@70000868 {
                pinctrl-names = "default";
                pinctrl-0 = <&state_default>;
 
                state_default: pinmux {
                        /* Analogue Audio (On-module) */
-                       dap3_fs_pp0 {
+                       dap3-fs-pp0 {
                                nvidia,pins = "dap3_fs_pp0";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap3_din_pp1 {
+                       dap3-din-pp1 {
                                nvidia,pins = "dap3_din_pp1";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap3_dout_pp2 {
+                       dap3-dout-pp2 {
                                nvidia,pins = "dap3_dout_pp2";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap3_sclk_pp3 {
+                       dap3-sclk-pp3 {
                                nvidia,pins = "dap3_sclk_pp3";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap_mclk1_pw4 {
+                       dap-mclk1-pw4 {
                                nvidia,pins = "dap_mclk1_pw4";
                                nvidia,function = "extperiph1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis CAM1_MCLK */
-                       cam_mclk_pcc0 {
+                       cam-mclk-pcc0 {
                                nvidia,pins = "cam_mclk_pcc0";
                                nvidia,function = "vi_alt3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis Digital Audio */
-                       dap2_fs_pa2 {
+                       dap2-fs-pa2 {
                                nvidia,pins = "dap2_fs_pa2";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap2_sclk_pa3 {
+                       dap2-sclk-pa3 {
                                nvidia,pins = "dap2_sclk_pa3";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap2_din_pa4 {
+                       dap2-din-pa4 {
                                nvidia,pins = "dap2_din_pa4";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dap2_dout_pa5 {
+                       dap2-dout-pa5 {
                                nvidia,pins = "dap2_dout_pa5";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       clk3_out_pee0 {
+                       clk3-out-pee0 {
                                nvidia,pins = "clk3_out_pee0";
                                nvidia,function = "extperiph3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis GPIO */
-                       ddc_scl_pv4 {
+                       ddc-scl-pv4 {
                                nvidia,pins = "ddc_scl_pv4";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       ddc_sda_pv5 {
+                       ddc-sda-pv5 {
                                nvidia,pins = "ddc_sda_pv5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l0_rst_n_pdd1 {
+                       pex-l0-rst-n-pdd1 {
                                nvidia,pins = "pex_l0_rst_n_pdd1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l0_clkreq_n_pdd2 {
+                       pex-l0-clkreq-n-pdd2 {
                                nvidia,pins = "pex_l0_clkreq_n_pdd2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l1_rst_n_pdd5 {
+                       pex-l1-rst-n-pdd5 {
                                nvidia,pins = "pex_l1_rst_n_pdd5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       pex_l1_clkreq_n_pdd6 {
+                       pex-l1-clkreq-n-pdd6 {
                                nvidia,pins = "pex_l1_clkreq_n_pdd6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       dp_hpd_pff0 {
+                       dp-hpd-pff0 {
                                nvidia,pins = "dp_hpd_pff0";
                                nvidia,function = "dp";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis HDMI1_CEC */
-                       hdmi_cec_pee3 {
+                       hdmi-cec-pee3 {
                                nvidia,pins = "hdmi_cec_pee3";
                                nvidia,function = "cec";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis HDMI1_HPD */
-                       hdmi_int_pn7 {
+                       hdmi-int-pn7 {
                                nvidia,pins = "hdmi_int_pn7";
                                nvidia,function = "rsvd1";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                        };
 
                        /* Apalis I2C1 */
-                       gen1_i2c_scl_pc4 {
+                       gen1-i2c-scl-pc4 {
                                nvidia,pins = "gen1_i2c_scl_pc4";
                                nvidia,function = "i2c1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       gen1_i2c_sda_pc5 {
+                       gen1-i2c-sda-pc5 {
                                nvidia,pins = "gen1_i2c_sda_pc5";
                                nvidia,function = "i2c1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis I2C2 (DDC) */
-                       gen2_i2c_scl_pt5 {
+                       gen2-i2c-scl-pt5 {
                                nvidia,pins = "gen2_i2c_scl_pt5";
                                nvidia,function = "i2c2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       gen2_i2c_sda_pt6 {
+                       gen2-i2c-sda-pt6 {
                                nvidia,pins = "gen2_i2c_sda_pt6";
                                nvidia,function = "i2c2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis I2C3 (CAM) */
-                       cam_i2c_scl_pbb1 {
+                       cam-i2c-scl-pbb1 {
                                nvidia,pins = "cam_i2c_scl_pbb1";
                                nvidia,function = "i2c3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       cam_i2c_sda_pbb2 {
+                       cam-i2c-sda-pbb2 {
                                nvidia,pins = "cam_i2c_sda_pbb2";
                                nvidia,function = "i2c3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis MMC1 */
-                       sdmmc1_cd_n_pv3 { /* CD# GPIO */
+                       sdmmc1-cd-n-pv3 { /* CD# GPIO */
                                nvidia,pins = "sdmmc1_wp_n_pv3";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       clk2_out_pw5 { /* D5 GPIO */
+                       clk2-out-pw5 { /* D5 GPIO */
                                nvidia,pins = "clk2_out_pw5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat3_py4 {
+                       sdmmc1-dat3-py4 {
                                nvidia,pins = "sdmmc1_dat3_py4";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat2_py5 {
+                       sdmmc1-dat2-py5 {
                                nvidia,pins = "sdmmc1_dat2_py5";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat1_py6 {
+                       sdmmc1-dat1-py6 {
                                nvidia,pins = "sdmmc1_dat1_py6";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_dat0_py7 {
+                       sdmmc1-dat0-py7 {
                                nvidia,pins = "sdmmc1_dat0_py7";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_clk_pz0 {
+                       sdmmc1-clk-pz0 {
                                nvidia,pins = "sdmmc1_clk_pz0";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc1_cmd_pz1 {
+                       sdmmc1-cmd-pz1 {
                                nvidia,pins = "sdmmc1_cmd_pz1";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       clk2_req_pcc5 { /* D4 GPIO */
+                       clk2-req-pcc5 { /* D4 GPIO */
                                nvidia,pins = "clk2_req_pcc5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_clk_lb_in_pee5 { /* D6 GPIO */
+                       sdmmc3-clk-lb-in-pee5 { /* D6 GPIO */
                                nvidia,pins = "sdmmc3_clk_lb_in_pee5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       usb_vbus_en2_pff1 { /* D7 GPIO */
+                       usb-vbus-en2-pff1 { /* D7 GPIO */
                                nvidia,pins = "usb_vbus_en2_pff1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis SATA1_ACT# */
-                       dap1_dout_pn2 {
+                       dap1-dout-pn2 {
                                nvidia,pins = "dap1_dout_pn2";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis SD1 */
-                       sdmmc3_clk_pa6 {
+                       sdmmc3-clk-pa6 {
                                nvidia,pins = "sdmmc3_clk_pa6";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_cmd_pa7 {
+                       sdmmc3-cmd-pa7 {
                                nvidia,pins = "sdmmc3_cmd_pa7";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat3_pb4 {
+                       sdmmc3-dat3-pb4 {
                                nvidia,pins = "sdmmc3_dat3_pb4";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat2_pb5 {
+                       sdmmc3-dat2-pb5 {
                                nvidia,pins = "sdmmc3_dat2_pb5";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat1_pb6 {
+                       sdmmc3-dat1-pb6 {
                                nvidia,pins = "sdmmc3_dat1_pb6";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_dat0_pb7 {
+                       sdmmc3-dat0-pb7 {
                                nvidia,pins = "sdmmc3_dat0_pb7";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc3_cd_n_pv2 { /* CD# GPIO */
+                       sdmmc3-cd-n-pv2 { /* CD# GPIO */
                                nvidia,pins = "sdmmc3_cd_n_pv2";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* Apalis SPDIF */
-                       spdif_out_pk5 {
+                       spdif-out-pk5 {
                                nvidia,pins = "spdif_out_pk5";
                                nvidia,function = "spdif";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       spdif_in_pk6 {
+                       spdif-in-pk6 {
                                nvidia,pins = "spdif_in_pk6";
                                nvidia,function = "spdif";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis SPI1 */
-                       ulpi_clk_py0 {
+                       ulpi-clk-py0 {
                                nvidia,pins = "ulpi_clk_py0";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_dir_py1 {
+                       ulpi-dir-py1 {
                                nvidia,pins = "ulpi_dir_py1";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       ulpi_nxt_py2 {
+                       ulpi-nxt-py2 {
                                nvidia,pins = "ulpi_nxt_py2";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_stp_py3 {
+                       ulpi-stp-py3 {
                                nvidia,pins = "ulpi_stp_py3";
                                nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart1_txd_pu0 {
+                       uart1-txd-pu0 {
                                nvidia,pins = "pu0";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart1_rxd_pu1 {
+                       uart1-rxd-pu1 {
                                nvidia,pins = "pu1";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart1_cts_n_pu2 {
+                       uart1-cts-n-pu2 {
                                nvidia,pins = "pu2";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart1_rts_n_pu3 {
+                       uart1-rts-n-pu3 {
                                nvidia,pins = "pu3";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart3_cts_n_pa1 { /* DSR GPIO */
+                       uart3-cts-n-pa1 { /* DSR GPIO */
                                nvidia,pins = "uart3_cts_n_pa1";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart3_rts_n_pc0 { /* DTR GPIO */
+                       uart3-rts-n-pc0 { /* DTR GPIO */
                                nvidia,pins = "uart3_rts_n_pc0";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis UART2 */
-                       uart2_txd_pc2 {
+                       uart2-txd-pc2 {
                                nvidia,pins = "uart2_txd_pc2";
                                nvidia,function = "irda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart2_rxd_pc3 {
+                       uart2-rxd-pc3 {
                                nvidia,pins = "uart2_rxd_pc3";
                                nvidia,function = "irda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart2_cts_n_pj5 {
+                       uart2-cts-n-pj5 {
                                nvidia,pins = "uart2_cts_n_pj5";
                                nvidia,function = "uartb";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart2_rts_n_pj6 {
+                       uart2-rts-n-pj6 {
                                nvidia,pins = "uart2_rts_n_pj6";
                                nvidia,function = "uartb";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis UART3 */
-                       uart3_txd_pw6 {
+                       uart3-txd-pw6 {
                                nvidia,pins = "uart3_txd_pw6";
                                nvidia,function = "uartc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       uart3_rxd_pw7 {
+                       uart3-rxd-pw7 {
                                nvidia,pins = "uart3_rxd_pw7";
                                nvidia,function = "uartc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis UART4 */
-                       uart4_rxd_pb0 {
+                       uart4-rxd-pb0 {
                                nvidia,pins = "pb0";
                                nvidia,function = "uartd";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       uart4_txd_pj7 {
+                       uart4-txd-pj7 {
                                nvidia,pins = "pj7";
                                nvidia,function = "uartd";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis USBH_EN */
-                       usb_vbus_en1_pn5 {
+                       usb-vbus-en1-pn5 {
                                nvidia,pins = "usb_vbus_en1_pn5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis USBO1_EN */
-                       usb_vbus_en0_pn4 {
+                       usb-vbus-en0-pn4 {
                                nvidia,pins = "usb_vbus_en0_pn4";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis WAKE1_MICO */
-                       pex_wake_n_pdd3 {
+                       pex-wake-n-pdd3 {
                                nvidia,pins = "pex_wake_n_pdd3";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* CORE_PWR_REQ */
-                       core_pwr_req {
+                       core-pwr-req {
                                nvidia,pins = "core_pwr_req";
                                nvidia,function = "pwron";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* CPU_PWR_REQ */
-                       cpu_pwr_req {
+                       cpu-pwr-req {
                                nvidia,pins = "cpu_pwr_req";
                                nvidia,function = "cpu";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* DVFS */
-                       dvfs_pwm_px0 {
+                       dvfs-pwm-px0 {
                                nvidia,pins = "dvfs_pwm_px0";
                                nvidia,function = "cldvfs";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dvfs_clk_px2 {
+                       dvfs-clk-px2 {
                                nvidia,pins = "dvfs_clk_px2";
                                nvidia,function = "cldvfs";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* eMMC */
-                       sdmmc4_dat0_paa0 {
+                       sdmmc4-dat0-paa0 {
                                nvidia,pins = "sdmmc4_dat0_paa0";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat1_paa1 {
+                       sdmmc4-dat1-paa1 {
                                nvidia,pins = "sdmmc4_dat1_paa1";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat2_paa2 {
+                       sdmmc4-dat2-paa2 {
                                nvidia,pins = "sdmmc4_dat2_paa2";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat3_paa3 {
+                       sdmmc4-dat3-paa3 {
                                nvidia,pins = "sdmmc4_dat3_paa3";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat4_paa4 {
+                       sdmmc4-dat4-paa4 {
                                nvidia,pins = "sdmmc4_dat4_paa4";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat5_paa5 {
+                       sdmmc4-dat5-paa5 {
                                nvidia,pins = "sdmmc4_dat5_paa5";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat6_paa6 {
+                       sdmmc4-dat6-paa6 {
                                nvidia,pins = "sdmmc4_dat6_paa6";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat7_paa7 {
+                       sdmmc4-dat7-paa7 {
                                nvidia,pins = "sdmmc4_dat7_paa7";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_clk_pcc4 {
+                       sdmmc4-clk-pcc4 {
                                nvidia,pins = "sdmmc4_clk_pcc4";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_cmd_pt7 {
+                       sdmmc4-cmd-pt7 {
                                nvidia,pins = "sdmmc4_cmd_pt7";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* JTAG_RTCK */
-                       jtag_rtck {
+                       jtag-rtck {
                                nvidia,pins = "jtag_rtck";
                                nvidia,function = "rtck";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* LAN_DEV_OFF# */
-                       ulpi_data5_po6 {
+                       ulpi-data5-po6 {
                                nvidia,pins = "ulpi_data5_po6";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* LAN_RESET# */
-                       kb_row10_ps2 {
+                       kb-row10-ps2 {
                                nvidia,pins = "kb_row10_ps2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* LAN_WAKE# */
-                       ulpi_data4_po5 {
+                       ulpi-data4-po5 {
                                nvidia,pins = "ulpi_data4_po5";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* MCU SPI */
-                       gpio_x4_aud_px4 {
+                       gpio-x4-aud-px4 {
                                nvidia,pins = "gpio_x4_aud_px4";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x5_aud_px5 {
+                       gpio-x5-aud-px5 {
                                nvidia,pins = "gpio_x5_aud_px5";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x6_aud_px6 { /* MCU_CS */
+                       gpio-x6-aud-px6 { /* MCU_CS */
                                nvidia,pins = "gpio_x6_aud_px6";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x7_aud_px7 {
+                       gpio-x7-aud-px7 {
                                nvidia,pins = "gpio_x7_aud_px7";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       gpio_w2_aud_pw2 { /* MCU_CSEZP */
+                       gpio-w2-aud-pw2 { /* MCU_CSEZP */
                                nvidia,pins = "gpio_w2_aud_pw2";
                                nvidia,function = "spi2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PMIC_CLK_32K */
-                       clk_32k_in {
+                       clk-32k-in {
                                nvidia,pins = "clk_32k_in";
                                nvidia,function = "clk";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PMIC_CPU_OC_INT */
-                       clk_32k_out_pa0 {
+                       clk-32k-out-pa0 {
                                nvidia,pins = "clk_32k_out_pa0";
                                nvidia,function = "soc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PWR_I2C */
-                       pwr_i2c_scl_pz6 {
+                       pwr-i2c-scl-pz6 {
                                nvidia,pins = "pwr_i2c_scl_pz6";
                                nvidia,function = "i2cpwr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
-                       pwr_i2c_sda_pz7 {
+                       pwr-i2c-sda-pz7 {
                                nvidia,pins = "pwr_i2c_sda_pz7";
                                nvidia,function = "i2cpwr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* PWR_INT_N */
-                       pwr_int_n {
+                       pwr-int-n {
                                nvidia,pins = "pwr_int_n";
                                nvidia,function = "pmi";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* RESET_OUT_N */
-                       reset_out_n {
+                       reset-out-n {
                                nvidia,pins = "reset_out_n";
                                nvidia,function = "reset_out_n";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* SHIFT_CTRL_DIR_IN */
-                       kb_row0_pr0 {
+                       kb-row0-pr0 {
                                nvidia,pins = "kb_row0_pr0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row1_pr1 {
+                       kb-row1-pr1 {
                                nvidia,pins = "kb_row1_pr1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                        };
 
                        /* Configure level-shifter as output for HDA */
-                       kb_row11_ps3 {
+                       kb-row11-ps3 {
                                nvidia,pins = "kb_row11_ps3";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* SHIFT_CTRL_DIR_OUT */
-                       kb_col5_pq5 {
+                       kb-col5-pq5 {
                                nvidia,pins = "kb_col5_pq5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col6_pq6 {
+                       kb-col6-pq6 {
                                nvidia,pins = "kb_col6_pq6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col7_pq7 {
+                       kb-col7-pq7 {
                                nvidia,pins = "kb_col7_pq7";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                        };
 
                        /* SHIFT_CTRL_OE */
-                       kb_col0_pq0 {
+                       kb-col0-pq0 {
                                nvidia,pins = "kb_col0_pq0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col1_pq1 {
+                       kb-col1-pq1 {
                                nvidia,pins = "kb_col1_pq1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col2_pq2 {
+                       kb-col2-pq2 {
                                nvidia,pins = "kb_col2_pq2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col4_pq4 {
+                       kb-col4-pq4 {
                                nvidia,pins = "kb_col4_pq4";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row2_pr2 {
+                       kb-row2-pr2 {
                                nvidia,pins = "kb_row2_pr2";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                        };
 
                        /* TOUCH_INT */
-                       gpio_w3_aud_pw3 {
+                       gpio-w3-aud-pw3 {
                                nvidia,pins = "gpio_w3_aud_pw3";
                                nvidia,function = "spi6";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_fs_pn0 { /* NC */
+                       dap1-fs-pn0 { /* NC */
                                nvidia,pins = "dap1_fs_pn0";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_din_pn1 { /* NC */
+                       dap1-din-pn1 { /* NC */
                                nvidia,pins = "dap1_din_pn1";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_sclk_pn3 { /* NC */
+                       dap1-sclk-pn3 { /* NC */
                                nvidia,pins = "dap1_sclk_pn3";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data7_po0 { /* NC */
+                       ulpi-data7-po0 { /* NC */
                                nvidia,pins = "ulpi_data7_po0";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data0_po1 { /* NC */
+                       ulpi-data0-po1 { /* NC */
                                nvidia,pins = "ulpi_data0_po1";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data1_po2 { /* NC */
+                       ulpi-data1-po2 { /* NC */
                                nvidia,pins = "ulpi_data1_po2";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data2_po3 { /* NC */
+                       ulpi-data2-po3 { /* NC */
                                nvidia,pins = "ulpi_data2_po3";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data3_po4 { /* NC */
+                       ulpi-data3-po4 { /* NC */
                                nvidia,pins = "ulpi_data3_po4";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_data6_po7 { /* NC */
+                       ulpi-data6-po7 { /* NC */
                                nvidia,pins = "ulpi_data6_po7";
                                nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_fs_pp4 { /* NC */
+                       dap4-fs-pp4 { /* NC */
                                nvidia,pins = "dap4_fs_pp4";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_din_pp5 { /* NC */
+                       dap4-din-pp5 { /* NC */
                                nvidia,pins = "dap4_din_pp5";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_dout_pp6 { /* NC */
+                       dap4-dout-pp6 { /* NC */
                                nvidia,pins = "dap4_dout_pp6";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap4_sclk_pp7 { /* NC */
+                       dap4-sclk-pp7 { /* NC */
                                nvidia,pins = "dap4_sclk_pp7";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_col3_pq3 { /* NC */
+                       kb-col3-pq3 { /* NC */
                                nvidia,pins = "kb_col3_pq3";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row3_pr3 { /* NC */
+                       kb-row3-pr3 { /* NC */
                                nvidia,pins = "kb_row3_pr3";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row4_pr4 { /* NC */
+                       kb-row4-pr4 { /* NC */
                                nvidia,pins = "kb_row4_pr4";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row5_pr5 { /* NC */
+                       kb-row5-pr5 { /* NC */
                                nvidia,pins = "kb_row5_pr5";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row6_pr6 { /* NC */
+                       kb-row6-pr6 { /* NC */
                                nvidia,pins = "kb_row6_pr6";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row7_pr7 { /* NC */
+                       kb-row7-pr7 { /* NC */
                                nvidia,pins = "kb_row7_pr7";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row8_ps0 { /* NC */
+                       kb-row8-ps0 { /* NC */
                                nvidia,pins = "kb_row8_ps0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row9_ps1 { /* NC */
+                       kb-row9-ps1 { /* NC */
                                nvidia,pins = "kb_row9_ps1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row12_ps4 { /* NC */
+                       kb-row12-ps4 { /* NC */
                                nvidia,pins = "kb_row12_ps4";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row13_ps5 { /* NC */
+                       kb-row13-ps5 { /* NC */
                                nvidia,pins = "kb_row13_ps5";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row14_ps6 { /* NC */
+                       kb-row14-ps6 { /* NC */
                                nvidia,pins = "kb_row14_ps6";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row15_ps7 { /* NC */
+                       kb-row15-ps7 { /* NC */
                                nvidia,pins = "kb_row15_ps7";
                                nvidia,function = "rsvd3";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row16_pt0 { /* NC */
+                       kb-row16-pt0 { /* NC */
                                nvidia,pins = "kb_row16_pt0";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row17_pt1 { /* NC */
+                       kb-row17-pt1 { /* NC */
                                nvidia,pins = "kb_row17_pt1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x1_aud_px1 { /* NC */
+                       gpio-x1-aud-px1 { /* NC */
                                nvidia,pins = "gpio_x1_aud_px1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_x3_aud_px3 { /* NC */
+                       gpio-x3-aud-px3 { /* NC */
                                nvidia,pins = "gpio_x3_aud_px3";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       clk3_req_pee1 { /* NC */
+                       clk3-req-pee1 { /* NC */
                                nvidia,pins = "clk3_req_pee1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap_mclk1_req_pee2 { /* NC */
+                       dap-mclk1-req-pee2 { /* NC */
                                nvidia,pins = "dap_mclk1_req_pee2";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                         * SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1
                         * bits being set to 0xfffd according to the TRM!
                         */
-                       sdmmc3_clk_lb_out_pee4 { /* NC */
+                       sdmmc3-clk-lb-out-pee4 { /* NC */
                                nvidia,pins = "sdmmc3_clk_lb_out_pee4";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                sgtl5000: codec@a {
                        compatible = "fsl,sgtl5000";
                        reg = <0x0a>;
-                       VDDA-supply = <&reg_3v3>;
-                       VDDIO-supply = <&vddio_1v8>;
+                       VDDA-supply = <&reg_module_3v3_audio>;
+                       VDDD-supply = <&reg_1v8_vddio>;
+                       VDDIO-supply = <&reg_1v8_vddio>;
                        clocks = <&tegra_car TEGRA124_CLK_EXTERN1>;
                };
 
                        pinctrl-0 = <&as3722_default>;
 
                        as3722_default: pinmux {
-                               gpio2_7 {
+                               gpio2-7 {
                                        pins = "gpio2", /* PWR_EN_+V3.3 */
                                               "gpio7"; /* +V1.6_LPO */
                                        function = "gpio";
                                        bias-pull-up;
                                };
 
-                               gpio0_1_3_4_5_6 {
+                               gpio0-1-3-4-5-6 {
                                        pins = "gpio0", "gpio1", "gpio3",
                                               "gpio4", "gpio5", "gpio6";
                                        bias-high-impedance;
                        };
 
                        regulators {
-                               vsup-sd2-supply = <&reg_3v3>;
-                               vsup-sd3-supply = <&reg_3v3>;
-                               vsup-sd4-supply = <&reg_3v3>;
-                               vsup-sd5-supply = <&reg_3v3>;
-                               vin-ldo0-supply = <&vddio_ddr_1v35>;
-                               vin-ldo1-6-supply = <&reg_3v3>;
-                               vin-ldo2-5-7-supply = <&vddio_1v8>;
-                               vin-ldo3-4-supply = <&reg_3v3>;
-                               vin-ldo9-10-supply = <&reg_3v3>;
-                               vin-ldo11-supply = <&reg_3v3>;
-
-                               vdd_cpu: sd0 {
+                               vsup-sd2-supply = <&reg_module_3v3>;
+                               vsup-sd3-supply = <&reg_module_3v3>;
+                               vsup-sd4-supply = <&reg_module_3v3>;
+                               vsup-sd5-supply = <&reg_module_3v3>;
+                               vin-ldo0-supply = <&reg_1v35_vddio_ddr>;
+                               vin-ldo1-6-supply = <&reg_module_3v3>;
+                               vin-ldo2-5-7-supply = <&reg_1v8_vddio>;
+                               vin-ldo3-4-supply = <&reg_module_3v3>;
+                               vin-ldo9-10-supply = <&reg_module_3v3>;
+                               vin-ldo11-supply = <&reg_module_3v3>;
+
+                               reg_vdd_cpu: sd0 {
                                        regulator-name = "+VDD_CPU_AP";
                                        regulator-min-microvolt = <700000>;
                                        regulator-max-microvolt = <1400000>;
                                        ams,ext-control = <1>;
                                };
 
-                               vddio_ddr_1v35: sd2 {
+                               reg_1v35_vddio_ddr: sd2 {
                                        regulator-name =
                                                "+V1.35_VDDIO_DDR(sd2)";
                                        regulator-min-microvolt = <1350000>;
                                        regulator-boot-on;
                                };
 
-                               vdd_1v05: sd4 {
+                               reg_1v05_vdd: sd4 {
                                        regulator-name = "+V1.05";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                                };
 
-                               vddio_1v8: sd5 {
+                               reg_1v8_vddio: sd5 {
                                        regulator-name = "+V1.8";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
                                };
 
-                               vdd_gpu: sd6 {
+                               reg_vdd_gpu: sd6 {
                                        regulator-name = "+VDD_GPU_AP";
                                        regulator-min-microvolt = <650000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                };
 
-                               avdd_1v05: ldo0 {
+                               reg_1v05_avdd: ldo0 {
                                        regulator-name = "+V1.05_AVDD";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                 * TMP451 temperature sensor
                 * Note: THERM_N directly connected to AS3722 PMIC THERM
                 */
-               temperature-sensor@4c {
+               temp-sensor@4c {
                        compatible = "ti,tmp451";
                        reg = <0x4c>;
                        interrupt-parent = <&gpio>;
                        interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
                        #thermal-sensor-cells = <1>;
+                       vcc-supply = <&reg_module_3v3>;
                };
        };
 
        sata@70020000 {
                phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>;
                phy-names = "sata-0";
-               avdd-supply = <&vdd_1v05>;
-               hvdd-supply = <&reg_3v3>;
-               vddio-supply = <&vdd_1v05>;
+               avdd-supply = <&reg_1v05_vdd>;
+               hvdd-supply = <&reg_module_3v3>;
+               vddio-supply = <&reg_1v05_vdd>;
        };
 
        usb@70090000 {
                       <&{/padctl@7009f000/pads/usb2/lanes/usb2-2}>,
                       <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>;
                phy-names = "usb2-0", "usb3-1", "usb2-1", "usb2-2", "usb3-0";
-               avddio-pex-supply = <&vdd_1v05>;
-               avdd-pll-erefe-supply = <&avdd_1v05>;
-               avdd-pll-utmip-supply = <&vddio_1v8>;
-               avdd-usb-ss-pll-supply = <&vdd_1v05>;
-               avdd-usb-supply = <&reg_3v3>;
-               dvddio-pex-supply = <&vdd_1v05>;
-               hvdd-usb-ss-pll-e-supply = <&reg_3v3>;
-               hvdd-usb-ss-supply = <&reg_3v3>;
+               avddio-pex-supply = <&reg_1v05_vdd>;
+               avdd-pll-erefe-supply = <&reg_1v05_avdd>;
+               avdd-pll-utmip-supply = <&reg_1v8_vddio>;
+               avdd-usb-ss-pll-supply = <&reg_1v05_vdd>;
+               avdd-usb-supply = <&reg_module_3v3>;
+               dvddio-pex-supply = <&reg_1v05_vdd>;
+               hvdd-usb-ss-pll-e-supply = <&reg_module_3v3>;
+               hvdd-usb-ss-supply = <&reg_module_3v3>;
        };
 
        padctl@7009f000 {
 
                                lanes {
                                        usb2-0 {
-                                               nvidia,function = "xusb";
                                                status = "okay";
+                                               nvidia,function = "xusb";
                                        };
 
                                        usb2-1 {
-                                               nvidia,function = "xusb";
                                                status = "okay";
+                                               nvidia,function = "xusb";
                                        };
 
                                        usb2-2 {
-                                               nvidia,function = "xusb";
                                                status = "okay";
+                                               nvidia,function = "xusb";
                                        };
                                };
                        };
 
                                lanes {
                                        pcie-0 {
-                                               nvidia,function = "usb3-ss";
                                                status = "okay";
+                                               nvidia,function = "usb3-ss";
                                        };
 
                                        pcie-1 {
-                                               nvidia,function = "usb3-ss";
                                                status = "okay";
+                                               nvidia,function = "usb3-ss";
                                        };
 
                                        pcie-2 {
-                                               nvidia,function = "pcie";
                                                status = "okay";
+                                               nvidia,function = "pcie";
                                        };
 
                                        pcie-3 {
-                                               nvidia,function = "pcie";
                                                status = "okay";
+                                               nvidia,function = "pcie";
                                        };
 
                                        pcie-4 {
-                                               nvidia,function = "pcie";
                                                status = "okay";
+                                               nvidia,function = "pcie";
                                        };
                                };
                        };
 
                                lanes {
                                        sata-0 {
-                                               nvidia,function = "sata";
                                                status = "okay";
+                                               nvidia,function = "sata";
                                        };
                                };
                        };
                        usb2-0 {
                                status = "okay";
                                mode = "otg";
-
                                vbus-supply = <&reg_usbo1_vbus>;
                        };
 
                        usb2-1 {
                                status = "okay";
                                mode = "host";
-
                                vbus-supply = <&reg_usbh_vbus>;
                        };
 
                        usb2-2 {
                                status = "okay";
                                mode = "host";
-
                                vbus-supply = <&reg_usbh_vbus>;
                        };
 
                        usb3-0 {
-                               nvidia,usb2-companion = <2>;
                                status = "okay";
+                               nvidia,usb2-companion = <2>;
+                               vbus-supply = <&reg_usbh_vbus>;
                        };
 
                        usb3-1 {
-                               nvidia,usb2-companion = <0>;
                                status = "okay";
+                               nvidia,usb2-companion = <0>;
+                               vbus-supply = <&reg_usbo1_vbus>;
                        };
                };
        };
                status = "okay";
                bus-width = <8>;
                non-removable;
+               vmmc-supply = <&reg_module_3v3>; /* VCC */
+               vqmmc-supply = <&reg_1v8_vddio>; /* VCCQ */
+               mmc-ddr-1_8v;
        };
 
        /* CPU DFLL clock */
        clock@70110000 {
                status = "okay";
-               vdd-cpu-supply = <&vdd_cpu>;
                nvidia,i2c-fs-rate = <400000>;
+               vdd-cpu-supply = <&reg_vdd_cpu>;
        };
 
        ahub@70300000 {
                };
        };
 
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               clk32k_in: clock@0 {
-                       compatible = "fixed-clock";
-                       reg = <0>;
-                       #clock-cells = <0>;
-                       clock-frequency = <32768>;
-               };
+       clk32k_in: osc3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
        };
 
        cpus {
                cpu@0 {
-                       vdd-cpu-supply = <&vdd_cpu>;
+                       vdd-cpu-supply = <&reg_vdd_cpu>;
                };
        };
 
                regulator-min-microvolt = <1050000>;
                regulator-max-microvolt = <1050000>;
                gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
-               vin-supply = <&vdd_1v05>;
+               vin-supply = <&reg_1v05_vdd>;
        };
 
        reg_3v3_mxm: regulator-3v3-mxm {
                regulator-boot-on;
        };
 
-       reg_3v3: regulator-3v3 {
+       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&reg_1v05_vdd>;
+       };
+
+       reg_module_3v3: regulator-module-3v3 {
                compatible = "regulator-fixed";
                regulator-name = "+V3.3";
                regulator-min-microvolt = <3300000>;
                vin-supply = <&reg_3v3_mxm>;
        };
 
-       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+       reg_module_3v3_audio: regulator-module-3v3-audio {
                compatible = "regulator-fixed";
-               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-name = "+V3.3_AUDIO_AVDD_S";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               vin-supply = <&vdd_1v05>;
+               regulator-always-on;
        };
 
        sound {
 
 &gpio {
        /* I210 Gigabit Ethernet Controller Reset */
-       lan_reset_n {
+       lan-reset-n {
                gpio-hog;
                gpios = <TEGRA_GPIO(S, 2) GPIO_ACTIVE_HIGH>;
                output-high;
        };
 
        /* Control MXM3 pin 26 Reset Module Output Carrier Input */
-       reset_moci_ctrl {
+       reset-moci-ctrl {
                gpio-hog;
                gpios = <TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>;
                output-high;
diff --git a/arch/arm/boot/dts/tegra20-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra20-colibri-eval-v3.dts
new file mode 100644 (file)
index 0000000..3c0f268
--- /dev/null
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra20-colibri.dtsi"
+
+/ {
+       model = "Toradex Colibri T20 on Colibri Evaluation Board";
+       compatible = "toradex,colibri_t20-eval-v3", "toradex,colibri_t20",
+                    "nvidia,tegra20";
+
+       aliases {
+               rtc0 = "/i2c@7000c000/rtc@68";
+               rtc1 = "/i2c@7000d000/pmic@34";
+               rtc2 = "/rtc@7000e000";
+               serial0 = &uarta;
+               serial1 = &uartd;
+               serial2 = &uartb;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       host1x@50000000 {
+               dc@54200000 {
+                       rgb {
+                               status = "okay";
+                               nvidia,panel = <&panel>;
+                       };
+               };
+
+               hdmi@54280000 {
+                       status = "okay";
+                       hdmi-supply = <&reg_5v0>;
+               };
+       };
+
+       pinmux@70000014 {
+               state_default: pinmux {
+                       bl-on {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       ddc {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       hotplug-detect {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       i2c {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       lcd {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       lm1 {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       mmc {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       mmccd {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       pwm-a-b {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       pwm-c-d {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       ssp {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       uart-a {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       uart-b {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       uart-c {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       usbh-pen {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+               };
+       };
+
+       /* Colibri UART-A */
+       serial@70006000 {
+               status = "okay";
+       };
+
+       /* Colibri UART-C */
+       serial@70006040 {
+               status = "okay";
+       };
+
+       /* Colibri UART-B */
+       serial@70006300 {
+               status = "okay";
+       };
+
+       pwm@7000a000 {
+               status = "okay";
+       };
+
+       /*
+        * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
+        * board)
+        */
+       i2c@7000c000 {
+               status = "okay";
+               clock-frequency = <400000>;
+
+               /* M41T0M6 real time clock on carrier board */
+               rtc@68 {
+                       compatible = "st,m41t0";
+                       reg = <0x68>;
+               };
+       };
+
+       /* GEN2_I2C: unused */
+
+       /* CAM_I2C (I2C3): unused */
+
+       /* DDC_CLOCK/DATA on X3 pin 15/16 (e.g. display EDID) */
+       i2c@7000c400 {
+               status = "okay";
+       };
+
+       /* EHCI instance 0: USB1_DP/N -> USBC_P/N */
+       usb@c5000000 {
+               status = "okay";
+               dr_mode = "otg";
+       };
+
+       usb-phy@c5000000 {
+               status = "okay";
+               vbus-supply = <&reg_usbc_vbus>;
+       };
+
+       /* EHCI instance 2: USB3_DP/N -> USBH_P/N */
+       usb@c5008000 {
+               status = "okay";
+       };
+
+       usb-phy@c5008000 {
+               status = "okay";
+               vbus-supply = <&reg_usbh_vbus>;
+       };
+
+       /* SPI4: Colibri SSP */
+       spi@7000da00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+
+               can@0 {
+                       compatible = "microchip,mcp2515";
+                       reg = <0>;
+                       clocks = <&clk16m>;
+                       interrupt-parent = <&gpio>;
+                       /* CAN_INT */
+                       interrupts = <TEGRA_GPIO(A, 0) IRQ_TYPE_EDGE_FALLING>;
+                       spi-max-frequency = <10000000>;
+                       vdd-supply = <&reg_3v3>;
+                       xceiver-supply = <&reg_5v0>;
+               };
+       };
+
+       /* SD/MMC */
+       sdhci@c8000600 {
+               status = "okay";
+               bus-width = <4>;
+               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; /* MMCD */
+               no-1-8-v;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <255 128 64 32 16 8 4 0>;
+               default-brightness-level = <6>;
+               /* BL_ON */
+               enable-gpios = <&gpio TEGRA_GPIO(T, 4) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 0 5000000>; /* PWM<A> */
+       };
+
+       clk16m: osc3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <16000000>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               wakeup {
+                       label = "SODIMM pin 45 wakeup";
+                       gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_WAKEUP>;
+                       debounce-interval = <10>;
+                       wakeup-source;
+               };
+       };
+
+       panel: panel {
+               /*
+                * edt,et057090dhu: EDT 5.7" LCD TFT
+                * edt,et070080dh6: EDT 7.0" LCD TFT
+                */
+               compatible = "edt,et057090dhu", "simple-panel";
+               backlight = <&backlight>;
+               power-supply = <&reg_3v3>;
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_5v0: regulator-5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "5V_SW";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       reg_usbc_vbus: regulator-usbc-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USB5";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&reg_5v0>;
+       };
+
+       /* USBH_PEN resp. USB_P_EN */
+       reg_usbh_vbus: regulator-usbh-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USB[1-4]";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
+               vin-supply = <&reg_5v0>;
+       };
+};
index 57f16c0e9917ed0ac85e75432b2563e205767797..d8004d68efa0d422fb2e3214b9d39a62f25571ad 100644 (file)
@@ -1,15 +1,21 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
 #include "tegra20-colibri.dtsi"
 
 / {
-       model = "Toradex Colibri T20 256/512 MB on Iris";
-       compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20";
+       model = "Toradex Colibri T20 on Iris";
+       compatible = "toradex,colibri_t20-iris", "toradex,colibri_t20",
+                    "nvidia,tegra20";
 
        aliases {
+               rtc0 = "/i2c@7000c000/rtc@68";
+               rtc1 = "/i2c@7000d000/pmic@34";
+               rtc2 = "/rtc@7000e000";
                serial0 = &uarta;
                serial1 = &uartd;
+               serial2 = &uartb;
        };
 
        chosen {
        };
 
        host1x@50000000 {
+               dc@54200000 {
+                       rgb {
+                               status = "okay";
+                               nvidia,panel = <&panel>;
+                       };
+               };
+
                hdmi@54280000 {
                        status = "okay";
+                       hdmi-supply = <&reg_5v0>;
                };
        };
 
        pinmux@70000014 {
                state_default: pinmux {
-                       hdint {
+                       bl-on {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       ddc {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       hotplug-detect {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       i2c {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       lcd {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       lm1 {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       mmc {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       mmccd {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       pwm-a-b {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       pwm-c-d {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       ssp {
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       i2cddc {
+                       uart-a {
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       sdio4 {
+                       uart-b {
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       uarta {
+                       uart-c {
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       uartd {
+                       usbh-pen {
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
                };
        };
 
+       /* Colibri UART-A */
        serial@70006000 {
                status = "okay";
        };
 
+       /* Colibri UART-C */
+       serial@70006040 {
+               status = "okay";
+       };
+
+       /* Colibri UART-B */
        serial@70006300 {
                status = "okay";
        };
 
-       i2c_ddc: i2c@7000c400 {
+       pwm@7000a000 {
+               status = "okay";
+       };
+
+       /*
+        * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
+        * board)
+        */
+       i2c@7000c000 {
+               status = "okay";
+               clock-frequency = <400000>;
+
+               /* M41T0M6 real time clock on carrier board */
+               rtc@68 {
+                       compatible = "st,m41t0";
+                       reg = <0x68>;
+               };
+       };
+
+       /* GEN2_I2C: unused */
+
+       /* CAM_I2C (I2C3): unused */
+
+       /* DDC_CLOCK/DATA on X3 pin 15/16 (e.g. display EDID) */
+       i2c@7000c400 {
                status = "okay";
        };
 
+       /* EHCI instance 0: USB1_DP/N -> USBC_P/N */
        usb@c5000000 {
                status = "okay";
+               dr_mode = "otg";
        };
 
        usb-phy@c5000000 {
                status = "okay";
+               vbus-supply = <&reg_usbc_vbus>;
        };
 
+       /* EHCI instance 2: USB3_DP/N -> USBH_P/N */
        usb@c5008000 {
                status = "okay";
        };
 
        usb-phy@c5008000 {
                status = "okay";
+               vbus-supply = <&reg_usbh_vbus>;
+       };
+
+       /* SPI4: Colibri SSP */
+       spi@7000da00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
        };
 
+       /* SD/MMC */
        sdhci@c8000600 {
                status = "okay";
                bus-width = <4>;
-               vmmc-supply = <&vcc_sd_reg>;
-               vqmmc-supply = <&vcc_sd_reg>;
-       };
-
-       regulators {
-               regulator@0 {
-                       compatible = "regulator-fixed";
-                       reg = <0>;
-                       regulator-name = "usb_host_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       regulator-boot-on;
-                       regulator-always-on;
-                       gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
-               };
+               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; /* MMCD */
+               no-1-8-v;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <255 128 64 32 16 8 4 0>;
+               default-brightness-level = <6>;
+               /* BL_ON */
+               enable-gpios = <&gpio TEGRA_GPIO(T, 4) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 0 5000000>; /* PWM<A> */
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
 
-               vcc_sd_reg: regulator@1 {
-                       compatible = "regulator-fixed";
-                       reg = <1>;
-                       regulator-name = "vcc_sd";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-boot-on;
-                       regulator-always-on;
+               wakeup {
+                       label = "SODIMM pin 45 wakeup";
+                       gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+                       linux,code = <KEY_WAKEUP>;
+                       debounce-interval = <10>;
+                       wakeup-source;
                };
        };
+
+       panel: panel {
+               /*
+                * edt,et057090dhu: EDT 5.7" LCD TFT
+                * edt,et070080dh6: EDT 7.0" LCD TFT
+                */
+               compatible = "edt,et057090dhu", "simple-panel";
+               backlight = <&backlight>;
+               power-supply = <&reg_3v3>;
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_5v0: regulator-5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       reg_usbc_vbus: regulator-usbc-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USB2";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&reg_5v0>;
+       };
+
+       /* USBH_PEN resp. USB_P_EN */
+       reg_usbh_vbus: regulator-usbh-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USB1";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
+               vin-supply = <&reg_5v0>;
+       };
 };
index e7b9ab09908a1af6212cb9c59d9f2136849c1427..6162d193e12cd0b24ecd140254bcd95c724a22fc 100644 (file)
@@ -1,15 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "tegra20.dtsi"
 
+/*
+ * Toradex Colibri T20 Module Device Tree
+ * Compatible for Revisions Colibri T20 256MB V1.1B, V1.2A;
+ * Colibri T20 256MB IT V1.2A; Colibri T20 512MB V1.1C, V1.2A;
+ * Colibri T20 512MB IT V1.2A
+ */
 / {
-       model = "Toradex Colibri T20 256/512 MB";
-       compatible = "toradex,colibri_t20-512", "nvidia,tegra20";
-
-       aliases {
-               rtc0 = "/i2c@7000d000/tps6586x@34";
-               rtc1 = "/rtc@7000e000";
-       };
-
        memory@0 {
                /*
                 * Set memory to 256 MB to be safe as this could be used on
 
        host1x@50000000 {
                hdmi@54280000 {
-                       vdd-supply = <&hdmi_vdd_reg>;
-                       pll-supply = <&hdmi_pll_reg>;
-
-                       nvidia,ddc-i2c-bus = <&i2c_ddc>;
-                       nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
-                               GPIO_ACTIVE_HIGH>;
+                       nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+                       nvidia,hpd-gpio =
+                               <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+                       pll-supply = <&reg_1v8_avdd_hdmi_pll>;
+                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                };
        };
 
                pinctrl-0 = <&state_default>;
 
                state_default: pinmux {
-                       audio_refclk {
+                       /* Analogue Audio AC97 to WM9712 (On-module) */
+                       audio-refclk {
                                nvidia,pins = "cdev1";
                                nvidia,function = "plla_out";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       crt {
-                               nvidia,pins = "crtp";
-                               nvidia,function = "crt";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
                        dap3 {
                                nvidia,pins = "dap3";
                                nvidia,function = "dap3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       displaya {
-                               nvidia,pins = "ld0", "ld1", "ld2", "ld3",
-                                       "ld4", "ld5", "ld6", "ld7", "ld8",
-                                       "ld9", "ld10", "ld11", "ld12", "ld13",
-                                       "ld14", "ld15", "ld16", "ld17",
-                                       "lhs", "lpw0", "lpw2", "lsc0",
-                                       "lsc1", "lsck", "lsda", "lspi", "lvs";
-                               nvidia,function = "displaya";
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       gpio_dte {
-                               nvidia,pins = "dte";
-                               nvidia,function = "rsvd1";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       gpio_gmi {
-                               nvidia,pins = "ata", "atc", "atd", "ate",
-                                       "dap1", "dap2", "dap4", "gpu", "irrx",
-                                       "irtx", "spia", "spib", "spic";
-                               nvidia,function = "gmi";
+
+                       /*
+                        * AC97_RESET, ULPI_RESET, AC97_INT aka WM9712 GENIRQ
+                        * (All on-module), SODIMM Pin 45 Wakeup
+                        */
+                       gpio-uac {
+                               nvidia,pins = "uac";
+                               nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_pta {
+
+                       /*
+                        * Buffer Enables for nPWE and RDnWR (On-module,
+                        * see GPIO hogging further down below)
+                        */
+                       gpio-pta {
                                nvidia,pins = "pta";
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       gpio_uac {
-                               nvidia,pins = "uac";
-                               nvidia,function = "rsvd2";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+
+                       /*
+                        * CLK_32K_OUT, CORE_PWR_REQ, CPU_PWR_REQ, PWR_INT_N,
+                        * SYS_CLK_REQ (All on-module)
+                        */
+                       pmc {
+                               nvidia,pins = "pmc";
+                               nvidia,function = "pwr_on";
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       hdint {
-                               nvidia,pins = "hdint";
+
+                       /*
+                        * Colibri Address/Data Bus (GMI)
+                        * Note: spid and spie optionally used for SPI1
+                        */
+                       gmi {
+                               nvidia,pins = "atc", "atd", "ate", "dap1",
+                                             "dap2", "dap4", "gmd", "gpu",
+                                             "irrx", "irtx", "spia", "spib",
+                                             "spic", "spid", "spie", "uca",
+                                             "ucb";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Further pins may be used as GPIOs */
+                       gmi-gpio1 {
+                               nvidia,pins = "lpw0", "lsc1", "lsck", "lsda";
                                nvidia,function = "hdmi";
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       i2c1 {
-                               nvidia,pins = "rm";
-                               nvidia,function = "i2c1";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                       gmi-gpio2 {
+                               nvidia,pins = "lcsn", "ldc", "lm0", "lsdi";
+                               nvidia,function = "rsvd4";
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       i2c3 {
-                               nvidia,pins = "dtf";
-                               nvidia,function = "i2c3";
+
+                       /* Colibri BL_ON */
+                       bl-on {
+                               nvidia,pins = "dta";
+                               nvidia,function = "rsvd1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       i2cddc {
+
+                       /* Colibri Backlight PWM<A>, PWM<B> */
+                       pwm-a-b {
+                               nvidia,pins = "sdc";
+                               nvidia,function = "pwm";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri DDC */
+                       ddc {
                                nvidia,pins = "ddc";
                                nvidia,function = "i2c2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       i2cp {
-                               nvidia,pins = "i2cp";
-                               nvidia,function = "i2cp";
+
+                       /*
+                        * Colibri EXT_IO*
+                        * Note: dtf optionally used for I2C3
+                        */
+                       ext-io {
+                               nvidia,pins = "dtf", "spdi";
+                               nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       irda {
-                               nvidia,pins = "uad";
-                               nvidia,function = "irda";
+
+                       /*
+                        * Colibri Ethernet (On-module)
+                        * ULPI EHCI instance 1 USB2_DP/N -> AX88772B
+                        */
+                       ulpi {
+                               nvidia,pins = "uaa", "uab", "uda";
+                               nvidia,function = "ulpi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       nand {
-                               nvidia,pins = "kbca", "kbcc", "kbcd",
-                                       "kbce", "kbcf";
-                               nvidia,function = "nand";
+                       ulpi-refclk {
+                               nvidia,pins = "cdev2";
+                               nvidia,function = "pllp_out4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       owc {
-                               nvidia,pins = "owc";
-                               nvidia,function = "owr";
+
+                       /* Colibri HOTPLUG_DETECT (HDMI) */
+                       hotplug-detect {
+                               nvidia,pins = "hdint";
+                               nvidia,function = "hdmi";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri I2C */
+                       i2c {
+                               nvidia,pins = "rm";
+                               nvidia,function = "i2c1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       pmc {
-                               nvidia,pins = "pmc";
-                               nvidia,function = "pwr_on";
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+
+                       /*
+                        * Colibri L_BIAS, LCD_M1 is muxed with LCD_DE
+                        * today's display need DE, disable LCD_M1
+                        */
+                       lm1 {
+                               nvidia,pins = "lm1";
+                               nvidia,function = "rsvd3";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       pwm {
-                               nvidia,pins = "sdb", "sdc", "sdd";
-                               nvidia,function = "pwm";
+
+                       /* Colibri LCD (L_* resp. LDD<*>) */
+                       lcd {
+                               nvidia,pins = "ld0", "ld1", "ld2", "ld3",
+                                             "ld4", "ld5", "ld6", "ld7",
+                                             "ld8", "ld9", "ld10", "ld11",
+                                             "ld12", "ld13", "ld14", "ld15",
+                                             "ld16", "ld17", "lhs", "lsc0",
+                                             "lspi", "lvs";
+                               nvidia,function = "displaya";
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       sdio4 {
-                               nvidia,pins = "atb", "gma", "gme";
+                       /* Colibri LCD (Optional 24 BPP Support) */
+                       lcd-24 {
+                               nvidia,pins = "ldi", "lhp0", "lhp1", "lhp2",
+                                             "lpp", "lvp1";
+                               nvidia,function = "displaya";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri MMC */
+                       mmc {
+                               nvidia,pins = "atb", "gma";
                                nvidia,function = "sdio4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       spi1 {
-                               nvidia,pins = "spid", "spie", "spif";
-                               nvidia,function = "spi1";
+
+                       /* Colibri MMCCD */
+                       mmccd {
+                               nvidia,pins = "gmb";
+                               nvidia,function = "gmi_int";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       spi4 {
+
+                       /* Colibri MMC (Optional 8-bit) */
+                       mmc-8bit {
+                               nvidia,pins = "gme";
+                               nvidia,function = "sdio4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /*
+                        * Colibri Parallel Camera (Optional)
+                        * pins multiplexed with others and therefore disabled
+                        * Note: dta used for BL_ON by default
+                        */
+                       cif-mclk {
+                               nvidia,pins = "csus";
+                               nvidia,function = "vi_sensor_clk";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       cif {
+                               nvidia,pins = "dtb", "dtc", "dtd";
+                               nvidia,function = "vi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri PWM<C>, PWM<D> */
+                       pwm-c-d {
+                               nvidia,pins = "sdb", "sdd";
+                               nvidia,function = "pwm";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri SSP */
+                       ssp {
                                nvidia,pins = "slxa", "slxc", "slxd", "slxk";
                                nvidia,function = "spi4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       uarta {
+
+                       /* Colibri UART-A */
+                       uart-a {
                                nvidia,pins = "sdio1";
                                nvidia,function = "uarta";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       uartd {
+                       uart-a-dsr {
+                               nvidia,pins = "lpw1";
+                               nvidia,function = "rsvd3";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       uart-a-dcd {
+                               nvidia,pins = "lpw2";
+                               nvidia,function = "hdmi";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri UART-B */
+                       uart-b {
                                nvidia,pins = "gmc";
                                nvidia,function = "uartd";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       ulpi {
-                               nvidia,pins = "uaa", "uab", "uda";
-                               nvidia,function = "ulpi";
+
+                       /* Colibri UART-C */
+                       uart-c {
+                               nvidia,pins = "uad";
+                               nvidia,function = "irda";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri USB_CDET */
+                       usb-cdet {
+                               nvidia,pins = "spdo";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri USBH_OC */
+                       usbh-oc {
+                               nvidia,pins = "spih";
+                               nvidia,function = "spi2_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri USBH_PEN */
+                       usbh-pen {
+                               nvidia,pins = "spig";
+                               nvidia,function = "spi2_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri VGA not supported */
+                       vga {
+                               nvidia,pins = "crtp";
+                               nvidia,function = "crt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* I2C3 (Optional) */
+                       i2c3 {
+                               nvidia,pins = "dtf";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* JTAG_RTCK */
+                       jtag-rtck {
+                               nvidia,pins = "gpu7";
+                               nvidia,function = "rtck";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /*
+                        * LAN_RESET, LAN_EXT_WAKEUP and LAN_PME
+                        * (All On-module)
+                        */
+                       gpio-gpv {
+                               nvidia,pins = "gpv";
+                               nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       ulpi_refclk {
-                               nvidia,pins = "cdev2";
-                               nvidia,function = "pllp_out4";
+
+                       /*
+                        * LAN_V_BUS, VDD_FAULT, BATT_FAULT, WM9712 PENDOWN
+                        * (All On-module); Colibri CAN_INT
+                        */
+                       gpio-dte {
+                               nvidia,pins = "dte";
+                               nvidia,function = "rsvd1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       usb_gpio {
-                               nvidia,pins = "spig", "spih";
-                               nvidia,function = "spi2_alt";
+
+                       /* NAND (On-module) */
+                       nand {
+                               nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+                                             "kbce", "kbcf";
+                               nvidia,function = "nand";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       vi {
-                               nvidia,pins = "dta", "dtb", "dtc", "dtd";
-                               nvidia,function = "vi";
+
+                       /* Onewire (Optional) */
+                       owr {
+                               nvidia,pins = "owc";
+                               nvidia,function = "owr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
-                       vi_sc {
-                               nvidia,pins = "csus";
-                               nvidia,function = "vi_sensor_clk";
+
+                       /* Power I2C (On-module) */
+                       i2cp {
+                               nvidia,pins = "i2cp";
+                               nvidia,function = "i2cp";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* RESET_OUT */
+                       reset-out {
+                               nvidia,pins = "ata";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /*
+                        * SPI1 (Optional)
+                        * Note: spid and spie used for Colibri Address/Data
+                        *       Bus (GMI)
+                        */
+                       spi1 {
+                               nvidia,pins = "spid", "spie", "spif";
+                               nvidia,function = "spi1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
                        };
+
+                       /*
+                        * THERMD_ALERT# (On-module), unlatched I2C address pin
+                        * of LM95245 temperature sensor therefore requires
+                        * disabling for now
+                        */
+                       lvp0 {
+                               nvidia,pins = "lvp0";
+                               nvidia,function = "rsvd3";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
                };
        };
 
-       ac97: ac97@70002000 {
+       tegra_ac97: ac97@70002000 {
                status = "okay";
-               nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
-                       GPIO_ACTIVE_HIGH>;
-               nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
-                       GPIO_ACTIVE_HIGH>;
+               nvidia,codec-reset-gpio =
+                       <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_HIGH>;
+               nvidia,codec-sync-gpio =
+                       <&gpio TEGRA_GPIO(P, 0) GPIO_ACTIVE_HIGH>;
+       };
+
+       serial@70006040 {
+               compatible = "nvidia,tegra20-hsuart";
+       };
+
+       serial@70006300 {
+               compatible = "nvidia,tegra20-hsuart";
        };
 
        nand-controller@70008000 {
        };
 
        /* DDC_SCL/SDA on X3 pin 15/16 (e.g. display EDID) */
-       i2c_ddc: i2c@7000c400 {
+       hdmi_ddc: i2c@7000c400 {
                clock-frequency = <10000>;
        };
 
                status = "okay";
                clock-frequency = <100000>;
 
-               pmic: tps6586x@34 {
+               pmic@34 {
                        compatible = "ti,tps6586x";
                        reg = <0x34>;
                        interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-
                        ti,system-power-controller;
-
                        #gpio-cells = <2>;
                        gpio-controller;
-
-                       sys-supply = <&vdd_3v3_reg>;
-                       vin-sm0-supply = <&sys_reg>;
-                       vin-sm1-supply = <&sys_reg>;
-                       vin-sm2-supply = <&sys_reg>;
-                       vinldo01-supply = <&sm2_reg>;
-                       vinldo23-supply = <&vdd_3v3_reg>;
-                       vinldo4-supply = <&vdd_3v3_reg>;
-                       vinldo678-supply = <&vdd_3v3_reg>;
-                       vinldo9-supply = <&vdd_3v3_reg>;
+                       sys-supply = <&reg_module_3v3>;
+                       vin-sm0-supply = <&reg_3v3_vsys>;
+                       vin-sm1-supply = <&reg_3v3_vsys>;
+                       vin-sm2-supply = <&reg_3v3_vsys>;
+                       vinldo01-supply = <&reg_1v8_vdd_ddr2>;
+                       vinldo23-supply = <&reg_module_3v3>;
+                       vinldo4-supply = <&reg_module_3v3>;
+                       vinldo678-supply = <&reg_module_3v3>;
+                       vinldo9-supply = <&reg_module_3v3>;
 
                        regulators {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               sys_reg: regulator@0 {
-                                       reg = <0>;
-                                       regulator-compatible = "sys";
-                                       regulator-name = "vdd_sys";
+                               reg_3v3_vsys: sys {
+                                       regulator-name = "VSYS_3.3V";
                                        regulator-always-on;
                                };
 
-                               regulator@1 {
-                                       reg = <1>;
-                                       regulator-compatible = "sm0";
-                                       regulator-name = "vdd_sm0,vdd_core";
+                               sm0 {
+                                       regulator-name = "VDD_CORE_1.2V";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                };
 
-                               regulator@2 {
-                                       reg = <2>;
-                                       regulator-compatible = "sm1";
-                                       regulator-name = "vdd_sm1,vdd_cpu";
+                               sm1 {
+                                       regulator-name = "VDD_CPU_1.0V";
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1000000>;
                                        regulator-always-on;
                                };
 
-                               sm2_reg: regulator@3 {
-                                       reg = <3>;
-                                       regulator-compatible = "sm2";
-                                       regulator-name = "vdd_sm2,vin_ldo*";
+                               reg_1v8_vdd_ddr2: sm2 {
+                                       regulator-name = "VDD_DDR2_1.8V";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
 
                                /* LDO0 is not connected to anything */
 
-                               regulator@5 {
-                                       reg = <5>;
-                                       regulator-compatible = "ldo1";
-                                       regulator-name = "vdd_ldo1,avdd_pll*";
+                               /*
+                                * +3.3V_ENABLE_N switching via FET:
+                                * AVDD_AUDIO_S and +3.3V
+                                * see also +3.3V fixed supply
+                                */
+                               ldo1 {
+                                       regulator-name = "AVDD_PLL_1.1V";
                                        regulator-min-microvolt = <1100000>;
                                        regulator-max-microvolt = <1100000>;
                                        regulator-always-on;
                                };
 
-                               regulator@6 {
-                                       reg = <6>;
-                                       regulator-compatible = "ldo2";
-                                       regulator-name = "vdd_ldo2,vdd_rtc";
+                               ldo2 {
+                                       regulator-name = "VDD_RTC_1.2V";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                };
 
                                /* LDO3 is not connected to anything */
 
-                               regulator@8 {
-                                       reg = <8>;
-                                       regulator-compatible = "ldo4";
-                                       regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+                               ldo4 {
+                                       regulator-name = "VDDIO_SYS_1.8V";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
                                };
 
-                               ldo5_reg: regulator@9 {
-                                       reg = <9>;
-                                       regulator-compatible = "ldo5";
-                                       regulator-name = "vdd_ldo5,vdd_fuse";
+                               /* Switched via FET from regular +3.3V */
+                               ldo5 {
+                                       regulator-name = "+3.3V_USB";
                                        regulator-min-microvolt = <3300000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-always-on;
                                };
 
-                               regulator@10 {
-                                       reg = <10>;
-                                       regulator-compatible = "ldo6";
-                                       regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
+                               ldo6 {
+                                       regulator-name = "AVDD_VDAC_2.85V";
                                        regulator-min-microvolt = <2850000>;
                                        regulator-max-microvolt = <2850000>;
                                };
 
-                               hdmi_vdd_reg: regulator@11 {
-                                       reg = <11>;
-                                       regulator-compatible = "ldo7";
-                                       regulator-name = "vdd_ldo7,avdd_hdmi";
+                               reg_3v3_avdd_hdmi: ldo7 {
+                                       regulator-name = "AVDD_HDMI_3.3V";
                                        regulator-min-microvolt = <3300000>;
                                        regulator-max-microvolt = <3300000>;
                                };
 
-                               hdmi_pll_reg: regulator@12 {
-                                       reg = <12>;
-                                       regulator-compatible = "ldo8";
-                                       regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+                               reg_1v8_avdd_hdmi_pll: ldo8 {
+                                       regulator-name = "AVDD_HDMI_PLL_1.8V";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                };
 
-                               regulator@13 {
-                                       reg = <13>;
-                                       regulator-compatible = "ldo9";
-                                       regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
+                               ldo9 {
+                                       regulator-name = "VDDIO_RX_DDR_2.85V";
                                        regulator-min-microvolt = <2850000>;
                                        regulator-max-microvolt = <2850000>;
                                        regulator-always-on;
                                };
 
-                               regulator@14 {
-                                       reg = <14>;
-                                       regulator-compatible = "ldo_rtc";
-                                       regulator-name = "vdd_rtc_out,vdd_cell";
+                               ldo_rtc {
+                                       regulator-name = "VCC_BATT";
                                        regulator-min-microvolt = <3300000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-always-on;
                        };
                };
 
-               temperature-sensor@4c {
+               /* LM95245 temperature sensor */
+               temp-sensor@4c {
                        compatible = "national,lm95245";
                        reg = <0x4c>;
                };
                nvidia,core-pwr-good-time = <3845 3845>;
                nvidia,core-pwr-off-time = <3875>;
                nvidia,sys-clock-req-active-high;
+
+               /* Set SLEEP MODE bit in SUPPLYENE register of TPS658643 PMIC */
+               i2c-thermtrip {
+                       nvidia,i2c-controller-id = <3>;
+                       nvidia,bus-addr = <0x34>;
+                       nvidia,reg-addr = <0x14>;
+                       nvidia,reg-data = <0x8>;
+               };
        };
 
        memory-controller@7000f400 {
                };
        };
 
+       /* EHCI instance 1: ULPI PHY -> AX88772B (On-module) */
        usb@c5004000 {
                status = "okay";
-               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
-                       GPIO_ACTIVE_LOW>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               asix@1 {
+                       reg = <1>;
+                       local-mac-address = [00 00 00 00 00 00];
+               };
        };
 
        usb-phy@c5004000 {
                status = "okay";
-               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
-                       GPIO_ACTIVE_LOW>;
+               nvidia,phy-reset-gpio =
+                       <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_LOW>;
+               vbus-supply = <&reg_lan_v_bus>;
        };
 
-       sdhci@c8000600 {
-               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+       clk32k_in: xtal3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
        };
 
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               clk32k_in: clock@0 {
-                       compatible = "fixed-clock";
-                       reg = <0>;
-                       #clock-cells = <0>;
-                       clock-frequency = <32768>;
-               };
+       reg_lan_v_bus: regulator-lan-v-bus {
+               compatible = "regulator-fixed";
+               regulator-name = "LAN_V_BUS";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
        };
 
-       regulators {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               vdd_3v3_reg: regulator@100 {
-                       compatible = "regulator-fixed";
-                       reg = <100>;
-                       regulator-name = "vdd_3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-always-on;
-               };
-
-               regulator@101 {
-                       compatible = "regulator-fixed";
-                       reg = <101>;
-                       regulator-name = "internal_usb";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       enable-active-high;
-                       regulator-boot-on;
-                       regulator-always-on;
-                       gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
-               };
+       reg_module_3v3: regulator-module-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
        };
 
        sound {
                compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
-                                "nvidia,tegra-audio-wm9712";
-               nvidia,model = "Colibri T20 AC97 Audio";
-
+                            "nvidia,tegra-audio-wm9712";
+               nvidia,model = "Toradex Colibri T20";
                nvidia,audio-routing =
                        "Headphone", "HPOUTL",
                        "Headphone", "HPOUTR",
                        "LineIn", "LINEINL",
                        "LineIn", "LINEINR",
                        "Mic", "MIC1";
-
-               nvidia,ac97-controller = <&ac97>;
-
+               nvidia,ac97-controller = <&tegra_ac97>;
                clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
                         <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
                         <&tegra_car TEGRA20_CLK_CDEV1>;
                clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
+
+&gpio {
+       lan-reset-n {
+               gpio-hog;
+               gpios = <TEGRA_GPIO(V, 4) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "LAN_RESET#";
+       };
+
+       /* Tri-stating GMI_WR_N on SODIMM pin 99 nPWE */
+       npwe {
+               gpio-hog;
+               gpios = <TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "Tri-state nPWE";
+       };
+
+       /* Not tri-stating GMI_WR_N on SODIMM pin 93 RDnWR */
+       rdnwr {
+               gpio-hog;
+               gpios = <TEGRA_GPIO(T, 6) GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "Not tri-state RDnWR";
+       };
+};
index ef245291924f076d73aec01d5ad0f68db0e92589..8861e0976e3759a0e5c437c086afa0664a1e3fa0 100644 (file)
                request-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
                slave-addr = <138>;
                clocks = <&tegra_car TEGRA20_CLK_I2C3>,
-                        <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
+                        <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
                clock-names = "div-clk", "fast-clk";
                resets = <&tegra_car 67>;
                reset-names = "i2c";
        gpio-keys {
                compatible = "gpio-keys";
 
-               power {
-                       label = "Power";
+               wakeup {
+                       label = "Wakeup";
                        gpios = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_LOW>;
-                       linux,code = <KEY_POWER>;
+                       linux,code = <KEY_WAKEUP>;
                        wakeup-source;
                };
        };
                        GPIO_ACTIVE_HIGH>;
 
                clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
-                        <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
-                        <&tegra_car TEGRA20_CLK_CDEV1>;
+                        <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+                        <&tegra_car TEGRA20_CLK_CDEV1>;
                clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 15b73bd377f0408b948f80b36a4afaff82f14688..20869757d32f46f9fa264e83f86724d22284dc91 100644 (file)
                status = "disabled";
        };
 
-       gmi@70009000 {
-               compatible = "nvidia,tegra20-gmi";
-               reg = <0x70009000 0x1000>;
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0xd0000000 0xfffffff>;
-               clocks = <&tegra_car TEGRA20_CLK_NOR>;
-               clock-names = "gmi";
-               resets = <&tegra_car 42>;
-               reset-names = "gmi";
-               status = "disabled";
-       };
-
        nand-controller@70008000 {
                compatible = "nvidia,tegra20-nand";
                reg = <0x70008000 0x100>;
                status = "disabled";
        };
 
+       gmi@70009000 {
+               compatible = "nvidia,tegra20-gmi";
+               reg = <0x70009000 0x1000>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <0 0 0xd0000000 0xfffffff>;
+               clocks = <&tegra_car TEGRA20_CLK_NOR>;
+               clock-names = "gmi";
+               resets = <&tegra_car 42>;
+               reset-names = "gmi";
+               status = "disabled";
+       };
+
        pwm: pwm@7000a000 {
                compatible = "nvidia,tegra20-pwm";
                reg = <0x7000a000 0x100>;
                compatible = "arm,cortex-a9-pmu";
                interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&{/cpus/cpu@0}>,
+                                    <&{/cpus/cpu@1}>;
        };
 };
index 0dc85a20bd4535ccfe5945a2194a9e0dee5d3f9c..749fc6d1ff70e8e8b47b216d1152a1d5fe964919 100644 (file)
@@ -6,11 +6,12 @@
 
 / {
        model = "Toradex Apalis T30 on Apalis Evaluation Board";
-       compatible = "toradex,apalis_t30-eval", "toradex,apalis_t30", "nvidia,tegra30";
+       compatible = "toradex,apalis_t30-eval", "toradex,apalis_t30",
+                    "nvidia,tegra30";
 
        aliases {
                rtc0 = "/i2c@7000c000/rtc@68";
-               rtc1 = "/i2c@7000d000/tps65911@2d";
+               rtc1 = "/i2c@7000d000/pmic@2d";
                rtc2 = "/rtc@7000e000";
                serial0 = &uarta;
                serial1 = &uartb;
@@ -23,8 +24,6 @@
        };
 
        pcie@3000 {
-               status = "okay";
-
                pci@1,0 {
                        status = "okay";
                };
                pci@2,0 {
                        status = "okay";
                };
-
-               pci@3,0 {
-                       status = "okay";
-               };
        };
 
        host1x@50000000 {
                                nvidia,panel = <&panel>;
                        };
                };
+
                hdmi@54280000 {
                        status = "okay";
+                       hdmi-supply = <&reg_5v0>;
                };
        };
 
+       /* Apalis UART1 */
        serial@70006000 {
                status = "okay";
        };
 
+       /* Apalis UART2 */
        serial@70006040 {
-               compatible = "nvidia,tegra30-hsuart";
                status = "okay";
        };
 
+       /* Apalis UART3 */
        serial@70006200 {
-               compatible = "nvidia,tegra30-hsuart";
                status = "okay";
        };
 
+       /* Apalis UART4 */
        serial@70006300 {
-               compatible = "nvidia,tegra30-hsuart";
                status = "okay";
        };
 
         * CAM_I2C: I2C3_SDA/SCL on MXM3 pin 201/203 (e.g. camera sensor on
         * carrier board)
         */
-       cami2c: i2c@7000c500 {
+       i2c@7000c500 {
                status = "okay";
                clock-frequency = <400000>;
        };
 
        /* DDC: I2C2_SDA/SCL on MXM3 pin 205/207 (e.g. display EDID) */
-       hdmiddc: i2c@7000c700 {
+       i2c@7000c700 {
                status = "okay";
        };
 
        spi@7000d400 {
                status = "okay";
                spi-max-frequency = <25000000>;
-               spidev0: spidev@1 {
-                       compatible = "spidev";
-                       reg = <1>;
-                       spi-max-frequency = <25000000>;
-               };
        };
 
        /* SPI5: Apalis SPI2 */
        spi@7000dc00 {
                status = "okay";
                spi-max-frequency = <25000000>;
-               spidev1: spidev@2 {
-                       compatible = "spidev";
-                       reg = <2>;
-                       spi-max-frequency = <25000000>;
-               };
-       };
-
-       hda@70030000 {
-               status = "okay";
        };
 
-       sd1: sdhci@78000000 {
+       /* Apalis SD1 */
+       sdhci@78000000 {
                status = "okay";
                bus-width = <4>;
                /* SD1_CD# */
                no-1-8-v;
        };
 
-       mmc1: sdhci@78000400 {
+       /* Apalis MMC1 */
+       sdhci@78000400 {
                status = "okay";
                bus-width = <8>;
                /* MMC1_CD# */
        /* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */
        usb@7d000000 {
                status = "okay";
+               dr_mode = "otg";
        };
 
        usb-phy@7d000000 {
                status = "okay";
-               dr_mode = "otg";
-               vbus-supply = <&usbo1_vbus_reg>;
+               vbus-supply = <&reg_usbo1_vbus>;
        };
 
        /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */
 
        usb-phy@7d004000 {
                status = "okay";
-               vbus-supply = <&usbh_vbus_reg>;
+               vbus-supply = <&reg_usbh_vbus>;
        };
 
        /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */
 
        usb-phy@7d008000 {
                status = "okay";
-               vbus-supply = <&usbh_vbus_reg>;
+               vbus-supply = <&reg_usbh_vbus>;
        };
 
        backlight: backlight {
                compatible = "pwm-backlight";
-
-               /* PWM_BKL1 */
-               pwms = <&pwm 0 5000000>;
                brightness-levels = <255 231 223 207 191 159 127 0>;
                default-brightness-level = <6>;
                /* BKL1_ON */
                enable-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 0 5000000>; /* BKL1_PWM */
        };
 
        gpio-keys {
                 * edt,et070080dh6: EDT 7.0" LCD TFT
                 */
                compatible = "edt,et057090dhu", "simple-panel";
-
                backlight = <&backlight>;
+               power-supply = <&reg_3v3>;
        };
 
-       pwmleds {
-               compatible = "pwm-leds";
-
-               pwm1 {
-                       label = "PWM1";
-                       pwms = <&pwm 3 19600>;
-                       max-brightness = <255>;
-               };
-
-               pwm2 {
-                       label = "PWM2";
-                       pwms = <&pwm 2 19600>;
-                       max-brightness = <255>;
-               };
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
 
-               pwm3 {
-                       label = "PWM3";
-                       pwms = <&pwm 1 19600>;
-                       max-brightness = <255>;
-               };
+       reg_5v0: regulator-5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "5V_SW";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
        };
 
-       regulators {
-               sys_5v0_reg: regulator@1 {
-                       compatible = "regulator-fixed";
-                       reg = <1>;
-                       regulator-name = "5v0";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       regulator-always-on;
-               };
+       /* USBO1_EN */
+       reg_usbo1_vbus: regulator-usbo1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USBO1";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               vin-supply = <&reg_5v0>;
+       };
 
-               /* USBO1_EN */
-               usbo1_vbus_reg: regulator@2 {
-                       compatible = "regulator-fixed";
-                       reg = <2>;
-                       regulator-name = "usbo1_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
-                       enable-active-high;
-                       vin-supply = <&sys_5v0_reg>;
-               };
+       /* USBH_EN */
+       reg_usbh_vbus: regulator-usbh-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USBH(2A|2C|2D|3|4)";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               vin-supply = <&reg_5v0>;
+       };
+};
 
-               /* USBH_EN */
-               usbh_vbus_reg: regulator@3 {
-                       compatible = "regulator-fixed";
-                       reg = <3>;
-                       regulator-name = "usbh_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
-                       enable-active-high;
-                       vin-supply = <&sys_5v0_reg>;
-               };
+&gpio {
+       /* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
+       pex-perst-n {
+               gpio-hog;
+               gpios = <TEGRA_GPIO(S, 7) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "PEX_PERST_N";
        };
 };
diff --git a/arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts b/arch/arm/boot/dts/tegra30-apalis-v1.1-eval.dts
new file mode 100644 (file)
index 0000000..0be50e8
--- /dev/null
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra30-apalis-v1.1.dtsi"
+
+/ {
+       model = "Toradex Apalis T30 on Apalis Evaluation Board";
+       compatible = "toradex,apalis_t30-v1.1-eval", "toradex,apalis_t30-eval",
+                    "toradex,apalis_t30-v1.1", "toradex,apalis_t30",
+                    "nvidia,tegra30";
+
+       aliases {
+               rtc0 = "/i2c@7000c000/rtc@68";
+               rtc1 = "/i2c@7000d000/pmic@2d";
+               rtc2 = "/rtc@7000e000";
+               serial0 = &uarta;
+               serial1 = &uartb;
+               serial2 = &uartc;
+               serial3 = &uartd;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       pcie@3000 {
+               pci@1,0 {
+                       status = "okay";
+               };
+
+               pci@2,0 {
+                       status = "okay";
+               };
+       };
+
+       host1x@50000000 {
+               dc@54200000 {
+                       rgb {
+                               status = "okay";
+                               nvidia,panel = <&panel>;
+                       };
+               };
+
+               hdmi@54280000 {
+                       status = "okay";
+                       hdmi-supply = <&reg_5v0>;
+               };
+       };
+
+       /* Apalis UART1 */
+       serial@70006000 {
+               status = "okay";
+       };
+
+       /* Apalis UART2 */
+       serial@70006040 {
+               status = "okay";
+       };
+
+       /* Apalis UART3 */
+       serial@70006200 {
+               status = "okay";
+       };
+
+       /* Apalis UART4 */
+       serial@70006300 {
+               status = "okay";
+       };
+
+       pwm@7000a000 {
+               status = "okay";
+       };
+
+       /*
+        * GEN1_I2C: I2C1_SDA/SCL on MXM3 pin 209/211 (e.g. RTC on carrier
+        * board)
+        */
+       i2c@7000c000 {
+               status = "okay";
+               clock-frequency = <400000>;
+
+               pcie-switch@58 {
+                       compatible = "plx,pex8605";
+                       reg = <0x58>;
+               };
+
+               /* M41T0M6 real time clock on carrier board */
+               rtc@68 {
+                       compatible = "st,m41t0";
+                       reg = <0x68>;
+               };
+       };
+
+       /* GEN2_I2C: unused */
+
+       /*
+        * CAM_I2C: I2C3_SDA/SCL on MXM3 pin 201/203 (e.g. camera sensor on
+        * carrier board)
+        */
+       i2c@7000c500 {
+               status = "okay";
+               clock-frequency = <400000>;
+       };
+
+       /* DDC: I2C2_SDA/SCL on MXM3 pin 205/207 (e.g. display EDID) */
+       i2c@7000c700 {
+               status = "okay";
+       };
+
+       /* SPI1: Apalis SPI1 */
+       spi@7000d400 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       /* SPI5: Apalis SPI2 */
+       spi@7000dc00 {
+               status = "okay";
+               spi-max-frequency = <25000000>;
+       };
+
+       /* Apalis SD1 */
+       sdhci@78000000 {
+               status = "okay";
+               bus-width = <4>;
+               /* SD1_CD# */
+               cd-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_LOW>;
+               no-1-8-v;
+       };
+
+       /* Apalis MMC1 */
+       sdhci@78000400 {
+               status = "okay";
+               bus-width = <8>;
+               /* MMC1_CD# */
+               cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>;
+               vqmmc-supply = <&reg_vddio_sdmmc3>;
+       };
+
+       /* EHCI instance 0: USB1_DP/N -> USBO1_DP/N */
+       usb@7d000000 {
+               status = "okay";
+               dr_mode = "otg";
+       };
+
+       usb-phy@7d000000 {
+               status = "okay";
+               vbus-supply = <&reg_usbo1_vbus>;
+       };
+
+       /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */
+       usb@7d004000 {
+               status = "okay";
+       };
+
+       usb-phy@7d004000 {
+               status = "okay";
+               vbus-supply = <&reg_usbh_vbus>;
+       };
+
+       /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */
+       usb@7d008000 {
+               status = "okay";
+       };
+
+       usb-phy@7d008000 {
+               status = "okay";
+               vbus-supply = <&reg_usbh_vbus>;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <255 231 223 207 191 159 127 0>;
+               default-brightness-level = <6>;
+               /* BKL1_ON */
+               enable-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 0 5000000>; /* BKL1_PWM */
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               wakeup {
+                       label = "WAKE1_MICO";
+                       gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_WAKEUP>;
+                       debounce-interval = <10>;
+                       wakeup-source;
+               };
+       };
+
+       panel: panel {
+               /*
+                * edt,et057090dhu: EDT 5.7" LCD TFT
+                * edt,et070080dh6: EDT 7.0" LCD TFT
+                */
+               compatible = "edt,et057090dhu", "simple-panel";
+               backlight = <&backlight>;
+               power-supply = <&reg_3v3>;
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_5v0: regulator-5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "5V_SW";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       /* USBO1_EN */
+       reg_usbo1_vbus: regulator-usbo1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USBO1";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               vin-supply = <&reg_5v0>;
+       };
+
+       /* USBH_EN */
+       reg_usbh_vbus: regulator-usbh-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USBH(2A|2C|2D|3|4)";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               vin-supply = <&reg_5v0>;
+       };
+
+       /*
+        * 1.8 volt resp. 3.3 volt VDDIO_SDMMC3 depending on
+        * EN_+3.3_SDMMC3 GPIO
+        */
+       reg_vddio_sdmmc3: regulator-vddio-sdmmc3 {
+               compatible = "regulator-gpio";
+               regulator-name = "VDDIO_SDMMC3";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-type = "voltage";
+               gpios = <&gpio TEGRA_GPIO(J, 5) GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x0
+                         3300000 0x1>;
+               startup-delay-us = <100000>;
+               vin-supply = <&vddio_sdmmc_1v8_reg>;
+       };
+};
+
+&gpio {
+       /* Apalis GPIO7 MXM3 pin 15 PLX PEX 8605 PCIe Switch Reset */
+       pex-perst-n {
+               gpio-hog;
+               gpios = <TEGRA_GPIO(S, 7) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "PEX_PERST_N";
+       };
+};
diff --git a/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi b/arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi
new file mode 100644 (file)
index 0000000..02f8126
--- /dev/null
@@ -0,0 +1,1189 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+#include "tegra30.dtsi"
+
+/*
+ * Toradex Apalis T30 Module Device Tree
+ * Compatible for Revisions 1GB: V1.1A, V1.1B; 1GB IT: V1.1A, V1.1B;
+ * 2GB: V1.1A, V1.1B
+ */
+/ {
+       memory@80000000 {
+               reg = <0x80000000 0x40000000>;
+       };
+
+       pcie@3000 {
+               status = "okay";
+               avdd-pexa-supply = <&vdd2_reg>;
+               avdd-pexb-supply = <&vdd2_reg>;
+               avdd-pex-pll-supply = <&vdd2_reg>;
+               avdd-plle-supply = <&ldo6_reg>;
+               hvdd-pex-supply = <&reg_module_3v3>;
+               vddio-pex-ctl-supply = <&reg_module_3v3>;
+               vdd-pexa-supply = <&vdd2_reg>;
+               vdd-pexb-supply = <&vdd2_reg>;
+
+               /* Apalis type specific */
+               pci@1,0 {
+                       nvidia,num-lanes = <4>;
+               };
+
+               /* Apalis PCIe */
+               pci@2,0 {
+                       nvidia,num-lanes = <1>;
+               };
+
+               /* I210/I211 Gigabit Ethernet Controller (on-module) */
+               pci@3,0 {
+                       status = "okay";
+                       nvidia,num-lanes = <1>;
+
+                       pcie@0 {
+                               reg = <0 0 0 0 0>;
+                               local-mac-address = [00 00 00 00 00 00];
+                       };
+               };
+       };
+
+       host1x@50000000 {
+               hdmi@54280000 {
+                       nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+                       nvidia,hpd-gpio =
+                               <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
+                       pll-supply = <&reg_1v8_avdd_hdmi_pll>;
+                       vdd-supply = <&reg_3v3_avdd_hdmi>;
+               };
+       };
+
+       pinmux@70000868 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&state_default>;
+
+               state_default: pinmux {
+                       /* Analogue Audio (On-module) */
+                       clk1-out-pw4 {
+                               nvidia,pins = "clk1_out_pw4";
+                               nvidia,function = "extperiph1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap3-fs-pp0 {
+                               nvidia,pins = "dap3_fs_pp0",
+                                             "dap3_sclk_pp3",
+                                             "dap3_din_pp1",
+                                             "dap3_dout_pp2";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis BKL1_ON */
+                       pv2 {
+                               nvidia,pins = "pv2";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis BKL1_PWM */
+                       uart3-rts-n-pc0 {
+                               nvidia,pins = "uart3_rts_n_pc0";
+                               nvidia,function = "pwm0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* BKL1_PWM_EN#, disable TPS65911 PMIC PWM backlight */
+                       uart3-cts-n-pa1 {
+                               nvidia,pins = "uart3_cts_n_pa1";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis CAN1 on SPI6 */
+                       spi2-cs0-n-px3 {
+                               nvidia,pins = "spi2_cs0_n_px3",
+                                             "spi2_miso_px1",
+                                             "spi2_mosi_px0",
+                                             "spi2_sck_px2";
+                               nvidia,function = "spi6";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* CAN_INT1 */
+                       spi2-cs1-n-pw2 {
+                               nvidia,pins = "spi2_cs1_n_pw2";
+                               nvidia,function = "spi3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis CAN2 on SPI4 */
+                       gmi-a16-pj7 {
+                               nvidia,pins = "gmi_a16_pj7",
+                                             "gmi_a17_pb0",
+                                             "gmi_a18_pb1",
+                                             "gmi_a19_pk7";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* CAN_INT2 */
+                       spi2-cs2-n-pw3 {
+                               nvidia,pins = "spi2_cs2_n_pw3";
+                               nvidia,function = "spi3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis Digital Audio */
+                       clk1-req-pee2 {
+                               nvidia,pins = "clk1_req_pee2";
+                               nvidia,function = "hda";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk2-out-pw5 {
+                               nvidia,pins = "clk2_out_pw5";
+                               nvidia,function = "extperiph2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap1-fs-pn0 {
+                               nvidia,pins = "dap1_fs_pn0",
+                                             "dap1_din_pn1",
+                                             "dap1_dout_pn2",
+                                             "dap1_sclk_pn3";
+                               nvidia,function = "hda";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis GPIO */
+                       kb-col0-pq0 {
+                               nvidia,pins = "kb_col0_pq0",
+                                             "kb_col1_pq1",
+                                             "kb_row10_ps2",
+                                             "kb_row11_ps3",
+                                             "kb_row12_ps4",
+                                             "kb_row13_ps5",
+                                             "kb_row14_ps6",
+                                             "kb_row15_ps7";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Multiplexed and therefore disabled */
+                       owr {
+                               nvidia,pins = "owr";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis HDMI1 */
+                       hdmi-cec-pee3 {
+                               nvidia,pins = "hdmi_cec_pee3";
+                               nvidia,function = "cec";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdmi-int-pn7 {
+                               nvidia,pins = "hdmi_int_pn7";
+                               nvidia,function = "hdmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis I2C1 */
+                       gen1-i2c-scl-pc4 {
+                               nvidia,pins = "gen1_i2c_scl_pc4",
+                                             "gen1_i2c_sda_pc5";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis I2C2 (DDC) */
+                       ddc-scl-pv4 {
+                               nvidia,pins = "ddc_scl_pv4",
+                                             "ddc_sda_pv5";
+                               nvidia,function = "i2c4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis I2C3 (CAM) */
+                       cam-i2c-scl-pbb1 {
+                               nvidia,pins = "cam_i2c_scl_pbb1",
+                                             "cam_i2c_sda_pbb2";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis LCD1 */
+                       lcd-d0-pe0 {
+                               nvidia,pins = "lcd_d0_pe0",
+                                             "lcd_d1_pe1",
+                                             "lcd_d2_pe2",
+                                             "lcd_d3_pe3",
+                                             "lcd_d4_pe4",
+                                             "lcd_d5_pe5",
+                                             "lcd_d6_pe6",
+                                             "lcd_d7_pe7",
+                                             "lcd_d8_pf0",
+                                             "lcd_d9_pf1",
+                                             "lcd_d10_pf2",
+                                             "lcd_d11_pf3",
+                                             "lcd_d12_pf4",
+                                             "lcd_d13_pf5",
+                                             "lcd_d14_pf6",
+                                             "lcd_d15_pf7",
+                                             "lcd_d16_pm0",
+                                             "lcd_d17_pm1",
+                                             "lcd_d18_pm2",
+                                             "lcd_d19_pm3",
+                                             "lcd_d20_pm4",
+                                             "lcd_d21_pm5",
+                                             "lcd_d22_pm6",
+                                             "lcd_d23_pm7",
+                                             "lcd_de_pj1",
+                                             "lcd_hsync_pj3",
+                                             "lcd_pclk_pb3",
+                                             "lcd_vsync_pj4";
+                               nvidia,function = "displaya";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis MMC1 */
+                       sdmmc3-clk-pa6 {
+                               nvidia,pins = "sdmmc3_clk_pa6";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc3-dat0-pb7 {
+                               nvidia,pins = "sdmmc3_cmd_pa7",
+                                             "sdmmc3_dat0_pb7",
+                                             "sdmmc3_dat1_pb6",
+                                             "sdmmc3_dat2_pb5",
+                                             "sdmmc3_dat3_pb4",
+                                             "sdmmc3_dat4_pd1",
+                                             "sdmmc3_dat5_pd0",
+                                             "sdmmc3_dat6_pd3",
+                                             "sdmmc3_dat7_pd4";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* Apalis MMC1_CD# */
+                       pv3 {
+                               nvidia,pins = "pv3";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis Parallel Camera */
+                       cam-mclk-pcc0 {
+                               nvidia,pins = "cam_mclk_pcc0";
+                               nvidia,function = "vi_alt3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       vi-vsync-pd6 {
+                               nvidia,pins = "vi_d0_pt4",
+                                             "vi_d1_pd5",
+                                             "vi_d2_pl0",
+                                             "vi_d3_pl1",
+                                             "vi_d4_pl2",
+                                             "vi_d5_pl3",
+                                             "vi_d6_pl4",
+                                             "vi_d7_pl5",
+                                             "vi_d8_pl6",
+                                             "vi_d9_pl7",
+                                             "vi_d10_pt2",
+                                             "vi_d11_pt3",
+                                             "vi_hsync_pd7",
+                                             "vi_pclk_pt0",
+                                             "vi_vsync_pd6";
+                               nvidia,function = "vi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Multiplexed and therefore disabled */
+                       kb-col2-pq2 {
+                               nvidia,pins = "kb_col2_pq2",
+                                             "kb_col3_pq3",
+                                             "kb_col4_pq4",
+                                             "kb_row4_pr4";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb-row0-pr0 {
+                               nvidia,pins = "kb_row0_pr0",
+                                             "kb_row1_pr1",
+                                             "kb_row2_pr2",
+                                             "kb_row3_pr3";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb-row5-pr5 {
+                               nvidia,pins = "kb_row5_pr5",
+                                             "kb_row6_pr6",
+                                             "kb_row7_pr7";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /*
+                        * VI level-shifter direction
+                        * (pull-down => default direction input)
+                        */
+                       vi-mclk-pt1 {
+                               nvidia,pins = "vi_mclk_pt1";
+                               nvidia,function = "vi_alt3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis PWM1 */
+                       pu6 {
+                               nvidia,pins = "pu6";
+                               nvidia,function = "pwm3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis PWM2 */
+                       pu5 {
+                               nvidia,pins = "pu5";
+                               nvidia,function = "pwm2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis PWM3 */
+                       pu4 {
+                               nvidia,pins = "pu4";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis PWM4 */
+                       pu3 {
+                               nvidia,pins = "pu3";
+                               nvidia,function = "pwm0";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis RESET_MOCI# */
+                       gmi-rst-n-pi4 {
+                               nvidia,pins = "gmi_rst_n_pi4";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis SATA1_ACT# */
+                       pex-l0-prsnt-n-pdd0 {
+                               nvidia,pins = "pex_l0_prsnt_n_pdd0";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis SD1 */
+                       sdmmc1-clk-pz0 {
+                               nvidia,pins = "sdmmc1_clk_pz0";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       sdmmc1-cmd-pz1 {
+                               nvidia,pins = "sdmmc1_cmd_pz1",
+                                             "sdmmc1_dat0_py7",
+                                             "sdmmc1_dat1_py6",
+                                             "sdmmc1_dat2_py5",
+                                             "sdmmc1_dat3_py4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* Apalis SD1_CD# */
+                       clk2-req-pcc5 {
+                               nvidia,pins = "clk2_req_pcc5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis SPDIF1 */
+                       spdif-out-pk5 {
+                               nvidia,pins = "spdif_out_pk5",
+                                             "spdif_in_pk6";
+                               nvidia,function = "spdif";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis SPI1 */
+                       spi1-sck-px5 {
+                               nvidia,pins = "spi1_sck_px5",
+                                             "spi1_mosi_px4",
+                                             "spi1_miso_px7",
+                                             "spi1_cs0_n_px6";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis SPI2 */
+                       lcd-sck-pz4 {
+                               nvidia,pins = "lcd_sck_pz4",
+                                             "lcd_sdout_pn5",
+                                             "lcd_sdin_pz2",
+                                             "lcd_cs0_n_pn4";
+                               nvidia,function = "spi5";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /*
+                        * Apalis TS (Low-speed type specific)
+                        * pins may be used as GPIOs
+                        */
+                       kb-col5-pq5 {
+                               nvidia,pins = "kb_col5_pq5";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       kb-col6-pq6 {
+                               nvidia,pins = "kb_col6_pq6",
+                                             "kb_col7_pq7",
+                                             "kb_row8_ps0",
+                                             "kb_row9_ps1";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis UART1 */
+                       ulpi-data0 {
+                               nvidia,pins = "ulpi_data0_po1",
+                                             "ulpi_data1_po2",
+                                             "ulpi_data2_po3",
+                                             "ulpi_data3_po4",
+                                             "ulpi_data4_po5",
+                                             "ulpi_data5_po6",
+                                             "ulpi_data6_po7",
+                                             "ulpi_data7_po0";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis UART2 */
+                       ulpi-clk-py0 {
+                               nvidia,pins = "ulpi_clk_py0",
+                                             "ulpi_dir_py1",
+                                             "ulpi_nxt_py2",
+                                             "ulpi_stp_py3";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis UART3 */
+                       uart2-rxd-pc3 {
+                               nvidia,pins = "uart2_rxd_pc3",
+                                             "uart2_txd_pc2";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis UART4 */
+                       uart3-rxd-pw7 {
+                               nvidia,pins = "uart3_rxd_pw7",
+                                             "uart3_txd_pw6";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis USBH_EN */
+                       pex-l0-rst-n-pdd1 {
+                               nvidia,pins = "pex_l0_rst_n_pdd1";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis USBH_OC# */
+                       pex-l0-clkreq-n-pdd2 {
+                               nvidia,pins = "pex_l0_clkreq_n_pdd2";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis USBO1_EN */
+                       gen2-i2c-scl-pt5 {
+                               nvidia,pins = "gen2_i2c_scl_pt5";
+                               nvidia,function = "rsvd4";
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis USBO1_OC# */
+                       gen2-i2c-sda-pt6 {
+                               nvidia,pins = "gen2_i2c_sda_pt6";
+                               nvidia,function = "rsvd4";
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis VGA1 not supported and therefore disabled */
+                       crt-hsync-pv6 {
+                               nvidia,pins = "crt_hsync_pv6",
+                                             "crt_vsync_pv7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis WAKE1_MICO */
+                       pv1 {
+                               nvidia,pins = "pv1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* eMMC (On-module) */
+                       sdmmc4-clk-pcc4 {
+                               nvidia,pins = "sdmmc4_clk_pcc4",
+                                             "sdmmc4_cmd_pt7",
+                                             "sdmmc4_rst_n_pcc3";
+                               nvidia,function = "sdmmc4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdmmc4-dat0-paa0 {
+                               nvidia,pins = "sdmmc4_dat0_paa0",
+                                             "sdmmc4_dat1_paa1",
+                                             "sdmmc4_dat2_paa2",
+                                             "sdmmc4_dat3_paa3",
+                                             "sdmmc4_dat4_paa4",
+                                             "sdmmc4_dat5_paa5",
+                                             "sdmmc4_dat6_paa6",
+                                             "sdmmc4_dat7_paa7";
+                               nvidia,function = "sdmmc4";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* EN_+3.3_SDMMC3 */
+                       uart2-cts-n-pj5 {
+                               nvidia,pins = "uart2_cts_n_pj5";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* LAN i210/i211 DEV_OFF_N, PE_RST_N (On-module) */
+                       pex-l2-prsnt-n-pdd7 {
+                               nvidia,pins = "pex_l2_prsnt_n_pdd7",
+                                             "pex_l2_rst_n_pcc6";
+                               nvidia,function = "pcie";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* LAN i210/i211 PE_WAKE_N, SDP3 (On-module) */
+                       pex-wake-n-pdd3 {
+                               nvidia,pins = "pex_wake_n_pdd3",
+                                             "pex_l2_clkreq_n_pcc7";
+                               nvidia,function = "pcie";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* LAN i210/i211 SMB_ALERT_N (On-module) */
+                       sys-clk-req-pz5 {
+                               nvidia,pins = "sys_clk_req_pz5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* LVDS Transceiver Configuration */
+                       pbb0 {
+                               nvidia,pins = "pbb0",
+                                             "pbb7",
+                                             "pcc1",
+                                             "pcc2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pbb3 {
+                               nvidia,pins = "pbb3",
+                                             "pbb4",
+                                             "pbb5",
+                                             "pbb6";
+                               nvidia,function = "displayb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Not connected and therefore disabled */
+                       clk-32k-out-pa0 {
+                               nvidia,pins = "clk3_out_pee0",
+                                             "clk3_req_pee1",
+                                             "clk_32k_out_pa0",
+                                             "dap4_din_pp5",
+                                             "dap4_dout_pp6",
+                                             "dap4_fs_pp4",
+                                             "dap4_sclk_pp7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2-fs-pa2 {
+                               nvidia,pins = "dap2_fs_pa2",
+                                             "dap2_sclk_pa3",
+                                             "dap2_din_pa4",
+                                             "dap2_dout_pa5",
+                                             "lcd_dc0_pn6",
+                                             "lcd_m1_pw1",
+                                             "lcd_pwr1_pc1",
+                                             "pex_l1_clkreq_n_pdd6",
+                                             "pex_l1_prsnt_n_pdd4",
+                                             "pex_l1_rst_n_pdd5";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-ad0-pg0 {
+                               nvidia,pins = "gmi_ad0_pg0",
+                                             "gmi_ad2_pg2",
+                                             "gmi_ad3_pg3",
+                                             "gmi_ad4_pg4",
+                                             "gmi_ad5_pg5",
+                                             "gmi_ad6_pg6",
+                                             "gmi_ad7_pg7",
+                                             "gmi_ad8_ph0",
+                                             "gmi_ad9_ph1",
+                                             "gmi_ad10_ph2",
+                                             "gmi_ad11_ph3",
+                                             "gmi_ad12_ph4",
+                                             "gmi_ad13_ph5",
+                                             "gmi_ad14_ph6",
+                                             "gmi_ad15_ph7",
+                                             "gmi_adv_n_pk0",
+                                             "gmi_clk_pk1",
+                                             "gmi_cs4_n_pk2",
+                                             "gmi_cs2_n_pk3",
+                                             "gmi_dqs_pi2",
+                                             "gmi_iordy_pi5",
+                                             "gmi_oe_n_pi1",
+                                             "gmi_wait_pi7",
+                                             "gmi_wr_n_pi0",
+                                             "lcd_cs1_n_pw0",
+                                             "pu0",
+                                             "pu1",
+                                             "pu2";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-cs0-n-pj0 {
+                               nvidia,pins = "gmi_cs0_n_pj0",
+                                             "gmi_cs1_n_pj2",
+                                             "gmi_cs3_n_pk4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-cs6-n-pi3 {
+                               nvidia,pins = "gmi_cs6_n_pi3";
+                               nvidia,function = "sata";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-cs7-n-pi6 {
+                               nvidia,pins = "gmi_cs7_n_pi6";
+                               nvidia,function = "gmi_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd-pwr0-pb2 {
+                               nvidia,pins = "lcd_pwr0_pb2",
+                                             "lcd_pwr2_pc6",
+                                             "lcd_wr_n_pz3";
+                               nvidia,function = "hdcp";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2-rts-n-pj6 {
+                               nvidia,pins = "uart2_rts_n_pj6";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Power I2C (On-module) */
+                       pwr-i2c-scl-pz6 {
+                               nvidia,pins = "pwr_i2c_scl_pz6",
+                                             "pwr_i2c_sda_pz7";
+                               nvidia,function = "i2cpwr";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /*
+                        * THERMD_ALERT#, unlatched I2C address pin of LM95245
+                        * temperature sensor therefore requires disabling for
+                        * now
+                        */
+                       lcd-dc1-pd2 {
+                               nvidia,pins = "lcd_dc1_pd2";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* TOUCH_PEN_INT# (On-module) */
+                       pv0 {
+                               nvidia,pins = "pv0";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+               };
+       };
+
+       serial@70006040 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       serial@70006200 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       serial@70006300 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       hdmi_ddc: i2c@7000c700 {
+               clock-frequency = <10000>;
+       };
+
+       /*
+        * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and
+        * touch screen controller
+        */
+       i2c@7000d000 {
+               status = "okay";
+               clock-frequency = <100000>;
+
+               /* SGTL5000 audio codec */
+               sgtl5000: codec@a {
+                       compatible = "fsl,sgtl5000";
+                       reg = <0x0a>;
+                       VDDA-supply = <&reg_module_3v3_audio>;
+                       VDDD-supply = <&reg_1v8_vio>;
+                       VDDIO-supply = <&reg_module_3v3>;
+                       clocks = <&tegra_car TEGRA30_CLK_EXTERN1>;
+               };
+
+               pmic: pmic@2d {
+                       compatible = "ti,tps65911";
+                       reg = <0x2d>;
+
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+
+                       ti,system-power-controller;
+
+                       #gpio-cells = <2>;
+                       gpio-controller;
+
+                       vcc1-supply = <&reg_module_3v3>;
+                       vcc2-supply = <&reg_module_3v3>;
+                       vcc3-supply = <&reg_1v8_vio>;
+                       vcc4-supply = <&reg_module_3v3>;
+                       vcc5-supply = <&reg_module_3v3>;
+                       vcc6-supply = <&reg_1v8_vio>;
+                       vcc7-supply = <&reg_5v0_charge_pump>;
+                       vccio-supply = <&reg_module_3v3>;
+
+                       regulators {
+                               vdd1_reg: vdd1 {
+                                       regulator-name = "+V1.35_VDDIO_DDR";
+                                       regulator-min-microvolt = <1350000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                               };
+
+                               vdd2_reg: vdd2 {
+                                       regulator-name = "+V1.05";
+                                       regulator-min-microvolt = <1050000>;
+                                       regulator-max-microvolt = <1050000>;
+                               };
+
+                               vddctrl_reg: vddctrl {
+                                       regulator-name = "+V1.0_VDD_CPU";
+                                       regulator-min-microvolt = <1150000>;
+                                       regulator-max-microvolt = <1150000>;
+                                       regulator-always-on;
+                               };
+
+                               reg_1v8_vio: vio {
+                                       regulator-name = "+V1.8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               /*
+                                * 1.8 volt +VDDIO_SDMMC3 in case EN_+3.3_SDMMC3
+                                * is off
+                                */
+                               vddio_sdmmc_1v8_reg: ldo1 {
+                                       regulator-name = "+VDDIO_SDMMC3_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               /*
+                                * EN_+V3.3 switching via FET:
+                                * +V3.3_AUDIO_AVDD_S, +V3.3
+                                * see also +V3.3 fixed supply
+                                */
+                               ldo2_reg: ldo2 {
+                                       regulator-name = "EN_+V3.3";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo3_reg: ldo3 {
+                                       regulator-name = "+V1.2_CSI";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                               };
+
+                               ldo4_reg: ldo4 {
+                                       regulator-name = "+V1.2_VDD_RTC";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               /*
+                                * +V2.8_AVDD_VDAC:
+                                * only required for (unsupported) analog RGB
+                                */
+                               ldo5_reg: ldo5 {
+                                       regulator-name = "+V2.8_AVDD_VDAC";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                               };
+
+                               /*
+                                * +V1.05_AVDD_PLLE: avdd_plle should be 1.05V
+                                * but LDO6 can't set voltage in 50mV
+                                * granularity
+                                */
+                               ldo6_reg: ldo6 {
+                                       regulator-name = "+V1.05_AVDD_PLLE";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                               };
+
+                               ldo7_reg: ldo7 {
+                                       regulator-name = "+V1.2_AVDD_PLL";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo8_reg: ldo8 {
+                                       regulator-name = "+V1.0_VDD_DDR_HS";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+                       };
+               };
+
+               /* STMPE811 touch screen controller */
+               touchscreen@41 {
+                       compatible = "st,stmpe811";
+                       reg = <0x41>;
+                       irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
+                       interrupt-controller;
+                       id = <0>;
+                       blocks = <0x5>;
+                       irq-trigger = <0x1>;
+
+                       stmpe_touchscreen {
+                               compatible = "st,stmpe-ts";
+                               /* 3.25 MHz ADC clock speed */
+                               st,adc-freq = <1>;
+                               /* 8 sample average control */
+                               st,ave-ctrl = <3>;
+                               /* 7 length fractional part in z */
+                               st,fraction-z = <7>;
+                               /*
+                                * 50 mA typical 80 mA max touchscreen drivers
+                                * current limit value
+                                */
+                               st,i-drive = <1>;
+                               /* 12-bit ADC */
+                               st,mod-12b = <1>;
+                               /* internal ADC reference */
+                               st,ref-sel = <0>;
+                               /* ADC converstion time: 80 clocks */
+                               st,sample-time = <4>;
+                               /* 1 ms panel driver settling time */
+                               st,settling = <3>;
+                               /* 5 ms touch detect interrupt delay */
+                               st,touch-det-delay = <5>;
+                       };
+               };
+
+               /*
+                * LM95245 temperature sensor
+                * Note: OVERT1# directly connected to TPS65911 PMIC PWRDN
+                */
+               temp-sensor@4c {
+                       compatible = "national,lm95245";
+                       reg = <0x4c>;
+               };
+
+               /* SW: +V1.2_VDD_CORE */
+               regulator@60 {
+                       compatible = "ti,tps62362";
+                       reg = <0x60>;
+
+                       regulator-name = "tps62362-vout";
+                       regulator-min-microvolt = <900000>;
+                       regulator-max-microvolt = <1400000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+                       ti,vsel0-state-low;
+                       /* VSEL1: EN_CORE_DVFS_N low for DVFS */
+                       ti,vsel1-state-low;
+               };
+       };
+
+       /* SPI4: CAN2 */
+       spi@7000da00 {
+               status = "okay";
+               spi-max-frequency = <10000000>;
+
+               can@1 {
+                       compatible = "microchip,mcp2515";
+                       reg = <1>;
+                       clocks = <&clk16m>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_EDGE_FALLING>;
+                       spi-max-frequency = <10000000>;
+               };
+       };
+
+       /* SPI6: CAN1 */
+       spi@7000de00 {
+               status = "okay";
+               spi-max-frequency = <10000000>;
+
+               can@0 {
+                       compatible = "microchip,mcp2515";
+                       reg = <0>;
+                       clocks = <&clk16m>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = <TEGRA_GPIO(W, 2) IRQ_TYPE_EDGE_FALLING>;
+                       spi-max-frequency = <10000000>;
+               };
+       };
+
+       pmc@7000e400 {
+               nvidia,invert-interrupt;
+               nvidia,suspend-mode = <1>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <0>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
+
+               /* Set DEV_OFF bit in DCDC control register of TPS65911 PMIC */
+               i2c-thermtrip {
+                       nvidia,i2c-controller-id = <4>;
+                       nvidia,bus-addr = <0x2d>;
+                       nvidia,reg-addr = <0x3f>;
+                       nvidia,reg-data = <0x1>;
+               };
+       };
+
+       hda@70030000 {
+               status = "okay";
+       };
+
+       ahub@70080000 {
+               i2s@70080500 {
+                       status = "okay";
+               };
+       };
+
+       /* eMMC */
+       sdhci@78000600 {
+               status = "okay";
+               bus-width = <8>;
+               non-removable;
+               vmmc-supply = <&reg_module_3v3>; /* VCC */
+               vqmmc-supply = <&reg_1v8_vio>; /* VCCQ */
+               mmc-ddr-1_8v;
+       };
+
+       clk32k_in: xtal1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
+
+       clk16m: osc4 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <16000000>;
+       };
+
+       reg_1v8_avdd_hdmi_pll: regulator-1v8-avdd-hdmi-pll {
+               compatible = "regulator-fixed";
+               regulator-name = "+V1.8_AVDD_HDMI_PLL";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               enable-active-high;
+               gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_1v8_vio>;
+       };
+
+       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_module_3v3>;
+       };
+
+       reg_5v0_charge_pump: regulator-5v0-charge-pump {
+               compatible = "regulator-fixed";
+               regulator-name = "+V5.0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       reg_module_3v3: regulator-module-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_module_3v3_audio: regulator-module-3v3-audio {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AUDIO_AVDD_S";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       sound {
+               compatible = "toradex,tegra-audio-sgtl5000-apalis_t30",
+                            "nvidia,tegra-audio-sgtl5000";
+               nvidia,model = "Toradex Apalis T30";
+               nvidia,audio-routing =
+                       "Headphone Jack", "HP_OUT",
+                       "LINE_IN", "Line In Jack",
+                       "MIC_IN", "Mic Jack";
+               nvidia,i2s-controller = <&tegra_i2s2>;
+               nvidia,audio-codec = <&sgtl5000>;
+               clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+                        <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+                        <&tegra_car TEGRA30_CLK_EXTERN1>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
+       };
+};
index 2f807d40c1b792bd35c662bcd243588b7fa91d0b..7f112f192fe9a4ebe2e0db0c0d6e7e2715b65811 100644 (file)
@@ -3,48 +3,53 @@
 
 /*
  * Toradex Apalis T30 Module Device Tree
- * Compatible for Revisions 1GB: V1.0A, V1.1A; 1GB IT: V1.1A;
- * 2GB: V1.0B, V1.0C, V1.0E, V1.1A
+ * Compatible for Revisions 1GB: V1.0A; 2GB: V1.0B, V1.0C, V1.0E
  */
 / {
-       model = "Toradex Apalis T30";
-       compatible = "toradex,apalis_t30", "nvidia,tegra30";
-
        memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
 
        pcie@3000 {
+               status = "okay";
                avdd-pexa-supply = <&vdd2_reg>;
-               vdd-pexa-supply = <&vdd2_reg>;
                avdd-pexb-supply = <&vdd2_reg>;
-               vdd-pexb-supply = <&vdd2_reg>;
                avdd-pex-pll-supply = <&vdd2_reg>;
                avdd-plle-supply = <&ldo6_reg>;
-               vddio-pex-ctl-supply = <&sys_3v3_reg>;
-               hvdd-pex-supply = <&sys_3v3_reg>;
+               hvdd-pex-supply = <&reg_module_3v3>;
+               vddio-pex-ctl-supply = <&reg_module_3v3>;
+               vdd-pexa-supply = <&vdd2_reg>;
+               vdd-pexb-supply = <&vdd2_reg>;
 
+               /* Apalis type specific */
                pci@1,0 {
                        nvidia,num-lanes = <4>;
                };
 
+               /* Apalis PCIe */
                pci@2,0 {
                        nvidia,num-lanes = <1>;
                };
 
+               /* I210/I211 Gigabit Ethernet Controller (on-module) */
                pci@3,0 {
+                       status = "okay";
                        nvidia,num-lanes = <1>;
+
+                       pcie@0 {
+                               reg = <0 0 0 0 0>;
+                               local-mac-address = [00 00 00 00 00 00];
+                       };
                };
        };
 
        host1x@50000000 {
                hdmi@54280000 {
-                       vdd-supply = <&avdd_hdmi_3v3_reg>;
-                       pll-supply = <&avdd_hdmi_pll_1v8_reg>;
-
+                       nvidia,ddc-i2c-bus = <&hdmi_ddc>;
                        nvidia,hpd-gpio =
                                <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
-                       nvidia,ddc-i2c-bus = <&hdmiddc>;
+                       pll-supply = <&reg_1v8_avdd_hdmi_pll>;
+                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                };
        };
 
 
                state_default: pinmux {
                        /* Analogue Audio (On-module) */
-                       clk1_out_pw4 {
+                       clk1-out-pw4 {
                                nvidia,pins = "clk1_out_pw4";
                                nvidia,function = "extperiph1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap3_fs_pp0 {
-                               nvidia,pins =   "dap3_fs_pp0",
-                                               "dap3_sclk_pp3",
-                                               "dap3_din_pp1",
-                                               "dap3_dout_pp2";
+                       dap3-fs-pp0 {
+                               nvidia,pins = "dap3_fs_pp0",
+                                             "dap3_sclk_pp3",
+                                             "dap3_din_pp1",
+                                             "dap3_dout_pp2";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,function = "rsvd4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
                        /* Apalis BKL1_PWM */
-                       uart3_rts_n_pc0 {
+                       uart3-rts-n-pc0 {
                                nvidia,pins = "uart3_rts_n_pc0";
                                nvidia,function = "pwm0";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
                        /* BKL1_PWM_EN#, disable TPS65911 PMIC PWM backlight */
-                       uart3_cts_n_pa1 {
+                       uart3-cts-n-pa1 {
                                nvidia,pins = "uart3_cts_n_pa1";
                                nvidia,function = "rsvd2";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
                        /* Apalis CAN1 on SPI6 */
-                       spi2_cs0_n_px3 {
+                       spi2-cs0-n-px3 {
                                nvidia,pins = "spi2_cs0_n_px3",
                                              "spi2_miso_px1",
                                              "spi2_mosi_px0",
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
                        /* CAN_INT1 */
-                       spi2_cs1_n_pw2 {
+                       spi2-cs1-n-pw2 {
                                nvidia,pins = "spi2_cs1_n_pw2";
                                nvidia,function = "spi3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis CAN2 on SPI4 */
-                       gmi_a16_pj7 {
+                       gmi-a16-pj7 {
                                nvidia,pins = "gmi_a16_pj7",
                                              "gmi_a17_pb0",
                                              "gmi_a18_pb1",
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
                        /* CAN_INT2 */
-                       spi2_cs2_n_pw3 {
+                       spi2-cs2-n-pw3 {
                                nvidia,pins = "spi2_cs2_n_pw3";
                                nvidia,function = "spi3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Apalis Digital Audio */
-                       clk1_req_pee2 {
+                       clk1-req-pee2 {
                                nvidia,pins = "clk1_req_pee2";
                                nvidia,function = "hda";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       clk2_out_pw5 {
+                       clk2-out-pw5 {
                                nvidia,pins = "clk2_out_pw5";
                                nvidia,function = "extperiph2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap1_fs_pn0 {
+                       dap1-fs-pn0 {
                                nvidia,pins = "dap1_fs_pn0",
                                              "dap1_din_pn1",
                                              "dap1_dout_pn2",
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* Apalis I2C3 */
-                       cam_i2c_scl_pbb1 {
+                       /* Apalis GPIO */
+                       kb-col0-pq0 {
+                               nvidia,pins = "kb_col0_pq0",
+                                             "kb_col1_pq1",
+                                             "kb_row10_ps2",
+                                             "kb_row11_ps3",
+                                             "kb_row12_ps4",
+                                             "kb_row13_ps5",
+                                             "kb_row14_ps6",
+                                             "kb_row15_ps7";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Multiplexed and therefore disabled */
+                       owr {
+                               nvidia,pins = "owr";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis HDMI1 */
+                       hdmi-cec-pee3 {
+                               nvidia,pins = "hdmi_cec_pee3";
+                               nvidia,function = "cec";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdmi-int-pn7 {
+                               nvidia,pins = "hdmi_int_pn7";
+                               nvidia,function = "hdmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis I2C1 */
+                       gen1-i2c-scl-pc4 {
+                               nvidia,pins = "gen1_i2c_scl_pc4",
+                                             "gen1_i2c_sda_pc5";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis I2C2 (DDC) */
+                       ddc-scl-pv4 {
+                               nvidia,pins = "ddc_scl_pv4",
+                                             "ddc_sda_pv5";
+                               nvidia,function = "i2c4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis I2C3 (CAM) */
+                       cam-i2c-scl-pbb1 {
                                nvidia,pins = "cam_i2c_scl_pbb1",
                                              "cam_i2c_sda_pbb2";
                                nvidia,function = "i2c3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-                               nvidia,lock = <TEGRA_PIN_DISABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
 
+                       /* Apalis LCD1 */
+                       lcd-d0-pe0 {
+                               nvidia,pins = "lcd_d0_pe0",
+                                             "lcd_d1_pe1",
+                                             "lcd_d2_pe2",
+                                             "lcd_d3_pe3",
+                                             "lcd_d4_pe4",
+                                             "lcd_d5_pe5",
+                                             "lcd_d6_pe6",
+                                             "lcd_d7_pe7",
+                                             "lcd_d8_pf0",
+                                             "lcd_d9_pf1",
+                                             "lcd_d10_pf2",
+                                             "lcd_d11_pf3",
+                                             "lcd_d12_pf4",
+                                             "lcd_d13_pf5",
+                                             "lcd_d14_pf6",
+                                             "lcd_d15_pf7",
+                                             "lcd_d16_pm0",
+                                             "lcd_d17_pm1",
+                                             "lcd_d18_pm2",
+                                             "lcd_d19_pm3",
+                                             "lcd_d20_pm4",
+                                             "lcd_d21_pm5",
+                                             "lcd_d22_pm6",
+                                             "lcd_d23_pm7",
+                                             "lcd_de_pj1",
+                                             "lcd_hsync_pj3",
+                                             "lcd_pclk_pb3",
+                                             "lcd_vsync_pj4";
+                               nvidia,function = "displaya";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
                        /* Apalis MMC1 */
-                       sdmmc3_clk_pa6 {
-                               nvidia,pins = "sdmmc3_clk_pa6",
-                                             "sdmmc3_cmd_pa7";
+                       sdmmc3-clk-pa6 {
+                               nvidia,pins = "sdmmc3_clk_pa6";
                                nvidia,function = "sdmmc3";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       sdmmc3_dat0_pb7 {
-                               nvidia,pins = "sdmmc3_dat0_pb7",
+                       sdmmc3-dat0-pb7 {
+                               nvidia,pins = "sdmmc3_cmd_pa7",
+                                             "sdmmc3_dat0_pb7",
                                              "sdmmc3_dat1_pb6",
                                              "sdmmc3_dat2_pb5",
                                              "sdmmc3_dat3_pb4",
                        pv3 {
                                nvidia,pins = "pv3";
                                nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis Parallel Camera */
+                       cam-mclk-pcc0 {
+                               nvidia,pins = "cam_mclk_pcc0";
+                               nvidia,function = "vi_alt3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       vi-vsync-pd6 {
+                               nvidia,pins = "vi_d0_pt4",
+                                             "vi_d1_pd5",
+                                             "vi_d2_pl0",
+                                             "vi_d3_pl1",
+                                             "vi_d4_pl2",
+                                             "vi_d5_pl3",
+                                             "vi_d6_pl4",
+                                             "vi_d7_pl5",
+                                             "vi_d8_pl6",
+                                             "vi_d9_pl7",
+                                             "vi_d10_pt2",
+                                             "vi_d11_pt3",
+                                             "vi_hsync_pd7",
+                                             "vi_pclk_pt0",
+                                             "vi_vsync_pd6";
+                               nvidia,function = "vi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
+                       /* Multiplexed and therefore disabled */
+                       kb-col2-pq2 {
+                               nvidia,pins = "kb_col2_pq2",
+                                             "kb_col3_pq3",
+                                             "kb_col4_pq4",
+                                             "kb_row4_pr4";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb-row0-pr0 {
+                               nvidia,pins = "kb_row0_pr0",
+                                             "kb_row1_pr1",
+                                             "kb_row2_pr2",
+                                             "kb_row3_pr3";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb-row5-pr5 {
+                               nvidia,pins = "kb_row5_pr5",
+                                             "kb_row6_pr6",
+                                             "kb_row7_pr7";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /*
+                        * VI level-shifter direction
+                        * (pull-down => default direction input)
+                        */
+                       vi-mclk-pt1 {
+                               nvidia,pins = "vi_mclk_pt1";
+                               nvidia,function = "vi_alt3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
 
                        /* Apalis PWM1 */
                        pu6 {
                        };
 
                        /* Apalis RESET_MOCI# */
-                       gmi_rst_n_pi4 {
+                       gmi-rst-n-pi4 {
                                nvidia,pins = "gmi_rst_n_pi4";
                                nvidia,function = "gmi";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
+                       /* Apalis SATA1_ACT# */
+                       pex-l0-prsnt-n-pdd0 {
+                               nvidia,pins = "pex_l0_prsnt_n_pdd0";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
                        /* Apalis SD1 */
-                       sdmmc1_clk_pz0 {
+                       sdmmc1-clk-pz0 {
                                nvidia,pins = "sdmmc1_clk_pz0";
                                nvidia,function = "sdmmc1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       sdmmc1_cmd_pz1 {
+                       sdmmc1-cmd-pz1 {
                                nvidia,pins = "sdmmc1_cmd_pz1",
                                              "sdmmc1_dat0_py7",
                                              "sdmmc1_dat1_py6",
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
                        /* Apalis SD1_CD# */
-                       clk2_req_pcc5 {
+                       clk2-req-pcc5 {
                                nvidia,pins = "clk2_req_pcc5";
                                nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Apalis SPDIF1 */
+                       spdif-out-pk5 {
+                               nvidia,pins = "spdif_out_pk5",
+                                             "spdif_in_pk6";
+                               nvidia,function = "spdif";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
 
                        /* Apalis SPI1 */
-                       spi1_sck_px5 {
+                       spi1-sck-px5 {
                                nvidia,pins = "spi1_sck_px5",
                                              "spi1_mosi_px4",
                                              "spi1_miso_px7",
                        };
 
                        /* Apalis SPI2 */
-                       lcd_sck_pz4 {
+                       lcd-sck-pz4 {
                                nvidia,pins = "lcd_sck_pz4",
                                              "lcd_sdout_pn5",
                                              "lcd_sdin_pz2",
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
+                       /*
+                        * Apalis TS (Low-speed type specific)
+                        * pins may be used as GPIOs
+                        */
+                       kb-col5-pq5 {
+                               nvidia,pins = "kb_col5_pq5";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       kb-col6-pq6 {
+                               nvidia,pins = "kb_col6_pq6",
+                                             "kb_col7_pq7",
+                                             "kb_row8_ps0",
+                                             "kb_row9_ps1";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
                        /* Apalis UART1 */
-                       ulpi_data0 {
+                       ulpi-data0 {
                                nvidia,pins = "ulpi_data0_po1",
                                              "ulpi_data1_po2",
                                              "ulpi_data2_po3",
                        };
 
                        /* Apalis UART2 */
-                       ulpi_clk_py0 {
+                       ulpi-clk-py0 {
                                nvidia,pins = "ulpi_clk_py0",
                                              "ulpi_dir_py1",
                                              "ulpi_nxt_py2",
                        };
 
                        /* Apalis UART3 */
-                       uart2_rxd_pc3 {
+                       uart2-rxd-pc3 {
                                nvidia,pins = "uart2_rxd_pc3",
                                              "uart2_txd_pc2";
                                nvidia,function = "uartb";
                        };
 
                        /* Apalis UART4 */
-                       uart3_rxd_pw7 {
+                       uart3-rxd-pw7 {
                                nvidia,pins = "uart3_rxd_pw7",
                                              "uart3_txd_pw6";
                                nvidia,function = "uartc";
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
+                       /* Apalis USBH_EN */
+                       pex-l0-rst-n-pdd1 {
+                               nvidia,pins = "pex_l0_rst_n_pdd1";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Apalis USBH_OC# */
+                       pex-l0-clkreq-n-pdd2 {
+                               nvidia,pins = "pex_l0_clkreq_n_pdd2";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
                        /* Apalis USBO1_EN */
-                       gen2_i2c_scl_pt5 {
+                       gen2-i2c-scl-pt5 {
                                nvidia,pins = "gen2_i2c_scl_pt5";
                                nvidia,function = "rsvd4";
                                nvidia,open-drain = <TEGRA_PIN_DISABLE>;
                        };
 
                        /* Apalis USBO1_OC# */
-                       gen2_i2c_sda_pt6 {
+                       gen2-i2c-sda-pt6 {
                                nvidia,pins = "gen2_i2c_sda_pt6";
                                nvidia,function = "rsvd4";
                                nvidia,open-drain = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
 
+                       /* Apalis VGA1 not supported and therefore disabled */
+                       crt-hsync-pv6 {
+                               nvidia,pins = "crt_hsync_pv6",
+                                             "crt_vsync_pv7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
                        /* Apalis WAKE1_MICO */
                        pv1 {
                                nvidia,pins = "pv1";
                        };
 
                        /* eMMC (On-module) */
-                       sdmmc4_clk_pcc4 {
+                       sdmmc4-clk-pcc4 {
                                nvidia,pins = "sdmmc4_clk_pcc4",
+                                             "sdmmc4_cmd_pt7",
                                              "sdmmc4_rst_n_pcc3";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat0_paa0 {
+                       sdmmc4-dat0-paa0 {
                                nvidia,pins = "sdmmc4_dat0_paa0",
                                              "sdmmc4_dat1_paa1",
                                              "sdmmc4_dat2_paa2",
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* LAN i210/i211 DEV_OFF_N, PE_RST_N (On-module) */
+                       pex-l2-prsnt-n-pdd7 {
+                               nvidia,pins = "pex_l2_prsnt_n_pdd7",
+                                             "pex_l2_rst_n_pcc6";
+                               nvidia,function = "pcie";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* LAN i210/i211 PE_WAKE_N, SDP3 (On-module) */
+                       pex-wake-n-pdd3 {
+                               nvidia,pins = "pex_wake_n_pdd3",
+                                             "pex_l2_clkreq_n_pcc7";
+                               nvidia,function = "pcie";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* LAN i210/i211 SMB_ALERT_N (On-module) */
+                       sys-clk-req-pz5 {
+                               nvidia,pins = "sys_clk_req_pz5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
 
                        /* LVDS Transceiver Configuration */
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
-                               nvidia,lock = <TEGRA_PIN_DISABLE>;
                        };
                        pbb3 {
                                nvidia,pins = "pbb3",
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
-                               nvidia,lock = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Not connected and therefore disabled */
+                       clk-32k-out-pa0 {
+                               nvidia,pins = "clk3_out_pee0",
+                                             "clk3_req_pee1",
+                                             "clk_32k_out_pa0",
+                                             "dap4_din_pp5",
+                                             "dap4_dout_pp6",
+                                             "dap4_fs_pp4",
+                                             "dap4_sclk_pp7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       dap2-fs-pa2 {
+                               nvidia,pins = "dap2_fs_pa2",
+                                             "dap2_sclk_pa3",
+                                             "dap2_din_pa4",
+                                             "dap2_dout_pa5",
+                                             "lcd_dc0_pn6",
+                                             "lcd_m1_pw1",
+                                             "lcd_pwr1_pc1",
+                                             "pex_l1_clkreq_n_pdd6",
+                                             "pex_l1_prsnt_n_pdd4",
+                                             "pex_l1_rst_n_pdd5";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-ad0-pg0 {
+                               nvidia,pins = "gmi_ad0_pg0",
+                                             "gmi_ad2_pg2",
+                                             "gmi_ad3_pg3",
+                                             "gmi_ad4_pg4",
+                                             "gmi_ad5_pg5",
+                                             "gmi_ad6_pg6",
+                                             "gmi_ad7_pg7",
+                                             "gmi_ad8_ph0",
+                                             "gmi_ad9_ph1",
+                                             "gmi_ad10_ph2",
+                                             "gmi_ad11_ph3",
+                                             "gmi_ad12_ph4",
+                                             "gmi_ad13_ph5",
+                                             "gmi_ad14_ph6",
+                                             "gmi_ad15_ph7",
+                                             "gmi_adv_n_pk0",
+                                             "gmi_clk_pk1",
+                                             "gmi_cs4_n_pk2",
+                                             "gmi_cs2_n_pk3",
+                                             "gmi_dqs_pi2",
+                                             "gmi_iordy_pi5",
+                                             "gmi_oe_n_pi1",
+                                             "gmi_wait_pi7",
+                                             "gmi_wr_n_pi0",
+                                             "lcd_cs1_n_pw0",
+                                             "pu0",
+                                             "pu1",
+                                             "pu2";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-cs0-n-pj0 {
+                               nvidia,pins = "gmi_cs0_n_pj0",
+                                             "gmi_cs1_n_pj2",
+                                             "gmi_cs3_n_pk4";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-cs6-n-pi3 {
+                               nvidia,pins = "gmi_cs6_n_pi3";
+                               nvidia,function = "sata";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-cs7-n-pi6 {
+                               nvidia,pins = "gmi_cs7_n_pi6";
+                               nvidia,function = "gmi_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd-pwr0-pb2 {
+                               nvidia,pins = "lcd_pwr0_pb2",
+                                             "lcd_pwr2_pc6",
+                                             "lcd_wr_n_pz3";
+                               nvidia,function = "hdcp";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       uart2-cts-n-pj5 {
+                               nvidia,pins = "uart2_cts_n_pj5",
+                                             "uart2_rts_n_pj6";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
                        /* Power I2C (On-module) */
-                       pwr_i2c_scl_pz6 {
+                       pwr-i2c-scl-pz6 {
                                nvidia,pins = "pwr_i2c_scl_pz6",
                                              "pwr_i2c_sda_pz7";
                                nvidia,function = "i2cpwr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-                               nvidia,lock = <TEGRA_PIN_DISABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
 
                         * temperature sensor therefore requires disabling for
                         * now
                         */
-                       lcd_dc1_pd2 {
+                       lcd-dc1-pd2 {
                                nvidia,pins = "lcd_dc1_pd2";
                                nvidia,function = "rsvd3";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* TOUCH_PEN_INT# */
+                       /* TOUCH_PEN_INT# (On-module) */
                        pv0 {
                                nvidia,pins = "pv0";
                                nvidia,function = "rsvd1";
                };
        };
 
-       hdmiddc: i2c@7000c700 {
+       serial@70006040 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       serial@70006200 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       serial@70006300 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       hdmi_ddc: i2c@7000c700 {
                clock-frequency = <10000>;
        };
 
                sgtl5000: codec@a {
                        compatible = "fsl,sgtl5000";
                        reg = <0x0a>;
-                       VDDA-supply = <&sys_3v3_reg>;
-                       VDDIO-supply = <&sys_3v3_reg>;
+                       VDDA-supply = <&reg_module_3v3_audio>;
+                       VDDD-supply = <&reg_1v8_vio>;
+                       VDDIO-supply = <&reg_module_3v3>;
                        clocks = <&tegra_car TEGRA30_CLK_EXTERN1>;
                };
 
-               pmic: tps65911@2d {
+               pmic: pmic@2d {
                        compatible = "ti,tps65911";
                        reg = <0x2d>;
 
                        #gpio-cells = <2>;
                        gpio-controller;
 
-                       vcc1-supply = <&sys_3v3_reg>;
-                       vcc2-supply = <&sys_3v3_reg>;
-                       vcc3-supply = <&vio_reg>;
-                       vcc4-supply = <&sys_3v3_reg>;
-                       vcc5-supply = <&sys_3v3_reg>;
-                       vcc6-supply = <&vio_reg>;
-                       vcc7-supply = <&charge_pump_5v0_reg>;
-                       vccio-supply = <&sys_3v3_reg>;
+                       vcc1-supply = <&reg_module_3v3>;
+                       vcc2-supply = <&reg_module_3v3>;
+                       vcc3-supply = <&reg_1v8_vio>;
+                       vcc4-supply = <&reg_module_3v3>;
+                       vcc5-supply = <&reg_module_3v3>;
+                       vcc6-supply = <&reg_1v8_vio>;
+                       vcc7-supply = <&reg_5v0_charge_pump>;
+                       vccio-supply = <&reg_module_3v3>;
 
                        regulators {
-                               /* SW1: +V1.35_VDDIO_DDR */
                                vdd1_reg: vdd1 {
-                                       regulator-name = "vddio_ddr_1v35";
+                                       regulator-name = "+V1.35_VDDIO_DDR";
                                        regulator-min-microvolt = <1350000>;
                                        regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
                                };
 
-                               /* SW2: +V1.05 */
                                vdd2_reg: vdd2 {
-                                       regulator-name =
-                                               "vdd_pexa,vdd_pexb,vdd_sata";
+                                       regulator-name = "+V1.05";
                                        regulator-min-microvolt = <1050000>;
                                        regulator-max-microvolt = <1050000>;
                                };
 
-                               /* SW CTRL: +V1.0_VDD_CPU */
                                vddctrl_reg: vddctrl {
-                                       regulator-name = "vdd_cpu,vdd_sys";
+                                       regulator-name = "+V1.0_VDD_CPU";
                                        regulator-min-microvolt = <1150000>;
                                        regulator-max-microvolt = <1150000>;
                                        regulator-always-on;
                                };
 
-                               /* SWIO: +V1.8 */
-                               vio_reg: vio {
-                                       regulator-name = "vdd_1v8_gen";
+                               reg_1v8_vio: vio {
+                                       regulator-name = "+V1.8";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
 
                                /*
                                 * EN_+V3.3 switching via FET:
-                                * +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
-                                * see also v3_3 fixed supply
+                                * +V3.3_AUDIO_AVDD_S, +V3.3
+                                * see also +V3.3 fixed supply
                                 */
                                ldo2_reg: ldo2 {
-                                       regulator-name = "en_3v3";
+                                       regulator-name = "EN_+V3.3";
                                        regulator-min-microvolt = <3300000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-always-on;
                                };
 
-                               /* +V1.2_CSI */
                                ldo3_reg: ldo3 {
-                                       regulator-name =
-                                               "avdd_dsi_csi,pwrdet_mipi";
+                                       regulator-name = "+V1.2_CSI";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                };
 
-                               /* +V1.2_VDD_RTC */
                                ldo4_reg: ldo4 {
-                                       regulator-name = "vdd_rtc";
+                                       regulator-name = "+V1.2_VDD_RTC";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
 
                                /*
                                 * +V2.8_AVDD_VDAC:
-                                * only required for analog RGB
+                                * only required for (unsupported) analog RGB
                                 */
                                ldo5_reg: ldo5 {
-                                       regulator-name = "avdd_vdac";
+                                       regulator-name = "+V2.8_AVDD_VDAC";
                                        regulator-min-microvolt = <2800000>;
                                        regulator-max-microvolt = <2800000>;
                                        regulator-always-on;
                                 * granularity
                                 */
                                ldo6_reg: ldo6 {
-                                       regulator-name = "avdd_plle";
+                                       regulator-name = "+V1.05_AVDD_PLLE";
                                        regulator-min-microvolt = <1100000>;
                                        regulator-max-microvolt = <1100000>;
                                };
 
-                               /* +V1.2_AVDD_PLL */
                                ldo7_reg: ldo7 {
-                                       regulator-name = "avdd_pll";
+                                       regulator-name = "+V1.2_AVDD_PLL";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                };
 
-                               /* +V1.0_VDD_DDR_HS */
                                ldo8_reg: ldo8 {
-                                       regulator-name = "vdd_ddr_hs";
+                                       regulator-name = "+V1.0_VDD_DDR_HS";
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1000000>;
                                        regulator-always-on;
                };
 
                /* STMPE811 touch screen controller */
-               stmpe811@41 {
+               touchscreen@41 {
                        compatible = "st,stmpe811";
                        reg = <0x41>;
-                       interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
-                       interrupt-parent = <&gpio>;
+                       irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
                        interrupt-controller;
                        id = <0>;
                        blocks = <0x5>;
 
                /*
                 * LM95245 temperature sensor
-                * Note: OVERT_N directly connected to PMIC PWRDN
+                * Note: OVERT1# directly connected to TPS65911 PMIC PWRDN
                 */
                temp-sensor@4c {
                        compatible = "national,lm95245";
                };
 
                /* SW: +V1.2_VDD_CORE */
-               tps62362@60 {
+               regulator@60 {
                        compatible = "ti,tps62362";
                        reg = <0x60>;
 
                        reg = <1>;
                        clocks = <&clk16m>;
                        interrupt-parent = <&gpio>;
-                       interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_EDGE_FALLING>;
                        spi-max-frequency = <10000000>;
                };
        };
                        reg = <0>;
                        clocks = <&clk16m>;
                        interrupt-parent = <&gpio>;
-                       interrupts = <TEGRA_GPIO(W, 2) IRQ_TYPE_EDGE_RISING>;
+                       interrupts = <TEGRA_GPIO(W, 2) IRQ_TYPE_EDGE_FALLING>;
                        spi-max-frequency = <10000000>;
                };
        };
                nvidia,core-pwr-off-time = <0>;
                nvidia,core-power-req-active-high;
                nvidia,sys-clock-req-active-high;
+
+               /* Set DEV_OFF bit in DCDC control register of TPS65911 PMIC */
+               i2c-thermtrip {
+                       nvidia,i2c-controller-id = <4>;
+                       nvidia,bus-addr = <0x2d>;
+                       nvidia,reg-addr = <0x3f>;
+                       nvidia,reg-data = <0x1>;
+               };
+       };
+
+       hda@70030000 {
+               status = "okay";
        };
 
        ahub@70080000 {
                status = "okay";
                bus-width = <8>;
                non-removable;
+               vmmc-supply = <&reg_module_3v3>; /* VCC */
+               vqmmc-supply = <&reg_1v8_vio>; /* VCCQ */
+               mmc-ddr-1_8v;
        };
 
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
+       clk32k_in: xtal1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
 
-               clk32k_in: clk@0 {
-                       compatible = "fixed-clock";
-                       reg = <0>;
-                       #clock-cells = <0>;
-                       clock-frequency = <32768>;
-               };
+       clk16m: osc4 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <16000000>;
+       };
 
-               clk16m: clk@1 {
-                       compatible = "fixed-clock";
-                       reg = <1>;
-                       #clock-cells = <0>;
-                       clock-frequency = <16000000>;
-                       clock-output-names = "clk16m";
-               };
+       reg_1v8_avdd_hdmi_pll: regulator-1v8-avdd-hdmi-pll {
+               compatible = "regulator-fixed";
+               regulator-name = "+V1.8_AVDD_HDMI_PLL";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               enable-active-high;
+               gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_1v8_vio>;
        };
 
-       regulators {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               avdd_hdmi_pll_1v8_reg: regulator@100 {
-                       compatible = "regulator-fixed";
-                       reg = <100>;
-                       regulator-name = "+V1.8_AVDD_HDMI_PLL";
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       enable-active-high;
-                       gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
-                       vin-supply = <&vio_reg>;
-               };
+       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_module_3v3>;
+       };
 
-               sys_3v3_reg: regulator@101 {
-                       compatible = "regulator-fixed";
-                       reg = <101>;
-                       regulator-name = "3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-always-on;
-               };
+       reg_5v0_charge_pump: regulator-5v0-charge-pump {
+               compatible = "regulator-fixed";
+               regulator-name = "+V5.0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
 
-               avdd_hdmi_3v3_reg: regulator@102 {
-                       compatible = "regulator-fixed";
-                       reg = <102>;
-                       regulator-name = "+V3.3_AVDD_HDMI";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       enable-active-high;
-                       gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
-                       vin-supply = <&sys_3v3_reg>;
-               };
+       reg_module_3v3: regulator-module-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
 
-               charge_pump_5v0_reg: regulator@103 {
-                       compatible = "regulator-fixed";
-                       reg = <103>;
-                       regulator-name = "5v0";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       regulator-always-on;
-               };
+       reg_module_3v3_audio: regulator-module-3v3-audio {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AUDIO_AVDD_S";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
        };
 
        sound {
index 16e1f387aa6db65aad52d814bd4e663522f81048..5965150ecdd25aea0b529940b41ba9b0542b78fd 100644 (file)
@@ -1,15 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
 #include "tegra30-colibri.dtsi"
 
 / {
        model = "Toradex Colibri T30 on Colibri Evaluation Board";
-       compatible = "toradex,colibri_t30-eval-v3", "toradex,colibri_t30", "nvidia,tegra30";
+       compatible = "toradex,colibri_t30-eval-v3", "toradex,colibri_t30",
+                    "nvidia,tegra30";
 
        aliases {
                rtc0 = "/i2c@7000c000/rtc@68";
-               rtc1 = "/i2c@7000d000/tps65911@2d";
+               rtc1 = "/i2c@7000d000/pmic@2d";
                rtc2 = "/rtc@7000e000";
                serial0 = &uarta;
                serial1 = &uartb;
                                nvidia,panel = <&panel>;
                        };
                };
+
                hdmi@54280000 {
                        status = "okay";
+                       hdmi-supply = <&reg_5v0>;
                };
        };
 
+       /* Colibri UART-A */
        serial@70006000 {
                status = "okay";
        };
 
+       /* Colibri UART-C */
        serial@70006040 {
-               compatible = "nvidia,tegra30-hsuart";
                status = "okay";
        };
 
+       /* Colibri UART-B */
        serial@70006300 {
-               compatible = "nvidia,tegra30-hsuart";
                status = "okay";
        };
 
                };
        };
 
+       /* GEN2_I2C: unused */
+
+       /* CAM_I2C (I2C3): unused */
+
        /* DDC_CLOCK/DATA on X3 pin 15/16 (e.g. display EDID) */
-       hdmiddc: i2c@7000c700 {
+       i2c@7000c700 {
                status = "okay";
        };
 
        spi@7000d400 {
                status = "okay";
                spi-max-frequency = <25000000>;
-               can0: can@0 {
+
+               can@0 {
                        compatible = "microchip,mcp2515";
                        reg = <0>;
                        clocks = <&clk16m>;
                        interrupt-parent = <&gpio>;
-                       interrupts = <TEGRA_GPIO(S, 0) IRQ_TYPE_EDGE_RISING>;
+                       /* CAN_INT */
+                       interrupts = <TEGRA_GPIO(S, 0) IRQ_TYPE_EDGE_FALLING>;
                        spi-max-frequency = <10000000>;
-               };
-               spidev0: spi@1 {
-                       compatible = "spidev";
-                       reg = <1>;
-                       spi-max-frequency = <25000000>;
+                       vdd-supply = <&reg_3v3>;
+                       xceiver-supply = <&reg_5v0>;
                };
        };
 
        sdhci@78000200 {
                status = "okay";
                bus-width = <4>;
-               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; /* MMCD */
                no-1-8-v;
        };
 
        /* EHCI instance 0: USB1_DP/N -> USBC_P/N */
        usb@7d000000 {
                status = "okay";
+               dr_mode = "otg";
        };
 
        usb-phy@7d000000 {
                status = "okay";
-               dr_mode = "otg";
-               vbus-supply = <&usbc_vbus_reg>;
+               vbus-supply = <&reg_usbc_vbus>;
        };
 
        /* EHCI instance 2: USB3_DP/N -> USBH_P/N */
 
        usb-phy@7d008000 {
                status = "okay";
-               vbus-supply = <&usbh_vbus_reg>;
+               vbus-supply = <&reg_usbh_vbus>;
        };
 
        backlight: backlight {
                compatible = "pwm-backlight";
-
-               /* PWM<A> */
-               pwms = <&pwm 0 5000000>;
                brightness-levels = <255 128 64 32 16 8 4 0>;
                default-brightness-level = <6>;
                /* BL_ON */
                enable-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3>;
+               pwms = <&pwm 0 5000000>; /* PWM<A> */
        };
 
-       clocks {
-               clk16m: clk@1 {
-                       compatible = "fixed-clock";
-                       reg = <1>;
-                       #clock-cells = <0>;
-                       clock-frequency = <16000000>;
-                       clock-output-names = "clk16m";
-               };
+       clk16m: osc3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <16000000>;
        };
 
        gpio-keys {
                 * edt,et070080dh6: EDT 7.0" LCD TFT
                 */
                compatible = "edt,et057090dhu", "simple-panel";
-
                backlight = <&backlight>;
+               power-supply = <&reg_3v3>;
        };
 
-       pwmleds {
-               compatible = "pwm-leds";
-
-               pwmb {
-                       label = "PWM<B>";
-                       pwms = <&pwm 1 19600>;
-                       max-brightness = <255>;
-               };
-               pwmc {
-                       label = "PWM<C>";
-                       pwms = <&pwm 2 19600>;
-                       max-brightness = <255>;
-               };
-               pwmd {
-                       label = "PWM<D>";
-                       pwms = <&pwm 3 19600>;
-                       max-brightness = <255>;
-               };
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
        };
 
-       regulators {
-               sys_5v0_reg: regulator@1 {
-                       compatible = "regulator-fixed";
-                       reg = <1>;
-                       regulator-name = "5v0";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       regulator-always-on;
-               };
+       reg_5v0: regulator-5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "5V_SW";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
 
-               usbc_vbus_reg: regulator@2 {
-                       compatible = "regulator-fixed";
-                       reg = <2>;
-                       regulator-name = "usbc_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       vin-supply = <&sys_5v0_reg>;
-               };
+       reg_usbc_vbus: regulator-usbc-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USB5";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&reg_5v0>;
+       };
 
-               /* USBH_PEN */
-               usbh_vbus_reg: regulator@3 {
-                       compatible = "regulator-fixed";
-                       reg = <3>;
-                       regulator-name = "usbh_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
-                       vin-supply = <&sys_5v0_reg>;
-               };
+       /* USBH_PEN resp. USB_P_EN */
+       reg_usbh_vbus: regulator-usbh-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_USB[1-4]";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
+               vin-supply = <&reg_5v0>;
        };
 };
index 526ed71cf7a320f970770213947d6c325e86c181..35af03ca9e908e9146715dcf2005e39d79c65de2 100644 (file)
@@ -1,27 +1,22 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <dt-bindings/input/input.h>
 #include "tegra30.dtsi"
 
 /*
  * Toradex Colibri T30 Module Device Tree
- * Compatible for Revisions V1.1B, V1.1C, V1.1D, V1.1E; IT: V1.1A
+ * Compatible for Revisions V1.1B, V1.1C, V1.1D, V1.1E, V1.1F; IT: V1.1A, V1.1B
  */
 / {
-       model = "Toradex Colibri T30";
-       compatible = "toradex,colibri_t30", "nvidia,tegra30";
-
        memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
 
        host1x@50000000 {
                hdmi@54280000 {
-                       vdd-supply = <&avdd_hdmi_3v3_reg>;
-                       pll-supply = <&avdd_hdmi_pll_1v8_reg>;
-
+                       nvidia,ddc-i2c-bus = <&hdmi_ddc>;
                        nvidia,hpd-gpio =
                                <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
-                       nvidia,ddc-i2c-bus = <&hdmiddc>;
+                       pll-supply = <&reg_1v8_avdd_hdmi_pll>;
+                       vdd-supply = <&reg_3v3_avdd_hdmi>;
                };
        };
 
 
                state_default: pinmux {
                        /* Analogue Audio (On-module) */
-                       clk1_out_pw4 {
+                       clk1-out-pw4 {
                                nvidia,pins = "clk1_out_pw4";
                                nvidia,function = "extperiph1";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
-                       dap3_fs_pp0 {
-                               nvidia,pins =   "dap3_fs_pp0",
-                                               "dap3_sclk_pp3",
-                                               "dap3_din_pp1",
-                                               "dap3_dout_pp2";
+                       dap3-fs-pp0 {
+                               nvidia,pins = "dap3_fs_pp0",
+                                             "dap3_sclk_pp3",
+                                             "dap3_din_pp1",
+                                             "dap3_dout_pp2";
                                nvidia,function = "i2s2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
+                       /* Colibri Address/Data Bus (GMI) */
+                       gmi-ad0-pg0 {
+                               nvidia,pins = "gmi_ad0_pg0",
+                                             "gmi_ad2_pg2",
+                                             "gmi_ad3_pg3",
+                                             "gmi_ad4_pg4",
+                                             "gmi_ad5_pg5",
+                                             "gmi_ad6_pg6",
+                                             "gmi_ad7_pg7",
+                                             "gmi_ad8_ph0",
+                                             "gmi_ad9_ph1",
+                                             "gmi_ad10_ph2",
+                                             "gmi_ad11_ph3",
+                                             "gmi_ad12_ph4",
+                                             "gmi_ad13_ph5",
+                                             "gmi_ad14_ph6",
+                                             "gmi_ad15_ph7",
+                                             "gmi_adv_n_pk0",
+                                             "gmi_clk_pk1",
+                                             "gmi_cs4_n_pk2",
+                                             "gmi_cs2_n_pk3",
+                                             "gmi_iordy_pi5",
+                                             "gmi_oe_n_pi1",
+                                             "gmi_wait_pi7",
+                                             "gmi_wr_n_pi0",
+                                             "dap1_fs_pn0",
+                                             "dap1_din_pn1",
+                                             "dap1_dout_pn2",
+                                             "dap1_sclk_pn3",
+                                             "dap2_fs_pa2",
+                                             "dap2_sclk_pa3",
+                                             "dap2_din_pa4",
+                                             "dap2_dout_pa5",
+                                             "spi1_sck_px5",
+                                             "spi1_mosi_px4",
+                                             "spi1_cs0_n_px6",
+                                             "spi2_cs0_n_px3",
+                                             "spi2_miso_px1",
+                                             "spi2_mosi_px0",
+                                             "spi2_sck_px2",
+                                             "uart2_cts_n_pj5",
+                                             "uart2_rts_n_pj6";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Further pins may be used as GPIOs */
+                       dap4-din-pp5 {
+                               nvidia,pins = "dap4_din_pp5",
+                                             "dap4_dout_pp6",
+                                             "dap4_fs_pp4",
+                                             "dap4_sclk_pp7",
+                                             "pbb7",
+                                             "sdmmc1_clk_pz0",
+                                             "sdmmc1_cmd_pz1",
+                                             "sdmmc1_dat0_py7",
+                                             "sdmmc1_dat1_py6",
+                                             "sdmmc1_dat3_py4",
+                                             "uart3_cts_n_pa1",
+                                             "uart3_txd_pw6",
+                                             "uart3_rxd_pw7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       lcd-d18-pm2 {
+                               nvidia,pins = "lcd_d18_pm2",
+                                             "lcd_d19_pm3",
+                                             "lcd_d20_pm4",
+                                             "lcd_d21_pm5",
+                                             "lcd_d22_pm6",
+                                             "lcd_d23_pm7",
+                                             "lcd_dc0_pn6",
+                                             "pex_l2_clkreq_n_pcc7";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       lcd-cs0-n-pn4 {
+                               nvidia,pins = "lcd_cs0_n_pn4",
+                                             "lcd_sdin_pz2",
+                                             "pu0",
+                                             "pu1",
+                                             "pu2",
+                                             "pu3",
+                                             "pu4",
+                                             "pu5",
+                                             "pu6",
+                                             "spi1_miso_px7",
+                                             "uart3_rts_n_pc0";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       lcd-pwr0-pb2 {
+                               nvidia,pins = "lcd_pwr0_pb2",
+                                             "lcd_sck_pz4",
+                                             "lcd_sdout_pn5",
+                                             "lcd_wr_n_pz3";
+                               nvidia,function = "hdcp";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       pbb4 {
+                               nvidia,pins = "pbb4",
+                                             "pbb5",
+                                             "pbb6";
+                               nvidia,function = "displayb";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Multiplexed RDnWR and therefore disabled */
+                       lcd-cs1-n-pw0 {
+                               nvidia,pins = "lcd_cs1_n_pw0";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* Multiplexed GMI_CLK and therefore disabled */
+                       owr {
+                               nvidia,pins = "owr";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* Tri-stating GMI_WR_N on nPWE SODIMM pin 99 */
+                       sdmmc3-dat4-pd1 {
+                               nvidia,pins = "sdmmc3_dat4_pd1";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       /* Not tri-stating GMI_WR_N on RDnWR SODIMM pin 93 */
+                       sdmmc3-dat5-pd0 {
+                               nvidia,pins = "sdmmc3_dat5_pd0";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
                        /* Colibri BL_ON */
                        pv2 {
                                nvidia,pins = "pv2";
                        };
 
                        /* Colibri Backlight PWM<A> */
-                       sdmmc3_dat3_pb4 {
+                       sdmmc3-dat3-pb4 {
                                nvidia,pins = "sdmmc3_dat3_pb4";
                                nvidia,function = "pwm0";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                        };
 
                        /* Colibri CAN_INT */
-                       kb_row8_ps0 {
+                       kb-row8-ps0 {
                                nvidia,pins = "kb_row8_ps0";
                                nvidia,function = "kbc";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
 
+                       /* Colibri DDC */
+                       ddc-scl-pv4 {
+                               nvidia,pins = "ddc_scl_pv4",
+                                             "ddc_sda_pv5";
+                               nvidia,function = "i2c4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri EXT_IO* */
+                       gen2-i2c-scl-pt5 {
+                               nvidia,pins = "gen2_i2c_scl_pt5",
+                                             "gen2_i2c_sda_pt6";
+                               nvidia,function = "rsvd4";
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       spdif-in-pk6 {
+                               nvidia,pins =   "spdif_in_pk6";
+                               nvidia,function = "hda";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri GPIO */
+                       clk2-out-pw5 {
+                               nvidia,pins = "clk2_out_pw5",
+                                             "pcc2",
+                                             "pv3",
+                                             "sdmmc1_dat2_py5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       lcd-pwr1-pc1 {
+                               nvidia,pins = "lcd_pwr1_pc1",
+                                             "pex_l1_clkreq_n_pdd6",
+                                             "pex_l1_rst_n_pdd5";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       pv1 {
+                               nvidia,pins = "pv1",
+                                             "sdmmc3_dat0_pb7",
+                                             "sdmmc3_dat1_pb6";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri HOTPLUG_DETECT (HDMI) */
+                       hdmi-int-pn7 {
+                               nvidia,pins = "hdmi_int_pn7";
+                               nvidia,function = "hdmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri I2C */
+                       gen1-i2c-scl-pc4 {
+                               nvidia,pins = "gen1_i2c_scl_pc4",
+                                             "gen1_i2c_sda_pc5";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri LCD (L_* resp. LDD<*>) */
+                       lcd-d0-pe0 {
+                               nvidia,pins = "lcd_d0_pe0",
+                                             "lcd_d1_pe1",
+                                             "lcd_d2_pe2",
+                                             "lcd_d3_pe3",
+                                             "lcd_d4_pe4",
+                                             "lcd_d5_pe5",
+                                             "lcd_d6_pe6",
+                                             "lcd_d7_pe7",
+                                             "lcd_d8_pf0",
+                                             "lcd_d9_pf1",
+                                             "lcd_d10_pf2",
+                                             "lcd_d11_pf3",
+                                             "lcd_d12_pf4",
+                                             "lcd_d13_pf5",
+                                             "lcd_d14_pf6",
+                                             "lcd_d15_pf7",
+                                             "lcd_d16_pm0",
+                                             "lcd_d17_pm1",
+                                             "lcd_de_pj1",
+                                             "lcd_hsync_pj3",
+                                             "lcd_pclk_pb3",
+                                             "lcd_vsync_pj4";
+                               nvidia,function = "displaya";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
                        /*
                         * Colibri L_BIAS, LCD_M1 is muxed with LCD_DE
-                        * todays display need DE, disable LCD_M1
+                        * today's display need DE, disable LCD_M1
                         */
-                       lcd_m1_pw1 {
+                       lcd-m1-pw1 {
                                nvidia,pins = "lcd_m1_pw1";
                                nvidia,function = "rsvd3";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
                        /* Colibri MMC */
-                       kb_row10_ps2 {
+                       kb-row10-ps2 {
                                nvidia,pins = "kb_row10_ps2";
                                nvidia,function = "sdmmc2";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       kb_row11_ps3 {
+                       kb-row11-ps3 {
                                nvidia,pins = "kb_row11_ps3",
                                              "kb_row12_ps4",
                                              "kb_row13_ps5",
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
+                       /* Colibri MMC_CD */
+                       gmi-wp-n-pc7 {
+                               nvidia,pins = "gmi_wp_n_pc7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* Multiplexed and therefore disabled */
+                       cam-mclk-pcc0 {
+                               nvidia,pins =   "cam_mclk_pcc0";
+                               nvidia,function = "vi_alt3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       cam-i2c-scl-pbb1 {
+                               nvidia,pins = "cam_i2c_scl_pbb1",
+                                             "cam_i2c_sda_pbb2";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                               nvidia,open-drain = <TEGRA_PIN_DISABLE>;
+                       };
+                       pbb0 {
+                               nvidia,pins = "pbb0",
+                                             "pcc1";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       pbb3 {
+                               nvidia,pins = "pbb3";
+                               nvidia,function = "displayb";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Colibri nRESET_OUT */
+                       gmi-rst-n-pi4 {
+                               nvidia,pins = "gmi_rst_n_pi4";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /*
+                        * Colibri Parallel Camera (Optional)
+                        * pins multiplexed with others and therefore disabled
+                        */
+                       vi-vsync-pd6 {
+                               nvidia,pins = "vi_d0_pt4",
+                                             "vi_d1_pd5",
+                                             "vi_d2_pl0",
+                                             "vi_d3_pl1",
+                                             "vi_d4_pl2",
+                                             "vi_d5_pl3",
+                                             "vi_d6_pl4",
+                                             "vi_d7_pl5",
+                                             "vi_d8_pl6",
+                                             "vi_d9_pl7",
+                                             "vi_d10_pt2",
+                                             "vi_d11_pt3",
+                                             "vi_hsync_pd7",
+                                             "vi_mclk_pt1",
+                                             "vi_pclk_pt0",
+                                             "vi_vsync_pd6";
+                               nvidia,function = "vi";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Colibri PWM<B> */
+                       sdmmc3-dat2-pb5 {
+                               nvidia,pins = "sdmmc3_dat2_pb5";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Colibri PWM<C> */
+                       sdmmc3-clk-pa6 {
+                               nvidia,pins = "sdmmc3_clk_pa6";
+                               nvidia,function = "pwm2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Colibri PWM<D> */
+                       sdmmc3-cmd-pa7 {
+                               nvidia,pins = "sdmmc3_cmd_pa7";
+                               nvidia,function = "pwm3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
 
                        /* Colibri SSP */
-                       ulpi_clk_py0 {
+                       ulpi-clk-py0 {
                                nvidia,pins = "ulpi_clk_py0",
                                              "ulpi_dir_py1",
                                              "ulpi_nxt_py2",
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
-                       sdmmc3_dat6_pd3 {
+                       /* Multiplexed SSPFRM, SSPTXD and therefore disabled */
+                       sdmmc3-dat6-pd3 {
                                nvidia,pins = "sdmmc3_dat6_pd3",
                                              "sdmmc3_dat7_pd4";
                                nvidia,function = "spdif";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* Colibri UART_A */
-                       ulpi_data0 {
+                       /* Colibri UART-A */
+                       ulpi-data0 {
                                nvidia,pins = "ulpi_data0_po1",
                                              "ulpi_data1_po2",
                                              "ulpi_data2_po3",
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* Colibri UART_B */
-                       gmi_a16_pj7 {
+                       /* Colibri UART-B */
+                       gmi-a16-pj7 {
                                nvidia,pins = "gmi_a16_pj7",
                                              "gmi_a17_pb0",
                                              "gmi_a18_pb1",
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* Colibri UART_C */
-                       uart2_rxd {
+                       /* Colibri UART-C */
+                       uart2-rxd {
                                nvidia,pins = "uart2_rxd_pc3",
                                              "uart2_txd_pc2";
                                nvidia,function = "uartb";
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* eMMC */
-                       sdmmc4_clk_pcc4 {
+                       /* Colibri USBC_DET */
+                       spdif-out-pk5 {
+                               nvidia,pins =   "spdif_out_pk5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri USBH_PEN */
+                       spi2-cs1-n-pw2 {
+                               nvidia,pins = "spi2_cs1_n_pw2";
+                               nvidia,function = "spi2_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* Colibri USBH_OC */
+                       spi2-cs2-n-pw3, {
+                               nvidia,pins = "spi2_cs2_n_pw3";
+                               nvidia,function = "spi2_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Colibri VGA not supported and therefore disabled */
+                       crt-hsync-pv6 {
+                               nvidia,pins = "crt_hsync_pv6",
+                                             "crt_vsync_pv7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* eMMC (On-module) */
+                       sdmmc4-clk-pcc4 {
                                nvidia,pins = "sdmmc4_clk_pcc4",
+                                             "sdmmc4_cmd_pt7",
                                              "sdmmc4_rst_n_pcc3";
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
-                       sdmmc4_dat0_paa0 {
+                       sdmmc4-dat0-paa0 {
                                nvidia,pins = "sdmmc4_dat0_paa0",
                                              "sdmmc4_dat1_paa1",
                                              "sdmmc4_dat2_paa2",
                                nvidia,function = "sdmmc4";
                                nvidia,pull = <TEGRA_PIN_PULL_UP>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* LAN_EXT_WAKEUP#, LAN_PME (On-module) */
+                       pex-l0-rst-n-pdd1 {
+                               nvidia,pins = "pex_l0_rst_n_pdd1",
+                                             "pex_wake_n_pdd3";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+                       /* LAN_V_BUS, LAN_RESET# (On-module) */
+                       pex-l0-clkreq-n-pdd2 {
+                               nvidia,pins = "pex_l0_clkreq_n_pdd2",
+                                             "pex_l0_prsnt_n_pdd0";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       /* nBATT_FAULT(SENSE), nVDD_FAULT(SENSE) */
+                       pex-l2-rst-n-pcc6 {
+                               nvidia,pins = "pex_l2_rst_n_pcc6",
+                                             "pex_l2_prsnt_n_pdd7";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                       };
+
+                       /* Not connected and therefore disabled */
+                       clk1-req-pee2 {
+                               nvidia,pins = "clk1_req_pee2",
+                                             "pex_l1_prsnt_n_pdd4";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       clk2-req-pcc5 {
+                               nvidia,pins = "clk2_req_pcc5",
+                                             "clk3_out_pee0",
+                                             "clk3_req_pee1",
+                                             "clk_32k_out_pa0",
+                                             "hdmi_cec_pee3",
+                                             "sys_clk_req_pz5";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       gmi-dqs-pi2 {
+                               nvidia,pins = "gmi_dqs_pi2",
+                                             "kb_col2_pq2",
+                                             "kb_col3_pq3",
+                                             "kb_col4_pq4",
+                                             "kb_col5_pq5",
+                                             "kb_row4_pr4";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb-col0-pq0 {
+                               nvidia,pins = "kb_col0_pq0",
+                                             "kb_col1_pq1",
+                                             "kb_col6_pq6",
+                                             "kb_col7_pq7",
+                                             "kb_row5_pr5",
+                                             "kb_row6_pr6",
+                                             "kb_row7_pr7",
+                                             "kb_row9_ps1";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       kb-row0-pr0 {
+                               nvidia,pins = "kb_row0_pr0",
+                                             "kb_row1_pr1",
+                                             "kb_row2_pr2",
+                                             "kb_row3_pr3";
+                               nvidia,function = "rsvd3";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+                       };
+                       lcd-pwr2-pc6 {
+                               nvidia,pins = "lcd_pwr2_pc6";
+                               nvidia,function = "hdcp";
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
                        /* Power I2C (On-module) */
-                       pwr_i2c_scl_pz6 {
+                       pwr-i2c-scl-pz6 {
                                nvidia,pins = "pwr_i2c_scl_pz6",
                                              "pwr_i2c_sda_pz7";
                                nvidia,function = "i2cpwr";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-                               nvidia,lock = <TEGRA_PIN_DISABLE>;
                                nvidia,open-drain = <TEGRA_PIN_ENABLE>;
                        };
 
                         * temperature sensor therefore requires disabling for
                         * now
                         */
-                       lcd_dc1_pd2 {
+                       lcd-dc1-pd2 {
                                nvidia,pins = "lcd_dc1_pd2";
                                nvidia,function = "rsvd3";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+                               nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                        };
 
-                       /* TOUCH_PEN_INT# */
+                       /* TOUCH_PEN_INT# (On-module) */
                        pv0 {
                                nvidia,pins = "pv0";
                                nvidia,function = "rsvd1";
                };
        };
 
-       hdmiddc: i2c@7000c700 {
+       serial@70006040 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       serial@70006300 {
+               compatible = "nvidia,tegra30-hsuart";
+       };
+
+       hdmi_ddc: i2c@7000c700 {
                clock-frequency = <10000>;
        };
 
        /*
         * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and
-        * touch screen controller
+        * touch screen controller (On-module)
         */
        i2c@7000d000 {
                status = "okay";
                sgtl5000: codec@a {
                        compatible = "fsl,sgtl5000";
                        reg = <0x0a>;
-                       VDDA-supply = <&sys_3v3_reg>;
-                       VDDIO-supply = <&sys_3v3_reg>;
+                       VDDA-supply = <&reg_module_3v3_audio>;
+                       VDDD-supply = <&reg_1v8_vio>;
+                       VDDIO-supply = <&reg_module_3v3>;
                        clocks = <&tegra_car TEGRA30_CLK_EXTERN1>;
                };
 
-               pmic: tps65911@2d {
+               pmic: pmic@2d {
                        compatible = "ti,tps65911";
                        reg = <0x2d>;
 
                        #gpio-cells = <2>;
                        gpio-controller;
 
-                       vcc1-supply = <&sys_3v3_reg>;
-                       vcc2-supply = <&sys_3v3_reg>;
-                       vcc3-supply = <&vio_reg>;
-                       vcc4-supply = <&sys_3v3_reg>;
-                       vcc5-supply = <&sys_3v3_reg>;
-                       vcc6-supply = <&vio_reg>;
-                       vcc7-supply = <&charge_pump_5v0_reg>;
-                       vccio-supply = <&sys_3v3_reg>;
+                       vcc1-supply = <&reg_module_3v3>;
+                       vcc2-supply = <&reg_module_3v3>;
+                       vcc3-supply = <&reg_1v8_vio>;
+                       vcc4-supply = <&reg_module_3v3>;
+                       vcc5-supply = <&reg_module_3v3>;
+                       vcc6-supply = <&reg_1v8_vio>;
+                       vcc7-supply = <&reg_5v0_charge_pump>;
+                       vccio-supply = <&reg_module_3v3>;
 
                        regulators {
-                               /* SW1: +V1.35_VDDIO_DDR */
                                vdd1_reg: vdd1 {
-                                       regulator-name = "vddio_ddr_1v35";
+                                       regulator-name = "+V1.35_VDDIO_DDR";
                                        regulator-min-microvolt = <1350000>;
                                        regulator-max-microvolt = <1350000>;
                                        regulator-always-on;
 
                                /* SW2: unused */
 
-                               /* SW CTRL: +V1.0_VDD_CPU */
                                vddctrl_reg: vddctrl {
-                                       regulator-name = "vdd_cpu,vdd_sys";
+                                       regulator-name = "+V1.0_VDD_CPU";
                                        regulator-min-microvolt = <1150000>;
                                        regulator-max-microvolt = <1150000>;
                                        regulator-always-on;
                                };
 
-                               /* SWIO: +V1.8 */
-                               vio_reg: vio {
-                                       regulator-name = "vdd_1v8_gen";
+                               reg_1v8_vio: vio {
+                                       regulator-name = "+V1.8";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <1800000>;
                                        regulator-always-on;
                                /*
                                 * EN_+V3.3 switching via FET:
                                 * +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
-                                * see also 3v3 fixed supply
+                                * see also +V3.3 fixed supply
                                 */
                                ldo2_reg: ldo2 {
-                                       regulator-name = "en_3v3";
+                                       regulator-name = "EN_+V3.3";
                                        regulator-min-microvolt = <3300000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-always-on;
 
                                /* LDO3: unused */
 
-                               /* +V1.2_VDD_RTC */
                                ldo4_reg: ldo4 {
-                                       regulator-name = "vdd_rtc";
+                                       regulator-name = "+V1.2_VDD_RTC";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
 
                                /*
                                 * +V2.8_AVDD_VDAC:
-                                * only required for analog RGB
+                                * only required for (unsupported) analog RGB
                                 */
                                ldo5_reg: ldo5 {
-                                       regulator-name = "avdd_vdac";
+                                       regulator-name = "+V2.8_AVDD_VDAC";
                                        regulator-min-microvolt = <2800000>;
                                        regulator-max-microvolt = <2800000>;
                                        regulator-always-on;
                                 * granularity
                                 */
                                ldo6_reg: ldo6 {
-                                       regulator-name = "avdd_plle";
+                                       regulator-name = "+V1.05_AVDD_PLLE";
                                        regulator-min-microvolt = <1100000>;
                                        regulator-max-microvolt = <1100000>;
                                };
 
-                               /* +V1.2_AVDD_PLL */
                                ldo7_reg: ldo7 {
-                                       regulator-name = "avdd_pll";
+                                       regulator-name = "+V1.2_AVDD_PLL";
                                        regulator-min-microvolt = <1200000>;
                                        regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                };
 
-                               /* +V1.0_VDD_DDR_HS */
                                ldo8_reg: ldo8 {
-                                       regulator-name = "vdd_ddr_hs";
+                                       regulator-name = "+V1.0_VDD_DDR_HS";
                                        regulator-min-microvolt = <1000000>;
                                        regulator-max-microvolt = <1000000>;
                                        regulator-always-on;
                };
 
                /* STMPE811 touch screen controller */
-               stmpe811@41 {
+               touchscreen@41 {
                        compatible = "st,stmpe811";
                        reg = <0x41>;
-                       interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
-                       interrupt-parent = <&gpio>;
+                       irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
                        interrupt-controller;
                        id = <0>;
                        blocks = <0x5>;
 
                /*
                 * LM95245 temperature sensor
-                * Note: OVERT_N directly connected to PMIC PWRDN
+                * Note: OVERT1# directly connected to TPS65911 PMIC PWRDN
                 */
                temp-sensor@4c {
                        compatible = "national,lm95245";
                };
 
                /* SW: +V1.2_VDD_CORE */
-               tps62362@60 {
+               regulator@60 {
                        compatible = "ti,tps62362";
                        reg = <0x60>;
 
                nvidia,core-pwr-off-time = <0>;
                nvidia,core-power-req-active-high;
                nvidia,sys-clock-req-active-high;
+
+               /* Set DEV_OFF bit in DCDC control register of TPS65911 PMIC */
+               i2c-thermtrip {
+                       nvidia,i2c-controller-id = <4>;
+                       nvidia,bus-addr = <0x2d>;
+                       nvidia,reg-addr = <0x3f>;
+                       nvidia,reg-data = <0x1>;
+               };
+       };
+
+       hda@70030000 {
+               status = "okay";
        };
 
        ahub@70080000 {
                status = "okay";
                bus-width = <8>;
                non-removable;
+               vmmc-supply = <&reg_module_3v3>; /* VCC */
+               vqmmc-supply = <&reg_1v8_vio>; /* VCCQ */
+               mmc-ddr-1_8v;
        };
 
-       /* EHCI instance 1: USB2_DP/N -> AX88772B */
+       /* EHCI instance 1: USB2_DP/N -> AX88772B (On-module) */
        usb@7d004000 {
                status = "okay";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               asix@1 {
+                       reg = <1>;
+                       local-mac-address = [00 00 00 00 00 00];
+               };
        };
 
        usb-phy@7d004000 {
                status = "okay";
-               nvidia,is-wired = <1>;
+               vbus-supply = <&reg_lan_v_bus>;
        };
 
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
+       clk32k_in: xtal1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
 
-               clk32k_in: clk@0 {
-                       compatible = "fixed-clock";
-                       reg = <0>;
-                       #clock-cells = <0>;
-                       clock-frequency = <32768>;
-               };
+       reg_1v8_avdd_hdmi_pll: regulator-1v8-avdd-hdmi-pll {
+               compatible = "regulator-fixed";
+               regulator-name = "+V1.8_AVDD_HDMI_PLL";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               enable-active-high;
+               gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_1v8_vio>;
        };
 
-       regulators {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
+       reg_3v3_avdd_hdmi: regulator-3v3-avdd-hdmi {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AVDD_HDMI";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_module_3v3>;
+       };
 
-               avdd_hdmi_pll_1v8_reg: regulator@100 {
-                       compatible = "regulator-fixed";
-                       reg = <100>;
-                       regulator-name = "+V1.8_AVDD_HDMI_PLL";
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       enable-active-high;
-                       gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
-                       vin-supply = <&vio_reg>;
-               };
+       reg_5v0_charge_pump: regulator-5v0-charge-pump {
+               compatible = "regulator-fixed";
+               regulator-name = "+V5.0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
 
-               sys_3v3_reg: regulator@101 {
-                       compatible = "regulator-fixed";
-                       reg = <101>;
-                       regulator-name = "3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-always-on;
-               };
+       reg_lan_v_bus: regulator-lan-v-bus {
+               compatible = "regulator-fixed";
+               regulator-name = "LAN_V_BUS";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&gpio TEGRA_GPIO(DD, 2) GPIO_ACTIVE_HIGH>;
+       };
 
-               avdd_hdmi_3v3_reg: regulator@102 {
-                       compatible = "regulator-fixed";
-                       reg = <102>;
-                       regulator-name = "+V3.3_AVDD_HDMI";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       enable-active-high;
-                       gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
-                       vin-supply = <&sys_3v3_reg>;
-               };
+       reg_module_3v3: regulator-module-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
 
-               charge_pump_5v0_reg: regulator@103 {
-                       compatible = "regulator-fixed";
-                       reg = <103>;
-                       regulator-name = "5v0";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       regulator-always-on;
-               };
+       reg_module_3v3_audio: regulator-module-3v3-audio {
+               compatible = "regulator-fixed";
+               regulator-name = "+V3.3_AUDIO_AVDD_S";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
        };
 
        sound {
                clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
+
+&gpio {
+       lan-reset-n {
+               gpio-hog;
+               gpios = <TEGRA_GPIO(DD, 0) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "LAN_RESET#";
+       };
+};
index a6781f6533105e7e27a7bb1e9da8f066cc1814a8..d2b553f76719070e58284a49c3b62fd2c0c491be 100644 (file)
                nvidia,elastic-limit = <16>;
                nvidia,term-range-adj = <6>;
                nvidia,xcvr-setup = <51>;
-               nvidia.xcvr-setup-use-fuses;
+               nvidia,xcvr-setup-use-fuses;
                nvidia,xcvr-lsfslew = <1>;
                nvidia,xcvr-lsrslew = <1>;
                nvidia,xcvr-hsslew = <32>;
                nvidia,elastic-limit = <16>;
                nvidia,term-range-adj = <6>;
                nvidia,xcvr-setup = <51>;
-               nvidia.xcvr-setup-use-fuses;
+               nvidia,xcvr-setup-use-fuses;
                nvidia,xcvr-lsfslew = <2>;
                nvidia,xcvr-lsrslew = <2>;
                nvidia,xcvr-hsslew = <32>;
                nvidia,elastic-limit = <16>;
                nvidia,term-range-adj = <6>;
                nvidia,xcvr-setup = <51>;
-               nvidia.xcvr-setup-use-fuses;
+               nvidia,xcvr-setup-use-fuses;
                nvidia,xcvr-lsfslew = <2>;
                nvidia,xcvr-lsrslew = <2>;
                nvidia,xcvr-hsslew = <32>;
                             <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&{/cpus/cpu@0}>,
+                                    <&{/cpus/cpu@1}>,
+                                    <&{/cpus/cpu@2}>,
+                                    <&{/cpus/cpu@3}>;
        };
 };
index 21407e159bf77868a35a1ab6c75dfd9850716f2d..3aaca10f6644ab25f739403ae4550105b40763c3 100644 (file)
        status = "okay";
 };
 
+&sd {
+       status = "okay";
+};
+
 &usb0 {
        status = "okay";
 };
index 37950ad2de7c81024adc730a10f14b1c2d16488b..b73d594b6dcd472de158e2e98a9223719160624b 100644 (file)
                        cache-level = <2>;
                };
 
+               spi: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        };
                };
 
+               sd: sdhc@5a400000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a400000 0x200>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default", "uhs";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       pinctrl-1 = <&pinctrl_sd_uhs>;
+                       clocks = <&mio_clk 0>;
+                       reset-names = "host", "bridge";
+                       resets = <&mio_rst 0>, <&mio_rst 3>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       sd-uhs-sdr12;
+                       sd-uhs-sdr25;
+                       sd-uhs-sdr50;
+               };
+
+               emmc: sdhc@5a500000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a500000 0x200>;
+                       interrupts = <0 78 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_emmc>;
+                       clocks = <&mio_clk 1>;
+                       reset-names = "host", "bridge", "hw";
+                       resets = <&mio_rst 1>, <&mio_rst 4>, <&mio_rst 6>;
+                       bus-width = <8>;
+                       cap-mmc-highspeed;
+                       cap-mmc-hw-reset;
+                       non-removable;
+               };
+
                usb0: usb@5a800100 {
                        compatible = "socionext,uniphier-ehci", "generic-ehci";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand2cs>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
index a0a44a422e1259a8688051c978f9cd68ecedc3d5..3d9080ee7aef73b5a1642757d5931b5345e698a6 100644 (file)
        status = "okay";
 };
 
+&sd {
+       status = "okay";
+};
+
 &eth {
        status = "okay";
        phy-handle = <&ethphy>;
        };
 };
 
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
 &nand {
        status = "okay";
 };
index 51f0e69f49fd1aad851f3f7d065b00190d50a0ce..1fee5ffbfb9c9e463a500d88c5965e5267e5c83e 100644 (file)
                function = "sd";
        };
 
+       pinctrl_sd_uhs: sd-uhs {
+               groups = "sd";
+               function = "sd";
+       };
+
        pinctrl_sd1: sd1 {
                groups = "sd1";
                function = "sd1";
        };
 
+       pinctrl_spi0: spi0 {
+               groups = "spi0";
+               function = "spi0";
+       };
+
+       pinctrl_spi1: spi1 {
+               groups = "spi1";
+               function = "spi1";
+       };
+
+       pinctrl_spi2: spi2 {
+               groups = "spi2";
+               function = "spi2";
+       };
+
+       pinctrl_spi3: spi3 {
+               groups = "spi3";
+               function = "spi3";
+       };
+
        pinctrl_system_bus: system-bus {
                groups = "system_bus", "system_bus_cs1";
                function = "system_bus";
index db1b08935ae5a2321be27b2f17e4f325e58ac9f8..92cc48dd86d030ca59f68f96baa5746a6e4c94c6 100644 (file)
        status = "okay";
 };
 
+&sd {
+       status = "okay";
+};
+
 &usb2 {
        status = "okay";
 };
                reg = <1>;
        };
 };
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
index efb084983b82ef5229e922084c120d4aef3d9486..28038b17bbb3a784975ee4a5add93478ee1752a1 100644 (file)
        status = "okay";
 };
 
+&sd {
+       status = "okay";
+};
+
 &usb2 {
        status = "okay";
 };
        };
 };
 
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
 &nand {
        status = "okay";
 };
index dac4d6679a327e4f09312c6b0e8e9ac5358d38f0..dda1a2f214a8bfb2b4faa47c2853938056e189f6 100644 (file)
        status = "okay";
 };
 
+&emmc {
+       status = "okay";
+};
+
 &eth {
        status = "okay";
        phy-handle = <&ethphy>;
                reg = <1>;
        };
 };
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
index 49539f0352193cb4e1c768e7f13ee6ce5b5215c8..0beb606cf3c8e6443fd5aa2f2c99892eaee98ae9 100644 (file)
                        cache-level = <2>;
                };
 
+               spi0: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        };
                };
 
+               sd: sdhc@5a400000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a400000 0x200>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default", "uhs";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       pinctrl-1 = <&pinctrl_sd_uhs>;
+                       clocks = <&mio_clk 0>;
+                       reset-names = "host", "bridge";
+                       resets = <&mio_rst 0>, <&mio_rst 3>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       sd-uhs-sdr12;
+                       sd-uhs-sdr25;
+                       sd-uhs-sdr50;
+               };
+
+               emmc: sdhc@5a500000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a500000 0x200>;
+                       interrupts = <0 78 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_emmc>;
+                       clocks = <&mio_clk 1>;
+                       reset-names = "host", "bridge", "hw";
+                       resets = <&mio_rst 1>, <&mio_rst 4>, <&mio_rst 6>;
+                       bus-width = <8>;
+                       cap-mmc-highspeed;
+                       cap-mmc-hw-reset;
+                       non-removable;
+               };
+
+               sd1: sdhc@5a600000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a600000 0x200>;
+                       interrupts = <0 85 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_sd1>;
+                       clocks = <&mio_clk 2>;
+                       reset-names = "host", "bridge";
+                       resets = <&mio_rst 2>, <&mio_rst 5>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+               };
+
                usb2: usb@5a800100 {
                        compatible = "socionext,uniphier-ehci", "generic-ehci";
                        status = "disabled";
                                 <&mio_clk 12>;
                        resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
                                 <&mio_rst 12>;
+                       phy-names = "usb";
+                       phys = <&usb_phy0>;
                        has-transaction-translator;
                };
 
                                 <&mio_clk 13>;
                        resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
                                 <&mio_rst 13>;
+                       phy-names = "usb";
+                       phys = <&usb_phy1>;
                        has-transaction-translator;
                };
 
                        pinctrl: pinctrl {
                                compatible = "socionext,uniphier-pro4-pinctrl";
                        };
+
+                       usb-phy {
+                               compatible = "socionext,uniphier-pro4-usb2-phy";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               usb_phy0: phy@0 {
+                                       reg = <0>;
+                                       #phy-cells = <0>;
+                               };
+
+                               usb_phy1: phy@1 {
+                                       reg = <1>;
+                                       #phy-cells = <0>;
+                               };
+
+                               usb_phy2: phy@2 {
+                                       reg = <2>;
+                                       #phy-cells = <0>;
+                                       vbus-supply = <&usb0_vbus>;
+                               };
+
+                               usb_phy3: phy@3 {
+                                       reg = <3>;
+                                       #phy-cells = <0>;
+                                       vbus-supply = <&usb1_vbus>;
+                               };
+                       };
                };
 
                soc-glue@5f900000 {
                        };
                };
 
+               usb0: usb@65a00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65a00000 0xcd00>;
+                       interrupt-names = "host", "peripheral";
+                       interrupts = <0 134 4>, <0 135 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb0>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>;
+                       resets = <&usb0_rst 4>;
+                       phys = <&usb_phy2>, <&usb0_ssphy>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65b00000 {
+                       compatible = "socionext,uniphier-pro4-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65b00000 0x100>;
+
+                       usb0_vbus: regulator@0 {
+                               compatible = "socionext,uniphier-pro4-usb3-regulator";
+                               reg = <0 0x10>;
+                               clock-names = "gio", "link";
+                               clocks = <&sys_clk 12>, <&sys_clk 14>;
+                               reset-names = "gio", "link";
+                               resets = <&sys_rst 12>, <&sys_rst 14>;
+                       };
+
+                       usb0_ssphy: ss-phy@10 {
+                               compatible = "socionext,uniphier-pro4-usb3-ssphy";
+                               reg = <0x10 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "gio", "link";
+                               clocks = <&sys_clk 12>, <&sys_clk 14>;
+                               reset-names = "gio", "link";
+                               resets = <&sys_rst 12>, <&sys_rst 14>;
+                               vbus-supply = <&usb0_vbus>;
+                       };
+
+                       usb0_rst: reset@40 {
+                               compatible = "socionext,uniphier-pro4-usb3-reset";
+                               reg = <0x40 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "gio", "link";
+                               clocks = <&sys_clk 12>, <&sys_clk 14>;
+                               reset-names = "gio", "link";
+                               resets = <&sys_rst 12>, <&sys_rst 14>;
+                       };
+               };
+
+               usb1: usb@65c00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65c00000 0xcd00>;
+                       interrupt-names = "host", "peripheral";
+                       interrupts = <0 137 4>, <0 138 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb1>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>;
+                       resets = <&usb1_rst 4>;
+                       phys = <&usb_phy3>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65d00000 {
+                       compatible = "socionext,uniphier-pro4-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65d00000 0x100>;
+
+                       usb1_vbus: regulator@0 {
+                               compatible = "socionext,uniphier-pro4-usb3-regulator";
+                               reg = <0 0x10>;
+                               clock-names = "gio", "link";
+                               clocks = <&sys_clk 12>, <&sys_clk 15>;
+                               reset-names = "gio", "link";
+                               resets = <&sys_rst 12>, <&sys_rst 15>;
+                       };
+
+                       usb1_rst: reset@40 {
+                               compatible = "socionext,uniphier-pro4-usb3-reset";
+                               reg = <0x40 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "gio", "link";
+                               clocks = <&sys_clk 12>, <&sys_clk 15>;
+                               reset-names = "gio", "link";
+                               resets = <&sys_rst 12>, <&sys_rst 15>;
+                       };
+               };
+
                nand: nand@68000000 {
                        compatible = "socionext,uniphier-denali-nand-v5a";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
index 06c2cef91ec73aee07d028fb0301ec15192fd2b1..3657387394126b802de7e2eb918f609de4585960 100644 (file)
                        cache-level = <3>;
                };
 
+               spi0: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi1: spi@54006100 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006100 0x100>;
+                       interrupts = <0 216 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi1>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand2cs>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
+
+               emmc: sdhc@68400000 {
+                       compatible = "socionext,uniphier-sd-v3.1";
+                       status = "disabled";
+                       reg = <0x68400000 0x800>;
+                       interrupts = <0 78 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_emmc>;
+                       clocks = <&sd_clk 1>;
+                       reset-names = "host", "hw";
+                       resets = <&sd_rst 1>, <&sd_rst 6>;
+                       bus-width = <8>;
+                       cap-mmc-highspeed;
+                       cap-mmc-hw-reset;
+                       non-removable;
+               };
+
+               sd: sdhc@68800000 {
+                       compatible = "socionext,uniphier-sd-v3.1";
+                       status = "disabled";
+                       reg = <0x68800000 0x800>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default", "uhs";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       pinctrl-1 = <&pinctrl_sd_uhs>;
+                       clocks = <&sd_clk 0>;
+                       reset-names = "host";
+                       resets = <&sd_rst 0>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       sd-uhs-sdr12;
+                       sd-uhs-sdr25;
+                       sd-uhs-sdr50;
+               };
        };
 };
 
index bed26b8ed9a3d6f4ac8c8766350002b74597b722..e27fd4f2a5690802fb317eb5e9359c3804acbeaa 100644 (file)
        };
 };
 
+&emmc {
+       status = "okay";
+};
+
 &eth {
        status = "okay";
        phy-handle = <&ethphy>;
                reg = <1>;
        };
 };
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
index b13d2d16ddad88a02d9331e642a53cacb3cdb0b8..23fe42b7408bb4036f0b588a852660aa2b5adb28 100644 (file)
        status = "okay";
 };
 
+&emmc {
+       status = "okay";
+};
+
 &eth {
        status = "okay";
        phy-handle = <&ethphy>;
@@ -87,3 +91,7 @@
                reg = <1>;
        };
 };
+
+&usb0 {
+       status = "okay";
+};
index e2d1a22c5950d5310838222049891f9ea6fe313d..8d20e9548e399e4534c651d7b903feb9131758a8 100644 (file)
                        cache-level = <2>;
                };
 
+               spi0: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi1: spi@54006100 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006100 0x100>;
+                       interrupts = <0 216 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi1>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        };
                };
 
+               emmc: sdhc@5a000000 {
+                       compatible = "socionext,uniphier-sd-v3.1.1";
+                       status = "disabled";
+                       reg = <0x5a000000 0x800>;
+                       interrupts = <0 78 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_emmc>;
+                       clocks = <&sd_clk 1>;
+                       reset-names = "host", "hw";
+                       resets = <&sd_rst 1>, <&sd_rst 6>;
+                       bus-width = <8>;
+                       cap-mmc-highspeed;
+                       cap-mmc-hw-reset;
+                       non-removable;
+               };
+
+               sd: sdhc@5a400000 {
+                       compatible = "socionext,uniphier-sd-v3.1.1";
+                       status = "disabled";
+                       reg = <0x5a400000 0x800>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default", "uhs";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       pinctrl-1 = <&pinctrl_sd_uhs>;
+                       clocks = <&sd_clk 0>;
+                       reset-names = "host";
+                       resets = <&sd_rst 0>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       sd-uhs-sdr12;
+                       sd-uhs-sdr25;
+                       sd-uhs-sdr50;
+               };
+
                soc_glue: soc-glue@5f800000 {
                        compatible = "socionext,uniphier-pxs2-soc-glue",
                                     "simple-mfd", "syscon";
                        };
                };
 
+               usb0: usb@65a00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65a00000 0xcd00>;
+                       interrupt-names = "host", "peripheral";
+                       interrupts = <0 134 4>, <0 135 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 14>, <&sys_clk 14>, <&sys_clk 14>;
+                       resets = <&usb0_rst 15>;
+                       phys = <&usb0_hsphy0>, <&usb0_hsphy1>,
+                              <&usb0_ssphy0>, <&usb0_ssphy1>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65b00000 {
+                       compatible = "socionext,uniphier-pxs2-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65b00000 0x400>;
+
+                       usb0_rst: reset@0 {
+                               compatible = "socionext,uniphier-pxs2-usb3-reset";
+                               reg = <0x0 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb0_vbus0: regulator@100 {
+                               compatible = "socionext,uniphier-pxs2-usb3-regulator";
+                               reg = <0x100 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb0_vbus1: regulator@110 {
+                               compatible = "socionext,uniphier-pxs2-usb3-regulator";
+                               reg = <0x110 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb0_hsphy0: hs-phy@200 {
+                               compatible = "socionext,uniphier-pxs2-usb3-hsphy";
+                               reg = <0x200 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 16>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 16>;
+                               vbus-supply = <&usb0_vbus0>;
+                       };
+
+                       usb0_hsphy1: hs-phy@210 {
+                               compatible = "socionext,uniphier-pxs2-usb3-hsphy";
+                               reg = <0x210 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 16>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 16>;
+                               vbus-supply = <&usb0_vbus1>;
+                       };
+
+                       usb0_ssphy0: ss-phy@300 {
+                               compatible = "socionext,uniphier-pxs2-usb3-ssphy";
+                               reg = <0x300 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 17>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 17>;
+                               vbus-supply = <&usb0_vbus0>;
+                       };
+
+                       usb0_ssphy1: ss-phy@310 {
+                               compatible = "socionext,uniphier-pxs2-usb3-ssphy";
+                               reg = <0x310 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 18>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 18>;
+                               vbus-supply = <&usb0_vbus1>;
+                       };
+               };
+
+               usb1: usb@65c00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65c00000 0xcd00>;
+                       interrupt-names = "host", "peripheral";
+                       interrupts = <0 137 4>, <0 138 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 15>, <&sys_clk 15>, <&sys_clk 15>;
+                       resets = <&usb1_rst 15>;
+                       phys = <&usb1_hsphy0>, <&usb1_hsphy1>, <&usb1_ssphy0>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65d00000 {
+                       compatible = "socionext,uniphier-pxs2-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65d00000 0x400>;
+
+                       usb1_rst: reset@0 {
+                               compatible = "socionext,uniphier-pxs2-usb3-reset";
+                               reg = <0x0 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 15>;
+                               reset-names = "link";
+                               resets = <&sys_rst 15>;
+                       };
+
+                       usb1_vbus0: regulator@100 {
+                               compatible = "socionext,uniphier-pxs2-usb3-regulator";
+                               reg = <0x100 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 15>;
+                               reset-names = "link";
+                               resets = <&sys_rst 15>;
+                       };
+
+                       usb1_vbus1: regulator@110 {
+                               compatible = "socionext,uniphier-pxs2-usb3-regulator";
+                               reg = <0x110 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 15>;
+                               reset-names = "link";
+                               resets = <&sys_rst 15>;
+                       };
+
+                       usb1_hsphy0: hs-phy@200 {
+                               compatible = "socionext,uniphier-pxs2-usb3-hsphy";
+                               reg = <0x200 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 15>, <&sys_clk 20>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 15>, <&sys_rst 20>;
+                               vbus-supply = <&usb1_vbus0>;
+                       };
+
+                       usb1_hsphy1: hs-phy@210 {
+                               compatible = "socionext,uniphier-pxs2-usb3-hsphy";
+                               reg = <0x210 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 15>, <&sys_clk 20>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 15>, <&sys_rst 20>;
+                               vbus-supply = <&usb1_vbus1>;
+                       };
+
+                       usb1_ssphy0: ss-phy@300 {
+                               compatible = "socionext,uniphier-pxs2-usb3-ssphy";
+                               reg = <0x300 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 15>, <&sys_clk 21>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 15>, <&sys_rst 21>;
+                               vbus-supply = <&usb1_vbus0>;
+                       };
+               };
+
                nand: nand@68000000 {
                        compatible = "socionext,uniphier-denali-nand-v5b";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand2cs>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
index fe386fa2ea4bee8182cebbe8a9e66464aa301de5..01bf94c6b93aeabacb954fbcf1dd1efdf02b313b 100644 (file)
        status = "okay";
 };
 
+&sd {
+       status = "okay";
+};
+
 &usb0 {
        status = "okay";
 };
index e9b9b4f3c5581606895467a57bc79eb42534c01b..f7fcf6b45995953e08dd0157ff6d14f4d00c97ec 100644 (file)
                        cache-level = <2>;
                };
 
+               spi: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        };
                };
 
+               sd: sdhc@5a400000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a400000 0x200>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default", "uhs";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       pinctrl-1 = <&pinctrl_sd_uhs>;
+                       clocks = <&mio_clk 0>;
+                       reset-names = "host", "bridge";
+                       resets = <&mio_rst 0>, <&mio_rst 3>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       sd-uhs-sdr12;
+                       sd-uhs-sdr25;
+                       sd-uhs-sdr50;
+               };
+
+               emmc: sdhc@5a500000 {
+                       compatible = "socionext,uniphier-sd-v2.91";
+                       status = "disabled";
+                       reg = <0x5a500000 0x200>;
+                       interrupts = <0 78 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_emmc>;
+                       clocks = <&mio_clk 1>;
+                       reset-names = "host", "bridge", "hw";
+                       resets = <&mio_rst 1>, <&mio_rst 4>, <&mio_rst 6>;
+                       bus-width = <8>;
+                       cap-mmc-highspeed;
+                       cap-mmc-hw-reset;
+                       non-removable;
+               };
+
                usb0: usb@5a800100 {
                        compatible = "socionext,uniphier-ehci", "generic-ehci";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand2cs>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
index 5f61d36090270131ed6c8f91a2f93f3ee92ef5e3..6f4f60ba5429c8dedcd3a9863c5558a5e0b8199d 100644 (file)
                        clock-names = "apb_pclk";
                };
 
-               ssp@101f4000 {
+               spi@101f4000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x101f4000 0x1000>;
                        interrupts = <11>;
index bbff0115e2fb9451ca440a77a5ba2d64c5989ce2..76a0949df4a88b6693e769563b8393dc3506b32d 100644 (file)
@@ -1,43 +1,6 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2013 Freescale Semiconductor, Inc.
 
 #include "vfxxx.dtsi"
 #include <dt-bindings/interrupt-controller/arm-gic.h>
index 6be7a828ae64e3d44c2831b555741f86c3428719..59fceea8805d83186eb6c3ca9ed39543ba4b806a 100644 (file)
@@ -1,43 +1,6 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2013 Freescale Semiconductor, Inc.
 
 /dts-v1/;
 #include "vf610.dtsi"
index 37777cf22e67b036a5a0c345a74f974068423b7e..b76c3d0413df0eec54f5716bc54918f47f9f6faf 100644 (file)
                 regulator-min-microvolt = <3300000>;
                 regulator-max-microvolt = <3300000>;
        };
+
+       sff: sfp {
+               compatible = "sff,sff";
+               pinctrl-0 = <&pinctrl_optical>;
+               pinctrl-names = "default";
+               i2c-bus = <&i2c0>;
+               los-gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+               tx-disable-gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+       };
 };
 
 &adc0 {
        non-removable;
        no-1-8-v;
        keep-power-in-suspend;
+       no-sdio;
+       no-sd;
        status = "okay";
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_esdhc1>;
        bus-width = <4>;
+       no-sdio;
        status = "okay";
 };
 
                                        label = "eth_cu_1000_3";
                                };
 
+                               port@5 {
+                                       reg = <5>;
+                                       label = "eth_fc_1000_1";
+                                       phy-mode = "1000base-x";
+                                       managed = "in-band-status";
+                                       sfp = <&sff>;
+                               };
+
                                port@6 {
                                        reg = <6>;
                                        label = "cpu";
                >;
        };
 
+       pinctrl_optical: optical-grp {
+               fsl,pins = <
+               /* SFF SD input */
+               VF610_PAD_PTE27__GPIO_132       0x3061
+
+               /* SFF Transmit disable output */
+               VF610_PAD_PTE13__GPIO_118       0x3043
+               >;
+       };
+
        pinctrl_switch: switch-grp {
                fsl,pins = <
                        VF610_PAD_PTB28__GPIO_98                0x3061
index 0b1e94c6f25bd0867c9eee3c603cd2bf1da8ec7d..6f4a5602cefd510b8fb5df499ff8ad9dfd4330a0 100644 (file)
                                                phy-handle = <&switch1phy4>;
                                        };
 
+                                       port@9 {
+                                               reg = <9>;
+                                               label = "sff2";
+                                               phy-mode = "sgmii";
+                                               managed = "in-band-status";
+                                               sfp = <&sff2>;
+                                       };
 
                                        switch1port10: port@10 {
                                                reg = <10>;
                        #size-cells = <0>;
                };
        };
+
+       sff2: sff2 {
+               /* lower */
+               compatible = "sff,sff";
+               i2c-bus = <&sff2_i2c>;
+               los-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+               tx-disable-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>;
+       };
+
+       sff3: sff3 {
+               /* upper */
+               compatible = "sff,sff";
+               i2c-bus = <&sff3_i2c>;
+               los-gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
+               tx-disable-gpios = <&gpio6 15 GPIO_ACTIVE_HIGH>;
+       };
 };
 
 &dspi0 {
                interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
                gpio-controller;
                interrupt-controller;
-
-               enet_swr_en {
-                       gpio-hog;
-                       gpios = <0 GPIO_ACTIVE_HIGH>;
-                       output-high;
-                       line-name = "enet-swr-en";
-               };
        };
 
        /*
                        reg = <0>;
                };
 
-               i2c@1 {
+               sff2_i2c: i2c@1 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <1>;
-
-                       sfp2: at24c04@50 {
-                               compatible = "atmel,24c02";
-                               reg = <0x50>;
-                       };
                };
 
-               i2c@2 {
+               sff3_i2c: i2c@2 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <2>;
-
-                       sfp3: at24c04@50 {
-                               compatible = "atmel,24c02";
-                               reg = <0x50>;
-                       };
                };
 
                i2c@3 {
index 80fef182c672e8a6ad50dc6b112c99e78aa39cb2..7fd39817f8ab617b6c83769bdba02c0852dfbfb6 100644 (file)
@@ -1,43 +1,7 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2013 Freescale Semiconductor, Inc.
+
 
 #include "vf500.dtsi"
 
index d392794d9c139f139fecfa6938c3ac5cdb69bed5..028e0ec30e0c05d0ccffcb4c2d53deebc4cfc6e4 100644 (file)
@@ -1,43 +1,6 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2013 Freescale Semiconductor, Inc.
 
 #include "vf610-pinfunc.h"
 #include <dt-bindings/clock/vf610-clock.h>
                                status = "disabled";
                        };
 
-                       dspi0: dspi0@4002c000 {
+                       dspi0: spi@4002c000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-dspi";
                                status = "disabled";
                        };
 
-                       dspi1: dspi1@4002d000 {
+                       dspi1: spi@4002d000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-dspi";
                                status = "disabled";
                        };
 
-                       qspi0: quadspi@40044000 {
+                       qspi0: spi@40044000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-qspi";
                                status = "disabled";
                        };
 
-                       dspi2: dspi2@400ac000 {
+                       dspi2: spi@400ac000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-dspi";
                                status = "disabled";
                        };
 
-                       dspi3: dspi3@400ad000 {
+                       dspi3: spi@400ad000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-dspi";
                                status = "disabled";
                        };
 
-                       qspi1: quadspi@400c4000 {
+                       qspi1: spi@400c4000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "fsl,vf610-qspi";
index cc5a3dc2b4a08dc3ceca92112bc6e0206bfd21d1..27cd6cb52f1ba33607db41ce80c6fb502a55837f 100644 (file)
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <7>;
-                       hwmon@52 {
+                       hwmon@34 {
                                compatible = "ti,ucd9248";
-                               reg = <52>;
+                               reg = <0x34>;
                        };
-                       hwmon@53 {
+                       hwmon@35 {
                                compatible = "ti,ucd9248";
-                               reg = <53>;
+                               reg = <0x35>;
                        };
-                       hwmon@54 {
+                       hwmon@36 {
                                compatible = "ti,ucd9248";
-                               reg = <54>;
+                               reg = <0x36>;
                        };
                };
        };
index 0e1bfdd3421ff04f31266051546b23f5b9e3cfd0..0dd352289a45e58150f75896a590873f66773174 100644 (file)
@@ -68,7 +68,7 @@
        status = "okay";
        num-cs = <4>;
        is-decoded-cs = <0>;
-       flash@0 {
+       flash@1 {
                compatible = "sst25wf080", "jedec,spi-nor";
                reg = <1>;
                spi-max-frequency = <1000000>;
index 651913f1afa2a06647addfdb6ae415b567031f66..4ae2c85df3a0078111f1b4aa9a24b695265cee16 100644 (file)
@@ -62,7 +62,7 @@
        status = "okay";
        num-cs = <4>;
        is-decoded-cs = <0>;
-       eeprom: eeprom@0 {
+       eeprom: eeprom@2 {
                at25,byte-len = <8192>;
                at25,addr-mode = <2>;
                at25,page-size = <32>;
index e5ad0708849a2f57d14d6e1f8141f6469d44aeeb..c8e198631d4182511d1bb3dee008ceae4c01f4d2 100644 (file)
@@ -7,6 +7,9 @@ config DMABOUNCE
        bool
        select ZONE_DMA
 
+config KRAIT_L2_ACCESSORS
+       bool
+
 config SHARP_LOCOMO
        bool
 
index 3157be413297e5d22ad3174e2082b5199fc3083c..219a260bbe5f78abec23091e7ad07a7b1e992624 100644 (file)
@@ -7,6 +7,7 @@ obj-y                           += firmware.o
 
 obj-$(CONFIG_SA1111)           += sa1111.o
 obj-$(CONFIG_DMABOUNCE)                += dmabounce.o
+obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o
 obj-$(CONFIG_SHARP_LOCOMO)     += locomo.o
 obj-$(CONFIG_SHARP_PARAM)      += sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)      += scoop.o
diff --git a/arch/arm/common/krait-l2-accessors.c b/arch/arm/common/krait-l2-accessors.c
new file mode 100644 (file)
index 0000000..9a97dda
--- /dev/null
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/spinlock.h>
+#include <linux/export.h>
+
+#include <asm/barrier.h>
+#include <asm/krait-l2-accessors.h>
+
+static DEFINE_RAW_SPINLOCK(krait_l2_lock);
+
+void krait_set_l2_indirect_reg(u32 addr, u32 val)
+{
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&krait_l2_lock, flags);
+       /*
+        * Select the L2 window by poking l2cpselr, then write to the window
+        * via l2cpdr.
+        */
+       asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
+       isb();
+       asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
+       isb();
+
+       raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
+}
+EXPORT_SYMBOL(krait_set_l2_indirect_reg);
+
+u32 krait_get_l2_indirect_reg(u32 addr)
+{
+       u32 val;
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&krait_l2_lock, flags);
+       /*
+        * Select the L2 window by poking l2cpselr, then read from the window
+        * via l2cpdr.
+        */
+       asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
+       isb();
+       asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
+
+       raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
+
+       return val;
+}
+EXPORT_SYMBOL(krait_get_l2_indirect_reg);
index e9bc88937b1e43a7d84fdb0ecf445bdee3625d98..bb6a35fb1dd7017b4644325a4231766cb30b30e3 100644 (file)
@@ -128,7 +128,7 @@ CONFIG_LEDS_TRIGGER_CAMERA=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_BCM2835=y
 CONFIG_STAGING=y
-CONFIG_BCM2835_VCHIQ=m
+CONFIG_SND_BCM2835=m
 CONFIG_MAILBOX=y
 CONFIG_BCM2835_MBOX=y
 # CONFIG_IOMMU_SUPPORT is not set
index 4cd2f4a2bff4e20beb76fd524348aae58fbc3590..8661dd9b064a5cdfd4a8801a8b98e9c9f45d7dc0 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
@@ -10,13 +11,6 @@ CONFIG_EXPERT=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_KPROBES=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_MULTI_V4T=y
 CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
@@ -29,11 +23,17 @@ CONFIG_MACH_PCA100=y
 CONFIG_MACH_IMX27_DT=y
 CONFIG_SOC_IMX1=y
 CONFIG_SOC_IMX25=y
-CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_PM_DEBUG=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=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_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -141,11 +141,9 @@ CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_ULPI=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_ETH=m
-CONFIG_USB_ULPI_BUS=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
index 7eca43ff69bbed1f1d5d431a968826612812ed18..1ad5736c8fa6deb85f77a7efe58c0fd0541723e2 100644 (file)
@@ -2,6 +2,7 @@ CONFIG_KERNEL_LZO=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
@@ -12,11 +13,6 @@ CONFIG_EXPERT=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_MXC=y
 CONFIG_MACH_MX31LILLY=y
@@ -48,7 +44,6 @@ CONFIG_PCI_MSI=y
 CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
-CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_HIGHMEM=y
 CONFIG_FORCE_MAX_ZONEORDER=14
 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
@@ -62,11 +57,17 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ARM_IMX6Q_CPUFREQ=y
 CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
-CONFIG_BINFMT_MISC=m
 CONFIG_PM_DEBUG=y
 CONFIG_PM_TEST_SUSPEND=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -90,6 +91,8 @@ CONFIG_RFKILL_INPUT=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
 CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_IMX_WEIM=y
 CONFIG_CONNECTOR=y
@@ -149,9 +152,12 @@ CONFIG_MICREL_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
-CONFIG_USB_RTL8152=m
+CONFIG_USB_RTL8152=y
+CONFIG_USB_LAN78XX=y
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_USB_NET_MCS7830=y
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
 CONFIG_MWIFIEX_SDIO=m
@@ -211,6 +217,7 @@ CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_SYSCON=y
 CONFIG_POWER_RESET_SYSCON_POWEROFF=y
 CONFIG_POWER_SUPPLY=y
+CONFIG_SENSORS_MC13783_ADC=y
 CONFIG_SENSORS_GPIO_FAN=y
 CONFIG_SENSORS_IIO_HWMON=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
@@ -302,7 +309,6 @@ CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_ULPI=y
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -339,7 +345,6 @@ CONFIG_USB_GADGETFS=m
 CONFIG_USB_FUNCTIONFS=m
 CONFIG_USB_MASS_STORAGE=m
 CONFIG_USB_G_SERIAL=m
-CONFIG_USB_ULPI_BUS=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
@@ -409,6 +414,7 @@ CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_JFFS2_FS=y
 CONFIG_UBIFS_FS=y
 CONFIG_NFS_FS=y
@@ -421,14 +427,6 @@ CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_UTF8=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_PROVE_LOCKING=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_FTRACE is not set
-# CONFIG_ARM_UNWIND is not set
 CONFIG_SECURITYFS=y
 CONFIG_CRYPTO_DEV_FSL_CAAM=y
 CONFIG_CRYPTO_DEV_SAHARA=y
@@ -439,3 +437,10 @@ CONFIG_LIBCRC32C=m
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_PROVE_LOCKING=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
index fc33444e94f05c1fac99976bdeadb4b6e785fd19..63af6234c1b69a20b763470a8a73a989e1d7f747 100644 (file)
@@ -79,6 +79,7 @@ CONFIG_ARCH_R7S72100=y
 CONFIG_ARCH_R8A73A4=y
 CONFIG_ARCH_R8A7740=y
 CONFIG_ARCH_R8A7743=y
+CONFIG_ARCH_R8A7744=y
 CONFIG_ARCH_R8A7745=y
 CONFIG_ARCH_R8A77470=y
 CONFIG_ARCH_R8A7778=y
@@ -282,6 +283,7 @@ CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_MOUSE_CYAPA=m
 CONFIG_MOUSE_ELAN_I2C=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADC=m
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_TOUCHSCREEN_MMS114=m
 CONFIG_TOUCHSCREEN_WM97XX=m
@@ -391,6 +393,7 @@ CONFIG_SPI_S3C64XX=m
 CONFIG_SPI_SH_MSIOF=m
 CONFIG_SPI_SH_HSPI=y
 CONFIG_SPI_SIRF=y
+CONFIG_SPI_STM32=m
 CONFIG_SPI_SUN4I=y
 CONFIG_SPI_SUN6I=y
 CONFIG_SPI_TEGRA114=y
@@ -584,6 +587,7 @@ CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_VIDEO_STI_BDISP=m
 CONFIG_VIDEO_STI_HVA=m
 CONFIG_VIDEO_STI_DELTA=m
+CONFIG_VIDEO_RENESAS_FDP1=m
 CONFIG_VIDEO_RENESAS_JPU=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_V4L_TEST_DRIVERS=y
@@ -614,6 +618,8 @@ CONFIG_DRM_RCAR_LVDS=y
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_FSL_DCU=m
 CONFIG_DRM_TEGRA=y
+CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
+CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
 CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
@@ -625,6 +631,8 @@ CONFIG_DRM_SII9234=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_STI=m
+CONFIG_DRM_STM=m
+CONFIG_DRM_STM_DSI=m
 CONFIG_DRM_VC4=m
 CONFIG_DRM_ETNAVIV=m
 CONFIG_DRM_MXSFB=m
@@ -636,6 +644,7 @@ CONFIG_FB_SIMPLE=y
 CONFIG_LCD_PLATFORM=m
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
+CONFIG_BACKLIGHT_GPIO=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_SOUND=m
@@ -650,6 +659,7 @@ CONFIG_SND_SOC=m
 CONFIG_SND_ATMEL_SOC=m
 CONFIG_SND_ATMEL_SOC_WM8904=m
 CONFIG_SND_ATMEL_SOC_PDMIC=m
+CONFIG_SND_ATMEL_SOC_I2S=m
 CONFIG_SND_BCM2835_SOC_I2S=m
 CONFIG_SND_SOC_FSL_SAI=m
 CONFIG_SND_SOC_ROCKCHIP=m
@@ -771,6 +781,7 @@ CONFIG_MMC_ATMELMCI=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_MMC_SDHI=y
+CONFIG_MMC_UNIPHIER=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_ROCKCHIP=y
@@ -943,6 +954,8 @@ CONFIG_PHY_STIH407_USB=y
 CONFIG_PHY_STM32_USBPHYC=y
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_PHY_DM816X_USB=m
+CONFIG_PHY_UNIPHIER_USB3=y
+CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_OMAP_USB2=y
 CONFIG_TI_PIPE3=y
 CONFIG_TWL4030_USB=m
index 7b82128575351c9285ca5137e79ed73b9741462c..38480596c44983de48d7ff37ea7e274b4f1eaad5 100644 (file)
@@ -1,6 +1,7 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_TASKSTATS=y
 CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
@@ -15,6 +16,9 @@ CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_MXS=y
+CONFIG_AEABI=y
 CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
 CONFIG_MODULE_UNLOAD=y
@@ -23,11 +27,6 @@ CONFIG_MODVERSIONS=y
 CONFIG_BLK_DEV_INTEGRITY=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_ARCH_MULTI_V7 is not set
-CONFIG_ARCH_MXS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PREEMPT_VOLUNTARY=y
-CONFIG_AEABI=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -80,7 +79,6 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_MXS_AUART=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MXS=y
@@ -102,7 +100,6 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -163,6 +160,10 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_15=y
+CONFIG_CRYPTO_DEV_MXS_DCP=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC7=m
+CONFIG_FONTS=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
 CONFIG_FRAME_WARN=2048
@@ -174,7 +175,3 @@ CONFIG_PROVE_LOCKING=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_STRICT_DEVMEM=y
 CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_DEV_MXS_DCP=y
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC7=m
-CONFIG_FONTS=y
index 6aa7046fb91ffeba3e67ab481e730da1ec8e8fa4..bd6440f234939eb450cd47af85e292429eaf0821 100644 (file)
@@ -207,6 +207,7 @@ CONFIG_MSM_MMCC_8974=y
 CONFIG_MSM_IOMMU=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_MAILBOX=y
 CONFIG_REMOTEPROC=y
 CONFIG_QCOM_ADSP_PIL=y
 CONFIG_QCOM_Q6V5_PIL=y
index 2080025556b548fda23c33d10260b08889b20c1e..b0026f73083d7b1f929202405c286047a8fb1769 100644 (file)
@@ -116,6 +116,7 @@ CONFIG_KEYBOARD_QT1070=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADC=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 # CONFIG_SERIO is not set
 CONFIG_LEGACY_PTY_COUNT=4
@@ -167,6 +168,7 @@ CONFIG_SND_ATMEL_SOC_WM8904=y
 # CONFIG_HID_GENERIC is not set
 CONFIG_SND_ATMEL_SOC_PDMIC=y
 CONFIG_SND_ATMEL_SOC_TSE850_PCM5142=m
+CONFIG_SND_ATMEL_SOC_I2S=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
index f8faf37294647789d6055ba464119cb707556a41..d090022ca97564a3ee6185c3e3572e5b3efccc64 100644 (file)
@@ -13,6 +13,7 @@ CONFIG_ARCH_R7S72100=y
 CONFIG_ARCH_R8A73A4=y
 CONFIG_ARCH_R8A7740=y
 CONFIG_ARCH_R8A7743=y
+CONFIG_ARCH_R8A7744=y
 CONFIG_ARCH_R8A7745=y
 CONFIG_ARCH_R8A77470=y
 CONFIG_ARCH_R8A7778=y
@@ -32,10 +33,8 @@ CONFIG_PCI_RCAR_GEN2=y
 CONFIG_PCIE_RCAR=y
 CONFIG_SMP=y
 CONFIG_SCHED_MC=y
-CONFIG_HAVE_ARM_ARCH_TIMER=y
 CONFIG_NR_CPUS=8
 CONFIG_HIGHMEM=y
-CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
@@ -50,6 +49,7 @@ CONFIG_CPUFREQ_DT=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -129,10 +129,9 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_SOC_CAMERA=y
-CONFIG_SOC_CAMERA_PLATFORM=y
 CONFIG_VIDEO_RCAR_VIN=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_FDP1=y
 CONFIG_VIDEO_RENESAS_JPU=y
 CONFIG_VIDEO_RENESAS_VSP1=y
 # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
@@ -209,7 +208,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_ARM_UNWIND is not set
diff --git a/arch/arm/include/asm/krait-l2-accessors.h b/arch/arm/include/asm/krait-l2-accessors.h
new file mode 100644 (file)
index 0000000..a5f2cdd
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H
+#define __ASMARM_KRAIT_L2_ACCESSORS_H
+
+extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
+extern u32 krait_get_l2_indirect_reg(u32 addr);
+
+#endif
index 1bf65b47808a1b99cc574d4340c3a41491fd76a6..120f4c9bbfde2a3fbade0fa5e611aca635bc6b82 100644 (file)
 #ifndef __ASM_ARM_PROCESSOR_H
 #define __ASM_ARM_PROCESSOR_H
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
 #ifdef __KERNEL__
 
 #include <asm/hw_breakpoint.h>
index 13bcd3b867cbab7991470e507a6a22986a34b013..e3057c1b55b9643c449d78c599096baba91b6de0 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/types.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
index 4c249cb261f3913112792cd6cad0a7e2df17ff4f..ac7e08886863cfa74855e5b91c4f436e85da1e0a 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/utsname.h>
 #include <linux/initrd.h>
 #include <linux/console.h>
-#include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/screen_info.h>
 #include <linux/of_platform.h>
@@ -857,7 +856,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc)
                 */
                boot_alias_start = phys_to_idmap(start);
                if (arm_has_idmap_alias() && boot_alias_start != IDMAP_INVALID_ADDR) {
-                       res = memblock_virt_alloc(sizeof(*res), 0);
+                       res = memblock_alloc(sizeof(*res), SMP_CACHE_BYTES);
                        res->name = "System RAM (boot alias)";
                        res->start = boot_alias_start;
                        res->end = phys_to_idmap(end);
@@ -865,7 +864,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc)
                        request_resource(&iomem_resource, res);
                }
 
-               res = memblock_virt_alloc(sizeof(*res), 0);
+               res = memblock_alloc(sizeof(*res), SMP_CACHE_BYTES);
                res->name  = "System RAM";
                res->start = start;
                res->end = end;
index 32fae4dbd63bac62391928de43831520c0bb39bc..51e808adb00cc23576b1f9148f0388542627d397 100644 (file)
@@ -143,15 +143,15 @@ static int at91_pm_config_ws(unsigned int pm_mode, bool set)
 
                        /* Check if enabled on SHDWC. */
                        if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit))
-                               goto put_node;
+                               goto put_device;
 
                        mode |= wsi->pmc_fsmr_bit;
                        if (wsi->set_polarity)
                                polarity |= wsi->pmc_fsmr_bit;
                }
 
-put_node:
-               of_node_put(np);
+put_device:
+               put_device(&pdev->dev);
        }
 
        if (mode) {
@@ -580,8 +580,6 @@ static int __init at91_pm_backup_init(void)
        if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
                return 0;
 
-       pm_bu = NULL;
-
        np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
        if (!np) {
                pr_warn("%s: failed to find sfrbu!\n", __func__);
@@ -590,7 +588,6 @@ static int __init at91_pm_backup_init(void)
 
        pm_data.sfrbu = of_iomap(np, 0);
        of_node_put(np);
-       pm_bu = NULL;
 
        np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
        if (!np)
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
deleted file mode 100644 (file)
index 42ed4f2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * arch/arm/mach-davinci/include/mach/clock.h
- *
- * Clock control driver for DaVinci - header file
- *
- * Authors: Vladimir Barinov <source@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
-#define __ASM_ARCH_DAVINCI_CLOCK_H
-
-struct clk;
-
-int davinci_clk_reset_assert(struct clk *c);
-int davinci_clk_reset_deassert(struct clk *c);
-
-#endif
index dcd21bb95e3b9cc7fc705ecbcc8d007d9fb9dd28..f96730cce6e82c48e9f2d2c0b2be58bd55ff93ee 100644 (file)
@@ -110,6 +110,7 @@ void exynos_firmware_init(void);
 #define EXYNOS_SLEEP_MAGIC     0x00000bad
 #define EXYNOS_AFTR_MAGIC      0xfcba0d10
 
+bool __init exynos_secure_firmware_available(void);
 void exynos_set_boot_flag(unsigned int cpu, unsigned int mode);
 void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode);
 
index be1f20fe28f448bee2b03c35dcd30d726ec34a69..d602e3bf3f9665cd367e52d67069c2018748407d 100644 (file)
@@ -185,7 +185,7 @@ static void exynos_l2_configure(const struct l2x0_regs *regs)
        exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0);
 }
 
-void __init exynos_firmware_init(void)
+bool __init exynos_secure_firmware_available(void)
 {
        struct device_node *nd;
        const __be32 *addr;
@@ -193,14 +193,22 @@ void __init exynos_firmware_init(void)
        nd = of_find_compatible_node(NULL, NULL,
                                        "samsung,secure-firmware");
        if (!nd)
-               return;
+               return false;
 
        addr = of_get_address(nd, 0, NULL, NULL);
        if (!addr) {
                pr_err("%s: No address specified.\n", __func__);
-               return;
+               return false;
        }
 
+       return true;
+}
+
+void __init exynos_firmware_init(void)
+{
+       if (!exynos_secure_firmware_available())
+               return;
+
        pr_info("Running under secure firmware.\n");
 
        register_firmware_ops(&exynos_firmware_ops);
index 7ead3acd6fa4d4f14463cb3606222894dbc991c4..bb8e3985acdb30f5f568a340f1ceaf3c39e43bb7 100644 (file)
@@ -59,10 +59,15 @@ struct exynos_pm_data {
        int (*cpu_suspend)(unsigned long);
 };
 
-static const struct exynos_pm_data *pm_data __ro_after_init;
+/* Used only on Exynos542x/5800 */
+struct exynos_pm_state {
+       int cpu_state;
+       unsigned int pmu_spare3;
+       void __iomem *sysram_base;
+};
 
-static int exynos5420_cpu_state;
-static unsigned int exynos_pmu_spare3;
+static const struct exynos_pm_data *pm_data __ro_after_init;
+static struct exynos_pm_state pm_state;
 
 /*
  * GIC wake-up support
@@ -257,7 +262,7 @@ static int exynos5420_cpu_suspend(unsigned long arg)
        unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
        unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 
-       writel_relaxed(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
+       writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE);
 
        if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
                mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
@@ -321,7 +326,7 @@ static void exynos5420_pm_prepare(void)
        /* Set wake-up mask registers */
        exynos_pm_set_wakeup_mask();
 
-       exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
+       pm_state.pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
        /*
         * The cpu state needs to be saved and restored so that the
         * secondary CPUs will enter low power start. Though the U-Boot
@@ -329,8 +334,8 @@ static void exynos5420_pm_prepare(void)
         * needs to restore it back in case, the primary cpu fails to
         * suspend for any reason.
         */
-       exynos5420_cpu_state = readl_relaxed(sysram_base_addr +
-                                            EXYNOS5420_CPU_STATE);
+       pm_state.cpu_state = readl_relaxed(pm_state.sysram_base +
+                                          EXYNOS5420_CPU_STATE);
 
        exynos_pm_enter_sleep_mode();
 
@@ -448,8 +453,8 @@ static void exynos5420_pm_resume(void)
                       EXYNOS5_ARM_CORE0_SYS_PWR_REG);
 
        /* Restore the sysram cpu state register */
-       writel_relaxed(exynos5420_cpu_state,
-                      sysram_base_addr + EXYNOS5420_CPU_STATE);
+       writel_relaxed(pm_state.cpu_state,
+                      pm_state.sysram_base + EXYNOS5420_CPU_STATE);
 
        pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
                        S5P_CENTRAL_SEQ_OPTION);
@@ -457,7 +462,7 @@ static void exynos5420_pm_resume(void)
        if (exynos_pm_central_resume())
                goto early_wakeup;
 
-       pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
+       pmu_raw_writel(pm_state.pmu_spare3, S5P_PMU_SPARE3);
 
 early_wakeup:
 
@@ -654,4 +659,13 @@ void __init exynos_pm_init(void)
 
        register_syscore_ops(&exynos_pm_syscore_ops);
        suspend_set_ops(&exynos_suspend_ops);
+
+       /*
+        * Applicable as of now only to Exynos542x. If booted under secure
+        * firmware, the non-secure region of sysram should be used.
+        */
+       if (exynos_secure_firmware_available())
+               pm_state.sysram_base = sysram_ns_base_addr;
+       else
+               pm_state.sysram_base = sysram_base_addr;
 }
index 61f3d94f16336a85b707850d8977a0351792b81a..45d618abf26b77fda2572346d0329cfb1e2dc3d2 100644 (file)
@@ -31,6 +31,8 @@
 #define ANADIG_DIGPROG_IMX6SL  0x280
 #define ANADIG_DIGPROG_IMX7D   0x800
 
+#define SRC_SBMR2              0x1c
+
 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG   0x40000
 #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN      0x8
 #define BM_ANADIG_REG_CORE_FET_ODRIVE          0x20000000
@@ -148,6 +150,24 @@ void __init imx_init_revision_from_anatop(void)
                major_part = (digprog >> 8) & 0xf;
                minor_part = digprog & 0xf;
                revision = ((major_part + 1) << 4) | minor_part;
+
+               if ((digprog >> 16) == MXC_CPU_IMX6ULL) {
+                       void __iomem *src_base;
+                       u32 sbmr2;
+
+                       np = of_find_compatible_node(NULL, NULL,
+                                                    "fsl,imx6ul-src");
+                       src_base = of_iomap(np, 0);
+                       WARN_ON(!src_base);
+                       sbmr2 = readl_relaxed(src_base + SRC_SBMR2);
+                       iounmap(src_base);
+
+                       /* src_sbmr2 bit 6 is to identify if it is i.MX6ULZ */
+                       if (sbmr2 & (1 << 6)) {
+                               digprog &= ~(0xff << 16);
+                               digprog |= (MXC_CPU_IMX6ULZ << 16);
+                       }
+               }
        }
 
        mxc_set_cpu_type(digprog >> 16 & 0xff);
index c6b1bf97a6c16e4e1bfcd4237362f5270323189b..c73593e0912161a906c57568ff93e42fc75ca270 100644 (file)
@@ -136,6 +136,9 @@ struct device * __init imx_soc_device_init(void)
        case MXC_CPU_IMX6ULL:
                soc_id = "i.MX6ULL";
                break;
+       case MXC_CPU_IMX6ULZ:
+               soc_id = "i.MX6ULZ";
+               break;
        case MXC_CPU_IMX6SLL:
                soc_id = "i.MX6SLL";
                break;
index 04b3bf71de94ba7d24ae0561d2dfab62db189163..e49e068345162ba77d77ae36dbef324c446ef862 100644 (file)
@@ -11,6 +11,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <linux/clk.h>
 #include <linux/hrtimer.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -546,7 +547,20 @@ static int imx_mmdc_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        void __iomem *mmdc_base, *reg;
+       struct clk *mmdc_ipg_clk;
        u32 val;
+       int err;
+
+       /* the ipg clock is optional */
+       mmdc_ipg_clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(mmdc_ipg_clk))
+               mmdc_ipg_clk = NULL;
+
+       err = clk_prepare_enable(mmdc_ipg_clk);
+       if (err) {
+               dev_err(&pdev->dev, "Unable to enable mmdc ipg clock.\n");
+               return err;
+       }
 
        mmdc_base = of_iomap(np, 0);
        WARN_ON(!mmdc_base);
index 026e2ca45f1e1cb53c78d7f84427c7d42c7c2e92..b130a53ff62a8bc8389e967661b5912d8e0ff61d 100644 (file)
@@ -40,6 +40,8 @@
 #define MXC_CPU_IMX6Q          0x63
 #define MXC_CPU_IMX6UL         0x64
 #define MXC_CPU_IMX6ULL                0x65
+/* virtual cpu id for i.mx6ulz */
+#define MXC_CPU_IMX6ULZ                0x6b
 #define MXC_CPU_IMX6SLL                0x67
 #define MXC_CPU_IMX7D          0x72
 
@@ -80,6 +82,11 @@ static inline bool cpu_is_imx6ull(void)
        return __mxc_cpu_type == MXC_CPU_IMX6ULL;
 }
 
+static inline bool cpu_is_imx6ulz(void)
+{
+       return __mxc_cpu_type == MXC_CPU_IMX6ULZ;
+}
+
 static inline bool cpu_is_imx6sll(void)
 {
        return __mxc_cpu_type == MXC_CPU_IMX6SLL;
index b08e407d8d96f4f7a61d107ee877a64571a8acaf..87f45b926c78d50bd820bfab0fe874f966b16425 100644 (file)
@@ -313,7 +313,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
                if (cpu_is_imx6sl())
                        val |= BM_CLPCR_BYPASS_PMIC_READY;
                if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
-                   cpu_is_imx6ull() || cpu_is_imx6sll())
+                   cpu_is_imx6ull() || cpu_is_imx6sll() || cpu_is_imx6ulz())
                        val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
                else
                        val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -331,7 +331,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
                if (cpu_is_imx6sl() || cpu_is_imx6sx())
                        val |= BM_CLPCR_BYPASS_PMIC_READY;
                if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
-                   cpu_is_imx6ull() || cpu_is_imx6sll())
+                   cpu_is_imx6ull() || cpu_is_imx6sll() || cpu_is_imx6ulz())
                        val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
                else
                        val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -618,6 +618,28 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
                                   IMX6Q_GPR1_GINT);
 }
 
+static void imx6_pm_stby_poweroff(void)
+{
+       imx6_set_lpm(STOP_POWER_OFF);
+       imx6q_suspend_finish(0);
+
+       mdelay(1000);
+
+       pr_emerg("Unable to poweroff system\n");
+}
+
+static int imx6_pm_stby_poweroff_probe(void)
+{
+       if (pm_power_off) {
+               pr_warn("%s: pm_power_off already claimed  %p %pf!\n",
+                       __func__, pm_power_off, pm_power_off);
+               return -EBUSY;
+       }
+
+       pm_power_off = imx6_pm_stby_poweroff;
+       return 0;
+}
+
 void __init imx6_pm_ccm_init(const char *ccm_compat)
 {
        struct device_node *np;
@@ -634,6 +656,9 @@ void __init imx6_pm_ccm_init(const char *ccm_compat)
        val = readl_relaxed(ccm_base + CLPCR);
        val &= ~BM_CLPCR_LPM;
        writel_relaxed(val, ccm_base + CLPCR);
+
+       if (of_property_read_bool(np, "fsl,pmic-stby-poweroff"))
+               imx6_pm_stby_poweroff_probe();
 }
 
 void __init imx6q_pm_init(void)
index ccca95173e175358a54cc5c48396a2d956c4e8b9..0b10acd7d1b9fbd4d7db7c03d44a11f629bfcc27 100644 (file)
@@ -145,6 +145,13 @@ static void __init mvebu_dt_init(void)
                i2c_quirk();
 }
 
+static void __init armada_370_xp_dt_fixup(void)
+{
+#ifdef CONFIG_SMP
+       smp_set_ops(smp_ops(armada_xp_smp_ops));
+#endif
+}
+
 static const char * const armada_370_xp_dt_compat[] __initconst = {
        "marvell,armada-370-xp",
        NULL,
@@ -153,17 +160,12 @@ static const char * const armada_370_xp_dt_compat[] __initconst = {
 DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
        .l2c_aux_val    = 0,
        .l2c_aux_mask   = ~0,
-/*
- * The following field (.smp) is still needed to ensure backward
- * compatibility with old Device Trees that were not specifying the
- * cpus enable-method property.
- */
-       .smp            = smp_ops(armada_xp_smp_ops),
        .init_machine   = mvebu_dt_init,
        .init_irq       = mvebu_init_irq,
        .restart        = mvebu_restart,
        .reserve        = mvebu_memblock_reserve,
        .dt_compat      = armada_370_xp_dt_compat,
+       .dt_fixup       = armada_370_xp_dt_fixup,
 MACHINE_END
 
 static const char * const armada_375_dt_compat[] __initconst = {
index ddc27638ba2a5e7807b9a904df874c5e913ef812..e3faa0274b564b3b36bbf6b0599545bbd91436a7 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <linux/platform_data/ams-delta-fiq.h>
+#include <linux/platform_data/gpio-omap.h>
 
 #include <asm/assembler.h>
 #include <mach/board-ams-delta.h>
 #include "soc.h"
 
 /*
- * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c.
- * Unfortunately, those were not placed in a separate header file.
+ * OMAP1510 GPIO related symbol copied from arch/arm/mach-omap1/gpio15xx.c.
+ * Unfortunately, it was not placed in a separate header file.
  */
 #define OMAP1510_GPIO_BASE             0xFFFCE000
-#define OMAP1510_GPIO_DATA_INPUT       0x00
-#define OMAP1510_GPIO_DATA_OUTPUT      0x04
-#define OMAP1510_GPIO_DIR_CONTROL      0x08
-#define OMAP1510_GPIO_INT_CONTROL      0x0c
-#define OMAP1510_GPIO_INT_MASK         0x10
-#define OMAP1510_GPIO_INT_STATUS       0x14
-#define OMAP1510_GPIO_PIN_CONTROL      0x18
 
 /* GPIO register bitmasks */
 #define KEYBRD_DATA_MASK               (0x1 << AMS_DELTA_GPIO_PIN_KEYBRD_DATA)
index f226973f3d8cc49f057c5f264a9ce3aa19d4033f..af318d958fd2a7c9796ad2384c8c122ca04358e2 100644 (file)
@@ -250,39 +250,6 @@ static struct platform_device latch2_gpio_device = {
 #define LATCH2_PIN_HOOKFLASH1          14
 #define LATCH2_PIN_HOOKFLASH2          15
 
-static const struct gpio latch_gpios[] __initconst = {
-       {
-               .gpio   = LATCH1_GPIO_BASE + 6,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "dockit1",
-       },
-       {
-               .gpio   = LATCH1_GPIO_BASE + 7,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "dockit2",
-       },
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_SCARD_RSTIN,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "scard_rstin",
-       },
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_SCARD_CMDVCC,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "scard_cmdvcc",
-       },
-       {
-               .gpio   = AMS_DELTA_LATCH2_GPIO_BASE + 14,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "hookflash1",
-       },
-       {
-               .gpio   = AMS_DELTA_LATCH2_GPIO_BASE + 15,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "hookflash2",
-       },
-};
-
 static struct regulator_consumer_supply modem_nreset_consumers[] = {
        REGULATOR_SUPPLY("RESET#", "serial8250.1"),
        REGULATOR_SUPPLY("POR", "cx20442-codec"),
@@ -329,20 +296,6 @@ struct modem_private_data {
 
 static struct modem_private_data modem_priv;
 
-void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value)
-{
-       int bit = 0;
-       u16 bitpos = 1 << bit;
-
-       for (; bit < ngpio; bit++, bitpos = bitpos << 1) {
-               if (!(mask & bitpos))
-                       continue;
-               else
-                       gpio_set_value(base + bit, (value & bitpos) != 0);
-       }
-}
-EXPORT_SYMBOL(ams_delta_latch_write);
-
 static struct resource ams_delta_nand_resources[] = {
        [0] = {
                .start  = OMAP1_MPUIO_BASE,
@@ -638,6 +591,28 @@ static struct gpiod_hog ams_delta_gpio_hogs[] = {
        {},
 };
 
+static struct plat_serial8250_port ams_delta_modem_ports[];
+
+/*
+ * Obtain MODEM IRQ GPIO descriptor using its hardware pin
+ * number and assign related IRQ number to the MODEM port.
+ * Keep the GPIO descriptor open so nobody steps in.
+ */
+static void __init modem_assign_irq(struct gpio_chip *chip)
+{
+       struct gpio_desc *gpiod;
+
+       gpiod = gpiochip_request_own_desc(chip, AMS_DELTA_GPIO_PIN_MODEM_IRQ,
+                                         "modem_irq");
+       if (IS_ERR(gpiod)) {
+               pr_err("%s: modem IRQ GPIO request failed (%ld)\n", __func__,
+                      PTR_ERR(gpiod));
+       } else {
+               gpiod_direction_input(gpiod);
+               ams_delta_modem_ports[0].irq = gpiod_to_irq(gpiod);
+       }
+}
+
 /*
  * The purpose of this function is to take care of proper initialization of
  * devices and data structures which depend on GPIO lines provided by OMAP GPIO
@@ -657,7 +632,47 @@ static void __init omap_gpio_deps_init(void)
                return;
        }
 
+       /*
+        * Start with FIQ initialization as it may have to request
+        * and release successfully each OMAP GPIO pin in turn.
+        */
        ams_delta_init_fiq(chip, &ams_delta_serio_device);
+
+       modem_assign_irq(chip);
+}
+
+/*
+ * Initialize latch2 pins with values which are safe for dependent on-board
+ * devices or useful for their successull initialization even before GPIO
+ * driver takes control over the latch pins:
+ * - LATCH2_PIN_LCD_VBLEN      = 0
+ * - LATCH2_PIN_LCD_NDISP      = 0     Keep LCD device powered off before its
+ *                                     driver takes control over it.
+ * - LATCH2_PIN_NAND_NCE       = 0
+ * - LATCH2_PIN_NAND_NWP       = 0     Keep NAND device down and write-
+ *                                     protected before its driver takes
+ *                                     control over it.
+ * - LATCH2_PIN_KEYBRD_PWR     = 0     Keep keyboard powered off before serio
+ *                                     driver takes control over it.
+ * - LATCH2_PIN_KEYBRD_DATAOUT = 0     Keep low to avoid corruption of first
+ *                                     byte of data received from attached
+ *                                     keyboard when serio device is probed;
+ *                                     the pin is also hogged low by the latch2
+ *                                     GPIO driver as soon as it is ready.
+ * - LATCH2_PIN_MODEM_NRESET   = 1     Enable voice MODEM device, allowing for
+ *                                     its successful probe even before a
+ *                                     regulator it depends on, which in turn
+ *                                     takes control over the pin, is set up.
+ * - LATCH2_PIN_MODEM_CODEC    = 1     Attach voice MODEM CODEC data port
+ *                                     to the MODEM so the CODEC is under
+ *                                     control even if audio driver doesn't
+ *                                     take it over.
+ */
+static void __init ams_delta_latch2_init(void)
+{
+       u16 latch2 = 1 << LATCH2_PIN_MODEM_NRESET | 1 << LATCH2_PIN_MODEM_CODEC;
+
+       __raw_writew(latch2, LATCH2_VIRT);
 }
 
 static void __init ams_delta_init(void)
@@ -681,6 +696,7 @@ static void __init ams_delta_init(void)
        omap_cfg_reg(J18_1610_CAM_D7);
 
        omap_gpio_deps_init();
+       ams_delta_latch2_init();
        gpiod_add_hogs(ams_delta_gpio_hogs);
 
        omap_serial_init();
@@ -821,7 +837,6 @@ static void __init ams_delta_led_init(struct gpio_chip *chip)
 static int __init ams_delta_gpio_init(void)
 {
        struct gpio_chip *chip;
-       int err;
 
        if (!machine_is_ams_delta())
                return -ENODEV;
@@ -832,11 +847,7 @@ static int __init ams_delta_gpio_init(void)
        else
                ams_delta_led_init(chip);
 
-       err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
-       if (err)
-               pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
-
-       return err;
+       return 0;
 }
 device_initcall_sync(ams_delta_gpio_init);
 
@@ -852,33 +863,44 @@ static int __init modem_nreset_init(void)
 }
 
 
+/*
+ * This function expects MODEM IRQ number already assigned to the port
+ * and fails if it's not.
+ * The MODEM device requires its RESET# pin kept high during probe.
+ * That requirement can be fulfilled in several ways:
+ * - with a descriptor of already functional modem_nreset regulator
+ *   assigned to the MODEM private data,
+ * - with the regulator not yet controlled by modem_pm function but
+ *   already enabled by default on probe,
+ * - before the modem_nreset regulator is probed, with the pin already
+ *   set high explicitly.
+ * The last one is already guaranteed by ams_delta_latch2_init() called
+ * from machine_init.
+ * In order to avoid taking over ttyS0 device slot, the MODEM device
+ * should be registered after OMAP serial ports.  Since those ports
+ * are registered at arch_initcall, this function can be called safely
+ * at arch_initcall_sync earliest.
+ */
 static int __init ams_delta_modem_init(void)
 {
        int err;
 
-       omap_cfg_reg(M14_1510_GPIO2);
-       ams_delta_modem_ports[0].irq =
-                       gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+       if (!machine_is_ams_delta())
+               return -ENODEV;
 
-       err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem");
-       if (err) {
-               pr_err("Couldn't request gpio pin for modem\n");
-               return err;
-       }
-       gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+       if (ams_delta_modem_ports[0].irq < 0)
+               return ams_delta_modem_ports[0].irq;
+
+       omap_cfg_reg(M14_1510_GPIO2);
 
        /* Initialize the modem_nreset regulator consumer before use */
        modem_priv.regulator = ERR_PTR(-ENODEV);
 
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
-                       AMS_DELTA_LATCH2_MODEM_CODEC);
-
        err = platform_device_register(&ams_delta_modem_device);
-       if (err)
-               gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
 
        return err;
 }
+arch_initcall_sync(ams_delta_modem_init);
 
 static int __init late_init(void)
 {
@@ -888,10 +910,6 @@ static int __init late_init(void)
        if (err)
                return err;
 
-       err = ams_delta_modem_init();
-       if (err)
-               return err;
-
        /*
         * Once the modem device is registered, the modem_nreset
         * regulator can be requested on behalf of that device.
@@ -906,7 +924,6 @@ static int __init late_init(void)
 
 unregister:
        platform_device_unregister(&ams_delta_modem_device);
-       gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
        return err;
 }
 
index ad6f865d1f161bedf714674ff11eaee77e0cf8be..3b2d8019238a01b92c779f71fc6591d4b2a559eb 100644 (file)
 #define AMS_DELTA_LATCH2_GPIO_BASE     AMS_DELTA_GPIO_PIN_LCD_VBLEN
 #define AMS_DELTA_LATCH2_NGPIO         16
 
-#ifndef __ASSEMBLY__
-void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value);
-#define ams_delta_latch2_write(mask, value) \
-       ams_delta_latch_write(AMS_DELTA_LATCH2_GPIO_BASE, \
-                       AMS_DELTA_LATCH2_NGPIO, (mask), (value))
-#endif
-
 #endif /* CONFIG_MACH_AMS_DELTA */
 
 #endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
index cd65ea4e9c54e633bd66a0178ca3f06ad16e8db9..083dcd9942ce5c8643f0f56a8731f722fa514f63 100644 (file)
 #include <linux/cpu.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <linux/platform_data/ti-sysc.h>
 
 
 /**
  * struct clkctrl_provider - clkctrl provider mapping data
- * @addr: base address for the provider
- * @size: size of the provider address space
- * @offset: offset of the provider from PRCM instance base
+ * @num_addrs: number of base address ranges for the provider
+ * @addr: base address(es) for the provider
+ * @size: size(s) of the provider address space(s)
  * @node: device node associated with the provider
  * @link: list link
  */
 struct clkctrl_provider {
-       u32                     addr;
-       u32                     size;
-       u16                     offset;
+       int                     num_addrs;
+       u32                     *addr;
+       u32                     *size;
        struct device_node      *node;
        struct list_head        link;
 };
@@ -724,23 +724,36 @@ static int __init _setup_clkctrl_provider(struct device_node *np)
        const __be32 *addrp;
        struct clkctrl_provider *provider;
        u64 size;
+       int i;
 
-       provider = memblock_virt_alloc(sizeof(*provider), 0);
+       provider = memblock_alloc(sizeof(*provider), SMP_CACHE_BYTES);
        if (!provider)
                return -ENOMEM;
 
-       addrp = of_get_address(np, 0, &size, NULL);
-       provider->addr = (u32)of_translate_address(np, addrp);
-       addrp = of_get_address(np->parent, 0, NULL, NULL);
-       provider->offset = provider->addr -
-                          (u32)of_translate_address(np->parent, addrp);
-       provider->addr &= ~0xff;
-       provider->size = size | 0xff;
        provider->node = np;
 
-       pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name,
-                provider->addr, provider->addr + provider->size,
-                provider->offset);
+       provider->num_addrs =
+               of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2;
+
+       provider->addr =
+               memblock_alloc(sizeof(void *) * provider->num_addrs,
+                              SMP_CACHE_BYTES);
+       if (!provider->addr)
+               return -ENOMEM;
+
+       provider->size =
+               memblock_alloc(sizeof(u32) * provider->num_addrs,
+                              SMP_CACHE_BYTES);
+       if (!provider->size)
+               return -ENOMEM;
+
+       for (i = 0; i < provider->num_addrs; i++) {
+               addrp = of_get_address(np, i, &size, NULL);
+               provider->addr[i] = (u32)of_translate_address(np, addrp);
+               provider->size[i] = size;
+               pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i],
+                        provider->addr[i] + provider->size[i]);
+       }
 
        list_add(&provider->link, &clkctrl_providers);
 
@@ -787,23 +800,26 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
        pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
 
        list_for_each_entry(provider, &clkctrl_providers, link) {
-               if (provider->addr <= addr &&
-                   provider->addr + provider->size >= addr) {
-                       struct of_phandle_args clkspec;
+               int i;
 
-                       clkspec.np = provider->node;
-                       clkspec.args_count = 2;
-                       clkspec.args[0] = addr - provider->addr -
-                                         provider->offset;
-                       clkspec.args[1] = 0;
+               for (i = 0; i < provider->num_addrs; i++) {
+                       if (provider->addr[i] <= addr &&
+                           provider->addr[i] + provider->size[i] > addr) {
+                               struct of_phandle_args clkspec;
 
-                       clk = of_clk_get_from_provider(&clkspec);
+                               clkspec.np = provider->node;
+                               clkspec.args_count = 2;
+                               clkspec.args[0] = addr - provider->addr[0];
+                               clkspec.args[1] = 0;
 
-                       pr_debug("%s: %s got %p (offset=%x, provider=%s)\n",
-                                __func__, oh->name, clk, clkspec.args[0],
-                                provider->node->parent->name);
+                               clk = of_clk_get_from_provider(&clkspec);
 
-                       return clk;
+                               pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n",
+                                        __func__, oh->name, clk,
+                                        clkspec.args[0], provider->node);
+
+                               return clk;
+                       }
                }
        }
 
@@ -2107,8 +2123,8 @@ static int of_dev_find_hwmod(struct device_node *np,
                if (res)
                        continue;
                if (!strcmp(p, oh->name)) {
-                       pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
-                                np->name, i, oh->name);
+                       pr_debug("omap_hwmod: dt %pOFn[%i] uses hwmod %s\n",
+                                np, i, oh->name);
                        return i;
                }
        }
@@ -2241,8 +2257,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
                return -ENOENT;
 
        if (nr_addr != 1 || nr_size != 1) {
-               pr_err("%s: invalid range for %s->%s\n", __func__,
-                      oh->name, np->name);
+               pr_err("%s: invalid range for %s->%pOFn\n", __func__,
+                      oh->name, np);
                return -EINVAL;
        }
 
@@ -2250,8 +2266,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
        base = of_translate_address(np, ranges++);
        size = be32_to_cpup(ranges);
 
-       pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n",
-                oh ? oh->name : "", np->name, base, size);
+       pr_debug("omap_hwmod: %s %pOFn at 0x%llx size 0x%llx\n",
+                oh->name, np, base, size);
 
        if (oh && oh->mpu_rt_idx) {
                omap_hwmod_fix_mpu_rt_idx(oh, np, res);
@@ -2359,8 +2375,8 @@ static int __init _init(struct omap_hwmod *oh, void *data)
        if (r)
                pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
        else if (np && index)
-               pr_warn("omap_hwmod: %s using broken dt data from %s\n",
-                       oh->name, np->name);
+               pr_warn("omap_hwmod: %s using broken dt data from %pOFn\n",
+                       oh->name, np);
 
        r = _init_mpu_rt_base(oh, NULL, index, np);
        if (r < 0) {
index 9d5595c4ad99f813b4c861344ad87b28f20872f1..594901f3b8e58b8383125c54abf8759c665725dd 100644 (file)
@@ -219,17 +219,6 @@ static void gta02_udc_vbus_draw(unsigned int ma)
 #define gta02_udc_vbus_draw            NULL
 #endif
 
-/*
- * This is called when pc50633 is probed, unfortunately quite late in the
- * day since it is an I2C bus device. Here we can belatedly define some
- * platform devices with the advantage that we can mark the pcf50633 as the
- * parent. This makes them get suspended and resumed with their parent
- * the pcf50633 still around.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
-
-
 static char *gta02_batteries[] = {
        "battery",
 };
@@ -355,7 +344,6 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
                },
 
        },
-       .probe_done = gta02_pmu_attach_child_devices,
        .mbc_event_callback = gta02_pmu_event_callback,
 };
 
@@ -512,36 +500,6 @@ static struct platform_device *gta02_devices[] __initdata = {
        &s3c_device_ts,
 };
 
-/* These guys DO need to be children of PMU. */
-
-static struct platform_device *gta02_devices_pmu_children[] = {
-};
-
-
-/*
- * This is called when pc50633 is probed, quite late in the day since it is an
- * I2C bus device.  Here we can define platform devices with the advantage that
- * we can mark the pcf50633 as the parent.  This makes them get suspended and
- * resumed with their parent the pcf50633 still around.  All devices whose
- * operation depends on something from pcf50633 must have this relationship
- * made explicit like this, or suspend and resume will become an unreliable
- * hellworld.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
-{
-       int n;
-
-       /* Grab a copy of the now probed PMU pointer. */
-       gta02_pcf = pcf;
-
-       for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
-               gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
-
-       platform_add_devices(gta02_devices_pmu_children,
-                            ARRAY_SIZE(gta02_devices_pmu_children));
-}
-
 static void gta02_poweroff(void)
 {
        pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
index f9fc1f8d2b2814dbf0de70b77d47b38e6d0ab665..50d67d760efdeef7f3878e00f63195df67336fbf 100644 (file)
@@ -64,31 +64,31 @@ static struct map_desc mini2440_iodesc[] __initdata = {
 };
 
 #define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
 
 
 static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
        [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
        [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
        [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
        },
 };
 
@@ -104,8 +104,8 @@ static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
 /*
  * This macro simplifies the table bellow
  */
-#define _LCD_DECLARE(_clock,_xres,margin_left,margin_right,hsync, \
-                       _yres,margin_top,margin_bottom,vsync, refresh) \
+#define _LCD_DECLARE(_clock, _xres, margin_left, margin_right, hsync, \
+                       _yres, margin_top, margin_bottom, vsync, refresh) \
        .width = _xres, \
        .xres = _xres, \
        .height = _yres, \
@@ -128,7 +128,7 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
        [0] = { /* mini2440 + 3.5" TFT + touchscreen */
                _LCD_DECLARE(
                        7,                      /* The 3.5 is quite fast */
-                       240, 21, 38, 6,         /* x timing */
+                       240, 21, 38, 6,         /* x timing */
                        320, 4, 4, 2,           /* y timing */
                        60),                    /* refresh rate */
                .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
@@ -140,7 +140,7 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
        [1] = { /* mini2440 + 7" TFT + touchscreen */
                _LCD_DECLARE(
                        10,                     /* the 7" runs slower */
-                       800, 40, 40, 48,        /* x timing */
+                       800, 40, 40, 48,        /* x timing */
                        480, 29, 3, 3,          /* y timing */
                        50),                    /* refresh rate */
                .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
@@ -148,7 +148,7 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
                                   S3C2410_LCDCON5_INVVFRAME |
                                   S3C2410_LCDCON5_PWREN),
        },
-       /* The VGA shield can outout at several resolutions. All share 
+       /* The VGA shield can outout at several resolutions. All share
         * the same timings, however, anything smaller than 1024x768
         * will only be displayed in the top left corner of a 1024x768
         * XGA output unless you add optional dip switches to the shield.
@@ -158,9 +158,10 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
                _LCD_DECLARE(
                        10,
                        1024, 1, 2, 2,          /* y timing */
-                       768, 200, 16, 16,       /* x timing */
+                       768, 200, 16, 16,       /* x timing */
                        24),    /* refresh rate, maximum stable,
-                                tested with the FPGA shield */
+                                * tested with the FPGA shield
+                                */
                .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
                                   S3C2410_LCDCON5_HWSWP),
        },
@@ -196,7 +197,8 @@ static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
 
        /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
         * and disable the pull down resistors on pins we are using for LCD
-        * data. */
+        * data.
+        */
 
        .gpcup          = (0xf << 1) | (0x3f << 10),
 
@@ -232,10 +234,11 @@ static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
 /* MMC/SD  */
 
 static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = {
-   .gpio_detect   = S3C2410_GPG(8),
-   .gpio_wprotect = S3C2410_GPH(8),
-   .set_power     = NULL,
-   .ocr_avail     = MMC_VDD_32_33|MMC_VDD_33_34,
+       .gpio_detect            = S3C2410_GPG(8),
+       .gpio_wprotect          = S3C2410_GPH(8),
+       .wprotect_invert        = 1,
+       .set_power              = NULL,
+       .ocr_avail              = MMC_VDD_32_33|MMC_VDD_33_34,
 };
 
 /* NAND Flash on MINI2440 board */
@@ -254,7 +257,8 @@ static struct mtd_partition mini2440_default_nand_part[] __initdata = {
        [2] = {
                .name   = "kernel",
                /* 5 megabytes, for a kernel with no modules
-                * or a uImage with a ramdisk attached */
+                * or a uImage with a ramdisk attached
+                */
                .size   = 0x00500000,
                .offset = SZ_256K + SZ_128K,
        },
@@ -271,7 +275,7 @@ static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = {
                .nr_chips       = 1,
                .nr_partitions  = ARRAY_SIZE(mini2440_default_nand_part),
                .partitions     = mini2440_default_nand_part,
-               .flash_bbt      = 1, /* we use u-boot to create a BBT */
+               .flash_bbt      = 1, /* we use u-boot to create a BBT */
        },
 };
 
@@ -282,7 +286,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = {
        .nr_sets        = ARRAY_SIZE(mini2440_nand_sets),
        .sets           = mini2440_nand_sets,
        .ignore_unset_ecc = 1,
-       .ecc_mode       = NAND_ECC_HW,
+       .ecc_mode       = NAND_ECC_HW,
 };
 
 /* DM9000AEP 10/100 ethernet controller */
@@ -290,7 +294,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = {
 static struct resource mini2440_dm9k_resource[] = {
        [0] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE, 4),
        [1] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE + 4, 4),
-       [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, IORESOURCE_IRQ \
+       [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, IORESOURCE_IRQ
                                                | IORESOURCE_IRQ_HIGHEDGE),
 };
 
@@ -362,7 +366,8 @@ static struct gpio_keys_button mini2440_buttons[] = {
        },
 #if 0
        /* this pin is also known as TCLK1 and seems to already
-        * marked as "in use" somehow in the kernel -- possibly wrongly */
+        * marked as "in use" somehow in the kernel -- possibly wrongly
+        */
        {
                .gpio           = S3C2410_GPG(11),      /* K6 */
                .code           = KEY_F6,
@@ -564,7 +569,8 @@ static char mini2440_features_str[12] __initdata = "0tb";
 static int __init mini2440_features_setup(char *str)
 {
        if (str)
-               strlcpy(mini2440_features_str, str, sizeof(mini2440_features_str));
+               strlcpy(mini2440_features_str, str,
+                       sizeof(mini2440_features_str));
        return 1;
 }
 
@@ -583,10 +589,10 @@ struct mini2440_features_t {
 };
 
 static void __init mini2440_parse_features(
-               struct mini2440_features_t * features,
-               const char * features_str )
+               struct mini2440_features_t *features,
+               const char *features_str)
 {
-       const char * fp = features_str;
+       const char *fp = features_str;
 
        features->count = 0;
        features->done = 0;
@@ -598,13 +604,14 @@ static void __init mini2440_parse_features(
                switch (f) {
                case '0'...'9': /* tft screen */
                        if (features->done & FEATURE_SCREEN) {
-                               printk(KERN_INFO "MINI2440: '%c' ignored, "
-                                       "screen type already set\n", f);
+                               pr_info("MINI2440: '%c' ignored, screen type already set\n",
+                                       f);
                        } else {
                                int li = f - '0';
+
                                if (li >= ARRAY_SIZE(mini2440_lcd_cfg))
-                                       printk(KERN_INFO "MINI2440: "
-                                               "'%c' out of range LCD mode\n", f);
+                                       pr_info("MINI2440: '%c' out of range LCD mode\n",
+                                               f);
                                else {
                                        features->optional[features->count++] =
                                                        &s3c_device_lcd;
@@ -615,8 +622,8 @@ static void __init mini2440_parse_features(
                        break;
                case 'b':
                        if (features->done & FEATURE_BACKLIGHT)
-                               printk(KERN_INFO "MINI2440: '%c' ignored, "
-                                       "backlight already set\n", f);
+                               pr_info("MINI2440: '%c' ignored, backlight already set\n",
+                                       f);
                        else {
                                features->optional[features->count++] =
                                                &mini2440_led_backlight;
@@ -624,13 +631,13 @@ static void __init mini2440_parse_features(
                        features->done |= FEATURE_BACKLIGHT;
                        break;
                case 't':
-                       printk(KERN_INFO "MINI2440: '%c' ignored, "
-                               "touchscreen not compiled in\n", f);
+                       pr_info("MINI2440: '%c' ignored, touchscreen not compiled in\n",
+                               f);
                        break;
                case 'c':
                        if (features->done & FEATURE_CAMERA)
-                               printk(KERN_INFO "MINI2440: '%c' ignored, "
-                                       "camera already registered\n", f);
+                               pr_info("MINI2440: '%c' ignored, camera already registered\n",
+                                       f);
                        else
                                features->optional[features->count++] =
                                        &s3c_device_camif;
@@ -645,7 +652,7 @@ static void __init mini2440_init(void)
        struct mini2440_features_t features = { 0 };
        int i;
 
-       printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
+       pr_info("MINI2440: Option string mini2440=%s\n",
                        mini2440_features_str);
 
        /* Parse the feature string */
@@ -674,17 +681,17 @@ static void __init mini2440_init(void)
                mini2440_fb_info.displays =
                        &mini2440_lcd_cfg[features.lcd_index];
 
-               printk(KERN_INFO "MINI2440: LCD");
+               pr_info("MINI2440: LCD");
                for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
                        if (li == features.lcd_index)
-                               printk(" [%d:%dx%d]", li,
+                               pr_cont(" [%d:%dx%d]", li,
                                        mini2440_lcd_cfg[li].width,
                                        mini2440_lcd_cfg[li].height);
                        else
-                               printk(" %d:%dx%d", li,
+                               pr_cont(" %d:%dx%d", li,
                                        mini2440_lcd_cfg[li].width,
                                        mini2440_lcd_cfg[li].height);
-               printk("\n");
+               pr_cont("\n");
                s3c24xx_fb_set_platdata(&mini2440_fb_info);
        }
 
index aeb2eed085988bb853685cc0174b192de0b4f054..b100c26a858f9015b5b001c7a6c52acd227d94aa 100644 (file)
@@ -1,6 +1,4 @@
-config ARCH_SHMOBILE
-       bool
-
+# SPDX-License-Identifier: GPL-2.0
 config PM_RMOBILE
        bool
        select PM
@@ -30,7 +28,6 @@ config ARCH_RMOBILE
 menuconfig ARCH_RENESAS
        bool "Renesas ARM SoCs"
        depends on ARCH_MULTI_V7 && MMU
-       select ARCH_SHMOBILE
        select ARM_GIC
        select GPIOLIB
        select HAVE_ARM_SCU if SMP
@@ -55,6 +52,12 @@ config ARCH_R7S72100
        select SYS_SUPPORTS_SH_MTU2
        select RENESAS_OSTM
 
+config ARCH_R7S9210
+       bool "RZ/A2 (R7S9210)"
+       select PM
+       select PM_GENERIC_DOMAINS
+       select RENESAS_OSTM
+
 config ARCH_R8A73A4
        bool "R-Mobile APE6 (R8A73A40)"
        select ARCH_RMOBILE
@@ -72,6 +75,11 @@ config ARCH_R8A7743
        select ARCH_RCAR_GEN2
        select ARM_ERRATA_798181 if SMP
 
+config ARCH_R8A7744
+       bool "RZ/G1N (R8A77440)"
+       select ARCH_RCAR_GEN2
+       select ARM_ERRATA_798181 if SMP
+
 config ARCH_R8A7745
        bool "RZ/G1E (R8A77450)"
        select ARCH_RCAR_GEN2
index b33dc59d8698d218bacf6fd1117b9814dd5ade6b..5591646cb9bbfd33def30a3f91529acb99c7ed1b 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_R8A7778)    += setup-r8a7778.o
 obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o
 obj-$(CONFIG_ARCH_EMEV2)       += setup-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)    += setup-r7s72100.o
+obj-$(CONFIG_ARCH_R7S9210)     += setup-r7s9210.o
 
 # CPU reset vector handling objects
 cpu-y                          := platsmp.o headsmp.o
index 936d7011c3141b73228c923129f29f3635b0df13..d0234296ae622b5f1745d9be7002d4705c3e4913 100644 (file)
@@ -1,17 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  * Shared SCU setup for mach-shmobile
  *
  * Copyright (C) 2012 Bastian Hecht
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/linkage.h>
index cef8e8c555f84b926adfa95e45c421b6759c665a..9466ae61f56abd17726098143c4019789da1b201 100644 (file)
@@ -1,14 +1,11 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * SMP support for R-Mobile / SH-Mobile
  *
  * Copyright (C) 2010  Magnus Damm
  * Copyright (C) 2010  Takashi Yoshii
  *
  * Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/init.h>
 #include <linux/linkage.h>
index f1a1efde4beb19c2b520188aa9dac6fed428c224..fcfcef1d1ae4f81f91b6387ea55d3fa1d1041dd8 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for SoCs with SCU covered by mach-shmobile
  *
  * Copyright (C) 2013  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/cpu.h>
 #include <linux/delay.h>
index b23378f3d7e1726b6f92b3cc8be0ba8264c838f7..7437c01513f632651caf955b410b42906a828676 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for R-Mobile / SH-Mobile
  *
@@ -5,10 +6,6 @@
  * Copyright (C) 2011  Paul Mundt
  *
  * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/init.h>
 #include <asm/cacheflush.h>
index 7efe95bd584f07a6895a829702579868364d1a17..8c2a205915245a65a72db531b3aa26473e3a8db3 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car Generation 2 Power management support
  *
  * Copyright (C) 2013 - 2015  Renesas Electronics Corporation
  * Copyright (C) 2011  Renesas Solutions Corp.
  * Copyright (C) 2011  Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/kernel.h>
index 94fdeef11b81c4b860982efc7631b5d79e82fd03..c6a11b5ec6dbc704d867cbcee5c1fce26ef69b57 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * rmobile power management support
  *
@@ -7,10 +8,6 @@
  *
  * based on pm-sh7372.c
  *  Copyright (C) 2011 Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 #include <linux/clk/renesas.h>
 #include <linux/console.h>
@@ -189,7 +186,7 @@ static void __init add_special_pd(struct device_node *np, enum pd_types type)
                return;
        }
 
-       pr_debug("Special PM domain %s type %d for %pOF\n", pd->name, type, np);
+       pr_debug("Special PM domain %pOFn type %d for %pOF\n", pd, type, np);
 
        special_pds[num_special_pds].pd = pd;
        special_pds[num_special_pds].type = type;
index 8146bb6d7237eafc8c1cf5cc87a8c95f5fe62a6e..69f839259b092002691b4b295738ec81927e9316 100644 (file)
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * Copyright (C) 2012 Renesas Solutions Corp.
  *
  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 #ifndef PM_RMOBILE_H
 #define PM_RMOBILE_H
index 21ebc7678ffddbba07a1ffa3be13eb01b2dec1ed..8e50daa99151686c7fad5981a2fbd6075f680cd0 100644 (file)
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/mfd/da9063/registers.h>
 
-
 #define IRQC_BASE              0xe61c0000
 #define IRQC_MONITOR           0x104   /* IRQn Signal Level Monitor Register */
 
 /* start of DA9210 System Control and Event Registers */
 #define DA9210_REG_MASK_A              0x54
 
+struct regulator_quirk {
+       struct list_head                list;
+       const struct of_device_id       *id;
+       struct of_phandle_args          irq_args;
+       struct i2c_msg                  i2c_msg;
+       bool                            shared; /* IRQ line is shared */
+};
+
+static LIST_HEAD(quirk_list);
 static void __iomem *irqc;
 
 /* first byte sets the memory pointer, following are consecutive reg values */
 static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff };
 static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff };
 
-static struct i2c_msg da9xxx_msgs[3] = {
-       {
-               .addr = 0x58,
-               .len = ARRAY_SIZE(da9063_irq_clr),
-               .buf = da9063_irq_clr,
-       }, {
-               .addr = 0x68,
-               .len = ARRAY_SIZE(da9210_irq_clr),
-               .buf = da9210_irq_clr,
-       }, {
-               .addr = 0x70,
-               .len = ARRAY_SIZE(da9210_irq_clr),
-               .buf = da9210_irq_clr,
-       },
+static struct i2c_msg da9063_msg = {
+       .len = ARRAY_SIZE(da9063_irq_clr),
+       .buf = da9063_irq_clr,
+};
+
+static struct i2c_msg da9210_msg = {
+       .len = ARRAY_SIZE(da9210_irq_clr),
+       .buf = da9210_irq_clr,
+};
+
+static const struct of_device_id rcar_gen2_quirk_match[] = {
+       { .compatible = "dlg,da9063", .data = &da9063_msg },
+       { .compatible = "dlg,da9210", .data = &da9210_msg },
+       {},
 };
 
 static int regulator_quirk_notify(struct notifier_block *nb,
                                  unsigned long action, void *data)
 {
+       struct regulator_quirk *pos, *tmp;
        struct device *dev = data;
        struct i2c_client *client;
        static bool done;
+       int ret;
        u32 mon;
 
        if (done)
@@ -80,17 +92,20 @@ static int regulator_quirk_notify(struct notifier_block *nb,
        client = to_i2c_client(dev);
        dev_dbg(dev, "Detected %s\n", client->name);
 
-       if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) ||
-           (client->addr == 0x68 && !strcmp(client->name, "da9210")) ||
-           (client->addr == 0x70 && !strcmp(client->name, "da9210"))) {
-               int ret, len;
+       /*
+        * Send message to all PMICs that share an IRQ line to deassert it.
+        *
+        * WARNING: This works only if all the PMICs are on the same I2C bus.
+        */
+       list_for_each_entry(pos, &quirk_list, list) {
+               if (!pos->shared)
+                       continue;
 
-               /* There are two DA9210 on Stout, one on the other boards. */
-               len = of_machine_is_compatible("renesas,stout") ? 3 : 2;
+               dev_info(&client->dev, "clearing %s@0x%02x interrupts\n",
+                        pos->id->compatible, pos->i2c_msg.addr);
 
-               dev_info(&client->dev, "clearing da9063/da9210 interrupts\n");
-               ret = i2c_transfer(client->adapter, da9xxx_msgs, len);
-               if (ret != len)
+               ret = i2c_transfer(client->adapter, &pos->i2c_msg, 1);
+               if (ret != 1)
                        dev_err(&client->dev, "i2c error %d\n", ret);
        }
 
@@ -103,6 +118,11 @@ static int regulator_quirk_notify(struct notifier_block *nb,
 remove:
        dev_info(dev, "IRQ2 is not asserted, removing quirk\n");
 
+       list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
+               list_del(&pos->list);
+               kfree(pos);
+       }
+
        done = true;
        iounmap(irqc);
        return 0;
@@ -114,7 +134,12 @@ static struct notifier_block regulator_quirk_nb = {
 
 static int __init rcar_gen2_regulator_quirk(void)
 {
-       u32 mon;
+       struct regulator_quirk *quirk, *pos, *tmp;
+       struct of_phandle_args *argsa, *argsb;
+       const struct of_device_id *id;
+       struct device_node *np;
+       u32 mon, addr;
+       int ret;
 
        if (!of_machine_is_compatible("renesas,koelsch") &&
            !of_machine_is_compatible("renesas,lager") &&
@@ -122,22 +147,78 @@ static int __init rcar_gen2_regulator_quirk(void)
            !of_machine_is_compatible("renesas,gose"))
                return -ENODEV;
 
+       for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
+               if (!of_device_is_available(np))
+                       break;
+
+               ret = of_property_read_u32(np, "reg", &addr);
+               if (ret)        /* Skip invalid entry and continue */
+                       continue;
+
+               quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
+               if (!quirk) {
+                       ret = -ENOMEM;
+                       goto err_mem;
+               }
+
+               argsa = &quirk->irq_args;
+               memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg));
+
+               quirk->id = id;
+               quirk->i2c_msg.addr = addr;
+
+               ret = of_irq_parse_one(np, 0, argsa);
+               if (ret) {      /* Skip invalid entry and continue */
+                       kfree(quirk);
+                       continue;
+               }
+
+               list_for_each_entry(pos, &quirk_list, list) {
+                       argsb = &pos->irq_args;
+
+                       if (argsa->args_count != argsb->args_count)
+                               continue;
+
+                       ret = memcmp(argsa->args, argsb->args,
+                                    argsa->args_count *
+                                    sizeof(argsa->args[0]));
+                       if (!ret) {
+                               pos->shared = true;
+                               quirk->shared = true;
+                       }
+               }
+
+               list_add_tail(&quirk->list, &quirk_list);
+       }
+
        irqc = ioremap(IRQC_BASE, PAGE_SIZE);
-       if (!irqc)
-               return -ENOMEM;
+       if (!irqc) {
+               ret = -ENOMEM;
+               goto err_mem;
+       }
 
        mon = ioread32(irqc + IRQC_MONITOR);
        if (mon & REGULATOR_IRQ_MASK) {
                pr_debug("%s: IRQ2 is not asserted, not installing quirk\n",
                         __func__);
-               iounmap(irqc);
-               return 0;
+               ret = 0;
+               goto err_free;
        }
 
        pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n");
 
        bus_register_notifier(&i2c_bus_type, &regulator_quirk_nb);
        return 0;
+
+err_free:
+       iounmap(irqc);
+err_mem:
+       list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
+               list_del(&pos->list);
+               kfree(pos);
+       }
+
+       return ret;
 }
 
 arch_initcall(rcar_gen2_regulator_quirk);
diff --git a/arch/arm/mach-shmobile/setup-r7s9210.c b/arch/arm/mach-shmobile/setup-r7s9210.c
new file mode 100644 (file)
index 0000000..573fb99
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r7s9210 processor support
+ *
+ * Copyright (C) 2018  Renesas Electronics Corporation
+ * Copyright (C) 2018  Chris Brandt
+ *
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static const char *const r7s9210_boards_compat_dt[] __initconst = {
+       "renesas,r7s9210",
+       NULL,
+};
+
+DT_MACHINE_START(R7S72100_DT, "Generic R7S9210 (Flattened Device Tree)")
+       .l2c_aux_val    = 0,
+       .l2c_aux_mask   = ~0,
+       .init_early     = shmobile_init_delay,
+       .init_late      = shmobile_init_late,
+       .dt_compat      = r7s9210_boards_compat_dt,
+MACHINE_END
index d589326099e01f6dc92cda4c37f5cb267b6ed810..b13ec9088ce5354c80bfb475641faab0b2770244 100644 (file)
@@ -7,9 +7,7 @@
  * Copyright (C) 2013  Cogent Embedded, Inc.
  */
 #include <linux/init.h>
-#include <linux/irq.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/arm-gic.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 013acc97795cbfc48bb99323a3936e1a9de46adc..eea60b20c6b4605fe15f225388e66f5a209847f5 100644 (file)
@@ -25,6 +25,7 @@
 static const struct of_device_id cpg_matches[] __initconst = {
        { .compatible = "renesas,rcar-gen2-cpg-clocks", },
        { .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" },
+       { .compatible = "renesas,r8a7744-cpg-mssr", .data = "extal" },
        { .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" },
        { .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" },
        { .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" },
@@ -193,6 +194,7 @@ MACHINE_END
 
 static const char * const rz_g1_boards_compat_dt[] __initconst = {
        "renesas,r8a7743",
+       "renesas,r8a7744",
        "renesas,r8a7745",
        "renesas,r8a77470",
        NULL,
index 41137404382e2f94c61d610988c4e442dc094800..9bc543faba96af6e272c137c99b5464da12bf975 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for R-Mobile / SH-Mobile - sh73a0 portion
  *
  * Copyright (C) 2010  Magnus Damm
  * Copyright (C) 2010  Takashi Yoshii
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 74b30bade2c15c380c0d3fd721d5aa80a957ef79..3969a499746e8c6ed17dc36504a789454518175a 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Suspend-to-RAM support code for SH-Mobile ARM
  *
  *  Copyright (C) 2011 Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/pm.h>
index e48b0939693f6ebc69ab5ccf02f7fdba52f0a027..2335311b5f365cd503d0c2078b04f10a319bef19 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SH-Mobile Timer
  *
  * Copyright (C) 2010  Magnus Damm
  * Copyright (C) 2002 - 2009  Paul Mundt
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/platform_device.h>
 #include <linux/clocksource.h>
index 4f43c1cd5db08acd77d5b8fe81a9459890a21f5e..c3c8bf54f0335d14b1b232c2e880f9dbaf80e0e9 100644 (file)
@@ -29,17 +29,4 @@ config U300_DEBUG
        help
                Debug support for U300 in sysfs, procfs etc.
 
-config MACH_U300_SPIDUMMY
-       depends on ARCH_U300
-       bool "SSP/SPI dummy chip"
-       select SPI
-       select SPI_MASTER
-       select SPI_PL022
-       help
-               This creates a small kernel module that creates a dummy
-               SPI device to be used for loopback tests. Regularly used
-               to test reference designs. If you're not testing SPI,
-               you don't need it. Selecting this will activate the
-               SPI framework and ARM PL022 support.
-
 endif
index 87d37de054b65b5d273dddd29d97ac5fc0912c8b..5a8804fa8776889625d55b5531683f38ff0cf4ba 100644 (file)
@@ -4,5 +4,4 @@
 
 obj-y          := core.o
 
-obj-$(CONFIG_MACH_U300_SPIDUMMY)  += dummyspichip.o
 obj-$(CONFIG_REGULATOR_AB3100)    += regulator.o
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
deleted file mode 100644 (file)
index 68fe986..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * arch/arm/mach-u300/dummyspichip.c
- *
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * This is a dummy loopback SPI "chip" used for testing SPI.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/sysfs.h>
-#include <linux/mutex.h>
-#include <linux/spi/spi.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-/*
- * WARNING! Do not include this pl022-specific controller header
- * for any generic driver. It is only done in this dummy chip
- * because we alter the chip configuration in order to test some
- * different settings on the loopback device. Normal chip configs
- * shall be STATIC and not altered by the driver!
- */
-#include <linux/amba/pl022.h>
-
-struct dummy {
-       struct device *dev;
-       struct mutex lock;
-};
-
-#define DMA_TEST_SIZE 2048
-
-/* When we cat /sys/bus/spi/devices/spi0.0/looptest this will be triggered */
-static ssize_t dummy_looptest(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct spi_device *spi = to_spi_device(dev);
-       struct dummy *p_dummy = dev_get_drvdata(&spi->dev);
-
-       /*
-        * WARNING! Do not dereference the chip-specific data in any normal
-        * driver for a chip. It is usually STATIC and shall not be read
-        * or written to. Your chip driver should NOT depend on fields in this
-        * struct, this is just used here to alter the behaviour of the chip
-        * in order to perform tests.
-        */
-       int status;
-       u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD,
-                       0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05,
-                       0xF0, 0x0D};
-       u8 rxbuf[14];
-       u8 *bigtxbuf_virtual;
-       u8 *bigrxbuf_virtual;
-
-       if (mutex_lock_interruptible(&p_dummy->lock))
-               return -ERESTARTSYS;
-
-       bigtxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL);
-       if (bigtxbuf_virtual == NULL) {
-               status = -ENOMEM;
-               goto out;
-       }
-       bigrxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL);
-
-       /* Fill TXBUF with some happy pattern */
-       memset(bigtxbuf_virtual, 0xAA, DMA_TEST_SIZE);
-
-       /*
-        * Force chip to 8 bit mode
-        * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
-        */
-       spi->bits_per_word = 8;
-       /* You should NOT DO THIS EITHER */
-       spi->master->setup(spi);
-
-       /* Now run the tests for 8bit mode */
-       pr_info("Simple test 1: write 0xAA byte, read back garbage byte "
-               "in 8bit mode\n");
-       status = spi_w8r8(spi, 0xAA);
-       if (status < 0)
-               pr_warn("Simple test 1: FAILURE: spi_write_then_read failed with status %d\n",
-                       status);
-       else
-               pr_info("Simple test 1: SUCCESS!\n");
-
-       pr_info("Simple test 2: write 8 bytes, read back 8 bytes garbage "
-               "in 8bit mode (full FIFO)\n");
-       status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
-       if (status < 0)
-               pr_warn("Simple test 2: FAILURE: spi_write_then_read() failed with status %d\n",
-                       status);
-       else
-               pr_info("Simple test 2: SUCCESS!\n");
-
-       pr_info("Simple test 3: write 14 bytes, read back 14 bytes garbage "
-               "in 8bit mode (see if we overflow FIFO)\n");
-       status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
-       if (status < 0)
-               pr_warn("Simple test 3: FAILURE: failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 3: SUCCESS!\n");
-
-       pr_info("Simple test 4: write 8 bytes with spi_write(), read 8 "
-               "bytes garbage with spi_read() in 8bit mode\n");
-       status = spi_write(spi, &txbuf[0], 8);
-       if (status < 0)
-               pr_warn("Simple test 4 step 1: FAILURE: spi_write() failed with status %d\n",
-                       status);
-       else
-               pr_info("Simple test 4 step 1: SUCCESS!\n");
-       status = spi_read(spi, &rxbuf[0], 8);
-       if (status < 0)
-               pr_warn("Simple test 4 step 2: FAILURE: spi_read() failed with status %d\n",
-                       status);
-       else
-               pr_info("Simple test 4 step 2: SUCCESS!\n");
-
-       pr_info("Simple test 5: write 14 bytes with spi_write(), read "
-               "14 bytes garbage with spi_read() in 8bit mode\n");
-       status = spi_write(spi, &txbuf[0], 14);
-       if (status < 0)
-               pr_warn("Simple test 5 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 5 step 1: SUCCESS!\n");
-       status = spi_read(spi, &rxbuf[0], 14);
-       if (status < 0)
-               pr_warn("Simple test 5 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 5: SUCCESS!\n");
-
-       pr_info("Simple test 6: write %d bytes with spi_write(), "
-               "read %d bytes garbage with spi_read() in 8bit mode\n",
-               DMA_TEST_SIZE, DMA_TEST_SIZE);
-       status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
-       if (status < 0)
-               pr_warn("Simple test 6 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 6 step 1: SUCCESS!\n");
-       status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
-       if (status < 0)
-               pr_warn("Simple test 6 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 6: SUCCESS!\n");
-
-
-       /*
-        * Force chip to 16 bit mode
-        * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
-        */
-       spi->bits_per_word = 16;
-       /* You should NOT DO THIS EITHER */
-       spi->master->setup(spi);
-
-       pr_info("Simple test 7: write 0xAA byte, read back garbage byte "
-               "in 16bit bus mode\n");
-       status = spi_w8r8(spi, 0xAA);
-       if (status == -EIO)
-               pr_info("Simple test 7: SUCCESS! (expected failure with "
-                       "status EIO)\n");
-       else if (status < 0)
-               pr_warn("Simple test 7: FAILURE: spi_write_then_read failed with status %d\n",
-                       status);
-       else
-               pr_warn("Simple test 7: FAILURE: spi_write_then_read succeeded but it was expected to fail!\n");
-
-       pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage "
-               "in 16bit mode (full FIFO)\n");
-       status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
-       if (status < 0)
-               pr_warn("Simple test 8: FAILURE: spi_write_then_read() failed with status %d\n",
-                       status);
-       else
-               pr_info("Simple test 8: SUCCESS!\n");
-
-       pr_info("Simple test 9: write 14 bytes, read back 14 bytes garbage "
-               "in 16bit mode (see if we overflow FIFO)\n");
-       status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
-       if (status < 0)
-               pr_warn("Simple test 9: FAILURE: failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 9: SUCCESS!\n");
-
-       pr_info("Simple test 10: write %d bytes with spi_write(), "
-              "read %d bytes garbage with spi_read() in 16bit mode\n",
-              DMA_TEST_SIZE, DMA_TEST_SIZE);
-       status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
-       if (status < 0)
-               pr_warn("Simple test 10 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 10 step 1: SUCCESS!\n");
-
-       status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
-       if (status < 0)
-               pr_warn("Simple test 10 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n",
-                       status);
-       else
-               pr_info("Simple test 10: SUCCESS!\n");
-
-       status = sprintf(buf, "loop test complete\n");
-       kfree(bigrxbuf_virtual);
-       kfree(bigtxbuf_virtual);
- out:
-       mutex_unlock(&p_dummy->lock);
-       return status;
-}
-
-static DEVICE_ATTR(looptest, S_IRUGO, dummy_looptest, NULL);
-
-static int pl022_dummy_probe(struct spi_device *spi)
-{
-       struct dummy *p_dummy;
-       int status;
-
-       dev_info(&spi->dev, "probing dummy SPI device\n");
-
-       p_dummy = kzalloc(sizeof *p_dummy, GFP_KERNEL);
-       if (!p_dummy)
-               return -ENOMEM;
-
-       dev_set_drvdata(&spi->dev, p_dummy);
-       mutex_init(&p_dummy->lock);
-
-       /* sysfs hook */
-       status = device_create_file(&spi->dev, &dev_attr_looptest);
-       if (status) {
-               dev_dbg(&spi->dev, "device_create_file looptest failure.\n");
-               goto out_dev_create_looptest_failed;
-       }
-
-       return 0;
-
-out_dev_create_looptest_failed:
-       dev_set_drvdata(&spi->dev, NULL);
-       kfree(p_dummy);
-       return status;
-}
-
-static int pl022_dummy_remove(struct spi_device *spi)
-{
-       struct dummy *p_dummy = dev_get_drvdata(&spi->dev);
-
-       dev_info(&spi->dev, "removing dummy SPI device\n");
-       device_remove_file(&spi->dev, &dev_attr_looptest);
-       dev_set_drvdata(&spi->dev, NULL);
-       kfree(p_dummy);
-
-       return 0;
-}
-
-static const struct of_device_id pl022_dummy_dt_match[] = {
-       { .compatible = "arm,pl022-dummy" },
-       {},
-};
-
-static struct spi_driver pl022_dummy_driver = {
-       .driver = {
-               .name   = "spi-dummy",
-               .of_match_table = pl022_dummy_dt_match,
-       },
-       .probe  = pl022_dummy_probe,
-       .remove = pl022_dummy_remove,
-};
-
-module_spi_driver(pl022_dummy_driver);
-MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
-MODULE_DESCRIPTION("PL022 SSP/SPI DUMMY Linux driver");
-MODULE_LICENSE("GPL");
index f0292a30e6f696058114ac64d54c5f8720447b70..10ef99ce1d9051c25b358898ee85fa32dbb2a7da 100644 (file)
@@ -233,7 +233,7 @@ int __init zynq_early_slcr_init(void)
 
        register_restart_handler(&zynq_slcr_restart_nb);
 
-       pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
+       pr_info("%pOFn mapped to %p\n", np, zynq_slcr_base);
 
        of_node_put(np);
 
index 66566472c15384c6eb9fc0bea6045b8c8287e972..661fe48ab78da175732920d87046ec7460bc5d8f 100644 (file)
@@ -9,7 +9,6 @@
  *
  *  DMA uncached mapping support.
  */
-#include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/genalloc.h>
index 0cc8e04295a40dc1d16f308396afdfb7540aa48c..32e4845af2b66fe1af4c1b43601b05b1fd1c51f8 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/errno.h>
 #include <linux/swap.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/sched/signal.h>
 #include <linux/sched/task.h>
@@ -508,7 +507,7 @@ void __init mem_init(void)
 
        /* this will put all unused low memory onto the freelists */
        free_unused_memmap();
-       free_all_bootmem();
+       memblock_free_all();
 
 #ifdef CONFIG_SA1111
        /* now that our DMA memory is actually so designated, we can free it */
index e46a6a446cdd27126869bb97574d5bf51075e9e4..f5cc1ccfea3db97ac5e72867c034e79b797fbe92 100644 (file)
@@ -721,7 +721,7 @@ EXPORT_SYMBOL(phys_mem_access_prot);
 
 static void __init *early_alloc_aligned(unsigned long sz, unsigned long align)
 {
-       void *ptr = __va(memblock_alloc(sz, align));
+       void *ptr = __va(memblock_phys_alloc(sz, align));
        memset(ptr, 0, sz);
        return ptr;
 }
index b600e38364eb64ccd99ce165e4d4a13825408937..377ff9cda667a11135fef4f12d84d160a3b08aaa 100644 (file)
@@ -256,7 +256,7 @@ config S3C_PM_DEBUG_LED_SMDK
 
 config SAMSUNG_PM_CHECK
        bool "S3C2410 PM Suspend Memory CRC"
-       depends on PM
+       depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210)
        select CRC32
        help
          Enable the PM code's memory area checksum over sleep. This option
index 785d2a562a231390e8f22933297da682c43145db..cb44aa290e73c5290586f737fe5ffae2f108bae6 100644 (file)
@@ -1,6 +1,5 @@
 #include <linux/cpu.h>
 #include <linux/dma-mapping.h>
-#include <linux/bootmem.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
 #include <linux/export.h>
index 0641ba54ab62ae9786cb12ab88b2666b5c783b7a..e70a49fc8dcd1f8c13a260c91ace70a2e299393c 100644 (file)
@@ -1,4 +1,4 @@
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/gfp.h>
 #include <linux/export.h>
 #include <linux/spinlock.h>
index 964f682a2b7b0b8da41248665d09980a1808983e..787d7850e0643d80197e29bcfbfedf6d40ab46eb 100644 (file)
@@ -139,7 +139,6 @@ config ARM64
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_HW_BREAKPOINT if PERF_EVENTS
        select HAVE_IRQ_TIME_ACCOUNTING
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP if NUMA
        select HAVE_NMI
        select HAVE_PATA_PLATFORM
@@ -161,7 +160,6 @@ config ARM64
        select MULTI_IRQ_HANDLER
        select NEED_DMA_MAP_STATE
        select NEED_SG_DMA_LENGTH
-       select NO_BOOTMEM
        select OF
        select OF_EARLY_FLATTREE
        select OF_RESERVED_MEM
index 5a89a957641b5270ed4b370f72e813e16cf1d765..51bc479334a43f5dbc7686a25d5e261c83e742dd 100644 (file)
@@ -3,6 +3,7 @@ menu "Platform selection"
 config ARCH_ACTIONS
        bool "Actions Semi Platforms"
        select OWL_TIMER
+       select PINCTRL
        help
          This enables support for the Actions Semiconductor S900 SoC family.
 
@@ -67,6 +68,7 @@ config ARCH_EXYNOS
        select HAVE_S3C_RTC if RTC_CLASS
        select PINCTRL
        select PINCTRL_EXYNOS
+       select PM_GENERIC_DOMAINS if PM
        select SOC_SAMSUNG
        help
          This enables support for ARMv8 based Samsung Exynos SoC family.
@@ -153,40 +155,30 @@ config ARCH_REALTEK
          This enables support for the ARMv8 based Realtek chipsets,
          like the RTD1295.
 
-config ARCH_ROCKCHIP
-       bool "Rockchip Platforms"
-       select ARCH_HAS_RESET_CONTROLLER
-       select GPIOLIB
-       select PINCTRL
-       select PINCTRL_ROCKCHIP
-       select PM
-       select ROCKCHIP_TIMER
-       help
-         This enables support for the ARMv8 based Rockchip chipsets,
-         like the RK3368.
-
-config ARCH_SEATTLE
-       bool "AMD Seattle SoC Family"
-       help
-         This enables support for AMD Seattle SOC Family
-
-config ARCH_SHMOBILE
-       bool
-
-config ARCH_SYNQUACER
-       bool "Socionext SynQuacer SoC Family"
-
 config ARCH_RENESAS
        bool "Renesas SoC Platforms"
-       select ARCH_SHMOBILE
        select PINCTRL
        select PM
        select PM_GENERIC_DOMAINS
        select RENESAS_IRQC
        select SOC_BUS
+       select SYS_SUPPORTS_SH_CMT
+       select SYS_SUPPORTS_SH_TMU
        help
          This enables support for the ARMv8 based Renesas SoCs.
 
+config ARCH_R8A774A1
+       bool "Renesas RZ/G2M SoC Platform"
+       depends on ARCH_RENESAS
+       help
+         This enables support for the Renesas RZ/G2M SoC.
+
+config ARCH_R8A774C0
+       bool "Renesas RZ/G2E SoC Platform"
+       depends on ARCH_RENESAS
+       help
+         This enables support for the Renesas RZ/G2E SoC.
+
 config ARCH_R8A7795
        bool "Renesas R-Car H3 SoC Platform"
        depends on ARCH_RENESAS
@@ -229,11 +221,31 @@ config ARCH_R8A77995
        help
          This enables support for the Renesas R-Car D3 SoC.
 
+config ARCH_ROCKCHIP
+       bool "Rockchip Platforms"
+       select ARCH_HAS_RESET_CONTROLLER
+       select GPIOLIB
+       select PINCTRL
+       select PINCTRL_ROCKCHIP
+       select PM
+       select ROCKCHIP_TIMER
+       help
+         This enables support for the ARMv8 based Rockchip chipsets,
+         like the RK3368.
+
+config ARCH_SEATTLE
+       bool "AMD Seattle SoC Family"
+       help
+         This enables support for AMD Seattle SOC Family
+
 config ARCH_STRATIX10
        bool "Altera's Stratix 10 SoCFPGA Family"
        help
          This enables support for Altera's Stratix 10 SoCFPGA Family.
 
+config ARCH_SYNQUACER
+       bool "Socionext SynQuacer SoC Family"
+
 config ARCH_TEGRA
        bool "NVIDIA Tegra SoC Family"
        select ARCH_HAS_RESET_CONTROLLER
@@ -302,6 +314,7 @@ config ARCH_ZX
 
 config ARCH_ZYNQMP
        bool "Xilinx ZynqMP Family"
+       select ZYNQMP_FIRMWARE
        help
          This enables support for Xilinx ZynqMP Family
 
index d8b923480f5a790f5c2e6cecee67a996d96e00cb..b57fd2372ecd55608e87b48fbd42864fe3c7d9f8 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
 dtb-$(CONFIG_ARCH_ACTIONS) += s700-cubieboard7.dtb
 
 dtb-$(CONFIG_ARCH_ACTIONS) += s900-bubblegum-96.dtb
index ef79d7905f44639b255a65f8a7dc3c290fb90baf..28f3f4a0f7f061d9d2a8856ce902b81f17a00eb5 100644 (file)
                device_type = "memory";
                reg = <0x1 0xe0000000 0x0 0x0>;
        };
-
-       uart3_clk: uart3-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <921600>;
-               #clock-cells = <0>;
-       };
 };
 
 &timer {
@@ -42,5 +36,4 @@
 
 &uart3 {
        status = "okay";
-       clocks = <&uart3_clk>;
 };
index 66dd5309f0a23b87c8f39838131f5ab28bb8cdce..192c7b39c8c1da52d38ea4a3266bd400cfc50ac3 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2017 Andreas Färber
  */
 
+#include <dt-bindings/clock/actions,s700-cmu.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
                #clock-cells = <0>;
        };
 
+       losc: losc {
+               compatible = "fixed-clock";
+               clock-frequency = <32768>;
+               #clock-cells = <0>;
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                uart0: serial@e0120000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0120000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART0>;
                        interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart1: serial@e0122000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0122000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART1>;
                        interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart2: serial@e0124000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0124000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART2>;
                        interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart3: serial@e0126000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0126000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART3>;
                        interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart4: serial@e0128000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0128000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART4>;
                        interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart5: serial@e012a000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe012a000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART5>;
                        interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart6: serial@e012c000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe012c000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART6>;
                        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
+               cmu: clock-controller@e0168000 {
+                       compatible = "actions,s700-cmu";
+                       reg = <0x0 0xe0168000 0x0 0x1000>;
+                       clocks = <&hosc>, <&losc>;
+                       #clock-cells = <1>;
+               };
+
                sps: power-controller@e01b0100 {
                        compatible = "actions,s700-sps";
                        reg = <0x0 0xe01b0100 0x0 0x100>;
index 21ca80f9941ce040b5ed64621a40897ab32a8e2c..732daaa6e9d3d89fe76864915ae6d50934e3389a 100644 (file)
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
 /dts-v1/;
                device_type = "memory";
                reg = <0x0 0x0 0x0 0x80000000>;
        };
+};
+
+&i2c0 {
+       status = "disabled";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_default>;
+};
+
+&i2c1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_default>;
+};
+
+&i2c2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_default>;
+};
+
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ *         NC = not connected (pin out but not routed from the chip to
+ *              anything the board)
+ *         "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ *         LSEC = Low Speed External Connector
+ *         HSEC = High Speed External Connector
+ *
+ * Line names are taken from the schematic "Schematics Bubblegum96"
+ * version v1.0
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Boards naming of a line and the schematic name of
+ * the same line are in conflict, the 96Boards specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART2. Only exception is the I2C lines for which the schematic
+ * naming has been preferred. This is only for the informational
+ * lines i.e. "[FOO]", the GPIO named lines "GPIO-A" thru "GPIO-L"
+ * are the only ones actually used for GPIO.
+ */
+
+&pinctrl {
+       gpio-line-names =
+               "GPIO-A", /* GPIO_0, LSEC pin 23 */
+               "GPIO-B", /* GPIO_1, LSEC pin 24 */
+               "GPIO-C", /* GPIO_2, LSEC pin 25 */
+               "GPIO-D", /* GPIO_3, LSEC pin 26 */
+               "GPIO-E", /* GPIO_4, LSEC pin 27 */
+               "GPIO-F", /* GPIO_5, LSEC pin 28 */
+               "GPIO-G", /* GPIO_6, LSEC pin 29 */
+               "GPIO-H", /* GPIO_7, LSEC pin 30 */
+               "GPIO-I", /* GPIO_8, LSEC pin 31 */
+               "GPIO-J", /* GPIO_9, LSEC pin 32 */
+               "NC", /* GPIO_10 */
+               "NC", /* GPIO_11 */
+               "SIRQ2_1V8", /* GPIO_12 */
+               "PCM0_OUT", /* GPIO_13 */
+               "WIFI_LED", /* GPIO_14 */
+               "PCM0_SYNC", /* GPIO_15 */
+               "PCM0_CLK", /* GPIO_16 */
+               "PCM0_IN", /* GPIO_17 */
+               "BT_LED", /* GPIO_18 */
+               "LED0", /* GPIO_19 */
+               "LED1", /* GPIO_20 */
+               "JTAG_TCK", /* GPIO_21 */
+               "JTAG_TMS", /* GPIO_22 */
+               "JTAG_TDI", /* GPIO_23 */
+               "JTAG_TDO", /* GPIO_24 */
+               "[UART1_RxD]", /* GPIO_25, LSEC pin 13 */
+               "NC", /* GPIO_26 */
+               "[UART1_TxD]", /* GPIO_27, LSEC pin 11 */
+               "SD0_D0", /* GPIO_28 */
+               "SD0_D1", /* GPIO_29 */
+               "SD0_D2", /* GPIO_30 */
+               "SD0_D3", /* GPIO_31 */
+               "SD1_D0", /* GPIO_32 */
+               "SD1_D1", /* GPIO_33 */
+               "SD1_D2", /* GPIO_34 */
+               "SD1_D3", /* GPIO_35 */
+               "SD0_CMD", /* GPIO_36 */
+               "SD0_CLK", /* GPIO_37 */
+               "SD1_CMD", /* GPIO_38 */
+               "SD1_CLK", /* GPIO_39 */
+               "SPI0_SCLK", /* GPIO_40, LSEC pin 8 */
+               "SPI0_CS", /* GPIO_41, LSEC pin 12 */
+               "SPI0_DIN", /* GPIO_42, LSEC pin 10 */
+               "SPI0_DOUT", /* GPIO_43, LSEC pin 14 */
+               "I2C5_SDATA", /* GPIO_44, HSEC pin 36 */
+               "I2C5_SCLK", /* GPIO_45, HSEC pin 38 */
+               "UART0_RX", /* GPIO_46, LSEC pin 7 */
+               "UART0_TX", /* GPIO_47, LSEC pin 5 */
+               "UART0_RTSB", /* GPIO_48, LSEC pin 9 */
+               "UART0_CTSB", /* GPIO_49, LSEC pin 3 */
+               "I2C4_SCLK", /* GPIO_50, HSEC pin 32 */
+               "I2C4_SDATA", /* GPIO_51, HSEC pin 34 */
+               "I2C0_SCLK", /* GPIO_52 */
+               "I2C0_SDATA", /* GPIO_53 */
+               "I2C1_SCLK", /* GPIO_54, LSEC pin 15 */
+               "I2C1_SDATA", /* GPIO_55, LSEC pin 17 */
+               "I2C2_SCLK", /* GPIO_56, LSEC pin 19 */
+               "I2C2_SDATA", /* GPIO_57, LSEC pin 21 */
+               "CSI0_DN0", /* GPIO_58, HSEC pin 10 */
+               "CSI0_DP0", /* GPIO_59, HSEC pin 8 */
+               "CSI0_DN1", /* GPIO_60, HSEC pin 16 */
+               "CSI0_DP1", /* GPIO_61, HSEC pin 14 */
+               "CSI0_CN", /* GPIO_62, HSEC pin 4 */
+               "CSI0_CP", /* GPIO_63, HSEC pin 2 */
+               "CSI0_DN2", /* GPIO_64, HSEC pin 22 */
+               "CSI0_DP2", /* GPIO_65, HSEC pin 20 */
+               "CSI0_DN3", /* GPIO_66, HSEC pin 28 */
+               "CSI0_DP3", /* GPIO_67, HSEC pin 26 */
+               "[CLK0]", /* GPIO_68, HSEC pin 15 */
+               "CSI1_DN0", /* GPIO_69, HSEC pin 44 */
+               "CSI1_DP0", /* GPIO_70, HSEC pin 42 */
+               "CSI1_DN1", /* GPIO_71, HSEC pin 50 */
+               "CSI1_DP1", /* GPIO_72, HSEC pin 48 */
+               "CSI1_CN", /* GPIO_73, HSEC pin 56 */
+               "CSI1_CP", /* GPIO_74, HSEC pin 54 */
+               "[CLK1]", /* GPIO_75, HSEC pin 17 */
+               "[GPIOD0]", /* GPIO_76 */
+               "[GPIOD1]", /* GPIO_77 */
+               "BT_RST_N", /* GPIO_78 */
+               "EXT_DC_EN", /* GPIO_79 */
+               "[PCM_DI]", /* GPIO_80, LSEC pin 22 */
+               "[PCM_DO]", /* GPIO_81, LSEC pin 20 */
+               "[PCM_CLK]", /* GPIO_82, LSEC pin 18 */
+               "[PCM_FS]", /* GPIO_83, LSEC pin 16 */
+               "WAKE_BT", /* GPIO_84 */
+               "WL_REG_ON", /* GPIO_85 */
+               "NC", /* GPIO_86 */
+               "NC", /* GPIO_87 */
+               "NC", /* GPIO_88 */
+               "NC", /* GPIO_89 */
+               "NC", /* GPIO_90 */
+               "WIFI_WAKE", /* GPIO_91 */
+               "BT_WAKE", /* GPIO_92 */
+               "NC", /* GPIO_93 */
+               "OTG_EN2", /* GPIO_94 */
+               "OTG_EN", /* GPIO_95 */
+               "DSI_DP3", /* GPIO_96, HSEC pin 45 */
+               "DSI_DN3", /* GPIO_97, HSEC pin 47 */
+               "DSI_DP1", /* GPIO_98, HSEC pin 33 */
+               "DSI_DN1", /* GPIO_99, HSEC pin 35 */
+               "DSI_CP", /* GPIO_100, HSEC pin 21 */
+               "DSI_CN", /* GPIO_101, HSEC pin 23 */
+               "DSI_DP0", /* GPIO_102, HSEC pin 27 */
+               "DSI_DN0", /* GPIO_103, HSEC pin 29 */
+               "DSI_DP2", /* GPIO_104, HSEC pin 39 */
+               "DSI_DN2", /* GPIO_105, HSEC pin 41 */
+               "N0_D0", /* GPIO_106 */
+               "N0_D1", /* GPIO_107 */
+               "N0_D2", /* GPIO_108 */
+               "N0_D3", /* GPIO_109 */
+               "N0_D4", /* GPIO_110 */
+               "N0_D5", /* GPIO_111 */
+               "N0_D6", /* GPIO_112 */
+               "N0_D7", /* GPIO_113 */
+               "N0_DQS", /* GPIO_114 */
+               "N0_DQSN", /* GPIO_115 */
+               "NC", /* GPIO_116 */
+               "NC", /* GPIO_117 */
+               "NC", /* GPIO_118 */
+               "N0_CEB1", /* GPIO_119 */
+               "CARD_DT", /* GPIO_120 */
+               "N0_CEB3", /* GPIO_121 */
+               "SD_DAT0", /* GPIO_122, HSEC pin 1 */
+               "SD_DAT1", /* GPIO_123, HSEC pin 3 */
+               "SD_DAT2", /* GPIO_124, HSEC pin 5 */
+               "SD_DAT3", /* GPIO_125, HSEC pin 7 */
+               "NC", /* GPIO_126 */
+               "NC", /* GPIO_127 */
+               "[PWR_BTN_N]", /* GPIO_128, LSEC pin 4 */
+               "[RST_BTN_N]", /* GPIO_129, LSEC pin 6 */
+               "NC", /* GPIO_130 */
+               "SD_CMD", /* GPIO_131 */
+               "GPIO-L", /* GPIO_132, LSEC pin 34 */
+               "GPIO-K", /* GPIO_133, LSEC pin 33 */
+               "NC", /* GPIO_134 */
+               "SD_SCLK", /* GPIO_135 */
+               "NC", /* GPIO_136 */
+               "JTAG_TRST", /* GPIO_137 */
+               "I2C3_SCLK", /* GPIO_138 */
+               "LED2", /* GPIO_139 */
+               "LED3", /* GPIO_140 */
+               "I2C3_SDATA", /* GPIO_141 */
+               "UART3_RX", /* GPIO_142 */
+               "UART3_TX", /* GPIO_143 */
+               "UART3_RTSB", /* GPIO_144 */
+               "UART3_CTSB"; /* GPIO_145 */
+
+       i2c0_default: i2c0-default {
+               pinmux {
+                       groups = "i2c0_mfp";
+                       function = "i2c0";
+               };
+               pinconf {
+                       pins = "i2c0_sclk", "i2c0_sdata";
+                       bias-pull-up;
+               };
+       };
+
+       i2c1_default: i2c1-default {
+               pinconf {
+                       pins = "i2c1_sclk", "i2c1_sdata";
+                       bias-pull-up;
+               };
+       };
 
-       uart5_clk: uart5-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <921600>;
-               #clock-cells = <0>;
+       i2c2_default: i2c2-default {
+               pinconf {
+                       pins = "i2c2_sclk", "i2c2_sdata";
+                       bias-pull-up;
+               };
        };
 };
 
 
 &uart5 {
        status = "okay";
-       clocks = <&uart5_clk>;
 };
index 11406f6d3a6d5d2124c7afc82492c72dbfafa3c6..491ddccc9038b45a230c5d33afc29d370f8344e1 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Andreas Färber
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
+#include <dt-bindings/clock/actions,s900-cmu.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
                #clock-cells = <0>;
        };
 
+       losc: losc {
+               compatible = "fixed-clock";
+               clock-frequency = <32768>;
+               #clock-cells = <0>;
+       };
+
+       diff24M: diff24M {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               #clock-cells = <0>;
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                uart0: serial@e0120000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0120000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART0>;
                        interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart1: serial@e0122000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0122000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART1>;
                        interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart2: serial@e0124000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0124000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART2>;
                        interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart3: serial@e0126000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0126000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART3>;
                        interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart4: serial@e0128000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe0128000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART4>;
                        interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart5: serial@e012a000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe012a000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART5>;
                        interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
                uart6: serial@e012c000 {
                        compatible = "actions,s900-uart", "actions,owl-uart";
                        reg = <0x0 0xe012c000 0x0 0x2000>;
+                       clocks = <&cmu CLK_UART6>;
                        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
+               sps: power-controller@e012e000 {
+                       compatible = "actions,s900-sps";
+                       reg = <0x0 0xe012e000 0x0 0x2000>;
+                       #power-domain-cells = <1>;
+               };
+
+               cmu: clock-controller@e0160000 {
+                       compatible = "actions,s900-cmu";
+                       reg = <0x0 0xe0160000 0x0 0x1000>;
+                       clocks = <&hosc>, <&losc>;
+                       #clock-cells = <1>;
+               };
+
+               i2c0: i2c@e0170000 {
+                       compatible = "actions,s900-i2c";
+                       reg = <0 0xe0170000 0 0x1000>;
+                       clocks = <&cmu CLK_I2C0>;
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@e0172000 {
+                       compatible = "actions,s900-i2c";
+                       reg = <0 0xe0172000 0 0x1000>;
+                       clocks = <&cmu CLK_I2C1>;
+                       interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@e0174000 {
+                       compatible = "actions,s900-i2c";
+                       reg = <0 0xe0174000 0 0x1000>;
+                       clocks = <&cmu CLK_I2C2>;
+                       interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@e0176000 {
+                       compatible = "actions,s900-i2c";
+                       reg = <0 0xe0176000 0 0x1000>;
+                       clocks = <&cmu CLK_I2C3>;
+                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@e0178000 {
+                       compatible = "actions,s900-i2c";
+                       reg = <0 0xe0178000 0 0x1000>;
+                       clocks = <&cmu CLK_I2C4>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@e017a000 {
+                       compatible = "actions,s900-i2c";
+                       reg = <0 0xe017a000 0 0x1000>;
+                       clocks = <&cmu CLK_I2C5>;
+                       interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               pinctrl: pinctrl@e01b0000 {
+                       compatible = "actions,s900-pinctrl";
+                       reg = <0x0 0xe01b0000 0x0 0x1000>;
+                       clocks = <&cmu CLK_GPIO>;
+                       gpio-controller;
+                       gpio-ranges = <&pinctrl 0 0 146>;
+                       #gpio-cells = <2>;
+               };
+
                timer: timer@e0228000 {
                        compatible = "actions,s900-timer";
                        reg = <0x0 0xe0228000 0x0 0x8000>;
                        interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "timer1";
                };
+
+               dma: dma-controller@e0260000 {
+                       compatible = "actions,s900-dma";
+                       reg = <0x0 0xe0260000 0x0 0x1000>;
+                       interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       dma-channels = <12>;
+                       dma-requests = <46>;
+                       clocks = <&cmu CLK_DMAC>;
+               };
        };
 };
index 9ffa7a038791eb26aacd9d02a528fba224f4571c..8d4f97f279e022570b5bb17c5f0e4d692d71f584 100644 (file)
@@ -4,10 +4,13 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.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
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinebook.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-libretech-all-h3-cc.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo-plus2.dtb
@@ -15,4 +18,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-pc2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-prime.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus2.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
index eac4793c850249b2016e8ddf4bffb710b3e6e129..6cb2b7f0c8173387f1914ab5b3f143494ad1523b 100644 (file)
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index 094cfed13df97aa35e58ec6e06dc86fcbc18767a..ef1c90401bb2a027a4823ad4e50268a1523beca5 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";
 
        };
 };
 
+&de {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
        status = "okay";
 };
 
+&hdmi {
+       hvcc-supply = <&reg_dldo1>;
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 &i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins>;
 
 &mmc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&mmc2_pins>;
+       pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <8>;
        non-removable;
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index 98dbff19f5cccd6db3711cbe611f2fe3f0f8128f..31884dbc8838fd4681f3021f8a302ec3ffe2efa5 100644 (file)
        compatible = "friendlyarm,nanopi-a64", "allwinner,sun50i-a64";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
        };
 
        chosen {
                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";
+
+               blue {
+                       label = "nanopi-a64:blue:status";
+                       gpios = <&pio 3 24 GPIO_ACTIVE_LOW>; /* PD24 */
+               };
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rtc 1>;
+               clock-names = "ext_clock";
+               reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+       };
+};
+
+&de {
+       status = "okay";
 };
 
 &ehci0 {
        status = "okay";
 };
 
+&emac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       phy-mode = "rgmii";
+       phy-handle = <&ext_rgmii_phy>;
+       phy-supply = <&reg_dcdc1>;
+       status = "okay";
+};
+
+&hdmi {
+       hvcc-supply = <&reg_dldo1>;
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 /* i2c1 connected with gpio headers like pine64, bananapi */
 &i2c1 {
        pinctrl-names = "default";
        bias-pull-up;
 };
 
+&mdio {
+       ext_rgmii_phy: ethernet-phy@1 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <7>;
+       };
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
        status = "okay";
 };
 
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&reg_dcdc1>;
+       vqmmc-supply = <&reg_dldo4>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       rtl8189etv: wifi@1 {
+               reg = <1>;
+               interrupt-parent = <&r_pio>;
+               interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
+               interrupt-names = "host-wake";
+       };
+};
+
 &ohci0 {
        status = "okay";
 };
 
 &reg_dcdc1 {
        regulator-always-on;
-       regulator-min-microvolt = <3000000>;
-       regulator-max-microvolt = <3000000>;
-       regulator-name = "vcc-3v";
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-3v3";
 };
 
 &reg_dcdc2 {
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index 3f531393eaee9a8cbae54ad5e1f5fd0e1b3aafbb..f7a4bccaa5d40a0a4c15309cf3b832eb711f0fbf 100644 (file)
@@ -51,6 +51,7 @@
        compatible = "olimex,a64-olinuxino", "allwinner,sun50i-a64";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
        };
 
                stdout-path = "serial0:115200n8";
        };
 
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb1-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               enable-active-high;
+               gpio = <&pio 6 9 GPIO_ACTIVE_HIGH>; /* PG9 */
+               status = "okay";
+       };
+
        wifi_pwrseq: wifi_pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
        };
 };
 
+&de {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&emac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       phy-mode = "rgmii";
+       phy-handle = <&ext_rgmii_phy>;
+       phy-supply = <&reg_dcdc1>;
+       allwinner,tx-delay-ps = <600>;
+       status = "okay";
+};
+
+&hdmi {
+       hvcc-supply = <&reg_dldo1>;
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&mdio {
+       ext_rgmii_phy: ethernet-phy@1 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
        };
 };
 
+&ohci0 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
 &r_rsb {
        status = "okay";
 
                reg = <0x3a3>;
                interrupt-parent = <&r_intc>;
                interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+               x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
        };
 };
 
 
 /* DCDC3 is polyphased with DCDC2 */
 
+/*
+ * The board uses DDR3L DRAM chips. 1.36V is the closest to the nominal
+ * 1.35V that the PMIC can drive.
+ */
 &reg_dcdc5 {
        regulator-always-on;
-       regulator-min-microvolt = <1500000>;
-       regulator-max-microvolt = <1500000>;
+       regulator-min-microvolt = <1360000>;
+       regulator-max-microvolt = <1360000>;
        regulator-name = "vcc-ddr3";
 };
 
        regulator-name = "vcc-wifi-io";
 };
 
+&reg_drivevbus {
+       regulator-name = "usb0-vbus";
+       status = "okay";
+};
+
 &reg_eldo1 {
        regulator-min-microvolt = <1800000>;
        regulator-max-microvolt = <1800000>;
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usbphy {
        status = "okay";
+       usb0_id_det-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+       usb0_vbus-supply = <&reg_drivevbus>;
+       usb1_vbus-supply = <&reg_usb1_vbus>;
 };
index 1221764f5719cfe19a97b63c440ff8465e2b5dec..b0c64f75792c163bd7d0000ea023541079fbd1be 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
+ * Copyright (C) 2017-2018 Samuel Holland <samuel@sholland.org>
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
        compatible = "xunlong,orangepi-win", "allwinner,sun50i-a64";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
        };
 
        chosen {
                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";
+
+               status {
+                       label = "orangepi:green:status";
+                       gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
+               };
+       };
+
+       reg_gmac_3v3: gmac-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "gmac-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               enable-active-high;
+               gpio = <&pio 3 14 GPIO_ACTIVE_HIGH>; /* PD14 */
+               status = "okay";
+       };
+
+       reg_usb1_vbus: usb1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb1-vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               enable-active-high;
+               gpio = <&pio 3 7 GPIO_ACTIVE_HIGH>; /* PD7 */
+               status = "okay";
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 */
+       };
+};
+
+&de {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
 };
 
 &ehci1 {
        status = "okay";
 };
 
+&emac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       phy-mode = "rgmii";
+       phy-handle = <&ext_rgmii_phy>;
+       phy-supply = <&reg_gmac_3v3>;
+       status = "okay";
+};
+
+&hdmi {
+       hvcc-supply = <&reg_dldo1>;
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&mdio {
+       ext_rgmii_phy: ethernet-phy@1 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
        vmmc-supply = <&reg_dcdc1>;
-       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+       disable-wp;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&reg_dldo2>;
+       vqmmc-supply = <&reg_dldo4>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+};
+
+&ohci0 {
        status = "okay";
 };
 
 #include "axp803.dtsi"
 
 &reg_aldo1 {
-       regulator-always-on;
-       regulator-min-microvolt = <1800000>;
-       regulator-max-microvolt = <3300000>;
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
        regulator-name = "afvcc-csi";
 };
 
        regulator-name = "vcc-wifi-io";
 };
 
+&reg_drivevbus {
+       regulator-name = "usb0-vbus";
+       status = "okay";
+};
+
 &reg_eldo1 {
        regulator-min-microvolt = <1800000>;
        regulator-max-microvolt = <1800000>;
        regulator-name = "cpvdd";
 };
 
+&reg_eldo3 {
+       regulator-min-microvolt = <1500000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "dvdd-csi";
+};
+
 &reg_fldo1 {
        regulator-min-microvolt = <1200000>;
        regulator-max-microvolt = <1200000>;
        vcc-hdmi-supply = <&reg_dldo1>;
 };
 
+&spi0 {
+       status = "okay";
+
+       spi-flash@0 {
+               compatible = "mxicy,mx25l1606e", "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <80000000>;
+               m25p,fast-read;
+               status = "okay";
+       };
+};
+
+/* On debug connector */
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
-&usbphy {
+/* Bluetooth */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
        status = "okay";
 };
 
+/* On Pi-2 connector, RTS/CTS optional */
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "disabled";
+};
+
+/* On Pi-2 connector, RTS/CTS optional */
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+       status = "disabled";
+};
+
+/* On Pi-2 connector (labeled for SPI1), RTS/CTS optional */
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_pins>;
+       status = "disabled";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+       usb0_vbus-supply = <&reg_drivevbus>;
+       usb1_vbus-supply = <&reg_usb1_vbus>;
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
new file mode 100644 (file)
index 0000000..72d6961
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ *
+ * Copyright (c) 2018 ARM Ltd.
+ */
+
+#include "sun50i-a64-sopine-baseboard.dts"
+
+/ {
+       model = "Pine64 LTS";
+       compatible = "pine64,pine64-lts", "allwinner,sun50i-r18",
+                    "allwinner,sun50i-a64";
+};
index 1b9b92e541d2d7348225a38dd49dd45202687356..c077b6c1f458a31f731e0a8ec388c13fedef50ae 100644 (file)
        chosen {
                stdout-path = "serial0:115200n8";
        };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+};
+
+&de {
+       status = "okay";
 };
 
 &ehci0 {
 
 };
 
+&hdmi {
+       hvcc-supply = <&reg_dldo1>;
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 &i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins>;
 /* On Exp and Euler connectors */
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index 897e60cbe38d1121c0878c742e7d3fd1bf4a52a5..77fac84797e9d03cfd78a0e1ed285e713a0f871e 100644 (file)
@@ -80,8 +80,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
        vmmc-supply = <&reg_dcdc1>;
-       cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
        disable-wp;
        bus-width = <4>;
        status = "okay";
 
 &mmc2 {
        pinctrl-names = "default";
-       pinctrl-0 = <&mmc2_pins>;
+       pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
        vmmc-supply = <&reg_dcdc1>;
        vqmmc-supply = <&reg_eldo1>;
        bus-width = <8>;
 &r_i2c {
        clock-frequency = <100000>;
        pinctrl-names = "default";
-       pinctrl-0 = <&r_i2c_pins_a>;
+       pinctrl-0 = <&r_i2c_pl89_pins>;
        status = "okay";
 };
 
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index c21f2331add60255d0cb97b49319a3e30c22d354..53fcc9098df364c165c19705ee115c5cd959cac2 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
        reg_vcc1v8: vcc1v8 {
                compatible = "regulator-fixed";
                regulator-name = "vcc1v8";
        };
 };
 
+&de {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
        status = "okay";
 };
 
+&hdmi {
+       hvcc-supply = <&reg_dldo1>;
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 &mdio {
        ext_rgmii_phy: ethernet-phy@1 {
                compatible = "ethernet-phy-ieee802.3-c22";
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index 81f8e0098699e89ec3f9b56405aa5f1509957ab1..c455b24dd079a426f6feaa3b6659b8e14eb9e40b 100644 (file)
 
 &uart0 {
        pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pins_a>;
+       pinctrl-0 = <&uart0_pb_pins>;
        status = "okay";
 };
 
index d3daf90a8715c50b844eb6e6f577aeb2c756991b..f3a66f888205e11d54b8fdba57618e6c2df5daed 100644 (file)
@@ -88,6 +88,7 @@
                        device_type = "cpu";
                        reg = <0>;
                        enable-method = "psci";
+                       next-level-cache = <&L2>;
                };
 
                cpu1: cpu@1 {
@@ -95,6 +96,7 @@
                        device_type = "cpu";
                        reg = <1>;
                        enable-method = "psci";
+                       next-level-cache = <&L2>;
                };
 
                cpu2: cpu@2 {
                        device_type = "cpu";
                        reg = <2>;
                        enable-method = "psci";
+                       next-level-cache = <&L2>;
                };
 
                cpu3: cpu@3 {
                        device_type = "cpu";
                        reg = <3>;
                        enable-method = "psci";
+                       next-level-cache = <&L2>;
                };
+
+               L2: l2-cache {
+                       compatible = "cache";
+                       cache-level = <2>;
+               };
+       };
+
+       de: display-engine {
+               compatible = "allwinner,sun50i-a64-display-engine";
+               allwinner,pipelines = <&mixer0>,
+                                     <&mixer1>;
+               status = "disabled";
        };
 
        osc24M: osc24M_clk {
                                #clock-cells = <1>;
                                #reset-cells = <1>;
                        };
+
+                       mixer0: mixer@100000 {
+                               compatible = "allwinner,sun50i-a64-de2-mixer-0";
+                               reg = <0x100000 0x100000>;
+                               clocks = <&display_clocks CLK_BUS_MIXER0>,
+                                        <&display_clocks CLK_MIXER0>;
+                               clock-names = "bus",
+                                             "mod";
+                               resets = <&display_clocks RST_MIXER0>;
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       mixer0_out: port@1 {
+                                               reg = <1>;
+
+                                               mixer0_out_tcon0: endpoint {
+                                                       remote-endpoint = <&tcon0_in_mixer0>;
+                                               };
+                                       };
+                               };
+                       };
+
+                       mixer1: mixer@200000 {
+                               compatible = "allwinner,sun50i-a64-de2-mixer-1";
+                               reg = <0x200000 0x100000>;
+                               clocks = <&display_clocks CLK_BUS_MIXER1>,
+                                        <&display_clocks CLK_MIXER1>;
+                               clock-names = "bus",
+                                             "mod";
+                               resets = <&display_clocks RST_MIXER1>;
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       mixer1_out: port@1 {
+                                               reg = <1>;
+
+                                               mixer1_out_tcon1: endpoint {
+                                                       remote-endpoint = <&tcon1_in_mixer1>;
+                                               };
+                                       };
+                               };
+                       };
                };
 
                syscon: syscon@1c00000 {
                        #dma-cells = <1>;
                };
 
+               tcon0: lcd-controller@1c0c000 {
+                       compatible = "allwinner,sun50i-a64-tcon-lcd",
+                                    "allwinner,sun8i-a83t-tcon-lcd";
+                       reg = <0x01c0c000 0x1000>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>;
+                       clock-names = "ahb", "tcon-ch0";
+                       clock-output-names = "tcon-pixel-clock";
+                       resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
+                       reset-names = "lcd", "lvds";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tcon0_in: port@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       tcon0_in_mixer0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&mixer0_out_tcon0>;
+                                       };
+                               };
+
+                               tcon0_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               tcon1: lcd-controller@1c0d000 {
+                       compatible = "allwinner,sun50i-a64-tcon-tv",
+                                    "allwinner,sun8i-a83t-tcon-tv";
+                       reg = <0x01c0d000 0x1000>;
+                       interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_TCON1>;
+                       clock-names = "ahb", "tcon-ch1";
+                       resets = <&ccu RST_BUS_TCON1>;
+                       reset-names = "lcd";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tcon1_in: port@0 {
+                                       reg = <0>;
+
+                                       tcon1_in_mixer1: endpoint {
+                                               remote-endpoint = <&mixer1_out_tcon1>;
+                                       };
+                               };
+
+                               tcon1_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       tcon1_out_hdmi: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&hdmi_in_tcon1>;
+                                       };
+                               };
+                       };
+               };
+
                mmc0: mmc@1c0f000 {
                        compatible = "allwinner,sun50i-a64-mmc";
                        reg = <0x01c0f000 0x1000>;
                        #size-cells = <0>;
                };
 
+               sid: eeprom@1c14000 {
+                       compatible = "allwinner,sun50i-a64-sid";
+                       reg = <0x1c14000 0x400>;
+               };
+
                usb_otg: usb@1c19000 {
                        compatible = "allwinner,sun8i-a33-musb";
                        reg = <0x01c19000 0x0400>;
                        };
 
                        mmc2_pins: mmc2-pins {
-                               pins = "PC1", "PC5", "PC6", "PC8", "PC9",
+                               pins = "PC5", "PC6", "PC8", "PC9",
                                       "PC10","PC11", "PC12", "PC13",
                                       "PC14", "PC15", "PC16";
                                function = "mmc2";
                                bias-pull-up;
                        };
 
+                       mmc2_ds_pin: mmc2-ds-pin {
+                               pins = "PC1";
+                               function = "mmc2";
+                               drive-strength = <30>;
+                               bias-pull-up;
+                       };
+
                        pwm_pin: pwm_pin {
                                pins = "PD22";
                                function = "pwm";
                                function = "spi1";
                        };
 
-                       uart0_pins_a: uart0 {
+                       uart0_pb_pins: uart0-pb-pins {
                                pins = "PB8", "PB9";
                                function = "uart0";
                        };
                        status = "disabled";
                };
 
+               hdmi: hdmi@1ee0000 {
+                       compatible = "allwinner,sun50i-a64-dw-hdmi",
+                                    "allwinner,sun8i-a83t-dw-hdmi";
+                       reg = <0x01ee0000 0x10000>;
+                       reg-io-width = <1>;
+                       interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>,
+                                <&ccu CLK_HDMI>;
+                       clock-names = "iahb", "isfr", "tmds";
+                       resets = <&ccu RST_BUS_HDMI1>;
+                       reset-names = "ctrl";
+                       phys = <&hdmi_phy>;
+                       phy-names = "hdmi-phy";
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               hdmi_in: port@0 {
+                                       reg = <0>;
+
+                                       hdmi_in_tcon1: endpoint {
+                                               remote-endpoint = <&tcon1_out_hdmi>;
+                                       };
+                               };
+
+                               hdmi_out: port@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               hdmi_phy: hdmi-phy@1ef0000 {
+                       compatible = "allwinner,sun50i-a64-hdmi-phy";
+                       reg = <0x01ef0000 0x10000>;
+                       clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>,
+                                <&ccu 7>;
+                       clock-names = "bus", "mod", "pll-0";
+                       resets = <&ccu RST_BUS_HDMI0>;
+                       reset-names = "phy";
+                       #phy-cells = <0>;
+               };
+
                rtc: rtc@1f00000 {
                        compatible = "allwinner,sun6i-a31-rtc";
                        reg = <0x01f00000 0x54>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 
-                       r_i2c_pins_a: i2c-a {
+                       r_i2c_pl89_pins: r-i2c-pl89-pins {
                                pins = "PL8", "PL9";
                                function = "s_i2c";
                        };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-bananapi-m2-plus-v1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-bananapi-m2-plus-v1.2.dts
new file mode 100644 (file)
index 0000000..2e2b14c
--- /dev/null
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2018 Chen-Yu Tsai <wens@csie.org>
+
+/dts-v1/;
+#include "sun50i-h5.dtsi"
+#include <arm/sunxi-bananapi-m2-plus-v1.2.dtsi>
+
+/ {
+       model = "Banana Pi BPI-M2-Plus v1.2 H5";
+       compatible = "bananapi,bpi-m2-plus-v1.2", "allwinner,sun50i-h5";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-bananapi-m2-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-bananapi-m2-plus.dts
new file mode 100644 (file)
index 0000000..7766100
--- /dev/null
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2018 Chen-Yu Tsai <wens@csie.org>
+
+/dts-v1/;
+#include "sun50i-h5.dtsi"
+#include <arm/sunxi-bananapi-m2-plus.dtsi>
+
+/ {
+       model = "Banana Pi BPI-M2-Plus H5";
+       compatible = "sinovoip,bpi-m2-plus", "allwinner,sun50i-h5";
+};
index 62d646baac3c403bb1d1908278694f7404a954f6..b41dc1aab67d3ec6a32d9173b277c7b01b81a78b 100644 (file)
                             <GIC_PPI 10
                                (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
        };
+
+       soc {
+               mali: gpu@1e80000 {
+                       compatible = "allwinner,sun50i-h5-mali", "arm,mali-450";
+                       reg = <0x01e80000 0x30000>;
+                       /*
+                        * While the datasheet lists an interrupt for the
+                        * PMU, the actual silicon does not have the PMU
+                        * block. Reads all return zero, and writes are
+                        * ignored.
+                        */
+                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "gp",
+                                         "gpmmu",
+                                         "pp",
+                                         "pp0",
+                                         "ppmmu0",
+                                         "pp1",
+                                         "ppmmu1",
+                                         "pp2",
+                                         "ppmmu2",
+                                         "pp3",
+                                         "ppmmu3",
+                                         "pmu";
+                       clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>;
+                       clock-names = "bus", "core";
+                       resets = <&ccu RST_BUS_GPU>;
+
+                       assigned-clocks = <&ccu CLK_GPU>;
+                       assigned-clock-rates = <384000000>;
+               };
+       };
 };
 
 &ccu {
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts
new file mode 100644 (file)
index 0000000..0612c19
--- /dev/null
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "OrangePi One Plus";
+       compatible = "xunlong,orangepi-one-plus", "allwinner,sun50i-h6";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins>;
+       vmmc-supply = <&reg_cldo1>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&r_i2c {
+       status = "okay";
+
+       axp805: pmic@36 {
+               compatible = "x-powers,axp805", "x-powers,axp806";
+               reg = <0x36>;
+               interrupt-parent = <&r_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               x-powers,self-working-mode;
+
+               regulators {
+                       reg_aldo1: aldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-pl";
+                       };
+
+                       reg_aldo2: aldo2 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-ac200";
+                       };
+
+                       reg_aldo3: aldo3 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc25-dram";
+                       };
+
+                       reg_bldo1: bldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-bias-pll";
+                       };
+
+                       reg_bldo2: bldo2 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-efuse-pcie-hdmi-io";
+                       };
+
+                       reg_bldo3: bldo3 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-dcxoio";
+                       };
+
+                       bldo4 {
+                               /* unused */
+                       };
+
+                       reg_cldo1: cldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-3v3";
+                       };
+
+                       reg_cldo2: cldo2 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-wifi-1";
+                       };
+
+                       reg_cldo3: cldo3 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-wifi-2";
+                       };
+
+                       reg_dcdca: dcdca {
+                               regulator-always-on;
+                               regulator-min-microvolt = <810000>;
+                               regulator-max-microvolt = <1080000>;
+                               regulator-name = "vdd-cpu";
+                       };
+
+                       reg_dcdcc: dcdcc {
+                               regulator-min-microvolt = <810000>;
+                               regulator-max-microvolt = <1080000>;
+                               regulator-name = "vdd-gpu";
+                       };
+
+                       reg_dcdcd: dcdcd {
+                               regulator-always-on;
+                               regulator-min-microvolt = <960000>;
+                               regulator-max-microvolt = <960000>;
+                               regulator-name = "vdd-sys";
+                       };
+
+                       reg_dcdce: dcdce {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-name = "vcc-dram";
+                       };
+
+                       sw {
+                               /* unused */
+                       };
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_ph_pins>;
+       status = "okay";
+};
index cfa5fffcf62b437c60a9fde4b601767ecc7548b3..040828d2e2c097d00cd5b379b15bc88cb233c47f 100644 (file)
                #size-cells = <1>;
                ranges;
 
+               syscon: syscon@3000000 {
+                       compatible = "allwinner,sun50i-h6-system-control",
+                                    "allwinner,sun50i-a64-system-control";
+                       reg = <0x03000000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       sram_c: sram@28000 {
+                               compatible = "mmio-sram";
+                               reg = <0x00028000 0x1e000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x00028000 0x1e000>;
+
+                               de2_sram: sram-section@0 {
+                                       compatible = "allwinner,sun50i-h6-sram-c",
+                                                    "allwinner,sun50i-a64-sram-c";
+                                       reg = <0x0000 0x1e000>;
+                               };
+                       };
+               };
+
                ccu: clock@3001000 {
                        compatible = "allwinner,sun50i-h6-ccu";
                        reg = <0x03001000 0x1000>;
index fb3d2ee77c567e9273ceec99763f2765a357cdae..8253a1a9e9857112f43c24d85c5c411e653376dd 100644 (file)
 
                sysmgr: sysmgr@ffd12000 {
                        compatible = "altr,sys-mgr", "syscon";
-                       reg = <0xffd12000 0x1000>;
+                       reg = <0xffd12000 0x228>;
                };
 
                /* Local timer */
index 7c661753bfaf4fade78932fd7de9754c28ddaddd..2e3863ee12b3e43be56d41bc7af86e87eac930f9 100644 (file)
@@ -21,6 +21,9 @@
 
        aliases {
                serial0 = &uart0;
+               ethernet0 = &gmac0;
+               ethernet1 = &gmac1;
+               ethernet2 = &gmac2;
        };
 
        chosen {
 &i2c1 {
        status = "okay";
        clock-frequency = <100000>;
+       i2c-sda-falling-time-ns = <890>;  /* hcnt */
+       i2c-sdl-falling-time-ns = <890>;  /* lcnt */
 
        adc@14 {
                compatible = "lltc,ltc2497";
index 125f4deb52fe9e0c08f866050788a941ca710b11..b664e7af74eb3a99953796816ed2e5525b169832 100644 (file)
                        clock-names = "uartclk", "apb_pclk";
                };
 
-               spi0: ssp@e1020000 {
+               spi0: spi@e1020000 {
                        status = "disabled";
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0 0xe1020000 0 0x1000>;
                        clock-names = "apb_pclk";
                };
 
-               spi1: ssp@e1030000 {
+               spi1: spi@e1030000 {
                        status = "disabled";
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0 0xe1030000 0 0x1000>;
index a97c0e2d7bc64b687277eeb87a550c3dd0f85ee4..c31f29d660debcfdad2ce6c58db462f297a701fd 100644 (file)
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
index d5c01427a5ca08cc9543acbfed8d22ecfdec4297..18778ada7bd32527f6060b51df09bbafd97b44ff 100644 (file)
                serial1 = &uart_A;
        };
 
+       linein: audio-codec@0 {
+               #sound-dai-cells = <0>;
+               compatible = "everest,es7241";
+               VDDA-supply = <&vcc_3v3>;
+               VDDP-supply = <&vcc_3v3>;
+               VDDD-supply = <&vcc_3v3>;
+               status = "okay";
+               sound-name-prefix = "Linein";
+       };
+
+       lineout: audio-codec@1 {
+               #sound-dai-cells = <0>;
+               compatible = "everest,es7154";
+               VDD-supply = <&vcc_3v3>;
+               PVDD-supply = <&vcc_5v>;
+               status = "okay";
+               sound-name-prefix = "Lineout";
+       };
+
+       spdif_dit: audio-codec@2 {
+               #sound-dai-cells = <0>;
+               compatible = "linux,spdif-dit";
+               status = "okay";
+               sound-name-prefix = "DIT";
+       };
+
+       dmics: audio-codec@3 {
+               #sound-dai-cells = <0>;
+               compatible = "dmic-codec";
+               num-channels = <7>;
+               wakeup-delay-ms = <50>;
+               status = "okay";
+               sound-name-prefix = "MIC";
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>;
+       };
+
        main_12v: regulator-main_12v {
                compatible = "regulator-fixed";
                regulator-name = "12V";
                regulator-always-on;
        };
 
-       vddio_boot: regulator-vddio_boot {
+       vcc_3v3: regulator-vcc_3v3 {
                compatible = "regulator-fixed";
-               regulator-name = "VDDIO_BOOT";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
+               regulator-name = "VCC_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
                vin-supply = <&vddao_3v3>;
                regulator-always-on;
        };
 
+       vcc_5v: regulator-vcc_5v {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&main_12v>;
+
+               gpio = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
        vddao_3v3: regulator-vddao_3v3 {
                compatible = "regulator-fixed";
                regulator-name = "VDDAO_3V3";
                regulator-always-on;
        };
 
-       vcc_3v3: regulator-vcc_3v3 {
+       vddio_boot: regulator-vddio_boot {
                compatible = "regulator-fixed";
-               regulator-name = "VCC_3V3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
+               regulator-name = "VDDIO_BOOT";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
                vin-supply = <&vddao_3v3>;
                regulator-always-on;
        };
 
-       vcc_5v: regulator-vcc_5v {
-               compatible = "regulator-fixed";
-               regulator-name = "VCC5V";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               vin-supply = <&main_12v>;
-
-               gpio = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
        usb_pwr: regulator-usb_pwr {
                compatible = "regulator-fixed";
                regulator-name = "USB_PWR";
                enable-active-high;
        };
 
-       emmc_pwrseq: emmc-pwrseq {
-               compatible = "mmc-pwrseq-emmc";
-               reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
-       };
-
        sdio_pwrseq: sdio-pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>;
                clock-names = "ext_clock";
        };
 
-       wifi32k: wifi32k {
-               compatible = "pwm-clock";
-               #clock-cells = <0>;
-               clock-frequency = <32768>;
-               pwms = <&pwm_ab 0 30518 0>; /* PWM_A at 32.768KHz */
-       };
-
        speaker-leds {
                compatible = "gpio-leds";
 
                };
        };
 
-       linein: audio-codec@0 {
-               #sound-dai-cells = <0>;
-               compatible = "everest,es7241";
-               VDDA-supply = <&vcc_3v3>;
-               VDDP-supply = <&vcc_3v3>;
-               VDDD-supply = <&vcc_3v3>;
+       sound {
+               compatible = "amlogic,axg-sound-card";
+               model = "AXG-S400";
+               audio-aux-devs = <&tdmin_a>, <&tdmin_b>,  <&tdmin_c>,
+                                <&tdmin_lb>, <&tdmout_c>;
+               audio-widgets = "Line", "Lineout",
+                               "Line", "Linein",
+                               "Speaker", "Speaker1 Left",
+                               "Speaker", "Speaker1 Right";
+               audio-routing = "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+                               "SPDIFOUT IN 0", "FRDDR_A OUT 3",
+                               "TDMOUT_C IN 1", "FRDDR_B OUT 2",
+                               "SPDIFOUT IN 1", "FRDDR_B OUT 3",
+                               "TDMOUT_C IN 2", "FRDDR_C OUT 2",
+                               "SPDIFOUT IN 2", "FRDDR_C OUT 3",
+                               "TDM_C Playback", "TDMOUT_C OUT",
+                               "TDMIN_A IN 2", "TDM_C Capture",
+                               "TDMIN_A IN 5", "TDM_C Loopback",
+                               "TDMIN_B IN 2", "TDM_C Capture",
+                               "TDMIN_B IN 5", "TDM_C Loopback",
+                               "TDMIN_C IN 2", "TDM_C Capture",
+                               "TDMIN_C IN 5", "TDM_C Loopback",
+                               "TDMIN_LB IN 2", "TDM_C Loopback",
+                               "TDMIN_LB IN 5", "TDM_C Capture",
+                               "TODDR_A IN 0", "TDMIN_A OUT",
+                               "TODDR_B IN 0", "TDMIN_A OUT",
+                               "TODDR_C IN 0", "TDMIN_A OUT",
+                               "TODDR_A IN 1", "TDMIN_B OUT",
+                               "TODDR_B IN 1", "TDMIN_B OUT",
+                               "TODDR_C IN 1", "TDMIN_B OUT",
+                               "TODDR_A IN 2", "TDMIN_C OUT",
+                               "TODDR_B IN 2", "TDMIN_C OUT",
+                               "TODDR_C IN 2", "TDMIN_C OUT",
+                               "TODDR_A IN 4", "PDM Capture",
+                               "TODDR_B IN 4", "PDM Capture",
+                               "TODDR_C IN 4", "PDM Capture",
+                               "TODDR_A IN 6", "TDMIN_LB OUT",
+                               "TODDR_B IN 6", "TDMIN_LB OUT",
+                               "TODDR_C IN 6", "TDMIN_LB OUT",
+                               "Lineout", "Lineout AOUTL",
+                               "Lineout", "Lineout AOUTR",
+                               "Speaker1 Left", "SPK1 OUT_A",
+                               "Speaker1 Left", "SPK1 OUT_B",
+                               "Speaker1 Right", "SPK1 OUT_C",
+                               "Speaker1 Right", "SPK1 OUT_D",
+                               "Linein AINL", "Linein",
+                               "Linein AINR", "Linein";
+               assigned-clocks = <&clkc CLKID_HIFI_PLL>,
+                                 <&clkc CLKID_MPLL0>,
+                                 <&clkc CLKID_MPLL1>;
+               assigned-clock-parents = <0>, <0>, <0>;
+               assigned-clock-rates = <589824000>,
+                                      <270950400>,
+                                      <393216000>;
                status = "okay";
-               sound-name-prefix = "Linein";
-       };
 
-       lineout: audio-codec@1 {
-               #sound-dai-cells = <0>;
-               compatible = "everest,es7154";
-               VDD-supply = <&vcc_3v3>;
-               PVDD-supply = <&vcc_5v>;
-               status = "okay";
-               sound-name-prefix = "Lineout";
+               dai-link@0 {
+                       sound-dai = <&frddr_a>;
+               };
+
+               dai-link@1 {
+                       sound-dai = <&frddr_b>;
+               };
+
+               dai-link@2 {
+                       sound-dai = <&frddr_c>;
+               };
+
+               dai-link@3 {
+                       sound-dai = <&toddr_a>;
+               };
+
+               dai-link@4 {
+                       sound-dai = <&toddr_b>;
+               };
+
+               dai-link@5 {
+                       sound-dai = <&toddr_c>;
+               };
+
+               dai-link@6 {
+                       sound-dai = <&tdmif_c>;
+                       dai-format = "i2s";
+                       dai-tdm-slot-tx-mask-2 = <1 1>;
+                       dai-tdm-slot-rx-mask-1 = <1 1>;
+                       mclk-fs = <256>;
+
+                       codec@0 {
+                               sound-dai = <&lineout>;
+                       };
+
+                       codec@1 {
+                               sound-dai = <&speaker_amp1>;
+                       };
+
+                       codec@2 {
+                               sound-dai = <&linein>;
+                       };
+
+               };
+
+               dai-link@7 {
+                       sound-dai = <&spdifout>;
+
+                       codec {
+                               sound-dai = <&spdif_dit>;
+                       };
+               };
+
+               dai-link@8 {
+                       sound-dai = <&pdm>;
+
+                       codec {
+                               sound-dai = <&dmics>;
+                       };
+               };
        };
 
-       spdif_dit: audio-codec@2 {
-               #sound-dai-cells = <0>;
-               compatible = "linux,spdif-dit";
-               status = "okay";
-               sound-name-prefix = "DIT";
+       wifi32k: wifi32k {
+               compatible = "pwm-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               pwms = <&pwm_ab 0 30518 0>; /* PWM_A at 32.768KHz */
        };
 };
 
        };
 };
 
-&uart_A {
+&frddr_a {
        status = "okay";
-       pinctrl-0 = <&uart_a_pins>;
-       pinctrl-names = "default";
 };
 
-&uart_AO {
+&frddr_b {
+       status = "okay";
+};
+
+&frddr_c {
        status = "okay";
-       pinctrl-0 = <&uart_ao_a_pins>;
-       pinctrl-names = "default";
 };
 
 &ir {
                PVDD_B-supply = <&main_12v>;
                PVDD_C-supply = <&main_12v>;
                PVDD_D-supply = <&main_12v>;
+               sound-name-prefix = "SPK1";
        };
 };
 
        };
 };
 
+&pdm {
+       pinctrl-0 = <&pdm_dclk_a14_pins>, <&pdm_din0_pins>,
+                   <&pdm_din1_pins>, <&pdm_din2_pins>, <&pdm_din3_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
 &pwm_ab {
        status = "okay";
        pinctrl-0 = <&pwm_a_x20_pins>;
        pinctrl-names = "default";
 };
 
-/* emmc storage */
-&sd_emmc_c {
+&saradc {
        status = "okay";
-       pinctrl-0 = <&emmc_pins>;
-       pinctrl-1 = <&emmc_clk_gate_pins>;
-       pinctrl-names = "default", "clk-gate";
-
-       bus-width = <8>;
-       cap-sd-highspeed;
-       cap-mmc-highspeed;
-       max-frequency = <180000000>;
-       non-removable;
-       disable-wp;
-       mmc-ddr-1_8v;
-       mmc-hs200-1_8v;
-
-       vmmc-supply = <&vcc_3v3>;
-       vqmmc-supply = <&vddio_boot>;
+       vref-supply = <&vddio_ao18>;
 };
 
 /* wifi module */
        };
 };
 
-&saradc {
+/* emmc storage */
+&sd_emmc_c {
+       status = "disabled";
+       pinctrl-0 = <&emmc_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <8>;
+       cap-sd-highspeed;
+       cap-mmc-highspeed;
+       max-frequency = <180000000>;
+       non-removable;
+       disable-wp;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+
+       mmc-pwrseq = <&emmc_pwrseq>;
+
+       vmmc-supply = <&vcc_3v3>;
+       vqmmc-supply = <&vddio_boot>;
+};
+
+&spdifout {
+       pinctrl-0 = <&spdif_out_a20_pins>;
+       pinctrl-names = "default";
        status = "okay";
-       vref-supply = <&vddio_ao18>;
+};
+
+&tdmif_a {
+       pinctrl-0 = <&tdma_sclk_pins>, <&tdma_fs_pins>,
+                   <&tdma_din0_pins>, <&tdma_dout0_x15_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&tdmif_b {
+       pinctrl-0 = <&tdmb_sclk_pins>, <&tdmb_fs_pins>,
+                   <&tdmb_din3_pins>, <&mclk_b_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&tdmif_c {
+       pinctrl-0 = <&tdmc_sclk_pins>, <&tdmc_fs_pins>,
+                   <&tdmc_din1_pins>, <&tdmc_dout2_pins>,
+                   <&mclk_c_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&tdmin_a {
+       status = "okay";
+};
+
+&tdmin_b {
+       status = "okay";
+};
+
+&tdmin_c {
+       status = "okay";
+};
+
+&tdmin_lb {
+       status = "okay";
+};
+
+&tdmout_c {
+       status = "okay";
+};
+
+&toddr_a {
+       status = "okay";
+};
+
+&toddr_b {
+       status = "okay";
+};
+
+&toddr_c {
+       status = "okay";
+};
+
+&uart_A {
+       status = "okay";
+       pinctrl-0 = <&uart_a_pins>;
+       pinctrl-names = "default";
+};
+
+&uart_AO {
+       status = "okay";
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
 };
index c518130e5ce730e8267456cee4a6062d4527b772..df017dbd2e572028f2c98b66b065d1d2b5325b3a 100644 (file)
@@ -3,13 +3,14 @@
  * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
  */
 
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/axg-aoclkc.h>
 #include <dt-bindings/clock/axg-audio-clkc.h>
 #include <dt-bindings/clock/axg-clkc.h>
-#include <dt-bindings/clock/axg-aoclkc.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/meson-axg-gpio.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-axg-reset.h>
 
 / {
        #address-cells = <2>;
        #size-cells = <2>;
 
-       reserved-memory {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               ranges;
+       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";
+       };
 
-               /* 16 MiB reserved for Hardware ROM Firmware */
-               hwrom_reserved: hwrom@0 {
-                       reg = <0x0 0x0 0x0 0x1000000>;
-                       no-map;
-               };
+       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";
+       };
 
-               /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
-               secmon_reserved: secmon@5000000 {
-                       reg = <0x0 0x05000000 0x0 0x300000>;
-                       no-map;
-               };
+       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";
+       };
+
+       ao_alt_xtal: ao_alt_xtal-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <32000000>;
+               clock-output-names = "ao_alt_xtal";
+               #clock-cells = <0>;
+       };
+
+       arm-pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
        };
 
        cpus {
                };
        };
 
-       arm-pmu {
-               compatible = "arm,cortex-a53-pmu";
-               interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
-                            <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
-       };
-
        psci {
                compatible = "arm,psci-1.0";
                method = "smc";
        };
 
-       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";
-       };
-
-       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)>;
-       };
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
 
-       xtal: xtal-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <24000000>;
-               clock-output-names = "xtal";
-               #clock-cells = <0>;
-       };
+               /* 16 MiB reserved for Hardware ROM Firmware */
+               hwrom_reserved: hwrom@0 {
+                       reg = <0x0 0x0 0x0 0x1000000>;
+                       no-map;
+               };
 
-       ao_alt_xtal: ao_alt_xtal-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <32000000>;
-               clock-output-names = "ao_alt_xtal";
-               #clock-cells = <0>;
+               /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved: secmon@5000000 {
+                       reg = <0x0 0x05000000 0x0 0x300000>;
+                       no-map;
+               };
        };
 
        soc {
                #size-cells = <2>;
                ranges;
 
-               apb: apb@ffe00000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xffe00000 0x0 0x200000>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x200000>;
-
-                       sd_emmc_b: sd@5000 {
-                               compatible = "amlogic,meson-axg-mmc";
-                               reg = <0x0 0x5000 0x0 0x800>;
-                               interrupts = <GIC_SPI 217 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>;
-                       };
+               ethmac: ethernet@ff3f0000 {
+                       compatible = "amlogic,meson-axg-dwmac", "snps,dwmac";
+                       reg = <0x0 0xff3f0000 0x0 0x10000
+                              0x0 0xff634540 0x0 0x8>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "macirq";
+                       clocks = <&clkc CLKID_ETH>,
+                                <&clkc CLKID_FCLK_DIV2>,
+                                <&clkc CLKID_MPLL2>;
+                       clock-names = "stmmaceth", "clkin0", "clkin1";
+                       status = "disabled";
+               };
 
-                       sd_emmc_c: mmc@7000 {
-                               compatible = "amlogic,meson-axg-mmc";
-                               reg = <0x0 0x7000 0x0 0x800>;
-                               interrupts = <GIC_SPI 218 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>;
-                       };
+               pdm: audio-controller@ff632000 {
+                       compatible = "amlogic,axg-pdm";
+                       reg = <0x0 0xff632000 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@ff642000 {
+               periphs: bus@ff634000 {
                        compatible = "simple-bus";
-                       reg = <0x0 0xff642000 0x0 0x2000>;
+                       reg = <0x0 0xff634000 0x0 0x2000>;
                        #address-cells = <2>;
                        #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xff642000 0x0 0x2000>;
-
-                       clkc_audio: clock-controller@0 {
-                               compatible = "amlogic,axg-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";
+                       ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
 
-                               resets = <&reset RESET_AUDIO>;
+                       hwrng: rng@18 {
+                               compatible = "amlogic,meson-rng";
+                               reg = <0x0 0x18 0x0 0x4>;
+                               clocks = <&clkc CLKID_RNG0>;
+                               clock-names = "core";
                        };
 
-                       arb: reset-controller@280 {
-                               compatible = "amlogic,meson-axg-audio-arb";
-                               reg = <0x0 0x280 0x0 0x4>;
-                               #reset-cells = <1>;
-                               clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
-                       };
+                       pinctrl_periphs: pinctrl@480 {
+                               compatible = "amlogic,meson-axg-periphs-pinctrl";
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges;
 
-                       tdmin_a: audio-controller@300 {
-                               compatible = "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";
-                       };
+                               gpio: bank@480 {
+                                       reg = <0x0 0x00480 0x0 0x40>,
+                                             <0x0 0x004e8 0x0 0x14>,
+                                             <0x0 0x00520 0x0 0x14>,
+                                             <0x0 0x00430 0x0 0x3c>;
+                                       reg-names = "mux", "pull", "pull-enable", "gpio";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       gpio-ranges = <&pinctrl_periphs 0 0 86>;
+                               };
 
-                       tdmin_b: audio-controller@340 {
-                               compatible = "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,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,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";
-                       };
-
-                       spdifout: audio-controller@480 {
-                               compatible = "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,axg-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,axg-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,axg-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";
-                       };
-               };
-
-               cbus: bus@ffd00000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xffd00000 0x0 0x25000>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x25000>;
-
-                       gpio_intc: interrupt-controller@f080 {
-                               compatible = "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>;
-                               status = "disabled";
-                       };
-
-                       pwm_ab: pwm@1b000 {
-                               compatible = "amlogic,meson-axg-ee-pwm";
-                               reg = <0x0 0x1b000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       pwm_cd: pwm@1a000 {
-                               compatible = "amlogic,meson-axg-ee-pwm";
-                               reg = <0x0 0x1a000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       reset: reset-controller@1004 {
-                               compatible = "amlogic,meson-axg-reset";
-                               reg = <0x0 0x01004 0x0 0x9c>;
-                               #reset-cells = <1>;
-                       };
-
-                       spicc0: spi@13000 {
-                               compatible = "amlogic,meson-axg-spicc";
-                               reg = <0x0 0x13000 0x0 0x3c>;
-                               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&clkc CLKID_SPICC0>;
-                               clock-names = "core";
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
-                       spicc1: spi@15000 {
-                               compatible = "amlogic,meson-axg-spicc";
-                               reg = <0x0 0x15000 0x0 0x3c>;
-                               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&clkc CLKID_SPICC1>;
-                               clock-names = "core";
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
-                       i2c0: i2c@1f000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               reg = <0x0 0x1f000 0x0 0x20>;
-                               interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc CLKID_I2C>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
-                       i2c1: i2c@1e000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               reg = <0x0 0x1e000 0x0 0x20>;
-                               interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc CLKID_I2C>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
-                       i2c2: i2c@1d000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               reg = <0x0 0x1d000 0x0 0x20>;
-                               interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc CLKID_I2C>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
-                       i2c3: i2c@1c000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               reg = <0x0 0x1c000 0x0 0x20>;
-                               interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc CLKID_I2C>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
-                       uart_A: serial@24000 {
-                               compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x24000 0x0 0x18>;
-                               interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
-                               status = "disabled";
-                               clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                       };
-
-                       uart_B: serial@23000 {
-                               compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x23000 0x0 0x18>;
-                               interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
-                               status = "disabled";
-                               clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                       };
-               };
-
-               ethmac: ethernet@ff3f0000 {
-                       compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac";
-                       reg = <0x0 0xff3f0000 0x0 0x10000
-                               0x0 0xff634540 0x0 0x8>;
-                       interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
-                       interrupt-names = "macirq";
-                       clocks = <&clkc CLKID_ETH>,
-                                <&clkc CLKID_FCLK_DIV2>,
-                                <&clkc CLKID_MPLL2>;
-                       clock-names = "stmmaceth", "clkin0", "clkin1";
-                       status = "disabled";
-               };
-
-               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>;
-               };
-
-               hiubus: bus@ff63c000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xff63c000 0x0 0x1c00>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xff63c000 0x0 0x1c00>;
+                               i2c0_pins: i2c0 {
+                                       mux {
+                                               groups = "i2c0_sck",
+                                                        "i2c0_sda";
+                                               function = "i2c0";
+                                       };
+                               };
 
-                       sysctrl: system-controller@0 {
-                               compatible = "amlogic,meson-axg-hhi-sysctrl", "syscon", "simple-mfd";
-                               reg = <0 0 0 0x400>;
+                               i2c1_x_pins: i2c1_x {
+                                       mux {
+                                               groups = "i2c1_sck_x",
+                                                        "i2c1_sda_x";
+                                               function = "i2c1";
+                                       };
+                               };
 
-                               clkc: clock-controller {
-                                       compatible = "amlogic,axg-clkc";
-                                       #clock-cells = <1>;
+                               i2c1_z_pins: i2c1_z {
+                                       mux {
+                                               groups = "i2c1_sck_z",
+                                                        "i2c1_sda_z";
+                                               function = "i2c1";
+                                       };
                                };
-                       };
-               };
 
-               mailbox: mailbox@ff63dc00 {
-                       compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
-                       reg = <0 0xff63dc00 0 0x400>;
-                       interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
-                                    <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
-                                    <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>;
-                       #mbox-cells = <1>;
-               };
+                               i2c2_a_pins: i2c2_a {
+                                       mux {
+                                               groups = "i2c2_sck_a",
+                                                        "i2c2_sda_a";
+                                               function = "i2c2";
+                                       };
+                               };
 
-               periphs: periphs@ff634000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xff634000 0x0 0x2000>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
+                               i2c2_x_pins: i2c2_x {
+                                       mux {
+                                               groups = "i2c2_sck_x",
+                                                        "i2c2_sda_x";
+                                               function = "i2c2";
+                                       };
+                               };
 
-                       hwrng: rng {
-                               compatible = "amlogic,meson-rng";
-                               reg = <0x0 0x18 0x0 0x4>;
-                               clocks = <&clkc CLKID_RNG0>;
-                               clock-names = "core";
-                       };
+                               i2c3_a6_pins: i2c3_a6 {
+                                       mux {
+                                               groups = "i2c3_sda_a6",
+                                                        "i2c3_sck_a7";
+                                               function = "i2c3";
+                                       };
+                               };
 
-                       pinctrl_periphs: pinctrl@480 {
-                               compatible = "amlogic,meson-axg-periphs-pinctrl";
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges;
+                               i2c3_a12_pins: i2c3_a12 {
+                                       mux {
+                                               groups = "i2c3_sda_a12",
+                                                        "i2c3_sck_a13";
+                                               function = "i2c3";
+                                       };
+                               };
 
-                               gpio: bank@480 {
-                                       reg = <0x0 0x00480 0x0 0x40>,
-                                               <0x0 0x004e8 0x0 0x14>,
-                                               <0x0 0x00520 0x0 0x14>,
-                                               <0x0 0x00430 0x0 0x3c>;
-                                       reg-names = "mux", "pull", "pull-enable", "gpio";
-                                       gpio-controller;
-                                       #gpio-cells = <2>;
-                                       gpio-ranges = <&pinctrl_periphs 0 0 86>;
+                               i2c3_a19_pins: i2c3_a19 {
+                                       mux {
+                                               groups = "i2c3_sda_a19",
+                                                        "i2c3_sck_a20";
+                                               function = "i2c3";
+                                       };
                                };
 
                                emmc_pins: emmc {
                                        mux {
                                                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_clk",
-                                                       "emmc_cmd",
-                                                       "emmc_ds";
+                                                        "emmc_nand_d1",
+                                                        "emmc_nand_d2",
+                                                        "emmc_nand_d3",
+                                                        "emmc_nand_d4",
+                                                        "emmc_nand_d5",
+                                                        "emmc_nand_d6",
+                                                        "emmc_nand_d7",
+                                                        "emmc_clk",
+                                                        "emmc_cmd",
+                                                        "emmc_ds";
                                                function = "emmc";
                                        };
                                };
                                        };
                                };
 
-                               sdio_pins: sdio {
+                               eth_rgmii_x_pins: eth-x-rgmii {
                                        mux {
-                                               groups = "sdio_d0",
-                                                       "sdio_d1",
-                                                       "sdio_d2",
-                                                       "sdio_d3",
-                                                       "sdio_cmd",
-                                                       "sdio_clk";
-                                               function = "sdio";
+                                               groups = "eth_mdio_x",
+                                                        "eth_mdc_x",
+                                                        "eth_rgmii_rx_clk_x",
+                                                        "eth_rx_dv_x",
+                                                        "eth_rxd0_x",
+                                                        "eth_rxd1_x",
+                                                        "eth_rxd2_rgmii",
+                                                        "eth_rxd3_rgmii",
+                                                        "eth_rgmii_tx_clk",
+                                                        "eth_txen_x",
+                                                        "eth_txd0_x",
+                                                        "eth_txd1_x",
+                                                        "eth_txd2_rgmii",
+                                                        "eth_txd3_rgmii";
+                                               function = "eth";
                                        };
                                };
 
-                               sdio_clk_gate_pins: sdio_clk_gate {
+                               eth_rgmii_y_pins: eth-y-rgmii {
                                        mux {
-                                               groups = "GPIOX_4";
-                                               function = "gpio_periphs";
-                                       };
-                                       cfg-pull-down {
-                                               pins = "GPIOX_4";
-                                               bias-pull-down;
+                                               groups = "eth_mdio_y",
+                                                        "eth_mdc_y",
+                                                        "eth_rgmii_rx_clk_y",
+                                                        "eth_rx_dv_y",
+                                                        "eth_rxd0_y",
+                                                        "eth_rxd1_y",
+                                                        "eth_rxd2_rgmii",
+                                                        "eth_rxd3_rgmii",
+                                                        "eth_rgmii_tx_clk",
+                                                        "eth_txen_y",
+                                                        "eth_txd0_y",
+                                                        "eth_txd1_y",
+                                                        "eth_txd2_rgmii",
+                                                        "eth_txd3_rgmii";
+                                               function = "eth";
                                        };
                                };
 
                                eth_rmii_x_pins: eth-x-rmii {
                                        mux {
                                                groups = "eth_mdio_x",
-                                                      "eth_mdc_x",
-                                                      "eth_rgmii_rx_clk_x",
-                                                      "eth_rx_dv_x",
-                                                      "eth_rxd0_x",
-                                                      "eth_rxd1_x",
-                                                      "eth_txen_x",
-                                                      "eth_txd0_x",
-                                                      "eth_txd1_x";
+                                                        "eth_mdc_x",
+                                                        "eth_rgmii_rx_clk_x",
+                                                        "eth_rx_dv_x",
+                                                        "eth_rxd0_x",
+                                                        "eth_rxd1_x",
+                                                        "eth_txen_x",
+                                                        "eth_txd0_x",
+                                                        "eth_txd1_x";
                                                function = "eth";
                                        };
                                };
                                eth_rmii_y_pins: eth-y-rmii {
                                        mux {
                                                groups = "eth_mdio_y",
-                                                      "eth_mdc_y",
-                                                      "eth_rgmii_rx_clk_y",
-                                                      "eth_rx_dv_y",
-                                                      "eth_rxd0_y",
-                                                      "eth_rxd1_y",
-                                                      "eth_txen_y",
-                                                      "eth_txd0_y",
-                                                      "eth_txd1_y";
+                                                        "eth_mdc_y",
+                                                        "eth_rgmii_rx_clk_y",
+                                                        "eth_rx_dv_y",
+                                                        "eth_rxd0_y",
+                                                        "eth_rxd1_y",
+                                                        "eth_txen_y",
+                                                        "eth_txd0_y",
+                                                        "eth_txd1_y";
                                                function = "eth";
                                        };
                                };
 
-                               eth_rgmii_x_pins: eth-x-rgmii {
+                               mclk_b_pins: mclk_b {
                                        mux {
-                                               groups = "eth_mdio_x",
-                                                      "eth_mdc_x",
-                                                      "eth_rgmii_rx_clk_x",
-                                                      "eth_rx_dv_x",
-                                                      "eth_rxd0_x",
-                                                      "eth_rxd1_x",
-                                                      "eth_rxd2_rgmii",
-                                                      "eth_rxd3_rgmii",
-                                                      "eth_rgmii_tx_clk",
-                                                      "eth_txen_x",
-                                                      "eth_txd0_x",
-                                                      "eth_txd1_x",
-                                                      "eth_txd2_rgmii",
-                                                      "eth_txd3_rgmii";
-                                               function = "eth";
+                                               groups = "mclk_b";
+                                               function = "mclk_b";
                                        };
                                };
 
-                               eth_rgmii_y_pins: eth-y-rgmii {
+                               mclk_c_pins: mclk_c {
                                        mux {
-                                               groups = "eth_mdio_y",
-                                                      "eth_mdc_y",
-                                                      "eth_rgmii_rx_clk_y",
-                                                      "eth_rx_dv_y",
-                                                      "eth_rxd0_y",
-                                                      "eth_rxd1_y",
-                                                      "eth_rxd2_rgmii",
-                                                      "eth_rxd3_rgmii",
-                                                      "eth_rgmii_tx_clk",
-                                                      "eth_txen_y",
-                                                      "eth_txd0_y",
-                                                      "eth_txd1_y",
-                                                      "eth_txd2_rgmii",
-                                                      "eth_txd3_rgmii";
-                                               function = "eth";
+                                               groups = "mclk_c";
+                                               function = "mclk_c";
                                        };
                                };
 
                                        };
                                };
 
+                               sdio_pins: sdio {
+                                       mux {
+                                               groups = "sdio_d0",
+                                                        "sdio_d1",
+                                                        "sdio_d2",
+                                                        "sdio_d3",
+                                                        "sdio_cmd",
+                                                        "sdio_clk";
+                                               function = "sdio";
+                                       };
+                               };
+
+                               sdio_clk_gate_pins: sdio_clk_gate {
+                                       mux {
+                                               groups = "GPIOX_4";
+                                               function = "gpio_periphs";
+                                       };
+                                       cfg-pull-down {
+                                               pins = "GPIOX_4";
+                                               bias-pull-down;
+                                       };
+                               };
+
                                spdif_in_z_pins: spdif_in_z {
                                        mux {
                                                groups = "spdif_in_z";
                                        };
                                };
 
-                               spdif_out_z_pins: spdif_out_z {
-                                       mux {
-                                               groups = "spdif_out_z";
-                                               function = "spdif_out";
-                                       };
-                               };
-
                                spdif_out_a1_pins: spdif_out_a1 {
                                        mux {
                                                groups = "spdif_out_a1";
                                        };
                                };
 
+                               spdif_out_z_pins: spdif_out_z {
+                                       mux {
+                                               groups = "spdif_out_z";
+                                               function = "spdif_out";
+                                       };
+                               };
+
                                spi0_pins: spi0 {
                                        mux {
                                                groups = "spi0_miso",
-                                                       "spi0_mosi",
-                                                       "spi0_clk";
+                                                        "spi0_mosi",
+                                                        "spi0_clk";
                                                function = "spi0";
                                        };
                                };
                                        };
                                };
 
-
                                spi1_a_pins: spi1_a {
                                        mux {
                                                groups = "spi1_miso_a",
-                                                       "spi1_mosi_a",
-                                                       "spi1_clk_a";
+                                                        "spi1_mosi_a",
+                                                        "spi1_clk_a";
                                                function = "spi1";
                                        };
                                };
                                spi1_x_pins: spi1_x {
                                        mux {
                                                groups = "spi1_miso_x",
-                                                       "spi1_mosi_x",
-                                                       "spi1_clk_x";
+                                                        "spi1_mosi_x",
+                                                        "spi1_clk_x";
                                                function = "spi1";
                                        };
                                };
                                        };
                                };
 
-                               i2c0_pins: i2c0 {
-                                       mux {
-                                               groups = "i2c0_sck",
-                                                       "i2c0_sda";
-                                               function = "i2c0";
-                                       };
-                               };
-
-                               i2c1_z_pins: i2c1_z {
-                                       mux {
-                                               groups = "i2c1_sck_z",
-                                                       "i2c1_sda_z";
-                                               function = "i2c1";
-                                       };
-                               };
-
-                               i2c1_x_pins: i2c1_x {
-                                       mux {
-                                               groups = "i2c1_sck_x",
-                                                       "i2c1_sda_x";
-                                               function = "i2c1";
-                                       };
-                               };
-
-                               i2c2_x_pins: i2c2_x {
-                                       mux {
-                                               groups = "i2c2_sck_x",
-                                                       "i2c2_sda_x";
-                                               function = "i2c2";
-                                       };
-                               };
-
-                               i2c2_a_pins: i2c2_a {
-                                       mux {
-                                               groups = "i2c2_sck_a",
-                                                       "i2c2_sda_a";
-                                               function = "i2c2";
-                                       };
-                               };
-
-                               i2c3_a6_pins: i2c3_a6 {
-                                       mux {
-                                               groups = "i2c3_sda_a6",
-                                                       "i2c3_sck_a7";
-                                               function = "i2c3";
-                                       };
-                               };
-
-                               i2c3_a12_pins: i2c3_a12 {
-                                       mux {
-                                               groups = "i2c3_sda_a12",
-                                                       "i2c3_sck_a13";
-                                               function = "i2c3";
-                                       };
-                               };
-
-                               i2c3_a19_pins: i2c3_a19 {
-                                       mux {
-                                               groups = "i2c3_sda_a19",
-                                                       "i2c3_sck_a20";
-                                               function = "i2c3";
-                                       };
-                               };
-
-                               uart_a_pins: uart_a {
-                                       mux {
-                                               groups = "uart_tx_a",
-                                                       "uart_rx_a";
-                                               function = "uart_a";
-                                       };
-                               };
-
-                               uart_a_cts_rts_pins: uart_a_cts_rts {
-                                       mux {
-                                               groups = "uart_cts_a",
-                                                       "uart_rts_a";
-                                               function = "uart_a";
-                                       };
-                               };
-
-                               uart_b_x_pins: uart_b_x {
-                                       mux {
-                                               groups = "uart_tx_b_x",
-                                                       "uart_rx_b_x";
-                                               function = "uart_b";
-                                       };
-                               };
-
-                               uart_b_x_cts_rts_pins: uart_b_x_cts_rts {
+                               tdma_din0_pins: tdma_din0 {
                                        mux {
-                                               groups = "uart_cts_b_x",
-                                                       "uart_rts_b_x";
-                                               function = "uart_b";
+                                               groups = "tdma_din0";
+                                               function = "tdma";
                                        };
                                };
 
-                               uart_b_z_pins: uart_b_z {
+                               tdma_dout0_x14_pins: tdma_dout0_x14 {
                                        mux {
-                                               groups = "uart_tx_b_z",
-                                                       "uart_rx_b_z";
-                                               function = "uart_b";
+                                               groups = "tdma_dout0_x14";
+                                               function = "tdma";
                                        };
                                };
 
-                               uart_b_z_cts_rts_pins: uart_b_z_cts_rts {
+                               tdma_dout0_x15_pins: tdma_dout0_x15 {
                                        mux {
-                                               groups = "uart_cts_b_z",
-                                                       "uart_rts_b_z";
-                                               function = "uart_b";
+                                               groups = "tdma_dout0_x15";
+                                               function = "tdma";
                                        };
                                };
 
-                               uart_ao_b_z_pins: uart_ao_b_z {
+                               tdma_dout1_pins: tdma_dout1 {
                                        mux {
-                                               groups = "uart_ao_tx_b_z",
-                                                       "uart_ao_rx_b_z";
-                                               function = "uart_ao_b_z";
+                                               groups = "tdma_dout1";
+                                               function = "tdma";
                                        };
                                };
 
-                               uart_ao_b_z_cts_rts_pins: uart_ao_b_z_cts_rts {
+                               tdma_din1_pins: tdma_din1 {
                                        mux {
-                                               groups = "uart_ao_cts_b_z",
-                                                       "uart_ao_rts_b_z";
-                                               function = "uart_ao_b_z";
+                                               groups = "tdma_din1";
+                                               function = "tdma";
                                        };
                                };
 
-                               mclk_b_pins: mclk_b {
+                               tdma_fs_pins: tdma_fs {
                                        mux {
-                                               groups = "mclk_b";
-                                               function = "mclk_b";
+                                               groups = "tdma_fs";
+                                               function = "tdma";
                                        };
                                };
 
-                               mclk_c_pins: mclk_c {
+                               tdma_fs_slv_pins: tdma_fs_slv {
                                        mux {
-                                               groups = "mclk_c";
-                                               function = "mclk_c";
+                                               groups = "tdma_fs_slv";
+                                               function = "tdma";
                                        };
                                };
 
                                        };
                                };
 
-                               tdma_fs_pins: tdma_fs {
-                                       mux {
-                                               groups = "tdma_fs";
-                                               function = "tdma";
-                                       };
-                               };
-
-                               tdma_fs_slv_pins: tdma_fs_slv {
+                               tdmb_din0_pins: tdmb_din0 {
                                        mux {
-                                               groups = "tdma_fs_slv";
-                                               function = "tdma";
+                                               groups = "tdmb_din0";
+                                               function = "tdmb";
                                        };
                                };
 
-                               tdma_din0_pins: tdma_din0 {
+                               tdmb_din1_pins: tdmb_din1 {
                                        mux {
-                                               groups = "tdma_din0";
-                                               function = "tdma";
+                                               groups = "tdmb_din1";
+                                               function = "tdmb";
                                        };
                                };
 
-                               tdma_dout0_x14_pins: tdma_dout0_x14 {
+                               tdmb_din2_pins: tdmb_din2 {
                                        mux {
-                                               groups = "tdma_dout0_x14";
-                                               function = "tdma";
+                                               groups = "tdmb_din2";
+                                               function = "tdmb";
                                        };
                                };
 
-                               tdma_dout0_x15_pins: tdma_dout0_x15 {
+                               tdmb_din3_pins: tdmb_din3 {
                                        mux {
-                                               groups = "tdma_dout0_x15";
-                                               function = "tdma";
+                                               groups = "tdmb_din3";
+                                               function = "tdmb";
                                        };
                                };
 
-                               tdma_dout1_pins: tdma_dout1 {
+                               tdmb_dout0_pins: tdmb_dout0 {
                                        mux {
-                                               groups = "tdma_dout1";
-                                               function = "tdma";
+                                               groups = "tdmb_dout0";
+                                               function = "tdmb";
                                        };
                                };
 
-                               tdma_din1_pins: tdma_din1 {
+                               tdmb_dout1_pins: tdmb_dout1 {
                                        mux {
-                                               groups = "tdma_din1";
-                                               function = "tdma";
+                                               groups = "tdmb_dout1";
+                                               function = "tdmb";
                                        };
                                };
 
-                               tdmb_sclk_pins: tdmb_sclk {
+                               tdmb_dout2_pins: tdmb_dout2 {
                                        mux {
-                                               groups = "tdmb_sclk";
+                                               groups = "tdmb_dout2";
                                                function = "tdmb";
                                        };
                                };
 
-                               tdmb_sclk_slv_pins: tdmb_sclk_slv {
+                               tdmb_dout3_pins: tdmb_dout3 {
                                        mux {
-                                               groups = "tdmb_sclk_slv";
+                                               groups = "tdmb_dout3";
                                                function = "tdmb";
                                        };
                                };
                                        };
                                };
 
-                               tdmb_din0_pins: tdmb_din0 {
+                               tdmb_sclk_pins: tdmb_sclk {
                                        mux {
-                                               groups = "tdmb_din0";
+                                               groups = "tdmb_sclk";
                                                function = "tdmb";
                                        };
                                };
 
-                               tdmb_dout0_pins: tdmb_dout0 {
+                               tdmb_sclk_slv_pins: tdmb_sclk_slv {
                                        mux {
-                                               groups = "tdmb_dout0";
+                                               groups = "tdmb_sclk_slv";
                                                function = "tdmb";
                                        };
                                };
 
-                               tdmb_din1_pins: tdmb_din1 {
+                               tdmc_fs_pins: tdmc_fs {
                                        mux {
-                                               groups = "tdmb_din1";
-                                               function = "tdmb";
+                                               groups = "tdmc_fs";
+                                               function = "tdmc";
                                        };
                                };
 
-                               tdmb_dout1_pins: tdmb_dout1 {
+                               tdmc_fs_slv_pins: tdmc_fs_slv {
                                        mux {
-                                               groups = "tdmb_dout1";
-                                               function = "tdmb";
+                                               groups = "tdmc_fs_slv";
+                                               function = "tdmc";
                                        };
                                };
 
-                               tdmb_din2_pins: tdmb_din2 {
+                               tdmc_sclk_pins: tdmc_sclk {
                                        mux {
-                                               groups = "tdmb_din2";
-                                               function = "tdmb";
+                                               groups = "tdmc_sclk";
+                                               function = "tdmc";
                                        };
                                };
 
-                               tdmb_dout2_pins: tdmb_dout2 {
+                               tdmc_sclk_slv_pins: tdmc_sclk_slv {
                                        mux {
-                                               groups = "tdmb_dout2";
-                                               function = "tdmb";
+                                               groups = "tdmc_sclk_slv";
+                                               function = "tdmc";
                                        };
                                };
 
-                               tdmb_din3_pins: tdmb_din3 {
+                               tdmc_din0_pins: tdmc_din0 {
                                        mux {
-                                               groups = "tdmb_din3";
-                                               function = "tdmb";
+                                               groups = "tdmc_din0";
+                                               function = "tdmc";
+                                       };
+                               };
+
+                               tdmc_din1_pins: tdmc_din1 {
+                                       mux {
+                                               groups = "tdmc_din1";
+                                               function = "tdmc";
+                                       };
+                               };
+
+                               tdmc_din2_pins: tdmc_din2 {
+                                       mux {
+                                               groups = "tdmc_din2";
+                                               function = "tdmc";
                                        };
                                };
 
-                               tdmb_dout3_pins: tdmb_dout3 {
+                               tdmc_din3_pins: tdmc_din3 {
                                        mux {
-                                               groups = "tdmb_dout3";
-                                               function = "tdmb";
+                                               groups = "tdmc_din3";
+                                               function = "tdmc";
                                        };
                                };
 
-                               tdmc_sclk_pins: tdmc_sclk {
+                               tdmc_dout0_pins: tdmc_dout0 {
                                        mux {
-                                               groups = "tdmc_sclk";
+                                               groups = "tdmc_dout0";
                                                function = "tdmc";
                                        };
                                };
 
-                               tdmc_sclk_slv_pins: tdmc_sclk_slv {
+                               tdmc_dout1_pins: tdmc_dout1 {
                                        mux {
-                                               groups = "tdmc_sclk_slv";
+                                               groups = "tdmc_dout1";
                                                function = "tdmc";
                                        };
                                };
 
-                               tdmc_fs_pins: tdmc_fs {
+                               tdmc_dout2_pins: tdmc_dout2 {
                                        mux {
-                                               groups = "tdmc_fs";
+                                               groups = "tdmc_dout2";
                                                function = "tdmc";
                                        };
                                };
 
-                               tdmc_fs_slv_pins: tdmc_fs_slv {
+                               tdmc_dout3_pins: tdmc_dout3 {
                                        mux {
-                                               groups = "tdmc_fs_slv";
+                                               groups = "tdmc_dout3";
                                                function = "tdmc";
                                        };
                                };
 
-                               tdmc_din0_pins: tdmc_din0 {
+                               uart_a_pins: uart_a {
                                        mux {
-                                               groups = "tdmc_din0";
-                                               function = "tdmc";
+                                               groups = "uart_tx_a",
+                                                        "uart_rx_a";
+                                               function = "uart_a";
                                        };
                                };
 
-                               tdmc_dout0_pins: tdmc_dout0 {
+                               uart_a_cts_rts_pins: uart_a_cts_rts {
                                        mux {
-                                               groups = "tdmc_dout0";
-                                               function = "tdmc";
+                                               groups = "uart_cts_a",
+                                                        "uart_rts_a";
+                                               function = "uart_a";
                                        };
                                };
 
-                               tdmc_din1_pins: tdmc_din1 {
+                               uart_b_x_pins: uart_b_x {
                                        mux {
-                                               groups = "tdmc_din1";
-                                               function = "tdmc";
+                                               groups = "uart_tx_b_x",
+                                                        "uart_rx_b_x";
+                                               function = "uart_b";
                                        };
                                };
 
-                               tdmc_dout1_pins: tdmc_dout1 {
+                               uart_b_x_cts_rts_pins: uart_b_x_cts_rts {
                                        mux {
-                                               groups = "tdmc_dout1";
-                                               function = "tdmc";
+                                               groups = "uart_cts_b_x",
+                                                        "uart_rts_b_x";
+                                               function = "uart_b";
                                        };
                                };
 
-                               tdmc_din2_pins: tdmc_din2 {
+                               uart_b_z_pins: uart_b_z {
                                        mux {
-                                               groups = "tdmc_din2";
-                                               function = "tdmc";
+                                               groups = "uart_tx_b_z",
+                                                        "uart_rx_b_z";
+                                               function = "uart_b";
                                        };
                                };
 
-                               tdmc_dout2_pins: tdmc_dout2 {
+                               uart_b_z_cts_rts_pins: uart_b_z_cts_rts {
                                        mux {
-                                               groups = "tdmc_dout2";
-                                               function = "tdmc";
+                                               groups = "uart_cts_b_z",
+                                                        "uart_rts_b_z";
+                                               function = "uart_b";
                                        };
                                };
 
-                               tdmc_din3_pins: tdmc_din3 {
+                               uart_ao_b_z_pins: uart_ao_b_z {
                                        mux {
-                                               groups = "tdmc_din3";
-                                               function = "tdmc";
+                                               groups = "uart_ao_tx_b_z",
+                                                        "uart_ao_rx_b_z";
+                                               function = "uart_ao_b_z";
                                        };
                                };
 
-                               tdmc_dout3_pins: tdmc_dout3 {
+                               uart_ao_b_z_cts_rts_pins: uart_ao_b_z_cts_rts {
                                        mux {
-                                               groups = "tdmc_dout3";
-                                               function = "tdmc";
+                                               groups = "uart_ao_cts_b_z",
+                                                        "uart_ao_rts_b_z";
+                                               function = "uart_ao_b_z";
                                        };
                                };
                        };
                };
 
-               sram: sram@fffc0000 {
-                       compatible = "amlogic,meson-axg-sram", "mmio-sram";
-                       reg = <0x0 0xfffc0000 0x0 0x20000>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x0 0xfffc0000 0x20000>;
+               hiubus: bus@ff63c000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff63c000 0x0 0x1c00>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff63c000 0x0 0x1c00>;
 
-                       cpu_scp_lpri: scp-shmem@0 {
-                               compatible = "amlogic,meson-axg-scp-shmem";
-                               reg = <0x13000 0x400>;
+                       sysctrl: system-controller@0 {
+                               compatible = "amlogic,meson-axg-hhi-sysctrl",
+                                            "simple-mfd", "syscon";
+                               reg = <0 0 0 0x400>;
+
+                               clkc: clock-controller {
+                                       compatible = "amlogic,axg-clkc";
+                                       #clock-cells = <1>;
+                               };
+                       };
+               };
+
+               mailbox: mailbox@ff63dc00 {
+                       compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+                       reg = <0 0xff63dc00 0 0x400>;
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
+                                    <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
+                                    <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>;
+                       #mbox-cells = <1>;
+               };
+
+               audio: bus@ff642000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff642000 0x0 0x2000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff642000 0x0 0x2000>;
+
+                       clkc_audio: clock-controller@0 {
+                               compatible = "amlogic,axg-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,axg-toddr";
+                               reg = <0x0 0x100 0x0 0x1c>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "TODDR_A";
+                               interrupts = <GIC_SPI 84 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,axg-toddr";
+                               reg = <0x0 0x140 0x0 0x1c>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "TODDR_B";
+                               interrupts = <GIC_SPI 85 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,axg-toddr";
+                               reg = <0x0 0x180 0x0 0x1c>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "TODDR_C";
+                               interrupts = <GIC_SPI 86 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,axg-frddr";
+                               reg = <0x0 0x1c0 0x0 0x1c>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "FRDDR_A";
+                               interrupts = <GIC_SPI 88 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,axg-frddr";
+                               reg = <0x0 0x200 0x0 0x1c>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "FRDDR_B";
+                               interrupts = <GIC_SPI 89 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,axg-frddr";
+                               reg = <0x0 0x240 0x0 0x1c>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "FRDDR_C";
+                               interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
+                               resets = <&arb AXG_ARB_FRDDR_C>;
+                               status = "disabled";
+                       };
+
+                       arb: reset-controller@280 {
+                               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,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,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,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,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";
+                       };
+
+                       spdifout: audio-controller@480 {
+                               compatible = "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,axg-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,axg-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";
                        };
 
-                       cpu_scp_hpri: scp-shmem@200 {
-                               compatible = "amlogic,meson-axg-scp-shmem";
-                               reg = <0x13400 0x400>;
+                       tdmout_c: audio-controller@580 {
+                               compatible = "amlogic,axg-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";
                        };
                };
 
                        ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>;
 
                        sysctrl_AO: sys-ctrl@0 {
-                               compatible = "amlogic,meson-axg-ao-sysctrl", "syscon", "simple-mfd";
+                               compatible = "amlogic,meson-axg-ao-sysctrl", "simple-mfd", "syscon";
                                reg =  <0x0 0x0 0x0 0x100>;
 
                                clkc_AO: clock-controller {
 
                                gpio_ao: bank@14 {
                                        reg = <0x0 0x00014 0x0 0x8>,
-                                               <0x0 0x0002c 0x0 0x4>,
-                                               <0x0 0x00024 0x0 0x8>;
+                                             <0x0 0x0002c 0x0 0x4>,
+                                             <0x0 0x00024 0x0 0x8>;
                                        reg-names = "mux", "pull", "gpio";
                                        gpio-controller;
                                        #gpio-cells = <2>;
                                uart_ao_a_pins: uart_ao_a {
                                        mux {
                                                groups = "uart_ao_tx_a",
-                                                       "uart_ao_rx_a";
+                                                        "uart_ao_rx_a";
                                                function = "uart_ao_a";
                                        };
                                };
                                uart_ao_a_cts_rts_pins: uart_ao_a_cts_rts {
                                        mux {
                                                groups = "uart_ao_cts_a",
-                                                       "uart_ao_rts_a";
+                                                        "uart_ao_rts_a";
                                                function = "uart_ao_a";
                                        };
                                };
                                uart_ao_b_pins: uart_ao_b {
                                        mux {
                                                groups = "uart_ao_tx_b",
-                                                       "uart_ao_rx_b";
+                                                        "uart_ao_rx_b";
                                                function = "uart_ao_b";
                                        };
                                };
                                uart_ao_b_cts_rts_pins: uart_ao_b_cts_rts {
                                        mux {
                                                groups = "uart_ao_cts_b",
-                                                       "uart_ao_rts_b";
+                                                        "uart_ao_rts_b";
                                                function = "uart_ao_b";
                                        };
                                };
                                amlogic,has-chip-id;
                        };
 
-                       pwm_AO_ab: pwm@7000 {
-                               compatible = "amlogic,meson-axg-ao-pwm";
-                               reg = <0x0 0x07000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
                        pwm_AO_cd: pwm@2000 {
                                compatible = "amlogic,meson-axg-ao-pwm";
                                reg = <0x0 0x02000  0x0 0x20>;
                                status = "disabled";
                        };
 
-                       i2c_AO: i2c@5000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               reg = <0x0 0x05000 0x0 0x20>;
-                               interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc CLKID_AO_I2C>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               status = "disabled";
-                       };
-
                        uart_AO: serial@3000 {
                                compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
                                reg = <0x0 0x3000 0x0 0x18>;
                                status = "disabled";
                        };
 
+                       i2c_AO: i2c@5000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               reg = <0x0 0x05000 0x0 0x20>;
+                               interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_AO_I2C>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       pwm_AO_ab: pwm@7000 {
+                               compatible = "amlogic,meson-axg-ao-pwm";
+                               reg = <0x0 0x07000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
                        ir: ir@8000 {
                                compatible = "amlogic,meson-gxbb-ir";
                                reg = <0x0 0x8000 0x0 0x20>;
                                #io-channel-cells = <1>;
                                interrupts = <GIC_SPI 73 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>;
+                                        <&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";
                        };
                };
+
+               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 0x25000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x25000>;
+
+                       reset: reset-controller@1004 {
+                               compatible = "amlogic,meson-axg-reset";
+                               reg = <0x0 0x01004 0x0 0x9c>;
+                               #reset-cells = <1>;
+                       };
+
+                       gpio_intc: interrupt-controller@f080 {
+                               compatible = "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>;
+                               status = "disabled";
+                       };
+
+                       pwm_ab: pwm@1b000 {
+                               compatible = "amlogic,meson-axg-ee-pwm";
+                               reg = <0x0 0x1b000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       pwm_cd: pwm@1a000 {
+                               compatible = "amlogic,meson-axg-ee-pwm";
+                               reg = <0x0 0x1a000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       spicc0: spi@13000 {
+                               compatible = "amlogic,meson-axg-spicc";
+                               reg = <0x0 0x13000 0x0 0x3c>;
+                               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clkc CLKID_SPICC0>;
+                               clock-names = "core";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spicc1: spi@15000 {
+                               compatible = "amlogic,meson-axg-spicc";
+                               reg = <0x0 0x15000 0x0 0x3c>;
+                               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clkc CLKID_SPICC1>;
+                               clock-names = "core";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@1c000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               reg = <0x0 0x1c000 0x0 0x20>;
+                               interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_I2C>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@1d000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               reg = <0x0 0x1d000 0x0 0x20>;
+                               interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_I2C>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@1e000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               reg = <0x0 0x1e000 0x0 0x20>;
+                               interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_I2C>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c0: i2c@1f000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               reg = <0x0 0x1f000 0x0 0x20>;
+                               interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc CLKID_I2C>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart_B: serial@23000 {
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x23000 0x0 0x18>;
+                               interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
+                               status = "disabled";
+                               clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                       };
+
+                       uart_A: serial@24000 {
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x24000 0x0 0x18>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+                               status = "disabled";
+                               clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                       };
+               };
+
+               apb: bus@ffe00000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xffe00000 0x0 0x200000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x200000>;
+
+                       sd_emmc_b: sd@5000 {
+                               compatible = "amlogic,meson-axg-mmc";
+                               reg = <0x0 0x5000 0x0 0x800>;
+                               interrupts = <GIC_SPI 217 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@7000 {
+                               compatible = "amlogic,meson-axg-mmc";
+                               reg = <0x0 0x7000 0x0 0x800>;
+                               interrupts = <GIC_SPI 218 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>;
+                       };
+               };
+
+               sram: sram@fffc0000 {
+                       compatible = "amlogic,meson-axg-sram", "mmio-sram";
+                       reg = <0x0 0xfffc0000 0x0 0x20000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x0 0xfffc0000 0x20000>;
+
+                       cpu_scp_lpri: scp-shmem@0 {
+                               compatible = "amlogic,meson-axg-scp-shmem";
+                               reg = <0x13000 0x400>;
+                       };
+
+                       cpu_scp_hpri: scp-shmem@200 {
+                               compatible = "amlogic,meson-axg-scp-shmem";
+                               reg = <0x13400 0x400>;
+                       };
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       xtal: xtal-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xtal";
+               #clock-cells = <0>;
        };
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
new file mode 100644 (file)
index 0000000..c44dbdd
--- /dev/null
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-g12a.dtsi"
+
+/ {
+       compatible = "amlogic,u200", "amlogic,g12a";
+       model = "Amlogic Meson G12A U200 Development Board";
+
+       aliases {
+               serial0 = &uart_AO;
+       };
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>;
+       };
+};
+
+&uart_AO {
+       status = "okay";
+};
+
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
new file mode 100644 (file)
index 0000000..3b82a97
--- /dev/null
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "amlogic,g12a";
+
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       cpus {
+               #address-cells = <0x2>;
+               #size-cells = <0x0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               l2: l2-cache0 {
+                       compatible = "cache";
+               };
+       };
+
+       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;
+               };
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               periphs: periphs@ff634000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff634000 0x0 0x2000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
+               };
+
+               hiubus: bus@ff63c000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff63c000 0x0 0x1c00>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff63c000 0x0 0x1c00>;
+               };
+
+               aobus: bus@ff800000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff800000 0x0 0x100000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>;
+
+                       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>, <&xtal>, <&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>, <&xtal>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+               };
+
+               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 0x25000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x25000>;
+               };
+
+               apb: apb@ffe00000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xffe00000 0x0 0x200000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x200000>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10
+                       (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       xtal: xtal-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xtal";
+               #clock-cells = <0>;
+       };
+
+};
index b8dc4dbb391b669fc13eb13b1a24f01d24ab252f..f1e5cdbade5edf281ecc9ea183c5e5b763c0f726 100644 (file)
@@ -44,7 +44,7 @@
                linux,cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0xbc00000>;
+                       size = <0x0 0x10000000>;
                        alignment = <0x0 0x400000>;
                        linux,cma-default;
                };
                        ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
 
                        sysctrl_AO: sys-ctrl@0 {
-                               compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd";
+                               compatible = "amlogic,meson-gx-ao-sysctrl", "simple-mfd", "syscon";
                                reg =  <0x0 0x0 0x0 0x100>;
 
                                pwrc_vpu: power-controller-vpu {
                        };
                };
 
+               dmcbus: bus@c8838000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xc8838000 0x0 0x400>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xc8838000 0x0 0x400>;
+
+                       canvas: video-lut@48 {
+                               compatible = "amlogic,canvas";
+                               reg = <0x0 0x48 0x0 0x14>;
+                       };
+               };
+
                hiubus: bus@c883c000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xc883c000 0x0 0x2000>;
                        ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
 
                        sysctrl: system-controller@0 {
-                               compatible = "amlogic,meson-gx-hhi-sysctrl", "syscon", "simple-mfd";
+                               compatible = "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon";
                                reg = <0 0 0 0x400>;
                        };
 
index 98cbba6809caa17e2fa4f6b630bf8b02e26f32ab..1ade7e486828c2db082a121e856456e5562d3445 100644 (file)
                        };
                };
 
-               spi_pins: spi {
+               spi_pins: spi-pins {
                        mux {
                                groups = "spi_miso",
                                        "spi_mosi",
index f63bceb88caafa249d84de963c3daa034fb842b7..90a56af967a7f11f24e7351da99e168abd0f1085 100644 (file)
@@ -13,7 +13,7 @@
 
 / {
        compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl";
-       model = "Libre Technology CC";
+       model = "Libre Computer Board AML-S905X-CC";
 
        aliases {
                serial0 = &uart_AO;
index c87a80e9bcc6a80bc0f8a59c43a32d6485facafe..8f0bb3c44bd6d05a11e6dea2ed390f0c88bdc9cc 100644 (file)
                        };
                };
 
-               spi_pins: spi {
+               spi_pins: spi-pins {
                        mux {
                                groups = "spi_miso",
                                        "spi_mosi",
index ce56a4acda4fa07bb7eedebfeeb55f05f29c0c8d..ed774ee8f65948d40d925379dc1a900200e1412d 100644 (file)
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
 
-                       /* input port */
-                       port@0 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                etf0_in_port: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&main_funnel_out_port>;
                                };
                        };
+               };
 
-                       /* output port */
-                       port@1 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                etf0_out_port: endpoint {
                                };
                        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       tpiu_in_port: endpoint {
-                               slave-mode;
-                               remote-endpoint = <&replicator_out_port0>;
+               in-ports {
+                       port {
+                               tpiu_in_port: endpoint {
+                                       remote-endpoint = <&replicator_out_port0>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
 
-                       /* output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                main_funnel_out_port: endpoint {
                                        remote-endpoint = <&etf0_in_port>;
                                };
                        };
+               };
 
-                       /* input ports */
-                       port@1 {
+               main_funnel_in_ports: in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                main_funnel_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster0_funnel_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                main_funnel_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster1_funnel_out_port>;
                                };
                        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       etr_in_port: endpoint {
-                               slave-mode;
-                               remote-endpoint = <&replicator_out_port1>;
+               arm,scatter-gather;
+               in-ports {
+                       port {
+                               etr_in_port: endpoint {
+                                       remote-endpoint = <&replicator_out_port1>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       stm_out_port: endpoint {
+               out-ports {
+                       port {
+                               stm_out_port: endpoint {
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       cluster0_etm0_out_port: endpoint {
-                               remote-endpoint = <&cluster0_funnel_in_port0>;
+               out-ports {
+                       port {
+                               cluster0_etm0_out_port: endpoint {
+                                       remote-endpoint = <&cluster0_funnel_in_port0>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                cluster0_funnel_out_port: endpoint {
                                        remote-endpoint = <&main_funnel_in_port0>;
                                };
                        };
+               };
 
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                cluster0_funnel_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster0_etm0_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                cluster0_funnel_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster0_etm1_out_port>;
                                };
                        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       cluster0_etm1_out_port: endpoint {
-                               remote-endpoint = <&cluster0_funnel_in_port1>;
+               out-ports {
+                       port {
+                               cluster0_etm1_out_port: endpoint {
+                                       remote-endpoint = <&cluster0_funnel_in_port1>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       cluster1_etm0_out_port: endpoint {
-                               remote-endpoint = <&cluster1_funnel_in_port0>;
+               out-ports {
+                       port {
+                               cluster1_etm0_out_port: endpoint {
+                                       remote-endpoint = <&cluster1_funnel_in_port0>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                cluster1_funnel_out_port: endpoint {
                                        remote-endpoint = <&main_funnel_in_port1>;
                                };
                        };
+               };
 
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
                                reg = <0>;
                                cluster1_funnel_in_port0: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster1_etm0_out_port>;
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                cluster1_funnel_in_port1: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster1_etm1_out_port>;
                                };
                        };
-                       port@3 {
+                       port@2 {
                                reg = <2>;
                                cluster1_funnel_in_port2: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster1_etm2_out_port>;
                                };
                        };
-                       port@4 {
+                       port@3 {
                                reg = <3>;
                                cluster1_funnel_in_port3: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&cluster1_etm3_out_port>;
                                };
                        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       cluster1_etm1_out_port: endpoint {
-                               remote-endpoint = <&cluster1_funnel_in_port1>;
+               out-ports {
+                       port {
+                               cluster1_etm1_out_port: endpoint {
+                                       remote-endpoint = <&cluster1_funnel_in_port1>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       cluster1_etm2_out_port: endpoint {
-                               remote-endpoint = <&cluster1_funnel_in_port2>;
+               out-ports {
+                       port {
+                               cluster1_etm2_out_port: endpoint {
+                                       remote-endpoint = <&cluster1_funnel_in_port2>;
+                               };
                        };
                };
        };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               port {
-                       cluster1_etm3_out_port: endpoint {
-                               remote-endpoint = <&cluster1_funnel_in_port3>;
+               out-ports {
+                       port {
+                               cluster1_etm3_out_port: endpoint {
+                                       remote-endpoint = <&cluster1_funnel_in_port3>;
+                               };
                        };
                };
        };
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
 
-               ports {
+               out-ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
                                        remote-endpoint = <&etr_in_port>;
                                };
                        };
-
-                       /* replicator input port */
-                       port@2 {
-                               reg = <0>;
+               };
+               in-ports {
+                       port {
                                replicator_in_port0: endpoint {
-                                       slave-mode;
                                };
                        };
                };
index 0c43fb3525eb1db2d9886e56eea474f2951562bf..cf285152deab7fb39d20698e803cdfe94e0d974f 100644 (file)
@@ -7,23 +7,16 @@
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                csys1_funnel_out_port: endpoint {
                                        remote-endpoint = <&etf1_in_port>;
                                };
                        };
-
-                       /* input port */
-                       port@1 {
-                               reg = <0>;
+               };
+               in-ports {
+                       port {
                                csys1_funnel_in_port0: endpoint {
-                                       slave-mode;
                                };
                        };
 
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* input port */
-                       port@0 {
-                               reg = <0>;
+               in-ports {
+                       port {
                                etf1_in_port: endpoint {
-                                       slave-mode;
                                        remote-endpoint = <&csys1_funnel_out_port>;
                                };
                        };
-
-                       /* output port */
-                       port@1 {
-                               reg = <0>;
+               };
+               out-ports {
+                       port {
                                etf1_out_port: endpoint {
                                        remote-endpoint = <&csys2_funnel_in_port1>;
                                };
                clocks = <&soc_smc50mhz>;
                clock-names = "apb_pclk";
                power-domains = <&scpi_devpd 0>;
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       /* output port */
-                       port@0 {
-                               reg = <0>;
+               out-ports {
+                       port {
                                csys2_funnel_out_port: endpoint {
                                        remote-endpoint = <&replicator_in_port0>;
                                };
                        };
+               };
 
-                       /* input ports */
-                       port@1 {
+               in-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       port@0 {
                                reg = <0>;
                                csys2_funnel_in_port0: endpoint {
                                        slave-mode;
@@ -88,7 +72,7 @@
                                };
                        };
 
-                       port@2 {
+                       port@1 {
                                reg = <1>;
                                csys2_funnel_in_port1: endpoint {
                                        slave-mode;
index 1fb5c5a0f32e38876e25561d39548dfe700dde34..08d4ba1716c3e54e043bf63d51dc0cba1259d54e 100644 (file)
        remote-endpoint = <&main_funnel_in_port2>;
 };
 
-&main_funnel {
-       ports {
-               port@3 {
-                       reg = <2>;
-                       main_funnel_in_port2: endpoint {
-                               slave-mode;
-                               remote-endpoint = <&stm_out_port>;
-                       };
+&main_funnel_in_ports {
+       port@2 {
+               reg = <2>;
+               main_funnel_in_port2: endpoint {
+                       remote-endpoint = <&stm_out_port>;
                };
        };
 };
index 1193a9e34bbb16aaea9cf0e684dc7601af45a10a..667ca989c11b262bc0f8783d373dc5c9eda202fa 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \
-                             bcm2837-rpi-3-b-plus.dtb
+                             bcm2837-rpi-3-b-plus.dtb \
+                             bcm2837-rpi-cm3-io3.dtb
 
 subdir-y       += northstar2
 subdir-y       += stingray
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
new file mode 100644 (file)
index 0000000..b1c4ab2
--- /dev/null
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "arm/bcm2837-rpi-cm3-io3.dts"
index 1a406a76c86a2ae7ae465c192b08739009e9d891..ea854f689fda89fe8c19526ce99c7724e41c0bd5 100644 (file)
                        status = "disabled";
                };
 
-               ssp0: ssp@66180000 {
+               ssp0: spi@66180000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x66180000 0x1000>;
                        interrupts = <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
-               ssp1: ssp@66190000 {
+               ssp1: spi@66190000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x66190000 0x1000>;
                        interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
index bc299c3d90683b02e168b9c06cbfd0b26c66ee2f..a9b92e52d50e8a1d4175ece1de5dc2050c34eea6 100644 (file)
 &i2c1 {
        status = "okay";
 
-       pcf8574: pcf8574@20 {
+       pcf8574: pcf8574@27 {
                compatible = "nxp,pcf8574a";
                gpio-controller;
                #gpio-cells = <2>;
index e283480bfc7e5d50701b7d62bde1b9b3e53ee5a5..cfeaa855bd05a189c348e8a1941dd8c9c7ad1ba7 100644 (file)
                        status = "disabled";
                };
 
-               ssp0: ssp@180000 {
+               ssp0: spi@180000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x00180000 0x1000>;
                        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
-               ssp1: ssp@190000 {
+               ssp1: spi@190000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x00190000 0x1000>;
                        interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
index a1e3194b74837721b3f6c641f43b67163b60364c..f3ed4c078ba59d37ca41638e6db0387461fcdfa2 100644 (file)
                                        };
                                };
                        };
+
+                       ports {
+                               port {
+                                       muic_to_usb: endpoint {
+                                               remote-endpoint = <&usb_to_muic>;
+                                       };
+                               };
+                       };
                };
 
                regulators {
        status = "okay";
        cap-sd-highspeed;
        disable-wp;
-       cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
-       cd-inverted;
+       cd-gpios = <&gpa2 4 GPIO_ACTIVE_LOW>;
        card-detect-delay = <200>;
        samsung,dw-mshc-ciu-div = <3>;
        samsung,dw-mshc-sdr-timing = <0 4>;
 
 &usbdrd_dwc3 {
        dr_mode = "otg";
-       extcon = <&muic>;
 };
 
 &usbdrd30_phy {
        vbus-supply = <&safeout1_reg>;
        status = "okay";
+
+       port {
+               usb_to_muic: endpoint {
+                       remote-endpoint = <&muic_to_usb>;
+               };
+       };
 };
 
 &xxti {
index 68ac78c4564dc74cdfd0f40697c1b599bee72add..5da732f82fa0cb0fc844b73bfdd20d347a786628 100644 (file)
                        status = "disabled";
                };
 
-               dspi: dspi@2100000 {
+               dspi: spi@2100000 {
                        compatible = "fsl,ls1012a-dspi", "fsl,ls1021a-v1.0-dspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
index c7b8d2c009cd5a286c26f7f385f9bdf170f3c849..dff3d648172ea245c4363ad0f213e7dbdab96f6c 100644 (file)
@@ -3,6 +3,7 @@
  * Device Tree Include file for Freescale Layerscape-1043A family SoC.
  *
  * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  */
@@ -50,6 +51,7 @@
        nor@0,0 {
                compatible = "cfi-flash";
                reg = <0x0 0x0 0x8000000>;
+               big-endian;
                bank-width = <2>;
                device-width = <1>;
        };
index 7b01ba8d3b7e193ef861fd44d34fb6a30e3bafe6..17ca357e854f2ec0fbb0ca2e4260a5b4591bbbde 100644 (file)
@@ -3,6 +3,7 @@
  * Device Tree Include file for Freescale Layerscape-1043A family SoC.
  *
  * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  */
@@ -65,6 +66,7 @@
                        #address-cells = <1>;
                        #size-cells = <1>;
                        reg = <0x0 0x0 0x8000000>;
+                       big-endian;
                        bank-width = <2>;
                        device-width = <1>;
                };
index 7881e3d81a9aba6134fc66a7d35e6d02daa4009a..3fed504b5381dce21888cf76dc5b1993b2686468 100644 (file)
@@ -3,6 +3,7 @@
  * Device Tree Include file for Freescale Layerscape-1043A family SoC.
  *
  * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
  */
                ifc: ifc@1530000 {
                        compatible = "fsl,ifc", "simple-bus";
                        reg = <0x0 0x1530000 0x0 0x10000>;
-                       big-endian;
                        interrupts = <0 43 0x4>;
                };
 
-               qspi: quadspi@1550000 {
+               qspi: spi@1550000 {
                        compatible = "fsl,ls1043a-qspi", "fsl,ls1021a-qspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        ranges = <0x0 0x5 0x00000000 0x8000000>;
                };
 
-               dspi0: dspi@2100000 {
+               dspi0: spi@2100000 {
                        compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
-               dspi1: dspi@2110000 {
+               dspi1: spi@2110000 {
                        compatible = "fsl,ls1043a-dspi", "fsl,ls1021a-v1.0-dspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
index e69306e6b0b180af5c8f9f69af82abdb6b367e37..e58a8ca1386cb2bcd1740189db33c295997106d6 100644 (file)
@@ -3,6 +3,7 @@
  * Device Tree Include file for Freescale Layerscape-1046A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Shaohui Xie <Shaohui.Xie@nxp.com>
  */
        nor@0,0 {
                compatible = "cfi-flash";
                reg = <0x0 0x0 0x8000000>;
+               big-endian;
                bank-width = <2>;
                device-width = <1>;
        };
index 440e111651d53d9bba85763f0a04cde2796022b3..a59b48203688a47db12732f019255800b9880def 100644 (file)
                reg = <0x4c>;
        };
 
-       eeprom@56 {
+       eeprom@52 {
                compatible = "atmel,24c512";
                reg = <0x52>;
        };
 
-       eeprom@57 {
+       eeprom@53 {
                compatible = "atmel,24c512";
                reg = <0x53>;
        };
index ef83786b8b905d57852ad6637bd2d4dfb5683c43..51cbd50012d625e62a25e9083b826447062ca81c 100644 (file)
@@ -3,6 +3,7 @@
  * Device Tree Include file for Freescale Layerscape-1046A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Mingkai Hu <mingkai.hu@nxp.com>
  */
                ifc: ifc@1530000 {
                        compatible = "fsl,ifc", "simple-bus";
                        reg = <0x0 0x1530000 0x0 0x10000>;
-                       big-endian;
                        interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
                };
 
-               qspi: quadspi@1550000 {
+               qspi: spi@1550000 {
                        compatible = "fsl,ls1021a-qspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        #thermal-sensor-cells = <1>;
                };
 
-               dspi: dspi@2100000 {
+               dspi: spi@2100000 {
                        compatible = "fsl,ls1021a-v1.0-dspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
index 90c0faf8579f0631d8c83b8e2e417fb5cfc58190..d188774a36e89b62178a42719f7868db2c9efe91 100644 (file)
@@ -22,6 +22,8 @@
                crypto = &crypto;
                serial0 = &serial0;
                serial1 = &serial1;
+               serial2 = &serial2;
+               serial3 = &serial3;
        };
 
        cpu: cpus {
                        interrupts = <0 32 0x4>; /* Level high type */
                };
 
+               serial2: serial@21d0500 {
+                       compatible = "fsl,ns16550", "ns16550a";
+                       reg = <0x0 0x21d0500 0x0 0x100>;
+                       clocks = <&clockgen 4 3>;
+                       interrupts = <0 33 0x4>; /* Level high type */
+               };
+
+               serial3: serial@21d0600 {
+                       compatible = "fsl,ns16550", "ns16550a";
+                       reg = <0x0 0x21d0600 0x0 0x100>;
+                       clocks = <&clockgen 4 3>;
+                       interrupts = <0 33 0x4>; /* Level high type */
+               };
+
                cluster1_core0_watchdog: wdt@c000000 {
                        compatible = "arm,sp805-wdt", "arm,primecell";
                        reg = <0x0 0xc000000 0x0 0x1000>;
                                     <0 208 4>, <0 209 4>;
                };
 
-               dspi: dspi@2100000 {
+               dspi: spi@2100000 {
                        status = "disabled";
                        compatible = "fsl,ls2080a-dspi", "fsl,ls2085a-dspi";
                        #address-cells = <1>;
                                  3 0 0x5 0x20000000 0x00010000>;
                };
 
-               qspi: quadspi@20c0000 {
+               qspi: spi@20c0000 {
                        status = "disabled";
                        compatible = "fsl,ls2080a-qspi", "fsl,ls1021a-qspi";
                        #address-cells = <1>;
index 03d93f8ef8a95a76ce9d8677dda1fe3ed17ead1e..f4d68caeba83185fa8a29f64fc3d023b67183f9a 100644 (file)
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_HISI) += hi3660-hikey960.dtb
+dtb-$(CONFIG_ARCH_HISI) += hi3670-hikey970.dtb
 dtb-$(CONFIG_ARCH_HISI) += hi3798cv200-poplar.dtb
 dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
 dtb-$(CONFIG_ARCH_HISI) += hip05-d02.dtb
diff --git a/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts b/arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts
new file mode 100644 (file)
index 0000000..4f51186
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Hisilicon HiKey970 Development Board
+ *
+ * Copyright (C) 2016, Hisilicon Ltd.
+ * Copyright (C) 2018, Linaro Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include "hi3670.dtsi"
+
+/ {
+       model = "HiKey970";
+       compatible = "hisilicon,hi3670-hikey970", "hisilicon,hi3670";
+
+       aliases {
+               serial6 = &uart6;       /* console UART */
+       };
+
+       chosen {
+               stdout-path = "serial6:115200n8";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               /* expect bootloader to fill in this region */
+               reg = <0x0 0x0 0x0 0x0>;
+       };
+};
+
+&uart6 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
new file mode 100644 (file)
index 0000000..c90e6f6
--- /dev/null
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Hisilicon Hi3670 SoC
+ *
+ * Copyright (C) 2016, Hisilicon Ltd.
+ * Copyright (C) 2018, Linaro Ltd.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "hisilicon,hi3670";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       psci {
+               compatible = "arm,psci-0.2";
+               method = "smc";
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+                               core2 {
+                                       cpu = <&cpu2>;
+                               };
+                               core3 {
+                                       cpu = <&cpu3>;
+                               };
+                       };
+                       cluster1 {
+                               core0 {
+                                       cpu = <&cpu4>;
+                               };
+                               core1 {
+                                       cpu = <&cpu5>;
+                               };
+                               core2 {
+                                       cpu = <&cpu6>;
+                               };
+                               core3 {
+                                       cpu = <&cpu7>;
+                               };
+                       };
+               };
+
+               cpu0: cpu@0 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+               };
+
+               cpu1: cpu@1 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+               };
+
+               cpu2: cpu@2 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+               };
+
+               cpu3: cpu@3 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+               };
+
+               cpu4: cpu@100 {
+                       compatible = "arm,cortex-a73", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x100>;
+                       enable-method = "psci";
+               };
+
+               cpu5: cpu@101 {
+                       compatible = "arm,cortex-a73", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x101>;
+                       enable-method = "psci";
+               };
+
+               cpu6: cpu@102 {
+                       compatible = "arm,cortex-a73", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x102>;
+                       enable-method = "psci";
+               };
+
+               cpu7: cpu@103 {
+                       compatible = "arm,cortex-a73", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0 0x103>;
+                       enable-method = "psci";
+               };
+       };
+
+       gic: interrupt-controller@e82b0000 {
+               compatible = "arm,gic-400";
+               reg = <0x0 0xe82b1000 0 0x1000>, /* GICD */
+                     <0x0 0xe82b2000 0 0x2000>, /* GICC */
+                     <0x0 0xe82b4000 0 0x2000>, /* GICH */
+                     <0x0 0xe82b6000 0 0x2000>; /* GICV */
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+                                        IRQ_TYPE_LEVEL_HIGH)>;
+               interrupt-controller;
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
+                                         IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
+                                         IRQ_TYPE_LEVEL_LOW)>;
+               clock-frequency = <1920000>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               uart6_clk: clk_19_2M {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <19200000>;
+               };
+
+               uart6: serial@fff32000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x0 0xfff32000 0x0 0x1000>;
+                       interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&uart6_clk &uart6_clk>;
+                       clock-names = "uartclk", "apb_pclk";
+                       status = "disabled";
+               };
+       };
+};
index 7afee5d5087b077a86766f4b6247abea45d56b0e..68c52f1149be66832c4606fb59d13f871add2e6b 100644 (file)
                        clocks = <&acpu_sctrl HI6220_ACPU_SFT_AT_S>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        soc_funnel_out: endpoint {
                                                remote-endpoint =
                                                        <&etf_in>;
                                        };
                                };
+                       };
 
-                               port@1 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        soc_funnel_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&acpu_funnel_out>;
                                        };
                        clocks = <&acpu_sctrl HI6220_ACPU_SFT_AT_S>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        etf_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&soc_funnel_out>;
                                        };
                                };
+                       };
 
-                               port@1 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        etf_out: endpoint {
                                                remote-endpoint =
                                                        <&replicator_in>;
                        clocks = <&acpu_sctrl HI6220_ACPU_SFT_AT_S>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        replicator_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etf_out>;
                                        };
                                };
+                       };
 
-                               port@1 {
+                       out-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
                                        reg = <0>;
                                        replicator_out0: endpoint {
                                                remote-endpoint =
@@ -98,7 +90,7 @@
                                        };
                                };
 
-                               port@2 {
+                               port@1 {
                                        reg = <1>;
                                        replicator_out1: endpoint {
                                                remote-endpoint =
                        clocks = <&acpu_sctrl HI6220_ACPU_SFT_AT_S>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        etr_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&replicator_out0>;
                                        };
                        clocks = <&acpu_sctrl HI6220_ACPU_SFT_AT_S>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        tpiu_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&replicator_out1>;
                                        };
                        clocks = <&acpu_sctrl HI6220_ACPU_SFT_AT_S>;
                        clock-names = "apb_pclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       out-ports {
+                               port {
                                        acpu_funnel_out: endpoint {
                                                remote-endpoint =
                                                        <&soc_funnel_in>;
                                        };
                                };
+                       };
 
-                               port@1 {
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
                                        reg = <0>;
                                        acpu_funnel_in0: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm0_out>;
                                        };
                                };
 
-                               port@2 {
+                               port@1 {
                                        reg = <1>;
                                        acpu_funnel_in1: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm1_out>;
                                        };
                                };
 
-                               port@3 {
+                               port@2 {
                                        reg = <2>;
                                        acpu_funnel_in2: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm2_out>;
                                        };
                                };
 
-                               port@4 {
+                               port@3 {
                                        reg = <3>;
                                        acpu_funnel_in3: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm3_out>;
                                        };
                                };
 
-                               port@5 {
+                               port@4 {
                                        reg = <4>;
                                        acpu_funnel_in4: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm4_out>;
                                        };
                                };
 
-                               port@6 {
+                               port@5 {
                                        reg = <5>;
                                        acpu_funnel_in5: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm5_out>;
                                        };
                                };
 
-                               port@7 {
+                               port@6 {
                                        reg = <6>;
                                        acpu_funnel_in6: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm6_out>;
                                        };
                                };
 
-                               port@8 {
+                               port@7 {
                                        reg = <7>;
                                        acpu_funnel_in7: endpoint {
-                                               slave-mode;
                                                remote-endpoint =
                                                        <&etm7_out>;
                                        };
 
                        cpu = <&cpu0>;
 
-                       port {
-                               etm0_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in0>;
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in0>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu1>;
 
-                       port {
-                               etm1_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in1>;
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in1>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu2>;
 
-                       port {
-                               etm2_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in2>;
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in2>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu3>;
 
-                       port {
-                               etm3_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in3>;
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in3>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu4>;
 
-                       port {
-                               etm4_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in4>;
+                       out-ports {
+                               port {
+                                       etm4_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in4>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu5>;
 
-                       port {
-                               etm5_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in5>;
+                       out-ports {
+                               port {
+                                       etm5_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in5>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu6>;
 
-                       port {
-                               etm6_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in6>;
+                       out-ports {
+                               port {
+                                       etm6_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in6>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&cpu7>;
 
-                       port {
-                               etm7_out: endpoint {
-                                       remote-endpoint =
-                                               <&acpu_funnel_in7>;
+                       out-ports {
+                               port {
+                                       etm7_out: endpoint {
+                                               remote-endpoint =
+                                                       <&acpu_funnel_in7>;
+                                       };
                                };
                        };
                };
index 247024df714fce9ab1d85ee4dc73a5bec948f99c..97d5bf2c6ec587273dc11a3bb4ef0683378096d3 100644 (file)
@@ -99,6 +99,7 @@
                        reg = <0x0 0x1>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER0_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
                        reg = <0x0 0x2>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER0_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
                        reg = <0x0 0x3>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER0_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
                        reg = <0x0 0x100>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER1_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
                        reg = <0x0 0x101>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER1_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
                        reg = <0x0 0x102>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER1_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
                        reg = <0x0 0x103>;
                        enable-method = "psci";
                        next-level-cache = <&CLUSTER1_L2>;
+                       clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                        #cooling-cells = <2>; /* min followed by max */
index 860c8fb10795011f6e6f9894f0ad5e8d4e9444d4..4bde7b6f2b113ccd541c68c9e2c0dee6efe5f568 100644 (file)
                        clock-names = "apb_pclk";
                        status="disabled";
                };
-               spi0: ssp@fe800000 {
+               spi0: spi@fe800000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x0 0xfe800000 0x1000>;
                        interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clk_bus>;
                        clock-names = "apb_pclk";
                };
-               spi1: ssp@fe900000 {
+               spi1: spi@fe900000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x0 0xfe900000 0x1000>;
                        interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
index 1887af654a7db96685581b9f6953f8906073da11..16ced1ff1ad36754977dd41c5a1d39c8d8f81866 100644 (file)
                        clock-names = "apb_pclk";
                        status="disabled";
                };
-               spi0: ssp@fe800000 {
+               spi0: spi@fe800000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x0 0xfe800000 0x1000>;
                        interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clk_bus>;
                        clock-names = "apb_pclk";
                };
-               spi1: ssp@fe900000 {
+               spi1: spi@fe900000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x0 0xfe900000 0x1000>;
                        interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
index ea9d49f2a911cc2ad7a4fc278443505e878e39bc..eca8bac6303a111999836102b6037a8f0731d5eb 100644 (file)
@@ -3,6 +3,7 @@
 dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb
+dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-clearfog-gt-8k.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-8080-db.dtb
index 97558a64e2768205c40ca4d31ceb12b902b8de25..6800945a88ad6cda28c218f87d415a06cadf7be0 100644 (file)
@@ -16,7 +16,7 @@
        compatible = "marvell,armada3720", "marvell,armada3710";
 
        cpus {
-               cpu@1 {
+               cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a53","arm,armv8";
                        reg = <0x1>;
index d9531e242eb4c859545dad19d4bbb6c12e1c3a66..4472bcd8f9fbbdd3110dfc7209c26702011e7a67 100644 (file)
@@ -40,7 +40,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0>;
                        /* 32M internal register @ 0xd000_0000 */
                        ranges = <0x0 0x0 0xd0000000 0x2000000>;
 
+                       wdt: watchdog@8300 {
+                               compatible = "marvell,armada-3700-wdt";
+                               reg = <0x8300 0x40>;
+                               marvell,system-controller = <&cpu_misc>;
+                               clocks = <&xtalclk>;
+                       };
+
+                       cpu_misc: system-controller@d000 {
+                               compatible = "marvell,armada-3700-cpu-misc",
+                                            "syscon";
+                               reg = <0xd000 0x1000>;
+                       };
+
                        spi0: spi@10600 {
                                compatible = "marvell,armada-3700-spi";
                                #address-cells = <1>;
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
new file mode 100644 (file)
index 0000000..9473d40
--- /dev/null
@@ -0,0 +1,441 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 SolidRun ltd.
+ * Based on Marvell MACCHIATOBin board
+ *
+ * Device Tree file for SolidRun's ClearFog GT 8K
+ */
+
+#include "armada-8040.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "SolidRun ClearFog GT 8K";
+       compatible = "solidrun,clearfog-gt-8k", "marvell,armada8040",
+                       "marvell,armada-ap806-quad", "marvell,armada-ap806";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@00000000 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
+
+       aliases {
+               ethernet0 = &cp1_eth1;
+               ethernet1 = &cp0_eth0;
+               ethernet2 = &cp1_eth2;
+       };
+
+       v_3_3: regulator-3-3v {
+               compatible = "regulator-fixed";
+               regulator-name = "v_3_3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               status = "okay";
+       };
+
+       v_5v0_usb3_hst_vbus: regulator-usb3-vbus0 {
+               compatible = "regulator-fixed";
+               gpio = <&cp0_gpio2 15 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cp0_xhci_vbus_pins>;
+               regulator-name = "v_5v0_usb3_hst_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               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>;
+               mod-def0-gpio = <&cp0_gpio2 17 GPIO_ACTIVE_LOW>;
+               tx-disable-gpio = <&cp1_gpio1 29 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cp0_sfp_present_pins &cp1_sfp_tx_disable_pins>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&cp0_led0_pins
+                            &cp0_led1_pins>;
+               pinctrl-names = "default";
+               /* No designated function for these LEDs at the moment */
+               led0 {
+                       label = "clearfog-gt-8k:green:led0";
+                       gpios = <&cp0_gpio2 8 GPIO_ACTIVE_LOW>;
+                       default-state = "on";
+               };
+               led1 {
+                       label = "clearfog-gt-8k:green:led1";
+                       gpios = <&cp0_gpio2 9 GPIO_ACTIVE_LOW>;
+                       default-state = "on";
+               };
+       };
+
+       keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&cp0_gpio_reset_pins &cp1_wps_button_pins>;
+               pinctrl-names = "default";
+
+               button_0 {
+                       /* The rear button */
+                       label = "Rear Button";
+                       gpios = <&cp0_gpio2 7 GPIO_ACTIVE_LOW>;
+                       linux,can-disable;
+                       linux,code = <BTN_0>;
+               };
+
+               button_1 {
+                       /* The wps button */
+                       label = "WPS Button";
+                       gpios = <&cp1_gpio1 30 GPIO_ACTIVE_LOW>;
+                       linux,can-disable;
+                       linux,code = <KEY_WPS_BUTTON>;
+               };
+       };
+};
+
+&uart0 {
+       status = "okay";
+       pinctrl-0 = <&uart0_pins>;
+       pinctrl-names = "default";
+};
+
+&ap_sdhci0 {
+       bus-width = <8>;
+       no-1-8-v;
+       no-sd;
+       no-sdio;
+       non-removable;
+       status = "okay";
+       vqmmc-supply = <&v_3_3>;
+};
+
+&cp0_i2c0 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_i2c0_pins>;
+       status = "okay";
+};
+
+&cp0_i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_i2c1_pins>;
+       status = "okay";
+};
+
+&cp0_pinctrl {
+       /*
+        * MPP Bus:
+        * [0-31] = 0xff: Keep default CP0_shared_pins:
+        * [11] CLKOUT_MPP_11 (out)
+        * [23] LINK_RD_IN_CP2CP (in)
+        * [25] CLKOUT_MPP_25 (out)
+        * [29] AVS_FB_IN_CP2CP (in)
+        * [32, 33, 34] pci0/1/2 reset
+        * [35-38] CP0 I2C1 and I2C0
+        * [39] GPIO reset button
+        * [40,41] LED0 and LED1
+        * [43] 1512 phy reset
+        * [47] USB VBUS EN (active low)
+        * [48] FAN PWM
+        * [49] SFP+ present signal
+        * [50] TPM interrupt
+        * [51] WLAN0 disable
+        * [52] WLAN1 disable
+        * [53] LTE disable
+        * [54] NFC reset
+        * [55] Micro SD card detect
+        * [56-61] Micro SD
+        */
+
+       cp0_pci0_reset_pins: pci0-reset-pins {
+               marvell,pins = "mpp32";
+               marvell,function = "gpio";
+       };
+
+       cp0_pci1_reset_pins: pci1-reset-pins {
+               marvell,pins = "mpp33";
+               marvell,function = "gpio";
+       };
+
+       cp0_pci2_reset_pins: pci2-reset-pins {
+               marvell,pins = "mpp34";
+               marvell,function = "gpio";
+       };
+
+       cp0_i2c1_pins: i2c1-pins {
+               marvell,pins = "mpp35", "mpp36";
+               marvell,function = "i2c1";
+       };
+
+       cp0_i2c0_pins: i2c0-pins {
+               marvell,pins = "mpp37", "mpp38";
+               marvell,function = "i2c0";
+       };
+
+       cp0_gpio_reset_pins: gpio-reset-pins {
+               marvell,pins = "mpp39";
+               marvell,function = "gpio";
+       };
+
+       cp0_led0_pins: led0-pins {
+               marvell,pins = "mpp40";
+               marvell,function = "gpio";
+       };
+
+       cp0_led1_pins: led1-pins {
+               marvell,pins = "mpp41";
+               marvell,function = "gpio";
+       };
+
+       cp0_copper_eth_phy_reset: copper-eth-phy-reset {
+               marvell,pins = "mpp43";
+               marvell,function = "gpio";
+       };
+
+       cp0_xhci_vbus_pins: xhci0-vbus-pins {
+               marvell,pins = "mpp47";
+               marvell,function = "gpio";
+       };
+
+       cp0_fan_pwm_pins: fan-pwm-pins {
+               marvell,pins = "mpp48";
+               marvell,function = "gpio";
+       };
+
+       cp0_sfp_present_pins: sfp-present-pins {
+               marvell,pins = "mpp49";
+               marvell,function = "gpio";
+       };
+
+       cp0_tpm_irq_pins: tpm-irq-pins {
+               marvell,pins = "mpp50";
+               marvell,function = "gpio";
+       };
+
+       cp0_sdhci_pins: sdhci-pins {
+               marvell,pins = "mpp55", "mpp56", "mpp57", "mpp58", "mpp59",
+                              "mpp60", "mpp61";
+               marvell,function = "sdio";
+       };
+};
+
+&cp0_pcie0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_pci0_reset_pins>;
+       reset-gpios = <&cp0_gpio2 0 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&cp0_gpio2 {
+       sata_reset {
+               gpio-hog;
+               gpios = <1 GPIO_ACTIVE_HIGH>;
+               output-high;
+       };
+};
+
+&cp0_ethernet {
+       status = "okay";
+};
+
+/* SFP */
+&cp0_eth0 {
+       status = "okay";
+       phy-mode = "10gbase-kr";
+       managed = "in-band-status";
+       phys = <&cp0_comphy2 0>;
+       sfp = <&sfp_cp0_eth0>;
+};
+
+&cp0_sdhci0 {
+       broken-cd;
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp0_sdhci_pins>;
+       status = "okay";
+       vqmmc-supply = <&v_3_3>;
+};
+
+&cp1_pinctrl {
+       /*
+        * MPP Bus:
+        * [0-5] TDM
+        * [6]   VHV Enable
+        * [7]   CP1 SPI0 CSn1 (FXS)
+        * [8]   CP1 SPI0 CSn0 (TPM)
+        * [9.11]CP1 SPI0 MOSI/MISO/CLK
+        * [13]  CP1 SPI1 MISO (TDM and SPI ROM shared)
+        * [14]  CP1 SPI1 CS0n (64Mb SPI ROM)
+        * [15]  CP1 SPI1 MOSI (TDM and SPI ROM shared)
+        * [16]  CP1 SPI1 CLK (TDM and SPI ROM shared)
+        * [24]  Topaz switch reset
+        * [26]  Buzzer
+        * [27]  CP1 SMI MDIO
+        * [28]  CP1 SMI MDC
+        * [29]  CP0 10G SFP TX Disable
+        * [30]  WPS button
+        * [31]  Front panel button
+        */
+
+       cp1_spi1_pins: spi1-pins {
+               marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+               marvell,function = "spi1";
+       };
+
+       cp1_switch_reset_pins: switch-reset-pins {
+               marvell,pins = "mpp24";
+               marvell,function = "gpio";
+       };
+
+       cp1_ge_mdio_pins: ge-mdio-pins {
+               marvell,pins = "mpp27", "mpp28";
+               marvell,function = "ge";
+       };
+
+       cp1_sfp_tx_disable_pins: sfp-tx-disable-pins {
+               marvell,pins = "mpp29";
+               marvell,function = "gpio";
+       };
+
+       cp1_wps_button_pins: wps-button-pins {
+               marvell,pins = "mpp30";
+               marvell,function = "gpio";
+       };
+};
+
+&cp1_sata0 {
+       pinctrl-0 = <&cp0_pci1_reset_pins>;
+       status = "okay";
+};
+
+&cp1_mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp1_ge_mdio_pins>;
+       status = "okay";
+
+       ge_phy: ethernet-phy@0 {
+               /* LED0 - GB link
+                * LED1 - on: link, blink: activity
+                */
+               marvell,reg-init = <3 16 0 0x1017>;
+               reg = <0>;
+       };
+
+       switch0: switch0@4 {
+               compatible = "marvell,mv88e6085";
+               reg = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cp1_switch_reset_pins>;
+               reset-gpios = <&cp1_gpio1 24 GPIO_ACTIVE_LOW>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@1 {
+                               reg = <1>;
+                               label = "lan2";
+                               phy-handle = <&switch0phy0>;
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan1";
+                               phy-handle = <&switch0phy1>;
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan4";
+                               phy-handle = <&switch0phy2>;
+                       };
+
+                       port@4 {
+                               reg = <4>;
+                               label = "lan3";
+                               phy-handle = <&switch0phy3>;
+                       };
+
+                       port@5 {
+                               reg = <5>;
+                               label = "cpu";
+                               ethernet = <&cp1_eth2>;
+                       };
+               };
+
+               mdio {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch0phy0: switch0phy0@11 {
+                               reg = <0x11>;
+                       };
+
+                       switch0phy1: switch0phy1@12 {
+                               reg = <0x12>;
+                       };
+
+                       switch0phy2: switch0phy2@13 {
+                               reg = <0x13>;
+                       };
+
+                       switch0phy3: switch0phy3@14 {
+                               reg = <0x14>;
+                       };
+               };
+       };
+};
+
+&cp1_ethernet {
+       status = "okay";
+};
+
+/* 1G copper */
+&cp1_eth1 {
+       status = "okay";
+       phy-mode = "sgmii";
+       phy = <&ge_phy>;
+       phys = <&cp1_comphy3 1>;
+};
+
+/* Switch uplink */
+&cp1_eth2 {
+       status = "okay";
+       phy-mode = "2500base-x";
+       phys = <&cp1_comphy5 2>;
+       fixed-link {
+               speed = <2500>;
+               full-duplex;
+       };
+};
+
+&cp1_spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&cp1_spi1_pins>;
+       status = "okay";
+
+       spi-flash@0 {
+               compatible = "st,w25q32";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+       };
+};
+
+&cp1_usb3_0 {
+       usb-phy = <&usb3h0_phy>;
+       status = "okay";
+};
index 64b5e61a698e48a852b121b24a65e616050006f1..d3c0636558ff63bd7ceae94e836714eac18db902 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x000>;
                        enable-method = "psci";
                };
-               cpu@1 {
+               cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x001>;
index 746e792767f5f4855b60551ff6ae8224b000dd46..64632c8738887804df7a81d5f2b5715280bfffb6 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x000>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
-               cpu@1 {
+               cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x001>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
-               cpu@100 {
+               cpu2: cpu@100 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x100>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
-               cpu@101 {
+               cpu3: cpu@101 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x101>;
                        enable-method = "psci";
+                       cpu-idle-states = <&CPU_SLEEP_0>;
                };
        };
 };
index 176e38d548727ddbac73e0c88a6ba01f6ace1e37..073610ac0a53e8dcd1786b4b8c8c59b7b955ef50 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
 
 /dts-v1/;
 
                method = "smc";
        };
 
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               idle_states {
+                       entry_method = "arm,pcsi";
+
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <80>;
+                               exit-latency-us  = <160>;
+                               min-residency-us = <320>;
+                       };
+
+                       CLUSTER_SLEEP_0: cluster-sleep-0 {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x1010000>;
+                               entry-latency-us = <500>;
+                               exit-latency-us = <1000>;
+                               min-residency-us = <2500>;
+                       };
+               };
+       };
+
        ap806 {
                #address-cells = <2>;
                #size-cells = <2>;
                                interrupts = <GIC_PPI 15 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
+                       sei: interrupt-controller@3f0200 {
+                               compatible = "marvell,ap806-sei";
+                               reg = <0x3f0200 0x40>;
+                               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                               msi-controller;
+                       };
+
                        xor@400000 {
                                compatible = "marvell,armada-7k-xor", "marvell,xor-v2";
                                reg = <0x400000 0x1000>,
                                };
                        };
 
-                       ap_thermal: thermal@6f808c {
-                               compatible = "marvell,armada-ap806-thermal";
-                               reg = <0x6f808c 0x4>,
-                                     <0x6f8084 0x8>;
+                       ap_syscon1: system-controller@6f8000 {
+                               compatible = "syscon", "simple-mfd";
+                               reg = <0x6f8000 0x1000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               ap_thermal: thermal-sensor@80 {
+                                       compatible = "marvell,armada-ap806-thermal";
+                                       reg = <0x80 0x10>;
+                                       #thermal-sensor-cells = <1>;
+                               };
                        };
                };
        };
+
+       /*
+        * The thermal IP features one internal sensor plus, if applicable, one
+        * remote channel wired to one sensor per CPU.
+        *
+        * The cooling maps are always empty as there are no cooling devices.
+        */
+       thermal-zones {
+               ap_thermal_ic: ap-thermal-ic {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 0>;
+
+                       trips { };
+                       cooling-maps { };
+               };
+
+               ap_thermal_cpu1: ap-thermal-cpu1 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 1>;
+
+                       trips { };
+                       cooling-maps { };
+               };
+
+               ap_thermal_cpu2: ap-thermal-cpu2 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 2>;
+
+                       trips { };
+                       cooling-maps { };
+               };
+
+               ap_thermal_cpu3: ap-thermal-cpu3 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 3>;
+
+                       trips { };
+                       cooling-maps { };
+               };
+
+               ap_thermal_cpu4: ap-thermal-cpu4 {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&ap_thermal 4>;
+
+                       trips { };
+                       cooling-maps { };
+               };
+       };
 };
index 7d00ae78fc7961407cdadaa43e94fc2987746406..b788cb63caf2f925e4e59206799629e5548fb1a9 100644 (file)
                #size-cells = <0>;
                compatible = "marvell,armada-ap810-octa";
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x000>;
                        enable-method = "psci";
                };
-               cpu@1 {
+               cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x001>;
                        enable-method = "psci";
                };
-               cpu@100 {
+               cpu2: cpu@100 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x100>;
                        enable-method = "psci";
                };
-               cpu@101 {
+               cpu3: cpu@101 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x101>;
                        enable-method = "psci";
                };
-               cpu@200 {
+               cpu4: cpu@200 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x200>;
                        enable-method = "psci";
                };
-               cpu@201 {
+               cpu5: cpu@201 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x201>;
                        enable-method = "psci";
                };
-               cpu@300 {
+               cpu6: cpu@300 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x300>;
                        enable-method = "psci";
                };
-               cpu@301 {
+               cpu7: cpu@301 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x301>;
index d5e8aedec18878886ce8c069779573cc87ef772c..b29c6405d214b672b338fc21e8bd5bfeaf291b7d 100644 (file)
@@ -7,4 +7,5 @@
 #define PASTER(x, y) x ## y
 #define EVALUATOR(x, y) PASTER(x, y)
 #define CP110_LABEL(name) EVALUATOR(CP110_NAME, EVALUATOR(_, name))
+#define CP110_NODE_NAME(name) EVALUATOR(CP110_NAME, EVALUATOR(-, name))
 #define ADDRESSIFY(addr) EVALUATOR(0x, addr)
index 840c8454d03e3e81770a718e8e6aa17f53298ec6..b9d9f31e3ba1ff9a9fd81f89a75fde4a3d237e27 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 #include "armada-common.dtsi"
 
         * save one indentation level
         */
        CP110_NAME: CP110_NAME { };
+
+       /*
+        * CPs only have one sensor in the thermal IC.
+        *
+        * The cooling maps are empty as there are no cooling devices.
+        */
+       thermal-zones {
+               CP110_LABEL(thermal_ic): CP110_NODE_NAME(thermal-ic) {
+                       polling-delay-passive = <1000>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&CP110_LABEL(thermal) 0>;
+
+                       trips { };
+                       cooling-maps { };
+               };
+       };
 };
 
 &CP110_NAME {
        #address-cells = <2>;
        #size-cells = <2>;
        compatible = "simple-bus";
-       interrupt-parent = <&CP110_LABEL(icu)>;
+       interrupt-parent = <&CP110_LABEL(icu_nsr)>;
        ranges;
 
        config-space@CP110_BASE {
                        dma-coherent;
 
                        CP110_LABEL(eth0): eth0 {
-                               interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 43 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 47 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 51 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 55 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 129 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
-                                       "tx-cpu3", "rx-shared", "link";
+                               interrupts = <39 IRQ_TYPE_LEVEL_HIGH>,
+                                       <43 IRQ_TYPE_LEVEL_HIGH>,
+                                       <47 IRQ_TYPE_LEVEL_HIGH>,
+                                       <51 IRQ_TYPE_LEVEL_HIGH>,
+                                       <55 IRQ_TYPE_LEVEL_HIGH>,
+                                       <59 IRQ_TYPE_LEVEL_HIGH>,
+                                       <63 IRQ_TYPE_LEVEL_HIGH>,
+                                       <67 IRQ_TYPE_LEVEL_HIGH>,
+                                       <71 IRQ_TYPE_LEVEL_HIGH>,
+                                       <129 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "hif0", "hif1", "hif2",
+                                       "hif3", "hif4", "hif5", "hif6", "hif7",
+                                       "hif8", "link";
                                port-id = <0>;
                                gop-port-id = <0>;
                                status = "disabled";
                        };
 
                        CP110_LABEL(eth1): eth1 {
-                               interrupts = <ICU_GRP_NSR 40 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 44 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 48 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 52 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 56 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 128 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
-                                       "tx-cpu3", "rx-shared", "link";
+                               interrupts = <40 IRQ_TYPE_LEVEL_HIGH>,
+                                       <44 IRQ_TYPE_LEVEL_HIGH>,
+                                       <48 IRQ_TYPE_LEVEL_HIGH>,
+                                       <52 IRQ_TYPE_LEVEL_HIGH>,
+                                       <56 IRQ_TYPE_LEVEL_HIGH>,
+                                       <60 IRQ_TYPE_LEVEL_HIGH>,
+                                       <64 IRQ_TYPE_LEVEL_HIGH>,
+                                       <68 IRQ_TYPE_LEVEL_HIGH>,
+                                       <72 IRQ_TYPE_LEVEL_HIGH>,
+                                       <128 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "hif0", "hif1", "hif2",
+                                       "hif3", "hif4", "hif5", "hif6", "hif7",
+                                       "hif8", "link";
                                port-id = <1>;
                                gop-port-id = <2>;
                                status = "disabled";
                        };
 
                        CP110_LABEL(eth2): eth2 {
-                               interrupts = <ICU_GRP_NSR 41 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 45 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 49 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 53 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 57 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 127 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
-                                       "tx-cpu3", "rx-shared", "link";
+                               interrupts = <41 IRQ_TYPE_LEVEL_HIGH>,
+                                       <45 IRQ_TYPE_LEVEL_HIGH>,
+                                       <49 IRQ_TYPE_LEVEL_HIGH>,
+                                       <53 IRQ_TYPE_LEVEL_HIGH>,
+                                       <57 IRQ_TYPE_LEVEL_HIGH>,
+                                       <61 IRQ_TYPE_LEVEL_HIGH>,
+                                       <65 IRQ_TYPE_LEVEL_HIGH>,
+                                       <69 IRQ_TYPE_LEVEL_HIGH>,
+                                       <73 IRQ_TYPE_LEVEL_HIGH>,
+                                       <127 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "hif0", "hif1", "hif2",
+                                       "hif3", "hif4", "hif5", "hif6", "hif7",
+                                       "hif8", "link";
                                port-id = <2>;
                                gop-port-id = <3>;
                                status = "disabled";
                CP110_LABEL(icu): interrupt-controller@1e0000 {
                        compatible = "marvell,cp110-icu";
                        reg = <0x1e0000 0x440>;
-                       #interrupt-cells = <3>;
-                       interrupt-controller;
-                       msi-parent = <&gicp>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       CP110_LABEL(icu_nsr): interrupt-controller@10 {
+                               compatible = "marvell,cp110-icu-nsr";
+                               reg = <0x10 0x20>;
+                               #interrupt-cells = <2>;
+                               interrupt-controller;
+                               msi-parent = <&gicp>;
+                       };
+
+                       CP110_LABEL(icu_sei): interrupt-controller@50 {
+                               compatible = "marvell,cp110-icu-sei";
+                               reg = <0x50 0x10>;
+                               #interrupt-cells = <2>;
+                               interrupt-controller;
+                               msi-parent = <&sei>;
+                       };
                };
 
                CP110_LABEL(rtc): rtc@284000 {
                        compatible = "marvell,armada-8k-rtc";
                        reg = <0x284000 0x20>, <0x284080 0x24>;
                        reg-names = "rtc", "rtc-soc";
-                       interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
-               };
-
-               CP110_LABEL(thermal): thermal@400078 {
-                       compatible = "marvell,armada-cp110-thermal";
-                       reg = <0x400078 0x4>,
-                       <0x400070 0x8>;
+                       interrupts = <77 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                CP110_LABEL(syscon0): system-controller@440000 {
                                #gpio-cells = <2>;
                                gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>;
                                interrupt-controller;
-                               interrupts = <ICU_GRP_NSR 86 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 85 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 84 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 83 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <86 IRQ_TYPE_LEVEL_HIGH>,
+                                       <85 IRQ_TYPE_LEVEL_HIGH>,
+                                       <84 IRQ_TYPE_LEVEL_HIGH>,
+                                       <83 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
                        };
 
                                #gpio-cells = <2>;
                                gpio-ranges = <&CP110_LABEL(pinctrl) 0 32 31>;
                                interrupt-controller;
-                               interrupts = <ICU_GRP_NSR 82 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 81 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 80 IRQ_TYPE_LEVEL_HIGH>,
-                                       <ICU_GRP_NSR 79 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <82 IRQ_TYPE_LEVEL_HIGH>,
+                                       <81 IRQ_TYPE_LEVEL_HIGH>,
+                                       <80 IRQ_TYPE_LEVEL_HIGH>,
+                                       <79 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
                        };
                };
 
+               CP110_LABEL(syscon1): system-controller@400000 {
+                       compatible = "syscon", "simple-mfd";
+                       reg = <0x400000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       CP110_LABEL(thermal): thermal-sensor@70 {
+                               compatible = "marvell,armada-cp110-thermal";
+                               reg = <0x70 0x10>;
+                               #thermal-sensor-cells = <1>;
+                       };
+               };
+
                CP110_LABEL(usb3_0): usb3@500000 {
                        compatible = "marvell,armada-8k-xhci",
                        "generic-xhci";
                        reg = <0x500000 0x4000>;
                        dma-coherent;
-                       interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <106 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "reg";
                        clocks = <&CP110_LABEL(clk) 1 22>,
                                 <&CP110_LABEL(clk) 1 16>;
                        "generic-xhci";
                        reg = <0x510000 0x4000>;
                        dma-coherent;
-                       interrupts = <ICU_GRP_NSR 105 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <105 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "reg";
                        clocks = <&CP110_LABEL(clk) 1 23>,
                                 <&CP110_LABEL(clk) 1 16>;
                        "generic-ahci";
                        reg = <0x540000 0x30000>;
                        dma-coherent;
-                       interrupts = <ICU_GRP_NSR 107 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&CP110_LABEL(clk) 1 15>,
                                 <&CP110_LABEL(clk) 1 16>;
                        status = "disabled";
                        reg = <0x701000 0x20>;
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       interrupts = <ICU_GRP_NSR 120 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "reg";
                        clocks = <&CP110_LABEL(clk) 1 21>,
                                 <&CP110_LABEL(clk) 1 17>;
                        reg = <0x701100 0x20>;
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       interrupts = <ICU_GRP_NSR 121 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "reg";
                        clocks = <&CP110_LABEL(clk) 1 21>,
                                 <&CP110_LABEL(clk) 1 17>;
                        compatible = "snps,dw-apb-uart";
                        reg = <0x702000 0x100>;
                        reg-shift = <2>;
-                       interrupts = <ICU_GRP_NSR 122 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
                        reg-io-width = <1>;
                        clock-names = "baudclk", "apb_pclk";
                        clocks = <&CP110_LABEL(clk) 1 21>,
                        compatible = "snps,dw-apb-uart";
                        reg = <0x702100 0x100>;
                        reg-shift = <2>;
-                       interrupts = <ICU_GRP_NSR 123 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
                        reg-io-width = <1>;
                        clock-names = "baudclk", "apb_pclk";
                        clocks = <&CP110_LABEL(clk) 1 21>,
                        compatible = "snps,dw-apb-uart";
                        reg = <0x702200 0x100>;
                        reg-shift = <2>;
-                       interrupts = <ICU_GRP_NSR 124 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
                        reg-io-width = <1>;
                        clock-names = "baudclk", "apb_pclk";
                        clocks = <&CP110_LABEL(clk) 1 21>,
                        compatible = "snps,dw-apb-uart";
                        reg = <0x702300 0x100>;
                        reg-shift = <2>;
-                       interrupts = <ICU_GRP_NSR 125 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
                        reg-io-width = <1>;
                        clock-names = "baudclk", "apb_pclk";
                        clocks = <&CP110_LABEL(clk) 1 21>,
                        reg = <0x720000 0x54>;
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       interrupts = <ICU_GRP_NSR 115 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <115 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "reg";
                        clocks = <&CP110_LABEL(clk) 1 2>,
                                 <&CP110_LABEL(clk) 1 17>;
                        compatible = "marvell,armada-8k-rng",
                        "inside-secure,safexcel-eip76";
                        reg = <0x760000 0x7d>;
-                       interrupts = <ICU_GRP_NSR 95 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <95 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "reg";
                        clocks = <&CP110_LABEL(clk) 1 25>,
                                 <&CP110_LABEL(clk) 1 17>;
                CP110_LABEL(sdhci0): sdhci@780000 {
                        compatible = "marvell,armada-cp110-sdhci";
                        reg = <0x780000 0x300>;
-                       interrupts = <ICU_GRP_NSR 27 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "core", "axi";
                        clocks = <&CP110_LABEL(clk) 1 4>, <&CP110_LABEL(clk) 1 18>;
                        dma-coherent;
                CP110_LABEL(crypto): crypto@800000 {
                        compatible = "inside-secure,safexcel-eip197b";
                        reg = <0x800000 0x200000>;
-                       interrupts = <ICU_GRP_NSR 87 IRQ_TYPE_LEVEL_HIGH>,
-                               <ICU_GRP_NSR 88 IRQ_TYPE_LEVEL_HIGH>,
-                               <ICU_GRP_NSR 89 IRQ_TYPE_LEVEL_HIGH>,
-                               <ICU_GRP_NSR 90 IRQ_TYPE_LEVEL_HIGH>,
-                               <ICU_GRP_NSR 91 IRQ_TYPE_LEVEL_HIGH>,
-                               <ICU_GRP_NSR 92 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <87 IRQ_TYPE_LEVEL_HIGH>,
+                               <88 IRQ_TYPE_LEVEL_HIGH>,
+                               <89 IRQ_TYPE_LEVEL_HIGH>,
+                               <90 IRQ_TYPE_LEVEL_HIGH>,
+                               <91 IRQ_TYPE_LEVEL_HIGH>,
+                               <92 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "mem", "ring0", "ring1",
                                "ring2", "ring3", "eip";
                        clock-names = "core", "reg";
                /* non-prefetchable memory */
                0x82000000 0 CP110_PCIEx_MEM_BASE(0) 0  CP110_PCIEx_MEM_BASE(0) 0 0xf00000>;
                interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-map = <0 0 0 0 &CP110_LABEL(icu_nsr) 22 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
                num-lanes = <1>;
                clock-names = "core", "reg";
                clocks = <&CP110_LABEL(clk) 1 13>, <&CP110_LABEL(clk) 1 14>;
                /* non-prefetchable memory */
                0x82000000 0 CP110_PCIEx_MEM_BASE(1) 0  CP110_PCIEx_MEM_BASE(1) 0 0xf00000>;
                interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-map = <0 0 0 0 &CP110_LABEL(icu_nsr) 24 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
 
                num-lanes = <1>;
                clock-names = "core", "reg";
                /* non-prefetchable memory */
                0x82000000 0 CP110_PCIEx_MEM_BASE(2) 0  CP110_PCIEx_MEM_BASE(2) 0 0xf00000>;
                interrupt-map-mask = <0 0 0 0>;
-               interrupt-map = <0 0 0 0 &CP110_LABEL(icu) ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-map = <0 0 0 0 &CP110_LABEL(icu_nsr) 23 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
 
                num-lanes = <1>;
                clock-names = "core", "reg";
index 5b7fd6ad96e424b2ba4b656b388968ff3e3c7d72..e8f952fb279b9dddce46d455483e7c94ef0884c2 100644 (file)
@@ -5,4 +5,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
index 75cc0f7cc088869f219d66da2fad2592acd5153e..ee627a7c7b45f585b3c5e05016684ff19b4f2857 100644 (file)
                status = "disabled";
        };
 
+       spis1: spi@10013000 {
+               compatible = "mediatek,mt2712-spi-slave";
+               reg = <0 0x10013000 0 0x100>;
+               interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&infracfg CLK_INFRA_AO_SPI1>;
+               clock-names = "spi";
+               assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
+               assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+               status = "disabled";
+       };
+
        apmixedsys: syscon@10209000 {
                compatible = "mediatek,mt2712-apmixedsys", "syscon";
                reg = <0 0x10209000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
new file mode 100644 (file)
index 0000000..5d6005c
--- /dev/null
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#include "mt7622.dtsi"
+#include "mt6380.dtsi"
+
+/ {
+       model = "Bananapi BPI-R64";
+       compatible = "bananapi,bpi-r64", "mediatek,mt7622";
+
+       chosen {
+               bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
+       };
+
+       cpus {
+               cpu@0 {
+                       proc-supply = <&mt6380_vcpu_reg>;
+                       sram-supply = <&mt6380_vm_reg>;
+               };
+
+               cpu@1 {
+                       proc-supply = <&mt6380_vcpu_reg>;
+                       sram-supply = <&mt6380_vm_reg>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               factory {
+                       label = "factory";
+                       linux,code = <BTN_0>;
+                       gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
+               };
+
+               wps {
+                       label = "wps";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&pio 102 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               green {
+                       label = "bpi-r64:pio:green";
+                       gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+
+               red {
+                       label = "bpi-r64:pio:red";
+                       gpios = <&pio 88 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
+
+       memory {
+               reg = <0 0x40000000 0 0x40000000>;
+       };
+
+       reg_1p8v: regulator-1p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+
+       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;
+       };
+};
+
+&bch {
+       status = "disabled";
+};
+
+&btif {
+       status = "okay";
+};
+
+&cir {
+       pinctrl-names = "default";
+       pinctrl-0 = <&irrx_pins>;
+       status = "okay";
+};
+
+&eth {
+       pinctrl-names = "default";
+       pinctrl-0 = <&eth_pins>;
+       status = "okay";
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-handle = <&phy5>;
+       };
+
+       mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               phy5: ethernet-phy@5 {
+                       reg = <5>;
+                       phy-mode = "sgmii";
+               };
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&emmc_pins_default>;
+       pinctrl-1 = <&emmc_pins_uhs>;
+       status = "okay";
+       bus-width = <8>;
+       max-frequency = <50000000>;
+       cap-mmc-highspeed;
+       mmc-hs200-1_8v;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+       non-removable;
+};
+
+&mmc1 {
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&sd0_pins_default>;
+       pinctrl-1 = <&sd0_pins_uhs>;
+       status = "okay";
+       bus-width = <4>;
+       max-frequency = <50000000>;
+       cap-sd-highspeed;
+       r_smpl = <1>;
+       cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_3p3v>;
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+};
+
+&nandc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&parallel_nand_pins>;
+       status = "disabled";
+};
+
+&nor_flash {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_nor_pins>;
+       status = "disabled";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
+       status = "okay";
+
+       pcie@0,0 {
+               status = "okay";
+       };
+
+       pcie@1,0 {
+               status = "okay";
+       };
+};
+
+&pio {
+       /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
+        * SATA functions. i.e. output-high: PCIe, output-low: SATA
+        */
+       asm_sel {
+               gpio-hog;
+               gpios = <90 GPIO_ACTIVE_HIGH>;
+               output-high;
+       };
+
+       /* eMMC is shared pin with parallel NAND */
+       emmc_pins_default: emmc-pins-default {
+               mux {
+                       function = "emmc", "emmc_rst";
+                       groups = "emmc";
+               };
+
+               /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",
+                * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4,
+                * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively
+                */
+               conf-cmd-dat {
+                       pins = "NDL0", "NDL1", "NDL2",
+                              "NDL3", "NDL4", "NDL5",
+                              "NDL6", "NDL7", "NRB";
+                       input-enable;
+                       bias-pull-up;
+               };
+
+               conf-clk {
+                       pins = "NCLE";
+                       bias-pull-down;
+               };
+       };
+
+       emmc_pins_uhs: emmc-pins-uhs {
+               mux {
+                       function = "emmc";
+                       groups = "emmc";
+               };
+
+               conf-cmd-dat {
+                       pins = "NDL0", "NDL1", "NDL2",
+                              "NDL3", "NDL4", "NDL5",
+                              "NDL6", "NDL7", "NRB";
+                       input-enable;
+                       drive-strength = <4>;
+                       bias-pull-up;
+               };
+
+               conf-clk {
+                       pins = "NCLE";
+                       drive-strength = <4>;
+                       bias-pull-down;
+               };
+       };
+
+       eth_pins: eth-pins {
+               mux {
+                       function = "eth";
+                       groups = "mdc_mdio", "rgmii_via_gmac2";
+               };
+       };
+
+       i2c1_pins: i2c1-pins {
+               mux {
+                       function = "i2c";
+                       groups =  "i2c1_0";
+               };
+       };
+
+       i2c2_pins: i2c2-pins {
+               mux {
+                       function = "i2c";
+                       groups =  "i2c2_0";
+               };
+       };
+
+       i2s1_pins: i2s1-pins {
+               mux {
+                       function = "i2s";
+                       groups =  "i2s_out_mclk_bclk_ws",
+                                 "i2s1_in_data",
+                                 "i2s1_out_data";
+               };
+
+               conf {
+                       pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK",
+                              "I2S_WS", "I2S_MCLK";
+                       drive-strength = <12>;
+                       bias-pull-down;
+               };
+       };
+
+       irrx_pins: irrx-pins {
+               mux {
+                       function = "ir";
+                       groups =  "ir_1_rx";
+               };
+       };
+
+       irtx_pins: irtx-pins {
+               mux {
+                       function = "ir";
+                       groups =  "ir_1_tx";
+               };
+       };
+
+       /* Parallel nand is shared pin with eMMC */
+       parallel_nand_pins: parallel-nand-pins {
+               mux {
+                       function = "flash";
+                       groups = "par_nand";
+               };
+       };
+
+       pcie0_pins: pcie0-pins {
+               mux {
+                       function = "pcie";
+                       groups = "pcie0_pad_perst",
+                                "pcie0_1_waken",
+                                "pcie0_1_clkreq";
+               };
+       };
+
+       pcie1_pins: pcie1-pins {
+               mux {
+                       function = "pcie";
+                       groups = "pcie1_pad_perst",
+                                "pcie1_0_waken",
+                                "pcie1_0_clkreq";
+               };
+       };
+
+       pmic_bus_pins: pmic-bus-pins {
+               mux {
+                       function = "pmic";
+                       groups = "pmic_bus";
+               };
+       };
+
+       pwm7_pins: pwm1-2-pins {
+               mux {
+                       function = "pwm";
+                       groups = "pwm_ch7_2";
+               };
+       };
+
+       wled_pins: wled-pins {
+               mux {
+                       function = "led";
+                       groups = "wled";
+               };
+       };
+
+       sd0_pins_default: sd0-pins-default {
+               mux {
+                       function = "sd";
+                       groups = "sd_0";
+               };
+
+               /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN",
+                *  "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1,
+                *  DAT2, DAT3, CMD, CLK for SD respectively.
+                */
+               conf-cmd-data {
+                       pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN",
+                              "I2S2_IN","I2S4_OUT";
+                       input-enable;
+                       drive-strength = <8>;
+                       bias-pull-up;
+               };
+               conf-clk {
+                       pins = "I2S3_OUT";
+                       drive-strength = <12>;
+                       bias-pull-down;
+               };
+               conf-cd {
+                       pins = "TXD3";
+                       bias-pull-up;
+               };
+       };
+
+       sd0_pins_uhs: sd0-pins-uhs {
+               mux {
+                       function = "sd";
+                       groups = "sd_0";
+               };
+
+               conf-cmd-data {
+                       pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN",
+                              "I2S2_IN","I2S4_OUT";
+                       input-enable;
+                       bias-pull-up;
+               };
+
+               conf-clk {
+                       pins = "I2S3_OUT";
+                       bias-pull-down;
+               };
+       };
+
+       /* Serial NAND is shared pin with SPI-NOR */
+       serial_nand_pins: serial-nand-pins {
+               mux {
+                       function = "flash";
+                       groups = "snfi";
+               };
+       };
+
+       spic0_pins: spic0-pins {
+               mux {
+                       function = "spi";
+                       groups = "spic0_0";
+               };
+       };
+
+       spic1_pins: spic1-pins {
+               mux {
+                       function = "spi";
+                       groups = "spic1_0";
+               };
+       };
+
+       /* SPI-NOR is shared pin with serial NAND */
+       spi_nor_pins: spi-nor-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";
+               };
+       };
+
+       uart0_pins: uart0-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart0_0_tx_rx" ;
+               };
+       };
+
+       uart2_pins: uart2-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart2_1_tx_rx" ;
+               };
+       };
+
+       watchdog_pins: watchdog-pins {
+               mux {
+                       function = "watchdog";
+                       groups = "watchdog";
+               };
+       };
+};
+
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm7_pins>;
+       status = "okay";
+};
+
+&pwrap {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pmic_bus_pins>;
+
+       status = "okay";
+};
+
+&sata {
+       status = "disable";
+};
+
+&sata_phy {
+       status = "disable";
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spic0_pins>;
+       status = "okay";
+};
+
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spic1_pins>;
+       status = "okay";
+};
+
+&ssusb {
+       vusb33-supply = <&reg_3p3v>;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&u3phy {
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+};
+
+&watchdog {
+       pinctrl-names = "default";
+       pinctrl-0 = <&watchdog_pins>;
+       status = "okay";
+};
index a747b7bf132d1dafe8ff4d6b5ebcaaa5b7021f1e..dcad0869b84ca01dc76e2924506583daf1c65c54 100644 (file)
@@ -51,7 +51,7 @@
        };
 
        memory {
-               reg = <0 0x40000000 0 0x3F000000>;
+               reg = <0 0x40000000 0 0x20000000>;
        };
 
        reg_1p8v: regulator-1p8v {
        };
 };
 
+&bch {
+       status = "disabled";
+};
+
+&btif {
+       status = "okay";
+};
+
+&cir {
+       pinctrl-names = "default";
+       pinctrl-0 = <&irrx_pins>;
+       status = "okay";
+};
+
+&eth {
+       pinctrl-names = "default";
+       pinctrl-0 = <&eth_pins>;
+       status = "okay";
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-handle = <&phy5>;
+       };
+
+       mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               phy5: ethernet-phy@5 {
+                       reg = <5>;
+                       phy-mode = "sgmii";
+               };
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&emmc_pins_default>;
+       pinctrl-1 = <&emmc_pins_uhs>;
+       status = "okay";
+       bus-width = <8>;
+       max-frequency = <50000000>;
+       cap-mmc-highspeed;
+       mmc-hs200-1_8v;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+       non-removable;
+};
+
+&mmc1 {
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&sd0_pins_default>;
+       pinctrl-1 = <&sd0_pins_uhs>;
+       status = "okay";
+       bus-width = <4>;
+       max-frequency = <50000000>;
+       cap-sd-highspeed;
+       r_smpl = <1>;
+       cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_3p3v>;
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+};
+
+&nandc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&parallel_nand_pins>;
+       status = "disabled";
+};
+
+&nor_flash {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_nor_pins>;
+       status = "disabled";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+       };
+};
+
 &pcie {
        pinctrl-names = "default";
        pinctrl-0 = <&pcie0_pins>;
        };
 };
 
-&bch {
-       status = "disabled";
-};
-
-&btif {
-       status = "okay";
-};
-
-&cir {
-       pinctrl-names = "default";
-       pinctrl-0 = <&irrx_pins>;
-       status = "okay";
-};
-
-&eth {
-       pinctrl-names = "default";
-       pinctrl-0 = <&eth_pins>;
-       status = "okay";
-
-       gmac1: mac@1 {
-               compatible = "mediatek,eth-mac";
-               reg = <1>;
-               phy-handle = <&phy5>;
-       };
-
-       mdio-bus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               phy5: ethernet-phy@5 {
-                       reg = <5>;
-                       phy-mode = "sgmii";
-               };
-       };
-};
-
-&i2c1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c1_pins>;
-       status = "okay";
-};
-
-&i2c2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c2_pins>;
-       status = "okay";
-};
-
-&mmc0 {
-       pinctrl-names = "default", "state_uhs";
-       pinctrl-0 = <&emmc_pins_default>;
-       pinctrl-1 = <&emmc_pins_uhs>;
-       status = "okay";
-       bus-width = <8>;
-       max-frequency = <50000000>;
-       cap-mmc-highspeed;
-       mmc-hs200-1_8v;
-       vmmc-supply = <&reg_3p3v>;
-       vqmmc-supply = <&reg_1p8v>;
-       assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
-       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
-       non-removable;
-};
-
-&mmc1 {
-       pinctrl-names = "default", "state_uhs";
-       pinctrl-0 = <&sd0_pins_default>;
-       pinctrl-1 = <&sd0_pins_uhs>;
-       status = "okay";
-       bus-width = <4>;
-       max-frequency = <50000000>;
-       cap-sd-highspeed;
-       r_smpl = <1>;
-       cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>;
-       vmmc-supply = <&reg_3p3v>;
-       vqmmc-supply = <&reg_3p3v>;
-       assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
-       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
-};
-
-&nandc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&parallel_nand_pins>;
-       status = "disabled";
-};
-
-&nor_flash {
-       pinctrl-names = "default";
-       pinctrl-0 = <&spi_nor_pins>;
-       status = "disabled";
-
-       flash@0 {
-               compatible = "jedec,spi-nor";
-               reg = <0>;
-       };
-};
-
 &pwm {
        pinctrl-names = "default";
        pinctrl-0 = <&pwm7_pins>;
index de2c47bdbe6468698ca6c2548b5a08b6386c7b93..fe0c875f1d9513538e5a18c74f641557d89675c8 100644 (file)
@@ -79,6 +79,7 @@
                        #cooling-cells = <2>;
                        enable-method = "psci";
                        clock-frequency = <1300000000>;
+                       cci-control-port = <&cci_control2>;
                };
 
                cpu1: cpu@1 {
@@ -92,6 +93,7 @@
                        #cooling-cells = <2>;
                        enable-method = "psci";
                        clock-frequency = <1300000000>;
+                       cci-control-port = <&cci_control2>;
                };
        };
 
                method      = "smc";
        };
 
+       pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 9 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-affinity = <&cpu0>, <&cpu1>;
+       };
+
        reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
                #reset-cells = <1>;
        };
 
+       timer: timer@10004000 {
+               compatible = "mediatek,mt7622-timer",
+                            "mediatek,mt6577-timer";
+               reg = <0 0x10004000 0 0x80>;
+               interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&infracfg CLK_INFRA_APXGPT_PD>,
+                        <&topckgen CLK_TOP_RTC>;
+               clock-names = "system-clk", "rtc-clk";
+       };
+
        scpsys: scpsys@10006000 {
                compatible = "mediatek,mt7622-scpsys",
                             "syscon";
                      <0 0x10360000 0 0x2000>;
        };
 
+       cci: cci@10390000 {
+               compatible = "arm,cci-400";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0 0x10390000 0 0x1000>;
+               ranges = <0 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>;
+               };
+       };
+
        auxadc: adc@11001000 {
                compatible = "mediatek,mt7622-auxadc";
                reg = <0 0x11001000 0 0x1000>;
                reg-shift = <2>;
                reg-io-width = <4>;
                status = "disabled";
+
+               bluetooth {
+                       compatible = "mediatek,mt7622-bluetooth";
+                       power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>;
+                       clocks = <&clk25m>;
+                       clock-names = "ref";
+               };
        };
 
        nandc: nfi@1100d000 {
index b762227f6aa1832ac0e8a5de872440deda102aea..2f3c8e29520d344304423ac1daa3a27d2329f1b6 100644 (file)
@@ -4,6 +4,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/mailbox/tegra186-hsp.h>
 #include <dt-bindings/memory/tegra186-mc.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
 #include <dt-bindings/power/tegra186-powergate.h>
 #include <dt-bindings/reset/tegra186-reset.h>
 #include <dt-bindings/thermal/tegra186-bpmp-thermal.h>
                clock-names = "sdhci";
                resets = <&bpmp TEGRA186_RESET_SDMMC1>;
                reset-names = "sdhci";
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc1_3v3>;
+               pinctrl-1 = <&sdmmc1_1v8>;
+               nvidia,pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+               nvidia,pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+               nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+               nvidia,pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
+               nvidia,pad-autocal-pull-up-offset-sdr104 = <0x03>;
+               nvidia,pad-autocal-pull-down-offset-sdr104 = <0x05>;
+               nvidia,default-tap = <0x5>;
+               nvidia,default-trim = <0xb>;
+               assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC1>,
+                                 <&bpmp TEGRA186_CLK_PLLP_OUT0>;
+               assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLP_OUT0>;
                status = "disabled";
        };
 
                clock-names = "sdhci";
                resets = <&bpmp TEGRA186_RESET_SDMMC2>;
                reset-names = "sdhci";
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc2_3v3>;
+               pinctrl-1 = <&sdmmc2_1v8>;
+               nvidia,pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+               nvidia,pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+               nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+               nvidia,pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
+               nvidia,default-tap = <0x5>;
+               nvidia,default-trim = <0xb>;
                status = "disabled";
        };
 
                clock-names = "sdhci";
                resets = <&bpmp TEGRA186_RESET_SDMMC3>;
                reset-names = "sdhci";
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc3_3v3>;
+               pinctrl-1 = <&sdmmc3_1v8>;
+               nvidia,pad-autocal-pull-up-offset-1v8 = <0x00>;
+               nvidia,pad-autocal-pull-down-offset-1v8 = <0x7a>;
+               nvidia,pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+               nvidia,pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+               nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+               nvidia,pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
+               nvidia,default-tap = <0x5>;
+               nvidia,default-trim = <0xb>;
                status = "disabled";
        };
 
                interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&bpmp TEGRA186_CLK_SDMMC4>;
                clock-names = "sdhci";
+               assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
+                                 <&bpmp TEGRA186_CLK_PLLC4_VCO>;
+               assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>;
                resets = <&bpmp TEGRA186_RESET_SDMMC4>;
                reset-names = "sdhci";
+               nvidia,pad-autocal-pull-up-offset-hs400 = <0x05>;
+               nvidia,pad-autocal-pull-down-offset-hs400 = <0x05>;
+               nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x0a>;
+               nvidia,pad-autocal-pull-down-offset-1v8-timeout = <0x0a>;
+               nvidia,default-tap = <0x5>;
+               nvidia,default-trim = <0x9>;
+               nvidia,dqs-trim = <63>;
+               mmc-hs400-1_8v;
                status = "disabled";
        };
 
                      <0 0x0c380000 0 0x10000>,
                      <0 0x0c390000 0 0x10000>;
                reg-names = "pmc", "wake", "aotag", "scratch";
+
+               sdmmc1_3v3: sdmmc1-3v3 {
+                       pins = "sdmmc1-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc1_1v8: sdmmc1-1v8 {
+                       pins = "sdmmc1-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
+
+               sdmmc2_3v3: sdmmc2-3v3 {
+                       pins = "sdmmc2-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc2_1v8: sdmmc2-1v8 {
+                       pins = "sdmmc2-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
+
+               sdmmc3_3v3: sdmmc3-3v3 {
+                       pins = "sdmmc3-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc3_1v8: sdmmc3-1v8 {
+                       pins = "sdmmc3-hv";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
        };
 
        ccplex@e000000 {
index a4dfcd19b9e88965187cd24e23116103b0f7e652..9fc14bb9a0affc7dea710afa5bae74b90a264adb 100644 (file)
                };
 
                gen1_i2c: i2c@3160000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x03160000 0x10000>;
                        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                };
 
                cam_i2c: i2c@3180000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x03180000 0x10000>;
                        interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
 
                /* shares pads with dpaux1 */
                dp_aux_ch1_i2c: i2c@3190000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x03190000 0x10000>;
                        interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
 
                /* shares pads with dpaux0 */
                dp_aux_ch0_i2c: i2c@31b0000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x031b0000 0x10000>;
                        interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                };
 
                gen7_i2c: i2c@31c0000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x031c0000 0x10000>;
                        interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                };
 
                gen9_i2c: i2c@31e0000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x031e0000 0x10000>;
                        interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                };
 
                gen2_i2c: i2c@c240000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x0c240000 0x10000>;
                        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                };
 
                gen8_i2c: i2c@c250000 {
-                       compatible = "nvidia,tegra194-i2c", "nvidia,tegra114-i2c";
+                       compatible = "nvidia,tegra194-i2c";
                        reg = <0x0c250000 0x10000>;
                        interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
index 212e6634c9baa5173efd128eb9e37c28a6714468..053458a5db55bef47ae3223af38eefc00828367a 100644 (file)
 
                                vddio_sdmmc: ldo2 {
                                        regulator-name = "VDDIO_SDMMC";
-                                       /*
-                                        * Technically this supply should have
-                                        * a supported range from 1.8 - 3.3 V.
-                                        * However, that would cause the SDHCI
-                                        * driver to request 2.7 V upon access
-                                        * and that in turn will cause traffic
-                                        * to be broken. Leave it at 3.3 V for
-                                        * now.
-                                        */
-                                       regulator-min-microvolt = <3300000>;
+                                       regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-always-on;
                                        regulator-boot-on;
                status = "okay";
                bus-width = <8>;
                non-removable;
+               vqmmc-supply = <&vdd_1v8>;
        };
 
        clocks {
index 9d5a0e6b2ca4f9b69413e84f8513a7c2f31a5d8f..365726ddd418bfd146ba90cd936aa583e4a3aad9 100644 (file)
        sdhci@700b0000 {
                status = "okay";
                bus-width = <4>;
-               no-1-8-v;
 
                cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
 
index 3be920efee823a2913f7695bbd09a4ca10f03eb8..8fe47d6445a5e264e89e7277a506c699111d8533 100644 (file)
@@ -3,6 +3,7 @@
 #include <dt-bindings/gpio/tegra-gpio.h>
 #include <dt-bindings/memory/tegra210-mc.h>
 #include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/thermal/tegra124-soctherm.h>
 
                                #power-domain-cells = <0>;
                        };
                };
+
+               sdmmc1_3v3: sdmmc1-3v3 {
+                       pins = "sdmmc1";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc1_1v8: sdmmc1-1v8 {
+                       pins = "sdmmc1";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
+
+               sdmmc3_3v3: sdmmc3-3v3 {
+                       pins = "sdmmc3";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_3V3>;
+               };
+
+               sdmmc3_1v8: sdmmc3-1v8 {
+                       pins = "sdmmc3";
+                       power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
+               };
        };
 
        fuse@7000f800 {
                clock-names = "sdhci";
                resets = <&tegra_car 14>;
                reset-names = "sdhci";
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc1_3v3>;
+               pinctrl-1 = <&sdmmc1_1v8>;
+               nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>;
+               nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>;
+               nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>;
+               nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
+               nvidia,default-tap = <0x2>;
+               nvidia,default-trim = <0x4>;
+               assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
+                                 <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>,
+                                 <&tegra_car TEGRA210_CLK_PLL_C4>;
+               assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
+               assigned-clock-rates = <200000000>, <1000000000>, <1000000000>;
                status = "disabled";
        };
 
                clock-names = "sdhci";
                resets = <&tegra_car 9>;
                reset-names = "sdhci";
+               nvidia,pad-autocal-pull-up-offset-1v8 = <0x05>;
+               nvidia,pad-autocal-pull-down-offset-1v8 = <0x05>;
+               nvidia,default-tap = <0x8>;
+               nvidia,default-trim = <0x0>;
                status = "disabled";
        };
 
                clock-names = "sdhci";
                resets = <&tegra_car 69>;
                reset-names = "sdhci";
+               pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+               pinctrl-0 = <&sdmmc3_3v3>;
+               pinctrl-1 = <&sdmmc3_1v8>;
+               nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>;
+               nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>;
+               nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>;
+               nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
+               nvidia,default-tap = <0x3>;
+               nvidia,default-trim = <0x3>;
                status = "disabled";
        };
 
                clock-names = "sdhci";
                resets = <&tegra_car 15>;
                reset-names = "sdhci";
+               nvidia,pad-autocal-pull-up-offset-1v8 = <0x05>;
+               nvidia,pad-autocal-pull-down-offset-1v8 = <0x05>;
+               nvidia,default-tap = <0x8>;
+               nvidia,default-trim = <0x0>;
+               assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
+                                 <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
+               assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
+               nvidia,dqs-trim = <40>;
+               mmc-hs400-1_8v;
                status = "disabled";
        };
 
index 9319e74b890687b0485f437dcea2d1cd8a1f4441..a658c07652a7508d836f7b7a73974df74874333a 100644 (file)
@@ -6,4 +6,5 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8992-bullhead-rev-101.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8994-angler-rev-101.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8996-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += msm8998-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-mtp.dtb
index 78ce3979ef096fd1dc3059c9d8e9e9f44ca56ba9..46feedf7c989bbe5126d182b5f0e791e76a283cc 100644 (file)
        };
 };
 
+&spmi_bus {
+       pm8916_0: pm8916@0 {
+               pon@800 {
+                       resin {
+                               compatible = "qcom,pm8941-resin";
+                               interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_VOLUMEDOWN>;
+                       };
+               };
+       };
+};
+
 &wcd_codec {
         status = "okay";
         clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
index 230e9c8484ac1f2a4ed4967ff4ed44357c9a90ac..da23bdafbd3393af0503be785b2f672ee1857c7e 100644 (file)
@@ -17,5 +17,5 @@
 
 / {
        model = "Qualcomm Technologies, Inc. DB820c";
-       compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc";
+       compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc", "qcom,apq8096";
 };
index 0ef90c6554a9885260c41dff9bbb6b627dc6ddac..bf20c55a6bc4a8b7d0379aacb7945c4776cfefd4 100644 (file)
                };
        };
 };
+
+&spmi_bus {
+       pmic@0 {
+               pon@800 {
+                       resin {
+                               compatible = "qcom,pm8941-resin";
+                               interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_VOLUMEDOWN>;
+                       };
+               };
+       };
+};
index 7b32b8990d62fb22acdbbf287929162fb826f480..d302d8d639a123d0c27fe6103de744daa29119d0 100644 (file)
@@ -18,9 +18,6 @@
 #include <dt-bindings/thermal/thermal.h>
 
 / {
-       model = "Qualcomm Technologies, Inc. MSM8916";
-       compatible = "qcom,msm8916";
-
        interrupt-parent = <&intc>;
 
        #address-cells = <2>;
                        clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       port {
-                               tpiu_in: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out1>;
+                       in-ports {
+                               port {
+                                       tpiu_in: endpoint {
+                                               remote-endpoint = <&replicator_out1>;
+                                       };
                                };
                        };
                };
                        clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                port@4 {
                                        reg = <4>;
                                        funnel0_in4: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&funnel1_out>;
                                        };
                                };
-                               port@8 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        funnel0_out: endpoint {
                                                remote-endpoint = <&etf_in>;
                                        };
                        clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       out-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                                remote-endpoint = <&tpiu_in>;
                                        };
                                };
-                               port@2 {
-                                       reg = <0>;
+                       };
+
+                       in-ports {
+                               port {
                                        replicator_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etf_out>;
                                        };
                                };
                        clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
+                       in-ports {
+                               port {
                                        etf_in: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&funnel0_out>;
                                        };
                                };
-                               port@1 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        etf_out: endpoint {
                                                remote-endpoint = <&replicator_in>;
                                        };
                        clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       port {
-                               etr_in: endpoint {
-                                       slave-mode;
-                                       remote-endpoint = <&replicator_out0>;
+                       in-ports {
+                               port {
+                                       etr_in: endpoint {
+                                               remote-endpoint = <&replicator_out0>;
+                                       };
                                };
                        };
                };
                        clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
                        clock-names = "apb_pclk", "atclk";
 
-                       ports {
+                       in-ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
 
                                port@0 {
                                        reg = <0>;
                                        funnel1_in0: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm0_out>;
                                        };
                                };
                                port@1 {
                                        reg = <1>;
                                        funnel1_in1: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm1_out>;
                                        };
                                };
                                port@2 {
                                        reg = <2>;
                                        funnel1_in2: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm2_out>;
                                        };
                                };
                                port@3 {
                                        reg = <3>;
                                        funnel1_in3: endpoint {
-                                               slave-mode;
                                                remote-endpoint = <&etm3_out>;
                                        };
                                };
-                               port@4 {
-                                       reg = <0>;
+                       };
+
+                       out-ports {
+                               port {
                                        funnel1_out: endpoint {
                                                remote-endpoint = <&funnel0_in4>;
                                        };
 
                        cpu = <&CPU0>;
 
-                       port {
-                               etm0_out: endpoint {
-                               remote-endpoint = <&funnel1_in0>;
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint = <&funnel1_in0>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU1>;
 
-                       port {
-                               etm1_out: endpoint {
-                                       remote-endpoint = <&funnel1_in1>;
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint = <&funnel1_in1>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU2>;
 
-                       port {
-                               etm2_out: endpoint {
-                                       remote-endpoint = <&funnel1_in2>;
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint = <&funnel1_in2>;
+                                       };
                                };
                        };
                };
 
                        cpu = <&CPU3>;
 
-                       port {
-                               etm3_out: endpoint {
-                                       remote-endpoint = <&funnel1_in3>;
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint = <&funnel1_in3>;
+                                       };
                                };
                        };
                };
index cd3865e7a270b97e1913c779fa7ad3448d3e5660..b29fe80d72883f60133b33ce4edc3338779c118f 100644 (file)
@@ -16,8 +16,6 @@
 #include <dt-bindings/clock/qcom,rpmcc.h>
 
 / {
-       model = "Qualcomm Technologies, Inc. MSM8996";
-
        interrupt-parent = <&intc>;
 
        #address-cells = <2>;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
 
-               apcs: syscon@9820000 {
-                       compatible = "syscon";
-                       reg = <0x9820000 0x1000>;
-               };
-
                apcs_glb: mailbox@9820000 {
                        compatible = "qcom,msm8996-apcs-hmss-global";
                        reg = <0x9820000 0x1000>;
                        interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
 
                        label = "lpass";
-                       qcom,ipc = <&apcs 16 8>;
+                       mboxes = <&apcs_glb 8>;
                        qcom,smd-edge = <1>;
                        qcom,remote-pid = <2>;
                };
 
                interrupts = <0 158 IRQ_TYPE_EDGE_RISING>;
 
-               qcom,ipc = <&apcs 16 10>;
+               mboxes = <&apcs_glb 10>;
 
                qcom,local-pid = <0>;
                qcom,remote-pid = <2>;
 
                interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
 
-               qcom,ipc = <&apcs 16 14>;
+               mboxes = <&apcs_glb 14>;
 
                qcom,local-pid = <0>;
                qcom,remote-pid = <1>;
 
                interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
 
-               qcom,ipc = <&apcs 16 26>;
+               mboxes = <&apcs_glb 26>;
 
                qcom,local-pid = <0>;
                qcom,remote-pid = <3>;
diff --git a/arch/arm64/boot/dts/qcom/msm8998-mtp.dts b/arch/arm64/boot/dts/qcom/msm8998-mtp.dts
new file mode 100644 (file)
index 0000000..66540d2
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved. */
+
+/dts-v1/;
+
+#include "msm8998-mtp.dtsi"
+
+/ {
+       model = "Qualcomm Technologies, Inc. MSM8998 v1 MTP";
+       compatible = "qcom,msm8998-mtp";
+
+       qcom,board-id = <8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi
new file mode 100644 (file)
index 0000000..b4276da
--- /dev/null
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved. */
+
+#include "msm8998.dtsi"
+#include "pm8998.dtsi"
+#include "pmi8998.dtsi"
+#include "pm8005.dtsi"
+
+/ {
+       aliases {
+               serial0 = &blsp2_uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       thermal-zones {
+               battery-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 0>;
+
+                       trips {
+                               battery_crit: trip0 {
+                                       temperature = <60000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               skin-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 5>;
+
+                       trips {
+                               skin_alert: trip0 {
+                                       temperature = <44000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               skip_crit: trip1 {
+                                       temperature = <70000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+       };
+
+       vph_pwr: vph-pwr-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vph_pwr";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&blsp2_uart1 {
+       status = "okay";
+};
+
+&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 = <&vreg_bob>;
+               vdd_l10_l23_l25-supply = <&vreg_bob>;
+               vdd_l13_l19_l21-supply = <&vreg_bob>;
+               vdd_l16_l28-supply = <&vreg_bob>;
+               vdd_l18_l22-supply = <&vreg_bob>;
+               vdd_l20_l24-supply = <&vreg_bob>;
+               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>;
+               };
+               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>;
+               };
+               vreg_l2a_1p2: l2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+               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>;
+               };
+               vreg_l21a_2p95: l21 {
+                       regulator-min-microvolt = <2960000>;
+                       regulator-max-microvolt = <2960000>;
+               };
+               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>;
+               };
+
+       };
+
+       pmi8998-regulators {
+               compatible = "qcom,rpm-pmi8998-regulators";
+
+               vdd_bob-supply = <&vph_pwr>;
+
+               vreg_bob: bob {
+                       regulator-min-microvolt = <3312000>;
+                       regulator-max-microvolt = <3600000>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
new file mode 100644 (file)
index 0000000..78227cc
--- /dev/null
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved. */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-msm8998.h>
+
+/ {
+       interrupt-parent = <&intc>;
+
+       qcom,msm-id = <292 0x0>;
+
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       chosen { };
+
+       memory {
+               device_type = "memory";
+               /* We expect the bootloader to fill in the reg */
+               reg = <0 0 0 0>;
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               memory@85800000 {
+                       reg = <0x0 0x85800000 0x0 0x800000>;
+                       no-map;
+               };
+
+               smem_mem: smem-mem@86000000 {
+                       reg = <0x0 0x86000000 0x0 0x200000>;
+                       no-map;
+               };
+
+               memory@86200000 {
+                       reg = <0x0 0x86200000 0x0 0x2600000>;
+                       no-map;
+               };
+
+               rmtfs {
+                       compatible = "qcom,rmtfs-mem";
+
+                       size = <0x0 0x200000>;
+                       alloc-ranges = <0x0 0xa0000000 0x0 0x2000000>;
+                       no-map;
+
+                       qcom,client-id = <1>;
+                       qcom,vmid = <15>;
+               };
+       };
+
+       clocks {
+               xo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <19200000>;
+               };
+
+               sleep_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32764>;
+               };
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               CPU0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       efficiency = <1024>;
+                       next-level-cache = <&L2_0>;
+                       L2_0: l2-cache {
+                               compatible = "arm,arch-cache";
+                               cache-level = <2>;
+                       };
+                       L1_I_0: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_0: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       efficiency = <1024>;
+                       next-level-cache = <&L2_0>;
+                       L1_I_1: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_1: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+                       efficiency = <1024>;
+                       next-level-cache = <&L2_0>;
+                       L1_I_2: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_2: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+                       efficiency = <1024>;
+                       next-level-cache = <&L2_0>;
+                       L1_I_3: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_3: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU4: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x100>;
+                       enable-method = "psci";
+                       efficiency = <1536>;
+                       next-level-cache = <&L2_1>;
+                       L2_1: l2-cache {
+                               compatible = "arm,arch-cache";
+                               cache-level = <2>;
+                       };
+                       L1_I_100: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_100: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU5: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x101>;
+                       enable-method = "psci";
+                       efficiency = <1536>;
+                       next-level-cache = <&L2_1>;
+                       L1_I_101: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_101: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU6: cpu@102 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x102>;
+                       enable-method = "psci";
+                       efficiency = <1536>;
+                       next-level-cache = <&L2_1>;
+                       L1_I_102: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_102: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               CPU7: cpu@103 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x103>;
+                       enable-method = "psci";
+                       efficiency = <1536>;
+                       next-level-cache = <&L2_1>;
+                       L1_I_103: l1-icache {
+                               compatible = "arm,arch-cache";
+                       };
+                       L1_D_103: l1-dcache {
+                               compatible = "arm,arch-cache";
+                       };
+               };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&CPU0>;
+                               };
+
+                               core1 {
+                                       cpu = <&CPU1>;
+                               };
+
+                               core2 {
+                                       cpu = <&CPU2>;
+                               };
+
+                               core3 {
+                                       cpu = <&CPU3>;
+                               };
+                       };
+
+                       cluster1 {
+                               core0 {
+                                       cpu = <&CPU4>;
+                               };
+
+                               core1 {
+                                       cpu = <&CPU5>;
+                               };
+
+                               core2 {
+                                       cpu = <&CPU6>;
+                               };
+
+                               core3 {
+                                       cpu = <&CPU7>;
+                               };
+                       };
+               };
+       };
+
+       firmware {
+               scm {
+                       compatible = "qcom,scm-msm8998";
+               };
+       };
+
+       tcsr_mutex: hwlock {
+               compatible = "qcom,tcsr-mutex";
+               syscon = <&tcsr_mutex_regs 0 0x1000>;
+               #hwlock-cells = <1>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       rpm-glink {
+               compatible = "qcom,glink-rpm";
+
+               interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+               qcom,rpm-msg-ram = <&rpm_msg_ram>;
+               mboxes = <&apcs_glb 0>;
+
+               rpm_requests: rpm-requests {
+                       compatible = "qcom,rpm-msm8998";
+                       qcom,glink-channels = "rpm_requests";
+               };
+       };
+
+       smem {
+               compatible = "qcom,smem";
+               memory-region = <&smem_mem>;
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
+       smp2p-lpass {
+               compatible = "qcom,smp2p";
+               qcom,smem = <443>, <429>;
+
+               interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apcs_glb 10>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <2>;
+
+               adsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               adsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-mpss {
+               compatible = "qcom,smp2p";
+               qcom,smem = <435>, <428>;
+               interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
+               mboxes = <&apcs_glb 14>;
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <1>;
+
+               modem_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               modem_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-slpi {
+               compatible = "qcom,smp2p";
+               qcom,smem = <481>, <430>;
+               interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
+               mboxes = <&apcs_glb 26>;
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <3>;
+
+               slpi_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               slpi_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       thermal-zones {
+               cpu-thermal0 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 6>;
+
+                       trips {
+                               cpu_alert0: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit0: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal1 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 7>;
+
+                       trips {
+                               cpu_alert1: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit1: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal2 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 8>;
+
+                       trips {
+                               cpu_alert2: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit2: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal3 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 9>;
+
+                       trips {
+                               cpu_alert3: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit3: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal4 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 10>;
+
+                       trips {
+                               cpu_alert4: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit4: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal5 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 11>;
+
+                       trips {
+                               cpu_alert5: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit5: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal6 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 0>;
+
+                       trips {
+                               cpu_alert6: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit6: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpu-thermal7 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 1>;
+
+                       trips {
+                               cpu_alert7: trip0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit7: trip1 {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               gpu-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 3>;
+               };
+       };
+
+       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>;
+       };
+
+       soc: soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0 0 0xffffffff>;
+               compatible = "simple-bus";
+
+               rpm_msg_ram: memory@68000 {
+                       compatible = "qcom,rpm-msg-ram";
+                       reg = <0x778000 0x7000>;
+               };
+
+               qfprom: qfprom@780000 {
+                       compatible = "qcom,qfprom";
+                       reg = <0x780000 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@10aa000 {
+                       compatible = "qcom,msm8998-tsens", "qcom,tsens-v2";
+                       reg = <0x10aa000 0x2000>;
+
+                       #qcom,sensors = <12>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               tsens1: thermal@10ad000 {
+                       compatible = "qcom,msm8998-tsens", "qcom,tsens-v2";
+                       reg = <0x10ad000 0x2000>;
+
+                       #qcom,sensors = <8>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               tcsr_mutex_regs: syscon@1f40000 {
+                       compatible = "syscon";
+                       reg = <0x1f40000 0x20000>;
+               };
+
+               apcs_glb: mailbox@9820000 {
+                       compatible = "qcom,msm8998-apcs-hmss-global";
+                       reg = <0x17911000 0x1000>;
+
+                       #mbox-cells = <1>;
+               };
+
+               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";
+               };
+
+               timer@17920000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       compatible = "arm,armv7-timer-mem";
+                       reg = <0x17920000 0x1000>;
+
+                       frame@17921000 {
+                               frame-number = <0>;
+                               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17921000 0x1000>,
+                                     <0x17922000 0x1000>;
+                       };
+
+                       frame@17923000 {
+                               frame-number = <1>;
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17923000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17924000 {
+                               frame-number = <2>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17924000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17925000 {
+                               frame-number = <3>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17925000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17926000 {
+                               frame-number = <4>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17926000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17927000 {
+                               frame-number = <5>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17927000 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17928000 {
+                               frame-number = <6>;
+                               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x17928000 0x1000>;
+                               status = "disabled";
+                       };
+               };
+
+               intc: interrupt-controller@17a00000 {
+                       compatible = "arm,gic-v3";
+                       reg = <0x17a00000 0x10000>,       /* GICD */
+                             <0x17b00000 0x100000>;      /* GICR * 8 */
+                       #interrupt-cells = <3>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       interrupt-controller;
+                       #redistributor-regions = <1>;
+                       redistributor-stride = <0x0 0x20000>;
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
+       };
+};
index 196b1c0ceb9b095ed341c8804cea50290ffc825e..15a37cbcd2164240c03852a23e34a03b944fa386 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <dt-bindings/iio/qcom,spmi-vadc.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/linux-event-codes.h>
 #include <dt-bindings/spmi/spmi.h>
 
 &spmi_bus {
                        interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
                };
 
-               pwrkey@800 {
-                       compatible = "qcom,pm8941-pwrkey";
+               pon@800 {
+                       compatible = "qcom,pm8916-pon";
                        reg = <0x800>;
-                       interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
-                       debounce = <15625>;
-                       bias-pull-up;
+                       mode-bootloader = <0x2>;
+                       mode-recovery = <0x1>;
+
+                       pwrkey {
+                               compatible = "qcom,pm8941-pwrkey";
+                               interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_POWER>;
+                       };
                };
 
                pm8916_gpios: gpios@c000 {
index 80024c0b1c7c26f7109cf0cd3750847ef961a08d..76b5a3e6a2b5090f7b0f5f78b5dcb33fd4320aae 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/input/linux-event-codes.h>
 
 &spmi_bus {
 
                        interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
                };
 
+               pon@800 {
+                       compatible = "qcom,pm8916-pon";
+
+                       reg = <0x800>;
+                       mode-bootloader = <0x2>;
+                       mode-recovery = <0x1>;
+
+                       pwrkey {
+                               compatible = "qcom,pm8941-pwrkey";
+                               interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_POWER>;
+                       };
+
+               };
+
                pm8994_gpios: gpios@c000 {
                        compatible = "qcom,pm8994-gpio";
                        reg = <0xc000>;
index 92bed1e7d4bbfa5c8caf1e1e6acd938943a1ae38..048f19fa01504ccfa2d29080cf12246961ac1f47 100644 (file)
@@ -1,8 +1,35 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /* Copyright 2018 Google LLC. */
 
-#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/input/linux-event-codes.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+       thermal-zones {
+               pm8998 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&pm8998_temp>;
+
+                       trips {
+                               pm8998_alert0: pm8998-alert0 {
+                                       temperature = <105000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               pm8998_crit: pm8998-crit {
+                                       temperature = <125000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+       };
+};
 
 &spmi_bus {
        pm8998_lsid0: pmic@0 {
                #address-cells = <1>;
                #size-cells = <0>;
 
+               pm8998_pon: pon@800 {
+                       compatible = "qcom,pm8916-pon";
+
+                       reg = <0x800>;
+                       mode-bootloader = <0x2>;
+                       mode-recovery = <0x1>;
+
+                       pwrkey {
+                               compatible = "qcom,pm8941-pwrkey";
+                               interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_POWER>;
+                       };
+               };
+
+               pm8998_temp: temp-alarm@2400 {
+                       compatible = "qcom,spmi-temp-alarm";
+                       reg = <0x2400>;
+                       interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
+                       #thermal-sensor-cells = <0>;
+               };
+
+               pm8998_coincell: coincell@2800 {
+                       compatible = "qcom,pm8941-coincell";
+                       reg = <0x2800>;
+
+                       status = "disabled";
+               };
+
+               pm8998_adc: adc@3100 {
+                       compatible = "qcom,spmi-adc-rev2";
+                       reg = <0x3100>;
+                       interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #io-channel-cells = <1>;
+               };
+
+               rtc@6000 {
+                       compatible = "qcom,pm8941-rtc";
+                       reg = <0x6000>, <0x6100>;
+                       reg-names = "rtc", "alarm";
+                       interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+               };
+
                pm8998_gpio: gpios@c000 {
                        compatible = "qcom,pm8998-gpio", "qcom,spmi-gpio";
                        reg = <0xc000>;
diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
new file mode 100644 (file)
index 0000000..da3285e
--- /dev/null
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+       pmi8998_lsid0: pmic@2 {
+               compatible = "qcom,pmi8998", "qcom,spmi-pmic";
+               reg = <0x2 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pmi8998_gpio: gpios@c000 {
+                       compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+                                    <0 0xc1 0 IRQ_TYPE_NONE>,
+                                    <0 0xc2 0 IRQ_TYPE_NONE>,
+                                    <0 0xc3 0 IRQ_TYPE_NONE>,
+                                    <0 0xc4 0 IRQ_TYPE_NONE>,
+                                    <0 0xc5 0 IRQ_TYPE_NONE>,
+                                    <0 0xc6 0 IRQ_TYPE_NONE>,
+                                    <0 0xc7 0 IRQ_TYPE_NONE>,
+                                    <0 0xc8 0 IRQ_TYPE_NONE>,
+                                    <0 0xc9 0 IRQ_TYPE_NONE>,
+                                    <0 0xca 0 IRQ_TYPE_NONE>,
+                                    <0 0xcb 0 IRQ_TYPE_NONE>,
+                                    <0 0xcc 0 IRQ_TYPE_NONE>,
+                                    <0 0xcd 0 IRQ_TYPE_NONE>;
+               };
+       };
+
+       pmi8998_lsid1: pmic@3 {
+               compatible = "qcom,pmi8998", "qcom,spmi-pmic";
+               reg = <0x3 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
index 6d651f314193724e024d099a2f7a9ae32fc26f5f..eedfaf8922e2afbc4d50b91dc13ebdc486033e1a 100644 (file)
@@ -7,6 +7,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include "sdm845.dtsi"
 
 / {
        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 PM8998 S4 because it
+        * is always-on; model it as a fixed regulator.
+        */
+       vreg_s4a_1p8: pm8998-smps4 {
+               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 {
+       pm8998-rpmh-regulators {
+               compatible = "qcom,pm8998-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-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 = <&vph_pwr>;
+               vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
+               vdd-l9-supply = <&vreg_bob>;
+               vdd-l10-l23-l25-supply = <&vreg_bob>;
+               vdd-l13-l19-l21-supply = <&vreg_bob>;
+               vdd-l16-l28-supply = <&vreg_bob>;
+               vdd-l18-l22-supply = <&vreg_bob>;
+               vdd-l20-l24-supply = <&vreg_bob>;
+               vdd-l26-supply = <&vreg_s3a_1p35>;
+               vin-lvs-1-2-supply = <&vreg_s4a_1p8>;
+
+               vreg_s2a_1p125: smps2 {
+                       regulator-min-microvolt = <1100000>;
+                       regulator-max-microvolt = <1100000>;
+               };
+
+               vreg_s3a_1p35: smps3 {
+                       regulator-min-microvolt = <1352000>;
+                       regulator-max-microvolt = <1352000>;
+               };
+
+               vreg_s5a_2p04: smps5 {
+                       regulator-min-microvolt = <1904000>;
+                       regulator-max-microvolt = <2040000>;
+               };
+
+               vreg_s7a_1p025: smps7 {
+                       regulator-min-microvolt = <900000>;
+                       regulator-max-microvolt = <1028000>;
+               };
+
+               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 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               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 = <1856000>;
+                       regulator-max-microvolt = <1856000>;
+                       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 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1248000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l9a_1p8: ldo9 {
+                       regulator-min-microvolt = <1704000>;
+                       regulator-max-microvolt = <2928000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l10a_1p8: ldo10 {
+                       regulator-min-microvolt = <1704000>;
+                       regulator-max-microvolt = <2928000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l11a_1p0: ldo11 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1048000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               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 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l14a_1p88: ldo14 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l15a_1p8: ldo15 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l16a_2p7: ldo16 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2704000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l17a_1p3: ldo17 {
+                       regulator-min-microvolt = <1304000>;
+                       regulator-max-microvolt = <1304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l18a_2p7: ldo18 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l19a_3p0: ldo19 {
+                       regulator-min-microvolt = <2856000>;
+                       regulator-max-microvolt = <3104000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l20a_2p95: ldo20 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l21a_2p95: ldo21 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l22a_2p85: ldo22 {
+                       regulator-min-microvolt = <2864000>;
+                       regulator-max-microvolt = <3312000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l23a_3p3: ldo23 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3312000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdda_qusb_hs0_3p1:
+               vreg_l24a_3p075: ldo24 {
+                       regulator-min-microvolt = <3088000>;
+                       regulator-max-microvolt = <3088000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l25a_3p3: ldo25 {
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3312000>;
+                       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 = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l28a_3p0: ldo28 {
+                       regulator-min-microvolt = <2856000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_lvs1a_1p8: lvs1 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               vreg_lvs2a_1p8: lvs2 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+       };
+
+       pmi8998-rpmh-regulators {
+               compatible = "qcom,pmi8998-rpmh-regulators";
+               qcom,pmic-id = "b";
+
+               vdd-bob-supply = <&vph_pwr>;
+
+               vreg_bob: bob {
+                       regulator-min-microvolt = <3312000>;
+                       regulator-max-microvolt = <3600000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+                       regulator-allow-bypass;
+               };
+       };
+
+       pm8005-rpmh-regulators {
+               compatible = "qcom,pm8005-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>;
+
+               vreg_s3c_0p6: smps3 {
+                       regulator-min-microvolt = <600000>;
+                       regulator-max-microvolt = <600000>;
+               };
+       };
 };
 
 &i2c10 {
        status = "okay";
 };
 
+&usb_1 {
+       status = "okay";
+};
+
+&usb_1_dwc3 {
+       /* Until we have Type C hooked up we'll force this as host. */
+       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 {
+       /*
+        * Though the USB block on SDM845 can support host, there's no vbus
+        * signal for this port on MTP.  Thus (unless you have a non-compliant
+        * hub that works without vbus) the only sensible thing is to force
+        * peripheral mode.
+        */
+       dr_mode = "peripheral";
+};
+
+&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>;
+};
+
 /* PINCTRL - additions to nodes defined in sdm845.dtsi */
 
 &qup_i2c10_default {
index 0c9a2aa6a1b5235fa5307784045d6e14ac036435..b72bdb0a31a571bb4f03da42c4370136fa0c071b 100644 (file)
@@ -5,9 +5,12 @@
  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  */
 
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
 #include <dt-bindings/clock/qcom,gcc-sdm845.h>
 #include <dt-bindings/clock/qcom,rpmh.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy-qcom-qusb2.h>
+#include <dt-bindings/reset/qcom,sdm845-aoss.h>
 #include <dt-bindings/soc/qcom,rpmh-rsc.h>
 
 / {
                hwlocks = <&tcsr_mutex 3>;
        };
 
+       smp2p-cdsp {
+               compatible = "qcom,smp2p";
+               qcom,smem = <94>, <432>;
+
+               interrupts = <GIC_SPI 576 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 6>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <5>;
+
+               cdsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               cdsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-lpass {
+               compatible = "qcom,smp2p";
+               qcom,smem = <443>, <429>;
+
+               interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 10>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <2>;
+
+               adsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               adsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-mpss {
+               compatible = "qcom,smp2p";
+               qcom,smem = <435>, <428>;
+               interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
+               mboxes = <&apss_shared 14>;
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <1>;
+
+               modem_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               modem_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-slpi {
+               compatible = "qcom,smp2p";
+               qcom,smem = <481>, <430>;
+               interrupts = <GIC_SPI 172 IRQ_TYPE_EDGE_RISING>;
+               mboxes = <&apss_shared 26>;
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <3>;
+
+               slpi_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               slpi_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
        psci {
                compatible = "arm,psci-1.0";
                method = "smc";
                        #power-domain-cells = <1>;
                };
 
+               qfprom@784000 {
+                       compatible = "qcom,qfprom";
+                       reg = <0x784000 0x8ff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       qusb2p_hstx_trim: hstx-trim-primary@1eb {
+                               reg = <0x1eb 0x1>;
+                               bits = <1 4>;
+                       };
+
+                       qusb2s_hstx_trim: hstx-trim-secondary@1eb {
+                               reg = <0x1eb 0x2>;
+                               bits = <6 4>;
+                       };
+               };
+
                qupv3_id_0: geniqup@8c0000 {
                        compatible = "qcom,geni-se-qup";
                        reg = <0x8c0000 0x6000>;
                        };
                };
 
+               usb_1_hsphy: phy@88e2000 {
+                       compatible = "qcom,sdm845-qusb2-phy";
+                       reg = <0x88e2000 0x400>;
+                       status = "disabled";
+                       #phy-cells = <0>;
+
+                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                                <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "cfg_ahb", "ref";
+
+                       resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+
+                       nvmem-cells = <&qusb2p_hstx_trim>;
+               };
+
+               usb_2_hsphy: phy@88e3000 {
+                       compatible = "qcom,sdm845-qusb2-phy";
+                       reg = <0x88e3000 0x400>;
+                       status = "disabled";
+                       #phy-cells = <0>;
+
+                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                                <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "cfg_ahb", "ref";
+
+                       resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+
+                       nvmem-cells = <&qusb2s_hstx_trim>;
+               };
+
+               usb_1_qmpphy: phy@88e9000 {
+                       compatible = "qcom,sdm845-qmp-usb3-phy";
+                       reg = <0x88e9000 0x18c>,
+                             <0x88e8000 0x10>;
+                       reg-names = "reg-base", "dp_com";
+                       status = "disabled";
+                       #clock-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+                                <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                                <&gcc GCC_USB3_PRIM_CLKREF_CLK>,
+                                <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
+                       clock-names = "aux", "cfg_ahb", "ref", "com_aux";
+
+                       resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
+                                <&gcc GCC_USB3_PHY_PRIM_BCR>;
+                       reset-names = "phy", "common";
+
+                       usb_1_ssphy: lane@88e9200 {
+                               reg = <0x88e9200 0x128>,
+                                     <0x88e9400 0x200>,
+                                     <0x88e9c00 0x218>,
+                                     <0x88e9a00 0x100>;
+                               #phy-cells = <0>;
+                               clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+                               clock-names = "pipe0";
+                               clock-output-names = "usb3_phy_pipe_clk_src";
+                       };
+               };
+
+               usb_2_qmpphy: phy@88eb000 {
+                       compatible = "qcom,sdm845-qmp-usb3-uni-phy";
+                       reg = <0x88eb000 0x18c>;
+                       status = "disabled";
+                       #clock-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>,
+                                <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                                <&gcc GCC_USB3_SEC_CLKREF_CLK>,
+                                <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>;
+                       clock-names = "aux", "cfg_ahb", "ref", "com_aux";
+
+                       resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>,
+                                <&gcc GCC_USB3_PHY_SEC_BCR>;
+                       reset-names = "phy", "common";
+
+                       usb_2_ssphy: lane@88eb200 {
+                               reg = <0x88eb200 0x128>,
+                                     <0x88eb400 0x1fc>,
+                                     <0x88eb800 0x218>,
+                                     <0x88e9600 0x70>;
+                               #phy-cells = <0>;
+                               clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
+                               clock-names = "pipe0";
+                               clock-output-names = "usb3_uni_phy_pipe_clk_src";
+                       };
+               };
+
+               usb_1: usb@a6f8800 {
+                       compatible = "qcom,sdm845-dwc3", "qcom,dwc3";
+                       reg = <0xa6f8800 0x400>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+                                <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+                                <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+                                <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+                                <&gcc GCC_USB30_PRIM_SLEEP_CLK>;
+                       clock-names = "cfg_noc", "core", "iface", "mock_utmi",
+                                     "sleep";
+
+                       assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+                                         <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+                       assigned-clock-rates = <19200000>, <150000000>;
+
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "hs_phy_irq", "ss_phy_irq",
+                                         "dm_hs_phy_irq", "dp_hs_phy_irq";
+
+                       power-domains = <&gcc USB30_PRIM_GDSC>;
+
+                       resets = <&gcc GCC_USB30_PRIM_BCR>;
+
+                       usb_1_dwc3: dwc3@a600000 {
+                               compatible = "snps,dwc3";
+                               reg = <0xa600000 0xcd00>;
+                               interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                               snps,dis_u2_susphy_quirk;
+                               snps,dis_enblslpm_quirk;
+                               phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+                               phy-names = "usb2-phy", "usb3-phy";
+                       };
+               };
+
+               usb_2: usb@a8f8800 {
+                       compatible = "qcom,sdm845-dwc3", "qcom,dwc3";
+                       reg = <0xa8f8800 0x400>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>,
+                                <&gcc GCC_USB30_SEC_MASTER_CLK>,
+                                <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>,
+                                <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+                                <&gcc GCC_USB30_SEC_SLEEP_CLK>;
+                       clock-names = "cfg_noc", "core", "iface", "mock_utmi",
+                                     "sleep";
+
+                       assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+                                         <&gcc GCC_USB30_SEC_MASTER_CLK>;
+                       assigned-clock-rates = <19200000>, <150000000>;
+
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "hs_phy_irq", "ss_phy_irq",
+                                         "dm_hs_phy_irq", "dp_hs_phy_irq";
+
+                       power-domains = <&gcc USB30_SEC_GDSC>;
+
+                       resets = <&gcc GCC_USB30_SEC_BCR>;
+
+                       usb_2_dwc3: dwc3@a800000 {
+                               compatible = "snps,dwc3";
+                               reg = <0xa800000 0xcd00>;
+                               interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                               snps,dis_u2_susphy_quirk;
+                               snps,dis_enblslpm_quirk;
+                               phys = <&usb_2_hsphy>, <&usb_2_ssphy>;
+                               phy-names = "usb2-phy", "usb3-phy";
+                       };
+               };
+
+               dispcc: clock-controller@af00000 {
+                       compatible = "qcom,sdm845-dispcc";
+                       reg = <0xaf00000 0x10000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+               };
+
                tsens0: thermal-sensor@c263000 {
                        compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
                        reg = <0xc263000 0x1ff>, /* TM */
                        #thermal-sensor-cells = <1>;
                };
 
+               aoss_reset: reset-controller@c2a0000 {
+                       compatible = "qcom,sdm845-aoss-cc";
+                       reg = <0xc2a0000 0x31000>;
+                       #reset-cells = <1>;
+               };
+
                spmi_bus: spmi@c440000 {
                        compatible = "qcom,spmi-pmic-arb";
                        reg = <0xc440000 0x1100>,
index 9e2394bc3c6271ef264db5d8209045af119dbcf2..a8ce6594342d993de8f19211a536e351d6166d57 100644 (file)
@@ -8,6 +8,8 @@ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf.dtb
 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb r8a77965-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
 dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb r8a77970-v3msk.dtb
 dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb r8a77980-v3hsk.dtb
 dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
new file mode 100644 (file)
index 0000000..012cbb6
--- /dev/null
@@ -0,0 +1,1663 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the r8a774a1 SoC
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/ {
+       compatible = "renesas,r8a774a1";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+               i2c7 = &i2c_dvfs;
+       };
+
+       /*
+        * The external audio clocks are configured as 0 Hz fixed frequency
+        * clocks by default.
+        * Boards that provide audio clocks should override them.
+        */
+       audio_clk_a: audio_clk_a {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_b: audio_clk_b {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       audio_clk_c: audio_clk_c {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       /* External CAN clock - to be overridden by boards that provide it */
+       can_clk: can {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               a57_0: cpu@0 {
+                       compatible = "arm,cortex-a57", "arm,armv8";
+                       reg = <0x0>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 0>;
+                       next-level-cache = <&L2_CA57>;
+                       enable-method = "psci";
+                       clocks = <&cpg CPG_CORE 0>;
+               };
+
+               a57_1: cpu@1 {
+                       compatible = "arm,cortex-a57", "arm,armv8";
+                       reg = <0x1>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 1>;
+                       next-level-cache = <&L2_CA57>;
+                       enable-method = "psci";
+                       clocks = <&cpg CPG_CORE 0>;
+               };
+
+               a53_0: cpu@100 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x100>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 5>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       clocks =<&cpg CPG_CORE 1>;
+               };
+
+               a53_1: cpu@101 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x101>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 6>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       clocks =<&cpg CPG_CORE 1>;
+               };
+
+               a53_2: cpu@102 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x102>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 7>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       clocks =<&cpg CPG_CORE 1>;
+               };
+
+               a53_3: cpu@103 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x103>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 8>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+                       clocks =<&cpg CPG_CORE 1>;
+               };
+
+               L2_CA57: cache-controller-0 {
+                       compatible = "cache";
+                       power-domains = <&sysc 12>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               L2_CA53: cache-controller-1 {
+                       compatible = "cache";
+                       power-domains = <&sysc 21>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+       };
+
+       extal_clk: extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       extalr_clk: extalr {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               /* This value must be overridden by the board */
+               clock-frequency = <0>;
+       };
+
+       /* External PCIe clock - can be overridden by the board */
+       pcie_bus_clk: pcie_bus {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       pmu_a53 {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>;
+       };
+
+       pmu_a57 {
+               compatible = "arm,cortex-a57-pmu";
+               interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a57_0>, <&a57_1>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0", "arm,psci-0.2";
+               method = "smc";
+       };
+
+       /* External SCIF clock - to be overridden by boards that provide it */
+       scif_clk: scif {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               interrupt-parent = <&gic>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               rwdt: watchdog@e6020000 {
+                       compatible = "renesas,r8a774a1-wdt",
+                                    "renesas,rcar-gen3-wdt";
+                       reg = <0 0xe6020000 0 0x0c>;
+                       clocks = <&cpg CPG_MOD 402>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 402>;
+                       status = "disabled";
+               };
+
+               gpio0: gpio@e6050000 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6050000 0 0x50>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 0 16>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 912>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 912>;
+               };
+
+               gpio1: gpio@e6051000 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6051000 0 0x50>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 32 29>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 911>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 911>;
+               };
+
+               gpio2: gpio@e6052000 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6052000 0 0x50>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 64 15>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 910>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 910>;
+               };
+
+               gpio3: gpio@e6053000 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6053000 0 0x50>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 96 16>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 909>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 909>;
+               };
+
+               gpio4: gpio@e6054000 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6054000 0 0x50>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 128 18>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 908>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 908>;
+               };
+
+               gpio5: gpio@e6055000 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055000 0 0x50>;
+                       interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 160 26>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 907>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 907>;
+               };
+
+               gpio6: gpio@e6055400 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055400 0 0x50>;
+                       interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 192 32>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 906>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 906>;
+               };
+
+               gpio7: gpio@e6055800 {
+                       compatible = "renesas,gpio-r8a774a1",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055800 0 0x50>;
+                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 224 4>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 905>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 905>;
+               };
+
+               pfc: pin-controller@e6060000 {
+                       compatible = "renesas,pfc-r8a774a1";
+                       reg = <0 0xe6060000 0 0x50c>;
+               };
+
+               cpg: clock-controller@e6150000 {
+                       compatible = "renesas,r8a774a1-cpg-mssr";
+                       reg = <0 0xe6150000 0 0x0bb0>;
+                       clocks = <&extal_clk>, <&extalr_clk>;
+                       clock-names = "extal", "extalr";
+                       #clock-cells = <2>;
+                       #power-domain-cells = <0>;
+                       #reset-cells = <1>;
+               };
+
+               rst: reset-controller@e6160000 {
+                       compatible = "renesas,r8a774a1-rst";
+                       reg = <0 0xe6160000 0 0x018c>;
+               };
+
+               sysc: system-controller@e6180000 {
+                       compatible = "renesas,r8a774a1-sysc";
+                       reg = <0 0xe6180000 0 0x0400>;
+                       #power-domain-cells = <1>;
+               };
+
+               tsc: thermal@e6198000 {
+                       compatible = "renesas,r8a774a1-thermal";
+                       reg = <0 0xe6198000 0 0x100>,
+                             <0 0xe61a0000 0 0x100>,
+                             <0 0xe61a8000 0 0x100>;
+                       interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 522>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 522>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               intc_ex: interrupt-controller@e61c0000 {
+                       compatible = "renesas,intc-ex-r8a774a1", "renesas,irqc";
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <0 0xe61c0000 0 0x200>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 407>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 407>;
+               };
+
+               i2c0: i2c@e6500000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6500000 0 0x40>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 931>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 931>;
+                       dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+                              <&dmac2 0x91>, <&dmac2 0x90>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@e6508000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6508000 0 0x40>;
+                       interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 930>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 930>;
+                       dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+                              <&dmac2 0x93>, <&dmac2 0x92>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@e6510000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6510000 0 0x40>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 929>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 929>;
+                       dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+                              <&dmac2 0x95>, <&dmac2 0x94>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@e66d0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d0000 0 0x40>;
+                       interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 928>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 928>;
+                       dmas = <&dmac0 0x97>, <&dmac0 0x96>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@e66d8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d8000 0 0x40>;
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 927>;
+                       dmas = <&dmac0 0x99>, <&dmac0 0x98>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@e66e0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e0000 0 0x40>;
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 919>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 919>;
+                       dmas = <&dmac0 0x9b>, <&dmac0 0x9a>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c6: i2c@e66e8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a774a1",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e8000 0 0x40>;
+                       interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 918>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 918>;
+                       dmas = <&dmac0 0x9d>, <&dmac0 0x9c>;
+                       dma-names = "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c_dvfs: i2c@e60b0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,iic-r8a774a1",
+                                    "renesas,rcar-gen3-iic",
+                                    "renesas,rmobile-iic";
+                       reg = <0 0xe60b0000 0 0x425>;
+                       interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 926>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 926>;
+                       dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
+               };
+
+               hscif0: serial@e6540000 {
+                       compatible = "renesas,hscif-r8a774a1",
+                                    "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 19>,
+                                <&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 32>;
+                       resets = <&cpg 520>;
+                       status = "disabled";
+               };
+
+               hscif1: serial@e6550000 {
+                       compatible = "renesas,hscif-r8a774a1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6550000 0 0x60>;
+                       interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 519>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+                              <&dmac2 0x33>, <&dmac2 0x32>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 519>;
+                       status = "disabled";
+               };
+
+               hscif2: serial@e6560000 {
+                       compatible = "renesas,hscif-r8a774a1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6560000 0 0x60>;
+                       interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 518>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+                              <&dmac2 0x35>, <&dmac2 0x34>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 518>;
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a774a1",
+                                    "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 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 517>;
+                       status = "disabled";
+               };
+
+               hscif4: serial@e66b0000 {
+                       compatible = "renesas,hscif-r8a774a1",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66b0000 0 0x60>;
+                       interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 516>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 516>;
+                       status = "disabled";
+               };
+
+               hsusb: usb@e6590000 {
+                       compatible = "renesas,usbhs-r8a774a1",
+                                    "renesas,rcar-gen3-usbhs";
+                       reg = <0 0xe6590000 0 0x100>;
+                       interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 704>;
+                       dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
+                              <&usb_dmac1 0>, <&usb_dmac1 1>;
+                       dma-names = "ch0", "ch1", "ch2", "ch3";
+                       renesas,buswait = <11>;
+                       phys = <&usb2_phy0>;
+                       phy-names = "usb";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 704>;
+                       status = "disabled";
+               };
+
+               usb_dmac0: dma-controller@e65a0000 {
+                       compatible = "renesas,r8a774a1-usb-dmac",
+                                    "renesas,usb-dmac";
+                       reg = <0 0xe65a0000 0 0x100>;
+                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1";
+                       clocks = <&cpg CPG_MOD 330>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 330>;
+                       #dma-cells = <1>;
+                       dma-channels = <2>;
+               };
+
+               usb_dmac1: dma-controller@e65b0000 {
+                       compatible = "renesas,r8a774a1-usb-dmac",
+                                    "renesas,usb-dmac";
+                       reg = <0 0xe65b0000 0 0x100>;
+                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1";
+                       clocks = <&cpg CPG_MOD 331>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 331>;
+                       #dma-cells = <1>;
+                       dma-channels = <2>;
+               };
+
+               usb3_phy0: usb-phy@e65ee000 {
+                       compatible = "renesas,r8a774a1-usb3-phy",
+                                    "renesas,rcar-gen3-usb3-phy";
+                       reg = <0 0xe65ee000 0 0x90>;
+                       clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>,
+                                <&usb_extal_clk>;
+                       clock-names = "usb3-if", "usb3s_clk", "usb_extal";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 328>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+
+               dmac0: dma-controller@e6700000 {
+                       compatible = "renesas,dmac-r8a774a1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe6700000 0 0x10000>;
+                       interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 219>;
+                       clock-names = "fck";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 219>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               dmac1: dma-controller@e7300000 {
+                       compatible = "renesas,dmac-r8a774a1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe7300000 0 0x10000>;
+                       interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 218>;
+                       clock-names = "fck";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 218>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               dmac2: dma-controller@e7310000 {
+                       compatible = "renesas,dmac-r8a774a1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe7310000 0 0x10000>;
+                       interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 217>;
+                       clock-names = "fck";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 217>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               ipmmu_ds0: mmu@e6740000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xe6740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ds1: mmu@e7740000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xe7740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 1>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_hc: mmu@e6570000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xe6570000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 2>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: mmu@e67b0000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xe67b0000 0 0x1000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mp: mmu@ec670000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xec670000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 4>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_pv0: mmu@fd800000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xfd800000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 5>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_pv1: mmu@fd950000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xfd950000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 6>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc0: mmu@fe6b0000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xfe6b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 8>;
+                       power-domains = <&sysc 14>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: mmu@febd0000 {
+                       compatible = "renesas,ipmmu-r8a774a1";
+                       reg = <0 0xfebd0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 9>;
+                       power-domains = <&sysc 32>;
+                       #iommu-cells = <1>;
+               };
+
+               avb: ethernet@e6800000 {
+                       compatible = "renesas,etheravb-r8a774a1",
+                                    "renesas,etheravb-rcar-gen3";
+                       reg = <0 0xe6800000 0 0x800>;
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1", "ch2", "ch3",
+                                         "ch4", "ch5", "ch6", "ch7",
+                                         "ch8", "ch9", "ch10", "ch11",
+                                         "ch12", "ch13", "ch14", "ch15",
+                                         "ch16", "ch17", "ch18", "ch19",
+                                         "ch20", "ch21", "ch22", "ch23",
+                                         "ch24";
+                       clocks = <&cpg CPG_MOD 812>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 812>;
+                       phy-mode = "rgmii";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               pwm0: pwm@e6e30000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e30000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               pwm1: pwm@e6e31000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e31000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               pwm2: pwm@e6e32000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e32000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               pwm3: pwm@e6e33000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e33000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               pwm4: pwm@e6e34000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e34000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               pwm5: pwm@e6e35000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e35000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               pwm6: pwm@e6e36000 {
+                       compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
+                       reg = <0 0xe6e36000 0 0x8>;
+                       #pwm-cells = <2>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       resets = <&cpg 523>;
+                       power-domains = <&sysc 32>;
+                       status = "disabled";
+               };
+
+               scif0: serial@e6e60000 {
+                       compatible = "renesas,scif-r8a774a1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e60000 0 0x40>;
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 207>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+                              <&dmac2 0x51>, <&dmac2 0x50>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 207>;
+                       status = "disabled";
+               };
+
+               scif1: serial@e6e68000 {
+                       compatible = "renesas,scif-r8a774a1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e68000 0 0x40>;
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 206>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+                              <&dmac2 0x53>, <&dmac2 0x52>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 206>;
+                       status = "disabled";
+               };
+
+               scif2: serial@e6e88000 {
+                       compatible = "renesas,scif-r8a774a1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e88000 0 0x40>;
+                       interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 310>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 310>;
+                       status = "disabled";
+               };
+
+               scif3: serial@e6c50000 {
+                       compatible = "renesas,scif-r8a774a1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6c50000 0 0x40>;
+                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 204>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 204>;
+                       status = "disabled";
+               };
+
+               scif4: serial@e6c40000 {
+                       compatible = "renesas,scif-r8a774a1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6c40000 0 0x40>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 203>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 203>;
+                       status = "disabled";
+               };
+
+               scif5: serial@e6f30000 {
+                       compatible = "renesas,scif-r8a774a1",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6f30000 0 0x40>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 202>,
+                                <&cpg CPG_CORE 19>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+                              <&dmac2 0x5b>, <&dmac2 0x5a>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 202>;
+                       status = "disabled";
+               };
+
+               msiof0: spi@e6e90000 {
+                       compatible = "renesas,msiof-r8a774a1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6e90000 0 0x0064>;
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 211>;
+                       dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+                              <&dmac2 0x41>, <&dmac2 0x40>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 211>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof1: spi@e6ea0000 {
+                       compatible = "renesas,msiof-r8a774a1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6ea0000 0 0x0064>;
+                       interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 210>;
+                       dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+                              <&dmac2 0x43>, <&dmac2 0x42>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 210>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof2: spi@e6c00000 {
+                       compatible = "renesas,msiof-r8a774a1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c00000 0 0x0064>;
+                       interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 209>;
+                       dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 209>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof3: spi@e6c10000 {
+                       compatible = "renesas,msiof-r8a774a1",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c10000 0 0x0064>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 208>;
+                       dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 208>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               rcar_sound: sound@ec500000 {
+                       /*
+                        * #sound-dai-cells is required
+                        *
+                        * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+                        * Multi  DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+                        */
+                       /*
+                        * #clock-cells is required for audio_clkout0/1/2/3
+                        *
+                        * clkout       : #clock-cells = <0>;   <&rcar_sound>;
+                        * clkout0/1/2/3: #clock-cells = <1>;   <&rcar_sound N>;
+                        */
+                       compatible =  "renesas,rcar_sound-r8a774a1", "renesas,rcar_sound-gen3";
+                       reg =   <0 0xec500000 0 0x1000>, /* SCU */
+                               <0 0xec5a0000 0 0x100>,  /* ADG */
+                               <0 0xec540000 0 0x1000>, /* SSIU */
+                               <0 0xec541000 0 0x280>,  /* SSI */
+                               <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+                       reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+                       clocks = <&cpg CPG_MOD 1005>,
+                                <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+                                <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+                                <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+                                <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+                                <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+                                <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+                                <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+                                <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+                                <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+                                <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+                                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                                <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+                                <&audio_clk_a>, <&audio_clk_b>,
+                                <&audio_clk_c>,
+                                <&cpg CPG_CORE 10>;
+                       clock-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0",
+                                     "src.9", "src.8", "src.7", "src.6",
+                                     "src.5", "src.4", "src.3", "src.2",
+                                     "src.1", "src.0",
+                                     "mix.1", "mix.0",
+                                     "ctu.1", "ctu.0",
+                                     "dvc.0", "dvc.1",
+                                     "clk_a", "clk_b", "clk_c", "clk_i";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 1005>,
+                                <&cpg 1006>, <&cpg 1007>,
+                                <&cpg 1008>, <&cpg 1009>,
+                                <&cpg 1010>, <&cpg 1011>,
+                                <&cpg 1012>, <&cpg 1013>,
+                                <&cpg 1014>, <&cpg 1015>;
+                       reset-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0";
+                       status = "disabled";
+
+                       rcar_sound,dvc {
+                               dvc0: dvc-0 {
+                                       dmas = <&audma1 0xbc>;
+                                       dma-names = "tx";
+                               };
+                               dvc1: dvc-1 {
+                                       dmas = <&audma1 0xbe>;
+                                       dma-names = "tx";
+                               };
+                       };
+
+                       rcar_sound,mix {
+                               mix0: mix-0 { };
+                               mix1: mix-1 { };
+                       };
+
+                       rcar_sound,ctu {
+                               ctu00: ctu-0 { };
+                               ctu01: ctu-1 { };
+                               ctu02: ctu-2 { };
+                               ctu03: ctu-3 { };
+                               ctu10: ctu-4 { };
+                               ctu11: ctu-5 { };
+                               ctu12: ctu-6 { };
+                               ctu13: ctu-7 { };
+                       };
+
+                       rcar_sound,src {
+                               src0: src-0 {
+                                       interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x85>, <&audma1 0x9a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src1: src-1 {
+                                       interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x87>, <&audma1 0x9c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src2: src-2 {
+                                       interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x89>, <&audma1 0x9e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src3: src-3 {
+                                       interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src4: src-4 {
+                                       interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src5: src-5 {
+                                       interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src6: src-6 {
+                                       interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x91>, <&audma1 0xb4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src7: src-7 {
+                                       interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x93>, <&audma1 0xb6>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src8: src-8 {
+                                       interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x95>, <&audma1 0xb8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src9: src-9 {
+                                       interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x97>, <&audma1 0xba>;
+                                       dma-names = "rx", "tx";
+                               };
+                       };
+
+                       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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                       };
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               port@0 {
+                                       reg = <0>;
+                               };
+                               port@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               audma0: dma-controller@ec700000 {
+                       compatible = "renesas,dmac-r8a774a1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xec700000 0 0x10000>;
+                       interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 502>;
+                       clock-names = "fck";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 502>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               audma1: dma-controller@ec720000 {
+                       compatible = "renesas,dmac-r8a774a1",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xec720000 0 0x10000>;
+                       interrupts = <GIC_SPI 351 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
+                                     GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 501>;
+                       clock-names = "fck";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 501>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               xhci0: usb@ee000000 {
+                       compatible = "renesas,xhci-r8a774a1",
+                                    "renesas,rcar-gen3-xhci";
+                       reg = <0 0xee000000 0 0xc00>;
+                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 328>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 328>;
+                       status = "disabled";
+               };
+
+               usb3_peri0: usb@ee020000 {
+                       compatible = "renesas,r8a774a1-usb3-peri",
+                                    "renesas,rcar-gen3-usb3-peri";
+                       reg = <0 0xee020000 0 0x400>;
+                       interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 328>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 328>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@ee080000 {
+                       compatible = "generic-ohci";
+                       reg = <0 0xee080000 0 0x100>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>;
+                       phys = <&usb2_phy0>;
+                       phy-names = "usb";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 703>;
+                       status = "disabled";
+               };
+
+               ohci1: usb@ee0a0000 {
+                       compatible = "generic-ohci";
+                       reg = <0 0xee0a0000 0 0x100>;
+                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 702>;
+                       phys = <&usb2_phy1>;
+                       phy-names = "usb";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 702>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@ee080100 {
+                       compatible = "generic-ehci";
+                       reg = <0 0xee080100 0 0x100>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>;
+                       phys = <&usb2_phy0>;
+                       phy-names = "usb";
+                       companion = <&ohci0>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 703>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@ee0a0100 {
+                       compatible = "generic-ehci";
+                       reg = <0 0xee0a0100 0 0x100>;
+                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 702>;
+                       phys = <&usb2_phy1>;
+                       phy-names = "usb";
+                       companion = <&ohci1>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 702>;
+                       status = "disabled";
+               };
+
+               usb2_phy0: usb-phy@ee080200 {
+                       compatible = "renesas,usb2-phy-r8a774a1",
+                                    "renesas,rcar-gen3-usb2-phy";
+                       reg = <0 0xee080200 0 0x700>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 703>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+
+               usb2_phy1: usb-phy@ee0a0200 {
+                       compatible = "renesas,usb2-phy-r8a774a1",
+                                    "renesas,rcar-gen3-usb2-phy";
+                       reg = <0 0xee0a0200 0 0x700>;
+                       clocks = <&cpg CPG_MOD 702>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 702>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+
+               sdhi0: sd@ee100000 {
+                       compatible = "renesas,sdhi-r8a774a1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee100000 0 0x2000>;
+                       interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 314>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 314>;
+                       status = "disabled";
+               };
+
+               sdhi1: sd@ee120000 {
+                       compatible = "renesas,sdhi-r8a774a1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee120000 0 0x2000>;
+                       interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 313>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 313>;
+                       status = "disabled";
+               };
+
+               sdhi2: sd@ee140000 {
+                       compatible = "renesas,sdhi-r8a774a1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee140000 0 0x2000>;
+                       interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 312>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 312>;
+                       status = "disabled";
+               };
+
+               sdhi3: sd@ee160000 {
+                       compatible = "renesas,sdhi-r8a774a1",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee160000 0 0x2000>;
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 311>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 311>;
+                       status = "disabled";
+               };
+
+               gic: interrupt-controller@f1010000 {
+                       compatible = "arm,gic-400";
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+                       interrupt-controller;
+                       reg = <0x0 0xf1010000 0 0x1000>,
+                             <0x0 0xf1020000 0 0x20000>,
+                             <0x0 0xf1040000 0 0x20000>,
+                             <0x0 0xf1060000 0 0x20000>;
+                       interrupts = <GIC_PPI 9
+                                       (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>;
+                       clocks = <&cpg CPG_MOD 408>;
+                       clock-names = "clk";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 408>;
+               };
+
+               fcpf0: fcp@fe950000 {
+                       compatible = "renesas,fcpf";
+                       reg = <0 0xfe950000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 615>;
+                       power-domains = <&sysc 14>;
+                       resets = <&cpg 615>;
+               };
+
+               fcpvb0: fcp@fe96f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe96f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 607>;
+                       power-domains = <&sysc 14>;
+                       resets = <&cpg 607>;
+               };
+
+               fcpvd0: fcp@fea27000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea27000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 603>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 603>;
+                       iommus = <&ipmmu_vi0 8>;
+               };
+
+               fcpvd1: fcp@fea2f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea2f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 602>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 602>;
+                       iommus = <&ipmmu_vi0 9>;
+               };
+
+               fcpvd2: fcp@fea37000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea37000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 601>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 601>;
+                       iommus = <&ipmmu_vi0 10>;
+               };
+
+               fcpvi0: fcp@fe9af000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe9af000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 611>;
+                       power-domains = <&sysc 14>;
+                       resets = <&cpg 611>;
+                       iommus = <&ipmmu_vc0 19>;
+               };
+
+               prr: chipid@fff00044 {
+                       compatible = "renesas,prr";
+                       reg = <0 0xfff00044 0 4>;
+               };
+       };
+
+       thermal-zones {
+               sensor_thermal1: sensor-thermal1 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 0>;
+
+                       trips {
+                               sensor1_crit: sensor1-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               sensor_thermal2: sensor-thermal2 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 1>;
+
+                       trips {
+                               sensor2_crit: sensor2-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+               };
+
+               sensor_thermal3: sensor-thermal3 {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 2>;
+
+                       trips {
+                               sensor3_crit: sensor3-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       /* External USB clocks - can be overridden by the board */
+       usb3s0_clk: usb3s0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       usb_extal_clk: usb_extal {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+};
index 6b5fa91f1d5d33d38a80a8d39ffb0f5baf92d764..0895503b69d0b71bcdf0f47d64d705ae38326049 100644 (file)
                 <&cpg CPG_MOD 723>,
                 <&cpg CPG_MOD 722>,
                 <&cpg CPG_MOD 721>,
-                <&cpg CPG_MOD 727>,
                 <&versaclock5 1>,
                 <&x21_clk>,
                 <&x22_clk>,
                 <&versaclock5 2>;
-       clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0",
+       clock-names = "du.0", "du.1", "du.2", "du.3",
                      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
 };
 
index 7b2fbaec9aef8d71fb1b9fbb04f0f8b1630b0bab..0fb84c219b2feaca91ebcc6a4be7651658997af6 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7795 ES1.x SoC
+ * Device Tree Source for the R-Car H3 (R8A77950) ES1.x SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
                port@1 {
                        vin0csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin0>;
+                               remote-endpoint = <&csi21vin0>;
                        };
                };
        };
                port@1 {
                        vin1csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin1>;
+                               remote-endpoint = <&csi21vin1>;
                        };
                };
        };
                port@1 {
                        vin2csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin2>;
+                               remote-endpoint = <&csi21vin2>;
                        };
                };
        };
                port@1 {
                        vin3csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin3>;
+                               remote-endpoint = <&csi21vin3>;
                        };
                };
        };
                port@1 {
                        vin4csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin4>;
+                               remote-endpoint = <&csi21vin4>;
                        };
                };
        };
                port@1 {
                        vin5csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin5>;
+                               remote-endpoint = <&csi21vin5>;
                        };
                };
        };
                port@1 {
                        vin6csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin6>;
+                               remote-endpoint = <&csi21vin6>;
                        };
                };
        };
                port@1 {
                        vin7csi21: endpoint@1 {
                                reg = <1>;
-                               remote-endpoint= <&csi21vin7>;
+                               remote-endpoint = <&csi21vin7>;
                        };
                };
        };
index df50bf46406e6e904f31541e1767a1dfe8b4b25a..54515eaf0310f1727f4e695196b74b5bd7354645 100644 (file)
                 <&cpg CPG_MOD 723>,
                 <&cpg CPG_MOD 722>,
                 <&cpg CPG_MOD 721>,
-                <&cpg CPG_MOD 727>,
                 <&versaclock5 1>,
                 <&versaclock5 3>,
                 <&versaclock5 4>,
                 <&versaclock5 2>;
-       clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0",
+       clock-names = "du.0", "du.1", "du.2", "du.3",
                      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
 };
index 446822f5751c77e8a78fe599c8f818a7db8d51f5..1620e8d8dacc3c561f0a8dde96877712bfe79547 100644 (file)
                 <&cpg CPG_MOD 723>,
                 <&cpg CPG_MOD 722>,
                 <&cpg CPG_MOD 721>,
-                <&cpg CPG_MOD 727>,
                 <&versaclock5 1>,
                 <&x21_clk>,
                 <&x22_clk>,
                 <&versaclock5 2>;
-       clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0",
+       clock-names = "du.0", "du.1", "du.2", "du.3",
                      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
 };
 
index 8ded64d0a4d56a82b7368b94dcaf285f4cb72e9c..cf08a119eec093cdf635fbd43998c58750accddc 100644 (file)
                 <&cpg CPG_MOD 723>,
                 <&cpg CPG_MOD 722>,
                 <&cpg CPG_MOD 721>,
-                <&cpg CPG_MOD 727>,
                 <&versaclock6 1>,
                 <&x21_clk>,
                 <&x22_clk>,
                 <&versaclock6 2>;
-       clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0",
+       clock-names = "du.0", "du.1", "du.2", "du.3",
                      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
 };
 
        };
 };
 
+&pca9654 {
+       pcie_sata_switch {
+               gpio-hog;
+               gpios = <7 GPIO_ACTIVE_HIGH>;
+               output-low; /* enable SATA by default */
+               line-name = "PCIE/SATA switch";
+       };
+};
+
 &pfc {
        usb2_pins: usb2 {
                groups = "usb2";
        };
 };
 
+/* SW12-7 must be set 'Off' (MD12 set to 1) which is not the default! */
+&sata {
+       status = "okay";
+};
+
 &usb2_phy2 {
        pinctrl-0 = <&usb2_pins>;
        pinctrl-names = "default";
index fb9d08ad7659da7938b8cffecba6b41ada7b07dc..b5f2273caca4ded1e6bc0cfe3a5e52b97a3fd854 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7795 SoC
+ * Device Tree Source for the R-Car H3 (R8A77950) SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
                        power-domains = <&sysc R8A7795_PD_CA57_CPU0>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        #cooling-cells = <2>;
                };
                        power-domains = <&sysc R8A7795_PD_CA57_CPU1>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        #cooling-cells = <2>;
                };
                        power-domains = <&sysc R8A7795_PD_CA57_CPU2>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        #cooling-cells = <2>;
                };
                        power-domains = <&sysc R8A7795_PD_CA57_CPU3>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        #cooling-cells = <2>;
                };
                        power-domains = <&sysc R8A7795_PD_CA53_CPU0>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7795_PD_CA53_CPU1>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7795_PD_CA53_CPU2>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7795_PD_CA53_CPU3>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7795_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7795_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 522>;
                        #thermal-sensor-cells = <1>;
-                       status = "okay";
                };
 
                intc_ex: interrupt-controller@e61c0000 {
                        status = "disabled";
                };
 
-               arm_cc630p: crypto@e6601000 {
-                       compatible = "arm,cryptocell-630p-ree";
-                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-                       reg = <0x0 0xe6601000 0 0x1000>;
-                       clocks = <&cpg CPG_MOD 229>;
-                       resets = <&cpg 229>;
-                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-               };
-
                i2c3: i2c@e66d0000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                                     "renesas,rcar-gen3-usbhs";
                        reg = <0 0xe6590000 0 0x100>;
                        interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 704>;
+                       clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>;
                        dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
                               <&usb_dmac1 0>, <&usb_dmac1 1>;
                        dma-names = "ch0", "ch1", "ch2", "ch3";
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 704>;
+                       resets = <&cpg 704>, <&cpg 703>;
                        status = "disabled";
                };
 
                                     "renesas,rcar-gen3-usbhs";
                        reg = <0 0xe659c000 0 0x100>;
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 705>;
+                       clocks = <&cpg CPG_MOD 705>, <&cpg CPG_MOD 700>;
                        dmas = <&usb_dmac2 0>, <&usb_dmac2 1>,
                               <&usb_dmac3 0>, <&usb_dmac3 1>;
                        dma-names = "ch0", "ch1", "ch2", "ch3";
                        phys = <&usb2_phy3>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 705>;
+                       resets = <&cpg 705>, <&cpg 700>;
                        status = "disabled";
                };
 
                        status = "disabled";
                };
 
+               arm_cc630p: crypto@e6601000 {
+                       compatible = "arm,cryptocell-630p-ree";
+                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                       reg = <0x0 0xe6601000 0 0x1000>;
+                       clocks = <&cpg CPG_MOD 229>;
+                       resets = <&cpg 229>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+               };
+
                dmac0: dma-controller@e6700000 {
                        compatible = "renesas,dmac-r8a7795",
                                     "renesas,rcar-dmac";
 
                                        vin0csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin0>;
+                                               remote-endpoint = <&csi20vin0>;
                                        };
                                        vin0csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin0>;
+                                               remote-endpoint = <&csi40vin0>;
                                        };
                                };
                        };
 
                                        vin1csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin1>;
+                                               remote-endpoint = <&csi20vin1>;
                                        };
                                        vin1csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin1>;
+                                               remote-endpoint = <&csi40vin1>;
                                        };
                                };
                        };
 
                                        vin2csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin2>;
+                                               remote-endpoint = <&csi20vin2>;
                                        };
                                        vin2csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin2>;
+                                               remote-endpoint = <&csi40vin2>;
                                        };
                                };
                        };
 
                                        vin3csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin3>;
+                                               remote-endpoint = <&csi20vin3>;
                                        };
                                        vin3csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin3>;
+                                               remote-endpoint = <&csi40vin3>;
                                        };
                                };
                        };
 
                                        vin4csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin4>;
+                                               remote-endpoint = <&csi20vin4>;
                                        };
                                        vin4csi41: endpoint@3 {
                                                reg = <3>;
-                                               remote-endpoint= <&csi41vin4>;
+                                               remote-endpoint = <&csi41vin4>;
                                        };
                                };
                        };
 
                                        vin5csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin5>;
+                                               remote-endpoint = <&csi20vin5>;
                                        };
                                        vin5csi41: endpoint@3 {
                                                reg = <3>;
-                                               remote-endpoint= <&csi41vin5>;
+                                               remote-endpoint = <&csi41vin5>;
                                        };
                                };
                        };
 
                                        vin6csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin6>;
+                                               remote-endpoint = <&csi20vin6>;
                                        };
                                        vin6csi41: endpoint@3 {
                                                reg = <3>;
-                                               remote-endpoint= <&csi41vin6>;
+                                               remote-endpoint = <&csi41vin6>;
                                        };
                                };
                        };
 
                                        vin7csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin7>;
+                                               remote-endpoint = <&csi20vin7>;
                                        };
                                        vin7csi41: endpoint@3 {
                                                reg = <3>;
-                                               remote-endpoint= <&csi41vin7>;
+                                               remote-endpoint = <&csi41vin7>;
                                        };
                                };
                        };
                        compatible = "generic-ohci";
                        reg = <0 0xee080000 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        compatible = "generic-ohci";
                        reg = <0 0xee0e0000 0 0x100>;
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 700>;
+                       clocks = <&cpg CPG_MOD 700>, <&cpg CPG_MOD 705>;
                        phys = <&usb2_phy3>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 700>;
+                       resets = <&cpg 700>, <&cpg 705>;
                        status = "disabled";
                };
 
                        compatible = "generic-ehci";
                        reg = <0 0xee080100 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        companion = <&ohci0>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        compatible = "generic-ehci";
                        reg = <0 0xee0e0100 0 0x100>;
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 700>;
+                       clocks = <&cpg CPG_MOD 700>, <&cpg CPG_MOD 705>;
                        phys = <&usb2_phy3>;
                        phy-names = "usb";
                        companion = <&ohci3>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 700>;
+                       resets = <&cpg 700>, <&cpg 705>;
                        status = "disabled";
                };
 
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee080200 0 0x700>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee0e0200 0 0x700>;
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 700>;
+                       clocks = <&cpg CPG_MOD 700>, <&cpg CPG_MOD 705>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 700>;
+                       resets = <&cpg 700>, <&cpg 705>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
 
                du: display@feb00000 {
                        compatible = "renesas,du-r8a7795";
-                       reg = <0 0xfeb00000 0 0x80000>,
-                             <0 0xfeb90000 0 0x14>;
-                       reg-names = "du", "lvds.0";
+                       reg = <0 0xfeb00000 0 0x80000>;
                        interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
                        clocks = <&cpg CPG_MOD 724>,
                                 <&cpg CPG_MOD 723>,
                                 <&cpg CPG_MOD 722>,
-                                <&cpg CPG_MOD 721>,
-                                <&cpg CPG_MOD 727>;
-                       clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0";
+                                <&cpg CPG_MOD 721>;
+                       clock-names = "du.0", "du.1", "du.2", "du.3";
                        vsps = <&vspd0 0 &vspd1 0 &vspd2 0 &vspd0 1>;
                        status = "disabled";
 
                                port@3 {
                                        reg = <3>;
                                        du_out_lvds0: endpoint {
+                                               remote-endpoint = <&lvds0_in>;
+                                       };
+                               };
+                       };
+               };
+
+               lvds0: lvds@feb90000 {
+                       compatible = "renesas,r8a7795-lvds";
+                       reg = <0 0xfeb90000 0 0x14>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       resets = <&cpg 727>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds0_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds0>;
+                                       };
+                               };
+                               port@1 {
+                                       reg = <1>;
+                                       lvds0_out: endpoint {
                                        };
                                };
                        };
index cbd8acbf537e634ab461bd03c9459203440bfbd0..9e4594c27fa6c5534d074eae609ece05eec8538e 100644 (file)
        clocks = <&cpg CPG_MOD 724>,
                 <&cpg CPG_MOD 723>,
                 <&cpg CPG_MOD 722>,
-                <&cpg CPG_MOD 727>,
                 <&versaclock5 1>,
                 <&versaclock5 3>,
                 <&versaclock5 2>;
-       clock-names = "du.0", "du.1", "du.2", "lvds.0",
+       clock-names = "du.0", "du.1", "du.2",
                      "dclkin.0", "dclkin.1", "dclkin.2";
 };
index 052d72acc862b83c659f0056deeb9fe720d875a6..b4f9567cb9f86312164fd4d2302a926974df75a6 100644 (file)
        clocks = <&cpg CPG_MOD 724>,
                 <&cpg CPG_MOD 723>,
                 <&cpg CPG_MOD 722>,
-                <&cpg CPG_MOD 727>,
                 <&versaclock5 1>,
                 <&x21_clk>,
                 <&versaclock5 2>;
-       clock-names = "du.0", "du.1", "du.2", "lvds.0",
+       clock-names = "du.0", "du.1", "du.2",
                      "dclkin.0", "dclkin.1", "dclkin.2";
 };
 
index cbd35c00b4af6e2bde98edc29b67a2fedb4a323d..1ec6aaa520c19975511b2e471dc6f97d8b702795 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a7796 SoC
+ * Device Tree Source for the R-Car M3-W (R8A77960) SoC
  *
  * Copyright (C) 2016-2017 Renesas Electronics Corp.
  */
                        power-domains = <&sysc R8A7796_PD_CA57_CPU0>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7796_CLK_Z>;
+                       clocks = <&cpg CPG_CORE R8A7796_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        #cooling-cells = <2>;
                };
                        power-domains = <&sysc R8A7796_PD_CA57_CPU1>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7796_CLK_Z>;
+                       clocks = <&cpg CPG_CORE R8A7796_CLK_Z>;
                        operating-points-v2 = <&cluster0_opp>;
                        #cooling-cells = <2>;
                };
                        power-domains = <&sysc R8A7796_PD_CA53_CPU0>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7796_PD_CA53_CPU1>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7796_PD_CA53_CPU2>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7796_PD_CA53_CPU3>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
-                       clocks =<&cpg CPG_CORE R8A7796_CLK_Z2>;
+                       clocks = <&cpg CPG_CORE R8A7796_CLK_Z2>;
                        operating-points-v2 = <&cluster1_opp>;
                };
 
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 522>;
                        #thermal-sensor-cells = <1>;
-                       status = "okay";
                };
 
                intc_ex: interrupt-controller@e61c0000 {
                                     "renesas,rcar-gen3-usbhs";
                        reg = <0 0xe6590000 0 0x100>;
                        interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 704>;
+                       clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>;
                        dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
                               <&usb_dmac1 0>, <&usb_dmac1 1>;
                        dma-names = "ch0", "ch1", "ch2", "ch3";
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-                       resets = <&cpg 704>;
+                       resets = <&cpg 704>, <&cpg 703>;
                        status = "disabled";
                };
 
 
                                        vin0csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin0>;
+                                               remote-endpoint = <&csi20vin0>;
                                        };
                                        vin0csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin0>;
+                                               remote-endpoint = <&csi40vin0>;
                                        };
                                };
                        };
 
                                        vin1csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin1>;
+                                               remote-endpoint = <&csi20vin1>;
                                        };
                                        vin1csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin1>;
+                                               remote-endpoint = <&csi40vin1>;
                                        };
                                };
                        };
 
                                        vin2csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin2>;
+                                               remote-endpoint = <&csi20vin2>;
                                        };
                                        vin2csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin2>;
+                                               remote-endpoint = <&csi40vin2>;
                                        };
                                };
                        };
 
                                        vin3csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin3>;
+                                               remote-endpoint = <&csi20vin3>;
                                        };
                                        vin3csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin3>;
+                                               remote-endpoint = <&csi40vin3>;
                                        };
                                };
                        };
 
                                        vin4csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin4>;
+                                               remote-endpoint = <&csi20vin4>;
                                        };
                                        vin4csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin4>;
+                                               remote-endpoint = <&csi40vin4>;
                                        };
                                };
                        };
 
                                        vin5csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin5>;
+                                               remote-endpoint = <&csi20vin5>;
                                        };
                                        vin5csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin5>;
+                                               remote-endpoint = <&csi40vin5>;
                                        };
                                };
                        };
 
                                        vin6csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin6>;
+                                               remote-endpoint = <&csi20vin6>;
                                        };
                                        vin6csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin6>;
+                                               remote-endpoint = <&csi40vin6>;
                                        };
                                };
                        };
 
                                        vin7csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin7>;
+                                               remote-endpoint = <&csi20vin7>;
                                        };
                                        vin7csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin7>;
+                                               remote-endpoint = <&csi40vin7>;
                                        };
                                };
                        };
                        compatible = "generic-ohci";
                        reg = <0 0xee080000 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        compatible = "generic-ehci";
                        reg = <0 0xee080100 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
-                       companion= <&ohci0>;
+                       companion = <&ohci0>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        clocks = <&cpg CPG_MOD 702>;
                        phys = <&usb2_phy1>;
                        phy-names = "usb";
-                       companion= <&ohci1>;
+                       companion = <&ohci1>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 702>;
                        status = "disabled";
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee080200 0 0x700>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
 
                du: display@feb00000 {
                        compatible = "renesas,du-r8a7796";
-                       reg = <0 0xfeb00000 0 0x70000>,
-                             <0 0xfeb90000 0 0x14>;
-                       reg-names = "du", "lvds.0";
+                       reg = <0 0xfeb00000 0 0x70000>;
                        interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 724>,
                                 <&cpg CPG_MOD 723>,
-                                <&cpg CPG_MOD 722>,
-                                <&cpg CPG_MOD 727>;
-                       clock-names = "du.0", "du.1", "du.2", "lvds.0";
+                                <&cpg CPG_MOD 722>;
+                       clock-names = "du.0", "du.1", "du.2";
                        status = "disabled";
 
                        vsps = <&vspd0 &vspd1 &vspd2>;
                                port@2 {
                                        reg = <2>;
                                        du_out_lvds0: endpoint {
+                                               remote-endpoint = <&lvds0_in>;
+                                       };
+                               };
+                       };
+               };
+
+               lvds0: lvds@feb90000 {
+                       compatible = "renesas,r8a7796-lvds";
+                       reg = <0 0xfeb90000 0 0x14>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+                       resets = <&cpg 727>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds0_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds0>;
+                                       };
+                               };
+                               port@1 {
+                                       reg = <1>;
+                                       lvds0_out: endpoint {
                                        };
                                };
                        };
diff --git a/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts
new file mode 100644 (file)
index 0000000..dadad97
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the M3NULCB Kingfisher board
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+#include "r8a77965-m3nulcb.dts"
+#include "ulcb-kf.dtsi"
+
+/ {
+       model = "Renesas M3NULCB Kingfisher board based on r8a77965";
+       compatible = "shimafuji,kingfisher", "renesas,m3nulcb",
+                    "renesas,r8a77965";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb.dts b/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb.dts
new file mode 100644 (file)
index 0000000..964078b
--- /dev/null
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the M3NULCB (R-Car Starter Kit Pro) board
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a77965.dtsi"
+#include "ulcb.dtsi"
+
+/ {
+       model = "Renesas M3NULCB board based on r8a77965";
+       compatible = "renesas,m3nulcb", "renesas,r8a77965";
+
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x78000000>;
+       };
+};
+
+&du {
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&cpg CPG_MOD 721>,
+                <&versaclock5 1>,
+                <&versaclock5 3>,
+                <&versaclock5 2>;
+       clock-names = "du.0", "du.1", "du.3",
+                     "dclkin.0", "dclkin.1", "dclkin.3";
+};
index 9de4e3db1621bd26d566f7a18696e4b77599b240..f03a5e9e0c427e0dc8ac9e05d95f2a0d4d7f87d7 100644 (file)
 &hdmi0_con {
        remote-endpoint = <&rcar_dw_hdmi0_out>;
 };
+
+&pca9654 {
+       pcie_sata_switch {
+               gpio-hog;
+               gpios = <7 GPIO_ACTIVE_HIGH>;
+               output-low; /* enable SATA by default */
+               line-name = "PCIE/SATA switch";
+       };
+};
+
+/* SW12-7 must be set 'Off' (MD12 set to 1) which is not the default! */
+&sata {
+       status = "okay";
+};
index 0cd44461a0bd218b830309f1e9b9f61509084492..83946ca2eba5d042b091cbbae863bb56d207f1c3 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a77965 SoC
+ * Device Tree Source for the R-Car M3-N (R8A77965) SoC
  *
  * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
  *
@@ -12,7 +12,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/power/r8a77965-sysc.h>
 
-#define CPG_AUDIO_CLK_I                10
+#define CPG_AUDIO_CLK_I                R8A77965_CLK_S0D4
 
 / {
        compatible = "renesas,r8a77965";
                clock-frequency = <0>;
        };
 
+       cluster0_opp: opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <830000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <830000>;
+                       clock-latency-ns = <300000>;
+               };
+               opp-1500000000 {
+                       opp-hz = /bits/ 64 <1500000000>;
+                       opp-microvolt = <830000>;
+                       clock-latency-ns = <300000>;
+                       opp-suspend;
+               };
+               opp-1600000000 {
+                       opp-hz = /bits/ 64 <1600000000>;
+                       opp-microvolt = <900000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+               opp-1700000000 {
+                       opp-hz = /bits/ 64 <1700000000>;
+                       opp-microvolt = <900000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+               opp-1800000000 {
+                       opp-hz = /bits/ 64 <1800000000>;
+                       opp-microvolt = <960000>;
+                       clock-latency-ns = <300000>;
+                       turbo-mode;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        power-domains = <&sysc R8A77965_PD_CA57_CPU0>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       clocks = <&cpg CPG_CORE R8A77965_CLK_Z>;
+                       operating-points-v2 = <&cluster0_opp>;
                };
 
                a57_1: cpu@1 {
                        power-domains = <&sysc R8A77965_PD_CA57_CPU1>;
                        next-level-cache = <&L2_CA57>;
                        enable-method = "psci";
+                       clocks = <&cpg CPG_CORE R8A77965_CLK_Z>;
+                       operating-points-v2 = <&cluster0_opp>;
                };
 
                L2_CA57: cache-controller-0 {
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
                        resets = <&cpg 522>;
                        #thermal-sensor-cells = <1>;
-                       status = "okay";
                };
 
                intc_ex: interrupt-controller@e61c0000 {
                };
 
                hsusb: usb@e6590000 {
-                       compatible = "renesas,usbhs-r8a7796",
+                       compatible = "renesas,usbhs-r8a77965",
                                     "renesas,rcar-gen3-usbhs";
                        reg = <0 0xe6590000 0 0x100>;
                        interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 704>;
+                       clocks = <&cpg CPG_MOD 704>, <&cpg CPG_MOD 703>;
                        dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
                               <&usb_dmac1 0>, <&usb_dmac1 1>;
                        dma-names = "ch0", "ch1", "ch2", "ch3";
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-                       resets = <&cpg 704>;
+                       resets = <&cpg 704>, <&cpg 703>;
                        status = "disabled";
                };
 
                        resets = <&cpg 219>;
                        #dma-cells = <1>;
                        dma-channels = <16>;
+                       iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+                              <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+                              <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+                              <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
+                              <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
+                              <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
+                              <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
+                              <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
                };
 
                dmac1: dma-controller@e7300000 {
                        resets = <&cpg 218>;
                        #dma-cells = <1>;
                        dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+                              <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+                              <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+                              <&ipmmu_ds1 6>, <&ipmmu_ds1 7>,
+                              <&ipmmu_ds1 8>, <&ipmmu_ds1 9>,
+                              <&ipmmu_ds1 10>, <&ipmmu_ds1 11>,
+                              <&ipmmu_ds1 12>, <&ipmmu_ds1 13>,
+                              <&ipmmu_ds1 14>, <&ipmmu_ds1 15>;
                };
 
                dmac2: dma-controller@e7310000 {
                        resets = <&cpg 217>;
                        #dma-cells = <1>;
                        dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+                              <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+                              <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+                              <&ipmmu_ds1 22>, <&ipmmu_ds1 23>,
+                              <&ipmmu_ds1 24>, <&ipmmu_ds1 25>,
+                              <&ipmmu_ds1 26>, <&ipmmu_ds1 27>,
+                              <&ipmmu_ds1 28>, <&ipmmu_ds1 29>,
+                              <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
                };
 
                ipmmu_ds0: mmu@e6740000 {
                        status = "disabled";
                };
 
+               can0: can@e6c30000 {
+                       reg = <0 0xe6c30000 0 0x1000>;
+                       /* placeholder */
+               };
+
+               can1: can@e6c38000 {
+                       reg = <0 0xe6c38000 0 0x1000>;
+                       /* placeholder */
+               };
+
                pwm0: pwm@e6e30000 {
                        compatible = "renesas,pwm-r8a77965", "renesas,pwm-rcar";
                        reg = <0 0xe6e30000 0 8>;
 
                                        vin0csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin0>;
+                                               remote-endpoint = <&csi20vin0>;
                                        };
                                        vin0csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin0>;
+                                               remote-endpoint = <&csi40vin0>;
                                        };
                                };
                        };
 
                                        vin1csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin1>;
+                                               remote-endpoint = <&csi20vin1>;
                                        };
                                        vin1csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin1>;
+                                               remote-endpoint = <&csi40vin1>;
                                        };
                                };
                        };
 
                                        vin2csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin2>;
+                                               remote-endpoint = <&csi20vin2>;
                                        };
                                        vin2csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin2>;
+                                               remote-endpoint = <&csi40vin2>;
                                        };
                                };
                        };
 
                                        vin3csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin3>;
+                                               remote-endpoint = <&csi20vin3>;
                                        };
                                        vin3csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin3>;
+                                               remote-endpoint = <&csi40vin3>;
                                        };
                                };
                        };
 
                                        vin4csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin4>;
+                                               remote-endpoint = <&csi20vin4>;
                                        };
                                        vin4csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin4>;
+                                               remote-endpoint = <&csi40vin4>;
                                        };
                                };
                        };
 
                                        vin5csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin5>;
+                                               remote-endpoint = <&csi20vin5>;
                                        };
                                        vin5csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin5>;
+                                               remote-endpoint = <&csi40vin5>;
                                        };
                                };
                        };
 
                                        vin6csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin6>;
+                                               remote-endpoint = <&csi20vin6>;
                                        };
                                        vin6csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin6>;
+                                               remote-endpoint = <&csi40vin6>;
                                        };
                                };
                        };
 
                                        vin7csi20: endpoint@0 {
                                                reg = <0>;
-                                               remote-endpoint= <&csi20vin7>;
+                                               remote-endpoint = <&csi20vin7>;
                                        };
                                        vin7csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin7>;
+                                               remote-endpoint = <&csi40vin7>;
                                        };
                                };
                        };
                };
 
                rcar_sound: sound@ec500000 {
+                       /*
+                        * #sound-dai-cells is required
+                        *
+                        * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+                        * Multi  DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+                        */
+                       /*
+                        * #clock-cells is required for audio_clkout0/1/2/3
+                        *
+                        * clkout       : #clock-cells = <0>;   <&rcar_sound>;
+                        * clkout0/1/2/3: #clock-cells = <1>;   <&rcar_sound N>;
+                        */
+                       compatible =  "renesas,rcar_sound-r8a77965", "renesas,rcar_sound-gen3";
                        reg =   <0 0xec500000 0 0x1000>, /* SCU */
                                <0 0xec5a0000 0 0x100>,  /* ADG */
                                <0 0xec540000 0 0x1000>, /* SSIU */
                                <0 0xec541000 0 0x280>,  /* SSI */
                                <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
-                       /* placeholder */
+                       reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
+
+                       clocks = <&cpg CPG_MOD 1005>,
+                                <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+                                <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+                                <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+                                <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+                                <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+                                <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+                                <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+                                <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+                                <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+                                <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+                                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                                <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+                                <&audio_clk_a>, <&audio_clk_b>,
+                                <&audio_clk_c>,
+                                <&cpg CPG_CORE R8A77965_CLK_S0D4>;
+                       clock-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0",
+                                     "src.9", "src.8", "src.7", "src.6",
+                                     "src.5", "src.4", "src.3", "src.2",
+                                     "src.1", "src.0",
+                                     "mix.1", "mix.0",
+                                     "ctu.1", "ctu.0",
+                                     "dvc.0", "dvc.1",
+                                     "clk_a", "clk_b", "clk_c", "clk_i";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 1005>,
+                                <&cpg 1006>, <&cpg 1007>,
+                                <&cpg 1008>, <&cpg 1009>,
+                                <&cpg 1010>, <&cpg 1011>,
+                                <&cpg 1012>, <&cpg 1013>,
+                                <&cpg 1014>, <&cpg 1015>;
+                       reset-names = "ssi-all",
+                                     "ssi.9", "ssi.8", "ssi.7", "ssi.6",
+                                     "ssi.5", "ssi.4", "ssi.3", "ssi.2",
+                                     "ssi.1", "ssi.0";
+                       status = "disabled";
 
                        rcar_sound,dvc {
                                dvc0: dvc-0 {
+                                       dmas = <&audma1 0xbc>;
+                                       dma-names = "tx";
                                };
                                dvc1: dvc-1 {
+                                       dmas = <&audma1 0xbe>;
+                                       dma-names = "tx";
                                };
                        };
 
+                       rcar_sound,mix {
+                               mix0: mix-0 { };
+                               mix1: mix-1 { };
+                       };
+
+                       rcar_sound,ctu {
+                               ctu00: ctu-0 { };
+                               ctu01: ctu-1 { };
+                               ctu02: ctu-2 { };
+                               ctu03: ctu-3 { };
+                               ctu10: ctu-4 { };
+                               ctu11: ctu-5 { };
+                               ctu12: ctu-6 { };
+                               ctu13: ctu-7 { };
+                       };
+
                        rcar_sound,src {
                                src0: src-0 {
+                                       interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x85>, <&audma1 0x9a>;
+                                       dma-names = "rx", "tx";
                                };
                                src1: src-1 {
+                                       interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x87>, <&audma1 0x9c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src2: src-2 {
+                                       interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x89>, <&audma1 0x9e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src3: src-3 {
+                                       interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8b>, <&audma1 0xa0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src4: src-4 {
+                                       interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8d>, <&audma1 0xb0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src5: src-5 {
+                                       interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x8f>, <&audma1 0xb2>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src6: src-6 {
+                                       interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x91>, <&audma1 0xb4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src7: src-7 {
+                                       interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x93>, <&audma1 0xb6>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src8: src-8 {
+                                       interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x95>, <&audma1 0xb8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               src9: src-9 {
+                                       interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x97>, <&audma1 0xba>;
+                                       dma-names = "rx", "tx";
                                };
                        };
 
                        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";
                                };
                                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";
                                };
-                       };
-
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               port@0 {
-                                       reg = <0>;
+                               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";
                                };
-                               port@1 {
-                                       reg = <1>;
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
+                               };
+                               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";
                                };
                        };
                };
 
+               audma0: dma-controller@ec700000 {
+                       compatible = "renesas,dmac-r8a77965",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xec700000 0 0x10000>;
+                       interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 502>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 502>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               audma1: dma-controller@ec720000 {
+                       compatible = "renesas,dmac-r8a77965",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xec720000 0 0x10000>;
+                       interrupts = <GIC_SPI 351 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
+                                     GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 501>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 501>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
                xhci0: usb@ee000000 {
                        compatible = "renesas,xhci-r8a77965",
                                     "renesas,rcar-gen3-xhci";
                        compatible = "generic-ohci";
                        reg = <0 0xee080000 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        compatible = "generic-ehci";
                        reg = <0 0xee080100 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        companion = <&ohci0>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee080200 0 0x700>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
                        compatible = "renesas,usb2-phy-r8a77965",
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee0a0200 0 0x700>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 702>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 702>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
                        status = "disabled";
                };
 
+               sata: sata@ee300000 {
+                       compatible = "renesas,sata-r8a77965",
+                                    "renesas,rcar-gen3-sata";
+                       reg = <0 0xee300000 0 0x200000>;
+                       interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 815>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 815>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@f1010000 {
                        compatible = "arm,gic-400";
                        #interrupt-cells = <3>;
                        status = "disabled";
                };
 
+               fdp1@fe940000 {
+                       compatible = "renesas,fdp1";
+                       reg = <0 0xfe940000 0 0x2400>;
+                       interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 119>;
+                       power-domains = <&sysc R8A77965_PD_A3VP>;
+                       resets = <&cpg 119>;
+                       renesas,fcp = <&fcpf0>;
+               };
+
                fcpf0: fcp@fe950000 {
                        compatible = "renesas,fcpf";
                        reg = <0 0xfe950000 0 0x200>;
                };
        };
 
-       timer {
-               compatible = "arm,armv8-timer";
-               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
-       };
-
        thermal-zones {
                sensor_thermal1: sensor-thermal1 {
                        polling-delay-passive = <250>;
                };
        };
 
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
        /* External USB clocks - can be overridden by the board */
        usb3s0_clk: usb3s0 {
                compatible = "fixed-clock";
index 8eac8ca6550b81f4922cafbe33174de16f3cca98..0dbcb4cccc1803e0d5128333b073edff4ba6b8e8 100644 (file)
                regulator-always-on;
        };
 
+       vcc_vddq_vin0: regulator-2 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_VDDQ_VIN0";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        lvds-decoder {
                compatible = "thine,thc63lvd1024";
                vcc-supply = <&vcc_d3_3v>;
                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";
        };
 };
 
+&mmc0 {
+       pinctrl-0 = <&mmc_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&vcc_d3_3v>;
+       vqmmc-supply = <&vcc_vddq_vin0>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
 &scif0 {
        pinctrl-0 = <&scif0_pins>;
        pinctrl-names = "default";
index 954168858fed95e7c8a34d41629540087eaeae87..cba7885cf7c352e5afabea141130f92e6dc9359d 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a77970 SoC
+ * Device Tree Source for the R-Car V3M (R8A77970) SoC
  *
  * Copyright (C) 2016-2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
                i2c4 = &i2c4;
        };
 
+       /* External CAN clock - to be overridden by boards that provide it */
+       can_clk: can {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                method = "smc";
        };
 
-       /* External CAN clock - to be overridden by boards that provide it */
-       can_clk: can {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <0>;
-       };
-
        /* External SCIF clock - to be overridden by boards that provide it */
        scif_clk: scif {
                compatible = "fixed-clock";
                        reg = <0 0xe6060000 0 0x504>;
                };
 
+               cmt0: timer@e60f0000 {
+                       compatible = "renesas,r8a77970-cmt0",
+                                    "renesas,rcar-gen3-cmt0";
+                       reg = <0 0xe60f0000 0 0x1004>;
+                       interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 303>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+                       resets = <&cpg 303>;
+                       status = "disabled";
+               };
+
+               cmt1: timer@e6130000 {
+                       compatible = "renesas,r8a77970-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6130000 0 0x1004>;
+                       interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 302>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+                       resets = <&cpg 302>;
+                       status = "disabled";
+               };
+
+               cmt2: timer@e6140000 {
+                       compatible = "renesas,r8a77970-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6140000 0 0x1004>;
+                       interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 301>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+                       resets = <&cpg 301>;
+                       status = "disabled";
+               };
+
+               cmt3: timer@e6148000 {
+                       compatible = "renesas,r8a77970-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6148000 0 0x1004>;
+                       interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 300>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+                       resets = <&cpg 300>;
+                       status = "disabled";
+               };
+
                cpg: clock-controller@e6150000 {
                        compatible = "renesas,r8a77970-cpg-mssr";
                        reg = <0 0xe6150000 0 0x1000>;
                        status = "disabled";
                };
 
+               tpu: pwm@e6e80000 {
+                       compatible = "renesas,tpu-r8a77970", "renesas,tpu";
+                       reg = <0 0xe6e80000 0 0x148>;
+                       interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 304>;
+                       power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+                       resets = <&cpg 304>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
 
                vin0: video@e6ef0000 {
                        compatible = "renesas,vin-r8a77970";
 
                                        vin0csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin0>;
+                                               remote-endpoint = <&csi40vin0>;
                                        };
                                };
                        };
 
                                        vin1csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin1>;
+                                               remote-endpoint = <&csi40vin1>;
                                        };
                                };
                        };
 
                                        vin2csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin2>;
+                                               remote-endpoint = <&csi40vin2>;
                                        };
                                };
                        };
 
                                        vin3csi40: endpoint@2 {
                                                reg = <2>;
-                                               remote-endpoint= <&csi40vin3>;
+                                               remote-endpoint = <&csi40vin3>;
                                        };
                                };
                        };
                        #iommu-cells = <1>;
                };
 
+               mmc0: mmc@ee140000 {
+                       compatible = "renesas,sdhi-r8a77970",
+                                    "renesas,rcar-gen3-sdhi";
+                       reg = <0 0xee140000 0 0x2000>;
+                       interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 314>;
+                       power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+                       resets = <&cpg 314>;
+                       max-frequency = <200000000>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@f1010000 {
                        compatible = "arm,gic-400";
                        #interrupt-cells = <3>;
index 9f25c407dfd711741d14e2b19521c60097ad5006..fe2e2c051cc93fc0668a3d3e59a3b13432ef4766 100644 (file)
                regulator-boot-on;
                regulator-always-on;
        };
+
+       d1_8v: regulator-2 {
+               compatible = "regulator-fixed";
+               regulator-name = "D1.8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       hdmi-out {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con: endpoint {
+                               remote-endpoint = <&adv7511_out>;
+                       };
+               };
+       };
+
+       lvds-decoder {
+               compatible = "thine,thc63lvd1024";
+               vcc-supply = <&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>;
+                               };
+                       };
+               };
+       };
+
+       x1_clk: x1-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <148500000>;
+       };
 };
 
 &avb {
        };
 };
 
+&du {
+       clocks = <&cpg CPG_MOD 724>,
+                <&x1_clk>;
+       clock-names = "du.0", "dclkin.0";
+       status = "okay";
+};
+
 &extal_clk {
        clock-frequency = <16666666>;
 };
                gpio-controller;
                #gpio-cells = <2>;
        };
+
+       hdmi@39 {
+               compatible = "adi,adv7511w";
+               reg = <0x39>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+               avdd-supply = <&d1_8v>;
+               dvdd-supply = <&d1_8v>;
+               pvdd-supply = <&d1_8v>;
+               bgvdd-supply = <&d1_8v>;
+               dvdd-3v-supply = <&d3_3v>;
+
+               adi,input-depth = <8>;
+               adi,input-colorspace = "rgb";
+               adi,input-clock = "1x";
+               adi,input-style = <1>;
+               adi,input-justification = "evenly";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7511_in: endpoint {
+                                       remote-endpoint = <&thc63lvd1024_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               adv7511_out: endpoint {
+                                       remote-endpoint = <&hdmi_con>;
+                               };
+                       };
+               };
+       };
+};
+
+&lvds0 {
+       status = "okay";
+
+       ports {
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&thc63lvd1024_in>;
+                       };
+               };
+       };
 };
 
 &mmc0 {
        status = "okay";
 };
 
+&pciec {
+       status = "okay";
+};
+
+&pcie_bus_clk {
+       clock-frequency = <100000000>;
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
 &pfc {
        avb_pins: avb {
                groups = "avb_mdio", "avb_rgmii";
        };
 };
 
+&rwdt {
+       timeout-sec = <60>;
+       status = "okay";
+};
+
 &scif0 {
        pinctrl-0 = <&scif0_pins>, <&scif_clk_pins>;
        pinctrl-names = "default";
index 9dac42f8f80435c91e19fad0121e1e56df6855e1..dd14a41b32cdf242e779fd27330aa311e51240ce 100644 (file)
                /* first 128MB is reserved for secure area. */
                reg = <0 0x48000000 0 0x78000000>;
        };
+
+       hdmi-out {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con: endpoint {
+                               remote-endpoint = <&adv7511_out>;
+                       };
+               };
+       };
+
+       lvds-decoder {
+               compatible = "thine,thc63lvd1024";
+               vcc-supply = <&vcc3v3_d5>;
+
+               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>;
+                               };
+                       };
+               };
+       };
+
+       osc1_clk: osc1-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <148500000>;
+       };
+
+       vcc1v8_d4: regulator-0 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC1V8_D4";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vcc3v3_d5: regulator-1 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC3V3_D5";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&du {
+       clocks = <&cpg CPG_MOD 724>,
+                <&osc1_clk>;
+       clock-names = "du.0", "dclkin.0";
+       status = "okay";
 };
 
 &extal_clk {
        };
 };
 
+&i2c0 {
+       pinctrl-0 = <&i2c0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       hdmi@39 {
+               compatible = "adi,adv7511w";
+               #sound-dai-cells = <0>;
+               reg = <0x39>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+               avdd-supply = <&vcc1v8_d4>;
+               dvdd-supply = <&vcc1v8_d4>;
+               pvdd-supply = <&vcc1v8_d4>;
+               bgvdd-supply = <&vcc1v8_d4>;
+               dvdd-3v-supply = <&vcc3v3_d5>;
+
+               adi,input-depth = <8>;
+               adi,input-colorspace = "rgb";
+               adi,input-clock = "1x";
+               adi,input-style = <1>;
+               adi,input-justification = "evenly";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7511_in: endpoint {
+                                       remote-endpoint = <&thc63lvd1024_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               adv7511_out: endpoint {
+                                       remote-endpoint = <&hdmi_con>;
+                               };
+                       };
+               };
+       };
+};
+
+&lvds0 {
+       status = "okay";
+
+       ports {
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&thc63lvd1024_in>;
+                       };
+               };
+       };
+};
+
 &pfc {
        gether_pins: gether {
                groups = "gether_mdio_a", "gether_rgmii",
                function = "gether";
        };
 
+       i2c0_pins: i2c0 {
+               groups = "i2c0";
+               function = "i2c0";
+       };
+
        scif0_pins: scif0 {
                groups = "scif0_data";
                function = "scif0";
        };
 };
 
+&rwdt {
+       timeout-sec = <60>;
+       status = "okay";
+};
+
 &scif0 {
        pinctrl-0 = <&scif0_pins>, <&scif_clk_pins>;
        pinctrl-names = "default";
index b8c9a56562f249bb084a9002f7332fc4f43dad5d..d4952b527d1468f75e93b0442514d090896e3b8d 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a77980 SoC
+ * Device Tree Source for the R-Car V3H (R8A77980) SoC
  *
  * Copyright (C) 2018 Renesas Electronics Corp.
  * Copyright (C) 2018 Cogent Embedded, Inc.
                i2c5 = &i2c5;
        };
 
+       /* External CAN clock - to be overridden by boards that provide it */
+       can_clk: can {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                };
        };
 
-       /* External CAN clock - to be overridden by boards that provide it */
-       can_clk: can {
+       extal_clk: extal {
                compatible = "fixed-clock";
                #clock-cells = <0>;
+               /* This value must be overridden by the board */
                clock-frequency = <0>;
        };
 
-       extal_clk: extal {
+       extalr_clk: extalr {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                /* This value must be overridden by the board */
                clock-frequency = <0>;
        };
 
-       extalr_clk: extalr {
+       /* External PCIe clock - can be overridden by the board */
+       pcie_bus_clk: pcie_bus {
                compatible = "fixed-clock";
                #clock-cells = <0>;
-               /* This value must be overridden by the board */
                clock-frequency = <0>;
        };
 
+       pmu_a53 {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>;
+       };
+
        psci {
                compatible = "arm,psci-1.0", "arm,psci-0.2";
                method = "smc";
                #size-cells = <2>;
                ranges;
 
+               rwdt: watchdog@e6020000 {
+                       compatible = "renesas,r8a77980-wdt",
+                                    "renesas,rcar-gen3-wdt";
+                       reg = <0 0xe6020000 0 0x0c>;
+                       clocks = <&cpg CPG_MOD 402>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 402>;
+                       status = "disabled";
+               };
+
                gpio0: gpio@e6050000 {
                        compatible = "renesas,gpio-r8a77980",
                                     "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6060000 0 0x50c>;
                };
 
+               cmt0: timer@e60f0000 {
+                       compatible = "renesas,r8a77980-cmt0",
+                                    "renesas,rcar-gen3-cmt0";
+                       reg = <0 0xe60f0000 0 0x1004>;
+                       interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 303>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 303>;
+                       status = "disabled";
+               };
+
+               cmt1: timer@e6130000 {
+                       compatible = "renesas,r8a77980-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6130000 0 0x1004>;
+                       interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 302>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 302>;
+                       status = "disabled";
+               };
+
+               cmt2: timer@e6140000 {
+                       compatible = "renesas,r8a77980-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6140000 0 0x1004>;
+                       interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 301>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 301>;
+                       status = "disabled";
+               };
+
+               cmt3: timer@e6148000 {
+                       compatible = "renesas,r8a77980-cmt1",
+                                    "renesas,rcar-gen3-cmt1";
+                       reg = <0 0xe6148000 0 0x1004>;
+                       interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 300>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 300>;
+                       status = "disabled";
+               };
+
                cpg: clock-controller@e6150000 {
                        compatible = "renesas,r8a77980-cpg-mssr";
                        reg = <0 0xe6150000 0 0x1000>;
                        status = "disabled";
                };
 
+               pcie_phy: pcie-phy@e65d0000 {
+                       compatible = "renesas,r8a77980-pcie-phy";
+                       reg = <0 0xe65d0000 0 0x8000>;
+                       #phy-cells = <0>;
+                       clocks = <&cpg CPG_MOD 319>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 319>;
+                       status = "disabled";
+               };
+
                canfd: can@e66c0000 {
                        compatible = "renesas,r8a77980-canfd",
                                     "renesas,rcar-gen3-canfd";
                        };
                };
 
-               ipmmu_ds1: mmu@e7740000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xe7740000 0 0x1000>;
-                       renesas,ipmmu-main = <&ipmmu_mm 0>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_vip0: mmu@e7b00000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xe7b00000 0 0x1000>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_vip1: mmu@e7960000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xe7960000 0 0x1000>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_ir: mmu@ff8b0000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xff8b0000 0 0x1000>;
-                       renesas,ipmmu-main = <&ipmmu_mm 3>;
-                       power-domains = <&sysc R8A77980_PD_A3IR>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_mm: mmu@e67b0000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xe67b0000 0 0x1000>;
-                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_rt: mmu@ffc80000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xffc80000 0 0x1000>;
-                       renesas,ipmmu-main = <&ipmmu_mm 10>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_vc0: mmu@fe6b0000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xfe6b0000 0 0x1000>;
-                       renesas,ipmmu-main = <&ipmmu_mm 12>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
-               ipmmu_vi0: mmu@febd0000 {
-                       compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xfebd0000 0 0x1000>;
-                       renesas,ipmmu-main = <&ipmmu_mm 14>;
-                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
-                       #iommu-cells = <1>;
-               };
-
                avb: ethernet@e6800000 {
                        compatible = "renesas,etheravb-r8a77980",
                                     "renesas,etheravb-rcar-gen3";
                        status = "disabled";
                };
 
+               tpu: pwm@e6e80000 {
+                       compatible = "renesas,tpu-r8a77980", "renesas,tpu";
+                       reg = <0 0xe6e80000 0 0x148>;
+                       interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 304>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 304>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
+
+               vin0: video@e6ef0000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef0000 0 0x1000>;
+                       interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 811>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 811>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin0csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin0>;
+                                       };
+                               };
+                       };
+               };
+
+               vin1: video@e6ef1000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef1000 0 0x1000>;
+                       interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 810>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       status = "disabled";
+                       resets = <&cpg 810>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin1csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin1>;
+                                       };
+                               };
+                       };
+               };
+
+               vin2: video@e6ef2000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef2000 0 0x1000>;
+                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 809>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 809>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin2csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin2>;
+                                       };
+                               };
+                       };
+               };
+
+               vin3: video@e6ef3000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef3000 0 0x1000>;
+                       interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 808>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 808>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin3csi40: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi40vin3>;
+                                       };
+                               };
+                       };
+               };
+
+               vin4: video@e6ef4000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef4000 0 0x1000>;
+                       interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 807>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 807>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin4csi41: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi41vin4>;
+                                       };
+                               };
+                       };
+               };
+
+               vin5: video@e6ef5000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef5000 0 0x1000>;
+                       interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 806>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 806>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin5csi41: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi41vin5>;
+                                       };
+                               };
+                       };
+               };
+
+               vin6: video@e6ef6000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef6000 0 0x1000>;
+                       interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 805>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 805>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin6csi41: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi41vin6>;
+                                       };
+                               };
+                       };
+               };
+
+               vin7: video@e6ef7000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef7000 0 0x1000>;
+                       interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 804>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 804>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       vin7csi41: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&csi41vin7>;
+                                       };
+                               };
+                       };
+               };
+
+               vin8: video@e6ef8000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef8000 0 0x1000>;
+                       interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 628>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 628>;
+                       status = "disabled";
+               };
+
+               vin9: video@e6ef9000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6ef9000 0 0x1000>;
+                       interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 627>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 627>;
+                       status = "disabled";
+               };
+
+               vin10: video@e6efa000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6efa000 0 0x1000>;
+                       interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 625>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 625>;
+                       status = "disabled";
+               };
+
+               vin11: video@e6efb000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6efb000 0 0x1000>;
+                       interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 618>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 618>;
+                       status = "disabled";
+               };
+
+               vin12: video@e6efc000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6efc000 0 0x1000>;
+                       interrupts = <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 612>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 612>;
+                       status = "disabled";
+               };
+
+               vin13: video@e6efd000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6efd000 0 0x1000>;
+                       interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 608>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 608>;
+                       status = "disabled";
+               };
+
+               vin14: video@e6efe000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6efe000 0 0x1000>;
+                       interrupts = <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 605>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 605>;
+                       status = "disabled";
+               };
+
+               vin15: video@e6eff000 {
+                       compatible = "renesas,vin-r8a77980";
+                       reg = <0 0xe6eff000 0 0x1000>;
+                       interrupts = <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 604>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 604>;
+                       status = "disabled";
+               };
+
                dmac1: dma-controller@e7300000 {
                        compatible = "renesas,dmac-r8a77980",
                                     "renesas,rcar-dmac";
                        resets = <&cpg 218>;
                        #dma-cells = <1>;
                        dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+                              <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+                              <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+                              <&ipmmu_ds1 6>, <&ipmmu_ds1 7>,
+                              <&ipmmu_ds1 8>, <&ipmmu_ds1 9>,
+                              <&ipmmu_ds1 10>, <&ipmmu_ds1 11>,
+                              <&ipmmu_ds1 12>, <&ipmmu_ds1 13>,
+                              <&ipmmu_ds1 14>, <&ipmmu_ds1 15>;
                };
 
                dmac2: dma-controller@e7310000 {
                        resets = <&cpg 217>;
                        #dma-cells = <1>;
                        dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+                              <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+                              <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+                              <&ipmmu_ds1 22>, <&ipmmu_ds1 23>,
+                              <&ipmmu_ds1 24>, <&ipmmu_ds1 25>,
+                              <&ipmmu_ds1 26>, <&ipmmu_ds1 27>,
+                              <&ipmmu_ds1 28>, <&ipmmu_ds1 29>,
+                              <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
                };
 
                gether: ethernet@e7400000 {
                        status = "disabled";
                };
 
+               ipmmu_ds1: mmu@e7740000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe7740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ir: mmu@ff8b0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xff8b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 3>;
+                       power-domains = <&sysc R8A77980_PD_A3IR>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: mmu@e67b0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe67b0000 0 0x1000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_rt: mmu@ffc80000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xffc80000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 10>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc0: mmu@fe6b0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xfe6b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 12>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: mmu@febd0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xfebd0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 14>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vip0: mmu@e7b00000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe7b00000 0 0x1000>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vip1: mmu@e7960000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe7960000 0 0x1000>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
                mmc0: mmc@ee140000 {
                        compatible = "renesas,sdhi-r8a77980",
                                     "renesas,rcar-gen3-sdhi";
                        resets = <&cpg 408>;
                };
 
+               pciec: pcie@fe000000 {
+                       compatible = "renesas,pcie-r8a77980",
+                                    "renesas,pcie-rcar-gen3";
+                       reg = <0 0xfe000000 0 0x80000>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <
+                               0x01000000 0 0x00000000 0 0xfe100000 0 0x0100000
+                               0x02000000 0 0xfe200000 0 0xfe200000 0 0x0200000
+                               0x02000000 0 0x30000000 0 0x30000000 0 0x8000000
+                               0x42000000 0 0x38000000 0 0x38000000 0 0x8000000
+                       >;
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000
+                                     0 0x80000000>;
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 148
+                                        IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 319>;
+                       phys = <&pcie_phy>;
+                       phy-names = "pcie";
+                       status = "disabled";
+               };
+
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
                        reg = <0 0xfea20000 0 0x5000>;
                        resets = <&cpg 603>;
                };
 
+               csi40: csi2@feaa0000 {
+                       compatible = "renesas,r8a77980-csi2";
+                       reg = <0 0xfeaa0000 0 0x10000>;
+                       interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 716>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 716>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       csi40vin0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&vin0csi40>;
+                                       };
+                                       csi40vin1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&vin1csi40>;
+                                       };
+                                       csi40vin2: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&vin2csi40>;
+                                       };
+                                       csi40vin3: endpoint@3 {
+                                               reg = <3>;
+                                               remote-endpoint = <&vin3csi40>;
+                                       };
+                               };
+                       };
+               };
+
+               csi41: csi2@feab0000 {
+                       compatible = "renesas,r8a77980-csi2";
+                       reg = <0 0xfeab0000 0 0x10000>;
+                       interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 715>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 715>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       csi41vin4: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&vin4csi41>;
+                                       };
+                                       csi41vin5: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&vin5csi41>;
+                                       };
+                                       csi41vin6: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&vin6csi41>;
+                                       };
+                                       csi41vin7: endpoint@3 {
+                                               reg = <3>;
+                                               remote-endpoint = <&vin7csi41>;
+                                       };
+                               };
+                       };
+               };
+
                du: display@feb00000 {
                        compatible = "renesas,du-r8a77980",
                                     "renesas,du-r8a77970";
index 2bc3a4884b0031f713391f046dabc2712f54f0aa..f342dd85b152804d3f5c0df483618c98170ce4e6 100644 (file)
                /* first 128MB is reserved for secure area. */
                reg = <0x0 0x48000000 0x0 0x38000000>;
        };
+
+       cvbs-in {
+               compatible = "composite-video-connector";
+               label = "CVBS IN";
+
+               port {
+                       cvbs_con: endpoint {
+                               remote-endpoint = <&adv7482_ain7>;
+                       };
+               };
+       };
+
+       hdmi-in {
+               compatible = "hdmi-connector";
+               label = "HDMI IN";
+               type = "a";
+
+               port {
+                       hdmi_in_con: endpoint {
+                               remote-endpoint = <&adv7482_hdmi>;
+                       };
+               };
+       };
+
+       hdmi-out {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_out: endpoint {
+                               remote-endpoint = <&adv7511_out>;
+                       };
+               };
+       };
+
+       lvds-decoder {
+               compatible = "thine,thc63lvd1024";
+               vcc-supply = <&reg_3p3v>;
+
+               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>;
+                               };
+                       };
+               };
+       };
+
+       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>;
+                               };
+                       };
+               };
+       };
+
+       reg_3p3v: regulator1 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       x13_clk: x13 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <74250000>;
+       };
 };
 
 &avb {
        };
 };
 
+&csi40 {
+       status = "okay";
+
+       ports {
+               port@0 {
+                       reg = <0>;
+
+                       csi40_in: endpoint {
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                               remote-endpoint = <&adv7482_txa>;
+                       };
+               };
+       };
+};
+
+&du {
+       pinctrl-0 = <&du_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&x13_clk>;
+       clock-names = "du.0", "du.1", "dclkin.0";
+
+       ports {
+               port@0 {
+                       endpoint {
+                               remote-endpoint = <&adv7123_in>;
+                       };
+               };
+       };
+};
+
 &ehci0 {
        status = "okay";
 };
        clock-frequency = <48000000>;
 };
 
+&i2c0 {
+       status = "okay";
+
+       hdmi-encoder@39 {
+               compatible = "adi,adv7511w";
+               reg = <0x39>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+
+               adi,input-depth = <8>;
+               adi,input-colorspace = "rgb";
+               adi,input-clock = "1x";
+               adi,input-style = <1>;
+               adi,input-justification = "evenly";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7511_in: endpoint {
+                                       remote-endpoint = <&thc63lvd1024_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               adv7511_out: endpoint {
+                                       remote-endpoint = <&hdmi_con_out>;
+                               };
+                       };
+               };
+       };
+
+       video-receiver@70 {
+               compatible = "adi,adv7482";
+               reg = <0x70>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               interrupt-parent = <&gpio0>;
+               interrupt-names = "intrq1", "intrq2";
+               interrupts = <7 IRQ_TYPE_LEVEL_LOW>,
+                            <17 IRQ_TYPE_LEVEL_LOW>;
+
+               port@7 {
+                       reg = <7>;
+
+                       adv7482_ain7: endpoint {
+                               remote-endpoint = <&cvbs_con>;
+                       };
+               };
+
+               port@8 {
+                       reg = <8>;
+
+                       adv7482_hdmi: endpoint {
+                               remote-endpoint = <&hdmi_in_con>;
+                       };
+               };
+
+               port@a {
+                       reg = <0xa>;
+
+                       adv7482_txa: endpoint {
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                               remote-endpoint = <&csi40_in>;
+                       };
+               };
+       };
+};
+
+&lvds0 {
+       status = "okay";
+
+       clocks = <&cpg CPG_MOD 727>,
+                <&x13_clk>,
+                <&extal_clk>;
+       clock-names = "fck", "dclkin.0", "extal";
+
+       ports {
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&thc63lvd1024_in>;
+                       };
+               };
+       };
+};
+
+&lvds1 {
+       clocks = <&cpg CPG_MOD 727>,
+                <&x13_clk>,
+                <&extal_clk>;
+       clock-names = "fck", "dclkin.0", "extal";
+};
+
 &ohci0 {
        status = "okay";
 };
                };
        };
 
+       du_pins: du {
+               groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
+               function = "du";
+       };
+
+       pwm3_pins: pwm3 {
+               groups = "pwm3_b";
+               function = "pwm3";
+       };
+
+       pwm5_pins: pwm5 {
+               groups = "pwm5_a";
+               function = "pwm5";
+       };
+
        usb0_pins: usb {
                groups = "usb0_b";
                function = "usb0";
        };
 };
 
+&pwm3 {
+       pinctrl-0 = <&pwm3_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&pwm5 {
+       pinctrl-0 = <&pwm5_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
 &rwdt {
        timeout-sec = <60>;
        status = "okay";
        status = "okay";
 };
 
+&vin4 {
+       status = "okay";
+};
+
 &xhci0 {
        pinctrl-0 = <&usb30_pins>;
        pinctrl-names = "default";
index ae89260baad9fd4d3ad1ec6dbef9c6a7bf1e118f..9509dc05665f59c27a6201e3f4d0d5b1ae517973 100644 (file)
@@ -1,11 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Device Tree Source for the r8a77990 SoC
+ * Device Tree Source for the R-Car E3 (R8A77990) SoC
  *
  * Copyright (C) 2018 Renesas Electronics Corp.
  */
 
-#include <dt-bindings/clock/renesas-cpg-mssr.h>
+#include <dt-bindings/clock/r8a77990-cpg-mssr.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/power/r8a77990-sysc.h>
 
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+               i2c7 = &i2c7;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
@@ -22,7 +33,7 @@
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0>;
                        device_type = "cpu";
-                       power-domains = <&sysc 5>;
+                       power-domains = <&sysc R8A77990_PD_CA53_CPU0>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
                };
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <1>;
                        device_type = "cpu";
-                       power-domains = <&sysc 6>;
+                       power-domains = <&sysc R8A77990_PD_CA53_CPU1>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
                };
 
                L2_CA53: cache-controller-0 {
                        compatible = "cache";
-                       power-domains = <&sysc 21>;
+                       power-domains = <&sysc R8A77990_PD_CA53_SCU>;
                        cache-unified;
                        cache-level = <2>;
                };
                method = "smc";
        };
 
+       /* External SCIF clock - to be overridden by boards that provide it */
+       scif_clk: scif {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
        soc: soc {
                compatible = "simple-bus";
                interrupt-parent = <&gic>;
@@ -75,7 +93,7 @@
                                     "renesas,rcar-gen3-wdt";
                        reg = <0 0xe6020000 0 0x0c>;
                        clocks = <&cpg CPG_MOD 402>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 402>;
                        status = "disabled";
                };
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 912>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 912>;
                };
 
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 911>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 911>;
                };
 
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 910>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 910>;
                };
 
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 909>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 909>;
                };
 
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 908>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 908>;
                };
 
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 907>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 907>;
                };
 
                        #interrupt-cells = <2>;
                        interrupt-controller;
                        clocks = <&cpg CPG_MOD 906>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 906>;
                };
 
+               i2c0: i2c@e6500000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6500000 0 0x40>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 931>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 931>;
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@e6508000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6508000 0 0x40>;
+                       interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 930>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 930>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@e6510000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6510000 0 0x40>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 929>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 929>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@e66d0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d0000 0 0x40>;
+                       interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 928>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 928>;
+                       i2c-scl-internal-delay-ns = <110>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@e66d8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d8000 0 0x40>;
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 927>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@e66e0000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e0000 0 0x40>;
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 919>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 919>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c6: i2c@e66e8000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e8000 0 0x40>;
+                       interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 918>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 918>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
+               i2c7: i2c@e6690000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77990",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6690000 0 0x40>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 1003>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 1003>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       status = "disabled";
+               };
+
                pfc: pin-controller@e6060000 {
                        compatible = "renesas,pfc-r8a77990";
                        reg = <0 0xe6060000 0 0x508>;
                        #power-domain-cells = <1>;
                };
 
+               dmac0: dma-controller@e6700000 {
+                       compatible = "renesas,dmac-r8a77990",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe6700000 0 0x10000>;
+                       interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 219>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 219>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+                       iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+                              <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+                              <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+                              <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
+                              <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
+                              <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
+                              <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
+                              <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
+               };
+
+               dmac1: dma-controller@e7300000 {
+                       compatible = "renesas,dmac-r8a77990",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe7300000 0 0x10000>;
+                       interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 218>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 218>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+                              <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+                              <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+                              <&ipmmu_ds1 6>, <&ipmmu_ds1 7>,
+                              <&ipmmu_ds1 8>, <&ipmmu_ds1 9>,
+                              <&ipmmu_ds1 10>, <&ipmmu_ds1 11>,
+                              <&ipmmu_ds1 12>, <&ipmmu_ds1 13>,
+                              <&ipmmu_ds1 14>, <&ipmmu_ds1 15>;
+               };
+
+               dmac2: dma-controller@e7310000 {
+                       compatible = "renesas,dmac-r8a77990",
+                                    "renesas,rcar-dmac";
+                       reg = <0 0xe7310000 0 0x10000>;
+                       interrupts = <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "error",
+                                       "ch0", "ch1", "ch2", "ch3",
+                                       "ch4", "ch5", "ch6", "ch7",
+                                       "ch8", "ch9", "ch10", "ch11",
+                                       "ch12", "ch13", "ch14", "ch15";
+                       clocks = <&cpg CPG_MOD 217>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 217>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+                       iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+                              <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+                              <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+                              <&ipmmu_ds1 22>, <&ipmmu_ds1 23>,
+                              <&ipmmu_ds1 24>, <&ipmmu_ds1 25>,
+                              <&ipmmu_ds1 26>, <&ipmmu_ds1 27>,
+                              <&ipmmu_ds1 28>, <&ipmmu_ds1 29>,
+                              <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
+               };
+
                ipmmu_ds0: mmu@e6740000 {
                        compatible = "renesas,ipmmu-r8a77990";
                        reg = <0 0xe6740000 0 0x1000>;
                                          "ch20", "ch21", "ch22", "ch23",
                                          "ch24";
                        clocks = <&cpg CPG_MOD 812>;
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 812>;
                        phy-mode = "rgmii";
                        #address-cells = <1>;
                        status = "disabled";
                };
 
+               pwm0: pwm@e6e30000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e30000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               pwm1: pwm@e6e31000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e31000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               pwm2: pwm@e6e32000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e32000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               pwm3: pwm@e6e33000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e33000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               pwm4: pwm@e6e34000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e34000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               pwm5: pwm@e6e35000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e35000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
+               pwm6: pwm@e6e36000 {
+                       compatible = "renesas,pwm-r8a77990", "renesas,pwm-rcar";
+                       reg = <0 0xe6e36000 0 0x8>;
+                       clocks = <&cpg CPG_MOD 523>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 523>;
+                       #pwm-cells = <2>;
+                       status = "disabled";
+               };
+
                scif2: serial@e6e88000 {
                        compatible = "renesas,scif-r8a77990",
                                     "renesas,rcar-gen3-scif", "renesas,scif";
                        reg = <0 0xe6e88000 0 64>;
                        interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 310>;
-                       clock-names = "fck";
-                       power-domains = <&sysc 32>;
+                       clocks = <&cpg CPG_MOD 310>,
+                                <&cpg CPG_CORE R8A77990_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 310>;
                        status = "disabled";
                };
 
+               msiof0: spi@e6e90000 {
+                       compatible = "renesas,msiof-r8a77990",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6e90000 0 0x0064>;
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 211>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 211>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof1: spi@e6ea0000 {
+                       compatible = "renesas,msiof-r8a77990",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6ea0000 0 0x0064>;
+                       interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 210>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 210>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof2: spi@e6c00000 {
+                       compatible = "renesas,msiof-r8a77990",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c00000 0 0x0064>;
+                       interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 209>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 209>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof3: spi@e6c10000 {
+                       compatible = "renesas,msiof-r8a77990",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c10000 0 0x0064>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 208>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 208>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               vin4: video@e6ef4000 {
+                       compatible = "renesas,vin-r8a77990";
+                       reg = <0 0xe6ef4000 0 0x1000>;
+                       interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 807>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 807>;
+                       renesas,id = <4>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       vin4csi40: endpoint {
+                                               remote-endpoint= <&csi40vin4>;
+                                       };
+                               };
+                       };
+               };
+
+               vin5: video@e6ef5000 {
+                       compatible = "renesas,vin-r8a77990";
+                       reg = <0 0xe6ef5000 0 0x1000>;
+                       interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 806>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 806>;
+                       renesas,id = <5>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       vin5csi40: endpoint {
+                                               remote-endpoint= <&csi40vin5>;
+                                       };
+                               };
+                       };
+               };
+
                xhci0: usb@ee000000 {
                        compatible = "renesas,xhci-r8a77990",
                                     "renesas,rcar-gen3-xhci";
                        compatible = "generic-ohci";
                        reg = <0 0xee080000 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
-                       power-domains = <&sysc 32>;
-                       resets = <&cpg 703>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        compatible = "generic-ehci";
                        reg = <0 0xee080100 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        companion = <&ohci0>;
-                       power-domains = <&sysc 32>;
-                       resets = <&cpg 703>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee080200 0 0x700>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
-                       power-domains = <&sysc 32>;
-                       resets = <&cpg 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
                                        (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
                        clocks = <&cpg CPG_MOD 408>;
                        clock-names = "clk";
-                       power-domains = <&sysc 32>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 408>;
                };
 
+               vspb0: 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 R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 626>;
+                       renesas,fcp = <&fcpvb0>;
+               };
+
+               fcpvb0: fcp@fe96f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe96f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 607>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 607>;
+                       iommus = <&ipmmu_vp0 5>;
+               };
+
+               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 R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 631>;
+                       renesas,fcp = <&fcpvi0>;
+               };
+
+               fcpvi0: fcp@fe9af000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe9af000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 611>;
+                       power-domains = <&sysc R8A77990_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>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 623>;
+                       renesas,fcp = <&fcpvd0>;
+               };
+
+               fcpvd0: fcp@fea27000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea27000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 603>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 603>;
+                       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 R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 622>;
+                       renesas,fcp = <&fcpvd1>;
+               };
+
+               fcpvd1: fcp@fea2f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea2f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 602>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 602>;
+                       iommus = <&ipmmu_vi0 9>;
+               };
+
+               csi40: csi2@feaa0000 {
+                       compatible = "renesas,r8a77990-csi2", "renesas,rcar-gen3-csi2";
+                       reg = <0 0xfeaa0000 0 0x10000>;
+                       interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 716>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 716>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       reg = <1>;
+
+                                       csi40vin4: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&vin4csi40>;
+                                       };
+                                       csi40vin5: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&vin5csi40>;
+                                       };
+                               };
+                       };
+               };
+
+               du: display@feb00000 {
+                       compatible = "renesas,du-r8a77990";
+                       reg = <0 0xfeb00000 0 0x80000>;
+                       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>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       du_out_rgb: endpoint {
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       du_out_lvds0: endpoint {
+                                               remote-endpoint = <&lvds0_in>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       du_out_lvds1: endpoint {
+                                               remote-endpoint = <&lvds1_in>;
+                                       };
+                               };
+                       };
+               };
+
+               lvds0: lvds-encoder@feb90000 {
+                       compatible = "renesas,r8a77990-lvds";
+                       reg = <0 0xfeb90000 0 0x20>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 727>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds0_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds0>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       lvds0_out: endpoint {
+                                       };
+                               };
+                       };
+               };
+
+               lvds1: lvds-encoder@feb90100 {
+                       compatible = "renesas,r8a77990-lvds";
+                       reg = <0 0xfeb90100 0 0x20>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 726>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds1_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds1>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       lvds1_out: endpoint {
+                                       };
+                               };
+                       };
+               };
+
                prr: chipid@fff00044 {
                        compatible = "renesas,prr";
                        reg = <0 0xfff00044 0 4>;
index a8e8f2669d4c53ae7492dc489107d3fbac30eebe..2405eaad0296cf4ee6a00f62a1fb43bb0a007922 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Device Tree Source for the Draak board
  *
- * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016-2018 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
  */
 
                stdout-path = "serial0:115200n8";
        };
 
-       vga {
-               compatible = "vga-connector";
+       composite-in {
+               compatible = "composite-video-connector";
 
                port {
-                       vga_in: endpoint {
-                               remote-endpoint = <&adv7123_out>;
+                       composite_con_in: endpoint {
+                               remote-endpoint = <&adv7180_in>;
                        };
                };
        };
 
-       vga-encoder {
-               compatible = "adi,adv7123";
-
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
+       hdmi-in {
+               compatible = "hdmi-connector";
+               type = "a";
 
-                       port@0 {
-                               reg = <0>;
-                               adv7123_in: endpoint {
-                                       remote-endpoint = <&du_out_rgb>;
-                               };
-                       };
-                       port@1 {
-                               reg = <1>;
-                               adv7123_out: endpoint {
-                                       remote-endpoint = <&vga_in>;
-                               };
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&adv7612_in>;
                        };
                };
        };
 
-       composite-in {
-               compatible = "composite-video-connector";
+       hdmi-out {
+               compatible = "hdmi-connector";
+               type = "a";
 
                port {
-                       composite_con_in: endpoint {
-                               remote-endpoint = <&adv7180_in>;
+                       hdmi_con_out: endpoint {
+                               remote-endpoint = <&adv7511_out>;
                        };
                };
        };
 
-       hdmi-in {
-               compatible = "hdmi-connector";
-               type = "a";
+       lvds-decoder {
+               compatible = "thine,thc63lvd1024";
+               vcc-supply = <&reg_3p3v>;
 
-               port {
-                       hdmi_con_in: endpoint {
-                               remote-endpoint = <&adv7612_in>;
+               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>;
+                               };
                        };
                };
        };
                regulator-always-on;
        };
 
-       x12_clk: x12 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <74250000>;
-       };
-};
-
-&extal_clk {
-       clock-frequency = <48000000>;
-};
+       vga {
+               compatible = "vga-connector";
 
-&pfc {
-       avb0_pins: avb {
-               mux {
-                       groups = "avb0_link", "avb0_mdio", "avb0_mii";
-                       function = "avb0";
+               port {
+                       vga_in: endpoint {
+                               remote-endpoint = <&adv7123_out>;
+                       };
                };
        };
 
-       du_pins: du {
-               groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
-               function = "du";
-       };
+       vga-encoder {
+               compatible = "adi,adv7123";
 
-       i2c0_pins: i2c0 {
-               groups = "i2c0";
-               function = "i2c0";
-       };
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
-       i2c1_pins: i2c1 {
-               groups = "i2c1";
-               function = "i2c1";
+                       port@0 {
+                               reg = <0>;
+                               adv7123_in: endpoint {
+                                       remote-endpoint = <&du_out_rgb>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               adv7123_out: endpoint {
+                                       remote-endpoint = <&vga_in>;
+                               };
+                       };
+               };
        };
 
-       pwm0_pins: pwm0 {
-               groups = "pwm0_c";
-               function = "pwm0";
+       x12_clk: x12 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <74250000>;
        };
+};
 
-       pwm1_pins: pwm1 {
-               groups = "pwm1_c";
-               function = "pwm1";
-       };
+&avb {
+       pinctrl-0 = <&avb0_pins>;
+       pinctrl-names = "default";
+       renesas,no-ether-link;
+       phy-handle = <&phy0>;
+       phy-mode = "rgmii-txid";
+       status = "okay";
 
-       scif2_pins: scif2 {
-               groups = "scif2_data";
-               function = "scif2";
+       phy0: ethernet-phy@0 {
+               rxc-skew-ps = <1500>;
+               reg = <0>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
        };
+};
 
-       sdhi2_pins: sd2 {
-               groups = "mmc_data8", "mmc_ctrl";
-               function = "mmc";
-               power-source = <1800>;
-       };
+&du {
+       pinctrl-0 = <&du_pins>;
+       pinctrl-names = "default";
+       status = "okay";
 
-       sdhi2_pins_uhs: sd2_uhs {
-               groups = "mmc_data8", "mmc_ctrl";
-               function = "mmc";
-               power-source = <1800>;
-       };
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&x12_clk>;
+       clock-names = "du.0", "du.1", "dclkin.0";
 
-       usb0_pins: usb0 {
-               groups = "usb0";
-               function = "usb0";
+       ports {
+               port@0 {
+                       endpoint {
+                               remote-endpoint = <&adv7123_in>;
+                       };
+               };
        };
+};
 
-       vin4_pins_cvbs: vin4 {
-               groups = "vin4_data8", "vin4_sync", "vin4_clk";
-               function = "vin4";
-       };
+&ehci0 {
+       status = "okay";
+};
+
+&extal_clk {
+       clock-frequency = <48000000>;
 };
 
 &i2c0 {
        pinctrl-names = "default";
        status = "okay";
 
-       eeprom@50 {
-               compatible = "rohm,br24t01", "atmel,24c01";
-               reg = <0x50>;
-               pagesize = <8>;
-       };
-
        composite-in@20 {
                compatible = "adi,adv7180cp";
                reg = <0x20>;
 
        };
 
+       hdmi-encoder@39 {
+               compatible = "adi,adv7511w";
+               reg = <0x39>, <0x3f>, <0x38>, <0x3c>;
+               reg-names = "main", "edid", "packet", "cec";
+               interrupt-parent = <&gpio1>;
+               interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+
+               /* Depends on LVDS */
+               max-clock = <135000000>;
+               min-vrefresh = <50>;
+
+               adi,input-depth = <8>;
+               adi,input-colorspace = "rgb";
+               adi,input-clock = "1x";
+               adi,input-style = <1>;
+               adi,input-justification = "evenly";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7511_in: endpoint {
+                                       remote-endpoint = <&thc63lvd1024_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               adv7511_out: endpoint {
+                                       remote-endpoint = <&hdmi_con_out>;
+                               };
+                       };
+               };
+       };
+
        hdmi-decoder@4c {
                compatible = "adi,adv7612";
                reg = <0x4c>;
                        };
                };
        };
+
+       eeprom@50 {
+               compatible = "rohm,br24t01", "atmel,24c01";
+               reg = <0x50>;
+               pagesize = <8>;
+       };
 };
 
 &i2c1 {
        status = "okay";
 };
 
-&du {
-       pinctrl-0 = <&du_pins>;
-       pinctrl-names = "default";
+&lvds0 {
        status = "okay";
 
-       clocks = <&cpg CPG_MOD 724>,
-                <&cpg CPG_MOD 723>,
-                <&x12_clk>;
-       clock-names = "du.0", "du.1", "dclkin.0";
+       clocks = <&cpg CPG_MOD 727>,
+                <&x12_clk>,
+                <&extal_clk>;
+       clock-names = "fck", "dclkin.0", "extal";
 
        ports {
-               port@0 {
-                       endpoint {
-                               remote-endpoint = <&adv7123_in>;
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&thc63lvd1024_in>;
                        };
                };
        };
 };
 
-&ehci0 {
-       status = "okay";
+&lvds1 {
+       clocks = <&cpg CPG_MOD 727>,
+                <&x12_clk>,
+                <&extal_clk>;
+       clock-names = "fck", "dclkin.0", "extal";
 };
 
 &ohci0 {
        status = "okay";
 };
 
-&avb {
-       pinctrl-0 = <&avb0_pins>;
+&pfc {
+       avb0_pins: avb {
+               mux {
+                       groups = "avb0_link", "avb0_mdio", "avb0_mii";
+                       function = "avb0";
+               };
+       };
+
+       du_pins: du {
+               groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
+               function = "du";
+       };
+
+       i2c0_pins: i2c0 {
+               groups = "i2c0";
+               function = "i2c0";
+       };
+
+       i2c1_pins: i2c1 {
+               groups = "i2c1";
+               function = "i2c1";
+       };
+
+       pwm0_pins: pwm0 {
+               groups = "pwm0_c";
+               function = "pwm0";
+       };
+
+       pwm1_pins: pwm1 {
+               groups = "pwm1_c";
+               function = "pwm1";
+       };
+
+       scif2_pins: scif2 {
+               groups = "scif2_data";
+               function = "scif2";
+       };
+
+       sdhi2_pins: sd2 {
+               groups = "mmc_data8", "mmc_ctrl";
+               function = "mmc";
+               power-source = <1800>;
+       };
+
+       sdhi2_pins_uhs: sd2_uhs {
+               groups = "mmc_data8", "mmc_ctrl";
+               function = "mmc";
+               power-source = <1800>;
+       };
+
+       usb0_pins: usb0 {
+               groups = "usb0";
+               function = "usb0";
+       };
+
+       vin4_pins_cvbs: vin4 {
+               groups = "vin4_data8", "vin4_sync", "vin4_clk";
+               function = "vin4";
+       };
+};
+
+&pwm0 {
+       pinctrl-0 = <&pwm0_pins>;
        pinctrl-names = "default";
-       renesas,no-ether-link;
-       phy-handle = <&phy0>;
-       phy-mode = "rgmii-txid";
+
        status = "okay";
+};
 
-       phy0: ethernet-phy@0 {
-               rxc-skew-ps = <1500>;
-               reg = <0>;
-               interrupt-parent = <&gpio5>;
-               interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
-       };
+&pwm1 {
+       pinctrl-0 = <&pwm1_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&rwdt {
+       timeout-sec = <60>;
+       status = "okay";
 };
 
 &scif2 {
        status = "okay";
 };
 
-&pwm0 {
-       pinctrl-0 = <&pwm0_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
-
-&pwm1 {
-       pinctrl-0 = <&pwm1_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
-
-&rwdt {
-       timeout-sec = <60>;
-       status = "okay";
-};
-
 &vin4 {
        pinctrl-0 = <&vin4_pins_cvbs>;
        pinctrl-names = "default";
index fe77bc43c4474d1579502652b5c88c469c3201b6..214f4954b321b89b2dd58d8b81cd48ce0a1bb8ff 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the r8a77995 SoC
+ * Device Tree Source for the R-Car D3 (R8A77995) SoC
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
                        resets = <&cpg 219>;
                        #dma-cells = <1>;
                        dma-channels = <8>;
+                       iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+                              <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+                              <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+                              <&ipmmu_ds0 6>, <&ipmmu_ds0 7>;
                };
 
                dmac1: dma-controller@e7300000 {
                        resets = <&cpg 218>;
                        #dma-cells = <1>;
                        dma-channels = <8>;
+                       iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
+                              <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
+                              <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
+                              <&ipmmu_ds1 6>, <&ipmmu_ds1 7>;
                };
 
                dmac2: dma-controller@e7310000 {
                        resets = <&cpg 217>;
                        #dma-cells = <1>;
                        dma-channels = <8>;
+                       iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
+                              <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
+                              <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
+                              <&ipmmu_ds1 22>, <&ipmmu_ds1 23>;
                };
 
                ipmmu_ds0: mmu@e6740000 {
                        compatible = "generic-ohci";
                        reg = <0 0xee080000 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                        compatible = "generic-ehci";
                        reg = <0 0xee080100 0 0x100>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        phys = <&usb2_phy0>;
                        phy-names = "usb";
                        companion = <&ohci0>;
                        power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        status = "disabled";
                };
 
                                     "renesas,rcar-gen3-usb2-phy";
                        reg = <0 0xee080200 0 0x700>;
                        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 703>;
+                       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
                        power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-                       resets = <&cpg 703>;
+                       resets = <&cpg 703>, <&cpg 704>;
                        #phy-cells = <0>;
                        status = "disabled";
                };
                                port@1 {
                                        reg = <1>;
                                        du_out_lvds0: endpoint {
+                                               remote-endpoint = <&lvds0_in>;
                                        };
                                };
 
                                port@2 {
                                        reg = <2>;
                                        du_out_lvds1: endpoint {
+                                               remote-endpoint = <&lvds1_in>;
+                                       };
+                               };
+                       };
+               };
+
+               lvds0: lvds-encoder@feb90000 {
+                       compatible = "renesas,r8a77995-lvds";
+                       reg = <0 0xfeb90000 0 0x20>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 727>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds0_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds0>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       lvds0_out: endpoint {
+                                       };
+                               };
+                       };
+               };
+
+               lvds1: lvds-encoder@feb90100 {
+                       compatible = "renesas,r8a77995-lvds";
+                       reg = <0 0xfeb90100 0 0x20>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 726>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds1_in: endpoint {
+                                               remote-endpoint = <&du_out_lvds1>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       lvds1_out: endpoint {
                                        };
                                };
                        };
index 7d3d866a006352ac196b52002c9c9ce8899f5208..7f91ff5241091b2fca66f9059911f50360628803 100644 (file)
 
        video-receiver@70 {
                compatible = "adi,adv7482";
-               reg = <0x70>;
+               reg = <0x70 0x71 0x72 0x73 0x74 0x75
+                      0x60 0x61 0x62 0x63 0x64 0x65>;
+               reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
+                           "infoframe", "cbus", "cec", "sdp", "txa", "txb" ;
 
                #address-cells = <1>;
                #size-cells = <0>;
 &i2c_dvfs {
        status = "okay";
 
+       clock-frequency = <400000>;
+
        pmic: pmic@30 {
                pinctrl-0 = <&irq0_pins>;
                pinctrl-names = "default";
        wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
        bus-width = <4>;
        sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
 };
 
        wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
        bus-width = <4>;
        sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
 };
 
index 8bf3091a899c81ce9234ab05cfcb8aa9542700d7..1b316d79df88ca50f18b4deace7d4e6f718a4271 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x71>;
-               reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
        };
 };
 
index 0ead552d7eae9678cda710c897b84b3f45964c13..89daca7356dfad191c4ddaede20134b59c5445d9 100644 (file)
@@ -18,6 +18,7 @@
        };
 
        chosen {
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
                stdout-path = "serial0:115200n8";
        };
 
 &i2c_dvfs {
        status = "okay";
 
+       clock-frequency = <400000>;
+
        pmic: pmic@30 {
                pinctrl-0 = <&irq0_pins>;
                pinctrl-names = "default";
        cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
        bus-width = <4>;
        sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
 };
 
index b0092d95b574dcc0256f9f5e244e07b4ff794c38..49042c47787031de279376e06d78646d2b812824 100644 (file)
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
@@ -14,5 +15,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
diff --git a/arch/arm64/boot/dts/rockchip/px30-evb.dts b/arch/arm64/boot/dts/rockchip/px30-evb.dts
new file mode 100644 (file)
index 0000000..263d7f3
--- /dev/null
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "px30.dtsi"
+
+/ {
+       model = "Rockchip PX30 EVB";
+       compatible = "rockchip,px30-evb", "rockchip,px30";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       adc-keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 2>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+               poll-interval = <100>;
+
+               esc-key {
+                       label = "esc";
+                       linux,code = <KEY_ESC>;
+                       press-threshold-microvolt = <1310000>;
+               };
+
+               home-key {
+                       label = "home";
+                       linux,code = <KEY_HOME>;
+                       press-threshold-microvolt = <624000>;
+               };
+
+               menu-key {
+                       label = "menu";
+                       linux,code = <KEY_MENU>;
+                       press-threshold-microvolt = <987000>;
+               };
+
+               vol-down-key {
+                       label = "volume down";
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       press-threshold-microvolt = <300000>;
+               };
+
+               vol-up-key {
+                       label = "volume up";
+                       linux,code = <KEY_VOLUMEUP>;
+                       press-threshold-microvolt = <17000>;
+               };
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 25000 0>;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_enable_h>;
+
+               /*
+                * On the module itself this is one of these (depending
+                * on the actual card populated):
+                * - SDIO_RESET_L_WL_REG_ON
+                * - PDN (power down when low)
+                */
+               reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */
+       };
+
+       vcc_phy: vcc-phy-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_phy";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc5v0_sys: vccsys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+};
+
+&display_subsystem {
+       status = "okay";
+};
+
+&emmc {
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       mmc-hs200-1_8v;
+       non-removable;
+       status = "okay";
+};
+
+&gmac {
+       clock_in_out = "output";
+       phy-supply = <&vcc_phy>;
+       snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 50000 50000>;
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2s1_2ch {
+       status = "okay";
+};
+
+&io_domains {
+       status = "okay";
+};
+
+&pinctrl {
+       headphone {
+               hp_det: hp-det {
+                       rockchip,pins =
+                               <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       pmic {
+               pmic_int: pmic_int {
+                       rockchip,pins =
+                               <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               soc_slppin_gpio: soc_slppin_gpio {
+                       rockchip,pins =
+                               <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               soc_slppin_slp: soc_slppin_slp {
+                       rockchip,pins =
+                               <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>;
+               };
+
+               soc_slppin_rst: soc_slppin_rst {
+                       rockchip,pins =
+                               <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>;
+               };
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h: wifi-enable-h {
+                       rockchip,pins =
+                               <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pmu_io_domains {
+       status = "okay";
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&saradc {
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       card-detect-delay = <800>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+       status = "okay";
+};
+
+&sdio {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       keep-power-in-suspend;
+       non-removable;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       sd-uhs-sdr104;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_xfer &uart1_cts>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb20_otg {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
new file mode 100644 (file)
index 0000000..9aa8d5e
--- /dev/null
@@ -0,0 +1,2047 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <dt-bindings/clock/px30-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/power/px30-power.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
+
+/ {
+       compatible = "rockchip,px30";
+
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               ethernet0 = &gmac;
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               serial5 = &uart5;
+               spi0 = &spi0;
+               spi1 = &spi1;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       dynamic-power-coefficient = <90>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       dynamic-power-coefficient = <90>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       dynamic-power-coefficient = <90>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a35", "arm,armv8";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+                       clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       dynamic-power-coefficient = <90>;
+                       operating-points-v2 = <&cpu0_opp_table>;
+               };
+
+               idle-states {
+                       entry-method = "psci";
+
+                       CPU_SLEEP: cpu-sleep {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <120>;
+                               exit-latency-us = <250>;
+                               min-residency-us = <900>;
+                       };
+
+                       CLUSTER_SLEEP: cluster-sleep {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x1010000>;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <500>;
+                               min-residency-us = <2000>;
+                       };
+               };
+       };
+
+       cpu0_opp_table: cpu0-opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-408000000 {
+                       opp-hz = /bits/ 64 <408000000>;
+                       opp-microvolt = <950000 950000 1350000>;
+                       clock-latency-ns = <40000>;
+                       opp-suspend;
+               };
+               opp-600000000 {
+                       opp-hz = /bits/ 64 <600000000>;
+                       opp-microvolt = <950000 950000 1350000>;
+                       clock-latency-ns = <40000>;
+               };
+               opp-816000000 {
+                       opp-hz = /bits/ 64 <816000000>;
+                       opp-microvolt = <1050000 1050000 1350000>;
+                       clock-latency-ns = <40000>;
+               };
+               opp-1008000000 {
+                       opp-hz = /bits/ 64 <1008000000>;
+                       opp-microvolt = <1175000 1175000 1350000>;
+                       clock-latency-ns = <40000>;
+               };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <1300000 1300000 1350000>;
+                       clock-latency-ns = <40000>;
+               };
+               opp-1296000000 {
+                       opp-hz = /bits/ 64 <1296000000>;
+                       opp-microvolt = <1350000 1350000 1350000>;
+                       clock-latency-ns = <40000>;
+               };
+       };
+
+       arm-pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
+       display_subsystem: display-subsystem {
+               compatible = "rockchip,display-subsystem";
+               ports = <&vopb_out>, <&vopl_out>;
+               status = "disabled";
+       };
+
+       firmware {
+               optee {
+                       compatible = "linaro,optee-tz";
+                       method = "smc";
+               };
+       };
+
+       gmac_clkin: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <50000000>;
+               clock-output-names = "gmac_clkin";
+               #clock-cells = <0>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       xin24m: xin24m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+               clock-output-names = "xin24m";
+       };
+
+       xin32k: xin32k {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "xin32k";
+       };
+
+       pmu: power-management@ff000000 {
+               compatible = "rockchip,px30-pmu", "syscon", "simple-mfd";
+               reg = <0x0 0xff000000 0x0 0x1000>;
+
+               power: power-controller {
+                       compatible = "rockchip,px30-power-controller";
+                       #power-domain-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       /* These power domains are grouped by VD_LOGIC */
+                       pd_usb@PX30_PD_USB {
+                               reg = <PX30_PD_USB>;
+                               clocks = <&cru HCLK_HOST>,
+                                        <&cru HCLK_OTG>,
+                                        <&cru SCLK_OTG_ADP>;
+                               pm_qos = <&qos_usb_host>, <&qos_usb_otg>;
+                       };
+                       pd_sdcard@PX30_PD_SDCARD {
+                               reg = <PX30_PD_SDCARD>;
+                               clocks = <&cru HCLK_SDMMC>,
+                                        <&cru SCLK_SDMMC>;
+                               pm_qos = <&qos_sdmmc>;
+                       };
+                       pd_gmac@PX30_PD_GMAC {
+                               reg = <PX30_PD_GMAC>;
+                               clocks = <&cru ACLK_GMAC>,
+                                        <&cru PCLK_GMAC>,
+                                        <&cru SCLK_MAC_REF>,
+                                        <&cru SCLK_GMAC_RX_TX>;
+                               pm_qos = <&qos_gmac>;
+                       };
+                       pd_mmc_nand@PX30_PD_MMC_NAND {
+                               reg = <PX30_PD_MMC_NAND>;
+                               clocks =  <&cru HCLK_NANDC>,
+                                         <&cru HCLK_EMMC>,
+                                         <&cru HCLK_SDIO>,
+                                         <&cru HCLK_SFC>,
+                                         <&cru SCLK_EMMC>,
+                                         <&cru SCLK_NANDC>,
+                                         <&cru SCLK_SDIO>,
+                                         <&cru SCLK_SFC>;
+                               pm_qos = <&qos_emmc>, <&qos_nand>,
+                                        <&qos_sdio>, <&qos_sfc>;
+                       };
+                       pd_vpu@PX30_PD_VPU {
+                               reg = <PX30_PD_VPU>;
+                               clocks = <&cru ACLK_VPU>,
+                                        <&cru HCLK_VPU>,
+                                        <&cru SCLK_CORE_VPU>;
+                               pm_qos = <&qos_vpu>, <&qos_vpu_r128>;
+                       };
+                       pd_vo@PX30_PD_VO {
+                               reg = <PX30_PD_VO>;
+                               clocks = <&cru ACLK_RGA>,
+                                        <&cru ACLK_VOPB>,
+                                        <&cru ACLK_VOPL>,
+                                        <&cru DCLK_VOPB>,
+                                        <&cru DCLK_VOPL>,
+                                        <&cru HCLK_RGA>,
+                                        <&cru HCLK_VOPB>,
+                                        <&cru HCLK_VOPL>,
+                                        <&cru PCLK_MIPI_DSI>,
+                                        <&cru SCLK_RGA_CORE>,
+                                        <&cru SCLK_VOPB_PWM>;
+                               pm_qos = <&qos_rga_rd>, <&qos_rga_wr>,
+                                        <&qos_vop_m0>, <&qos_vop_m1>;
+                       };
+                       pd_vi@PX30_PD_VI {
+                               reg = <PX30_PD_VI>;
+                               clocks = <&cru ACLK_CIF>,
+                                        <&cru ACLK_ISP>,
+                                        <&cru HCLK_CIF>,
+                                        <&cru HCLK_ISP>,
+                                        <&cru SCLK_ISP>;
+                               pm_qos = <&qos_isp_128>, <&qos_isp_rd>,
+                                        <&qos_isp_wr>, <&qos_isp_m1>,
+                                        <&qos_vip>;
+                       };
+                       pd_gpu@PX30_PD_GPU {
+                               reg = <PX30_PD_GPU>;
+                               clocks = <&cru SCLK_GPU>;
+                               pm_qos = <&qos_gpu>;
+                       };
+               };
+       };
+
+       pmugrf: syscon@ff010000 {
+               compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd";
+               reg = <0x0 0xff010000 0x0 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               pmu_io_domains: io-domains {
+                       compatible = "rockchip,px30-pmu-io-voltage-domain";
+                       status = "disabled";
+               };
+
+               reboot-mode {
+                       compatible = "syscon-reboot-mode";
+                       offset = <0x200>;
+                       mode-bootloader = <BOOT_BL_DOWNLOAD>;
+                       mode-fastboot = <BOOT_FASTBOOT>;
+                       mode-loader = <BOOT_BL_DOWNLOAD>;
+                       mode-normal = <BOOT_NORMAL>;
+                       mode-recovery = <BOOT_RECOVERY>;
+               };
+       };
+
+       uart0: serial@ff030000 {
+               compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff030000 0x0 0x100>;
+               interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>;
+               clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 0>, <&dmac 1>;
+               dma-names = "tx", "rx";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+               status = "disabled";
+       };
+
+       i2s1_2ch: i2s@ff070000 {
+               compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff070000 0x0 0x1000>;
+               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
+               clock-names = "i2s_clk", "i2s_hclk";
+               dmas = <&dmac 18>, <&dmac 19>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s1_2ch_sclk &i2s1_2ch_lrck
+                            &i2s1_2ch_sdi &i2s1_2ch_sdo>;
+               #sound-dai-cells = <0>;
+               status = "disabled";
+       };
+
+       i2s2_2ch: i2s@ff080000 {
+               compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
+               reg = <0x0 0xff080000 0x0 0x1000>;
+               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
+               clock-names = "i2s_clk", "i2s_hclk";
+               dmas = <&dmac 20>, <&dmac 21>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s2_2ch_sclk &i2s2_2ch_lrck
+                            &i2s2_2ch_sdi &i2s2_2ch_sdo>;
+               #sound-dai-cells = <0>;
+               status = "disabled";
+       };
+
+       gic: interrupt-controller@ff131000 {
+               compatible = "arm,gic-400";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0x0 0xff131000 0 0x1000>,
+                     <0x0 0xff132000 0 0x2000>,
+                     <0x0 0xff134000 0 0x2000>,
+                     <0x0 0xff136000 0 0x2000>;
+               interrupts = <GIC_PPI 9
+                     (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+       };
+
+       grf: syscon@ff140000 {
+               compatible = "rockchip,px30-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xff140000 0x0 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               io_domains: io-domains {
+                       compatible = "rockchip,px30-io-voltage-domain";
+                       status = "disabled";
+               };
+       };
+
+       uart1: serial@ff158000 {
+               compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff158000 0x0 0x100>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+               clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 2>, <&dmac 3>;
+               dma-names = "tx", "rx";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
+               status = "disabled";
+       };
+
+       uart2: serial@ff160000 {
+               compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff160000 0x0 0x100>;
+               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+               clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 4>, <&dmac 5>;
+               dma-names = "tx", "rx";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart2m0_xfer>;
+               status = "disabled";
+       };
+
+       uart3: serial@ff168000 {
+               compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff168000 0x0 0x100>;
+               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+               clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 6>, <&dmac 7>;
+               dma-names = "tx", "rx";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>;
+               status = "disabled";
+       };
+
+       uart4: serial@ff170000 {
+               compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff170000 0x0 0x100>;
+               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+               clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 8>, <&dmac 9>;
+               dma-names = "tx", "rx";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
+               status = "disabled";
+       };
+
+       uart5: serial@ff178000 {
+               compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+               reg = <0x0 0xff178000 0x0 0x100>;
+               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+               clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 10>, <&dmac 11>;
+               dma-names = "tx", "rx";
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>;
+               status = "disabled";
+       };
+
+       i2c0: i2c@ff180000 {
+               compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff180000 0x0 0x1000>;
+               clocks =  <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c0_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c1: i2c@ff190000 {
+               compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff190000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c1_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c2: i2c@ff1a0000 {
+               compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff1a0000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c3: i2c@ff1b0000 {
+               compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+               reg = <0x0 0xff1b0000 0x0 0x1000>;
+               clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
+               clock-names = "i2c", "pclk";
+               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c3_xfer>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi0: spi@ff1d0000 {
+               compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff1d0000 0x0 0x1000>;
+               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+               clock-names = "spiclk", "apb_pclk";
+               dmas = <&dmac 12>, <&dmac 13>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       spi1: spi@ff1d8000 {
+               compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
+               reg = <0x0 0xff1d8000 0x0 0x1000>;
+               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+               clock-names = "spiclk", "apb_pclk";
+               dmas = <&dmac 14>, <&dmac 15>;
+               dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       wdt: watchdog@ff1e0000 {
+               compatible = "snps,dw-wdt";
+               reg = <0x0 0xff1e0000 0x0 0x100>;
+               clocks = <&cru PCLK_WDT_NS>;
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               status = "disabled";
+       };
+
+       pwm0: pwm@ff200000 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff200000 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm0_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm1: pwm@ff200010 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff200010 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm1_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm2: pwm@ff200020 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff200020 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm2_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm3: pwm@ff200030 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff200030 0x0 0x10>;
+               clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm3_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm4: pwm@ff208000 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff208000 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm4_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm5: pwm@ff208010 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff208010 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm5_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm6: pwm@ff208020 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff208020 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm6_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       pwm7: pwm@ff208030 {
+               compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+               reg = <0x0 0xff208030 0x0 0x10>;
+               clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+               clock-names = "pwm", "pclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwm7_pin>;
+               #pwm-cells = <3>;
+               status = "disabled";
+       };
+
+       rktimer: timer@ff210000 {
+               compatible = "rockchip,px30-timer", "rockchip,rk3288-timer";
+               reg = <0x0 0xff210000 0x0 0x1000>;
+               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>;
+               clock-names = "pclk", "timer";
+       };
+
+       amba {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               dmac: dmac@ff240000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x0 0xff240000 0x0 0x4000>;
+                       interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru ACLK_DMAC>;
+                       clock-names = "apb_pclk";
+                       #dma-cells = <1>;
+               };
+       };
+
+       saradc: saradc@ff288000 {
+               compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc";
+               reg = <0x0 0xff288000 0x0 0x100>;
+               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+               #io-channel-cells = <1>;
+               clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+               clock-names = "saradc", "apb_pclk";
+               resets = <&cru SRST_SARADC_P>;
+               reset-names = "saradc-apb";
+               status = "disabled";
+       };
+
+       cru: clock-controller@ff2b0000 {
+               compatible = "rockchip,px30-cru";
+               reg = <0x0 0xff2b0000 0x0 0x1000>;
+               rockchip,grf = <&grf>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+
+               assigned-clocks = <&cru PLL_NPLL>;
+               assigned-clock-rates = <1188000000>;
+       };
+
+       pmucru: clock-controller@ff2bc000 {
+               compatible = "rockchip,px30-pmucru";
+               reg = <0x0 0xff2bc000 0x0 0x1000>;
+               rockchip,grf = <&grf>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+
+               assigned-clocks =
+                       <&pmucru PLL_GPLL>, <&pmucru PCLK_PMU_PRE>,
+                       <&pmucru SCLK_WIFI_PMU>, <&cru ARMCLK>,
+                       <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
+                       <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>,
+                       <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>;
+               assigned-clock-rates =
+                       <1200000000>, <100000000>,
+                       <26000000>, <600000000>,
+                       <200000000>, <200000000>,
+                       <150000000>, <150000000>,
+                       <100000000>, <200000000>;
+       };
+
+       usb20_otg: usb@ff300000 {
+               compatible = "rockchip,px30-usb", "rockchip,rk3066-usb",
+                            "snps,dwc2";
+               reg = <0x0 0xff300000 0x0 0x40000>;
+               interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_OTG>;
+               clock-names = "otg";
+               dr_mode = "otg";
+               g-np-tx-fifo-size = <16>;
+               g-rx-fifo-size = <280>;
+               g-tx-fifo-size = <256 128 128 64 32 16>;
+               g-use-dma;
+               power-domains = <&power PX30_PD_USB>;
+               status = "disabled";
+       };
+
+       usb_host0_ehci: usb@ff340000 {
+               compatible = "generic-ehci";
+               reg = <0x0 0xff340000 0x0 0x10000>;
+               interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_HOST>;
+               clock-names = "usbhost";
+               power-domains = <&power PX30_PD_USB>;
+               status = "disabled";
+       };
+
+       usb_host0_ohci: usb@ff350000 {
+               compatible = "generic-ohci";
+               reg = <0x0 0xff350000 0x0 0x10000>;
+               interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_HOST>;
+               clock-names = "usbhost";
+               power-domains = <&power PX30_PD_USB>;
+               status = "disabled";
+       };
+
+       gmac: ethernet@ff360000 {
+               compatible = "rockchip,px30-gmac";
+               reg = <0x0 0xff360000 0x0 0x10000>;
+               interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "macirq";
+               clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>,
+                        <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>,
+                        <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>,
+                        <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>;
+               clock-names = "stmmaceth", "mac_clk_rx",
+                             "mac_clk_tx", "clk_mac_ref",
+                             "clk_mac_refout", "aclk_mac",
+                             "pclk_mac", "clk_mac_speed";
+               rockchip,grf = <&grf>;
+               phy-mode = "rmii";
+               pinctrl-names = "default";
+               pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
+               power-domains = <&power PX30_PD_GMAC>;
+               resets = <&cru SRST_GMAC_A>;
+               reset-names = "stmmaceth";
+               status = "disabled";
+       };
+
+       sdmmc: dwmmc@ff370000 {
+               compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xff370000 0x0 0x4000>;
+               interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+                        <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               fifo-depth = <0x100>;
+               max-frequency = <150000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+               power-domains = <&power PX30_PD_SDCARD>;
+               status = "disabled";
+       };
+
+       sdio: dwmmc@ff380000 {
+               compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xff380000 0x0 0x4000>;
+               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+                        <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               fifo-depth = <0x100>;
+               max-frequency = <150000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>;
+               power-domains = <&power PX30_PD_MMC_NAND>;
+               status = "disabled";
+       };
+
+       emmc: dwmmc@ff390000 {
+               compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+               reg = <0x0 0xff390000 0x0 0x4000>;
+               interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+                        <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               fifo-depth = <0x100>;
+               max-frequency = <150000000>;
+               power-domains = <&power PX30_PD_MMC_NAND>;
+               status = "disabled";
+       };
+
+       vopb: vop@ff460000 {
+               compatible = "rockchip,px30-vop-big";
+               reg = <0x0 0xff460000 0x0 0xefc>;
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>,
+                        <&cru HCLK_VOPB>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_VOPB_A>, <&cru SRST_VOPB_H>, <&cru SRST_VOPB>;
+               reset-names = "axi", "ahb", "dclk";
+               iommus = <&vopb_mmu>;
+               power-domains = <&power PX30_PD_VO>;
+               rockchip,grf = <&grf>;
+               status = "disabled";
+
+               vopb_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+
+       vopb_mmu: iommu@ff460f00 {
+               compatible = "rockchip,iommu";
+               reg = <0x0 0xff460f00 0x0 0x100>;
+               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "vopb_mmu";
+               clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>;
+               clock-names = "aclk", "hclk";
+               power-domains = <&power PX30_PD_VO>;
+               #iommu-cells = <0>;
+               status = "disabled";
+       };
+
+       vopl: vop@ff470000 {
+               compatible = "rockchip,px30-vop-lit";
+               reg = <0x0 0xff470000 0x0 0xefc>;
+               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>,
+                        <&cru HCLK_VOPL>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_VOPL_A>, <&cru SRST_VOPL_H>, <&cru SRST_VOPL>;
+               reset-names = "axi", "ahb", "dclk";
+               iommus = <&vopl_mmu>;
+               power-domains = <&power PX30_PD_VO>;
+               rockchip,grf = <&grf>;
+               status = "disabled";
+
+               vopl_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+
+       vopl_mmu: iommu@ff470f00 {
+               compatible = "rockchip,iommu";
+               reg = <0x0 0xff470f00 0x0 0x100>;
+               interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "vopl_mmu";
+               clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>;
+               clock-names = "aclk", "hclk";
+               power-domains = <&power PX30_PD_VO>;
+               #iommu-cells = <0>;
+               status = "disabled";
+       };
+
+       qos_gmac: qos@ff518000 {
+               compatible = "syscon";
+               reg = <0x0 0xff518000 0x0 0x20>;
+       };
+
+       qos_gpu: qos@ff520000 {
+               compatible = "syscon";
+               reg = <0x0 0xff520000 0x0 0x20>;
+       };
+
+       qos_sdmmc: qos@ff52c000 {
+               compatible = "syscon";
+               reg = <0x0 0xff52c000 0x0 0x20>;
+       };
+
+       qos_emmc: qos@ff538000 {
+               compatible = "syscon";
+               reg = <0x0 0xff538000 0x0 0x20>;
+       };
+
+       qos_nand: qos@ff538080 {
+               compatible = "syscon";
+               reg = <0x0 0xff538080 0x0 0x20>;
+       };
+
+       qos_sdio: qos@ff538100 {
+               compatible = "syscon";
+               reg = <0x0 0xff538100 0x0 0x20>;
+       };
+
+       qos_sfc: qos@ff538180 {
+               compatible = "syscon";
+               reg = <0x0 0xff538180 0x0 0x20>;
+       };
+
+       qos_usb_host: qos@ff540000 {
+               compatible = "syscon";
+               reg = <0x0 0xff540000 0x0 0x20>;
+       };
+
+       qos_usb_otg: qos@ff540080 {
+               compatible = "syscon";
+               reg = <0x0 0xff540080 0x0 0x20>;
+       };
+
+       qos_isp_128: qos@ff548000 {
+               compatible = "syscon";
+               reg = <0x0 0xff548000 0x0 0x20>;
+       };
+
+       qos_isp_rd: qos@ff548080 {
+               compatible = "syscon";
+               reg = <0x0 0xff548080 0x0 0x20>;
+       };
+
+       qos_isp_wr: qos@ff548100 {
+               compatible = "syscon";
+               reg = <0x0 0xff548100 0x0 0x20>;
+       };
+
+       qos_isp_m1: qos@ff548180 {
+               compatible = "syscon";
+               reg = <0x0 0xff548180 0x0 0x20>;
+       };
+
+       qos_vip: qos@ff548200 {
+               compatible = "syscon";
+               reg = <0x0 0xff548200 0x0 0x20>;
+       };
+
+       qos_rga_rd: qos@ff550000 {
+               compatible = "syscon";
+               reg = <0x0 0xff550000 0x0 0x20>;
+       };
+
+       qos_rga_wr: qos@ff550080 {
+               compatible = "syscon";
+               reg = <0x0 0xff550080 0x0 0x20>;
+       };
+
+       qos_vop_m0: qos@ff550100 {
+               compatible = "syscon";
+               reg = <0x0 0xff550100 0x0 0x20>;
+       };
+
+       qos_vop_m1: qos@ff550180 {
+               compatible = "syscon";
+               reg = <0x0 0xff550180 0x0 0x20>;
+       };
+
+       qos_vpu: qos@ff558000 {
+               compatible = "syscon";
+               reg = <0x0 0xff558000 0x0 0x20>;
+       };
+
+       qos_vpu_r128: qos@ff558080 {
+               compatible = "syscon";
+               reg = <0x0 0xff558080 0x0 0x20>;
+       };
+
+       pinctrl: pinctrl {
+               compatible = "rockchip,px30-pinctrl";
+               rockchip,grf = <&grf>;
+               rockchip,pmu = <&pmugrf>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               gpio0: gpio0@ff040000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff040000 0x0 0x100>;
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&pmucru PCLK_GPIO0_PMU>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio1: gpio1@ff250000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff250000 0x0 0x100>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO1>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio2: gpio2@ff260000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff260000 0x0 0x100>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO2>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio3: gpio3@ff270000 {
+                       compatible = "rockchip,gpio-bank";
+                       reg = <0x0 0xff270000 0x0 0x100>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cru PCLK_GPIO3>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               pcfg_pull_up: pcfg-pull-up {
+                       bias-pull-up;
+               };
+
+               pcfg_pull_down: pcfg-pull-down {
+                       bias-pull-down;
+               };
+
+               pcfg_pull_none: pcfg-pull-none {
+                       bias-disable;
+               };
+
+               pcfg_pull_none_2ma: pcfg-pull-none-2ma {
+                       bias-disable;
+                       drive-strength = <2>;
+               };
+
+               pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+
+               pcfg_pull_up_4ma: pcfg-pull-up-4ma {
+                       bias-pull-up;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_none_4ma: pcfg-pull-none-4ma {
+                       bias-disable;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+                       bias-pull-down;
+                       drive-strength = <4>;
+               };
+
+               pcfg_pull_none_8ma: pcfg-pull-none-8ma {
+                       bias-disable;
+                       drive-strength = <8>;
+               };
+
+               pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+                       bias-pull-up;
+                       drive-strength = <8>;
+               };
+
+               pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+                       bias-disable;
+                       drive-strength = <12>;
+               };
+
+               pcfg_pull_up_12ma: pcfg-pull-up-12ma {
+                       bias-pull-up;
+                       drive-strength = <12>;
+               };
+
+               pcfg_pull_none_smt: pcfg-pull-none-smt {
+                       bias-disable;
+                       input-schmitt-enable;
+               };
+
+               pcfg_output_high: pcfg-output-high {
+                       output-high;
+               };
+
+               pcfg_output_low: pcfg-output-low {
+                       output-low;
+               };
+
+               pcfg_input_high: pcfg-input-high {
+                       bias-pull-up;
+                       input-enable;
+               };
+
+               pcfg_input: pcfg-input {
+                       input-enable;
+               };
+
+               i2c0 {
+                       i2c0_xfer: i2c0-xfer {
+                               rockchip,pins =
+                                       <0 RK_PB0 1 &pcfg_pull_none_smt>,
+                                       <0 RK_PB1 1 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c1 {
+                       i2c1_xfer: i2c1-xfer {
+                               rockchip,pins =
+                                       <0 RK_PC2 1 &pcfg_pull_none_smt>,
+                                       <0 RK_PC3 1 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c2 {
+                       i2c2_xfer: i2c2-xfer {
+                               rockchip,pins =
+                                       <2 RK_PB7 2 &pcfg_pull_none_smt>,
+                                       <2 RK_PC0 2 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               i2c3 {
+                       i2c3_xfer: i2c3-xfer {
+                               rockchip,pins =
+                                       <1 RK_PB4 4 &pcfg_pull_none_smt>,
+                                       <1 RK_PB5 4 &pcfg_pull_none_smt>;
+                       };
+               };
+
+               tsadc {
+                       tsadc_otp_gpio: tsadc-otp-gpio {
+                               rockchip,pins =
+                                       <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+
+                       tsadc_otp_out: tsadc-otp-out {
+                               rockchip,pins =
+                                       <0 RK_PA6 1 &pcfg_pull_none>;
+                       };
+               };
+
+               uart0 {
+                       uart0_xfer: uart0-xfer {
+                               rockchip,pins =
+                                       <0 RK_PB2 1 &pcfg_pull_up>,
+                                       <0 RK_PB3 1 &pcfg_pull_up>;
+                       };
+
+                       uart0_cts: uart0-cts {
+                               rockchip,pins =
+                                       <0 RK_PB4 1 &pcfg_pull_none>;
+                       };
+
+                       uart0_rts: uart0-rts {
+                               rockchip,pins =
+                                       <0 RK_PB5 1 &pcfg_pull_none>;
+                       };
+
+                       uart0_rts_gpio: uart0-rts-gpio {
+                               rockchip,pins =
+                                       <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+               };
+
+               uart1 {
+                       uart1_xfer: uart1-xfer {
+                               rockchip,pins =
+                                       <1 RK_PC1 1 &pcfg_pull_up>,
+                                       <1 RK_PC0 1 &pcfg_pull_up>;
+                       };
+
+                       uart1_cts: uart1-cts {
+                               rockchip,pins =
+                                       <1 RK_PC2 1 &pcfg_pull_none>;
+                       };
+
+                       uart1_rts: uart1-rts {
+                               rockchip,pins =
+                                       <1 RK_PC3 1 &pcfg_pull_none>;
+                       };
+
+                       uart1_rts_gpio: uart1-rts-gpio {
+                               rockchip,pins =
+                                       <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+               };
+
+               uart2-m0 {
+                       uart2m0_xfer: uart2m0-xfer {
+                               rockchip,pins =
+                                       <1 RK_PD2 2 &pcfg_pull_up>,
+                                       <1 RK_PD3 2 &pcfg_pull_up>;
+                       };
+               };
+
+               uart2-m1 {
+                       uart2m1_xfer: uart2m1-xfer {
+                               rockchip,pins =
+                                       <2 RK_PB4 2 &pcfg_pull_up>,
+                                       <2 RK_PB6 2 &pcfg_pull_up>;
+                       };
+               };
+
+               uart3-m0 {
+                       uart3m0_xfer: uart3m0-xfer {
+                               rockchip,pins =
+                                       <0 RK_PC0 2 &pcfg_pull_up>,
+                                       <0 RK_PC1 2 &pcfg_pull_up>;
+                       };
+
+                       uart3m0_cts: uart3m0-cts {
+                               rockchip,pins =
+                                       <0 RK_PC2 2 &pcfg_pull_none>;
+                       };
+
+                       uart3m0_rts: uart3m0-rts {
+                               rockchip,pins =
+                                       <0 RK_PC3 2 &pcfg_pull_none>;
+                       };
+
+                       uart3m0_rts_gpio: uart3m0-rts-gpio {
+                               rockchip,pins =
+                                       <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+               };
+
+               uart3-m1 {
+                       uart3m1_xfer: uart3m1-xfer {
+                               rockchip,pins =
+                                       <1 RK_PB6 2 &pcfg_pull_up>,
+                                       <1 RK_PB7 2 &pcfg_pull_up>;
+                       };
+
+                       uart3m1_cts: uart3m1-cts {
+                               rockchip,pins =
+                                       <1 RK_PB4 2 &pcfg_pull_none>;
+                       };
+
+                       uart3m1_rts: uart3m1-rts {
+                               rockchip,pins =
+                                       <1 RK_PB5 2 &pcfg_pull_none>;
+                       };
+
+                       uart3m1_rts_gpio: uart3m1-rts-gpio {
+                               rockchip,pins =
+                                       <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+               };
+
+               uart4 {
+                       uart4_xfer: uart4-xfer {
+                               rockchip,pins =
+                                       <1 RK_PD4 2 &pcfg_pull_up>,
+                                       <1 RK_PD5 2 &pcfg_pull_up>;
+                       };
+
+                       uart4_cts: uart4-cts {
+                               rockchip,pins =
+                                       <1 RK_PD6 2 &pcfg_pull_none>;
+                       };
+
+                       uart4_rts: uart4-rts {
+                               rockchip,pins =
+                                       <1 RK_PD7 2 &pcfg_pull_none>;
+                       };
+               };
+
+               uart5 {
+                       uart5_xfer: uart5-xfer {
+                               rockchip,pins =
+                                       <3 RK_PA2 4 &pcfg_pull_up>,
+                                       <3 RK_PA1 4 &pcfg_pull_up>;
+                       };
+
+                       uart5_cts: uart5-cts {
+                               rockchip,pins =
+                                       <3 RK_PA3 4 &pcfg_pull_none>;
+                       };
+
+                       uart5_rts: uart5-rts {
+                               rockchip,pins =
+                                       <3 RK_PA5 4 &pcfg_pull_none>;
+                       };
+               };
+
+               spi0 {
+                       spi0_clk: spi0-clk {
+                               rockchip,pins =
+                                       <1 RK_PB7 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_csn: spi0-csn {
+                               rockchip,pins =
+                                       <1 RK_PB6 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_miso: spi0-miso {
+                               rockchip,pins =
+                                       <1 RK_PB5 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_mosi: spi0-mosi {
+                               rockchip,pins =
+                                       <1 RK_PB4 3 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi0_clk_hs: spi0-clk-hs {
+                               rockchip,pins =
+                                       <1 RK_PB7 3 &pcfg_pull_up_8ma>;
+                       };
+
+                       spi0_miso_hs: spi0-miso-hs {
+                               rockchip,pins =
+                                       <1 RK_PB5 3 &pcfg_pull_up_8ma>;
+                       };
+
+                       spi0_mosi_hs: spi0-mosi-hs {
+                               rockchip,pins =
+                                       <1 RK_PB4 3 &pcfg_pull_up_8ma>;
+                       };
+               };
+
+               spi1 {
+                       spi1_clk: spi1-clk {
+                               rockchip,pins =
+                                       <3 RK_PB7 4 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_csn0: spi1-csn0 {
+                               rockchip,pins =
+                                       <3 RK_PB1 4 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_csn1: spi1-csn1 {
+                               rockchip,pins =
+                                       <3 RK_PB2 2 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_miso: spi1-miso {
+                               rockchip,pins =
+                                       <3 RK_PB6 4 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_mosi: spi1-mosi {
+                               rockchip,pins =
+                                       <3 RK_PB4 4 &pcfg_pull_up_4ma>;
+                       };
+
+                       spi1_clk_hs: spi1-clk-hs {
+                               rockchip,pins =
+                                       <3 RK_PB7 4 &pcfg_pull_up_8ma>;
+                       };
+
+                       spi1_miso_hs: spi1-miso-hs {
+                               rockchip,pins =
+                                       <3 RK_PB6 4 &pcfg_pull_up_8ma>;
+                       };
+
+                       spi1_mosi_hs: spi1-mosi-hs {
+                               rockchip,pins =
+                                       <3 RK_PB4 4 &pcfg_pull_up_8ma>;
+                       };
+               };
+
+               pdm {
+                       pdm_clk0m0: pdm-clk0m0 {
+                               rockchip,pins =
+                                       <3 RK_PC6 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_clk0m1: pdm-clk0m1 {
+                               rockchip,pins =
+                                       <2 RK_PC6 1 &pcfg_pull_none>;
+                       };
+
+                       pdm_clk1: pdm-clk1 {
+                               rockchip,pins =
+                                       <3 RK_PC7 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_sdi0m0: pdm-sdi0m0 {
+                               rockchip,pins =
+                                       <3 RK_PD3 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_sdi0m1: pdm-sdi0m1 {
+                               rockchip,pins =
+                                       <2 RK_PC5 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_sdi1: pdm-sdi1 {
+                               rockchip,pins =
+                                       <3 RK_PD0 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_sdi2: pdm-sdi2 {
+                               rockchip,pins =
+                                       <3 RK_PD1 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_sdi3: pdm-sdi3 {
+                               rockchip,pins =
+                                       <3 RK_PD2 2 &pcfg_pull_none>;
+                       };
+
+                       pdm_clk0m0_sleep: pdm-clk0m0-sleep {
+                               rockchip,pins =
+                                       <3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_clk0m_sleep1: pdm-clk0m1-sleep {
+                               rockchip,pins =
+                                       <2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_clk1_sleep: pdm-clk1-sleep {
+                               rockchip,pins =
+                                       <3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_sdi0m0_sleep: pdm-sdi0m0-sleep {
+                               rockchip,pins =
+                                       <3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_sdi0m1_sleep: pdm-sdi0m1-sleep {
+                               rockchip,pins =
+                                       <2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_sdi1_sleep: pdm-sdi1-sleep {
+                               rockchip,pins =
+                                       <3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_sdi2_sleep: pdm-sdi2-sleep {
+                               rockchip,pins =
+                                       <3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+
+                       pdm_sdi3_sleep: pdm-sdi3-sleep {
+                               rockchip,pins =
+                                       <3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>;
+                       };
+               };
+
+               i2s0 {
+                       i2s0_8ch_mclk: i2s0-8ch-mclk {
+                               rockchip,pins =
+                                       <3 RK_PC1 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sclktx: i2s0-8ch-sclktx {
+                               rockchip,pins =
+                                       <3 RK_PC3 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sclkrx: i2s0-8ch-sclkrx {
+                               rockchip,pins =
+                                       <3 RK_PB4 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_lrcktx: i2s0-8ch-lrcktx {
+                               rockchip,pins =
+                                       <3 RK_PC2 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_lrckrx: i2s0-8ch-lrckrx {
+                               rockchip,pins =
+                                       <3 RK_PB5 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdo0: i2s0-8ch-sdo0 {
+                               rockchip,pins =
+                                       <3 RK_PC4 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdo1: i2s0-8ch-sdo1 {
+                               rockchip,pins =
+                                       <3 RK_PC0 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdo2: i2s0-8ch-sdo2 {
+                               rockchip,pins =
+                                       <3 RK_PB7 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdo3: i2s0-8ch-sdo3 {
+                               rockchip,pins =
+                                       <3 RK_PB6 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdi0: i2s0-8ch-sdi0 {
+                               rockchip,pins =
+                                       <3 RK_PC5 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdi1: i2s0-8ch-sdi1 {
+                               rockchip,pins =
+                                       <3 RK_PB3 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdi2: i2s0-8ch-sdi2 {
+                               rockchip,pins =
+                                       <3 RK_PB1 2 &pcfg_pull_none>;
+                       };
+
+                       i2s0_8ch_sdi3: i2s0-8ch-sdi3 {
+                               rockchip,pins =
+                                       <3 RK_PB0 2 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s1 {
+                       i2s1_2ch_mclk: i2s1-2ch-mclk {
+                               rockchip,pins =
+                                       <2 RK_PC3 1 &pcfg_pull_none>;
+                       };
+
+                       i2s1_2ch_sclk: i2s1-2ch-sclk {
+                               rockchip,pins =
+                                       <2 RK_PC2 1 &pcfg_pull_none>;
+                       };
+
+                       i2s1_2ch_lrck: i2s1-2ch-lrck {
+                               rockchip,pins =
+                                       <2 RK_PC1 1 &pcfg_pull_none>;
+                       };
+
+                       i2s1_2ch_sdi: i2s1-2ch-sdi {
+                               rockchip,pins =
+                                       <2 RK_PC5 1 &pcfg_pull_none>;
+                       };
+
+                       i2s1_2ch_sdo: i2s1-2ch-sdo {
+                               rockchip,pins =
+                                       <2 RK_PC4 1 &pcfg_pull_none>;
+                       };
+               };
+
+               i2s2 {
+                       i2s2_2ch_mclk: i2s2-2ch-mclk {
+                               rockchip,pins =
+                                       <3 RK_PA1 2 &pcfg_pull_none>;
+                       };
+
+                       i2s2_2ch_sclk: i2s2-2ch-sclk {
+                               rockchip,pins =
+                                       <3 RK_PA2 2 &pcfg_pull_none>;
+                       };
+
+                       i2s2_2ch_lrck: i2s2-2ch-lrck {
+                               rockchip,pins =
+                                       <3 RK_PA3 2 &pcfg_pull_none>;
+                       };
+
+                       i2s2_2ch_sdi: i2s2-2ch-sdi {
+                               rockchip,pins =
+                                       <3 RK_PA5 2 &pcfg_pull_none>;
+                       };
+
+                       i2s2_2ch_sdo: i2s2-2ch-sdo {
+                               rockchip,pins =
+                                       <3 RK_PA7 2 &pcfg_pull_none>;
+                       };
+               };
+
+               sdmmc {
+                       sdmmc_clk: sdmmc-clk {
+                               rockchip,pins =
+                                       <1 RK_PD6 1 &pcfg_pull_none_8ma>;
+                       };
+
+                       sdmmc_cmd: sdmmc-cmd {
+                               rockchip,pins =
+                                       <1 RK_PD7 1 &pcfg_pull_up_8ma>;
+                       };
+
+                       sdmmc_det: sdmmc-det {
+                               rockchip,pins =
+                                       <0 RK_PA3 1 &pcfg_pull_up_8ma>;
+                       };
+
+                       sdmmc_bus1: sdmmc-bus1 {
+                               rockchip,pins =
+                                       <1 RK_PD2 1 &pcfg_pull_up_8ma>;
+                       };
+
+                       sdmmc_bus4: sdmmc-bus4 {
+                               rockchip,pins =
+                                       <1 RK_PD2 1 &pcfg_pull_up_8ma>,
+                                       <1 RK_PD3 1 &pcfg_pull_up_8ma>,
+                                       <1 RK_PD4 1 &pcfg_pull_up_8ma>,
+                                       <1 RK_PD5 1 &pcfg_pull_up_8ma>;
+                       };
+
+                       sdmmc_gpio: sdmmc-gpio {
+                               rockchip,pins =
+                                       <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+                                       <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+                                       <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+                                       <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+                                       <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up_4ma>,
+                                       <1 RK_PD7 RK_FUNC_GPIO &pcfg_pull_up_4ma>;
+                       };
+               };
+
+               sdio {
+                       sdio_clk: sdio-clk {
+                               rockchip,pins =
+                                       <1 RK_PC5 1 &pcfg_pull_none>;
+                       };
+
+                       sdio_cmd: sdio-cmd {
+                               rockchip,pins =
+                                       <1 RK_PC4 1 &pcfg_pull_up>;
+                       };
+
+                       sdio_bus4: sdio-bus4 {
+                               rockchip,pins =
+                                       <1 RK_PC6 1 &pcfg_pull_up>,
+                                       <1 RK_PC7 1 &pcfg_pull_up>,
+                                       <1 RK_PD0 1 &pcfg_pull_up>,
+                                       <1 RK_PD1 1 &pcfg_pull_up>;
+                       };
+
+                       sdio_gpio: sdio-gpio {
+                               rockchip,pins =
+                                       <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>,
+                                       <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>,
+                                       <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>,
+                                       <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>,
+                                       <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>,
+                                       <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+                       };
+               };
+
+               emmc {
+                       emmc_clk: emmc-clk {
+                               rockchip,pins =
+                                       <1 RK_PB1 2 &pcfg_pull_none_8ma>;
+                       };
+
+                       emmc_cmd: emmc-cmd {
+                               rockchip,pins =
+                                       <1 RK_PB2 2 &pcfg_pull_up_8ma>;
+                       };
+
+                       emmc_pwren: emmc-pwren {
+                               rockchip,pins =
+                                       <1 RK_PB0 2 &pcfg_pull_none>;
+                       };
+
+                       emmc_rstnout: emmc-rstnout {
+                               rockchip,pins =
+                                       <1 RK_PB3 2 &pcfg_pull_none>;
+                       };
+
+                       emmc_bus1: emmc-bus1 {
+                               rockchip,pins =
+                                       <1 RK_PA0 2 &pcfg_pull_up_8ma>;
+                       };
+
+                       emmc_bus4: emmc-bus4 {
+                               rockchip,pins =
+                                       <1 RK_PA0 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA1 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA2 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA3 2 &pcfg_pull_up_8ma>;
+                       };
+
+                       emmc_bus8: emmc-bus8 {
+                               rockchip,pins =
+                                       <1 RK_PA0 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA1 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA2 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA3 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA4 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA5 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA6 2 &pcfg_pull_up_8ma>,
+                                       <1 RK_PA7 2 &pcfg_pull_up_8ma>;
+                       };
+               };
+
+               flash {
+                       flash_cs0: flash-cs0 {
+                               rockchip,pins =
+                                       <1 RK_PB0 1 &pcfg_pull_none>;
+                       };
+
+                       flash_rdy: flash-rdy {
+                               rockchip,pins =
+                                       <1 RK_PB1 1 &pcfg_pull_none>;
+                       };
+
+                       flash_dqs: flash-dqs {
+                               rockchip,pins =
+                                       <1 RK_PB2 1 &pcfg_pull_none>;
+                       };
+
+                       flash_ale: flash-ale {
+                               rockchip,pins =
+                                       <1 RK_PB3 1 &pcfg_pull_none>;
+                       };
+
+                       flash_cle: flash-cle {
+                               rockchip,pins =
+                                       <1 RK_PB4 1 &pcfg_pull_none>;
+                       };
+
+                       flash_wrn: flash-wrn {
+                               rockchip,pins =
+                                       <1 RK_PB5 1 &pcfg_pull_none>;
+                       };
+
+                       flash_csl: flash-csl {
+                               rockchip,pins =
+                                       <1 RK_PB6 1 &pcfg_pull_none>;
+                       };
+
+                       flash_rdn: flash-rdn {
+                               rockchip,pins =
+                                       <1 RK_PB7 1 &pcfg_pull_none>;
+                       };
+
+                       flash_bus8: flash-bus8 {
+                               rockchip,pins =
+                                       <1 RK_PA0 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA1 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA2 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA3 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA4 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA5 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA6 1 &pcfg_pull_up_12ma>,
+                                       <1 RK_PA7 1 &pcfg_pull_up_12ma>;
+                       };
+               };
+
+               lcdc {
+                       lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin {
+                               rockchip,pins =
+                                       <3 RK_PA0 1 &pcfg_pull_none_12ma>;
+                       };
+
+                       lcdc_rgb_m0_hsync_pin: lcdc-rgb-m0-hsync-pin {
+                               rockchip,pins =
+                                       <3 RK_PA1 1 &pcfg_pull_none_12ma>;
+                       };
+
+                       lcdc_rgb_m0_vsync_pin: lcdc-rgb-m0-vsync-pin {
+                               rockchip,pins =
+                                       <3 RK_PA2 1 &pcfg_pull_none_12ma>;
+                       };
+
+                       lcdc_rgb_m0_den_pin: lcdc-rgb-m0-den-pin {
+                               rockchip,pins =
+                                       <3 RK_PA3 1 &pcfg_pull_none_12ma>;
+                       };
+
+                       lcdc_rgb888_m0_data_pins: lcdc-rgb888-m0-data-pins {
+                               rockchip,pins =
+                                       <3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+                                       <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+                                       <3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+                                       <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+                                       <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+                                       <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+                                       <3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+                                       <3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+                                       <3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+                                       <3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+                                       <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+                                       <3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+                                       <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+                                       <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+                                       <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+                                       <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+                                       <3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
+                                       <3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
+                                       <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+                                       <3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
+                                       <3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
+                                       <3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
+                                       <3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
+                                       <3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
+                       };
+
+                       lcdc_rgb666_m0_data_pins: lcdc-rgb666-m0-data-pins {
+                               rockchip,pins =
+                                       <3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+                                       <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+                                       <3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+                                       <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+                                       <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+                                       <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+                                       <3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+                                       <3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+                                       <3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+                                       <3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+                                       <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+                                       <3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+                                       <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+                                       <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+                                       <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+                                       <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+                                       <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+                                       <3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
+                       };
+
+                       lcdc_rgb565_m0_data_pins: lcdc-rgb565-m0-data-pins {
+                               rockchip,pins =
+                                       <3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+                                       <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+                                       <3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+                                       <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+                                       <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+                                       <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+                                       <3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+                                       <3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+                                       <3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+                                       <3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+                                       <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+                                       <3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+                                       <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+                                       <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+                                       <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+                                       <3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
+                       };
+
+                       lcdc_rgb888_m1_data_pins: lcdc-rgb888-m1-data-pins {
+                               rockchip,pins =
+                                       <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+                                       <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+                                       <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+                                       <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+                                       <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+                                       <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+                                       <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+                                       <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+                                       <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+                                       <3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
+                                       <3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
+                                       <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+                                       <3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
+                                       <3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
+                                       <3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
+                                       <3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
+                                       <3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
+                       };
+
+                       lcdc_rgb666_m1_data_pins: lcdc-rgb666-m1-data-pins {
+                               rockchip,pins =
+                                       <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+                                       <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+                                       <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+                                       <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+                                       <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+                                       <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+                                       <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+                                       <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+                                       <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+                                       <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+                                       <3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
+                       };
+
+                       lcdc_rgb565_m1_data_pins: lcdc-rgb565-m1-data-pins {
+                               rockchip,pins =
+                                       <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+                                       <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+                                       <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+                                       <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+                                       <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+                                       <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+                                       <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+                                       <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+                                       <3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
+                       };
+               };
+
+               pwm0 {
+                       pwm0_pin: pwm0-pin {
+                               rockchip,pins =
+                                       <0 RK_PB7 1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm1 {
+                       pwm1_pin: pwm1-pin {
+                               rockchip,pins =
+                                       <0 RK_PC0 1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm2 {
+                       pwm2_pin: pwm2-pin {
+                               rockchip,pins =
+                                       <2 RK_PB5 1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm3 {
+                       pwm3_pin: pwm3-pin {
+                               rockchip,pins =
+                                       <0 RK_PC1 1 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm4 {
+                       pwm4_pin: pwm4-pin {
+                               rockchip,pins =
+                                       <3 RK_PC2 3 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm5 {
+                       pwm5_pin: pwm5-pin {
+                               rockchip,pins =
+                                       <3 RK_PC3 3 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm6 {
+                       pwm6_pin: pwm6-pin {
+                               rockchip,pins =
+                                       <3 RK_PC4 3 &pcfg_pull_none>;
+                       };
+               };
+
+               pwm7 {
+                       pwm7_pin: pwm7-pin {
+                               rockchip,pins =
+                                       <3 RK_PC5 3 &pcfg_pull_none>;
+                       };
+               };
+
+               gmac {
+                       rmii_pins: rmii-pins {
+                               rockchip,pins =
+                                       <2 RK_PA0 2 &pcfg_pull_none_12ma>, /* mac_txen */
+                                       <2 RK_PA1 2 &pcfg_pull_none_12ma>, /* mac_txd1 */
+                                       <2 RK_PA2 2 &pcfg_pull_none_12ma>, /* mac_txd0 */
+                                       <2 RK_PA3 2 &pcfg_pull_none>, /* mac_rxd0 */
+                                       <2 RK_PA4 2 &pcfg_pull_none>, /* mac_rxd1 */
+                                       <2 RK_PA5 2 &pcfg_pull_none>, /* mac_rxer */
+                                       <2 RK_PA6 2 &pcfg_pull_none>, /* mac_rxdv */
+                                       <2 RK_PA7 2 &pcfg_pull_none>, /* mac_mdio */
+                                       <2 RK_PB1 2 &pcfg_pull_none>; /* mac_mdc */
+                       };
+
+                       mac_refclk_12ma: mac-refclk-12ma {
+                               rockchip,pins =
+                                       <2 RK_PB2 2 &pcfg_pull_none_12ma>;
+                       };
+
+                       mac_refclk: mac-refclk {
+                               rockchip,pins =
+                                       <2 RK_PB2 2 &pcfg_pull_none>;
+                       };
+               };
+
+               cif-m0 {
+                       cif_clkout_m0: cif-clkout-m0 {
+                               rockchip,pins =
+                                       <2 RK_PB3 1 &pcfg_pull_none>;
+                       };
+
+                       dvp_d2d9_m0: dvp-d2d9-m0 {
+                               rockchip,pins =
+                                       <2 RK_PA0 1 &pcfg_pull_none>, /* cif_data2 */
+                                       <2 RK_PA1 1 &pcfg_pull_none>, /* cif_data3 */
+                                       <2 RK_PA2 1 &pcfg_pull_none>, /* cif_data4 */
+                                       <2 RK_PA3 1 &pcfg_pull_none>, /* cif_data5 */
+                                       <2 RK_PA4 1 &pcfg_pull_none>, /* cif_data6 */
+                                       <2 RK_PA5 1 &pcfg_pull_none>, /* cif_data7 */
+                                       <2 RK_PA6 1 &pcfg_pull_none>, /* cif_data8 */
+                                       <2 RK_PA7 1 &pcfg_pull_none>, /* cif_data9 */
+                                       <2 RK_PB0 1 &pcfg_pull_none>, /* cif_sync */
+                                       <2 RK_PB1 1 &pcfg_pull_none>, /* cif_href */
+                                       <2 RK_PB2 1 &pcfg_pull_none>, /* cif_clkin */
+                                       <2 RK_PB3 1 &pcfg_pull_none>; /* cif_clkout */
+                       };
+
+                       dvp_d0d1_m0: dvp-d0d1-m0 {
+                               rockchip,pins =
+                                       <2 RK_PB4 1 &pcfg_pull_none>, /* cif_data0 */
+                                       <2 RK_PB6 1 &pcfg_pull_none>; /* cif_data1 */
+                       };
+
+                       dvp_d10d11_m0:d10-d11-m0 {
+                               rockchip,pins =
+                                       <2 RK_PB7 1 &pcfg_pull_none>, /* cif_data10 */
+                                       <2 RK_PC0 1 &pcfg_pull_none>; /* cif_data11 */
+                       };
+               };
+
+               cif-m1 {
+                       cif_clkout_m1: cif-clkout-m1 {
+                               rockchip,pins =
+                                       <3 RK_PD0 3 &pcfg_pull_none>;
+                       };
+
+                       dvp_d2d9_m1: dvp-d2d9-m1 {
+                               rockchip,pins =
+                                       <3 RK_PA3 3 &pcfg_pull_none>, /* cif_data2 */
+                                       <3 RK_PA5 3 &pcfg_pull_none>, /* cif_data3 */
+                                       <3 RK_PA7 3 &pcfg_pull_none>, /* cif_data4 */
+                                       <3 RK_PB0 3 &pcfg_pull_none>, /* cif_data5 */
+                                       <3 RK_PB1 3 &pcfg_pull_none>, /* cif_data6 */
+                                       <3 RK_PB4 3 &pcfg_pull_none>, /* cif_data7 */
+                                       <3 RK_PB6 3 &pcfg_pull_none>, /* cif_data8 */
+                                       <3 RK_PB7 3 &pcfg_pull_none>, /* cif_data9 */
+                                       <3 RK_PD1 3 &pcfg_pull_none>, /* cif_sync */
+                                       <3 RK_PD2 3 &pcfg_pull_none>, /* cif_href */
+                                       <3 RK_PD3 3 &pcfg_pull_none>, /* cif_clkin */
+                                       <3 RK_PD0 3 &pcfg_pull_none>; /* cif_clkout */
+                       };
+
+                       dvp_d0d1_m1: dvp-d0d1-m1 {
+                               rockchip,pins =
+                                       <3 RK_PA1 3 &pcfg_pull_none>, /* cif_data0 */
+                                       <3 RK_PA2 3 &pcfg_pull_none>; /* cif_data1 */
+                       };
+
+                       dvp_d10d11_m1:d10-d11-m1 {
+                               rockchip,pins =
+                                       <3 RK_PC6 3 &pcfg_pull_none>, /* cif_data10 */
+                                       <3 RK_PC7 3 &pcfg_pull_none>; /* cif_data11 */
+                       };
+               };
+
+               isp {
+                       isp_prelight: isp-prelight {
+                               rockchip,pins =
+                                       <3 RK_PD1 4 &pcfg_pull_none>;
+                       };
+               };
+       };
+};
index 246c317f6a6822990fc8851b48c2009bc2cc53a9..99d0d9912950bf6d33fecd4519c98eadc8e89e35 100644 (file)
                vin-supply = <&vcc_io>;
        };
 
+       vcc_sdio: sdmmcio-regulator {
+               compatible = "regulator-gpio";
+               gpios = <&grf_gpio 0 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x1
+                         3300000 0x0>;
+               regulator-name = "vcc_sdio";
+               regulator-type = "voltage";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
        vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator {
                compatible = "regulator-fixed";
                enable-active-high;
        };
 };
 
+&io_domains {
+       status = "okay";
+
+       vccio1-supply = <&vcc_io>;
+       vccio2-supply = <&vcc18_emmc>;
+       vccio3-supply = <&vcc_sdio>;
+       vccio4-supply = <&vcc_18>;
+       vccio5-supply = <&vcc_io>;
+       vccio6-supply = <&vcc_io>;
+       pmuio-supply = <&vcc_io>;
+};
+
 &pinctrl {
        pmic {
                pmic_int_l: pmic-int-l {
        max-frequency = <150000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
        vmmc-supply = <&vcc_sd>;
+       vqmmc-supply = <&vcc_sdio>;
        status = "okay";
 };
 
index 5272e887a434ec46d52afdffaf76164ad182cdaa..dc20145dd393d93d308f7f2f3abab84b6313343b 100644 (file)
@@ -46,7 +46,7 @@
        vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator {
                compatible = "regulator-fixed";
                enable-active-high;
-               gpio = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>;
+               gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&usb20_host_drv>;
                regulator-name = "vcc_host1_5v";
                regulator-min-microvolt = <5000000>;
                regulator-max-microvolt = <5000000>;
        };
+
+       sound {
+               compatible = "audio-graph-card";
+               label = "rockchip,rk3328";
+               dais = <&spdif_p0>;
+       };
+
+       spdif-dit {
+               compatible = "linux,spdif-dit";
+               #sound-dai-cells = <0>;
+
+               port {
+                       dit_p0_0: endpoint {
+                               remote-endpoint = <&spdif_p0_0>;
+                       };
+               };
+       };
 };
 
 &cpu0 {
        status = "okay";
 };
 
+&hdmi {
+       status = "okay";
+};
+
+&hdmiphy {
+       status = "okay";
+};
+
 &i2c1 {
        status = "okay";
 
 
        usb2 {
                usb20_host_drv: usb20-host-drv {
-                       rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+                       rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 
        status = "okay";
 };
 
+&spdif {
+       pinctrl-0 = <&spdifm0_tx>;
+       status = "okay";
+       #sound-dai-cells = <0>;
+
+       spdif_p0: port {
+               spdif_p0_0: endpoint {
+                       remote-endpoint = <&dit_p0_0>;
+               };
+       };
+};
+
+&spi0 {
+       status = "okay";
+
+       spiflash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+
+               /* maximum speed for Rockchip SPI */
+               spi-max-frequency = <50000000>;
+       };
+};
+
 &tsadc {
        rockchip,hw-tshut-mode = <0>;
        rockchip,hw-tshut-polarity = <0>;
 &usb_host0_ohci {
        status = "okay";
 };
+
+&vop {
+       status = "okay";
+};
+
+&vop_mmu {
+       status = "okay";
+};
index 3f5a2944300fe2441f87ec1ac144d771f2cddbfe..e1a33dd981e0d2c1f93c0e333de0910fdbcb4fdd 100644 (file)
                interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
        };
 
+       display_subsystem: display-subsystem {
+               compatible = "rockchip,display-subsystem";
+               ports = <&vop_out>;
+       };
+
        psci {
                compatible = "arm,psci-1.0", "arm,psci-0.2";
                method = "smc";
                        status = "disabled";
                };
 
+               grf_gpio: grf-gpio {
+                       compatible = "rockchip,rk3328-grf-gpio";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
                power: power-controller {
                        compatible = "rockchip,rk3328-power-controller";
                        #power-domain-cells = <1>;
                        mode-bootloader = <BOOT_FASTBOOT>;
                        mode-loader = <BOOT_BL_DOWNLOAD>;
                };
-
        };
 
        uart0: serial@ff110000 {
                status = "disabled";
        };
 
+       vop: vop@ff370000 {
+               compatible = "rockchip,rk3328-vop";
+               reg = <0x0 0xff370000 0x0 0x3efc>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru ACLK_VOP>, <&cru DCLK_LCDC>, <&cru HCLK_VOP>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_VOP_A>, <&cru SRST_VOP_H>, <&cru SRST_VOP_D>;
+               reset-names = "axi", "ahb", "dclk";
+               iommus = <&vop_mmu>;
+               status = "disabled";
+
+               vop_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       vop_out_hdmi: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&hdmi_in_vop>;
+                       };
+               };
+       };
+
        vop_mmu: iommu@ff373f00 {
                compatible = "rockchip,iommu";
                reg = <0x0 0xff373f00 0x0 0x100>;
                status = "disabled";
        };
 
+       hdmi: hdmi@ff3c0000 {
+               compatible = "rockchip,rk3328-dw-hdmi";
+               reg = <0x0 0xff3c0000 0x0 0x20000>;
+               reg-io-width = <4>;
+               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru PCLK_HDMI>,
+                        <&cru SCLK_HDMI_SFC>;
+               clock-names = "iahb",
+                             "isfr";
+               phys = <&hdmiphy>;
+               phy-names = "hdmi";
+               pinctrl-names = "default";
+               pinctrl-0 = <&hdmi_cec &hdmii2c_xfer &hdmi_hpd>;
+               rockchip,grf = <&grf>;
+               status = "disabled";
+
+               ports {
+                       hdmi_in: port {
+                               hdmi_in_vop: endpoint {
+                                       remote-endpoint = <&vop_out_hdmi>;
+                               };
+                       };
+               };
+       };
+
+       hdmiphy: phy@ff430000 {
+               compatible = "rockchip,rk3328-hdmi-phy";
+               reg = <0x0 0xff430000 0x0 0x10000>;
+               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru PCLK_HDMIPHY>, <&xin24m>, <&cru DCLK_HDMIPHY>;
+               clock-names = "sysclk", "refoclk", "refpclk";
+               clock-output-names = "hdmi_phy";
+               #clock-cells = <0>;
+               nvmem-cells = <&efuse_cpu_version>;
+               nvmem-cell-names = "cpu-version";
+               #phy-cells = <0>;
+               status = "disabled";
+       };
+
        cru: clock-controller@ff440000 {
                compatible = "rockchip,rk3328-cru", "rockchip,cru", "syscon";
                reg = <0x0 0xff440000 0x0 0x1000>;
index 8978d924eb83ec3d4dea337e683b2d570bc00581..cce266da28cd3b347f2901296ce1b1b4ed0837be 100644 (file)
@@ -7,8 +7,7 @@
  */
 
 /dts-v1/;
-#include "rk3399.dtsi"
-#include "rk3399-opp.dtsi"
+#include "rk3399-rock960.dtsi"
 
 / {
        model = "96boards RK3399 Ficus";
                clock-output-names = "clkin_gmac";
                #clock-cells = <0>;
        };
-
-       vcc1v8_s0: vcc1v8-s0 {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc1v8_s0";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-       };
-
-       vcc_sys: vcc-sys {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc_sys";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               regulator-always-on;
-       };
-
-       vcc3v3_sys: vcc3v3-sys {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc3v3_sys";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-always-on;
-               vin-supply = <&vcc_sys>;
-       };
-
-       vcc3v3_pcie: vcc3v3-pcie-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio1 24 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pcie_drv>;
-               regulator-boot-on;
-               regulator-name = "vcc3v3_pcie";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               vin-supply = <&vcc3v3_sys>;
-       };
-
-       vcc5v0_host: vcc5v0-host-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&host_vbus_drv>;
-               regulator-name = "vcc5v0_host";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               regulator-always-on;
-               vin-supply = <&vcc_sys>;
-       };
-
-       vdd_log: vdd-log {
-               compatible = "pwm-regulator";
-               pwms = <&pwm2 0 25000 0>;
-               regulator-name = "vdd_log";
-               regulator-min-microvolt = <800000>;
-               regulator-max-microvolt = <1400000>;
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc_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 {
        status = "okay";
 };
 
-&hdmi {
-       ddc-i2c-bus = <&i2c3>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&hdmi_cec>;
-       status = "okay";
-};
-
-&i2c0 {
-       clock-frequency = <400000>;
-       i2c-scl-rising-time-ns = <168>;
-       i2c-scl-falling-time-ns = <4>;
-       status = "okay";
-
-       vdd_cpu_b: regulator@40 {
-               compatible = "silergy,syr827";
-               reg = <0x40>;
-               fcs,suspend-voltage-selector = <1>;
-               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 = <&vcc_sys>;
-               status = "okay";
-
-               regulator-state-mem {
-                       regulator-off-in-suspend;
-               };
-       };
-
-       vdd_gpu: regulator@41 {
-               compatible = "silergy,syr828";
-               reg = <0x41>;
-               fcs,suspend-voltage-selector = <1>;
-               regulator-name = "vdd_gpu";
-               regulator-min-microvolt = <712500>;
-               regulator-max-microvolt = <1500000>;
-               regulator-ramp-delay = <1000>;
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc_sys>;
-               regulator-state-mem {
-                       regulator-off-in-suspend;
-               };
-       };
-
-       rk808: pmic@1b {
-               compatible = "rockchip,rk808";
-               reg = <0x1b>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pmic_int_l>;
-               rockchip,system-power-controller;
-               wakeup-source;
-               #clock-cells = <1>;
-               clock-output-names = "xin32k", "rk808-clkout2";
-
-               vcc1-supply = <&vcc_sys>;
-               vcc2-supply = <&vcc_sys>;
-               vcc3-supply = <&vcc_sys>;
-               vcc4-supply = <&vcc_sys>;
-               vcc6-supply = <&vcc_sys>;
-               vcc7-supply = <&vcc_sys>;
-               vcc8-supply = <&vcc3v3_sys>;
-               vcc9-supply = <&vcc_sys>;
-               vcc10-supply = <&vcc_sys>;
-               vcc11-supply = <&vcc_sys>;
-               vcc12-supply = <&vcc3v3_sys>;
-               vddio-supply = <&vcc_1v8>;
-
-               regulators {
-                       vdd_center: DCDC_REG1 {
-                               regulator-name = "vdd_center";
-                               regulator-min-microvolt = <750000>;
-                               regulator-max-microvolt = <1350000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vdd_cpu_l: DCDC_REG2 {
-                               regulator-name = "vdd_cpu_l";
-                               regulator-min-microvolt = <750000>;
-                               regulator-max-microvolt = <1350000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               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-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcc1v8_dvp: LDO_REG1 {
-                               regulator-name = "vcc1v8_dvp";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcca1v8_hdmi: LDO_REG2 {
-                               regulator-name = "vcca1v8_hdmi";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcca_1v8: LDO_REG3 {
-                               regulator-name = "vcca_1v8";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcc_sd: LDO_REG4 {
-                               regulator-name = "vcc_sd";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3300000>;
-                               };
-                       };
-
-                       vcc3v0_sd: LDO_REG5 {
-                               regulator-name = "vcc3v0_sd";
-                               regulator-min-microvolt = <3000000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3000000>;
-                               };
-                       };
-
-                       vcc_1v5: LDO_REG6 {
-                               regulator-name = "vcc_1v5";
-                               regulator-min-microvolt = <1500000>;
-                               regulator-max-microvolt = <1500000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1500000>;
-                               };
-                       };
-
-                       vcca0v9_hdmi: LDO_REG7 {
-                               regulator-name = "vcca0v9_hdmi";
-                               regulator-min-microvolt = <900000>;
-                               regulator-max-microvolt = <900000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <900000>;
-                               };
-                       };
-
-                       vcc_3v0: LDO_REG8 {
-                               regulator-name = "vcc_3v0";
-                               regulator-min-microvolt = <3000000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3000000>;
-                               };
-                       };
-
-                       vcc3v3_s3: SWITCH_REG1 {
-                               regulator-name = "vcc3v3_s3";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-
-                       vcc3v3_s0: SWITCH_REG2 {
-                               regulator-name = "vcc3v3_s0";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-               };
-       };
-};
-
-&i2c1 {
-       status = "okay";
-};
-
-&i2c2 {
-       status = "okay";
-};
-
-&i2c3 {
-       status = "okay";
-};
-
-&i2c4 {
-       status = "okay";
-};
-
-&io_domains {
-       bt656-supply = <&vcc1v8_s0>; /* bt656_gpio2ab_ms */
-       audio-supply = <&vcc1v8_s0>; /* audio_gpio3d4a_ms */
-       sdmmc-supply = <&vcc_sd>; /* sdmmc_gpio4b_ms */
-       gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */
-       status = "okay";
-};
-
-&pcie_phy {
-       status = "okay";
-};
-
 &pcie0 {
        ep-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>;
-       num-lanes = <4>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pcie_clkreqn_cpm>;
-       vpcie3v3-supply = <&vcc3v3_pcie>;
-       status = "okay";
-};
-
-&pmu_io_domains {
-       pmu1830-supply = <&vcc_1v8>;
-       status = "okay";
 };
 
 &pinctrl {
                };
        };
 
-       sdmmc {
-               sdmmc_bus1: sdmmc-bus1 {
-                       rockchip,pins =
-                               <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>;
-               };
-
-               sdmmc_bus4: sdmmc-bus4 {
-                       rockchip,pins =
-                               <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>,
-                               <4 9 RK_FUNC_1 &pcfg_pull_up_8ma>,
-                               <4 10 RK_FUNC_1 &pcfg_pull_up_8ma>,
-                               <4 11 RK_FUNC_1 &pcfg_pull_up_8ma>;
-               };
-
-               sdmmc_clk: sdmmc-clk {
-                       rockchip,pins =
-                               <4 12 RK_FUNC_1 &pcfg_pull_none_18ma>;
-               };
-
-               sdmmc_cmd: sdmmc-cmd {
-                       rockchip,pins =
-                               <4 13 RK_FUNC_1 &pcfg_pull_up_8ma>;
-               };
-       };
-
        pcie {
                pcie_drv: pcie-drv {
                        rockchip,pins =
                        };
        };
 
-       pmic {
-               pmic_int_l: pmic-int-l {
-                       rockchip,pins =
-                               <1 21 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-
-               vsel1_gpio: vsel1-gpio {
-                       rockchip,pins =
-                               <1 17 RK_FUNC_GPIO &pcfg_pull_down>;
-               };
-
-               vsel2_gpio: vsel2-gpio {
-                       rockchip,pins =
-                               <1 14 RK_FUNC_GPIO &pcfg_pull_down>;
-               };
-       };
-
        usb2 {
                host_vbus_drv: host-vbus-drv {
                        rockchip,pins =
        };
 };
 
-&pwm2 {
-       status = "okay";
-};
-
-&pwm3 {
-       status = "okay";
-};
-
-&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;
-       clock-frequency = <100000000>;
-       clock-freq-min-max = <100000 100000000>;
-       disable-wp;
-       sd-uhs-sdr104;
-       vqmmc-supply = <&vcc_sd>;
-       card-detect-delay = <800>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
-       status = "okay";
-};
-
-&tcphy0 {
-       status = "okay";
-};
-
-&tcphy1 {
-       status = "okay";
-};
-
-&u2phy0 {
-       status = "okay";
-};
-
-&u2phy1 {
-       status = "okay";
-};
-
-&u2phy0_host {
-       phy-supply = <&vcc5v0_host>;
-       status = "okay";
-};
-
-&u2phy1_host {
-       phy-supply = <&vcc5v0_host>;
-       status = "okay";
-};
-
-&u2phy0_otg {
-       status = "okay";
-};
-
-&u2phy1_otg {
-       status = "okay";
-};
-
-&uart0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart0_xfer &uart0_cts>;
-       status = "okay";
-};
-
-&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 = "host";
 };
 
-&usbdrd3_1 {
-       status = "okay";
-};
-
 &usbdrd_dwc3_1 {
-       status = "okay";
        dr_mode = "host";
 };
 
-&vopb {
-       status = "okay";
-};
-
-&vopb_mmu {
-       status = "okay";
-};
-
-&vopl {
-       status = "okay";
+&vcc3v3_pcie {
+       gpio = <&gpio1 24 GPIO_ACTIVE_HIGH>;
 };
 
-&vopl_mmu {
-       status = "okay";
+&vcc5v0_host {
+       gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
 };
index 38336ab57cc46046988500ac54496a7c97bc0c4f..c706db0ee9ec63e86199971bec605f946214ffe9 100644 (file)
                };
        };
 
+       wifi {
+               wifi_host_wake_l: wifi-host-wake-l {
+                       rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
        leds {
                work_led_gpio: work_led-gpio {
                        rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
        status = "okay";
 };
 
+&sdio0 {
+       /* WiFi & BT combo module Ampak AP6356S */
+       bus-width = <4>;
+       cap-sdio-irq;
+       cap-sd-highspeed;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       non-removable;
+       num-slots = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+       sd-uhs-sdr104;
+
+       /* Power supply */
+       vqmmc-supply = &vcc1v8_s3;      /* IO line */
+       vmmc-supply = &vcc_sdio;        /* card's power */
+
+       status = "okay";
+
+       brcmf: wifi@1 {
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
+               interrupt-names = "host-wake";
+               brcm,drive-strength = <5>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_host_wake_l>;
+       };
+};
+
 &sdmmc {
        bus-width = <4>;
        cap-mmc-highspeed;
index e0d64f862322e507798c4fd5d590963164da4c4e..2dceeea29b8351fa35358600d43aac4516fce8a2 100644 (file)
        status = "okay";
        clock-frequency = <400000>;
 
-       sgtl5000: codec@0a {
+       sgtl5000: codec@a {
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
                clocks = <&sgtl5000_clk>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts
new file mode 100644 (file)
index 0000000..19f7732
--- /dev/null
@@ -0,0 +1,680 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd
+ */
+
+/dts-v1/;
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       model = "Firefly ROC-RK3399-PC Board";
+       compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm0 0 25000 0>;
+       };
+
+       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_enable_h>;
+
+               /*
+                * On the module itself this is one of these (depending
+                * on the actual card populated):
+                * - SDIO_RESET_L_WL_REG_ON
+                * - PDN (power down when low)
+                */
+               reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+       };
+
+       vcc_vbus_typec0: vcc-vbus-typec0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_vbus_typec0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       /*
+        * should be placed inside mp8859, but not until mp8859 has
+        * its own dt-binding.
+        */
+       vcc12v_sys: mp8859-dcdc1 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc12v_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               vin-supply = <&vcc_vbus_typec0>;
+       };
+
+       /* switched by pmic_sleep */
+       vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_1v8>;
+       };
+
+       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 = <&vcc12v_sys>;
+       };
+
+       /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en &hub_rst>;
+               regulator-name = "vcc5v0_host";
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_vbus_typec1: vcc-vbus-typec1 {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc_vbus_typec1_en>;
+               regulator-name = "vcc_vbus_typec1";
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_sys: vcc-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc12v_sys>;
+       };
+
+       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 = <&vcc3v3_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 = <&vcc_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";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_cec>;
+       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 = <&vcc3v3_sys>;
+               vcc2-supply = <&vcc3v3_sys>;
+               vcc3-supply = <&vcc3v3_sys>;
+               vcc4-supply = <&vcc3v3_sys>;
+               vcc6-supply = <&vcc3v3_sys>;
+               vcc7-supply = <&vcc3v3_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc3v3_sys>;
+               vcc10-supply = <&vcc3v3_sys>;
+               vcc11-supply = <&vcc3v3_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc1v8_pmu>;
+
+               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>;
+                               };
+                       };
+
+                       vcca1v8_codec: LDO_REG1 {
+                               regulator-name = "vcca1v8_codec";
+                               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;
+                               };
+                       };
+
+                       vcc1v8_pmu: LDO_REG3 {
+                               regulator-name = "vcc1v8_pmu";
+                               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>;
+                               };
+                       };
+
+                       vcc_sdio: LDO_REG4 {
+                               regulator-name = "vcc_sdio";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               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>;
+                               };
+                       };
+
+                       vcca0v9_hdmi: LDO_REG7 {
+                               regulator-name = "vcca0v9_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>;
+                               };
+                       };
+
+                       vcc3v3_s3: vcc_lan: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_s3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_s0: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_s0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       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 = <&vcc3v3_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 = <&vcc3v3_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";
+
+       fusb1: usb-typec@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb1_int>;
+               vbus-supply = <&vcc_vbus_typec1>;
+               status = "okay";
+       };
+};
+
+&i2c7 {
+       i2c-scl-rising-time-ns = <600>;
+       i2c-scl-falling-time-ns = <20>;
+       status = "okay";
+
+       fusb0: usb-typec@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb0_int>;
+               vbus-supply = <&vcc_vbus_typec0>;
+               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 {
+       audio-supply = <&vcca1v8_codec>;
+       bt656-supply = <&vcc_3v0>;
+       gpio1830-supply = <&vcc_3v0>;
+       sdmmc-supply = <&vcc_sdio>;
+       status = "okay";
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_3v0>;
+       status = "okay";
+};
+
+&pinctrl {
+       lcd-panel {
+               lcd_panel_reset: lcd-panel-reset {
+                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       pmic {
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h: wifi-enable-h {
+                       rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb2 {
+               vcc5v0_host_en: vcc5v0-host-en {
+                       rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               hub_rst: hub-rst {
+                       rockchip,pins = <2 RK_PA4 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+       };
+
+       usb-typec {
+               vcc_vbus_typec1_en: vcc-vbus-typec1-en {
+                       rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       fusb30x {
+               fusb0_int: fusb0-int {
+                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               fusb1_int: fusb1-int {
+                       rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcca1v8_s3>;
+       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_cmd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&tsadc {
+       /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-mode = <1>;
+       /* tshut polarity 0:LOW 1:HIGH */
+       rockchip,hw-tshut-polarity = <1>;
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+
+       u2phy0_otg: otg-port {
+               phy-supply = <&vcc_vbus_typec0>;
+               status = "okay";
+       };
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_otg: otg-port {
+               phy-supply = <&vcc_vbus_typec1>;
+               status = "okay";
+       };
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+       status = "okay";
+};
+
+&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";
+};
+
+&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";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dts
new file mode 100644 (file)
index 0000000..3c3308d
--- /dev/null
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Linaro Ltd.
+ */
+
+/dts-v1/;
+#include "rk3399-rock960.dtsi"
+
+/ {
+       model = "96boards Rock960";
+       compatible = "vamrs,rock960", "rockchip,rk3399";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+};
+
+&pcie0 {
+       ep-gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
+};
+
+&pinctrl {
+       pcie {
+               pcie_drv: pcie-drv {
+                       rockchip,pins =
+                               <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+       };
+
+       usb2 {
+               host_vbus_drv: host-vbus-drv {
+                       rockchip,pins =
+                               <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&usbdrd_dwc3_0 {
+       dr_mode = "otg";
+};
+
+&usbdrd_dwc3_1 {
+       dr_mode = "host";
+};
+
+&vcc3v3_pcie {
+       gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+};
+
+&vcc5v0_host {
+       gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
new file mode 100644 (file)
index 0000000..6c8c4ab
--- /dev/null
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Collabora Ltd.
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2018 Linaro Ltd.
+ */
+
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       vcc1v8_s0: vcc1v8-s0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8_s0";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+
+       vcc_sys: vcc-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       vcc3v3_sys: vcc3v3-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_sys";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc3v3_pcie: vcc3v3-pcie-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie_drv>;
+               regulator-boot-on;
+               regulator-name = "vcc3v3_pcie";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               pinctrl-names = "default";
+               pinctrl-0 = <&host_vbus_drv>;
+               regulator-name = "vcc5v0_host";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vdd_log: vdd-log {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 25000 0>;
+               regulator-name = "vdd_log";
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1400000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_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";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_cec>;
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-rising-time-ns = <168>;
+       i2c-scl-falling-time-ns = <4>;
+       status = "okay";
+
+       vdd_cpu_b: regulator@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <1>;
+               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 = <&vcc_sys>;
+               status = "okay";
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_gpu: regulator@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               wakeup-source;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+
+               vcc1-supply = <&vcc_sys>;
+               vcc2-supply = <&vcc_sys>;
+               vcc3-supply = <&vcc_sys>;
+               vcc4-supply = <&vcc_sys>;
+               vcc6-supply = <&vcc_sys>;
+               vcc7-supply = <&vcc_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc_sys>;
+               vcc10-supply = <&vcc_sys>;
+               vcc11-supply = <&vcc_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc_1v8>;
+
+               regulators {
+                       vdd_center: DCDC_REG1 {
+                               regulator-name = "vdd_center";
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_l: DCDC_REG2 {
+                               regulator-name = "vdd_cpu_l";
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               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-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc1v8_dvp: LDO_REG1 {
+                               regulator-name = "vcc1v8_dvp";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca1v8_hdmi: LDO_REG2 {
+                               regulator-name = "vcca1v8_hdmi";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca_1v8: LDO_REG3 {
+                               regulator-name = "vcca_1v8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc_sd: LDO_REG4 {
+                               regulator-name = "vcc_sd";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc3v0_sd: LDO_REG5 {
+                               regulator-name = "vcc3v0_sd";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc_1v5: LDO_REG6 {
+                               regulator-name = "vcc_1v5";
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1500000>;
+                               };
+                       };
+
+                       vcca0v9_hdmi: LDO_REG7 {
+                               regulator-name = "vcca0v9_hdmi";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <900000>;
+                               };
+                       };
+
+                       vcc_3v0: LDO_REG8 {
+                               regulator-name = "vcc_3v0";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc3v3_s3: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_s3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_s0: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_s0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&io_domains {
+       bt656-supply = <&vcc1v8_s0>; /* bt656_gpio2ab_ms */
+       audio-supply = <&vcc1v8_s0>; /* audio_gpio3d4a_ms */
+       sdmmc-supply = <&vcc_sd>; /* sdmmc_gpio4b_ms */
+       gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */
+       status = "okay";
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pcie0 {
+       num-lanes = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_clkreqn_cpm>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_1v8>;
+       status = "okay";
+};
+
+&pinctrl {
+       sdmmc {
+               sdmmc_bus1: sdmmc-bus1 {
+                       rockchip,pins =
+                               <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>;
+               };
+
+               sdmmc_bus4: sdmmc-bus4 {
+                       rockchip,pins =
+                               <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>,
+                               <4 9 RK_FUNC_1 &pcfg_pull_up_8ma>,
+                               <4 10 RK_FUNC_1 &pcfg_pull_up_8ma>,
+                               <4 11 RK_FUNC_1 &pcfg_pull_up_8ma>;
+               };
+
+               sdmmc_clk: sdmmc-clk {
+                       rockchip,pins =
+                               <4 12 RK_FUNC_1 &pcfg_pull_none_18ma>;
+               };
+
+               sdmmc_cmd: sdmmc-cmd {
+                       rockchip,pins =
+                               <4 13 RK_FUNC_1 &pcfg_pull_up_8ma>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins =
+                               <1 21 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins =
+                               <1 17 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins =
+                               <1 14 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&pwm3 {
+       status = "okay";
+};
+
+&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;
+       clock-frequency = <100000000>;
+       clock-freq-min-max = <100000 100000000>;
+       cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       sd-uhs-sdr104;
+       vqmmc-supply = <&vcc_sd>;
+       card-detect-delay = <800>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy1 {
+       status = "okay";
+};
+
+&u2phy0_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&u2phy1_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
+&u2phy1_otg {
+       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";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+       status = "okay";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
new file mode 100644 (file)
index 0000000..1d35f54
--- /dev/null
@@ -0,0 +1,692 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2018 Akash Gajjar <Akash_Gajjar@mentor.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 = "Pine64 RockPro64";
+       compatible = "pine64,rockpro64", "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>;
+       };
+
+       dc_12v: dc-12v {
+               compatible = "regulator-fixed";
+               regulator-name = "dc_12v";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwrbtn>;
+
+               power {
+                       debounce-interval = <100>;
+                       gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+                       label = "GPIO Key Power";
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&work_led_gpio>, <&diy_led_gpio>;
+
+               work-led {
+                       label = "work";
+                       default-state = "on";
+                       gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>;
+               };
+
+               diy-led {
+                       label = "diy";
+                       default-state = "off";
+                       gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk808 1>;
+               clock-names = "ext_clock";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_enable_h>;
+
+               /*
+                * On the module itself this is one of these (depending
+                * on the actual card populated):
+                * - SDIO_RESET_L_WL_REG_ON
+                * - PDN (power down when low)
+                */
+               reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+       };
+
+       /* switched by pmic_sleep */
+       vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_1v8>;
+       };
+
+       vcc3v3_pcie: vcc3v3-pcie-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie_pwr_en>;
+               regulator-name = "vcc3v3_pcie";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&dc_12v>;
+       };
+
+       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 = <&vcc_sys>;
+       };
+
+       /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en>;
+               regulator-name = "vcc5v0_host";
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc5v0_typec: vcc5v0-typec-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_typec_en>;
+               regulator-name = "vcc5v0_typec";
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_sys: vcc-sys {
+               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>;
+       };
+
+       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 = <&vcc_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 = <&vcc_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";
+};
+
+&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 = <&vcc_sys>;
+               vcc2-supply = <&vcc_sys>;
+               vcc3-supply = <&vcc_sys>;
+               vcc4-supply = <&vcc_sys>;
+               vcc6-supply = <&vcc_sys>;
+               vcc7-supply = <&vcc_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc_sys>;
+               vcc10-supply = <&vcc_sys>;
+               vcc11-supply = <&vcc_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc1v8_pmu>;
+
+               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;
+                               };
+                       };
+
+                       vcc2v8_dvp: LDO_REG2 {
+                               regulator-name = "vcc2v8_dvp";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v8_pmu: LDO_REG3 {
+                               regulator-name = "vcc1v8_pmu";
+                               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>;
+                               };
+                       };
+
+                       vcc_sdio: LDO_REG4 {
+                               regulator-name = "vcc_sdio";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               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>;
+                               };
+                       };
+
+                       vcca1v8_codec: LDO_REG7 {
+                               regulator-name = "vcca1v8_codec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               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>;
+                               };
+                       };
+
+                       vcc3v3_s3: vcc_lan: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_s3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_s0: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_s0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       vdd_cpu_b: regulator@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <0>;
+               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 = <&vcc_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_gpu: regulator@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_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";
+
+       fusb0: typec-portc@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb0_int>;
+               vbus-supply = <&vcc5v0_typec>;
+               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 = <&vcca1v8_codec>;
+       sdmmc-supply = <&vcc_sdio>;
+       gpio1830-supply = <&vcc_3v0>;
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_3v0>;
+       status = "okay";
+};
+
+&pinctrl {
+       buttons {
+               pwrbtn: pwrbtn {
+                       rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       fusb302x {
+               fusb0_int: fusb0-int {
+                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       leds {
+               work_led_gpio: work_led-gpio {
+                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               diy_led_gpio: diy_led-gpio {
+                       rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       lcd-panel {
+               lcd_panel_reset: lcd-panel-reset {
+                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       pcie {
+               pcie_pwr_en: pcie-pwr-en {
+                       rockchip,pins = <1 RK_PC1 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_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h: wifi-enable-h {
+                       rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb-typec {
+               vcc5v0_typec_en: vcc5v0_typec_en {
+                       rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb2 {
+               vcc5v0_host_en: vcc5v0-host-en {
+                       rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcca1v8_s3>;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       max-frequency = <150000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&tsadc {
+       /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-mode = <1>;
+       /* tshut polarity 0:LOW 1:HIGH */
+       rockchip,hw-tshut-polarity = <1>;
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+
+       u2phy0_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+       status = "okay";
+};
+
+&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 36b60791c156d2ace112850571418d0410f81bd7..5421e23760c35c60d45e0519f1cb9203abf7db83 100644 (file)
                vin-supply = <&vcc_1v8>;
        };
 
+       vcc3v0_sd: vcc3v0-sd {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdmmc0_pwr_h>;
+               regulator-always-on;
+               regulator-max-microvolt = <3000000>;
+               regulator-min-microvolt = <3000000>;
+               regulator-name = "vcc3v0_sd";
+               vin-supply = <&vcc3v3_sys>;
+       };
+
        vcc3v3_sys: vcc3v3-sys {
                compatible = "regulator-fixed";
                regulator-name = "vcc3v3_sys";
                vin-supply = <&vcc_sys>;
        };
 
-       vcc_sys: vcc-sys {
-               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>;
-       };
-
        vcc5v0_host: vcc5v0-host-regulator {
                compatible = "regulator-fixed";
                enable-active-high;
-               gpio = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
+               gpio = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&vcc5v0_host_en>;
                regulator-name = "vcc5v0_host";
                vin-supply = <&vcc_sys>;
        };
 
+       vcc5v0_typec0: vcc5v0-typec0-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio2 RK_PA0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_typec0_en>;
+               regulator-name = "vcc5v0_typec0";
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_sys: vcc-sys {
+               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>;
+       };
+
        vdd_log: vdd-log {
                compatible = "pwm-regulator";
                pwms = <&pwm2 0 25000 1>;
                #clock-cells = <1>;
                clock-output-names = "xin32k", "rk808-clkout2";
                pinctrl-names = "default";
-               pinctrl-0 = <&pmic_int_l &pmic_dvs2>;
+               pinctrl-0 = <&pmic_int_l>;
                rockchip,system-power-controller;
                wakeup-source;
 
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
                                        regulator-suspend-microvolt = <3000000>;
                                <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
                };
 
-               pmic_dvs2: pmic-dvs2 {
-                       rockchip,pins =
-                               <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
-               };
-
                vsel1_gpio: vsel1-gpio {
                        rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
                };
                };
        };
 
+       sd {
+               sdmmc0_pwr_h: sdmmc0-pwr-h {
+                       rockchip,pins =
+                               <RK_GPIO0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
        usb2 {
                vcc5v0_host_en: vcc5v0-host-en {
                        rockchip,pins =
                                <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
                };
+               vcc5v0_typec0_en: vcc5v0-typec0-en {
+                       rockchip,pins =
+                               <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
        };
 };
 
 };
 
 &sdmmc {
+       broken-cd;
        bus-width = <4>;
        cap-mmc-highspeed;
        cap-sd-highspeed;
        max-frequency = <150000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+       vmmc-supply = <&vcc3v0_sd>;
        vqmmc-supply = <&vcc_sdio>;
        status = "okay";
 };
        status = "okay";
 
        u2phy0_otg: otg-port {
+               phy-supply = <&vcc5v0_typec0>;
                status = "okay";
        };
 
index c88e603396f610615e4070bc8af62dfa9d389b0b..99e7f65c1779475e4f24ebbf68182f78b1a63afc 100644 (file)
@@ -74,6 +74,7 @@
                        clocks = <&cru ARMCLKL>;
                        #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                };
 
                cpu_l1: cpu@1 {
@@ -84,6 +85,7 @@
                        clocks = <&cru ARMCLKL>;
                        #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                };
 
                cpu_l2: cpu@2 {
@@ -94,6 +96,7 @@
                        clocks = <&cru ARMCLKL>;
                        #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                };
 
                cpu_l3: cpu@3 {
                        clocks = <&cru ARMCLKL>;
                        #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                };
 
                cpu_b0: cpu@100 {
                        clocks = <&cru ARMCLKB>;
                        #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <436>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
                };
 
                cpu_b1: cpu@101 {
                        clocks = <&cru ARMCLKB>;
                        #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <436>;
+                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+               };
+
+               idle-states {
+                       entry-method = "psci";
+
+                       CPU_SLEEP: cpu-sleep {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <120>;
+                               exit-latency-us = <250>;
+                               min-residency-us = <900>;
+                       };
+
+                       CLUSTER_SLEEP: cluster-sleep {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x1010000>;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <500>;
+                               min-residency-us = <2000>;
+                       };
                };
        };
 
                resets = <&cru SRST_P_MIPI_DSI0>;
                reset-names = "apb";
                rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <0>;
                status = "disabled";
 
                ports {
                resets = <&cru SRST_P_MIPI_DSI1>;
                reset-names = "apb";
                rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <0>;
                status = "disabled";
 
                ports {
index d63b56e944de9202d3fe349e85aa1f34c5e3bafb..31ba52b14e99bac5fcb916502cad710a8569a250 100644 (file)
                #size-cells = <1>;
                ranges = <0 0 0 0xffffffff>;
 
+               spi0: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi1: spi@54006100 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006100 0x100>;
+                       interrupts = <0 216 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi1>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                                 <&mio_clk 12>;
                        resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
                                 <&mio_rst 12>;
+                       phy-names = "usb";
+                       phys = <&usb_phy0>;
                        has-transaction-translator;
                };
 
                                 <&mio_clk 13>;
                        resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
                                 <&mio_rst 13>;
+                       phy-names = "usb";
+                       phys = <&usb_phy1>;
                        has-transaction-translator;
                };
 
                                 <&mio_clk 14>;
                        resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
                                 <&mio_rst 14>;
+                       phy-names = "usb";
+                       phys = <&usb_phy2>;
                        has-transaction-translator;
                };
 
                        pinctrl: pinctrl {
                                compatible = "socionext,uniphier-ld11-pinctrl";
                        };
+
+                       usb-phy {
+                               compatible = "socionext,uniphier-ld11-usb2-phy";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               usb_phy0: phy@0 {
+                                       reg = <0>;
+                                       #phy-cells = <0>;
+                               };
+
+                               usb_phy1: phy@1 {
+                                       reg = <1>;
+                                       #phy-cells = <0>;
+                               };
+
+                               usb_phy2: phy@2 {
+                                       reg = <2>;
+                                       #phy-cells = <0>;
+                               };
+                       };
                };
 
                soc-glue@5f900000 {
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
index 1a5e7c24b90160a4b05ea237705a17415adb630f..d7ae28afef7d799d630c8318ce10dafc5b9a1a38 100644 (file)
 &nand {
        status = "okay";
 };
+
+&usb {
+       status = "okay";
+};
index 440c2e6a638b998c163b3f8aea91f94e115f516b..406244a5c8e8527647972b6233d81af86fc975a3 100644 (file)
@@ -75,3 +75,7 @@
                drive-strength = <9>;
        };
 };
+
+&usb {
+       status = "okay";
+};
index caf112629caad635b0948e23c8aa67941cf6161d..d7e2d8969601738779140de7369c99c572a7831f 100644 (file)
                #size-cells = <1>;
                ranges = <0 0 0 0xffffffff>;
 
+               spi0: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi1: spi@54006100 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006100 0x100>;
+                       interrupts = <0 216 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi1>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi2: spi@54006200 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006200 0x100>;
+                       interrupts = <0 229 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi2>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi3: spi@54006300 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006300 0x100>;
+                       interrupts = <0 230 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi3>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        cdns,phy-dll-delay-sdclk-hsmmc = <21>;
                };
 
+               sd: sdhc@5a400000 {
+                       compatible = "socionext,uniphier-sd-v3.1.1";
+                       status = "disabled";
+                       reg = <0x5a400000 0x800>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       clocks = <&sd_clk 0>;
+                       reset-names = "host";
+                       resets = <&sd_rst 0>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+               };
+
                soc_glue: soc-glue@5f800000 {
                        compatible = "socionext,uniphier-ld20-soc-glue",
                                     "simple-mfd", "syscon";
                        efuse@200 {
                                compatible = "socionext,uniphier-efuse";
                                reg = <0x200 0x68>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               /* USB cells */
+                               usb_rterm0: trim@54,4 {
+                                       reg = <0x54 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_rterm1: trim@55,4 {
+                                       reg = <0x55 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_rterm2: trim@58,4 {
+                                       reg = <0x58 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_rterm3: trim@59,4 {
+                                       reg = <0x59 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_sel_t0: trim@54,0 {
+                                       reg = <0x54 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_sel_t1: trim@55,0 {
+                                       reg = <0x55 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_sel_t2: trim@58,0 {
+                                       reg = <0x58 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_sel_t3: trim@59,0 {
+                                       reg = <0x59 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_hs_i0: trim@56,0 {
+                                       reg = <0x56 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_hs_i2: trim@5a,0 {
+                                       reg = <0x5a 1>;
+                                       bits = <0 4>;
+                               };
                        };
                };
 
                        };
                };
 
+               usb: usb@65a00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65a00000 0xcd00>;
+                       interrupt-names = "host";
+                       interrupts = <0 134 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb1>,
+                                   <&pinctrl_usb2>, <&pinctrl_usb3>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 14>, <&sys_clk 14>, <&sys_clk 14>;
+                       resets = <&usb_rst 15>;
+                       phys = <&usb_hsphy0>, <&usb_hsphy1>,
+                              <&usb_hsphy2>, <&usb_hsphy3>,
+                              <&usb_ssphy0>, <&usb_ssphy1>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65b00000 {
+                       compatible = "socionext,uniphier-ld20-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65b00000 0x400>;
+
+                       usb_rst: reset@0 {
+                               compatible = "socionext,uniphier-ld20-usb3-reset";
+                               reg = <0x0 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb_vbus0: regulator@100 {
+                               compatible = "socionext,uniphier-ld20-usb3-regulator";
+                               reg = <0x100 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb_vbus1: regulator@110 {
+                               compatible = "socionext,uniphier-ld20-usb3-regulator";
+                               reg = <0x110 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb_vbus2: regulator@120 {
+                               compatible = "socionext,uniphier-ld20-usb3-regulator";
+                               reg = <0x120 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb_vbus3: regulator@130 {
+                               compatible = "socionext,uniphier-ld20-usb3-regulator";
+                               reg = <0x130 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 14>;
+                               reset-names = "link";
+                               resets = <&sys_rst 14>;
+                       };
+
+                       usb_hsphy0: hs-phy@200 {
+                               compatible = "socionext,uniphier-ld20-usb3-hsphy";
+                               reg = <0x200 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 16>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 16>;
+                               vbus-supply = <&usb_vbus0>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm0>, <&usb_sel_t0>,
+                                             <&usb_hs_i0>;
+                       };
+
+                       usb_hsphy1: hs-phy@210 {
+                               compatible = "socionext,uniphier-ld20-usb3-hsphy";
+                               reg = <0x210 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 16>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 16>;
+                               vbus-supply = <&usb_vbus1>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm1>, <&usb_sel_t1>,
+                                             <&usb_hs_i0>;
+                       };
+
+                       usb_hsphy2: hs-phy@220 {
+                               compatible = "socionext,uniphier-ld20-usb3-hsphy";
+                               reg = <0x220 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 17>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 17>;
+                               vbus-supply = <&usb_vbus2>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm2>, <&usb_sel_t2>,
+                                             <&usb_hs_i2>;
+                       };
+
+                       usb_hsphy3: hs-phy@230 {
+                               compatible = "socionext,uniphier-ld20-usb3-hsphy";
+                               reg = <0x230 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 17>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 17>;
+                               vbus-supply = <&usb_vbus3>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm3>, <&usb_sel_t3>,
+                                             <&usb_hs_i2>;
+                       };
+
+                       usb_ssphy0: ss-phy@300 {
+                               compatible = "socionext,uniphier-ld20-usb3-ssphy";
+                               reg = <0x300 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 18>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 18>;
+                               vbus-supply = <&usb_vbus0>;
+                       };
+
+                       usb_ssphy1: ss-phy@310 {
+                               compatible = "socionext,uniphier-ld20-usb3-ssphy";
+                               reg = <0x310 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 14>, <&sys_clk 19>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 14>, <&sys_rst 19>;
+                               vbus-supply = <&usb_vbus1>;
+                       };
+               };
+
                nand: nand@68000000 {
                        compatible = "socionext,uniphier-denali-nand-v5b";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
index c1bb607bd2115dc56267736f6f10707dc76dde16..a41f7cac952a32ba488ff208c9c431daeaed4a99 100644 (file)
        status = "okay";
 };
 
+&sd {
+       status = "okay";
+};
+
 &eth0 {
        status = "okay";
        phy-handle = <&ethphy0>;
 &nand {
        status = "okay";
 };
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
index 2a4cf427f5d3717317178ea35c0c335e9e32b03b..4f57c9e9d7a81dc65f3a1c2402bb89a3b447bb29 100644 (file)
                #size-cells = <1>;
                ranges = <0 0 0 0xffffffff>;
 
+               spi0: spi@54006000 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006000 0x100>;
+                       interrupts = <0 39 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi0>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
+               spi1: spi@54006100 {
+                       compatible = "socionext,uniphier-scssi";
+                       status = "disabled";
+                       reg = <0x54006100 0x100>;
+                       interrupts = <0 216 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_spi1>;
+                       clocks = <&peri_clk 11>;
+                       resets = <&peri_rst 11>;
+               };
+
                serial0: serial@54006800 {
                        compatible = "socionext,uniphier-uart";
                        status = "disabled";
                        cdns,phy-dll-delay-sdclk-hsmmc = <21>;
                };
 
+               sd: sdhc@5a400000 {
+                       compatible = "socionext,uniphier-sd-v3.1.1";
+                       status = "disabled";
+                       reg = <0x5a400000 0x800>;
+                       interrupts = <0 76 4>;
+                       pinctrl-names = "default", "uhs";
+                       pinctrl-0 = <&pinctrl_sd>;
+                       pinctrl-1 = <&pinctrl_sd_uhs>;
+                       clocks = <&sd_clk 0>;
+                       reset-names = "host";
+                       resets = <&sd_rst 0>;
+                       bus-width = <4>;
+                       cap-sd-highspeed;
+                       sd-uhs-sdr12;
+                       sd-uhs-sdr25;
+                       sd-uhs-sdr50;
+               };
+
                soc_glue: soc-glue@5f800000 {
                        compatible = "socionext,uniphier-pxs3-soc-glue",
                                     "simple-mfd", "syscon";
                        efuse@200 {
                                compatible = "socionext,uniphier-efuse";
                                reg = <0x200 0x68>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               /* USB cells */
+                               usb_rterm0: trim@54,4 {
+                                       reg = <0x54 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_rterm1: trim@55,4 {
+                                       reg = <0x55 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_rterm2: trim@58,4 {
+                                       reg = <0x58 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_rterm3: trim@59,4 {
+                                       reg = <0x59 1>;
+                                       bits = <4 2>;
+                               };
+                               usb_sel_t0: trim@54,0 {
+                                       reg = <0x54 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_sel_t1: trim@55,0 {
+                                       reg = <0x55 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_sel_t2: trim@58,0 {
+                                       reg = <0x58 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_sel_t3: trim@59,0 {
+                                       reg = <0x59 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_hs_i0: trim@56,0 {
+                                       reg = <0x56 1>;
+                                       bits = <0 4>;
+                               };
+                               usb_hs_i2: trim@5a,0 {
+                                       reg = <0x5a 1>;
+                                       bits = <0 4>;
+                               };
                        };
                };
 
                        };
                };
 
+               usb0: usb@65a00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65a00000 0xcd00>;
+                       interrupt-names = "host", "peripheral";
+                       interrupts = <0 134 4>, <0 135 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>;
+                       resets = <&usb0_rst 15>;
+                       phys = <&usb0_hsphy0>, <&usb0_hsphy1>,
+                              <&usb0_ssphy0>, <&usb0_ssphy1>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65b00000 {
+                       compatible = "socionext,uniphier-pxs3-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65b00000 0x400>;
+
+                       usb0_rst: reset@0 {
+                               compatible = "socionext,uniphier-pxs3-usb3-reset";
+                               reg = <0x0 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 12>;
+                               reset-names = "link";
+                               resets = <&sys_rst 12>;
+                       };
+
+                       usb0_vbus0: regulator@100 {
+                               compatible = "socionext,uniphier-pxs3-usb3-regulator";
+                               reg = <0x100 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 12>;
+                               reset-names = "link";
+                               resets = <&sys_rst 12>;
+                       };
+
+                       usb0_vbus1: regulator@110 {
+                               compatible = "socionext,uniphier-pxs3-usb3-regulator";
+                               reg = <0x110 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 12>;
+                               reset-names = "link";
+                               resets = <&sys_rst 12>;
+                       };
+
+                       usb0_hsphy0: hs-phy@200 {
+                               compatible = "socionext,uniphier-pxs3-usb3-hsphy";
+                               reg = <0x200 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 12>, <&sys_clk 16>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 12>, <&sys_rst 16>;
+                               vbus-supply = <&usb0_vbus0>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm0>, <&usb_sel_t0>,
+                                             <&usb_hs_i0>;
+                       };
+
+                       usb0_hsphy1: hs-phy@210 {
+                               compatible = "socionext,uniphier-pxs3-usb3-hsphy";
+                               reg = <0x210 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 12>, <&sys_clk 16>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 12>, <&sys_rst 16>;
+                               vbus-supply = <&usb0_vbus1>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm1>, <&usb_sel_t1>,
+                                             <&usb_hs_i0>;
+                       };
+
+                       usb0_ssphy0: ss-phy@300 {
+                               compatible = "socionext,uniphier-pxs3-usb3-ssphy";
+                               reg = <0x300 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 12>, <&sys_clk 17>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 12>, <&sys_rst 17>;
+                               vbus-supply = <&usb0_vbus0>;
+                       };
+
+                       usb0_ssphy1: ss-phy@310 {
+                               compatible = "socionext,uniphier-pxs3-usb3-ssphy";
+                               reg = <0x310 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy";
+                               clocks = <&sys_clk 12>, <&sys_clk 18>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 12>, <&sys_rst 18>;
+                               vbus-supply = <&usb0_vbus1>;
+                       };
+               };
+
+               usb1: usb@65c00000 {
+                       compatible = "socionext,uniphier-dwc3", "snps,dwc3";
+                       status = "disabled";
+                       reg = <0x65c00000 0xcd00>;
+                       interrupt-names = "host", "peripheral";
+                       interrupts = <0 137 4>, <0 138 4>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>;
+                       clock-names = "ref", "bus_early", "suspend";
+                       clocks = <&sys_clk 13>, <&sys_clk 13>, <&sys_clk 13>;
+                       resets = <&usb1_rst 15>;
+                       phys = <&usb1_hsphy0>, <&usb1_hsphy1>,
+                              <&usb1_ssphy0>;
+                       dr_mode = "host";
+               };
+
+               usb-glue@65d00000 {
+                       compatible = "socionext,uniphier-pxs3-dwc3-glue",
+                                    "simple-mfd";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x65d00000 0x400>;
+
+                       usb1_rst: reset@0 {
+                               compatible = "socionext,uniphier-pxs3-usb3-reset";
+                               reg = <0x0 0x4>;
+                               #reset-cells = <1>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 13>;
+                               reset-names = "link";
+                               resets = <&sys_rst 13>;
+                       };
+
+                       usb1_vbus0: regulator@100 {
+                               compatible = "socionext,uniphier-pxs3-usb3-regulator";
+                               reg = <0x100 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 13>;
+                               reset-names = "link";
+                               resets = <&sys_rst 13>;
+                       };
+
+                       usb1_vbus1: regulator@110 {
+                               compatible = "socionext,uniphier-pxs3-usb3-regulator";
+                               reg = <0x110 0x10>;
+                               clock-names = "link";
+                               clocks = <&sys_clk 13>;
+                               reset-names = "link";
+                               resets = <&sys_rst 13>;
+                       };
+
+                       usb1_hsphy0: hs-phy@200 {
+                               compatible = "socionext,uniphier-pxs3-usb3-hsphy";
+                               reg = <0x200 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy", "phy-ext";
+                               clocks = <&sys_clk 13>, <&sys_clk 20>,
+                                        <&sys_clk 14>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 13>, <&sys_rst 20>;
+                               vbus-supply = <&usb1_vbus0>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm2>, <&usb_sel_t2>,
+                                             <&usb_hs_i2>;
+                       };
+
+                       usb1_hsphy1: hs-phy@210 {
+                               compatible = "socionext,uniphier-pxs3-usb3-hsphy";
+                               reg = <0x210 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy", "phy-ext";
+                               clocks = <&sys_clk 13>, <&sys_clk 20>,
+                                        <&sys_clk 14>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 13>, <&sys_rst 20>;
+                               vbus-supply = <&usb1_vbus1>;
+                               nvmem-cell-names = "rterm", "sel_t", "hs_i";
+                               nvmem-cells = <&usb_rterm3>, <&usb_sel_t3>,
+                                             <&usb_hs_i2>;
+                       };
+
+                       usb1_ssphy0: ss-phy@300 {
+                               compatible = "socionext,uniphier-pxs3-usb3-ssphy";
+                               reg = <0x300 0x10>;
+                               #phy-cells = <0>;
+                               clock-names = "link", "phy", "phy-ext";
+                               clocks = <&sys_clk 13>, <&sys_clk 21>,
+                                        <&sys_clk 14>;
+                               reset-names = "link", "phy";
+                               resets = <&sys_rst 13>, <&sys_rst 21>;
+                               vbus-supply = <&usb1_vbus0>;
+                       };
+               };
+
                nand: nand@68000000 {
                        compatible = "socionext,uniphier-denali-nand-v5b";
                        status = "disabled";
                        interrupts = <0 65 4>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_nand>;
-                       clocks = <&sys_clk 2>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
                        resets = <&sys_rst 2>;
                };
        };
diff --git a/arch/arm64/boot/dts/synaptics/as370.dtsi b/arch/arm64/boot/dts/synaptics/as370.dtsi
new file mode 100644 (file)
index 0000000..7331acf
--- /dev/null
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2018 Synaptics Incorporated
+ *
+ * Author: Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "syna,as370";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               cpu1: cpu@1 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x1>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               cpu2: cpu@2 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x2>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               cpu3: cpu@3 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x3>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+                       cpu-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               l2: cache {
+                       compatible = "cache";
+               };
+
+               idle-states {
+                       entry-method = "psci";
+                       CPU_SLEEP_0: cpu-sleep-0 {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <75>;
+                               exit-latency-us = <155>;
+                               min-residency-us = <1000>;
+                       };
+               };
+       };
+
+       osc: osc {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <25000000>;
+       };
+
+       pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>,
+                                    <&cpu1>,
+                                    <&cpu2>,
+                                    <&cpu3>;
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+
+       soc@f7000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0 0xf7000000 0x1000000>;
+
+               gic: interrupt-controller@901000 {
+                       compatible = "arm,gic-400";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x901000 0x1000>,
+                             <0x902000 0x2000>,
+                             <0x904000 0x2000>,
+                             <0x906000 0x2000>;
+                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               };
+
+               apb@e80000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0xe80000 0x10000>;
+
+                       uart0: serial@c00 {
+                               compatible = "snps,dw-apb-uart";
+                               reg = <0xc00 0x100>;
+                               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&osc>;
+                               reg-shift = <2>;
+                               status = "disabled";
+                       };
+
+                       gpio0: gpio@1800 {
+                               compatible = "snps,dw-apb-gpio";
+                               reg = <0x1800 0x400>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               porta: gpio-port@0 {
+                                       compatible = "snps,dw-apb-gpio-port";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       snps,nr-gpios = <32>;
+                                       reg = <0>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+
+                       gpio1: gpio@2000 {
+                               compatible = "snps,dw-apb-gpio";
+                               reg = <0x2000 0x400>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               portb: gpio-port@1 {
+                                       compatible = "snps,dw-apb-gpio-port";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       snps,nr-gpios = <32>;
+                                       reg = <0>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+               };
+       };
+};
index 2409344df4fa2f50ee9e91feddc483e0a4a10279..adcd6341e40c02aabef992516a075eb2a14245a8 100644 (file)
@@ -8,13 +8,13 @@
 &cbass_main {
        gic500: interrupt-controller@1800000 {
                compatible = "arm,gic-v3";
-               #address-cells = <1>;
-               #size-cells = <1>;
+               #address-cells = <2>;
+               #size-cells = <2>;
                ranges;
                #interrupt-cells = <3>;
                interrupt-controller;
-               reg = <0x01800000 0x10000>,     /* GICD */
-                     <0x01880000 0x90000>;     /* GICR */
+               reg = <0x00 0x01800000 0x00 0x10000>,   /* GICD */
+                     <0x00 0x01880000 0x00 0x90000>;   /* GICR */
                /*
                 * vcpumntirq:
                 * virtual CPU interface maintenance interrupt
 
                gic_its: gic-its@18200000 {
                        compatible = "arm,gic-v3-its";
-                       reg = <0x01820000 0x10000>;
+                       reg = <0x00 0x01820000 0x00 0x10000>;
                        msi-controller;
                        #msi-cells = <1>;
                };
        };
+
+       secure_proxy_main: mailbox@32c00000 {
+               compatible = "ti,am654-secure-proxy";
+               #mbox-cells = <1>;
+               reg-names = "target_data", "rt", "scfg";
+               reg = <0x00 0x32c00000 0x00 0x100000>,
+                     <0x00 0x32400000 0x00 0x100000>,
+                     <0x00 0x32800000 0x00 0x100000>;
+               interrupt-names = "rx_011";
+               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       main_uart0: serial@2800000 {
+               compatible = "ti,am654-uart";
+               reg = <0x00 0x02800000 0x00 0x100>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <48000000>;
+               current-speed = <115200>;
+       };
+
+       main_uart1: serial@2810000 {
+               compatible = "ti,am654-uart";
+               reg = <0x00 0x02810000 0x00 0x100>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <48000000>;
+               current-speed = <115200>;
+       };
+
+       main_uart2: serial@2820000 {
+               compatible = "ti,am654-uart";
+               reg = <0x00 0x02820000 0x00 0x100>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <48000000>;
+               current-speed = <115200>;
+       };
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
new file mode 100644 (file)
index 0000000..8c611d1
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM6 SoC Family MCU Domain peripherals
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+&cbass_mcu {
+       mcu_uart0: serial@40a00000 {
+               compatible = "ti,am654-uart";
+                       reg = <0x00 0x40a00000 0x00 0x100>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       interrupts = <GIC_SPI 565 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <96000000>;
+                       current-speed = <115200>;
+       };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
new file mode 100644 (file)
index 0000000..affc3c3
--- /dev/null
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM6 SoC Family Wakeup Domain peripherals
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+&cbass_wakeup {
+       dmsc: dmsc {
+               compatible = "ti,k2g-sci";
+               ti,host-id = <12>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               mbox-names = "rx", "tx";
+
+               mboxes= <&secure_proxy_main 11>,
+                       <&secure_proxy_main 13>;
+
+               k3_pds: power-controller {
+                       compatible = "ti,sci-pm-domain";
+                       #power-domain-cells = <1>;
+               };
+
+               k3_clks: clocks {
+                       compatible = "ti,k2g-sci-clk";
+                       #clock-cells = <2>;
+               };
+
+               k3_reset: reset-controller {
+                       compatible = "ti,sci-reset";
+                       #reset-cells = <2>;
+               };
+       };
+
+       wkup_uart0: serial@42300000 {
+               compatible = "ti,am654-uart";
+               reg = <0x00 0x42300000 0x00 0x100>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+               interrupts = <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <48000000>;
+               current-speed = <115200>;
+       };
+};
index cede1fa0983c9321511649251cff09c1cdaa4e63..3d4bf369d0304a3afb8bcb43e18ca1eeb2648413 100644 (file)
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               serial0 = &wkup_uart0;
+               serial1 = &mcu_uart0;
+               serial2 = &main_uart0;
+               serial3 = &main_uart1;
+               serial4 = &main_uart2;
+       };
+
        chosen { };
 
        firmware {
 
        cbass_main: interconnect@100000 {
                compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges = <0x00100000 0x00 0x00100000 0x00020000>, /* ctrl mmr */
-                        <0x00600000 0x00 0x00600000 0x00001100>, /* GPIO */
-                        <0x00900000 0x00 0x00900000 0x00012000>, /* serdes */
-                        <0x01000000 0x00 0x01000000 0x0af02400>, /* Most peripherals */
-                        <0x30800000 0x00 0x30800000 0x0bc00000>, /* MAIN NAVSS */
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
+                        <0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */
+                        <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */
+                        <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */
+                        <0x00 0x30800000 0x00 0x30800000 0x00 0x0bc00000>, /* MAIN NAVSS */
                         /* MCUSS Range */
-                        <0x28380000 0x00 0x28380000 0x03880000>,
-                        <0x40200000 0x00 0x40200000 0x00900100>,
-                        <0x42040000 0x00 0x42040000 0x03ac2400>,
-                        <0x45100000 0x00 0x45100000 0x00c24000>,
-                        <0x46000000 0x00 0x46000000 0x00200000>,
-                        <0x47000000 0x00 0x47000000 0x00068400>;
+                        <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>,
+                        <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>,
+                        <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>,
+                        <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>,
+                        <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>,
+                        <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>;
 
                cbass_mcu: interconnect@28380000 {
                        compatible = "simple-bus";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0x28380000 0x28380000 0x03880000>, /* MCU NAVSS*/
-                                <0x40200000 0x40200000 0x00900100>, /* First peripheral window */
-                                <0x42040000 0x42040000 0x03ac2400>, /* WKUP */
-                                <0x45100000 0x45100000 0x00c24000>, /* MMRs, remaining NAVSS */
-                                <0x46000000 0x46000000 0x00200000>, /* CPSW */
-                                <0x47000000 0x47000000 0x00068400>; /* OSPI space 1 */
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, /* MCU NAVSS*/
+                                <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>, /* First peripheral window */
+                                <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, /* WKUP */
+                                <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, /* MMRs, remaining NAVSS */
+                                <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, /* CPSW */
+                                <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>; /* OSPI space 1 */
 
                        cbass_wakeup: interconnect@42040000 {
                                compatible = "simple-bus";
                                #address-cells = <1>;
                                #size-cells = <1>;
                                /* WKUP  Basic peripherals */
-                               ranges = <0x42040000 0x42040000 0x03ac2400>;
+                               ranges = <0x42040000 0x00 0x42040000 0x03ac2400>;
                        };
                };
        };
@@ -85,3 +93,5 @@
 
 /* Now include the peripherals for each bus segments */
 #include "k3-am65-main.dtsi"
+#include "k3-am65-mcu.dtsi"
+#include "k3-am65-wakeup.dtsi"
index af6956fdc13f49662c47e2750b4296b843851a2e..e146ac2ad781b1f27ad0787f9f6a7b06b0f1a805 100644 (file)
@@ -34,3 +34,8 @@
                };
        };
 };
+
+&wkup_uart0 {
+       /* Wakeup UART is used by System firmware */
+       status = "disabled";
+};
index 3d165b4cdd2afe919ac19040f0543c0d76917272..3cb995606e605badbc58d977201eb10801ec3fdc 100644 (file)
@@ -50,6 +50,8 @@ CONFIG_ARCH_ROCKCHIP=y
 CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_RENESAS=y
+CONFIG_ARCH_R8A774A1=y
+CONFIG_ARCH_R8A774C0=y
 CONFIG_ARCH_R8A7795=y
 CONFIG_ARCH_R8A7796=y
 CONFIG_ARCH_R8A77965=y
@@ -68,6 +70,7 @@ CONFIG_ARCH_XGENE=y
 CONFIG_ARCH_ZX=y
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
 CONFIG_PCI_IOV=y
 CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=y
@@ -115,6 +118,7 @@ CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
 CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
 CONFIG_ARM_SCPI_CPUFREQ=y
 CONFIG_ARM_TEGRA186_CPUFREQ=y
+CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -150,6 +154,9 @@ CONFIG_BRIDGE_VLAN_FILTERING=y
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
 CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_QRTR=m
+CONFIG_QRTR_SMD=m
+CONFIG_QRTR_TUN=m
 CONFIG_BPF_JIT=y
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
@@ -222,6 +229,9 @@ CONFIG_THUNDER_NIC_PF=y
 CONFIG_HIX5HD2_GMAC=y
 CONFIG_HNS_DSAF=y
 CONFIG_HNS_ENET=y
+CONFIG_HNS3=y
+CONFIG_HNS3_HCLGE=y
+CONFIG_HNS3_ENET=y
 CONFIG_E1000E=y
 CONFIG_IGB=y
 CONFIG_IGBVF=y
@@ -279,6 +289,7 @@ CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_OMAP=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_8250_UNIPHIER=y
 CONFIG_SERIAL_OF_PLATFORM=y
@@ -434,6 +445,7 @@ CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_EXYNOS_MIC=y
 CONFIG_DRM_ROCKCHIP=m
+CONFIG_DRM_SUN4I=m
 CONFIG_ROCKCHIP_ANALOGIX_DP=y
 CONFIG_ROCKCHIP_CDN_DP=y
 CONFIG_ROCKCHIP_DW_HDMI=y
@@ -520,6 +532,7 @@ CONFIG_MMC_MESON_GX=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_SPI=y
 CONFIG_MMC_SDHI=y
+CONFIG_MMC_UNIPHIER=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_HI3798CV200=y
@@ -577,6 +590,7 @@ CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_CLK_QORIQ=y
 CONFIG_COMMON_CLK_PWM=y
+CONFIG_TI_SCI_CLK=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_IPQ_GCC_8074=y
@@ -588,6 +602,7 @@ CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_ARM_MHU=y
 CONFIG_PLATFORM_MHU=y
 CONFIG_BCM2835_MBOX=y
+CONFIG_TI_MESSAGE_MANAGER=y
 CONFIG_QCOM_APCS_IPC=y
 CONFIG_ROCKCHIP_IOMMU=y
 CONFIG_TEGRA_IOMMU_SMMU=y
@@ -608,6 +623,7 @@ CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_ARCH_TEGRA_194_SOC=y
 CONFIG_ARCH_K3_AM6_SOC=y
 CONFIG_SOC_TI=y
+CONFIG_TI_SCI_PM_DOMAINS=y
 CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_EXTCON_USBC_CROS_EC=y
@@ -627,6 +643,7 @@ CONFIG_PWM_RCAR=m
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_TEGRA=m
+CONFIG_RESET_TI_SCI=y
 CONFIG_PHY_XGENE=y
 CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_HI6220_USB=y
@@ -638,10 +655,13 @@ CONFIG_PHY_QCOM_USB_HS=y
 CONFIG_PHY_RCAR_GEN3_USB2=y
 CONFIG_PHY_RCAR_GEN3_USB3=m
 CONFIG_PHY_ROCKCHIP_EMMC=y
+CONFIG_PHY_ROCKCHIP_INNO_HDMI=m
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_PCIE=m
 CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_PHY_UNIPHIER_USB3=y
+CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
index 2bf6691371c212d5d59c9a0fc8cc0bfc6fdf7006..3e2091708b8e51f04b90e8d6b14c586dd54afeab 100644 (file)
 #define USER_DS                (TASK_SIZE_64 - 1)
 
 #ifndef __ASSEMBLY__
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
 #ifdef __KERNEL__
 
 #include <linux/build_bug.h>
index ed46dc188b225d2d0aec587f435b5b2ce774c5cd..44e3c351e1ea6efe09426697b2ca7a99f3cd6040 100644 (file)
@@ -16,7 +16,6 @@
 #define pr_fmt(fmt) "ACPI: " fmt
 
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
 #include <linux/cpumask.h>
 #include <linux/efi.h>
 #include <linux/efi-bgrt.h>
index 4f4f1815e0471e0eb2e242b8462a7e4eb8e8b137..eac1d0cc595ca8cc2fda38de34549f02d508c8e1 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
-#include <linux/bootmem.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/memblock.h>
index d0f62dd24c906b7054d7d7a76897c18736b50efd..953e316521fcaa34fcbe26a9ca8ca7de6b9f51e9 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/initrd.h>
 #include <linux/console.h>
 #include <linux/cache.h>
-#include <linux/bootmem.h>
 #include <linux/screen_info.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
@@ -217,8 +216,9 @@ static void __init request_standard_resources(void)
        kernel_data.end     = __pa_symbol(_end - 1);
 
        num_standard_resources = memblock.memory.cnt;
-       standard_resources = alloc_bootmem_low(num_standard_resources *
-                                              sizeof(*standard_resources));
+       standard_resources = memblock_alloc_low(num_standard_resources *
+                                               sizeof(*standard_resources),
+                                               SMP_CACHE_BYTES);
 
        for_each_memblock(memory, region) {
                res = &standard_resources[i++];
index d190612b8f33b2555ffe447bfa72421b34430c4c..3a703e5d4e3237f9844d09e871ef1eaa62b781cc 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <linux/gfp.h>
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/cache.h>
 #include <linux/export.h>
 #include <linux/slab.h>
index 3cf87341859f91345e30548344fafb1834560205..9d9582cac6c40cad483d431682a178c67c445b45 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/errno.h>
 #include <linux/swap.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/cache.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
@@ -536,7 +535,7 @@ static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn)
         * memmap array.
         */
        if (pg < pgend)
-               free_bootmem(pg, pgend - pg);
+               memblock_free(pg, pgend - pg);
 }
 
 /*
@@ -599,7 +598,7 @@ void __init mem_init(void)
        free_unused_memmap();
 #endif
        /* this will put all unused low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 
        kexec_reserve_crashkres_pages();
 
index fccb1a6f8c6f8c1b742e1efb7e6e9c2f90bcca33..63527e585aaceb6163f34898a0f4d389a3d61a03 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #define pr_fmt(fmt) "kasan: " fmt
-#include <linux/bootmem.h>
 #include <linux/kasan.h>
 #include <linux/kernel.h>
 #include <linux/sched/task.h>
@@ -38,7 +37,7 @@ static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
 
 static phys_addr_t __init kasan_alloc_zeroed_page(int node)
 {
-       void *p = memblock_virt_alloc_try_nid(PAGE_SIZE, PAGE_SIZE,
+       void *p = memblock_alloc_try_nid(PAGE_SIZE, PAGE_SIZE,
                                              __pa(MAX_DMA_ADDRESS),
                                              MEMBLOCK_ALLOC_ACCESSIBLE, node);
        return __pa(p);
index 9498c15b847b12e6be1e0d47b3f85f26911e79dc..394b8d554def4c3372425ed5088ee1116ef9898e 100644 (file)
@@ -101,7 +101,7 @@ static phys_addr_t __init early_pgtable_alloc(void)
        phys_addr_t phys;
        void *ptr;
 
-       phys = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+       phys = memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
 
        /*
         * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE
index d7b66fc5e1c579d047ba262a2607a642e6c2e9e6..27a31efd9e8e9ba569651961e325c3e2c6c5b32f 100644 (file)
@@ -20,7 +20,6 @@
 #define pr_fmt(fmt) "NUMA: " fmt
 
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -168,7 +167,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size,
 {
        int nid = early_cpu_to_node(cpu);
 
-       return  memblock_virt_alloc_try_nid(size, align,
+       return  memblock_alloc_try_nid(size, align,
                        __pa(MAX_DMA_ADDRESS), MEMBLOCK_ALLOC_ACCESSIBLE, nid);
 }
 
@@ -237,7 +236,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
        if (start_pfn >= end_pfn)
                pr_info("Initmem setup node %d [<memory-less node>]\n", nid);
 
-       nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
+       nd_pa = memblock_phys_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
        nd = __va(nd_pa);
 
        /* report and initialize */
index f65a084607fd4ae509db40df3385895f0c6c7a21..84420109113d50ac3cc2f3a46b9f7938ffdf6bf2 100644 (file)
@@ -13,7 +13,6 @@ config C6X
        select GENERIC_ATOMIC64
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_TRACEHOOK
-       select HAVE_MEMBLOCK
        select SPARSE_IRQ
        select IRQ_DOMAIN
        select OF
index 8f7cce829f8e2630cb88e81cdb024a8375a59e4f..a8581f5b27f63184bfc18c4c45e3b6273ea62772 100644 (file)
 #include <asm/page.h>
 #include <asm/current.h>
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr()                    \
-({                                             \
-       void *__pc;                             \
-       asm("mvc .S2 pce1,%0\n" : "=b"(__pc));  \
-       __pc;                                   \
-})
-
 /*
  * User space process size. This is mostly meaningless for NOMMU
  * but some C6X processors may have RAM addresses up to 0xFFFFFFFF.
index 05d96a9541b5873027c8a2a7d9a41a36745c5ea7..e9d6824ae94d51201a9aea3c4200318a206bff2d 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/memblock.h>
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
 #include <linux/clkdev.h>
 #include <linux/initrd.h>
 #include <linux/kernel.h>
@@ -291,7 +290,6 @@ notrace void __init machine_init(unsigned long dt_ptr)
 
 void __init setup_arch(char **cmdline_p)
 {
-       int bootmap_size;
        struct memblock_region *reg;
 
        printk(KERN_INFO "Initializing kernel\n");
@@ -348,16 +346,6 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data   = memory_start;
        init_mm.brk        = memory_start;
 
-       /*
-        * Give all the memory to the bootmap allocator,  tell it to put the
-        * boot mem_map at the start of memory
-        */
-       bootmap_size = init_bootmem_node(NODE_DATA(0),
-                                        memory_start >> PAGE_SHIFT,
-                                        PAGE_OFFSET >> PAGE_SHIFT,
-                                        memory_end >> PAGE_SHIFT);
-       memblock_reserve(memory_start, bootmap_size);
-
        unflatten_and_copy_device_tree();
 
        c6x_cache_init();
@@ -392,22 +380,9 @@ void __init setup_arch(char **cmdline_p)
        /* Initialize the coherent memory allocator */
        coherent_mem_init(dma_start, dma_size);
 
-       /*
-        * Free all memory as a starting point.
-        */
-       free_bootmem(PAGE_OFFSET, memory_end - PAGE_OFFSET);
-
-       /*
-        * Then reserve memory which is already being used.
-        */
-       for_each_memblock(reserved, reg) {
-               pr_debug("reserved - 0x%08x-0x%08x\n",
-                        (u32) reg->base, (u32) reg->size);
-               reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-       }
-
        max_low_pfn = PFN_DOWN(memory_end);
        min_low_pfn = PFN_UP(memory_start);
+       max_pfn = max_low_pfn;
        max_mapnr = max_low_pfn - min_low_pfn;
 
        /* Get kmalloc into gear */
index d0a8e0c4b27edcdc005ee9a12e309b560b8d6fea..01305c78720108ec39f0a199eff7b0951205d7eb 100644 (file)
@@ -135,8 +135,8 @@ void __init coherent_mem_init(phys_addr_t start, u32 size)
        if (dma_size & (PAGE_SIZE - 1))
                ++dma_pages;
 
-       bitmap_phys = memblock_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long),
-                                    sizeof(long));
+       bitmap_phys = memblock_phys_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long),
+                                         sizeof(long));
 
        dma_bitmap = phys_to_virt(bitmap_phys);
        memset(dma_bitmap, 0, dma_pages * PAGE_SIZE);
index 4cc72b0d1c1d9832457a3febe411d8a85dcff3a9..af5ada0520bea716b306209448e3235deb830ac6 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/module.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #ifdef CONFIG_BLK_DEV_RAM
 #include <linux/blkdev.h>
 #endif
@@ -38,7 +38,8 @@ void __init paging_init(void)
        struct pglist_data *pgdat = NODE_DATA(0);
        unsigned long zones_size[MAX_NR_ZONES] = {0, };
 
-       empty_zero_page      = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+       empty_zero_page      = (unsigned long) memblock_alloc(PAGE_SIZE,
+                                                             PAGE_SIZE);
        memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
        /*
@@ -61,7 +62,7 @@ void __init mem_init(void)
        high_memory = (void *)(memory_end & PAGE_MASK);
 
        /* this will put all memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 
        mem_init_print_info(NULL);
 }
index 0a0558567eaaa7bc00cb30a418b840f871c4b12d..cb64f8dacd08ee6fa56f622ddb89299f1305f607 100644 (file)
@@ -36,10 +36,8 @@ config CSKY
        select HAVE_C_RECORDMCOUNT
        select HAVE_DMA_API_DEBUG
        select HAVE_DMA_CONTIGUOUS
-       select HAVE_MEMBLOCK
        select MAY_HAVE_SPARSE_IRQ
        select MODULES_USE_ELF_RELA if MODULES
-       select NO_BOOTMEM
        select OF
        select OF_EARLY_FLATTREE
        select OF_RESERVED_MEM
index 5ad4f0b830929d7dc7c662902577daf675a870ea..b1748659b2e9578ab11d7342ea202639863a83cb 100644 (file)
@@ -4,12 +4,6 @@
 #ifndef __ASM_CSKY_PROCESSOR_H
 #define __ASM_CSKY_PROCESSOR_H
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 #include <linux/bitops.h>
 #include <asm/segment.h>
 #include <asm/ptrace.h>
index a5e3ab1d536032c72f052487bb98f14d08ca26f6..dff8b89444ec5571a6eeb82d36ac2f7f0329b8d7 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <linux/console.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/initrd.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
index e168ac087ccb2a4c6dafb9b10fe6352a38e567dc..53b1bfa4c462e798aa3753d4d4d838639d4f6cf4 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/module.h>
 #include <linux/highmem.h>
 #include <linux/smp.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
@@ -140,7 +140,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
                        pmd = (pmd_t *)pud;
                        for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
                                if (pmd_none(*pmd)) {
-                                       pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+                                       pte = (pte_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
                                        set_pmd(pmd, __pmd(__pa(pte)));
                                        BUG_ON(pte != pte_offset_kernel(pmd, 0));
                                }
index ce2711e050ad8759b916ffa9f51b1dd704242d04..dc07c078f9b8e92ee704bf1ef3664fb1ce9fae6c 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/memblock.h>
 #include <linux/swap.h>
@@ -47,7 +46,7 @@ void __init mem_init(void)
 #endif
        high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
-       free_all_bootmem();
+       memblock_free_all();
 
 #ifdef CONFIG_HIGHMEM
        for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
index 0b334b671e90c95f817a8638a89655f7f717c4d8..d19c6b16cd5d08a914c862465472620bc693a56e 100644 (file)
@@ -15,8 +15,6 @@ config H8300
        select OF
        select OF_IRQ
        select OF_EARLY_FLATTREE
-       select HAVE_MEMBLOCK
-       select NO_BOOTMEM
        select TIMER_OF
        select H8300_TMR8
        select HAVE_KERNEL_GZIP
index 985346393e4aa2122848144ca72cb58823b55a39..a060b41b2d31ca74f79aecfb50cbcef35ebb8b39 100644 (file)
 #ifndef __ASM_H8300_PROCESSOR_H
 #define __ASM_H8300_PROCESSOR_H
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 #include <linux/compiler.h>
 #include <asm/segment.h>
 #include <asm/ptrace.h>
index 34e2df5c0d6d8724509cdbacab72c9914397fa2d..b32bfa1fe99e5c56aedd9923f2f49c2807d180ce 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/console.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/of.h>
index 015287ac8ce8b8c46d5a475b74714896db840b4b..6519252ac4dbd7669ca5ebc95930e91773d4f397 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/gfp.h>
 
 #include <asm/setup.h>
@@ -67,7 +67,7 @@ void __init paging_init(void)
         * Initialize the bad page table and bad page to point
         * to a couple of allocated pages.
         */
-       empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+       empty_zero_page = (unsigned long)memblock_alloc(PAGE_SIZE, PAGE_SIZE);
        memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
        /*
@@ -96,7 +96,7 @@ void __init mem_init(void)
        max_mapnr = MAP_NR(high_memory);
 
        /* this will put all low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 
        mem_init_print_info(NULL);
 }
index 7b25d7c8fa49c6d444a79910e93ce9661ffdc00a..2b688af379e6d8dbed0bdd94ba67332cdef541ac 100644 (file)
@@ -21,9 +21,7 @@ config HEXAGON
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
-       select HAVE_MEMBLOCK
        select ARCH_DISCARD_MEMBLOCK
-       select NO_BOOTMEM
        select NEED_SG_DMA_LENGTH
        select NO_IOPORT_MAP
        select GENERIC_IOMAP
index ce67940860a536dce66bea9b59daeab1fcaa103e..227bcb9cfdac7b2b33ee3ba932aa8235e2d5aeb4 100644 (file)
@@ -27,9 +27,6 @@
 #include <asm/registers.h>
 #include <asm/hexagon_vm.h>
 
-/*  must be a macro  */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 /*  task_struct, defined elsewhere, is the "process descriptor" */
 struct task_struct;
 
index 70669937444483bd2a9be4b0a0a1956cc65ff604..38eaa7b703e7d05a939b032c051111b413c5d4b4 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <linux/dma-noncoherent.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/genalloc.h>
 #include <linux/module.h>
 #include <asm/page.h>
index dc8c7e75b5d1121ac9e6febce5e341a45778b59f..b3c3e04d4e5718ef61748a12172efec78e0354a4 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mmzone.h>
 #include <linux/mm.h>
 #include <linux/seq_file.h>
index d789b9cc0189458b2aa9da85c6410bac5af36e44..1719ede9e9bde102b66432d66e65bc462d5e6e15 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <linux/init.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <asm/atomic.h>
 #include <linux/highmem.h>
@@ -68,7 +67,7 @@ unsigned long long kmap_generation;
 void __init mem_init(void)
 {
        /*  No idea where this is actually declared.  Seems to evade LXR.  */
-       free_all_bootmem();
+       memblock_free_all();
        mem_init_print_info(NULL);
 
        /*
index 8b4a0c1748c03feb1529a32977ea3a72ad5fa867..36773def6920b4104a0c190b306e2aaf8019bd36 100644 (file)
@@ -26,9 +26,7 @@ config IA64
        select HAVE_FUNCTION_TRACER
        select TTY
        select HAVE_ARCH_TRACEHOOK
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
-       select NO_BOOTMEM
        select HAVE_VIRT_CPU_ACCOUNTING
        select ARCH_HAS_DMA_MARK_CLEAN
        select ARCH_HAS_SG_CHAIN
index 10061ccf0440db1ef6ebb2d258bf944655a91299..c91ef98ed6bf15d97485f7987ceee6ee715f0e08 100644 (file)
@@ -602,12 +602,6 @@ ia64_set_unat (__u64 *unat, void *spill_addr, unsigned long nat)
        *unat = (*unat & ~mask) | (nat << bit);
 }
 
-/*
- * Get the current instruction/program counter value.
- */
-#define current_text_addr() \
-       ({ void *_pc; _pc = (void *)ia64_getreg(_IA64_REG_IP); _pc; })
-
 static inline __u64
 ia64_get_ivr (void)
 {
index 39f4433a6f0e2dba8bcd0a46985b4b53832f0d87..bec762a9b418d3a52d12a9ebe890ad103c8ba8fb 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/smp.h>
 #include <linux/delay.h>
 #include <linux/crash_dump.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/kexec.h>
 #include <linux/elfcore.h>
 #include <linux/sysctl.h>
index f77d80edddfeb7d48dc85ffc9fad9454a60c5386..8f106638913c9bad4a7902969b2b6a59ddb8a2c5 100644 (file)
@@ -23,7 +23,7 @@
  *     Skip non-WB memory and ignore empty memory ranges.
  */
 #include <linux/module.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/crash_dump.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index 6b51c88e357811ff6a3203dbc23140e39f2b2970..b49fe6f618edb1dc78f2bd371998b56613b56ede 100644 (file)
@@ -6,7 +6,7 @@
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 #include <linux/compiler.h>
 #include <linux/export.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 EXPORT_SYMBOL(min_low_pfn);    /* defined by bootmem.c, but not exported by generic code */
 EXPORT_SYMBOL(max_low_pfn);    /* defined by bootmem.c, but not exported by generic code */
 #endif
index 550243a94b5dbc13a0ab5cf793e3df749f4a29de..fe6e4946672e5ac21aadba499614d14a37e5ebdf 100644 (file)
@@ -90,7 +90,7 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
index 6115464d5f03d3f8a62d1d7593a2c355eecaa516..91bd1e129379db09a7cc0ac60c41d5d94d04fc70 100644 (file)
@@ -77,7 +77,7 @@
 #include <linux/sched/task.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/acpi.h>
 #include <linux/timer.h>
 #include <linux/module.h>
@@ -361,9 +361,9 @@ static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
 
 #define IA64_LOG_ALLOCATE(it, size) \
        {ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \
-               (ia64_err_rec_t *)alloc_bootmem(size); \
+               (ia64_err_rec_t *)memblock_alloc(size, SMP_CACHE_BYTES); \
        ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \
-               (ia64_err_rec_t *)alloc_bootmem(size);}
+               (ia64_err_rec_t *)memblock_alloc(size, SMP_CACHE_BYTES);}
 #define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock)
 #define IA64_LOG_LOCK(it)      spin_lock_irqsave(&ia64_state_log[it].isl_lock, s)
 #define IA64_LOG_UNLOCK(it)    spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s)
@@ -1835,8 +1835,8 @@ format_mca_init_stack(void *mca_data, unsigned long offset,
 /* Caller prevents this from being called after init */
 static void * __ref mca_bootmem(void)
 {
-       return __alloc_bootmem(sizeof(struct ia64_mca_cpu),
-                           KERNEL_STACK_SIZE, 0);
+       return memblock_alloc_from(sizeof(struct ia64_mca_cpu),
+                                  KERNEL_STACK_SIZE, 0);
 }
 
 /* Do per-CPU MCA-related initialization.  */
index dfe40cbdf3b39a70b3812eaa65484618634e7575..45f956ad715a21d109ce2f61c07ae4c80843844e 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kallsyms.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/acpi.h>
 #include <linux/timer.h>
 #include <linux/module.h>
index 0e6c2d9fb49876b6e7147151eec5cbb458c4231b..583a3746d70be85de588b3dc64355cb85b389e61 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/cpu.h>
index 9a960829a01d9d1901b1dfa0c226ec42a87fc532..99099f73b2072e7972c15aa61d57c5186d346141 100644 (file)
@@ -344,10 +344,10 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
                get_signal(&ksig);
 
                /*
-                * get_signal_to_deliver() may have run a debugger (via notify_parent())
+                * get_signal() may have run a debugger (via notify_parent())
                 * and the debugger may have modified the state (e.g., to arrange for an
                 * inferior call), thus it's important to check for restarting _after_
-                * get_signal_to_deliver().
+                * get_signal().
                 */
                if ((long) scr->pt.r10 != -1)
                        /*
index 74fe317477e6273b48d0b97f29d96aeda7ba7872..51ec944b036c438c400a9325f864168e56210915 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/init.h>
index 9b820f7a6a989704e4ffbd25cdfc5a247f85f341..e311ee13e61d01536e79c431b2a830db93230a06 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/node.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/nodemask.h>
 #include <linux/notifier.h>
 #include <linux/export.h>
index e04efa08890293779a4f2806ad5fc1144e40ef64..7601fe0622d25e26ee083b317d159479df16ddf0 100644 (file)
@@ -28,7 +28,7 @@
  *       acquired, then the read-write lock must be acquired first.
  */
 #include <linux/module.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/elf.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
index e2e40bbd391c6a3207dc8d5cd1215abad84371c5..6e447234205c6f94fe5b6d2d276c0eca22c0b9dd 100644 (file)
@@ -14,7 +14,6 @@
  * Routines used by ia64 machines with contiguous (or virtually contiguous)
  * memory.
  */
-#include <linux/bootmem.h>
 #include <linux/efi.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
@@ -85,8 +84,9 @@ skip:
 static inline void
 alloc_per_cpu_data(void)
 {
-       cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * num_possible_cpus(),
-                                  PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+       cpu_data = memblock_alloc_from(PERCPU_PAGE_SIZE * num_possible_cpus(),
+                                      PERCPU_PAGE_SIZE,
+                                      __pa(MAX_DMA_ADDRESS));
 }
 
 /**
index 1928d5719e417d5b5899a7c2b48c73a3da3294bd..8a965784340c5c3616742fd01c30e3a0457b0092 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <linux/nmi.h>
 #include <linux/swap.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/acpi.h>
 #include <linux/efi.h>
@@ -451,8 +450,10 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
        if (bestnode == -1)
                bestnode = anynode;
 
-       ptr = __alloc_bootmem_node(pgdat_list[bestnode], pernodesize,
-               PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+       ptr = memblock_alloc_try_nid(pernodesize, PERCPU_PAGE_SIZE,
+                                    __pa(MAX_DMA_ADDRESS),
+                                    MEMBLOCK_ALLOC_ACCESSIBLE,
+                                    bestnode);
 
        return ptr;
 }
index 3b85c3ecac38d2ae0860bc0d5aedd79f1cc96a39..d5e12ff1d73cf69f1350577d61f311b5081e8075 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#include <linux/bootmem.h>
 #include <linux/efi.h>
 #include <linux/elf.h>
 #include <linux/memblock.h>
@@ -447,19 +446,19 @@ int __init create_mem_map_page_table(u64 start, u64 end, void *arg)
        for (address = start_page; address < end_page; address += PAGE_SIZE) {
                pgd = pgd_offset_k(address);
                if (pgd_none(*pgd))
-                       pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
+                       pgd_populate(&init_mm, pgd, memblock_alloc_node(PAGE_SIZE, PAGE_SIZE, node));
                pud = pud_offset(pgd, address);
 
                if (pud_none(*pud))
-                       pud_populate(&init_mm, pud, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
+                       pud_populate(&init_mm, pud, memblock_alloc_node(PAGE_SIZE, PAGE_SIZE, node));
                pmd = pmd_offset(pud, address);
 
                if (pmd_none(*pmd))
-                       pmd_populate_kernel(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
+                       pmd_populate_kernel(&init_mm, pmd, memblock_alloc_node(PAGE_SIZE, PAGE_SIZE, node));
                pte = pte_offset_kernel(pmd, address);
 
                if (pte_none(*pte))
-                       set_pte(pte, pfn_pte(__pa(alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)) >> PAGE_SHIFT,
+                       set_pte(pte, pfn_pte(__pa(memblock_alloc_node(PAGE_SIZE, PAGE_SIZE, node)) >> PAGE_SHIFT,
                                             PAGE_KERNEL));
        }
        return 0;
@@ -627,7 +626,7 @@ mem_init (void)
 
        set_max_mapnr(max_low_pfn);
        high_memory = __va(max_low_pfn * PAGE_SIZE);
-       free_all_bootmem();
+       memblock_free_all();
        mem_init_print_info(NULL);
 
        /*
index aa19b7ac8222a2fb604b90fc9edd3d3b86ef483c..3861d6e32d5ff910615305ef691b4a30fd1028f2 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/mm.h>
 #include <linux/node.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/module.h>
 #include <asm/mmzone.h>
 #include <asm/numa.h>
index acf10eb9da15c13252411746fe603785a61bffd7..9340bcb4f29c4ee0f0fa9868ae0571efff635d4a 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/slab.h>
 
 #include <asm/delay.h>
@@ -59,8 +59,10 @@ struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
 void __init
 mmu_context_init (void)
 {
-       ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
-       ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
+       ia64_ctx.bitmap = memblock_alloc((ia64_ctx.max_ctx + 1) >> 3,
+                                        SMP_CACHE_BYTES);
+       ia64_ctx.flushmap = memblock_alloc((ia64_ctx.max_ctx + 1) >> 3,
+                                          SMP_CACHE_BYTES);
 }
 
 /*
index 5d71800df4313a13970aa30d311740a118fe466b..196a0dd7ff97b0370cffc7dcecf101a18a0b7242 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 
 #include <asm/machvec.h>
index 9146192b86f5532e44b681a807fe77fa84d55223..9900e6d4add60d6e3731401ec087da87b1f4be1a 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/nodedata.h>
 #include <asm/delay.h>
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
index 102aabad6d20afdb9bfff0804311d4fd683a138c..8df13d0d96fa30f25ec94040715c3e93978e1d00 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <asm/sn/types.h>
@@ -385,16 +385,15 @@ void __init hubdev_init_node(nodepda_t * npda, cnodeid_t node)
 {
        struct hubdev_info *hubdev_info;
        int size;
-       pg_data_t *pg;
 
        size = sizeof(struct hubdev_info);
 
        if (node >= num_online_nodes()) /* Headless/memless IO nodes */
-               pg = NODE_DATA(0);
-       else
-               pg = NODE_DATA(node);
+               node = 0;
 
-       hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size);
+       hubdev_info = (struct hubdev_info *)memblock_alloc_node(size,
+                                                               SMP_CACHE_BYTES,
+                                                               node);
 
        npda->pdinfo = (void *)hubdev_info;
 }
index 5f6b6b48c1d58567b21ba3680969fb53f52195fa..a6d40a2c5bffcc5b19a66311a832a5522af278de 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/mm.h>
 #include <linux/serial.h>
 #include <linux/irq.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mmzone.h>
 #include <linux/interrupt.h>
 #include <linux/acpi.h>
@@ -511,7 +511,8 @@ static void __init sn_init_pdas(char **cmdline_p)
         */
        for_each_online_node(cnode) {
                nodepdaindr[cnode] =
-                   alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
+                   memblock_alloc_node(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);
@@ -522,7 +523,7 @@ static void __init sn_init_pdas(char **cmdline_p)
         */
        for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++)
                nodepdaindr[cnode] =
-                   alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t));
+                   memblock_alloc_node(sizeof(nodepda_t), SMP_CACHE_BYTES, 0);
 
        /*
         * Now copy the array of nodepda pointers to each nodepda.
index c7b2a8d60a41e00711a9ab9589a6af1d7afeb2a1..1bc9f1ba759a7bb3ab66c1f53ef531642048070b 100644 (file)
@@ -27,9 +27,7 @@ config M68K
        select OLD_SIGSUSPEND3
        select OLD_SIGACTION
        select DMA_DIRECT_OPS if HAS_DMA
-       select HAVE_MEMBLOCK
        select ARCH_DISCARD_MEMBLOCK
-       select NO_BOOTMEM
 
 config CPU_BIG_ENDIAN
        def_bool y
index c83d66442612e0747f58ebe8d12e5b07065b7e20..6ffc204eb07dec522ac8e6eae286c86948590ed1 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mount.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
@@ -95,7 +95,8 @@ void __init atari_stram_reserve_pages(void *start_mem)
 {
        if (kernel_in_stram) {
                pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n");
-               stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size);
+               stram_pool.start = (resource_size_t)memblock_alloc_low(pool_size,
+                                                                      PAGE_SIZE);
                stram_pool.end = stram_pool.start + pool_size - 1;
                request_resource(&iomem_resource, &stram_pool);
                stram_virt_offset = 0;
index adad03ca6e11956e606aa15c219fb4971ba73f52..360c723c0ae66a4784476138edfd7be21947f4ff 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/clk.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/pgalloc.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
index e45ce4243aaa3bdb7f4f22a0ecafd9de57b60261..a4ebd2445edaed9c3faa28e0a0268589ac650ad3 100644 (file)
@@ -47,10 +47,6 @@ static const char version[] =
 MODULE_AUTHOR("Milan Jurik");
 MODULE_DESCRIPTION("Atari NFeth driver");
 MODULE_LICENSE("GPL");
-/*
-MODULE_PARM(nfeth_debug, "i");
-MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
-*/
 
 
 static long nfEtherID;
index 464e9f5f50ee4236f255ae013bcad86837d69a53..3750819ac5a13bde46a73d0b9ae6af21dd5aa42f 100644 (file)
@@ -8,12 +8,6 @@
 #ifndef __ASM_M68K_PROCESSOR_H
 #define __ASM_M68K_PROCESSOR_H
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
 #include <linux/thread_info.h>
 #include <asm/segment.h>
 #include <asm/fpu.h>
index 5d3596c180f9f75efab10fa416199e554fba3794..a1a3eaeaf58c960df8e406dca1fcdf0e434470a2 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
index cfd5475bfc3152aa0c47246db970d8468e4fa944..3c5def10d486e0a563d9034fefc93785c037c203 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/console.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
index faf18f4fab1fdd9b7c2555faaa284e68a9ce5d9a..d19a94754d563369c60dc4bb5153f56cc4813eec 100644 (file)
@@ -88,9 +88,3 @@ kpt:
         .long 0
 availmem:
         .long 0
-| todo: remove next two. --m
-is_medusa:
-        .long 0
-m68k_pgtable_cachemode:
-        .long 0
-
index b29c3b241e1bb590eba500918e39e4ce9bc59796..1b4c562753da898fd62972b02b785dafc38528a6 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/console.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/initrd.h>
@@ -102,5 +102,5 @@ __init void process_uboot_commandline(char *commandp, int size)
        }
 
        parse_uboot_commandline(commandp, len);
-       commandp[size - 1] = 0;
+       commandp[len - 1] = 0;
 }
index 38e2b272c220cbfaee5fdd4032c4461ab45c5e2e..933c33e76a4831a2148115025009e2ed57d34341 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/gfp.h>
 
 #include <asm/setup.h>
@@ -93,7 +93,7 @@ void __init paging_init(void)
 
        high_memory = (void *) end_mem;
 
-       empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
+       empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 
        /*
         * Set up SFC/DFC registers (user data space).
@@ -140,7 +140,7 @@ static inline void init_pointer_tables(void)
 void __init mem_init(void)
 {
        /* this will put all memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
        init_pointer_tables();
        mem_init_print_info(NULL);
 }
index f5453d944ff5e19d341925590cca753ffb4fcd7e..0de4999a3810db9441b44251da67d537af90f682 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 
 #include <asm/setup.h>
@@ -44,7 +43,7 @@ void __init paging_init(void)
        enum zone_type zone;
        int i;
 
-       empty_zero_page = (void *) alloc_bootmem_pages(PAGE_SIZE);
+       empty_zero_page = (void *) memblock_alloc(PAGE_SIZE, PAGE_SIZE);
        memset((void *) empty_zero_page, 0, PAGE_SIZE);
 
        pg_dir = swapper_pg_dir;
@@ -52,7 +51,7 @@ void __init paging_init(void)
 
        size = num_pages * sizeof(pte_t);
        size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
-       next_pgtable = (unsigned long) alloc_bootmem_pages(size);
+       next_pgtable = (unsigned long) memblock_alloc(size, PAGE_SIZE);
 
        bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK;
        pg_dir += PAGE_OFFSET >> PGDIR_SHIFT;
index 4e17ecb5928aae85155c9f6a5b0b0704a24b1100..7497cf30bf1cd41b51afd915a45b5b80fd9dd939 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/gfp.h>
 
@@ -55,7 +54,7 @@ static pte_t * __init kernel_page_table(void)
 {
        pte_t *ptablep;
 
-       ptablep = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+       ptablep = (pte_t *)memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
 
        clear_page(ptablep);
        __flush_page_to_ram(ptablep);
@@ -95,7 +94,8 @@ static pmd_t * __init kernel_ptr_table(void)
 
        last_pgtable += PTRS_PER_PMD;
        if (((unsigned long)last_pgtable & ~PAGE_MASK) == 0) {
-               last_pgtable = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+               last_pgtable = (pmd_t *)memblock_alloc_low(PAGE_SIZE,
+                                                          PAGE_SIZE);
 
                clear_page(last_pgtable);
                __flush_page_to_ram(last_pgtable);
@@ -275,7 +275,7 @@ void __init paging_init(void)
         * initialize the bad page table and bad page to point
         * to a couple of allocated pages
         */
-       empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
+       empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 
        /*
         * Set up SFC/DFC registers
index 4a99799083576ff32beac547f7ef2972a4fe4850..f736db48a2e1bad63ae15d0a1b30b86542b47d59 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/setup.h>
 #include <linux/uaccess.h>
@@ -45,7 +45,7 @@ void __init paging_init(void)
        unsigned long zones_size[MAX_NR_ZONES] = { 0, };
        unsigned long size;
 
-       empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
+       empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 
        address = PAGE_OFFSET;
        pg_dir = swapper_pg_dir;
@@ -55,7 +55,7 @@ void __init paging_init(void)
        size = num_pages * sizeof(pte_t);
        size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
 
-       next_pgtable = (unsigned long)alloc_bootmem_pages(size);
+       next_pgtable = (unsigned long)memblock_alloc(size, PAGE_SIZE);
        bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK;
 
        /* Map whole memory from PAGE_OFFSET (0x0E000000) */
index 79a2bb85790615c308ecea9b2c3fdf9807054cbb..542c4404861c3827fc76821bfa25fbc7bb063528 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/platform_device.h>
 
 #include <asm/oplib.h>
index 5f92c72b05c31739b10116ca90b495da600415ac..a2c1c930489577ffdc7937715f07c2edd5fbd597 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/list.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
index d30da12a1702b5ef8779ebff8b295388aad4117b..582a1284059a90f92f192003f0ea6bd4a3a46d3e 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/sched/mm.h>
index 8546922adb47384943b937ce14aa268efd26a1fc..4d64711d3d47410cead0940360885ccf22617cae 100644 (file)
@@ -7,7 +7,7 @@
  * Contains common routines for sun3/sun3x DVMA management.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -267,7 +267,8 @@ void __init dvma_init(void)
 
        list_add(&(hole->list), &hole_list);
 
-       iommu_use = alloc_bootmem(IOMMU_TOTAL_ENTRIES * sizeof(unsigned long));
+       iommu_use = memblock_alloc(IOMMU_TOTAL_ENTRIES * sizeof(unsigned long),
+                                  SMP_CACHE_BYTES);
 
        dvma_unmap_iommu(DVMA_START, DVMA_SIZE);
 
index b2acbc862f60eb772bd43739804a10bcfc8bff42..89e630e6655579b61bcadeba1ae1c4a1f403de0c 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/vmalloc.h>
 
 #include <asm/sun3x.h>
index 164a4857737a0cf38fa0ba9e406517021ee3bdb8..effed2efd306c33804a769738e01f3614f0564b7 100644 (file)
@@ -28,8 +28,6 @@ config MICROBLAZE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACER
-       select NO_BOOTMEM
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_OPROFILE
        select IRQ_DOMAIN
index 330d556860ba7a8211b767cd4ac03275adcab9f0..66b537b8d138e510d1799a8898d0f3e9ddbdf652 100644 (file)
@@ -45,12 +45,6 @@ extern void ret_from_kernel_thread(void);
  */
 # define TASK_SIZE     (0x81000000 - 0x80000000)
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-# define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 /*
  * This decides where the kernel will search for a free chunk of vm
  * space during mmap's. We won't be using it
@@ -92,12 +86,6 @@ extern unsigned long get_wchan(struct task_struct *p);
 
 #  ifndef __ASSEMBLY__
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#  define current_text_addr()  ({ __label__ _l; _l: &&_l; })
-
 /* If you change this, you must change the associated assembly-languages
  * constants defined below, THREAD_*.
  */
index d801cc5f5b95571a7f96a9f5303a8d8ecf0c84f2..45e0a1aa935739cfac59134560605531490cf561 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
index df6de7ccdc2eb6fad45f93fcb1dbd74c0fff01e8..b17fd8aafd64aabd3c667c81394a81ab6f3b8583 100644 (file)
@@ -7,10 +7,9 @@
  * for more details.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/memblock.h>
 #include <linux/mm.h> /* mem_init */
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
@@ -204,7 +203,7 @@ void __init mem_init(void)
        high_memory = (void *)__va(memory_start + lowmem_size - 1);
 
        /* this will put all memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 #ifdef CONFIG_HIGHMEM
        highmem_setup();
 #endif
@@ -377,7 +376,7 @@ void * __ref zalloc_maybe_bootmem(size_t size, gfp_t mask)
        if (mem_init_done)
                p = kzalloc(size, mask);
        else {
-               p = alloc_bootmem(size);
+               p = memblock_alloc(size, SMP_CACHE_BYTES);
                if (p)
                        memset(p, 0, size);
        }
index 2ffd171af8b60b463e408efc2ac69fb89e61a20c..6b89a66ec1a5fc99ea3cac05c79a19a3d1c6ab5b 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/shmem_fs.h>
 #include <linux/list.h>
index 80778b40f8faedf1daf4bd674f63e5da64212691..8272ea4c72645777b0174907f621d57040857599 100644 (file)
@@ -60,7 +60,6 @@ config MIPS
        select HAVE_IRQ_TIME_ACCOUNTING
        select HAVE_KPROBES
        select HAVE_KRETPROBES
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NMI
@@ -78,7 +77,6 @@ config MIPS
        select RTC_LIB
        select SYSCTL_EXCEPTION_TRACE
        select VIRT_TO_BUS
-       select NO_BOOTMEM
 
 menu "Machine selection"
 
index 0332f0514d0508913048522c76328ae6de7e0127..80390a9ec2643b73977b02e112c8dab0d7984ff0 100644 (file)
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/pfn.h>
index 4c7a93f4039a0cba2a18504525ed9cd2e0c02389..9728abcb18face9269b806566058b3edb0c1cf49 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
index 7019e2967009e98e6f6191c1e86969d4663a957f..77a836e661c9eea91bc7582dd6ed435f5aba8f90 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/smp.h>
 #include <asm/bootinfo.h>
 #include <asm/bmips.h>
index 2be9caaa208530757af7ab41eaa6104c9a0616da..e28ee9a7cc7e2cfeb18211f1d3650464ba7d42a8 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ioport.h>
 #include <linux/pm.h>
 #include <asm/bootinfo.h>
index 6329c5f780d6cffd01bf90124e75339336386b21..1738a06396f9f693be2cecdc00d3b90c2a5aa4e3 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/bitops.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/clk-provider.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
index 236833be6fbe6d2a64c2e2a6386385c81db05bd3..e8eb60ed99f2a8f877b0cdf2bc673e1ee643f40b 100644 (file)
@@ -11,7 +11,7 @@
  * Copyright (C) 2010 Cavium Networks, Inc.
  */
 #include <linux/dma-direct.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/swiotlb.h>
 #include <linux/types.h>
 #include <linux/init.h>
@@ -244,7 +244,7 @@ void __init plat_swiotlb_setup(void)
        swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
        swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
 
-       octeon_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
+       octeon_swiotlb = memblock_alloc_low(swiotlbsize, PAGE_SIZE);
 
        if (swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1) == -ENOMEM)
                panic("Cannot allocate SWIOTLB buffer");
index a2acc6454cf3df44415e1d5b1394af3b6d8c47b5..5073d2ed78bbb6e7ec790e1ad758957e8cea2561 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
index cae42259d6da9cc49efd4ceb8bccdbad941fe3d0..675337b8a4a09c1481fc3dba607e7b65139cfcbc 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
index dd9496f26e6a930ec748937466bb0a153cc2a399..429b7f8d2aeb4389eacb9d023e7d9a2bd38bcec2 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/swap.h>
 
 #include <asm/sgialib.h>
index c373eb605040246ad67e332f72bc6de8aee0dfa8..ce3ed4d17813e2502d69e4f0cd7fd7eafe7fdc14 100644 (file)
 #include <asm/mipsregs.h>
 #include <asm/prefetch.h>
 
-/*
- * Return current * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
 /*
  * System setup and hardware flags..
  */
index 890245a9f0c4d4064588596ea86c76219f5d2e1b..16aa8a766aec229839602893e245ee020b3c19c2 100644 (file)
@@ -93,6 +93,8 @@
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY      0x5480          /* become controlling tty */
index 0a0aaf39fd162e83d618f24361c7473fd2ac353c..4c41ed0a637e554dc81f97bfcc01482a9353dca6 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/spinlock.h>
 #include <linux/gfp.h>
 #include <linux/dma-direct.h>
index 2c7288041a992f670fd4912be22d2ba6c359fbc2..81845ba04835bfe88353bed5437e71439dbb0b8b 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/smp.h>
 #include <linux/reboot.h>
 #include <linux/kexec.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/crash_dump.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
index a8657d29c62e0e3f4f84853907544c61c5b38d4d..01b2bd95ba1f7cad0137f787cd29b977f85bcdf4 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/highmem.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/crash_dump.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
index 89950b7bf536b7fe30e04fc531677c6b3b8666ea..93b8e0b4332f7d50e6882a7b1adbf77f917b7999 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/types.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/debugfs.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
index 01a5ff4c41ff5edb074c921e0b182a425c1c77e2..ea09ed6a80a9f2dc0aa625e2fcec0b34e2c6acea 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/export.h>
 #include <linux/screen_info.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/initrd.h>
 #include <linux/root_dev.h>
 #include <linux/highmem.h>
@@ -561,7 +560,7 @@ static void __init bootmem_init(void)
                extern void show_kernel_relocation(const char *level);
 
                offset = __pa_symbol(_text) - __pa_symbol(VMLINUX_LOAD_ADDRESS);
-               free_bootmem(__pa_symbol(VMLINUX_LOAD_ADDRESS), offset);
+               memblock_free(__pa_symbol(VMLINUX_LOAD_ADDRESS), offset);
 
 #if defined(CONFIG_DEBUG_KERNEL) && defined(CONFIG_DEBUG_INFO)
                /*
@@ -859,7 +858,7 @@ static void __init arch_mem_init(char **cmdline_p)
         * Prevent memblock from allocating high memory.
         * This cannot be done before max_low_pfn is detected, so up
         * to this point is possible to only reserve physical memory
-        * with memblock_reserve; memblock_virt_alloc* can be used
+        * with memblock_reserve; memblock_alloc* can be used
         * only after this point
         */
        memblock_set_current_limit(PFN_PHYS(max_low_pfn));
@@ -917,7 +916,7 @@ static void __init resource_init(void)
                if (end >= HIGHMEM_START)
                        end = HIGHMEM_START - 1;
 
-               res = alloc_bootmem(sizeof(struct resource));
+               res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
 
                res->start = start;
                res->end = end;
index 5feef28deac8fa87940f3cc54e6040aa70e4417f..0f852e1b589193d43f9125cfbfa303d6b47c6fed 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/smp.h>
 #include <linux/spinlock.h>
 #include <linux/kallsyms.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
@@ -2263,7 +2262,7 @@ void __init trap_init(void)
 
                memblock_set_bottom_up(true);
                ebase = (unsigned long)
-                       __alloc_bootmem(size, 1 << fls(size), 0);
+                       memblock_alloc_from(size, 1 << fls(size), 0);
                memblock_set_bottom_up(false);
 
                /*
index 0bef238d2c0c6fda901e5f20682a26cb33e217eb..6176b9acba950e7189c48752498a9bb79f3648ad 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/moduleloader.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/cacheflush.h>
index f43629979a0e59959db7f1732233ad2db538ca5d..5812e6145801f2ba88b1a17b0c4a56ced7596dbb 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
index f8e772564d74290d2c2043c36e2263db98c018ea..d77b61b3d6ee7e294e927ed588ef499003f5b438 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/cacheflush.h>
 
 #include "commpage.h"
index 4144bfaef137728f9143e4ec3d2ab0c5b0606a73..ec9ed23bca7fdeea33f0e66dc0dd1a86c655f64e 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kvm_host.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/random.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
index aa0a1a00faf650c5804eb3e9ff5445929d3d5582..7257e8b6f5a92c1ff9ba7449dccdb081cd762995 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 
index f7ea8e21656b168fbd16a57a46851c0ab78b0129..1fcc4d149054f16a74c59288459cf112f0c4c18a 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/vmalloc.h>
 #include <linux/sched/signal.h>
 #include <linux/fs.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/fpu.h>
 #include <asm/page.h>
index d984bd5c2ec5fa24c4e966311a2504962ffd4963..14d4c5e2b42fa5a2509528c0e4d738165df19ec6 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <linux/export.h>
 #include <linux/clk.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/of_fdt.h>
 
 #include <asm/bootinfo.h>
index 37b8fc5b9ac9e82da57918d6eff5e0872d276e72..5ce1407de2d592861fb95d172aef46ef3017a77e 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/ctype.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ioport.h>
 #include <asm/bootinfo.h>
 #include <asm/lasat/lasat.h>
index 6ef17120722f55166cd97035b1e96956971ad5dc..c073fbcb9805b3e01853c888901bbd012e6aa6a7 100644 (file)
@@ -8,7 +8,7 @@
  * option) any later version.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/bootinfo.h>
 #include <asm/traps.h>
 #include <asm/smp-ops.h>
index c1e6ec52c614eb0265fcb6189ad09caaa4185f2f..622761878cd11bd54e53affa43e5504c0aadc9c0 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/nodemask.h>
 #include <linux/swap.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/pfn.h>
 #include <linux/highmem.h>
 #include <asm/page.h>
@@ -272,7 +271,7 @@ void __init paging_init(void)
 void __init mem_init(void)
 {
        high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
-       free_all_bootmem();
+       memblock_free_all();
        setup_zero_pages();     /* This comes from node 0 */
        mem_init_print_info(NULL);
 }
index 15cae0f118808fbacf6a53bc90dd1f50754bfda2..b521d8e2d3592e7eec7610c495ab5738544ef9a3 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/proc_fs.h>
@@ -243,7 +243,8 @@ void __init fixrange_init(unsigned long start, unsigned long end,
                        pmd = (pmd_t *)pud;
                        for (; (k < PTRS_PER_PMD) && (vaddr < end); pmd++, k++) {
                                if (pmd_none(*pmd)) {
-                                       pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+                                       pte = (pte_t *) memblock_alloc_low(PAGE_SIZE,
+                                                                          PAGE_SIZE);
                                        set_pmd(pmd, __pmd((unsigned long)pte));
                                        BUG_ON(pte != pte_offset_kernel(pmd, 0));
                                }
@@ -462,7 +463,7 @@ void __init mem_init(void)
        high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
        maar_init();
-       free_all_bootmem();
+       memblock_free_all();
        setup_zero_pages();     /* Setup zeroed pages.  */
        mem_init_free_highmem();
        mem_init_print_info(NULL);
index b19a3c506b1e9d203cbacb0da71513d8f21868b1..e2a33adc0f29d0ba786af3c4fa142be2ef1df28c 100644 (file)
@@ -7,7 +7,7 @@
  */
 #include <linux/init.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <asm/fixmap.h>
 #include <asm/pgtable.h>
index a47556723b8543f82558524cc9165513f65c6fde..868921adef1d76819452f1ee06d5c317212971e4 100644 (file)
@@ -12,7 +12,7 @@
  *          Steven J. Hill <sjhill@mips.com>
  */
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
index b5ba83f4c646b3b48598e5cce482b8c1a49f7d9a..c856f2a3ea4244616e2a2b0fbb853defdd1801e6 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
index 3c3b1e6abb53562fd0508d7ac25ddb0b09891525..687513880fbf965c690a5044146947b9b20e83c5 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/bug.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/types.h>
index c2e94cf5ecdab7c7f3263bd65e76c30cf8eb32fc..e68b44b27c0dfc8d3ee22b0b5a3388f7de426279 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/bug.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/types.h>
index 1ada8492733b6018766d8a5c1e68cc633133b818..d544e7b07f7ad454b72f2ab667c04995e0f4bacd 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/sizes.h>
 #include <linux/of_fdt.h>
 #include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 
index 6484e4a4597bdf3ac570b475ef3bb8e5b8d57ecc..361a690facbf6cf87fde1ac897bb79d91ee7d2bc 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/export.h>
 #include <linux/string.h>
 #include <linux/console.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
 
index 6f7bef052b7f44b44219df28b030a448e9bedffb..d8b8444d679527e3843ea1de091be70926355f34 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/export.h>
 #include <linux/nodemask.h>
 #include <linux/swap.h>
-#include <linux/bootmem.h>
 #include <linux/pfn.h>
 #include <linux/highmem.h>
 #include <asm/page.h>
@@ -475,7 +474,7 @@ void __init paging_init(void)
 void __init mem_init(void)
 {
        high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
-       free_all_bootmem();
+       memblock_free_all();
        setup_zero_pages();     /* This comes from node 0 */
        mem_init_print_info(NULL);
 }
index 092fb2a6ec4a04415bb6ed72db53552ede93da35..12a780f251e16c2afd2da9aad6aa80a067a4b538 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/linkage.h>
 #include <linux/mm.h>
 #include <linux/blkdev.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pm.h>
 #include <linux/smp.h>
 
index 152ca71cc2d7b97a6c17a4f4aa7cb3fdd7dd7ad8..3b034b7178d6f106ef116d8ad704a59e50209b0e 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index bcb469247e8c4ffa024a616ab9f5154e9ef616a1..2b36a2ee744c1417b52db135a246e62bc85e1537 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/bootinfo.h>
 #include <asm/txx9/generic.h>
 #include <asm/txx9/rbtx4938.h>
index 56992330026a6b078bf4286d4d45921bf2b275f8..7a04adacb2f0bd3a46e1bb7745f5b700b27a496e 100644 (file)
@@ -29,14 +29,12 @@ config NDS32
        select HANDLE_DOMAIN_IRQ
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DEBUG_KMEMLEAK
-       select HAVE_MEMBLOCK
        select HAVE_REGS_AND_STACK_ACCESS_API
        select IRQ_DOMAIN
        select LOCKDEP_SUPPORT
        select MODULES_USE_ELF_RELA
        select OF
        select OF_EARLY_FLATTREE
-       select NO_BOOTMEM
        select NO_IOPORT_MAP
        select RTC_LIB
        select THREAD_INFO_IN_TASK
index 9c83caf4269f52314c3d35550628d91f29053c70..c2660f566baca99a7f88e401015e6b0816a5c52b 100644 (file)
@@ -4,12 +4,6 @@
 #ifndef __ASM_NDS32_PROCESSOR_H
 #define __ASM_NDS32_PROCESSOR_H
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
 #ifdef __KERNEL__
 
 #include <asm/ptrace.h>
index 63a1a5ef5219f47bcd9797e543298056294da22f..eacc79024879bad1d6948b4b872de78f6316befe 100644 (file)
@@ -2,9 +2,8 @@
 // Copyright (C) 2005-2017 Andes Technology Corporation
 
 #include <linux/cpu.h>
-#include <linux/bootmem.h>
-#include <linux/seq_file.h>
 #include <linux/memblock.h>
+#include <linux/seq_file.h>
 #include <linux/console.h>
 #include <linux/screen_info.h>
 #include <linux/delay.h>
index e17cb8a69315a05df7bd54435b9d71ba468bb72b..022779af6148ca671f32f8d080c57540ed0d4ee0 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 
index c713d2ad55dc9a430777b41a3485380a98896f1a..131104bd2538e5a919aa15b25f5bef8a7a2d671e 100644 (file)
@@ -7,12 +7,11 @@
 #include <linux/errno.h>
 #include <linux/swap.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
 #include <linux/highmem.h>
-#include <linux/memblock.h>
 
 #include <asm/sections.h>
 #include <asm/setup.h>
@@ -81,7 +80,7 @@ static void __init map_ram(void)
                }
 
                /* Alloc one page for holding PTE's... */
-               pte = (pte_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+               pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
                memset(pte, 0, PAGE_SIZE);
                set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
 
@@ -114,7 +113,7 @@ static void __init fixedrange_init(void)
        pgd = swapper_pg_dir + pgd_index(vaddr);
        pud = pud_offset(pgd, vaddr);
        pmd = pmd_offset(pud, vaddr);
-       fixmap_pmd_p = (pmd_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+       fixmap_pmd_p = (pmd_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
        memset(fixmap_pmd_p, 0, PAGE_SIZE);
        set_pmd(pmd, __pmd(__pa(fixmap_pmd_p) + _PAGE_KERNEL_TABLE));
 
@@ -127,7 +126,7 @@ static void __init fixedrange_init(void)
        pgd = swapper_pg_dir + pgd_index(vaddr);
        pud = pud_offset(pgd, vaddr);
        pmd = pmd_offset(pud, vaddr);
-       pte = (pte_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+       pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
        memset(pte, 0, PAGE_SIZE);
        set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
        pkmap_page_table = pte;
@@ -153,7 +152,7 @@ void __init paging_init(void)
        fixedrange_init();
 
        /* allocate space for empty_zero_page */
-       zero_page = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+       zero_page = __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
        memset(zero_page, 0, PAGE_SIZE);
        zone_sizes_init();
 
@@ -192,7 +191,7 @@ void __init mem_init(void)
        free_highmem();
 
        /* this will put all low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
        mem_init_print_info(NULL);
 
        pr_info("virtual kernel memory layout:\n"
index 2df0c57f28334a7aec2678c4d9ffc3dd75b39b12..7e95506e957aae25123ca9349eb35ad8e8dac791 100644 (file)
@@ -23,9 +23,7 @@ config NIOS2
        select SPARSE_IRQ
        select USB_ARCH_HAS_HCD if USB_SUPPORT
        select CPU_NO_EFFICIENT_FFS
-       select HAVE_MEMBLOCK
        select ARCH_DISCARD_MEMBLOCK
-       select NO_BOOTMEM
 
 config GENERIC_CSUM
        def_bool y
index 4944e2e1d8b0677d48c30ebba98629d43db90933..94bcb86f679f5e7ee542eb10d841fddf9ffeada0 100644 (file)
 #define KUSER_SIZE             (PAGE_SIZE)
 #ifndef __ASSEMBLY__
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 # define TASK_SIZE             0x7FFF0000UL
 # define TASK_UNMAPPED_BASE    (PAGE_ALIGN(TASK_SIZE / 3))
 
index a6d4f7530247b34897f54d4f7b882153619e4fdb..232a36b511aa9949810344c7ead8d4da1a14ccbb 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/io.h>
index 2d0011ddd4d589392a525330de7c9cf01e494a44..6bbd4ae2beb01eab6386dc14f4c38f890558e056 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/sched.h>
 #include <linux/sched/task.h>
 #include <linux/console.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/initrd.h>
 #include <linux/of_fdt.h>
index c92fe4234009ba59ab366b8ab9ca6b848b0c2797..16cea5776b87c6aa51101ea690f8a6401df191bb 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/binfmts.h>
 
@@ -73,7 +73,7 @@ void __init mem_init(void)
        high_memory = __va(end_mem);
 
        /* this will put all memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
        mem_init_print_info(NULL);
 }
 
index a655ae280637be50b0484ed362b70d91779bad59..285f7d05c8ed2d9a1a6b230b7d14009274dbb1ae 100644 (file)
@@ -12,7 +12,6 @@ config OPENRISC
        select OF_EARLY_FLATTREE
        select IRQ_DOMAIN
        select HANDLE_DOMAIN_IRQ
-       select HAVE_MEMBLOCK
        select GPIOLIB
         select HAVE_ARCH_TRACEHOOK
        select SPARSE_IRQ
@@ -32,7 +31,6 @@ config OPENRISC
        select HAVE_DEBUG_STACKOVERFLOW
        select OR1K_PIC
        select CPU_NO_EFFICIENT_FFS if !OPENRISC_HAVE_INST_FF1
-       select NO_BOOTMEM
        select ARCH_USE_QUEUED_SPINLOCKS
        select ARCH_USE_QUEUED_RWLOCKS
        select OMPIC if SMP
index af31a9fe736a85dbadafad8712ca9c1f212b94b5..351d3aed7a065b46280b6be224dc6d11fe7ffaa9 100644 (file)
                   | SPR_SR_DCE | SPR_SR_SM)
 #define USER_SR   (SPR_SR_DME | SPR_SR_IME | SPR_SR_ICE \
                   | SPR_SR_DCE | SPR_SR_IEE | SPR_SR_TEE)
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
 
 /*
  * User space process size. This is hardcoded into a few places,
index e17fcd83120f6fadc97a149136f4a22b4d02113f..c605bdad1746ad25288b6b2e06de9641704e1f3f 100644 (file)
 #include <linux/delay.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/seq_file.h>
 #include <linux/serial.h>
 #include <linux/initrd.h>
 #include <linux/of_fdt.h>
 #include <linux/of.h>
-#include <linux/memblock.h>
 #include <linux/device.h>
 
 #include <asm/sections.h>
index 6972d5d6f23f7343306c750945a22862e1f9e46e..d157310eb377a7d574a03a386641b2fae46027cb 100644 (file)
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>      /* for initrd_* */
 #include <linux/pagemap.h>
-#include <linux/memblock.h>
 
 #include <asm/segment.h>
 #include <asm/pgalloc.h>
@@ -106,7 +105,7 @@ static void __init map_ram(void)
                        }
 
                        /* Alloc one page for holding PTE's... */
-                       pte = (pte_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+                       pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
                        set_pmd(pme, __pmd(_KERNPG_TABLE + __pa(pte)));
 
                        /* Fill the newly allocated page with PTE'S */
@@ -213,7 +212,7 @@ void __init mem_init(void)
        memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
        /* this will put all low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 
        mem_init_print_info(NULL);
 
index 2175e4bfd9fc0a28e80df5dca135493ec3728720..c9697529b3f079c6ff4c5c84299f1f975d0b3d6d 100644 (file)
@@ -126,7 +126,7 @@ pte_t __ref *pte_alloc_one_kernel(struct mm_struct *mm,
        if (likely(mem_init_done)) {
                pte = (pte_t *) __get_free_page(GFP_KERNEL);
        } else {
-               pte = (pte_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+               pte = (pte_t *) __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
        }
 
        if (pte)
index f1cd12afd943c888f4a1a89a4fa10c598e6e0a77..92a339ee28b385e918613a794aa21566d6dabe90 100644 (file)
@@ -15,8 +15,6 @@ config PARISC
        select RTC_CLASS
        select RTC_DRV_GENERIC
        select INIT_ALL_POSSIBLE
-       select HAVE_MEMBLOCK
-       select NO_BOOTMEM
        select BUG
        select BUILDTIME_EXTABLE_SORT
        select HAVE_PERF_EVENTS
index 2bd5e695bdadd9d12ebf903a18ed56637e58ecb6..6e2a8176b0dd087234013231fbb866ce4a163556 100644 (file)
 #include <asm/percpu.h>
 #endif /* __ASSEMBLY__ */
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#ifdef CONFIG_PA20
-#define current_ia(x)  __asm__("mfia %0" : "=r"(x))
-#else /* mfia added in pa2.0 */
-#define current_ia(x)  __asm__("blr 0,%0\n\tnop" : "=r"(x))
-#endif
-#define current_text_addr() ({ void *pc; current_ia(pc); pc; })
-
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
 #define TASK_SIZE_OF(tsk)       ((tsk)->thread.task_size)
index aafb1c0ca0af63e4aefcc35687a9dfff78370b1e..82d1148c6379a50f0eae5622d7ab8fd71ffb80c1 100644 (file)
@@ -62,6 +62,8 @@
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX                0x5451
index 2785632c85e78988404a40e09cb595ef625c8d80..8dce56f5dcee6a3fc71095d815cb58c05d19e453 100644 (file)
@@ -16,9 +16,6 @@ typedef unsigned short                __kernel_mode_t;
 typedef unsigned short         __kernel_ipc_pid_t;
 #define __kernel_ipc_pid_t __kernel_ipc_pid_t
 
-typedef int                    __kernel_suseconds_t;
-#define __kernel_suseconds_t __kernel_suseconds_t
-
 typedef long long              __kernel_off64_t;
 typedef unsigned long long     __kernel_ino64_t;
 
index 1c60408a64ad3b46b3fd1fed63e96329f3221c8f..d5eb19efa65beb1adccaf197a14cea6efe2a0144 100644 (file)
        */
        .macro          space_check     spc,tmp,fault
        mfsp            %sr7,\tmp
+       /* check against %r0 which is same value as LINUX_GATEWAY_SPACE */
        or,COND(<>)     %r0,\spc,%r0    /* user may execute gateway page
                                         * as kernel, so defeat the space
                                         * check if it is */
@@ -910,9 +911,9 @@ intr_check_sig:
         * Only do signals if we are returning to user space
         */
        LDREG   PT_IASQ0(%r16), %r20
-       cmpib,COND(=),n 0,%r20,intr_restore /* backward */
+       cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */
        LDREG   PT_IASQ1(%r16), %r20
-       cmpib,COND(=),n 0,%r20,intr_restore /* backward */
+       cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */
 
        /* NOTE: We need to enable interrupts if we have to deliver
         * signals. We used to do this earlier but it caused kernel
index e7e626bcd0bedd5da1f66ddde635aa9d31d83527..2d7cffcaa476e13016abdd9b5deca4275d537614 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/gfp.h>
 #include <linux/delay.h>
@@ -513,17 +512,15 @@ static void __init map_pages(unsigned long start_vaddr,
 
 void __init set_kernel_text_rw(int enable_read_write)
 {
-       unsigned long start = (unsigned long)_stext;
+       unsigned long start = (unsigned long)__init_begin;
        unsigned long end   = (unsigned long)_etext;
 
        map_pages(start, __pa(start), end-start,
                PAGE_KERNEL_RWX, enable_read_write ? 1:0);
 
-       /* force the kernel to see the new TLB entries */
-       __flush_tlb_range(0, start, end);
-
-       /* dump old cached instructions */
-       flush_icache_range(start, end);
+       /* force the kernel to see the new page table entries */
+       flush_cache_all();
+       flush_tlb_all();
 }
 
 void __ref free_initmem(void)
@@ -623,7 +620,7 @@ void __init mem_init(void)
 
        high_memory = __va((max_pfn << PAGE_SHIFT));
        set_max_mapnr(page_to_pfn(virt_to_page(high_memory - 1)) + 1);
-       free_all_bootmem();
+       memblock_free_all();
 
 #ifdef CONFIG_PA11
        if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) {
index e84943d24e5c7c38e5235a65e9c3f0b60c634dc5..2d51b2bd4aa132992f2f28be908b0571a79ae4d3 100644 (file)
@@ -206,7 +206,6 @@ config PPC
        select HAVE_KRETPROBES
        select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
        select HAVE_LIVEPATCH                   if HAVE_DYNAMIC_FTRACE_WITH_REGS
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NMI                         if PERF_EVENTS || (PPC64 && PPC_BOOK3S)
@@ -231,7 +230,6 @@ config PPC
        select MODULES_USE_ELF_RELA
        select NEED_DMA_MAP_STATE               if PPC64 || NOT_COHERENT_CACHE
        select NEED_SG_DMA_LENGTH
-       select NO_BOOTMEM
        select OF
        select OF_EARLY_FLATTREE
        select OF_RESERVED_MEM
index 7d04d60a39c96aeff137324c832b7d91f2bb0a29..ee58526cb6c276d20c029ccab1fddf7d5575c4fb 100644 (file)
@@ -67,12 +67,6 @@ extern int _chrp_type;
 
 #endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
 /* Macros for adjusting thread priority (hardware multi-threading) */
 #define HMT_very_low()   asm volatile("or 31,31,31   # very low priority")
 #define HMT_low()       asm volatile("or 1,1,1      # low priority")
index 41b1a5c1573403b7c0ceea122a37f018eab74f9d..2c145da3b774a136044e9106e96e38559c9e5832 100644 (file)
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
index f432054234a472eae7077afda818b6dcb51ccf00..8be3721d93026376fe42051461f5632ba2b79989 100644 (file)
@@ -1008,9 +1008,7 @@ static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char
        /* Count and allocate space for cpu features */
        of_scan_flat_dt_subnodes(node, count_cpufeatures_subnodes,
                                                &nr_dt_cpu_features);
-       dt_cpu_features = __va(
-               memblock_alloc(sizeof(struct dt_cpu_feature)*
-                               nr_dt_cpu_features, PAGE_SIZE));
+       dt_cpu_features = __va(memblock_phys_alloc(sizeof(struct dt_cpu_feature) * nr_dt_cpu_features, PAGE_SIZE));
 
        cpufeatures_setup_start(isa);
 
index 0ee3e6d50f2885d519462af046e19560ca4ace8e..913bfca09c4f1f0a19be2e0e87b55257be3321f6 100644 (file)
@@ -198,7 +198,7 @@ void __init allocate_paca_ptrs(void)
        paca_nr_cpu_ids = nr_cpu_ids;
 
        paca_ptrs_size = sizeof(struct paca_struct *) * nr_cpu_ids;
-       paca_ptrs = __va(memblock_alloc(paca_ptrs_size, 0));
+       paca_ptrs = __va(memblock_phys_alloc(paca_ptrs_size, SMP_CACHE_BYTES));
        memset(paca_ptrs, 0x88, paca_ptrs_size);
 }
 
index 4da8ed5762290746baf9575906d264066ce1e026..d3f04f2d824944d9947993b00fa8aec0bb0fdf08 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/capability.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/syscalls.h>
 #include <linux/irq.h>
 #include <linux/list.h>
@@ -203,7 +203,8 @@ pci_create_OF_bus_map(void)
        struct property* of_prop;
        struct device_node *dn;
 
-       of_prop = memblock_virt_alloc(sizeof(struct property) + 256, 0);
+       of_prop = memblock_alloc(sizeof(struct property) + 256,
+                                SMP_CACHE_BYTES);
        dn = of_find_node_by_path("/");
        if (dn) {
                memset(of_prop, -1, sizeof(struct property) + 256);
index c4d7078e5295fa6eec81f1913783191a162aac06..fe758cedb93fd617e6bb9be04344c0be2678fb50 100644 (file)
@@ -126,7 +126,7 @@ static void __init move_device_tree(void)
        if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) ||
                        overlaps_crashkernel(start, size) ||
                        overlaps_initrd(start, size)) {
-               p = __va(memblock_alloc(size, PAGE_SIZE));
+               p = __va(memblock_phys_alloc(size, PAGE_SIZE));
                memcpy(p, initial_boot_params, size);
                initial_boot_params = p;
                DBG("Moved device tree to 0x%p\n", p);
index 9ca9db707bcbb9a157cfeca63c9e7cb95f9721c8..93ee3703b42f331e5e0706eefd3a3a0f347d0243 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/serial_8250.h>
 #include <linux/percpu.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/of_platform.h>
 #include <linux/hugetlb.h>
 #include <asm/debugfs.h>
@@ -460,8 +459,7 @@ void __init smp_setup_cpu_maps(void)
 
        DBG("smp_setup_cpu_maps()\n");
 
-       cpu_to_phys_id = __va(memblock_alloc(nr_cpu_ids * sizeof(u32),
-                                                       __alignof__(u32)));
+       cpu_to_phys_id = __va(memblock_phys_alloc(nr_cpu_ids * sizeof(u32), __alignof__(u32)));
        memset(cpu_to_phys_id, 0, nr_cpu_ids * sizeof(u32));
 
        for_each_node_by_type(dn, "cpu") {
index 8c507be12c3c342085bfe4c765b17725501f0a0a..81909600013a133cdebb7df19cd74bf9561d83a4 100644 (file)
@@ -206,9 +206,9 @@ void __init irqstack_early_init(void)
         * as the memblock is limited to lowmem by default */
        for_each_possible_cpu(i) {
                softirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
                hardirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
        }
 }
 
@@ -227,12 +227,12 @@ void __init exc_lvl_early_init(void)
 #endif
 
                critirq_ctx[hw_cpu] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
 #ifdef CONFIG_BOOKE
                dbgirq_ctx[hw_cpu] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
                mcheckirq_ctx[hw_cpu] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+                       __va(memblock_phys_alloc(THREAD_SIZE, THREAD_SIZE));
 #endif
        }
 }
index faf00222b324c3183f651bb4cbd47c8de8afd42e..2a51e4cc8246d35d18d8ddd54b258af02dda47c4 100644 (file)
 #include <linux/unistd.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pci.h>
 #include <linux/lockdep.h>
-#include <linux/memblock.h>
 #include <linux/memory.h>
 #include <linux/nmi.h>
 
@@ -763,13 +762,15 @@ void __init emergency_stack_init(void)
 
 static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
 {
-       return __alloc_bootmem_node(NODE_DATA(early_cpu_to_node(cpu)), size, align,
-                                   __pa(MAX_DMA_ADDRESS));
+       return memblock_alloc_try_nid(size, align, __pa(MAX_DMA_ADDRESS),
+                                     MEMBLOCK_ALLOC_ACCESSIBLE,
+                                     early_cpu_to_node(cpu));
+
 }
 
 static void __init pcpu_fc_free(void *ptr, size_t size)
 {
-       free_bootmem(__pa(ptr), size);
+       memblock_free(__pa(ptr), size);
 }
 
 static int pcpu_cpu_distance(unsigned int from, unsigned int to)
index 06796dec01ea563346aaf551d8684f07d07d069e..dedf88a76f58cc81c0de00bbb6e8e96420f78094 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/string.h>
 #include <asm/setup.h>
 
@@ -14,7 +14,7 @@ void * __ref zalloc_maybe_bootmem(size_t size, gfp_t mask)
        if (slab_is_available())
                p = kzalloc(size, mask);
        else {
-               p = memblock_virt_alloc(size, 0);
+               p = memblock_alloc(size, SMP_CACHE_BYTES);
        }
        return p;
 }
index a7226ed9cae669dc4eb51137f8a8dec99fbc1bfd..8cf035e68378b70b99a49261bc02ef28cda026fd 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/export.h>
 #include <linux/of_fdt.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/moduleparam.h>
 #include <linux/swap.h>
 #include <linux/swapops.h>
index dd949d6649a26efac4b2f5339d0ba5710310e7d3..0a64fffabee12d0969725292cb3666f16e5edb4d 100644 (file)
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
 #include <linux/suspend.h>
-#include <linux/memblock.h>
 #include <linux/hugetlb.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -349,7 +348,7 @@ void __init mem_init(void)
 
        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
        set_max_mapnr(max_pfn);
-       free_all_bootmem();
+       memblock_free_all();
 
 #ifdef CONFIG_HIGHMEM
        {
index 4d80239ef83c37a9c322794356bfbcc9f21db98d..2faca46ad720ca4e24045a14cc18e154feff3f93 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/slab.h>
@@ -461,10 +461,11 @@ void __init mmu_context_init(void)
        /*
         * Allocate the maps used by context management
         */
-       context_map = memblock_virt_alloc(CTX_MAP_SIZE, 0);
-       context_mm = memblock_virt_alloc(sizeof(void *) * (LAST_CONTEXT + 1), 0);
+       context_map = memblock_alloc(CTX_MAP_SIZE, SMP_CACHE_BYTES);
+       context_mm = memblock_alloc(sizeof(void *) * (LAST_CONTEXT + 1),
+                                   SMP_CACHE_BYTES);
 #ifdef CONFIG_SMP
-       stale_map[boot_cpuid] = memblock_virt_alloc(CTX_MAP_SIZE, 0);
+       stale_map[boot_cpuid] = memblock_alloc(CTX_MAP_SIZE, SMP_CACHE_BYTES);
 
        cpuhp_setup_state_nocalls(CPUHP_POWERPC_MMU_CTX_PREPARE,
                                  "powerpc/mmu/ctx:prepare",
index 693ae1c1acbabb8d16fb427e52e9896385981f20..3a048e98a13231b6ce8ec239d91e98fe1ed2d3a9 100644 (file)
@@ -11,7 +11,7 @@
 #define pr_fmt(fmt) "numa: " fmt
 
 #include <linux/threads.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
@@ -19,7 +19,6 @@
 #include <linux/nodemask.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
-#include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/pfn.h>
 #include <linux/cpuset.h>
@@ -788,7 +787,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
        void *nd;
        int tnid;
 
-       nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
+       nd_pa = memblock_phys_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
        nd = __va(nd_pa);
 
        /* report and initialize */
index 5877f5aa8f5d0a0d00da87e749452236c1a4e35c..bda3c6f1bd32aeb67952c664d945e910587fac6e 100644 (file)
@@ -50,7 +50,7 @@ __ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
        if (slab_is_available()) {
                pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
        } else {
-               pte = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+               pte = __va(memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE));
                if (pte)
                        clear_page(pte);
        }
index 38a793bfca37e579d801fe62c1af30dfef4a56b2..f6f575bae3bceceae811b3cd54633f41d2633ecd 100644 (file)
@@ -224,7 +224,7 @@ void __init MMU_init_hw(void)
         * Find some memory for the hash table.
         */
        if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
-       Hash = __va(memblock_alloc(Hash_size, Hash_size));
+       Hash = __va(memblock_phys_alloc(Hash_size, Hash_size));
        memset(Hash, 0, Hash_size);
        _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
 
index f06c83f321e6c352869c69e859c399c14e2b9777..f2971522fb4aa842cb9128b5c7ccc46c6e8d47a5 100644 (file)
@@ -213,7 +213,7 @@ static int __init iob_init(struct device_node *dn)
        pr_info("IOBMAP L2 allocated at: %p\n", iob_l2_base);
 
        /* Allocate a spare page to map all invalid IOTLB pages. */
-       tmp = memblock_alloc(IOBMAP_PAGE_SIZE, IOBMAP_PAGE_SIZE);
+       tmp = memblock_phys_alloc(IOBMAP_PAGE_SIZE, IOBMAP_PAGE_SIZE);
        if (!tmp)
                panic("IOBMAP: Cannot allocate spare page!");
        /* Empty l1 is marked invalid */
index 60b03a1703d1f1472b136933b02a7e889547848f..ae54d7fe68f3628da3a7eaec671c23ae25d208f0 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/errno.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
 #include <asm/sections.h>
@@ -513,7 +513,7 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
                printk(KERN_ERR "nvram: no address\n");
                return -EINVAL;
        }
-       nvram_image = memblock_virt_alloc(NVRAM_SIZE, 0);
+       nvram_image = memblock_alloc(NVRAM_SIZE, SMP_CACHE_BYTES);
        nvram_data = ioremap(addr, NVRAM_SIZE*2);
        nvram_naddrs = 1; /* Make sure we get the correct case */
 
index a29fdf8a2e56ed5ab70d663f2bb40e04fe821e72..84d038ed3882a7794987ba3f222aab7351895d8f 100644 (file)
@@ -70,6 +70,7 @@ static int change_memblock_state(struct memory_block *mem, void *arg)
        return 0;
 }
 
+/* called with device_hotplug_lock held */
 static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages)
 {
        u64 end_pfn = start_pfn + nr_pages - 1;
@@ -110,6 +111,7 @@ static u64 memtrace_alloc_node(u32 nid, u64 size)
        /* Trace memory needs to be aligned to the size */
        end_pfn = round_down(end_pfn - nr_pages, nr_pages);
 
+       lock_device_hotplug();
        for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) {
                if (memtrace_offline_pages(nid, base_pfn, nr_pages) == true) {
                        /*
@@ -118,15 +120,15 @@ static u64 memtrace_alloc_node(u32 nid, u64 size)
                         * we never try to remove memory that spans two iomem
                         * resources.
                         */
-                       lock_device_hotplug();
                        end_pfn = base_pfn + nr_pages;
                        for (pfn = base_pfn; pfn < end_pfn; pfn += bytes>> PAGE_SHIFT) {
-                               remove_memory(nid, pfn << PAGE_SHIFT, bytes);
+                               __remove_memory(nid, pfn << PAGE_SHIFT, bytes);
                        }
                        unlock_device_hotplug();
                        return base_pfn << PAGE_SHIFT;
                }
        }
+       unlock_device_hotplug();
 
        return 0;
 }
@@ -242,9 +244,11 @@ static int memtrace_online(void)
                 * we need to online the memory ourselves.
                 */
                if (!memhp_auto_online) {
+                       lock_device_hotplug();
                        walk_memory_range(PFN_DOWN(ent->start),
                                          PFN_UP(ent->start + ent->size - 1),
                                          NULL, online_mem_block);
+                       unlock_device_hotplug();
                }
 
                /*
index a4641515956f4f64a949e79fdac9d3e380ce41f4..beed86f4224b998a77d66a0102b509cfe222fb22 100644 (file)
@@ -171,7 +171,7 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
        /*
         * Allocate a buffer to hold the MC recoverable ranges.
         */
-       mc_recoverable_range =__va(memblock_alloc(size, __alignof__(u64)));
+       mc_recoverable_range =__va(memblock_phys_alloc(size, __alignof__(u64)));
        memset(mc_recoverable_range, 0, size);
 
        for (i = 0; i < mc_recoverable_range_len; i++) {
index cde710297a4e434c58d32f07da8ee61d0a24d4a7..dd807446801efea02ccf1754739608c2854b477c 100644 (file)
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/msi.h>
-#include <linux/memblock.h>
 #include <linux/iommu.h>
 #include <linux/rculist.h>
 #include <linux/sizes.h>
@@ -3770,7 +3769,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
        phb_id = be64_to_cpup(prop64);
        pr_debug("  PHB-ID  : 0x%016llx\n", phb_id);
 
-       phb = memblock_virt_alloc(sizeof(*phb), 0);
+       phb = memblock_alloc(sizeof(*phb), SMP_CACHE_BYTES);
 
        /* Allocate PCI controller */
        phb->hose = hose = pcibios_alloc_controller(np);
@@ -3816,7 +3815,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
        else
                phb->diag_data_size = PNV_PCI_DIAG_BUF_SIZE;
 
-       phb->diag_data = memblock_virt_alloc(phb->diag_data_size, 0);
+       phb->diag_data = memblock_alloc(phb->diag_data_size, SMP_CACHE_BYTES);
 
        /* Parse 32-bit and IO ranges (if any) */
        pci_process_bridge_OF_ranges(hose, np, !hose->global_number);
@@ -3875,7 +3874,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
        }
        pemap_off = size;
        size += phb->ioda.total_pe_num * sizeof(struct pnv_ioda_pe);
-       aux = memblock_virt_alloc(size, 0);
+       aux = memblock_alloc(size, SMP_CACHE_BYTES);
        phb->ioda.pe_alloc = aux;
        phb->ioda.m64_segmap = aux + m64map_off;
        phb->ioda.m32_segmap = aux + m32map_off;
index 77a37520068ded6cd49b4e5d60d0982ae69a5c38..658bfab3350b928493ce0bf2b435bc2d602923cd 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/root_dev.h>
 #include <linux/console.h>
 #include <linux/export.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/machdep.h>
 #include <asm/firmware.h>
@@ -126,7 +126,7 @@ static void __init prealloc(struct ps3_prealloc *p)
        if (!p->size)
                return;
 
-       p->address = memblock_virt_alloc(p->size, p->align);
+       p->address = memblock_alloc(p->size, p->align);
 
        printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size,
               p->address);
index 2b796da822c28014111be66ebcd048f3ea2fe0af..2a983b5a52e1cec3d19a381687c7fd6f52b78acf 100644 (file)
@@ -300,7 +300,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
        nid = memory_add_physaddr_to_nid(base);
 
        for (i = 0; i < sections_per_block; i++) {
-               remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE);
+               __remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE);
                base += MIN_MEMORY_BLOCK_SIZE;
        }
 
@@ -389,7 +389,7 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb)
        block_sz = pseries_memory_block_size();
        nid = memory_add_physaddr_to_nid(lmb->base_addr);
 
-       remove_memory(nid, lmb->base_addr, block_sz);
+       __remove_memory(nid, lmb->base_addr, block_sz);
 
        /* Update memory regions for memory remove */
        memblock_remove(lmb->base_addr, block_sz);
@@ -668,7 +668,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
        nid = memory_add_physaddr_to_nid(lmb->base_addr);
 
        /* Add the memory */
-       rc = add_memory(nid, lmb->base_addr, block_sz);
+       rc = __add_memory(nid, lmb->base_addr, block_sz);
        if (rc) {
                invalidate_lmb_associativity_index(lmb);
                return rc;
@@ -676,7 +676,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
 
        rc = dlpar_online_lmb(lmb);
        if (rc) {
-               remove_memory(nid, lmb->base_addr, block_sz);
+               __remove_memory(nid, lmb->base_addr, block_sz);
                invalidate_lmb_associativity_index(lmb);
        } else {
                lmb->flags |= DRCONF_MEM_ASSIGNED;
index 5ca3e22d051293b31bd3e0a2e19a668aee90f365..a5b40d1460f1a007df88ff75e63356778d76345d 100644 (file)
@@ -261,7 +261,7 @@ static void allocate_dart(void)
         * that to work around what looks like a problem with the HT bridge
         * prefetching into invalid pages and corrupting data
         */
-       tmp = memblock_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
+       tmp = memblock_phys_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
        dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) &
                                         DARTMAP_RPNMASK);
 
index e64a411d1a007ebfb241ac908e70e9d29c1ceb55..d45450f6666a9966e63eb15c74ed5cb89a9ff98c 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/kmemleak.h>
 #include <linux/bitmap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/msi_bitmap.h>
 #include <asm/setup.h>
 
@@ -128,7 +128,7 @@ int __ref msi_bitmap_alloc(struct msi_bitmap *bmp, unsigned int irq_count,
        if (bmp->bitmap_from_slab)
                bmp->bitmap = kzalloc(size, GFP_KERNEL);
        else {
-               bmp->bitmap = memblock_virt_alloc(size, 0);
+               bmp->bitmap = memblock_alloc(size, SMP_CACHE_BYTES);
                /* the bitmap won't be freed from memblock allocator */
                kmemleak_not_leak(bmp->bitmap);
        }
index fe451348ae571371f25887a1cfaa9616f43eef7c..55da93f4e818e22ff1918aa625a56dde5bc56019 100644 (file)
@@ -28,14 +28,12 @@ config RISCV
        select GENERIC_STRNLEN_USER
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_DMA_CONTIGUOUS
        select HAVE_FUTEX_CMPXCHG if FUTEX
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_PERF_EVENTS
        select IRQ_DOMAIN
-       select NO_BOOTMEM
        select RISCV_ISA_A if SMP
        select SPARSE_IRQ
        select SYSCTL_EXCEPTION_TRACE
@@ -109,7 +107,6 @@ config ARCH_RV32I
        select GENERIC_LIB_ASHRDI3
        select GENERIC_LIB_LSHRDI3
        select GENERIC_LIB_UCMPDI2
-       select GENERIC_LIB_UMODDI3
 
 config ARCH_RV64I
        bool "RV64I"
index a1ef503d616ed05760fcb324e579bb71e842d6bc..697fc23b0d5ae4f6d6cd508e8d0a2804c277e0ee 100644 (file)
@@ -16,9 +16,6 @@
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
 
-/* TODO: Move definition into include/uapi/linux/elf-em.h */
-#define EM_RISCV       0xF3
-
 /*
  * These are used to set parameters in the core dumps.
  */
index 50de774d827ae69ca88495747592c44fa08dd486..0531f49af5c30e7f5c825c84e3057f160b3a87dd 100644 (file)
 struct task_struct;
 struct pt_regs;
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr()    ({ __label__ _l; _l: &&_l; })
-
 /* CPU-specific state of a task */
 struct thread_struct {
        /* Callee-saved registers */
index 5493f3228704740e913e0d5883d1cca99ba7f645..0339087aa6520dba2790e6d31caa5d4f089c75b6 100644 (file)
@@ -28,7 +28,7 @@ bool has_fpu __read_mostly;
 
 void riscv_fill_hwcap(void)
 {
-       struct device_node *node;
+       struct device_node *node = NULL;
        const char *isa;
        size_t i;
        static unsigned long isa2hwcap[256] = {0};
@@ -44,9 +44,11 @@ void riscv_fill_hwcap(void)
 
        /*
         * We don't support running Linux on hertergenous ISA systems.  For
-        * now, we just check the ISA of the first processor.
+        * now, we just check the ISA of the first "okay" processor.
         */
-       node = of_find_node_by_type(NULL, "cpu");
+       while ((node = of_find_node_by_type(node, "cpu")))
+               if (riscv_of_processor_hartid(node) >= 0)
+                       break;
        if (!node) {
                pr_warning("Unable to find \"cpu\" devicetree entry");
                return;
index 58a522f9bcc319ae5d40a8ae15da5d9021921ebd..1d9bfaff60bca8c703646428af3581f4607fe0ef 100644 (file)
@@ -13,9 +13,8 @@
 
 #include <linux/init.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/initrd.h>
 #include <linux/memblock.h>
+#include <linux/initrd.h>
 #include <linux/swap.h>
 #include <linux/sizes.h>
 
@@ -55,7 +54,7 @@ void __init mem_init(void)
 #endif /* CONFIG_FLATMEM */
 
        high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
-       free_all_bootmem();
+       memblock_free_all();
 
        mem_init_print_info(NULL);
 }
index 8b25e1f45b2749c1472e6b1247082b3c24d023b6..5173366af8f359b98d9683afd6a9e105c7a7a910 100644 (file)
@@ -163,7 +163,6 @@ config S390
        select HAVE_LIVEPATCH
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MEMBLOCK_PHYS_MAP
        select HAVE_MOD_ARCH_SPECIFIC
@@ -175,7 +174,6 @@ config S390
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_VIRT_CPU_ACCOUNTING
        select MODULES_USE_ELF_RELA
-       select NO_BOOTMEM
        select OLD_SIGACTION
        select OLD_SIGSUSPEND3
        select SPARSE_IRQ
index 34768e6ef4fb7c963b5d3f397d6a7535115eb8eb..302795c47c06c299b732ed73de7b057a71b3805c 100644 (file)
@@ -73,12 +73,6 @@ static inline int test_cpu_flag_of(int flag, int cpu)
 
 #define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
-
 static inline void get_cpu_id(struct cpuid *ptr)
 {
        asm volatile("stidp %0" : "=Q" (*ptr));
index 376f6b6dfb3cb14b00174adef95820836c3ee0a6..97eae387186875ea834c635d0608e49658bf355a 100644 (file)
 #include <linux/mm.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/elf.h>
 #include <asm/asm-offsets.h>
-#include <linux/memblock.h>
 #include <asm/os_info.h>
 #include <asm/elf.h>
 #include <asm/ipl.h>
@@ -61,7 +60,7 @@ struct save_area * __init save_area_alloc(bool is_boot_cpu)
 {
        struct save_area *sa;
 
-       sa = (void *) memblock_alloc(sizeof(*sa), 8);
+       sa = (void *) memblock_phys_alloc(sizeof(*sa), 8);
        if (is_boot_cpu)
                list_add(&sa->list, &dump_save_areas);
        else
index a2e952b662487453b8baedefc53402eb04d70a83..72dd23ef771b6bf22f77e71df22a40e05fbee2d5 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/initrd.h>
-#include <linux/bootmem.h>
 #include <linux/root_dev.h>
 #include <linux/console.h>
 #include <linux/kernel_stat.h>
@@ -378,7 +377,7 @@ static void __init setup_lowcore(void)
         * Setup lowcore for boot cpu
         */
        BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * PAGE_SIZE);
-       lc = memblock_virt_alloc_low(sizeof(*lc), sizeof(*lc));
+       lc = memblock_alloc_low(sizeof(*lc), sizeof(*lc));
        lc->restart_psw.mask = PSW_KERNEL_BITS;
        lc->restart_psw.addr = (unsigned long) restart_int_handler;
        lc->external_new_psw.mask = PSW_KERNEL_BITS |
@@ -422,7 +421,7 @@ static void __init setup_lowcore(void)
         * Allocate the global restart stack which is the same for
         * all CPUs in cast *one* of them does a PSW restart.
         */
-       restart_stack = memblock_virt_alloc(THREAD_SIZE, THREAD_SIZE);
+       restart_stack = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
        restart_stack += STACK_INIT_OFFSET;
 
        /*
@@ -488,7 +487,7 @@ static void __init setup_resources(void)
        bss_resource.end = (unsigned long) __bss_stop - 1;
 
        for_each_memblock(memory, reg) {
-               res = memblock_virt_alloc(sizeof(*res), 8);
+               res = memblock_alloc(sizeof(*res), 8);
                res->flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM;
 
                res->name = "System RAM";
@@ -502,7 +501,7 @@ static void __init setup_resources(void)
                            std_res->start > res->end)
                                continue;
                        if (std_res->end > res->end) {
-                               sub_res = memblock_virt_alloc(sizeof(*sub_res), 8);
+                               sub_res = memblock_alloc(sizeof(*sub_res), 8);
                                *sub_res = *std_res;
                                sub_res->end = res->end;
                                std_res->start = res->end + 1;
@@ -967,7 +966,8 @@ static void __init setup_randomness(void)
 {
        struct sysinfo_3_2_2 *vmms;
 
-       vmms = (struct sysinfo_3_2_2 *) memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+       vmms = (struct sysinfo_3_2_2 *) memblock_phys_alloc(PAGE_SIZE,
+                                                           PAGE_SIZE);
        if (stsi(vmms, 3, 2, 2) == 0 && vmms->count)
                add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count);
        memblock_free((unsigned long) vmms, PAGE_SIZE);
index 1b3188f57b58f6dc1995f3cb9ae1134506450d27..f82b3d3c36e2d5620e4b8e6b363936bcdf38d673 100644 (file)
@@ -20,7 +20,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/workqueue.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/mm.h>
@@ -35,7 +35,6 @@
 #include <linux/sched/hotplug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/crash_dump.h>
-#include <linux/memblock.h>
 #include <linux/kprobes.h>
 #include <asm/asm-offsets.h>
 #include <asm/diag.h>
@@ -761,7 +760,7 @@ void __init smp_detect_cpus(void)
        u16 address;
 
        /* Get CPU information */
-       info = memblock_virt_alloc(sizeof(*info), 8);
+       info = memblock_alloc(sizeof(*info), 8);
        smp_get_core_info(info, 1);
        /* Find boot CPU type */
        if (sclp.has_core_type) {
index e8184a15578a332eae08bcb60e21fbb3ec0dd780..8992b04c0adea6329299e30c4aaf8013a94b2de1 100644 (file)
@@ -8,7 +8,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/workqueue.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/uaccess.h>
 #include <linux/sysctl.h>
 #include <linux/cpuset.h>
@@ -519,7 +519,7 @@ static void __init alloc_masks(struct sysinfo_15_1_x *info,
                nr_masks *= info->mag[TOPOLOGY_NR_MAG - offset - 1 - i];
        nr_masks = max(nr_masks, 1);
        for (i = 0; i < nr_masks; i++) {
-               mask->next = memblock_virt_alloc(sizeof(*mask->next), 8);
+               mask->next = memblock_alloc(sizeof(*mask->next), 8);
                mask = mask->next;
        }
 }
@@ -537,7 +537,7 @@ void __init topology_init_early(void)
        }
        if (!MACHINE_HAS_TOPOLOGY)
                goto out;
-       tl_info = memblock_virt_alloc(PAGE_SIZE, PAGE_SIZE);
+       tl_info = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
        info = tl_info;
        store_topology(info);
        pr_info("The CPU configuration topology of the machine is: %d %d %d %d %d %d / %d\n",
index ec31b48a42a52798bf31d5b55a7ef566b0ab3766..ebe748a9f472fde63cfccd42921472233f6ea529 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/user.h>
 #include <linux/elf.h>
 #include <linux/security.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/compat.h>
 #include <asm/asm-offsets.h>
 #include <asm/pgtable.h>
index 84111a43ea2932055fd3e6281eb2289a697da5c2..eba2def3414dc5d0a78b3209ab2569522a9f094e 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/export.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ctype.h>
 #include <linux/ioport.h>
 #include <asm/diag.h>
index 92d7a153e72a0fe8bad784552d7a142a9d03ba69..76d0708438e9b8d9c4dcabd5b280caceafb2bfb0 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/smp.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/memory.h>
 #include <linux/pfn.h>
 #include <linux/poison.h>
@@ -29,7 +29,6 @@
 #include <linux/export.h>
 #include <linux/cma.h>
 #include <linux/gfp.h>
-#include <linux/memblock.h>
 #include <asm/processor.h>
 #include <linux/uaccess.h>
 #include <asm/pgtable.h>
@@ -139,7 +138,7 @@ void __init mem_init(void)
        cmma_init();
 
        /* this will put all low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
        setup_zero_pages();     /* Setup zeroed pages. */
 
        cmma_init_nodat();
index db55561c598130475fc3828ce54c9ad394788dd0..0472e27febdfaa620cf4cd5849690907486d1136 100644 (file)
@@ -4,14 +4,13 @@
  *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/hugetlb.h>
 #include <linux/slab.h>
-#include <linux/memblock.h>
 #include <asm/cacheflush.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
@@ -36,7 +35,7 @@ static void __ref *vmem_alloc_pages(unsigned int order)
 
        if (slab_is_available())
                return (void *)__get_free_pages(GFP_KERNEL, order);
-       return (void *) memblock_alloc(size, size);
+       return (void *) memblock_phys_alloc(size, size);
 }
 
 void *vmem_crst_alloc(unsigned long val)
@@ -57,7 +56,7 @@ pte_t __ref *vmem_pte_alloc(void)
        if (slab_is_available())
                pte = (pte_t *) page_table_alloc(&init_mm);
        else
-               pte = (pte_t *) memblock_alloc(size, size);
+               pte = (pte_t *) memblock_phys_alloc(size, size);
        if (!pte)
                return NULL;
        memset64((u64 *)pte, _PAGE_INVALID, PTRS_PER_PTE);
index 83b222c576097b5a588cf65a77d210f128ad4a66..bfba273c32c01ae70497f4cf32c1c8a28b17179a 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/cpumask.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/node.h>
 #include <linux/memory.h>
 #include <linux/slab.h>
@@ -313,7 +312,7 @@ static void __ref create_core_to_node_map(void)
 {
        int i;
 
-       emu_cores = memblock_virt_alloc(sizeof(*emu_cores), 8);
+       emu_cores = memblock_alloc(sizeof(*emu_cores), 8);
        for (i = 0; i < ARRAY_SIZE(emu_cores->to_node_id); i++)
                emu_cores->to_node_id[i] = NODE_ID_FREE;
 }
index 5bd374491f9461467790e1e0522f838827f094df..ae0d9e889534cd880f750845fb58d919080e9325 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/mmzone.h>
 #include <linux/cpumask.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/node.h>
@@ -64,7 +63,7 @@ static __init pg_data_t *alloc_node_data(void)
 {
        pg_data_t *res;
 
-       res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8);
+       res = (pg_data_t *) memblock_phys_alloc(sizeof(pg_data_t), 8);
        memset(res, 0, sizeof(pg_data_t));
        return res;
 }
index 21d1e8a1546d061f829a83cd513a17b6a9d4ccc5..71a608cd4f6124ded785897f2aba031b88ea0772 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/cpumask.h>
 #include <linux/list.h>
 #include <linux/list_sort.h>
@@ -34,7 +34,7 @@ struct toptree __ref *toptree_alloc(int level, int id)
        if (slab_is_available())
                res = kzalloc(sizeof(*res), GFP_KERNEL);
        else
-               res = memblock_virt_alloc(sizeof(*res), 8);
+               res = memblock_alloc(sizeof(*res), 8);
        if (!res)
                return res;
 
index 475d786a65b0722a2b663c109f0e25945a2b82de..f82a4da7adf3fb34d4a8d03bf9a294f3a6312108 100644 (file)
@@ -9,9 +9,7 @@ config SUPERH
        select CLKDEV_LOOKUP
        select DMA_DIRECT_OPS
        select HAVE_IDE if HAS_IOPORT_MAP
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
-       select NO_BOOTMEM
        select ARCH_DISCARD_MEMBLOCK
        select HAVE_OPROFILE
        select HAVE_GENERIC_DMA_COHERENT
index 95100d8a0b7b485427cf615990543b71f6d19083..0e0ecc0132e3b1e64d724e79b17bc374bebdb845 100644 (file)
 #include <asm/types.h>
 #include <asm/hw_breakpoint.h>
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ void *pc; __asm__("mova 1f, %0\n.align 2\n1:":"=z" (pc)); pc; })
-
 /* Core Processor Version Register */
 #define CCN_PVR                0xff000030
 #define CCN_CVR                0xff000040
index 777a16318aff1fd41df535ccc91453d7d91d318f..f3d7075648d049239f58e1e5f76cb23d13dc89df 100644 (file)
 #include <asm/types.h>
 #include <cpu/registers.h>
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ \
-void *pc; \
-unsigned long long __dummy = 0; \
-__asm__("gettr tr0, %1\n\t" \
-       "pta    4, tr0\n\t" \
-       "gettr  tr0, %0\n\t" \
-       "ptabs  %1, tr0\n\t"    \
-       :"=r" (pc), "=r" (__dummy) \
-       : "1" (__dummy)); \
-pc; })
-
 #endif
 
 /*
index cc62f6f981036b539387abf9205cc8c43e5f18ec..11866d4f60e1679f4b4836276a20a858c7365563 100644 (file)
@@ -95,6 +95,8 @@
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD   _IOR('T', 84,  int) /* 0x5454 */
index 7713c084d0402ac5c5f3ce5619cdafd1b12e37c3..c8c13c777162c42ce5c189b1ff0c8c71806796e0 100644 (file)
 #include <linux/swap.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/proc_fs.h>
 #include <linux/pagemap.h>
 #include <linux/percpu.h>
 #include <linux/io.h>
-#include <linux/memblock.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <asm/mmu_context.h>
@@ -128,7 +127,7 @@ static pmd_t * __init one_md_table_init(pud_t *pud)
        if (pud_none(*pud)) {
                pmd_t *pmd;
 
-               pmd = alloc_bootmem_pages(PAGE_SIZE);
+               pmd = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
                pud_populate(&init_mm, pud, pmd);
                BUG_ON(pmd != pmd_offset(pud, 0));
        }
@@ -141,7 +140,7 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
        if (pmd_none(*pmd)) {
                pte_t *pte;
 
-               pte = alloc_bootmem_pages(PAGE_SIZE);
+               pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
                pmd_populate_kernel(&init_mm, pmd, pte);
                BUG_ON(pte != pte_offset_kernel(pmd, 0));
        }
@@ -350,7 +349,7 @@ void __init mem_init(void)
                high_memory = max_t(void *, high_memory,
                                    __va(pgdat_end_pfn(pgdat) << PAGE_SHIFT));
 
-       free_all_bootmem();
+       memblock_free_all();
 
        /* Set this up early, so we can take care of the zero page */
        cpu_cache_init();
index 927a1294c465f88dbd245c7ad45f9ce16c2d28dd..07e744d75fa01bba1137ffc105a42ebb2d1242c1 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/io.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/proc_fs.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
index 7e2aa59fcc2969ff55c33c57ddaf9b46407487f4..490b2c95c212cf794671ec2e72b4458d33fbdde8 100644 (file)
@@ -45,8 +45,6 @@ config SPARC
        select LOCKDEP_SMALL if LOCKDEP
        select NEED_DMA_MAP_STATE
        select NEED_SG_DMA_LENGTH
-       select HAVE_MEMBLOCK
-       select NO_BOOTMEM
 
 config SPARC32
        def_bool !64BIT
index 192493c257fa2905b00f79aa893785778f2df2a7..3c4bc2189092d350b7b6e2c794714f6c7249f692 100644 (file)
@@ -7,12 +7,6 @@
 #ifndef __ASM_SPARC_PROCESSOR_H
 #define __ASM_SPARC_PROCESSOR_H
 
-/*
- * Sparc32 implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ void *pc; __asm__("sethi %%hi(1f), %0; or %0, %%lo(1f), %0;\n1:" : "=r" (pc)); pc; })
-
 #include <asm/psr.h>
 #include <asm/ptrace.h>
 #include <asm/head.h>
index aac23d4a4ddd5647643dfdb3e337492802f57a8c..5cf145f18f36b01f416f56084e213d697fae045e 100644 (file)
@@ -8,12 +8,6 @@
 #ifndef __ASM_SPARC64_PROCESSOR_H
 #define __ASM_SPARC64_PROCESSOR_H
 
-/*
- * Sparc64 implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; })
-
 #include <asm/asi.h>
 #include <asm/pstate.h>
 #include <asm/ptrace.h>
index 2df52711e17033f5f725b682d9719306c7f35ec7..7fd2f5873c9e7a9f5878f20be1e47a68666759a3 100644 (file)
@@ -27,6 +27,8 @@
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGRS485     _IOR('T', 0x41, struct serial_rs485)
 #define TIOCSRS485     _IOWR('T', 0x42, struct serial_rs485)
+#define TIOCGISO7816   _IOR('T', 0x43, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x44, struct serial_iso7816)
 
 /* Note that all the ioctls that are not available in Linux have a
  * double underscore on the front to: a) avoid some programs to
index 39a2503fa3e18e8816dde7078c43dc5c5d509b5e..9a26b442f820c86b5df5cfd13efd309dea3d59cc 100644 (file)
@@ -5,13 +5,12 @@
  */
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/memblock.h>
 #include <linux/log2.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/refcount.h>
 
@@ -170,7 +169,7 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size
                       mdesc_size);
        alloc_size = PAGE_ALIGN(handle_size);
 
-       paddr = memblock_alloc(alloc_size, PAGE_SIZE);
+       paddr = memblock_phys_alloc(alloc_size, PAGE_SIZE);
 
        hp = NULL;
        if (paddr) {
@@ -190,7 +189,7 @@ static void __init mdesc_memblock_free(struct mdesc_handle *hp)
 
        alloc_size = PAGE_ALIGN(hp->handle_size);
        start = __pa(hp);
-       free_bootmem_late(start, alloc_size);
+       memblock_free_late(start, alloc_size);
 }
 
 static struct mdesc_mem_ops memblock_mdesc_ops = {
index b51cbb9e87dcbe8ae036d692d834ca5ebcaa9fee..d41e2a749c5d94668876b0d92ac4963954696699 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/prom.h>
 #include <asm/oplib.h>
@@ -32,7 +32,7 @@ void * __init prom_early_alloc(unsigned long size)
 {
        void *ret;
 
-       ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+       ret = memblock_alloc_from(size, SMP_CACHE_BYTES, 0UL);
        if (ret != NULL)
                memset(ret, 0, size);
 
index baeaeed6499391e368240be85baa2698e81a2600..c37955d127fe5feec18c61198fb9141611e254f2 100644 (file)
@@ -34,7 +34,7 @@
 
 void * __init prom_early_alloc(unsigned long size)
 {
-       unsigned long paddr = memblock_alloc(size, SMP_CACHE_BYTES);
+       unsigned long paddr = memblock_phys_alloc(size, SMP_CACHE_BYTES);
        void *ret;
 
        if (!paddr) {
index 7944b3ca216a1888048c1dce1ffe7c783292eac8..cd2825cb84207c16b3cf82870a25877a5793ffee 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/initrd.h>
 #include <linux/module.h>
 #include <linux/start_kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -621,12 +621,10 @@ void __init alloc_irqstack_bootmem(void)
        for_each_possible_cpu(i) {
                node = cpu_to_node(i);
 
-               softirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
-                                                       THREAD_SIZE,
-                                                       THREAD_SIZE, 0);
-               hardirq_stack[i] = __alloc_bootmem_node(NODE_DATA(node),
-                                                       THREAD_SIZE,
-                                                       THREAD_SIZE, 0);
+               softirq_stack[i] = memblock_alloc_node(THREAD_SIZE,
+                                                      THREAD_SIZE, node);
+               hardirq_stack[i] = memblock_alloc_node(THREAD_SIZE,
+                                                      THREAD_SIZE, node);
        }
 }
 
index d3ea1f3c06a003ae185b4d2b7bf9af552f62d34f..4792e08ad36b0116f5bb4948d1deb0e19ca30405 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/cache.h>
 #include <linux/jiffies.h>
 #include <linux/profile.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/vmalloc.h>
 #include <linux/ftrace.h>
 #include <linux/cpu.h>
@@ -1588,26 +1588,26 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, size_t size,
        void *ptr;
 
        if (!node_online(node) || !NODE_DATA(node)) {
-               ptr = __alloc_bootmem(size, align, goal);
+               ptr = memblock_alloc_from(size, align, goal);
                pr_info("cpu %d has no node %d or node-local memory\n",
                        cpu, node);
                pr_debug("per cpu data for cpu%d %lu bytes at %016lx\n",
                         cpu, size, __pa(ptr));
        } else {
-               ptr = __alloc_bootmem_node(NODE_DATA(node),
-                                          size, align, goal);
+               ptr = memblock_alloc_try_nid(size, align, goal,
+                                            MEMBLOCK_ALLOC_ACCESSIBLE, node);
                pr_debug("per cpu data for cpu%d %lu bytes on node%d at "
                         "%016lx\n", cpu, size, node, __pa(ptr));
        }
        return ptr;
 #else
-       return __alloc_bootmem(size, align, goal);
+       return memblock_alloc_from(size, align, goal);
 #endif
 }
 
 static void __init pcpu_free_bootmem(void *ptr, size_t size)
 {
-       free_bootmem(__pa(ptr), size);
+       memblock_free(__pa(ptr), size);
 }
 
 static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
@@ -1627,7 +1627,7 @@ static void __init pcpu_populate_pte(unsigned long addr)
        if (pgd_none(*pgd)) {
                pud_t *new;
 
-               new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+               new = memblock_alloc_from(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
                pgd_populate(&init_mm, pgd, new);
        }
 
@@ -1635,7 +1635,7 @@ static void __init pcpu_populate_pte(unsigned long addr)
        if (pud_none(*pud)) {
                pmd_t *new;
 
-               new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+               new = memblock_alloc_from(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
                pud_populate(&init_mm, pud, new);
        }
 
@@ -1643,7 +1643,7 @@ static void __init pcpu_populate_pte(unsigned long addr)
        if (!pmd_present(*pmd)) {
                pte_t *new;
 
-               new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+               new = memblock_alloc_from(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
                pmd_populate_kernel(&init_mm, pmd, new);
        }
 }
index 92634d4e440c26be54dddd96c22160259654dd1e..d900952bfc5f3b0da140e722025f9aea21bfcef4 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/initrd.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/pagemap.h>
 #include <linux/poison.h>
@@ -265,7 +264,7 @@ void __init mem_init(void)
        i = last_valid_pfn >> ((20 - PAGE_SHIFT) + 5);
        i += 1;
        sparc_valid_addr_bitmap = (unsigned long *)
-               __alloc_bootmem(i << 2, SMP_CACHE_BYTES, 0UL);
+               memblock_alloc_from(i << 2, SMP_CACHE_BYTES, 0UL);
 
        if (sparc_valid_addr_bitmap == NULL) {
                prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
@@ -277,7 +276,7 @@ void __init mem_init(void)
 
        max_mapnr = last_valid_pfn - pfn_base;
        high_memory = __va(max_low_pfn << PAGE_SHIFT);
-       free_all_bootmem();
+       memblock_free_all();
 
        for (i = 0; sp_banks[i].num_bytes != 0; i++) {
                unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
index 39822f611c01503211413a28d8c3492de60e6e26..3c8aac21f4260bd9227849a4fdc6f93820aa49e8 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/initrd.h>
@@ -25,7 +25,6 @@
 #include <linux/sort.h>
 #include <linux/ioport.h>
 #include <linux/percpu.h>
-#include <linux/memblock.h>
 #include <linux/mmzone.h>
 #include <linux/gfp.h>
 
@@ -1092,7 +1091,8 @@ static void __init allocate_node_data(int nid)
 #ifdef CONFIG_NEED_MULTIPLE_NODES
        unsigned long paddr;
 
-       paddr = memblock_alloc_try_nid(sizeof(struct pglist_data), SMP_CACHE_BYTES, nid);
+       paddr = memblock_phys_alloc_try_nid(sizeof(struct pglist_data),
+                                           SMP_CACHE_BYTES, nid);
        if (!paddr) {
                prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
                prom_halt();
@@ -1266,8 +1266,8 @@ static int __init grab_mlgroups(struct mdesc_handle *md)
        if (!count)
                return -ENOENT;
 
-       paddr = memblock_alloc(count * sizeof(struct mdesc_mlgroup),
-                         SMP_CACHE_BYTES);
+       paddr = memblock_phys_alloc(count * sizeof(struct mdesc_mlgroup),
+                                   SMP_CACHE_BYTES);
        if (!paddr)
                return -ENOMEM;
 
@@ -1307,8 +1307,8 @@ static int __init grab_mblocks(struct mdesc_handle *md)
        if (!count)
                return -ENOENT;
 
-       paddr = memblock_alloc(count * sizeof(struct mdesc_mblock),
-                         SMP_CACHE_BYTES);
+       paddr = memblock_phys_alloc(count * sizeof(struct mdesc_mblock),
+                                   SMP_CACHE_BYTES);
        if (!paddr)
                return -ENOMEM;
 
@@ -1810,7 +1810,8 @@ static unsigned long __ref kernel_map_range(unsigned long pstart,
                if (pgd_none(*pgd)) {
                        pud_t *new;
 
-                       new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+                       new = memblock_alloc_from(PAGE_SIZE, PAGE_SIZE,
+                                                 PAGE_SIZE);
                        alloc_bytes += PAGE_SIZE;
                        pgd_populate(&init_mm, pgd, new);
                }
@@ -1822,7 +1823,8 @@ static unsigned long __ref kernel_map_range(unsigned long pstart,
                                vstart = kernel_map_hugepud(vstart, vend, pud);
                                continue;
                        }
-                       new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+                       new = memblock_alloc_from(PAGE_SIZE, PAGE_SIZE,
+                                                 PAGE_SIZE);
                        alloc_bytes += PAGE_SIZE;
                        pud_populate(&init_mm, pud, new);
                }
@@ -1835,7 +1837,8 @@ static unsigned long __ref kernel_map_range(unsigned long pstart,
                                vstart = kernel_map_hugepmd(vstart, vend, pmd);
                                continue;
                        }
-                       new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+                       new = memblock_alloc_from(PAGE_SIZE, PAGE_SIZE,
+                                                 PAGE_SIZE);
                        alloc_bytes += PAGE_SIZE;
                        pmd_populate_kernel(&init_mm, pmd, new);
                }
@@ -2541,12 +2544,12 @@ void __init mem_init(void)
 {
        high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
-       free_all_bootmem();
+       memblock_free_all();
 
        /*
         * Must be done after boot memory is put on freelist, because here we
         * might set fields in deferred struct pages that have not yet been
-        * initialized, and free_all_bootmem() initializes all the reserved
+        * initialized, and memblock_free_all() initializes all the reserved
         * deferred pages for us.
         */
        register_page_bootmem_info();
index be9cb006517924284e50e66f1faf6bf1c56f5494..a6142c5abf6141e468331e64b85d6aee1a5a5d30 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <linux/seq_file.h>
 #include <linux/spinlock.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
 #include <linux/kdebug.h>
@@ -303,13 +303,13 @@ static void __init srmmu_nocache_init(void)
 
        bitmap_bits = srmmu_nocache_size >> SRMMU_NOCACHE_BITMAP_SHIFT;
 
-       srmmu_nocache_pool = __alloc_bootmem(srmmu_nocache_size,
-               SRMMU_NOCACHE_ALIGN_MAX, 0UL);
+       srmmu_nocache_pool = memblock_alloc_from(srmmu_nocache_size,
+                                                SRMMU_NOCACHE_ALIGN_MAX, 0UL);
        memset(srmmu_nocache_pool, 0, srmmu_nocache_size);
 
        srmmu_nocache_bitmap =
-               __alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long),
-                               SMP_CACHE_BYTES, 0UL);
+               memblock_alloc_from(BITS_TO_LONGS(bitmap_bits) * sizeof(long),
+                                   SMP_CACHE_BYTES, 0UL);
        bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits);
 
        srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
@@ -467,7 +467,7 @@ static void __init sparc_context_init(int numctx)
        unsigned long size;
 
        size = numctx * sizeof(struct ctx_list);
-       ctx_list_pool = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+       ctx_list_pool = memblock_alloc_from(size, SMP_CACHE_BYTES, 0UL);
 
        for (ctx = 0; ctx < numctx; ctx++) {
                struct ctx_list *clist;
index 10c15b8853ae5a56c2d4a200c80ceef956b690eb..6b9938919f0bab07e46fefbe97b45c4cab663a8c 100644 (file)
@@ -12,8 +12,6 @@ config UML
        select HAVE_UID16
        select HAVE_FUTEX_CMPXCHG if FUTEX
        select HAVE_DEBUG_KMEMLEAK
-       select HAVE_MEMBLOCK
-       select NO_BOOTMEM
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
index 8d80b27502e6ae4feb235d01801a67be5ca8cce4..7e524efed58484c394beefd2d6d3651ee0eeb5fa 100644 (file)
@@ -261,7 +261,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
        if (err == 0) {
                spin_unlock(&line->lock);
                return IRQ_NONE;
-       } else if (err < 0) {
+       } else if ((err < 0) && (err != -EAGAIN)) {
                line->head = line->buffer;
                line->tail = line->buffer;
        }
@@ -284,7 +284,7 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
        if (err)
                return err;
        if (output)
-               err = um_request_irq(driver->write_irq, fd, IRQ_NONE,
+               err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
                                     line_write_interrupt, IRQF_SHARED,
                                     driver->write_irq_name, data);
        return err;
index 3ef1b48e064a87dd33465ff083c604c4657b8bb2..624cb47cc9cd35b56c10a27e565c64b078cd84fa 100644 (file)
@@ -6,7 +6,7 @@
  * Licensed under the GPL.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/inetdevice.h>
@@ -650,7 +650,7 @@ static int __init eth_setup(char *str)
                return 1;
        }
 
-       new = alloc_bootmem(sizeof(*new));
+       new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES);
 
        INIT_LIST_HEAD(&new->list);
        new->index = n;
index 9a8e1b64c22e3dcf4a51845b4a9343adfbc1e144..5f56d11b886fc2926ac412b0f3b292a1a88b2ec3 100644 (file)
@@ -168,7 +168,7 @@ int port_connection(int fd, int *socket, int *pid_out)
 {
        int new, err;
        char *argv[] = { "/usr/sbin/in.telnetd", "-L",
-                        "/usr/lib/uml/port-helper", NULL };
+                        OS_LIB_PATH "/uml/port-helper", NULL };
        struct port_pre_exec_data data;
 
        new = accept(fd, NULL, 0);
index 50ee3bb5a63a9eb950d76baeba475bcf7f0700b8..046fa9ea0ccc7dae2ee80381c224916700e612d1 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/version.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/inetdevice.h>
@@ -1118,16 +1118,11 @@ static int vector_net_close(struct net_device *dev)
                os_close_file(vp->fds->tx_fd);
                vp->fds->tx_fd = -1;
        }
-       if (vp->bpf != NULL)
-               kfree(vp->bpf);
-       if (vp->fds->remote_addr != NULL)
-               kfree(vp->fds->remote_addr);
-       if (vp->transport_data != NULL)
-               kfree(vp->transport_data);
-       if (vp->header_rxbuffer != NULL)
-               kfree(vp->header_rxbuffer);
-       if (vp->header_txbuffer != NULL)
-               kfree(vp->header_txbuffer);
+       kfree(vp->bpf);
+       kfree(vp->fds->remote_addr);
+       kfree(vp->transport_data);
+       kfree(vp->header_rxbuffer);
+       kfree(vp->header_txbuffer);
        if (vp->rx_queue != NULL)
                destroy_queue(vp->rx_queue);
        if (vp->tx_queue != NULL)
@@ -1580,7 +1575,7 @@ static int __init vector_setup(char *str)
                                 str, error);
                return 1;
        }
-       new = alloc_bootmem(sizeof(*new));
+       new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES);
        INIT_LIST_HEAD(&new->list);
        new->unit = n;
        new->arguments = str;
index 4d6a78e31089f6c12f94bddbf9a53f85bf8d0401..3d8cdbdb4e661988df125b9cdb68d906fb1312a6 100644 (file)
@@ -267,8 +267,7 @@ cleanup:
                os_close_file(rxfd);
        if (txfd >= 0)
                os_close_file(txfd);
-       if (result != NULL)
-               kfree(result);
+       kfree(result);
        return NULL;
 }
 
@@ -434,8 +433,7 @@ cleanup:
        if (fd >= 0)
                os_close_file(fd);
        if (result != NULL) {
-               if (result->remote_addr != NULL)
-                       kfree(result->remote_addr);
+               kfree(result->remote_addr);
                kfree(result);
        }
        return NULL;
diff --git a/arch/um/include/shared/aio.h b/arch/um/include/shared/aio.h
deleted file mode 100644 (file)
index 423bae9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef AIO_H__
-#define AIO_H__
-
-enum aio_type { AIO_READ, AIO_WRITE, AIO_MMAP };
-
-struct aio_thread_reply {
-       void *data;
-       int err;
-};
-
-struct aio_context {
-       int reply_fd;
-       struct aio_context *next;
-};
-
-#define INIT_AIO_CONTEXT { .reply_fd   = -1, \
-                          .next        = NULL }
-
-extern int submit_aio(enum aio_type type, int fd, char *buf, int len,
-                     unsigned long long offset, int reply_fd,
-                      struct aio_context *aio);
-
-#endif
index 6f6e7896e53f4ea1f7141b1cbbec9de266108498..ce169ea87e6189e6ca025a41711638ab5ff9d483 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/initrd.h>
 #include <asm/types.h>
 #include <init.h>
@@ -36,7 +36,7 @@ int __init read_initrd(void)
                return 0;
        }
 
-       area = alloc_bootmem(size);
+       area = memblock_alloc(size, SMP_CACHE_BYTES);
 
        if (load_initrd(initrd, area, size) == -1)
                return 0;
index 6b7f3827d6e4add1993315c220bf96217bfb8986..8360fa3f676df2ec0e051235bb5aebea68cc9f83 100644 (file)
@@ -244,8 +244,7 @@ static void garbage_collect_irq_entries(void)
                        to_free = NULL;
                }
                walk = walk->next;
-               if (to_free != NULL)
-                       kfree(to_free);
+               kfree(to_free);
        }
 }
 
index 3c0e470ea6465872539a37ddab3229ab76eba868..1067469ba2ea54acf89c7ccbe3e4dbd21e2f952e 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/stddef.h>
 #include <linux/module.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
@@ -46,11 +46,11 @@ void __init mem_init(void)
         */
        brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
        map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
-       free_bootmem(__pa(brk_end), uml_reserved - brk_end);
+       memblock_free(__pa(brk_end), uml_reserved - brk_end);
        uml_reserved = brk_end;
 
        /* this will put all low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
        max_low_pfn = totalram_pages;
        max_pfn = totalram_pages;
        mem_init_print_info(NULL);
@@ -64,7 +64,8 @@ void __init mem_init(void)
 static void __init one_page_table_init(pmd_t *pmd)
 {
        if (pmd_none(*pmd)) {
-               pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+               pte_t *pte = (pte_t *) memblock_alloc_low(PAGE_SIZE,
+                                                         PAGE_SIZE);
                set_pmd(pmd, __pmd(_KERNPG_TABLE +
                                           (unsigned long) __pa(pte)));
                if (pte != pte_offset_kernel(pmd, 0))
@@ -75,7 +76,7 @@ static void __init one_page_table_init(pmd_t *pmd)
 static void __init one_md_table_init(pud_t *pud)
 {
 #ifdef CONFIG_3_LEVEL_PGTABLES
-       pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+       pmd_t *pmd_table = (pmd_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
        set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
        if (pmd_table != pmd_offset(pud, 0))
                BUG();
@@ -124,7 +125,7 @@ static void __init fixaddr_user_init( void)
                return;
 
        fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir);
-       v = (unsigned long) alloc_bootmem_low_pages(size);
+       v = (unsigned long) memblock_alloc_low(size, PAGE_SIZE);
        memcpy((void *) v , (void *) FIXADDR_USER_START, size);
        p = __pa(v);
        for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE,
@@ -143,7 +144,8 @@ void __init paging_init(void)
        unsigned long zones_size[MAX_NR_ZONES], vaddr;
        int i;
 
-       empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
+       empty_zero_page = (unsigned long *) memblock_alloc_low(PAGE_SIZE,
+                                                              PAGE_SIZE);
        for (i = 0; i < ARRAY_SIZE(zones_size); i++)
                zones_size[i] = 0;
 
index 296a91a04598b390bff809e0c178be89e4542d4f..5bf56af4d5b9522f2b1284236a516a39dcd37581 100644 (file)
@@ -4,7 +4,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/pfn.h>
index cced829460427180091b494e7eb2c9315dd66d73..0e8b6158f2245aa3babf94e9dfed8ceeb86f13cd 100644 (file)
@@ -19,7 +19,7 @@
 #include <skas.h>
 
 /*
- * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by
+ * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by
  * segv().
  */
 int handle_page_fault(unsigned long address, unsigned long ip,
index ada473bf6f46e536048a8589f7af67edd6048f1a..455b500afe97b93dacfa3e8fbbef26d1274a9525 100644 (file)
@@ -6,18 +6,14 @@
 # Don't instrument UML-specific code
 KCOV_INSTRUMENT                := n
 
-obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
+obj-y = execvp.o file.o helper.o irq.o main.o mem.o process.o \
        registers.o sigio.o signal.o start_up.o time.o tty.o \
        umid.o user_syms.o util.o drivers/ skas/
 
 obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
 
-USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
+USER_OBJS := $(user-objs-y) elf_aux.o execvp.o file.o helper.o irq.o \
        main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
        tty.o umid.o util.o
 
-HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \
-       echo -DHAVE_AIO_ABI )
-CFLAGS_aio.o += $(HAVE_AIO_ABI)
-
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
deleted file mode 100644 (file)
index 014eb35..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#include <unistd.h>
-#include <sched.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <asm/unistd.h>
-#include <aio.h>
-#include <init.h>
-#include <kern_util.h>
-#include <os.h>
-
-struct aio_thread_req {
-       enum aio_type type;
-       int io_fd;
-       unsigned long long offset;
-       char *buf;
-       int len;
-       struct aio_context *aio;
-};
-
-#if defined(HAVE_AIO_ABI)
-#include <linux/aio_abi.h>
-
-/*
- * If we have the headers, we are going to build with AIO enabled.
- * If we don't have aio in libc, we define the necessary stubs here.
- */
-
-#if !defined(HAVE_AIO_LIBC)
-
-static long io_setup(int n, aio_context_t *ctxp)
-{
-       return syscall(__NR_io_setup, n, ctxp);
-}
-
-static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
-{
-       return syscall(__NR_io_submit, ctx, nr, iocbpp);
-}
-
-static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
-                        struct io_event *events, struct timespec *timeout)
-{
-       return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
-}
-
-#endif
-
-/*
- * The AIO_MMAP cases force the mmapped page into memory here
- * rather than in whatever place first touches the data.  I used
- * to do this by touching the page, but that's delicate because
- * gcc is prone to optimizing that away.  So, what's done here
- * is we read from the descriptor from which the page was
- * mapped.  The caller is required to pass an offset which is
- * inside the page that was mapped.  Thus, when the read
- * returns, we know that the page is in the page cache, and
- * that it now backs the mmapped area.
- */
-
-static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
-                 int len, unsigned long long offset, struct aio_context *aio)
-{
-       struct iocb *iocbp = & ((struct iocb) {
-                                   .aio_data       = (unsigned long) aio,
-                                   .aio_fildes     = fd,
-                                   .aio_buf        = (unsigned long) buf,
-                                   .aio_nbytes     = len,
-                                   .aio_offset     = offset
-                            });
-       char c;
-
-       switch (type) {
-       case AIO_READ:
-               iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
-               break;
-       case AIO_WRITE:
-               iocbp->aio_lio_opcode = IOCB_CMD_PWRITE;
-               break;
-       case AIO_MMAP:
-               iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
-               iocbp->aio_buf = (unsigned long) &c;
-               iocbp->aio_nbytes = sizeof(c);
-               break;
-       default:
-               printk(UM_KERN_ERR "Bogus op in do_aio - %d\n", type);
-               return -EINVAL;
-       }
-
-       return (io_submit(ctx, 1, &iocbp) > 0) ? 0 : -errno;
-}
-
-/* Initialized in an initcall and unchanged thereafter */
-static aio_context_t ctx = 0;
-
-static int aio_thread(void *arg)
-{
-       struct aio_thread_reply reply;
-       struct io_event event;
-       int err, n, reply_fd;
-
-       os_fix_helper_signals();
-       while (1) {
-               n = io_getevents(ctx, 1, 1, &event, NULL);
-               if (n < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
-                              "errno = %d\n", errno);
-               }
-               else {
-                       reply = ((struct aio_thread_reply)
-                               { .data = (void *) (long) event.data,
-                                               .err    = event.res });
-                       reply_fd = ((struct aio_context *) reply.data)->reply_fd;
-                       err = write(reply_fd, &reply, sizeof(reply));
-                       if (err != sizeof(reply))
-                               printk(UM_KERN_ERR "aio_thread - write failed, "
-                                      "fd = %d, err = %d\n", reply_fd, errno);
-               }
-       }
-       return 0;
-}
-
-#endif
-
-static int do_not_aio(struct aio_thread_req *req)
-{
-       char c;
-       unsigned long long actual;
-       int n;
-
-       actual = lseek64(req->io_fd, req->offset, SEEK_SET);
-       if (actual != req->offset)
-               return -errno;
-
-       switch (req->type) {
-       case AIO_READ:
-               n = read(req->io_fd, req->buf, req->len);
-               break;
-       case AIO_WRITE:
-               n = write(req->io_fd, req->buf, req->len);
-               break;
-       case AIO_MMAP:
-               n = read(req->io_fd, &c, sizeof(c));
-               break;
-       default:
-               printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
-                      req->type);
-               return -EINVAL;
-       }
-
-       if (n < 0)
-               return -errno;
-       return 0;
-}
-
-/* These are initialized in initcalls and not changed */
-static int aio_req_fd_r = -1;
-static int aio_req_fd_w = -1;
-static int aio_pid = -1;
-static unsigned long aio_stack;
-
-static int not_aio_thread(void *arg)
-{
-       struct aio_thread_req req;
-       struct aio_thread_reply reply;
-       int err;
-
-       os_fix_helper_signals();
-       while (1) {
-               err = read(aio_req_fd_r, &req, sizeof(req));
-               if (err != sizeof(req)) {
-                       if (err < 0)
-                               printk(UM_KERN_ERR "not_aio_thread - "
-                                      "read failed, fd = %d, err = %d\n",
-                                      aio_req_fd_r,
-                                      errno);
-                       else {
-                               printk(UM_KERN_ERR "not_aio_thread - short "
-                                      "read, fd = %d, length = %d\n",
-                                      aio_req_fd_r, err);
-                       }
-                       continue;
-               }
-               err = do_not_aio(&req);
-               reply = ((struct aio_thread_reply) { .data      = req.aio,
-                                                    .err       = err });
-               err = write(req.aio->reply_fd, &reply, sizeof(reply));
-               if (err != sizeof(reply))
-                       printk(UM_KERN_ERR "not_aio_thread - write failed, "
-                              "fd = %d, err = %d\n", req.aio->reply_fd, errno);
-       }
-
-       return 0;
-}
-
-static int init_aio_24(void)
-{
-       int fds[2], err;
-
-       err = os_pipe(fds, 1, 1);
-       if (err)
-               goto out;
-
-       aio_req_fd_w = fds[0];
-       aio_req_fd_r = fds[1];
-
-       err = os_set_fd_block(aio_req_fd_w, 0);
-       if (err)
-               goto out_close_pipe;
-
-       err = run_helper_thread(not_aio_thread, NULL,
-                               CLONE_FILES | CLONE_VM, &aio_stack);
-       if (err < 0)
-               goto out_close_pipe;
-
-       aio_pid = err;
-       goto out;
-
-out_close_pipe:
-       close(fds[0]);
-       close(fds[1]);
-       aio_req_fd_w = -1;
-       aio_req_fd_r = -1;
-out:
-#ifndef HAVE_AIO_ABI
-       printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
-              "build\n");
-#endif
-       printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
-              "I/O thread\n");
-       return 0;
-}
-
-#ifdef HAVE_AIO_ABI
-#define DEFAULT_24_AIO 0
-static int init_aio_26(void)
-{
-       int err;
-
-       if (io_setup(256, &ctx)) {
-               err = -errno;
-               printk(UM_KERN_ERR "aio_thread failed to initialize context, "
-                      "err = %d\n", errno);
-               return err;
-       }
-
-       err = run_helper_thread(aio_thread, NULL,
-                               CLONE_FILES | CLONE_VM, &aio_stack);
-       if (err < 0)
-               return err;
-
-       aio_pid = err;
-
-       printk(UM_KERN_INFO "Using 2.6 host AIO\n");
-       return 0;
-}
-
-static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
-                        unsigned long long offset, struct aio_context *aio)
-{
-       struct aio_thread_reply reply;
-       int err;
-
-       err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
-       if (err) {
-               reply = ((struct aio_thread_reply) { .data = aio,
-                                        .err  = err });
-               err = write(aio->reply_fd, &reply, sizeof(reply));
-               if (err != sizeof(reply)) {
-                       err = -errno;
-                       printk(UM_KERN_ERR "submit_aio_26 - write failed, "
-                              "fd = %d, err = %d\n", aio->reply_fd, -err);
-               }
-               else err = 0;
-       }
-
-       return err;
-}
-
-#else
-#define DEFAULT_24_AIO 1
-static int init_aio_26(void)
-{
-       return -ENOSYS;
-}
-
-static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
-                        unsigned long long offset, struct aio_context *aio)
-{
-       return -ENOSYS;
-}
-#endif
-
-/* Initialized in an initcall and unchanged thereafter */
-static int aio_24 = DEFAULT_24_AIO;
-
-static int __init set_aio_24(char *name, int *add)
-{
-       aio_24 = 1;
-       return 0;
-}
-
-__uml_setup("aio=2.4", set_aio_24,
-"aio=2.4\n"
-"    This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n"
-"    available.  2.4 AIO is a single thread that handles one request at a\n"
-"    time, synchronously.  2.6 AIO is a thread which uses the 2.6 AIO \n"
-"    interface to handle an arbitrary number of pending requests.  2.6 AIO \n"
-"    is not available in tt mode, on 2.4 hosts, or when UML is built with\n"
-"    /usr/include/linux/aio_abi.h not available.  Many distributions don't\n"
-"    include aio_abi.h, so you will need to copy it from a kernel tree to\n"
-"    your /usr/include/linux in order to build an AIO-capable UML\n\n"
-);
-
-static int init_aio(void)
-{
-       int err;
-
-       if (!aio_24) {
-               err = init_aio_26();
-               if (err && (errno == ENOSYS)) {
-                       printk(UM_KERN_INFO "2.6 AIO not supported on the "
-                              "host - reverting to 2.4 AIO\n");
-                       aio_24 = 1;
-               }
-               else return err;
-       }
-
-       if (aio_24)
-               return init_aio_24();
-
-       return 0;
-}
-
-/*
- * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
- * needs to be called when the kernel is running because it calls run_helper,
- * which needs get_free_page.  exit_aio is a __uml_exitcall because the generic
- * kernel does not run __exitcalls on shutdown, and can't because many of them
- * break when called outside of module unloading.
- */
-__initcall(init_aio);
-
-static void exit_aio(void)
-{
-       if (aio_pid != -1) {
-               os_kill_process(aio_pid, 1);
-               free_stack(aio_stack, 0);
-       }
-}
-
-__uml_exitcall(exit_aio);
-
-static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
-                        unsigned long long offset, struct aio_context *aio)
-{
-       struct aio_thread_req req = { .type             = type,
-                                     .io_fd            = io_fd,
-                                     .offset           = offset,
-                                     .buf              = buf,
-                                     .len              = len,
-                                     .aio              = aio,
-       };
-       int err;
-
-       err = write(aio_req_fd_w, &req, sizeof(req));
-       if (err == sizeof(req))
-               err = 0;
-       else err = -errno;
-
-       return err;
-}
-
-int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
-              unsigned long long offset, int reply_fd,
-              struct aio_context *aio)
-{
-       aio->reply_fd = reply_fd;
-       if (aio_24)
-               return submit_aio_24(type, io_fd, buf, len, offset, aio);
-       else
-               return submit_aio_26(type, io_fd, buf, len, offset, aio);
-}
index c94c3bd70ccd797d03a53f7f9b7b5773ff274506..df4a985716eba7047cb0873fcea7fb61a57d7a80 100644 (file)
@@ -610,6 +610,11 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
                fatal_sigsegv();
        }
        longjmp(*switch_buf, 1);
+
+       /* unreachable */
+       printk(UM_KERN_ERR "impossible long jump!");
+       fatal_sigsegv();
+       return 0;
 }
 
 void initial_thread_cb_skas(void (*proc)(void *), void *arg)
index 0c5111b206bd8e8b2cdf7ea87d38ce664eba55f6..a4c05159dca5c29ce4393176e13a61a6ec3fcb84 100644 (file)
@@ -5,8 +5,6 @@ config UNICORE32
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
        select DMA_DIRECT_OPS
-       select HAVE_MEMBLOCK
-       select NO_BOOTMEM
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_BZIP2
index 4eaa4216766772055849a3ffdb1b6e20d30edecb..b772ed1c0f25ab290f2ef37c1057c1fbb56d6914 100644 (file)
 #ifndef __UNICORE_PROCESSOR_H__
 #define __UNICORE_PROCESSOR_H__
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l; })
-
 #ifdef __KERNEL__
 
 #include <asm/ptrace.h>
index 9969ec374abb345abcad9ffd5742f155fae36d37..29b71c68eb7cbcdefde8cd37dcd879895757ab29 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/gfp.h>
 #include <linux/suspend.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index c2bffa5614a48102a1d66a60865a2e3474a49597..4b0cb68c355ac0458653613be25571f557393e04 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/utsname.h>
 #include <linux/initrd.h>
 #include <linux/console.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/seq_file.h>
 #include <linux/screen_info.h>
 #include <linux/init.h>
@@ -27,7 +27,6 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
-#include <linux/memblock.h>
 #include <linux/elf.h>
 #include <linux/io.h>
 
@@ -207,7 +206,7 @@ request_standard_resources(struct meminfo *mi)
                if (mi->bank[i].size == 0)
                        continue;
 
-               res = alloc_bootmem_low(sizeof(*res));
+               res = memblock_alloc_low(sizeof(*res), SMP_CACHE_BYTES);
                res->name  = "System RAM";
                res->start = mi->bank[i].start;
                res->end   = mi->bank[i].start + mi->bank[i].size - 1;
index 8f8699e62bd5ac9b4f78916e3e5eec5e14aa9fa9..cf4eb9481fd667358c73f65178b4ee5039f232ec 100644 (file)
 #include <linux/errno.h>
 #include <linux/swap.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
-#include <linux/memblock.h>
 #include <linux/sort.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
@@ -238,7 +237,7 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
         * free the section of the memmap array.
         */
        if (pg < pgend)
-               free_bootmem(pg, pgend - pg);
+               memblock_free(pg, pgend - pg);
 }
 
 /*
@@ -286,7 +285,7 @@ void __init mem_init(void)
        free_unused_memmap(&meminfo);
 
        /* this will put all unused low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 
        mem_init_print_info(NULL);
        printk(KERN_NOTICE "Virtual kernel memory layout:\n"
index 0c94b7b4514dced7d28d3151a6f02081c7efc200..040a8c279761d827a7546960552061ce40cb875c 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/nodemask.h>
 #include <linux/memblock.h>
 #include <linux/fs.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 
 #include <asm/cputype.h>
@@ -144,7 +143,7 @@ static void __init build_mem_type_table(void)
 
 static void __init *early_alloc(unsigned long sz)
 {
-       void *ptr = __va(memblock_alloc(sz, sz));
+       void *ptr = __va(memblock_phys_alloc(sz, sz));
        memset(ptr, 0, sz);
        return ptr;
 }
index cbd5f28ea8e2188638d0c9429cb68ae987adc4f6..c51c989c19c08da99155d354cc11558c1cdb36d4 100644 (file)
@@ -169,7 +169,6 @@ config X86
        select HAVE_KRETPROBES
        select HAVE_KVM
        select HAVE_LIVEPATCH                   if X86_64
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MIXED_BREAKPOINTS_REGS
        select HAVE_MOD_ARCH_SPECIFIC
@@ -186,6 +185,7 @@ config X86
        select HAVE_RCU_TABLE_INVALIDATE        if HAVE_RCU_TABLE_FREE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION
+       select HAVE_FUNCTION_ARG_ACCESS_API
        select HAVE_STACKPROTECTOR              if CC_HAS_SANE_STACKPROTECTOR
        select HAVE_STACK_VALIDATION            if X86_64
        select HAVE_RSEQ
@@ -833,9 +833,6 @@ config JAILHOUSE_GUEST
 
 endif #HYPERVISOR_GUEST
 
-config NO_BOOTMEM
-       def_bool y
-
 source "arch/x86/Kconfig.cpu"
 
 config HPET_TIMER
index 3de0489deadef4e0172e7b418d0dc1edfe749975..5270ff39b9afec2d83385a6eeae2d4777594dde9 100644 (file)
@@ -105,8 +105,10 @@ int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask);
  * the PMIC bus while another driver is also accessing the PMIC bus various bad
  * things happen.
  *
- * To avoid these problems this function must be called before accessing the
- * P-Unit or the PMIC, be it through iosf_mbi* functions or through other means.
+ * Call this function before sending requests to the P-Unit which may make it
+ * access the PMIC, be it through iosf_mbi* functions or through other means.
+ * This function will block all kernel access to the PMIC I2C bus, so that the
+ * P-Unit can safely access the PMIC over the shared I2C bus.
  *
  * Note on these systems the i2c-bus driver will request a sempahore from the
  * P-Unit for exclusive access to the PMIC bus when i2c drivers are accessing
@@ -122,6 +124,31 @@ void iosf_mbi_punit_acquire(void);
  */
 void iosf_mbi_punit_release(void);
 
+/**
+ * iosf_mbi_block_punit_i2c_access() - Block P-Unit accesses to the PMIC bus
+ *
+ * Call this function to block P-Unit access to the PMIC I2C bus, so that the
+ * kernel can safely access the PMIC over the shared I2C bus.
+ *
+ * This function acquires the P-Unit bus semaphore and notifies
+ * pmic_bus_access_notifier listeners that they may no longer access the
+ * P-Unit in a way which may cause it to access the shared I2C bus.
+ *
+ * Note this function may be called multiple times and the bus will not
+ * be released until iosf_mbi_unblock_punit_i2c_access() has been called the
+ * same amount of times.
+ *
+ * Return: Nonzero on error
+ */
+int iosf_mbi_block_punit_i2c_access(void);
+
+/*
+ * iosf_mbi_unblock_punit_i2c_access() - Release PMIC I2C bus block
+ *
+ * Release i2c access block gotten through iosf_mbi_block_punit_i2c_access().
+ */
+void iosf_mbi_unblock_punit_i2c_access(void);
+
 /**
  * iosf_mbi_register_pmic_bus_access_notifier - Register PMIC bus notifier
  *
@@ -158,14 +185,6 @@ int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb);
 int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(
        struct notifier_block *nb);
 
-/**
- * iosf_mbi_call_pmic_bus_access_notifier_chain - Call PMIC bus notifier chain
- *
- * @val: action to pass into listener's notifier_call function
- * @v: data pointer to pass into listener's notifier_call function
- */
-int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v);
-
 /**
  * iosf_mbi_assert_punit_acquired - Assert that the P-Unit has been acquired.
  */
index 5125fca472bb0b44dc8baab1a00e719096e0d8e3..003f2daa3b0fd69b18075542010a5b5aee5b4701 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/string.h>
+#include <linux/kernel.h>
 
 #include <asm/page.h>
 #include <asm/ptrace.h>
@@ -132,7 +133,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
                asm volatile("movl %%cs, %%eax;" :"=a"(newregs->cs));
                asm volatile("pushfq; popq %0" :"=m"(newregs->flags));
 #endif
-               newregs->ip = (unsigned long)current_text_addr();
+               newregs->ip = _THIS_IP_;
        }
 }
 
index 617805981cce159b111ea0afb6b1222b3cf50f60..071b2a6fff85c9a85c3cc5f4f349fb836224254f 100644 (file)
@@ -42,18 +42,6 @@ struct vm86;
 #define NET_IP_ALIGN   0
 
 #define HBP_NUM 4
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-static inline void *current_text_addr(void)
-{
-       void *pc;
-
-       asm volatile("mov $1f, %0; 1:":"=r" (pc));
-
-       return pc;
-}
 
 /*
  * These alignment constraints are for performance in the vSMP case,
index 143c99499531cc1b0f7d50a7190d211664b7bd8b..8a7fc0cca2d17fde3258d00326327f9ec765c969 100644 (file)
@@ -286,6 +286,44 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
        return 0;
 }
 
+/**
+ * regs_get_kernel_argument() - get Nth function argument in kernel
+ * @regs:      pt_regs of that context
+ * @n:         function argument number (start from 0)
+ *
+ * regs_get_argument() returns @n th argument of the function call.
+ * Note that this chooses most probably assignment, in some case
+ * it can be incorrect.
+ * This is expected to be called from kprobes or ftrace with regs
+ * where the top of stack is the return address.
+ */
+static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
+                                                    unsigned int n)
+{
+       static const unsigned int argument_offs[] = {
+#ifdef __i386__
+               offsetof(struct pt_regs, ax),
+               offsetof(struct pt_regs, cx),
+               offsetof(struct pt_regs, dx),
+#define NR_REG_ARGUMENTS 3
+#else
+               offsetof(struct pt_regs, di),
+               offsetof(struct pt_regs, si),
+               offsetof(struct pt_regs, dx),
+               offsetof(struct pt_regs, cx),
+               offsetof(struct pt_regs, r8),
+               offsetof(struct pt_regs, r9),
+#define NR_REG_ARGUMENTS 6
+#endif
+       };
+
+       if (n >= NR_REG_ARGUMENTS) {
+               n -= NR_REG_ARGUMENTS - 1;
+               return regs_get_kernel_stack_nth(regs, n);
+       } else
+               return regs_get_register(regs, argument_offs[n]);
+}
+
 #define arch_has_single_step() (1)
 #ifdef CONFIG_X86_DEBUGCTLMSR
 #define arch_has_block_step()  (1)
index e8fea7ffa30654b59dda3602ada19588c5476dc1..92c76bf97ad828436405ce27398d48ce25132f65 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/dmi.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/efi-bgrt.h>
@@ -933,7 +933,8 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table)
         * the resource tree during the lateinit timeframe.
         */
 #define HPET_RESOURCE_NAME_SIZE 9
-       hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE);
+       hpet_res = memblock_alloc(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE,
+                                 SMP_CACHE_BYTES);
 
        hpet_res->name = (void *)&hpet_res[1];
        hpet_res->flags = IORESOURCE_MEM;
index f1915b7440522a82642a0b3369df1a570d8c834a..ca13851f05701387d5faa8bc57eb04fd9b513a9a 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/dmi.h>
 #include <linux/cpumask.h>
index ab731ab09f06d1cff436f3b94cb363fb6c271e7b..32b2b7a41ef5d37d7bad942435341a15fa046aba 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/acpi_pmtmr.h>
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ftrace.h>
 #include <linux/ioport.h>
 #include <linux/export.h>
index ff0d14cd9e827ef78b1ee4c8fdcebf08c56dfe71..2953bbf05c0857e36fc11ec7a7ae272e9e63bb63 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/kthread.h>
 #include <linux/jiffies.h>     /* time_after() */
 #include <linux/slab.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/irqdomain.h>
 #include <asm/io.h>
@@ -2578,7 +2578,7 @@ static struct resource * __init ioapic_setup_resources(void)
        n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
        n *= nr_ioapics;
 
-       mem = alloc_bootmem(n);
+       mem = memblock_alloc(n, SMP_CACHE_BYTES);
        res = (void *)mem;
 
        mem += sizeof(struct resource) * nr_ioapics;
@@ -2621,7 +2621,8 @@ void __init io_apic_init_mappings(void)
 #ifdef CONFIG_X86_32
 fake_ioapic_page:
 #endif
-                       ioapic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+                       ioapic_phys = (unsigned long)memblock_alloc(PAGE_SIZE,
+                                                                   PAGE_SIZE);
                        ioapic_phys = __pa(ioapic_phys);
                }
                set_fixmap_nocache(idx, ioapic_phys);
index 660d0b22e962e83b1026743d37f1194d95ed46e0..cbbd57ae06ee2af4b1028c95462209a2c348306f 100644 (file)
@@ -1,7 +1,7 @@
 /* cpu_feature_enabled() cannot be used this early */
 #define USE_EARLY_PGTABLE_L5
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/linkage.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
index d1f25c83144752272401afe8c8aec313d40298ae..50895c2f937d144f9fd2b133c0522aadc7841c9e 100644 (file)
@@ -9,11 +9,10 @@
  * allocation code routines via a platform independent interface (memblock, etc.).
  */
 #include <linux/crash_dump.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/suspend.h>
 #include <linux/acpi.h>
 #include <linux/firmware-map.h>
-#include <linux/memblock.h>
 #include <linux/sort.h>
 
 #include <asm/e820/api.h>
@@ -1094,7 +1093,8 @@ void __init e820__reserve_resources(void)
        struct resource *res;
        u64 end;
 
-       res = alloc_bootmem(sizeof(*res) * e820_table->nr_entries);
+       res = memblock_alloc(sizeof(*res) * e820_table->nr_entries,
+                            SMP_CACHE_BYTES);
        e820_res = res;
 
        for (i = 0; i < e820_table->nr_entries; i++) {
index f1c5eb99d445407a9fc134e76a8010d17a61d780..3482460d984d0395830c6227a39e639a5aa87b07 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
index 7ba73fe0d917de810abf81b3f344f2b68fa2c491..f4562fcec6815baaef955da689b01942d4995347 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/export.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/gfp.h>
 #include <linux/pci.h>
 
index 71c0b01d93b1b3d1befa524c31ecc88ae65f0b82..bd08b9e1c9e2a641209805b96c502eeb6523acdc 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/cache.h>
 #include <linux/init.h>
 #include <linux/swiotlb.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/dma-direct.h>
 #include <linux/mem_encrypt.h>
 
index 637982efecd80cbee7964f3473367cbfbd96191d..9b158b4716d29cc5f87f338b73ff7f39b58e4830 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/notifier.h>
 #include <linux/sched.h>
 #include <linux/gfp.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/nmi.h>
 
 #include <asm/fixmap.h>
index 7005f89bf3b22f21b7952c6f5a97951fc61045ec..b74e7bfed6ab40826b782f495324e2782963abb4 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/sfi.h>
 #include <linux/apm_bios.h>
 #include <linux/initrd.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/seq_file.h>
 #include <linux/console.h>
index ea554f812ee18e46289bb1fc9b65cc7408189a74..e8796fcd7e5a5ec2be8608a7c43ba78fc34b4e6f 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/percpu.h>
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
@@ -106,20 +106,22 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
        void *ptr;
 
        if (!node_online(node) || !NODE_DATA(node)) {
-               ptr = __alloc_bootmem_nopanic(size, align, goal);
+               ptr = memblock_alloc_from_nopanic(size, align, goal);
                pr_info("cpu %d has no node %d or node-local memory\n",
                        cpu, node);
                pr_debug("per cpu data for cpu%d %lu bytes at %016lx\n",
                         cpu, size, __pa(ptr));
        } else {
-               ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node),
-                                                  size, align, goal);
+               ptr = memblock_alloc_try_nid_nopanic(size, align, goal,
+                                                    MEMBLOCK_ALLOC_ACCESSIBLE,
+                                                    node);
+
                pr_debug("per cpu data for cpu%d %lu bytes on node%d at %016lx\n",
                         cpu, size, node, __pa(ptr));
        }
        return ptr;
 #else
-       return __alloc_bootmem_nopanic(size, align, goal);
+       return memblock_alloc_from_nopanic(size, align, goal);
 #endif
 }
 
@@ -133,7 +135,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
 
 static void __init pcpu_fc_free(void *ptr, size_t size)
 {
-       free_bootmem(__pa(ptr), size);
+       memblock_free(__pa(ptr), size);
 }
 
 static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
index 5369d7fac7978b9216c43c88931ab66e41a6fac6..a9134d1910b961d16fdbde13a71dd1aac6ffc28f 100644 (file)
@@ -49,7 +49,7 @@
 #include <linux/sched/hotplug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/percpu.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/err.h>
 #include <linux/nmi.h>
 #include <linux/tboot.h>
index f386bad0984ed70f89a432d89b6d90f28bb4eaee..285aaa62d153686c2f91354102c68820405cc757 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <asm/tce.h>
 #include <asm/calgary.h>
 #include <asm/proto.h>
@@ -173,7 +173,7 @@ void * __init alloc_tce_table(void)
        size = table_size_to_number_of_entries(specified_table_size);
        size *= TCE_ENTRY_SIZE;
 
-       return __alloc_bootmem_low(size, size, 0);
+       return memblock_alloc_low(size, size);
 }
 
 void __init free_tce_table(void *tbl)
@@ -186,5 +186,5 @@ void __init free_tce_table(void *tbl)
        size = table_size_to_number_of_entries(specified_table_size);
        size *= TCE_ENTRY_SIZE;
 
-       free_bootmem(__pa(tbl), size);
+       memblock_free(__pa(tbl), size);
 }
index 048c761d97b09539830ad461a12fc1cb3b7f7674..058b2f36b3a6e07f59ca02b6ccba52280694993c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/string.h>
 #include <linux/nodemask.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <linux/pci_ids.h>
index b24eb4eb9984947ea8c5d1951c30e4207d5cbf1b..71d4b9d4d43fdb5efb31287e86aad436b82df654 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/sched/task_stack.h>    /* task_stack_*(), ...          */
 #include <linux/kdebug.h>              /* oops_begin/end, ...          */
 #include <linux/extable.h>             /* search_exception_tables      */
-#include <linux/bootmem.h>             /* max_low_pfn                  */
+#include <linux/memblock.h>            /* max_low_pfn                  */
 #include <linux/kprobes.h>             /* NOKPROBE_SYMBOL, ...         */
 #include <linux/mmiotrace.h>           /* kmmio_handler, ...           */
 #include <linux/perf_event.h>          /* perf_sw_event                */
index 6d18b70ed5a9bb808f2c976450671e7034e3169c..0d4bdcb84da5ab3519ab27402d907adda1abe3bc 100644 (file)
@@ -1,7 +1,7 @@
 #include <linux/highmem.h>
 #include <linux/export.h>
 #include <linux/swap.h> /* for totalram_pages */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 void *kmap(struct page *page)
 {
@@ -111,7 +111,7 @@ void __init set_highmem_pages_init(void)
 
        /*
         * Explicitly reset zone->managed_pages because set_highmem_pages_init()
-        * is invoked before free_all_bootmem()
+        * is invoked before memblock_free_all()
         */
        reset_all_zones_managed_pages();
        for_each_zone(zone) {
index faca978ebf9d8b46b6437f908b9ae506d3489da2..ef99f3892e1faedbf96a935838c248c4801dbc2b 100644 (file)
@@ -3,7 +3,6 @@
 #include <linux/ioport.h>
 #include <linux/swap.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>     /* for max_low_pfn */
 #include <linux/swapfile.h>
 #include <linux/swapops.h>
 
index 142c7d9f89cc218e336cc156f2a14acfa84e565a..49ecf5ecf6d329f82e11e2bf12a71fe739de3545 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/pci.h>
 #include <linux/pfn.h>
 #include <linux/poison.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/proc_fs.h>
 #include <linux/memory_hotplug.h>
@@ -771,7 +770,7 @@ void __init mem_init(void)
 #endif
        /*
         * With CONFIG_DEBUG_PAGEALLOC initialization of highmem pages has to
-        * be done before free_all_bootmem(). Memblock use free low memory for
+        * be done before memblock_free_all(). Memblock use free low memory for
         * temporary data (see find_range_array()) and for this purpose can use
         * pages that was already passed to the buddy allocator, hence marked as
         * not accessible in the page tables when compiled with
@@ -781,7 +780,7 @@ void __init mem_init(void)
        set_highmem_pages_init();
 
        /* this will put all low memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
 
        after_bootmem = 1;
        x86_init.hyper.init_after_bootmem();
index dd519f3721692180b3aac7f5e8eeda52a1d68226..5fab264948c2a2d35b29136d66f24968b44ef7db 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/init.h>
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/proc_fs.h>
 #include <linux/pci.h>
@@ -197,7 +196,7 @@ static __ref void *spp_getpage(void)
        if (after_bootmem)
                ptr = (void *) get_zeroed_page(GFP_ATOMIC);
        else
-               ptr = alloc_bootmem_pages(PAGE_SIZE);
+               ptr = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 
        if (!ptr || ((unsigned long)ptr & ~PAGE_MASK)) {
                panic("set_pte_phys: cannot allocate page data %s\n",
@@ -1188,14 +1187,14 @@ void __init mem_init(void)
        /* clear_bss() already clear the empty_zero_page */
 
        /* this will put all memory onto the freelists */
-       free_all_bootmem();
+       memblock_free_all();
        after_bootmem = 1;
        x86_init.hyper.init_after_bootmem();
 
        /*
         * Must be done after boot memory is put on freelist, because here we
         * might set fields in deferred struct pages that have not yet been
-        * initialized, and free_all_bootmem() initializes all the reserved
+        * initialized, and memblock_free_all() initializes all the reserved
         * deferred pages for us.
         */
        register_page_bootmem_info();
index 24e0920a9b25f4e916dd82a42b92a1a5dd6ec2b5..5378d10f1d31d4887dabd469e535372e6ccc2196 100644 (file)
@@ -6,7 +6,7 @@
  * (C) Copyright 1995 1996 Linus Torvalds
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
index e3e77527f8dff8e44bd560d4f62a11ee8cf90c26..04a9cf6b034fe4ec8b0d451416a759e6c21ee051 100644 (file)
@@ -5,10 +5,9 @@
 /* cpu_feature_enabled() cannot be used this early */
 #define USE_EARLY_PGTABLE_L5
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/kasan.h>
 #include <linux/kdebug.h>
-#include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/sched/task.h>
@@ -28,11 +27,11 @@ static p4d_t tmp_p4d_table[MAX_PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE);
 static __init void *early_alloc(size_t size, int nid, bool panic)
 {
        if (panic)
-               return memblock_virt_alloc_try_nid(size, size,
-                       __pa(MAX_DMA_ADDRESS), BOOTMEM_ALLOC_ACCESSIBLE, nid);
+               return memblock_alloc_try_nid(size, size,
+                       __pa(MAX_DMA_ADDRESS), MEMBLOCK_ALLOC_ACCESSIBLE, nid);
        else
-               return memblock_virt_alloc_try_nid_nopanic(size, size,
-                       __pa(MAX_DMA_ADDRESS), BOOTMEM_ALLOC_ACCESSIBLE, nid);
+               return memblock_alloc_try_nid_nopanic(size, size,
+                       __pa(MAX_DMA_ADDRESS), MEMBLOCK_ALLOC_ACCESSIBLE, nid);
 }
 
 static void __init kasan_populate_pmd(pmd_t *pmd, unsigned long addr,
index 61db77b0eda9cecf9b71d38fde99d0febb5eb4ea..3f452ffed7e93f377aa1ae38150a1f2cf7e91a5c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/random.h>
+#include <linux/memblock.h>
 
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
index fa150855647cc9c85ef2e2b126bf30bcaba06994..1308f5408bf74881f89c5b323a465e23ac83177f 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/mmzone.h>
 #include <linux/ctype.h>
@@ -196,7 +195,7 @@ static void __init alloc_node_data(int nid)
         * Allocate node data.  Try node-local memory and then any node.
         * Never allocate in DMA zone.
         */
-       nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
+       nd_pa = memblock_phys_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
        if (!nd_pa) {
                nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
                                              MEMBLOCK_ALLOC_ACCESSIBLE);
index e8a4a09e20f178f7e420fab31b64cc16a02526e7..f2bd3d61e16bb2157ea227d9533fc4845cf1c79e 100644 (file)
@@ -22,7 +22,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/init.h>
 
index 066f3511d5f1fc29069c2a577466c6a1df1f8884..59d80160fa5a2d14b65b4e58ba1313498a1ad48c 100644 (file)
@@ -3,7 +3,7 @@
  * Generic VM initialization for x86-64 NUMA setups.
  * Copyright 2002,2003 Andi Kleen, SuSE Labs.
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include "numa_internal.h"
 
index b54d52a2d00a83a9fa4be8647fe3acf92b81c4c7..a80fdd7fb40f3b25791b2ab816ef068eb2f09170 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/errno.h>
 #include <linux/topology.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <asm/dma.h>
 
 #include "numa_internal.h"
index a25588ad75efef495c4abb9778439da2f7e64a5d..08f8f76a48527b475a5773f9c13488740872c888 100644 (file)
@@ -5,7 +5,7 @@
  * Clears the a test pte bit on random pages in the direct mapping,
  * then reverts and compares page tables forwards and afterwards.
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/kthread.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
index 62bb30b4bd2ab67de5607d27fd2d816f2c947c8a..f799076e3d577065e8c73c12c6cddb0c5d6f6cfe 100644 (file)
@@ -3,7 +3,7 @@
  * Thanks to Ben LaHaise for precious feedback.
  */
 #include <linux/highmem.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
index 3d0c83ef6aab98cde354b86f999eecfca3a38263..08013524fba18ebe2afc44bf798c5ad77839fa0b 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/debugfs.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
index 7f9acb68324ce3c61672f654be80a79b89661b44..bdc98150d4db887ecc43515bb60ae7dd19664ae3 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/mmdebug.h>
 #include <linux/export.h>
 #include <linux/mm.h>
index ed4ac215305d02e578db31ec9ccfd281b1e607fc..8cd66152cdb0e897fd47200109f3928d04ee03d2 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/errno.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/pat.h>
 #include <asm/e820/api.h>
index 9061babfbc83d73b59a1cddb7b954353e3f53c2d..7ae939e353cd97ba649db386a52e79d6cd515ecc 100644 (file)
@@ -36,9 +36,8 @@
 #include <linux/efi.h>
 #include <linux/efi-bgrt.h>
 #include <linux/export.h>
-#include <linux/bootmem.h>
-#include <linux/slab.h>
 #include <linux/memblock.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
 #include <linux/time.h>
index e8da7f492970add0d6c192e02028f0a3ad3794c3..cf0347f61b21c48e4a0507706121ec0b88ef7af5 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/mm.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
 #include <linux/efi.h>
index 669babcaf245a2929eaefc2e09a56c46e75840ae..95e77a667ba5c99c89b9eeeb8a29691e930c4c07 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/efi.h>
 #include <linux/slab.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 
@@ -333,7 +332,7 @@ void __init efi_reserve_boot_services(void)
 
                /*
                 * Because the following memblock_reserve() is paired
-                * with free_bootmem_late() for this region in
+                * with memblock_free_late() for this region in
                 * efi_free_boot_services(), we must be extremely
                 * careful not to reserve, and subsequently free,
                 * critical regions of memory (like the kernel image) or
@@ -364,7 +363,7 @@ void __init efi_reserve_boot_services(void)
                 * doesn't make sense as far as the firmware is
                 * concerned, but it does provide us with a way to tag
                 * those regions that must not be paired with
-                * free_bootmem_late().
+                * memblock_free_late().
                 */
                md->attribute |= EFI_MEMORY_RUNTIME;
        }
@@ -414,7 +413,7 @@ void __init efi_free_boot_services(void)
                        size -= rm_size;
                }
 
-               free_bootmem_late(start, size);
+               memblock_free_late(start, size);
        }
 
        if (!num_entries)
index 6f37a2137a79519c7e55382bf80f1eb098931bbb..2e569d10f2d083c1fbf4fd2125aaec6534861838 100644 (file)
  * enumerate the device using PCI.
  */
 
+#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
 #include <linux/capability.h>
+#include <linux/pm_qos.h>
 
 #include <asm/iosf_mbi.h>
 
-#define PCI_DEVICE_ID_BAYTRAIL         0x0F00
-#define PCI_DEVICE_ID_BRASWELL         0x2280
-#define PCI_DEVICE_ID_QUARK_X1000      0x0958
-#define PCI_DEVICE_ID_TANGIER          0x1170
+#define PCI_DEVICE_ID_INTEL_BAYTRAIL           0x0F00
+#define PCI_DEVICE_ID_INTEL_BRASWELL           0x2280
+#define PCI_DEVICE_ID_INTEL_QUARK_X1000                0x0958
+#define PCI_DEVICE_ID_INTEL_TANGIER            0x1170
 
 static struct pci_dev *mbi_pdev;
 static DEFINE_SPINLOCK(iosf_mbi_lock);
-static DEFINE_MUTEX(iosf_mbi_punit_mutex);
-static BLOCKING_NOTIFIER_HEAD(iosf_mbi_pmic_bus_access_notifier);
+
+/**************** Generic iosf_mbi access helpers ****************/
 
 static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset)
 {
@@ -192,6 +194,30 @@ bool iosf_mbi_available(void)
 }
 EXPORT_SYMBOL(iosf_mbi_available);
 
+/*
+ **************** P-Unit/kernel shared I2C bus arbritration ****************
+ *
+ * Some Bay Trail and Cherry Trail devices have the P-Unit and us (the kernel)
+ * share a single I2C bus to the PMIC. Below are helpers to arbitrate the
+ * accesses between the kernel and the P-Unit.
+ *
+ * See arch/x86/include/asm/iosf_mbi.h for kernel-doc text for each function.
+ */
+
+#define SEMAPHORE_TIMEOUT              500
+#define PUNIT_SEMAPHORE_BYT            0x7
+#define PUNIT_SEMAPHORE_CHT            0x10e
+#define PUNIT_SEMAPHORE_BIT            BIT(0)
+#define PUNIT_SEMAPHORE_ACQUIRE                BIT(1)
+
+static DEFINE_MUTEX(iosf_mbi_punit_mutex);
+static DEFINE_MUTEX(iosf_mbi_block_punit_i2c_access_count_mutex);
+static BLOCKING_NOTIFIER_HEAD(iosf_mbi_pmic_bus_access_notifier);
+static u32 iosf_mbi_block_punit_i2c_access_count;
+static u32 iosf_mbi_sem_address;
+static unsigned long iosf_mbi_sem_acquired;
+static struct pm_qos_request iosf_mbi_pm_qos;
+
 void iosf_mbi_punit_acquire(void)
 {
        mutex_lock(&iosf_mbi_punit_mutex);
@@ -204,6 +230,159 @@ void iosf_mbi_punit_release(void)
 }
 EXPORT_SYMBOL(iosf_mbi_punit_release);
 
+static int iosf_mbi_get_sem(u32 *sem)
+{
+       int ret;
+
+       ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
+                           iosf_mbi_sem_address, sem);
+       if (ret) {
+               dev_err(&mbi_pdev->dev, "Error P-Unit semaphore read failed\n");
+               return ret;
+       }
+
+       *sem &= PUNIT_SEMAPHORE_BIT;
+       return 0;
+}
+
+static void iosf_mbi_reset_semaphore(void)
+{
+       if (iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ,
+                           iosf_mbi_sem_address, 0, PUNIT_SEMAPHORE_BIT))
+               dev_err(&mbi_pdev->dev, "Error P-Unit semaphore reset failed\n");
+
+       pm_qos_update_request(&iosf_mbi_pm_qos, PM_QOS_DEFAULT_VALUE);
+
+       blocking_notifier_call_chain(&iosf_mbi_pmic_bus_access_notifier,
+                                    MBI_PMIC_BUS_ACCESS_END, NULL);
+}
+
+/*
+ * This function blocks P-Unit accesses to the PMIC I2C bus, so that kernel
+ * I2C code, such as e.g. a fuel-gauge driver, can access it safely.
+ *
+ * This function may be called by I2C controller code while an I2C driver has
+ * already blocked P-Unit accesses because it wants them blocked over multiple
+ * i2c-transfers, for e.g. read-modify-write of an I2C client register.
+ *
+ * The P-Unit accesses already being blocked is tracked through the
+ * iosf_mbi_block_punit_i2c_access_count variable which is protected by the
+ * iosf_mbi_block_punit_i2c_access_count_mutex this mutex is hold for the
+ * entire duration of the function.
+ *
+ * If access is not blocked yet, this function takes the following steps:
+ *
+ * 1) Some code sends request to the P-Unit which make it access the PMIC
+ *    I2C bus. Testing has shown that the P-Unit does not check its internal
+ *    PMIC bus semaphore for these requests. Callers of these requests call
+ *    iosf_mbi_punit_acquire()/_release() around their P-Unit accesses, these
+ *    functions lock/unlock the iosf_mbi_punit_mutex.
+ *    As the first step we lock the iosf_mbi_punit_mutex, to wait for any in
+ *    flight requests to finish and to block any new requests.
+ *
+ * 2) Some code makes such P-Unit requests from atomic contexts where it
+ *    cannot call iosf_mbi_punit_acquire() as that may sleep.
+ *    As the second step we call a notifier chain which allows any code
+ *    needing P-Unit resources from atomic context to acquire them before
+ *    we take control over the PMIC I2C bus.
+ *
+ * 3) When CPU cores enter C6 or C7 the P-Unit needs to talk to the PMIC
+ *    if this happens while the kernel itself is accessing the PMIC I2C bus
+ *    the SoC hangs.
+ *    As the third step we call pm_qos_update_request() to disallow the CPU
+ *    to enter C6 or C7.
+ *
+ * 4) The P-Unit has a PMIC bus semaphore which we can request to stop
+ *    autonomous P-Unit tasks from accessing the PMIC I2C bus while we hold it.
+ *    As the fourth and final step we request this semaphore and wait for our
+ *    request to be acknowledged.
+ */
+int iosf_mbi_block_punit_i2c_access(void)
+{
+       unsigned long start, end;
+       int ret = 0;
+       u32 sem;
+
+       if (WARN_ON(!mbi_pdev || !iosf_mbi_sem_address))
+               return -ENXIO;
+
+       mutex_lock(&iosf_mbi_block_punit_i2c_access_count_mutex);
+
+       if (iosf_mbi_block_punit_i2c_access_count > 0)
+               goto success;
+
+       mutex_lock(&iosf_mbi_punit_mutex);
+       blocking_notifier_call_chain(&iosf_mbi_pmic_bus_access_notifier,
+                                    MBI_PMIC_BUS_ACCESS_BEGIN, NULL);
+
+       /*
+        * Disallow the CPU to enter C6 or C7 state, entering these states
+        * requires the P-Unit to talk to the PMIC and if this happens while
+        * we're holding the semaphore, the SoC hangs.
+        */
+       pm_qos_update_request(&iosf_mbi_pm_qos, 0);
+
+       /* host driver writes to side band semaphore register */
+       ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
+                            iosf_mbi_sem_address, PUNIT_SEMAPHORE_ACQUIRE);
+       if (ret) {
+               dev_err(&mbi_pdev->dev, "Error P-Unit semaphore request failed\n");
+               goto error;
+       }
+
+       /* host driver waits for bit 0 to be set in semaphore register */
+       start = jiffies;
+       end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
+       do {
+               ret = iosf_mbi_get_sem(&sem);
+               if (!ret && sem) {
+                       iosf_mbi_sem_acquired = jiffies;
+                       dev_dbg(&mbi_pdev->dev, "P-Unit semaphore acquired after %ums\n",
+                               jiffies_to_msecs(jiffies - start));
+                       /*
+                        * Success, keep iosf_mbi_punit_mutex locked till
+                        * iosf_mbi_unblock_punit_i2c_access() gets called.
+                        */
+                       goto success;
+               }
+
+               usleep_range(1000, 2000);
+       } while (time_before(jiffies, end));
+
+       ret = -ETIMEDOUT;
+       dev_err(&mbi_pdev->dev, "Error P-Unit semaphore timed out, resetting\n");
+error:
+       iosf_mbi_reset_semaphore();
+       mutex_unlock(&iosf_mbi_punit_mutex);
+
+       if (!iosf_mbi_get_sem(&sem))
+               dev_err(&mbi_pdev->dev, "P-Unit semaphore: %d\n", sem);
+success:
+       if (!WARN_ON(ret))
+               iosf_mbi_block_punit_i2c_access_count++;
+
+       mutex_unlock(&iosf_mbi_block_punit_i2c_access_count_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL(iosf_mbi_block_punit_i2c_access);
+
+void iosf_mbi_unblock_punit_i2c_access(void)
+{
+       mutex_lock(&iosf_mbi_block_punit_i2c_access_count_mutex);
+
+       iosf_mbi_block_punit_i2c_access_count--;
+       if (iosf_mbi_block_punit_i2c_access_count == 0) {
+               iosf_mbi_reset_semaphore();
+               mutex_unlock(&iosf_mbi_punit_mutex);
+               dev_dbg(&mbi_pdev->dev, "punit semaphore held for %ums\n",
+                       jiffies_to_msecs(jiffies - iosf_mbi_sem_acquired));
+       }
+
+       mutex_unlock(&iosf_mbi_block_punit_i2c_access_count_mutex);
+}
+EXPORT_SYMBOL(iosf_mbi_unblock_punit_i2c_access);
+
 int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb)
 {
        int ret;
@@ -241,19 +420,14 @@ int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier);
 
-int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v)
-{
-       return blocking_notifier_call_chain(
-                               &iosf_mbi_pmic_bus_access_notifier, val, v);
-}
-EXPORT_SYMBOL(iosf_mbi_call_pmic_bus_access_notifier_chain);
-
 void iosf_mbi_assert_punit_acquired(void)
 {
        WARN_ON(!mutex_is_locked(&iosf_mbi_punit_mutex));
 }
 EXPORT_SYMBOL(iosf_mbi_assert_punit_acquired);
 
+/**************** iosf_mbi debug code ****************/
+
 #ifdef CONFIG_IOSF_MBI_DEBUG
 static u32     dbg_mdr;
 static u32     dbg_mcr;
@@ -338,7 +512,7 @@ static inline void iosf_debugfs_remove(void) { }
 #endif /* CONFIG_IOSF_MBI_DEBUG */
 
 static int iosf_mbi_probe(struct pci_dev *pdev,
-                         const struct pci_device_id *unused)
+                         const struct pci_device_id *dev_id)
 {
        int ret;
 
@@ -349,14 +523,16 @@ static int iosf_mbi_probe(struct pci_dev *pdev,
        }
 
        mbi_pdev = pci_dev_get(pdev);
+       iosf_mbi_sem_address = dev_id->driver_data;
+
        return 0;
 }
 
 static const struct pci_device_id iosf_mbi_pci_ids[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BAYTRAIL) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRASWELL) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_QUARK_X1000) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_TANGIER) },
+       { PCI_DEVICE_DATA(INTEL, BAYTRAIL, PUNIT_SEMAPHORE_BYT) },
+       { PCI_DEVICE_DATA(INTEL, BRASWELL, PUNIT_SEMAPHORE_CHT) },
+       { PCI_DEVICE_DATA(INTEL, QUARK_X1000, 0) },
+       { PCI_DEVICE_DATA(INTEL, TANGIER, 0) },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, iosf_mbi_pci_ids);
@@ -371,6 +547,9 @@ static int __init iosf_mbi_init(void)
 {
        iosf_debugfs_init();
 
+       pm_qos_add_request(&iosf_mbi_pm_qos, PM_QOS_CPU_DMA_LATENCY,
+                          PM_QOS_DEFAULT_VALUE);
+
        return pci_register_driver(&iosf_mbi_pci_driver);
 }
 
@@ -381,6 +560,8 @@ static void __exit iosf_mbi_exit(void)
        pci_unregister_driver(&iosf_mbi_pci_driver);
        pci_dev_put(mbi_pdev);
        mbi_pdev = NULL;
+
+       pm_qos_remove_request(&iosf_mbi_pm_qos);
 }
 
 module_init(iosf_mbi_init);
index d6ee9298692006115edb0c8e7124e7e24d4f9edc..24d2175a948038a530078540e3e412240d32706e 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_pdt.h>
@@ -141,7 +141,7 @@ void * __init prom_early_alloc(unsigned long size)
                 * fast enough on the platforms we care about while minimizing
                 * wasted bootmem) and hand off chunks of it to callers.
                 */
-               res = alloc_bootmem(chunk_size);
+               res = memblock_alloc(chunk_size, SMP_CACHE_BYTES);
                BUG_ON(!res);
                prom_early_allocated += chunk_size;
                memset(res, 0, chunk_size);
index 15695e30f982e633ca7c74a605ff08927caec888..be15bdcb20df07105597e45a6491f62a3c2c0ab0 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <linux/gfp.h>
 #include <linux/suspend.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index c112de81c9e19860fe59087a653697a5d2afb5e1..5fb1b8449adf611861f9dae7232547b1925aa600 100644 (file)
@@ -47,14 +47,6 @@ static inline void arch_copy_thread(struct arch_thread *from,
         memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array));
 }
 
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter"). Stolen
- * from asm-i386/processor.h
- */
-#define current_text_addr() \
-       ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
-
 #define current_sp() ({ void *sp; __asm__("movl %%esp, %0" : "=r" (sp) : ); sp; })
 #define current_bp() ({ unsigned long bp; __asm__("movl %%ebp, %0" : "=r" (bp) : ); bp; })
 
index c3be85205a6599402d4343c8c2554bb9722a5e54..1ef9c21877bc8580b93dac4800b31cfb405edfc7 100644 (file)
@@ -31,9 +31,6 @@ static inline void arch_copy_thread(struct arch_thread *from,
        to->fs = from->fs;
 }
 
-#define current_text_addr() \
-       ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; })
-
 #define current_sp() ({ void *sp; __asm__("movq %%rsp, %0" : "=r" (sp) : ); sp; })
 #define current_bp() ({ unsigned long bp; __asm__("movq %%rbp, %0" : "=r" (bp) : ); bp; })
 
index b94a108de1dc894e77c9e49310e4d0a12d177ce8..db8478a83a09700065b62e1795c2e796c04de608 100644 (file)
@@ -8,22 +8,10 @@
 
 #define MAX_FP_NR HOST_FPX_SIZE
 
-static inline void update_debugregs(int seq) {}
-
-/* syscall emulation path in ptrace */
-
-#ifndef PTRACE_SYSEMU
-#define PTRACE_SYSEMU 31
-#endif
-
 void set_using_sysemu(int value);
 int get_using_sysemu(void);
 extern int sysemu_supported;
 
-#ifndef PTRACE_SYSEMU_SINGLESTEP
-#define PTRACE_SYSEMU_SINGLESTEP 32
-#endif
-
 #define UPT_SYSCALL_ARG1(r) UPT_BX(r)
 #define UPT_SYSCALL_ARG2(r) UPT_CX(r)
 #define UPT_SYSCALL_ARG3(r) UPT_DX(r)
index 67b2f31a1265f3d6db430974428f8cbdef56150d..e996e8e744cbab90ecaca0ea17f07048465e208b 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #endif
 #include <linux/cpu.h>
 #include <linux/kexec.h>
index ec7a4209f3107ea5c4063db67dfb07f30efa933f..2f6787fc710660aae1598c8e245d04101f77cb18 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/start_kernel.h>
 #include <linux/sched.h>
 #include <linux/kprobes.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/page-flags.h>
@@ -31,7 +31,6 @@
 #include <linux/console.h>
 #include <linux/pci.h>
 #include <linux/gfp.h>
-#include <linux/memblock.h>
 #include <linux/edd.h>
 #include <linux/frame.h>
 
index 70ea598a37d2d525e42566bc0d86c89fdac3d79d..0d7b3ae4960bb0cc424cdc853cdf2f35a73835ae 100644 (file)
@@ -864,7 +864,7 @@ static int __init xen_mark_pinned(struct mm_struct *mm, struct page *page,
  * The init_mm pagetable is really pinned as soon as its created, but
  * that's before we have page structures to store the bits.  So do all
  * the book-keeping now once struct pages for allocated pages are
- * initialized. This happens only after free_all_bootmem() is called.
+ * initialized. This happens only after memblock_free_all() is called.
  */
 static void __init xen_after_bootmem(void)
 {
index d6d74efd8912a2e05d4700dc508b2a85f4ff3946..b06731705529b1e4c339bc21db8de0a565acf6d8 100644 (file)
@@ -67,7 +67,7 @@
 #include <linux/hash.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 
@@ -182,7 +182,7 @@ static void p2m_init_identity(unsigned long *p2m, unsigned long pfn)
 static void * __ref alloc_p2m_page(void)
 {
        if (unlikely(!slab_is_available()))
-               return alloc_bootmem_align(PAGE_SIZE, PAGE_SIZE);
+               return memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 
        return (void *)__get_free_page(GFP_KERNEL);
 }
@@ -190,7 +190,7 @@ static void * __ref alloc_p2m_page(void)
 static void __ref free_p2m_page(void *p)
 {
        if (unlikely(!slab_is_available())) {
-               free_bootmem((unsigned long)p, PAGE_SIZE);
+               memblock_free((unsigned long)p, PAGE_SIZE);
                return;
        }
 
index 66ab96a4e2b3e28a41c78fa7bbbbef0bc2e85064..96d7f7d39cb917a0957403aaf59ec8d6339af9a4 100644 (file)
@@ -134,6 +134,10 @@ void xen_unplug_emulated_devices(void)
 {
        int r;
 
+       /* PVH guests don't have emulated devices. */
+       if (xen_pvh_domain())
+               return;
+
        /* user explicitly requested no unplug */
        if (xen_emul_unplug & XEN_UNPLUG_NEVER)
                return;
index 23f6793af88aa75629c2c73a903568b4a68627ac..441c8826216982a4fb9532b68d68a37cbb0d3e05 100644 (file)
@@ -39,34 +39,25 @@ static void xen_qlock_kick(int cpu)
  */
 static void xen_qlock_wait(u8 *byte, u8 val)
 {
+       unsigned long flags;
        int irq = __this_cpu_read(lock_kicker_irq);
 
        /* If kicker interrupts not initialized yet, just spin */
-       if (irq == -1)
+       if (irq == -1 || in_nmi())
                return;
 
-       /* clear pending */
-       xen_clear_irq_pending(irq);
-       barrier();
-
-       /*
-        * We check the byte value after clearing pending IRQ to make sure
-        * that we won't miss a wakeup event because of the clearing.
-        *
-        * The sync_clear_bit() call in xen_clear_irq_pending() is atomic.
-        * So it is effectively a memory barrier for x86.
-        */
-       if (READ_ONCE(*byte) != val)
-               return;
+       /* Guard against reentry. */
+       local_irq_save(flags);
 
-       /*
-        * If an interrupt happens here, it will leave the wakeup irq
-        * pending, which will cause xen_poll_irq() to return
-        * immediately.
-        */
+       /* If irq pending already clear it. */
+       if (xen_test_irq_pending(irq)) {
+               xen_clear_irq_pending(irq);
+       } else if (READ_ONCE(*byte) == val) {
+               /* Block until irq becomes pending (or a spurious wakeup) */
+               xen_poll_irq(irq);
+       }
 
-       /* Block until irq becomes pending (or perhaps a spurious wakeup) */
-       xen_poll_irq(irq);
+       local_irq_restore(flags);
 }
 
 static irqreturn_t dummy_handler(int irq, void *dev_id)
index b0e471506cd8adcb06b3b0f620df5df41b83399b..1f8825bbaffbf7b87557de9ad1f6f1a67823cc4d 100644 (file)
@@ -170,7 +170,7 @@ canary:
        .fill 48, 1, 0
 
 early_stack:
-       .fill 256, 1, 0
+       .fill BOOT_STACK_SIZE, 1, 0
 early_stack_end:
 
        ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,
index ea5d8d03e53b8bfa16a4b5547321f99024631746..60c141af222bc5e05c426e6c0edf976e93c036d0 100644 (file)
@@ -28,13 +28,11 @@ config XTENSA
        select HAVE_FUTEX_CMPXCHG if !MMU
        select HAVE_HW_BREAKPOINT if PERF_EVENTS
        select HAVE_IRQ_TIME_ACCOUNTING
-       select HAVE_MEMBLOCK
        select HAVE_OPROFILE
        select HAVE_PERF_EVENTS
        select HAVE_STACKPROTECTOR
        select IRQ_DOMAIN
        select MODULES_USE_ELF_RELA
-       select NO_BOOTMEM
        select PERF_USE_VMALLOC
        select VIRT_TO_BUS
        help
index e4ccb88b799631102185e21bda4b8a5193a5c5f4..be9bfd9aa865beb554b2b6e7ce92010cf276b927 100644 (file)
@@ -152,14 +152,6 @@ struct thread_struct {
        int align[0] __attribute__ ((aligned(16)));
 };
 
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr()  ({ __label__ _l; _l: &&_l;})
-
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
index ec43609cbfc533c411e6ddb1bbcda8a3089ebf43..6d4a87296c95cc51636f3109bd213732dde5c6d4 100644 (file)
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define TIOCSERCONFIG  _IO('T', 83)
 #define TIOCSERGWILD   _IOR('T', 84,  int)
index 21f13e9aabe1b5f660cdb54b5d077f31c08c8e34..5ca440a7431671628ee87e319da5ac23b42744b4 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <asm/pci-bridge.h>
 #include <asm/platform.h>
index 9220dcde7520cd79e0a7924d8f130a62a0b0866d..b27359e2a464c6836c23df0e5f48da25bc07ed01 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
 
index 34aead7dcb4878bf18f48cc2087fd93b5bee95ca..9750a48f491b19c087b8b1013b4614eaf61e4cac 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
@@ -152,7 +152,7 @@ void __init mem_init(void)
        max_mapnr = max_pfn - ARCH_PFN_OFFSET;
        high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
 
-       free_all_bootmem();
+       memblock_free_all();
 
        mem_init_print_info(NULL);
        pr_info("virtual kernel memory layout:\n"
index 6b532b6bd785e924f4b6e325e44c1e37b5ab2793..6b95ca43aec0f78cd1827824d84b4b3ee5507357 100644 (file)
@@ -8,11 +8,10 @@
  * Copyright (C) 2017 Cadence Design Systems Inc.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init_task.h>
 #include <linux/kasan.h>
 #include <linux/kernel.h>
-#include <linux/memblock.h>
 #include <asm/initialize_mmu.h>
 #include <asm/tlbflush.h>
 #include <asm/traps.h>
@@ -43,7 +42,7 @@ static void __init populate(void *start, void *end)
        unsigned long vaddr = (unsigned long)start;
        pgd_t *pgd = pgd_offset_k(vaddr);
        pmd_t *pmd = pmd_offset(pgd, vaddr);
-       pte_t *pte = memblock_virt_alloc(n_pages * sizeof(pte_t), PAGE_SIZE);
+       pte_t *pte = memblock_alloc(n_pages * sizeof(pte_t), PAGE_SIZE);
 
        pr_debug("%s: %p - %p\n", __func__, start, end);
 
index 9d1ecfc53670876fc7a64c3950388bf547bc1052..a4dcfd39bc5c1c54f170e83c405f51980a8e84f4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Extracted from init.c
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -31,7 +31,7 @@ static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages)
        pr_debug("%s: vaddr: 0x%08lx, n_pages: %ld\n",
                 __func__, vaddr, n_pages);
 
-       pte = alloc_bootmem_low_pages(n_pages * sizeof(pte_t));
+       pte = memblock_alloc_low(n_pages * sizeof(pte_t), PAGE_SIZE);
 
        for (i = 0; i < n_pages; ++i)
                pte_clear(NULL, 0, pte + i);
index d027dddc41cadd6de0bca5b84b5c371d1eadb67e..d052712373b660e78cd4234afcc5fabb1917a830 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/etherdevice.h>
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/platform_device.h>
@@ -646,7 +646,7 @@ static int __init iss_net_setup(char *str)
                return 1;
        }
 
-       new = alloc_bootmem(sizeof(*new));
+       new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES);
        if (new == NULL) {
                pr_err("Alloc_bootmem failed\n");
                return 1;
index 58709e89a8ed1f41ed7acaad204d4d91e973386a..c14cc673976c32e5cb5de099bfa1c7ac8400260b 100644 (file)
@@ -16,7 +16,7 @@
  * option) any later version.
  *
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index ffd459969689df0821bf377d1c433f039d502de1..696c04c1ab6c1f24a426345e2f13a9fc2f848e58 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <linux/blkdev.h>
-#include <linux/bootmem.h>     /* for max_pfn/max_low_pfn */
+#include <linux/memblock.h>    /* for max_pfn/max_low_pfn */
 #include <linux/gcd.h>
 #include <linux/lcm.h>
 #include <linux/jiffies.h>
index ec0d99995f5f0581ebe32928cc8e82acd8773e04..cf49fe02f65cd017eb2132fd3475ba29a5d3cf75 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/init.h>
 #include <linux/hash.h>
 #include <linux/highmem.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/printk.h>
 #include <asm/tlbflush.h>
 
index 365e6c1a729edfaed3d14ed6fa7dad453789d56a..8f3a444c6ea9233a2c0cd116e387a71c65d2360f 100644 (file)
@@ -512,7 +512,7 @@ config CRC_PMIC_OPREGION
 
 config XPOWER_PMIC_OPREGION
        bool "ACPI operation region support for XPower AXP288 PMIC"
-       depends on MFD_AXP20X_I2C
+       depends on MFD_AXP20X_I2C && IOSF_MBI
        help
          This config adds ACPI operation region support for XPower AXP288 PMIC.
 
index 6b0d3ef7309cb710a63b38848ad35b770fed3c1a..8fe0960ea572495d927ead4053c783e23a94631b 100644 (file)
@@ -228,7 +228,7 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
                if (node < 0)
                        node = memory_add_physaddr_to_nid(info->start_addr);
 
-               result = add_memory(node, info->start_addr, info->length);
+               result = __add_memory(node, info->start_addr, info->length);
 
                /*
                 * If the memory block has been used by the kernel, add_memory()
@@ -282,7 +282,7 @@ static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
                        nid = memory_add_physaddr_to_nid(info->start_addr);
 
                acpi_unbind_memory_blocks(info);
-               remove_memory(nid, info->start_addr, info->length);
+               __remove_memory(nid, info->start_addr, info->length);
                list_del(&info->list);
                kfree(info);
        }
index 85167603b9c94318bcef7c260de689c13e4e4545..274699463b4f1eaf10bb01883434d870110a53e0 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/numa.h>
 #include <linux/nodemask.h>
index aadc86db804ce3c2ef68be52f1bb66a9459b8e26..2579675b7082b76e593a095771f50e9c8e07bca9 100644 (file)
@@ -8,8 +8,9 @@
 #include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/mfd/axp20x.h>
-#include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <linux/platform_device.h>
+#include <asm/iosf_mbi.h>
 #include "intel_pmic.h"
 
 #define XPOWER_GPADC_LOW       0x5b
@@ -172,15 +173,21 @@ static int intel_xpower_pmic_get_power(struct regmap *regmap, int reg,
 static int intel_xpower_pmic_update_power(struct regmap *regmap, int reg,
                                          int bit, bool on)
 {
-       int data;
+       int data, ret;
 
        /* GPIO1 LDO regulator needs special handling */
        if (reg == XPOWER_GPI1_CTRL)
                return regmap_update_bits(regmap, reg, GPI1_LDO_MASK,
                                          on ? GPI1_LDO_ON : GPI1_LDO_OFF);
 
-       if (regmap_read(regmap, reg, &data))
-               return -EIO;
+       ret = iosf_mbi_block_punit_i2c_access();
+       if (ret)
+               return ret;
+
+       if (regmap_read(regmap, reg, &data)) {
+               ret = -EIO;
+               goto out;
+       }
 
        if (on)
                data |= BIT(bit);
@@ -188,9 +195,11 @@ static int intel_xpower_pmic_update_power(struct regmap *regmap, int reg,
                data &= ~BIT(bit);
 
        if (regmap_write(regmap, reg, data))
-               return -EIO;
+               ret = -EIO;
+out:
+       iosf_mbi_unblock_punit_i2c_access();
 
-       return 0;
+       return ret;
 }
 
 /**
index a3d012b08fc5cc982e019f7049e90458012c8419..61203eebf3a1ae8cc3e70a7658b49cd39a8f249a 100644 (file)
@@ -31,9 +31,8 @@
 #include <linux/irq.h>
 #include <linux/errno.h>
 #include <linux/acpi.h>
-#include <linux/bootmem.h>
-#include <linux/earlycpio.h>
 #include <linux/memblock.h>
+#include <linux/earlycpio.h>
 #include <linux/initrd.h>
 #include "internal.h"
 
index 817320c7c4c1b72cf248b73a184bc8dee6ef28ac..0e598568264217f13fd515817800ae2bca12ee7c 100644 (file)
@@ -228,7 +228,6 @@ static bool pages_correctly_probed(unsigned long start_pfn)
 /*
  * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is
  * OK to have direct references to sparsemem variables in here.
- * Must already be protected by mem_hotplug_begin().
  */
 static int
 memory_block_action(unsigned long phys_index, unsigned long action, int online_type)
@@ -294,7 +293,6 @@ static int memory_subsys_online(struct device *dev)
        if (mem->online_type < 0)
                mem->online_type = MMOP_ONLINE_KEEP;
 
-       /* Already under protection of mem_hotplug_begin() */
        ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
 
        /* clear online_type */
@@ -341,19 +339,11 @@ store_mem_state(struct device *dev,
                goto err;
        }
 
-       /*
-        * Memory hotplug needs to hold mem_hotplug_begin() for probe to find
-        * the correct memory block to online before doing device_online(dev),
-        * which will take dev->mutex.  Take the lock early to prevent an
-        * inversion, memory_subsys_online() callbacks will be implemented by
-        * assuming it's already protected.
-        */
-       mem_hotplug_begin();
-
        switch (online_type) {
        case MMOP_ONLINE_KERNEL:
        case MMOP_ONLINE_MOVABLE:
        case MMOP_ONLINE_KEEP:
+               /* mem->online_type is protected by device_hotplug_lock */
                mem->online_type = online_type;
                ret = device_online(&mem->dev);
                break;
@@ -364,7 +354,6 @@ store_mem_state(struct device *dev,
                ret = -EINVAL; /* should never happen */
        }
 
-       mem_hotplug_done();
 err:
        unlock_device_hotplug();
 
@@ -519,15 +508,20 @@ memory_probe_store(struct device *dev, struct device_attribute *attr,
        if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
                return -EINVAL;
 
+       ret = lock_device_hotplug_sysfs();
+       if (ret)
+               goto out;
+
        nid = memory_add_physaddr_to_nid(phys_addr);
-       ret = add_memory(nid, phys_addr,
-                        MIN_MEMORY_BLOCK_SIZE * sections_per_block);
+       ret = __add_memory(nid, phys_addr,
+                          MIN_MEMORY_BLOCK_SIZE * sections_per_block);
 
        if (ret)
                goto out;
 
        ret = count;
 out:
+       unlock_device_hotplug();
        return ret;
 }
 
index 23cf4427f425cf12ad90fd38baeb9ae3a9d8e31d..41b91af95afbd31c2220981b7255b4460a03a3ce 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
index 73ed5f3a862dfcde598227671d55c2491d33408b..8e5140bbf24199873d5a62b7a4cf54386f722abe 100644 (file)
@@ -1500,9 +1500,6 @@ rbd_osd_req_create(struct rbd_obj_request *obj_req, unsigned int num_ops)
                        rbd_dev->header.object_prefix, obj_req->ex.oe_objno))
                goto err_req;
 
-       if (ceph_osdc_alloc_messages(req, GFP_NOIO))
-               goto err_req;
-
        return req;
 
 err_req:
@@ -1945,6 +1942,10 @@ static int __rbd_img_fill_request(struct rbd_img_request *img_req)
                }
                if (ret)
                        return ret;
+
+               ret = ceph_osdc_alloc_messages(obj_req->osd_req, GFP_NOIO);
+               if (ret)
+                       return ret;
        }
 
        return 0;
@@ -2374,8 +2375,7 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
        if (!obj_req->osd_req)
                return -ENOMEM;
 
-       ret = osd_req_op_cls_init(obj_req->osd_req, 0, CEPH_OSD_OP_CALL, "rbd",
-                                 "copyup");
+       ret = osd_req_op_cls_init(obj_req->osd_req, 0, "rbd", "copyup");
        if (ret)
                return ret;
 
@@ -2405,6 +2405,10 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes)
                rbd_assert(0);
        }
 
+       ret = ceph_osdc_alloc_messages(obj_req->osd_req, GFP_NOIO);
+       if (ret)
+               return ret;
+
        rbd_obj_request_submit(obj_req);
        return 0;
 }
@@ -3784,10 +3788,6 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
        ceph_oloc_copy(&req->r_base_oloc, oloc);
        req->r_flags = CEPH_OSD_FLAG_READ;
 
-       ret = ceph_osdc_alloc_messages(req, GFP_KERNEL);
-       if (ret)
-               goto out_req;
-
        pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
        if (IS_ERR(pages)) {
                ret = PTR_ERR(pages);
@@ -3798,6 +3798,10 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
        osd_req_op_extent_osd_data_pages(req, 0, pages, buf_len, 0, false,
                                         true);
 
+       ret = ceph_osdc_alloc_messages(req, GFP_KERNEL);
+       if (ret)
+               goto out_req;
+
        ceph_osdc_start_request(osdc, req, false);
        ret = ceph_osdc_wait_request(osdc, req);
        if (ret >= 0)
@@ -6067,7 +6071,7 @@ static ssize_t rbd_remove_single_major(struct bus_type *bus,
  * create control files in sysfs
  * /sys/bus/rbd/...
  */
-static int rbd_sysfs_init(void)
+static int __init rbd_sysfs_init(void)
 {
        int ret;
 
@@ -6082,13 +6086,13 @@ static int rbd_sysfs_init(void)
        return ret;
 }
 
-static void rbd_sysfs_cleanup(void)
+static void __exit rbd_sysfs_cleanup(void)
 {
        bus_unregister(&rbd_bus_type);
        device_unregister(&rbd_root_dev);
 }
 
-static int rbd_slab_init(void)
+static int __init rbd_slab_init(void)
 {
        rbd_assert(!rbd_img_request_cache);
        rbd_img_request_cache = KMEM_CACHE(rbd_img_request, 0);
index 6a94aa6a22c27ce90ab996277bbc3d5c2da50781..d84996a4528ead1c3d38ecdf74922b78c12bc2c1 100644 (file)
@@ -156,9 +156,6 @@ static int __init weim_parse_dt(struct platform_device *pdev,
        }
 
        for_each_available_child_of_node(pdev->dev.of_node, child) {
-               if (!child->name)
-                       continue;
-
                ret = weim_timing_setup(child, base, devtype);
                if (ret)
                        dev_warn(&pdev->dev, "%pOF set timing failed.\n",
index e4fe954e63a9be53b74397c825bf4f57b06dcca5..a3a2d39280d952e5c51d812a041f61916310c318 100644 (file)
@@ -701,69 +701,7 @@ awake:
        return error;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int sysc_suspend(struct device *dev)
-{
-       struct sysc *ddata;
-       int error;
-
-       ddata = dev_get_drvdata(dev);
-
-       if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER |
-                                SYSC_QUIRK_LEGACY_IDLE))
-               return 0;
-
-       if (!ddata->enabled)
-               return 0;
-
-       dev_dbg(ddata->dev, "%s %s\n", __func__,
-               ddata->name ? ddata->name : "");
-
-       error = pm_runtime_put_sync_suspend(dev);
-       if (error < 0) {
-               dev_warn(ddata->dev, "%s not idle %i %s\n",
-                        __func__, error,
-                        ddata->name ? ddata->name : "");
-
-               return 0;
-       }
-
-       ddata->needs_resume = true;
-
-       return 0;
-}
-
-static int sysc_resume(struct device *dev)
-{
-       struct sysc *ddata;
-       int error;
-
-       ddata = dev_get_drvdata(dev);
-
-       if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER |
-                                SYSC_QUIRK_LEGACY_IDLE))
-               return 0;
-
-       if (ddata->needs_resume) {
-               dev_dbg(ddata->dev, "%s %s\n", __func__,
-                       ddata->name ? ddata->name : "");
-
-               error = pm_runtime_get_sync(dev);
-               if (error < 0) {
-                       dev_err(ddata->dev, "%s  error %i %s\n",
-                               __func__, error,
-                                ddata->name ? ddata->name : "");
-
-                       return error;
-               }
-
-               ddata->needs_resume = false;
-       }
-
-       return 0;
-}
-
-static int sysc_noirq_suspend(struct device *dev)
+static int __maybe_unused sysc_noirq_suspend(struct device *dev)
 {
        struct sysc *ddata;
 
@@ -772,21 +710,10 @@ static int sysc_noirq_suspend(struct device *dev)
        if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
                return 0;
 
-       if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER))
-               return 0;
-
-       if (!ddata->enabled)
-               return 0;
-
-       dev_dbg(ddata->dev, "%s %s\n", __func__,
-               ddata->name ? ddata->name : "");
-
-       ddata->needs_resume = true;
-
-       return sysc_runtime_suspend(dev);
+       return pm_runtime_force_suspend(dev);
 }
 
-static int sysc_noirq_resume(struct device *dev)
+static int __maybe_unused sysc_noirq_resume(struct device *dev)
 {
        struct sysc *ddata;
 
@@ -795,24 +722,10 @@ static int sysc_noirq_resume(struct device *dev)
        if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
                return 0;
 
-       if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER))
-               return 0;
-
-       if (ddata->needs_resume) {
-               dev_dbg(ddata->dev, "%s %s\n", __func__,
-                       ddata->name ? ddata->name : "");
-
-               ddata->needs_resume = false;
-
-               return sysc_runtime_resume(dev);
-       }
-
-       return 0;
+       return pm_runtime_force_resume(dev);
 }
-#endif
 
 static const struct dev_pm_ops sysc_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume)
        SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_noirq_suspend, sysc_noirq_resume)
        SET_RUNTIME_PM_OPS(sysc_runtime_suspend,
                           sysc_runtime_resume,
@@ -845,28 +758,8 @@ struct sysc_revision_quirk {
        }
 
 static const struct sysc_revision_quirk sysc_revision_quirks[] = {
-       /* These need to use noirq_suspend */
-       SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-       SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff,
-                  SYSC_QUIRK_RESOURCE_PROVIDER),
-
        /* These drivers need to be fixed to not use pm_runtime_irq_safe() */
-       SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff,
+       SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffff00ff,
                   SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET),
        SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
@@ -881,38 +774,70 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
        /* Some timers on omap4 and later */
-       SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffffffff,
+       SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x50002100, 0xffffffff,
+                  SYSC_QUIRK_LEGACY_IDLE),
+       SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff,
                   SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
        /* Uarts on omap4 and later */
-       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffffffff,
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
                   SYSC_QUIRK_LEGACY_IDLE),
-
-       /* These devices don't yet suspend properly without legacy setting */
-       SYSC_QUIRK("sdio", 0, 0, 0x10, -1, 0x40202301, 0xffffffff,
-                  SYSC_QUIRK_LEGACY_IDLE),
-       SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xffffffff,
-                  SYSC_QUIRK_LEGACY_IDLE),
-       SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0d00, 0xffffffff,
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
 
 #ifdef DEBUG
+       SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0),
+       SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0),
        SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff, 0),
+       SYSC_QUIRK("cm", 0, 0, -1, -1, 0x40000301, 0xffffffff, 0),
+       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, 0, -1, -1, 0x00001401, 0xffffffff, 0),
+       SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0),
+       SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0),
        SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0),
        SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, 0),
+       SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, 0),
        SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0),
        SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0),
+       SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, 0),
+       SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0),
        SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0),
+       SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0),
        SYSC_QUIRK("mcbsp", 0, -1, 0x8c, -1, 0, 0, 0),
+       SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffff00ff, 0),
+       SYSC_QUIRK("mcspi", 0, 0, 0x110, 0x114, 0x40300a0b, 0xffffffff, 0),
        SYSC_QUIRK("mailbox", 0, 0, 0x10, -1, 0x00000400, 0xffffffff, 0),
+       SYSC_QUIRK("m3", 0, 0, -1, -1, 0x5f580105, 0x0fff0f00, 0),
+       SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xfffffff0, 0),
+       SYSC_QUIRK("ocp2scp", 0, 0, -1, -1, 0x50060007, 0xffffffff, 0),
+       SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, 0),
+       SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, 0),
+       SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x00004102, 0xffffffff, 0),
+       SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000400, 0xffffffff, 0),
+       SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0),
+       SYSC_QUIRK("scm", 0, 0, -1, -1, 0x4e8b0100, 0xffffffff, 0),
+       SYSC_QUIRK("scm", 0, 0, -1, -1, 0x4f000100, 0xffffffff, 0),
+       SYSC_QUIRK("scm", 0, 0, -1, -1, 0x40000900, 0xffffffff, 0),
+       SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff, 0),
+       SYSC_QUIRK("sdio", 0, 0, 0x10, -1, 0x40202301, 0xffff0ff0, 0),
+       SYSC_QUIRK("sdio", 0, 0x2fc, 0x110, 0x114, 0x31010000, 0xffffffff, 0),
+       SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff, 0),
        SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40000902, 0xffffffff, 0),
        SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40002903, 0xffffffff, 0),
        SYSC_QUIRK("spinlock", 0, 0, 0x10, -1, 0x50020000, 0xffffffff, 0),
+       SYSC_QUIRK("rng", 0, 0x1fe0, 0x1fe4, -1, 0x00000020, 0xffffffff, 0),
+       SYSC_QUIRK("rtc", 0, 0x74, 0x78, -1, 0x4eb01908, 0xffff00f0, 0),
+       SYSC_QUIRK("timer32k", 0, 0, 0x4, -1, 0x00000060, 0xffffffff, 0),
        SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
        SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
                   0xffffffff, 0),
+       SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 0),
+       SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0),
 #endif
 };
 
@@ -1221,8 +1146,8 @@ static int sysc_child_suspend_noirq(struct device *dev)
        if (!pm_runtime_status_suspended(dev)) {
                error = pm_generic_runtime_suspend(dev);
                if (error) {
-                       dev_warn(dev, "%s busy at %i: %i\n",
-                                __func__, __LINE__, error);
+                       dev_dbg(dev, "%s busy at %i: %i\n",
+                               __func__, __LINE__, error);
 
                        return 0;
                }
index 292056bbb30e91a39d6e0f2d27b41e4f0e907c8c..81cdb4eaca07fe13322e24593123dc0936f6ece1 100644 (file)
@@ -287,6 +287,7 @@ source "drivers/clk/actions/Kconfig"
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
+source "drivers/clk/ingenic/Kconfig"
 source "drivers/clk/keystone/Kconfig"
 source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
@@ -299,5 +300,6 @@ source "drivers/clk/sunxi-ng/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
+source "drivers/clk/zynqmp/Kconfig"
 
 endmenu
index a84c5573cabeae1ede83c2e597e8d310bc98d307..72be7a38cff1e8ab8b73e84ee607983c192e7ce9 100644 (file)
@@ -72,7 +72,8 @@ obj-$(CONFIG_H8300)                   += h8300/
 obj-$(CONFIG_ARCH_HISI)                        += hisilicon/
 obj-y                                  += imgtec/
 obj-$(CONFIG_ARCH_MXC)                 += imx/
-obj-$(CONFIG_MACH_INGENIC)             += ingenic/
+obj-y                                  += ingenic/
+obj-$(CONFIG_ARCH_K3)                  += keystone/
 obj-$(CONFIG_ARCH_KEYSTONE)            += keystone/
 obj-$(CONFIG_MACH_LOONGSON32)          += loongson1/
 obj-y                                  += mediatek/
@@ -108,3 +109,4 @@ obj-$(CONFIG_X86)                   += x86/
 endif
 obj-$(CONFIG_ARCH_ZX)                  += zte/
 obj-$(CONFIG_ARCH_ZYNQ)                        += zynq/
+obj-$(CONFIG_COMMON_CLK_ZYNQMP)         += zynqmp/
index dc38c85a48339cb49325029b4ac2a1f9b9268bbe..04f0a6355726f0503cfd0c4f84747b02a7d06089 100644 (file)
@@ -2,6 +2,7 @@ config CLK_ACTIONS
        bool "Clock driver for Actions Semi SoCs"
        depends on ARCH_ACTIONS || COMPILE_TEST
        select REGMAP_MMIO
+       select RESET_CONTROLLER
        default ARCH_ACTIONS
 
 if CLK_ACTIONS
index 78c17d56f9913c80c778a649ee4ae9b023b6327e..ccfdf9781ceffd65be8a45a12b6321afe9a60e14 100644 (file)
@@ -7,6 +7,7 @@ clk-owl-y                       += owl-divider.o
 clk-owl-y                      += owl-factor.o
 clk-owl-y                      += owl-composite.o
 clk-owl-y                      += owl-pll.o
+clk-owl-y                      += owl-reset.o
 
 # SoC support
 obj-$(CONFIG_CLK_OWL_S700)     += owl-s700.o
index 61c1071b5180a8168cff7382e31f1d81ee536b49..32dd29e0a37e18ea2e160816e618fe58403db097 100644 (file)
@@ -39,7 +39,7 @@ static void owl_clk_set_regmap(const struct owl_clk_desc *desc,
 }
 
 int owl_clk_regmap_init(struct platform_device *pdev,
-                        const struct owl_clk_desc *desc)
+                       struct owl_clk_desc *desc)
 {
        void __iomem *base;
        struct regmap *regmap;
@@ -57,6 +57,7 @@ int owl_clk_regmap_init(struct platform_device *pdev,
        }
 
        owl_clk_set_regmap(desc, regmap);
+       desc->regmap = regmap;
 
        return 0;
 }
index 4fd726ec54a6c1f2e8a48ad8c38d59514aed5393..5a866a8b913dbca3b6f07389ecb540fa039ecdfc 100644 (file)
@@ -26,6 +26,9 @@ struct owl_clk_desc {
        struct owl_clk_common           **clks;
        unsigned long                   num_clks;
        struct clk_hw_onecell_data      *hw_clks;
+       const struct owl_reset_map      *resets;
+       unsigned long                   num_resets;
+       struct regmap                   *regmap;
 };
 
 static inline struct owl_clk_common *
@@ -35,7 +38,7 @@ static inline struct owl_clk_common *
 }
 
 int owl_clk_regmap_init(struct platform_device *pdev,
-                        const struct owl_clk_desc *desc);
+                       struct owl_clk_desc *desc);
 int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks);
 
 #endif /* _OWL_COMMON_H_ */
diff --git a/drivers/clk/actions/owl-reset.c b/drivers/clk/actions/owl-reset.c
new file mode 100644 (file)
index 0000000..203f8f3
--- /dev/null
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// Actions Semi Owl SoCs Reset Management Unit driver
+//
+// Copyright (c) 2018 Linaro Ltd.
+// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include "owl-reset.h"
+
+static int owl_reset_assert(struct reset_controller_dev *rcdev,
+                           unsigned long id)
+{
+       struct owl_reset *reset = to_owl_reset(rcdev);
+       const struct owl_reset_map *map = &reset->reset_map[id];
+
+       return regmap_update_bits(reset->regmap, map->reg, map->bit, 0);
+}
+
+static int owl_reset_deassert(struct reset_controller_dev *rcdev,
+                             unsigned long id)
+{
+       struct owl_reset *reset = to_owl_reset(rcdev);
+       const struct owl_reset_map *map = &reset->reset_map[id];
+
+       return regmap_update_bits(reset->regmap, map->reg, map->bit, map->bit);
+}
+
+static int owl_reset_reset(struct reset_controller_dev *rcdev,
+                          unsigned long id)
+{
+       owl_reset_assert(rcdev, id);
+       udelay(1);
+       owl_reset_deassert(rcdev, id);
+
+       return 0;
+}
+
+static int owl_reset_status(struct reset_controller_dev *rcdev,
+                           unsigned long id)
+{
+       struct owl_reset *reset = to_owl_reset(rcdev);
+       const struct owl_reset_map *map = &reset->reset_map[id];
+       u32 reg;
+       int ret;
+
+       ret = regmap_read(reset->regmap, map->reg, &reg);
+       if (ret)
+               return ret;
+
+       /*
+        * The reset control API expects 0 if reset is not asserted,
+        * which is the opposite of what our hardware uses.
+        */
+       return !(map->bit & reg);
+}
+
+const struct reset_control_ops owl_reset_ops = {
+       .assert         = owl_reset_assert,
+       .deassert       = owl_reset_deassert,
+       .reset          = owl_reset_reset,
+       .status         = owl_reset_status,
+};
diff --git a/drivers/clk/actions/owl-reset.h b/drivers/clk/actions/owl-reset.h
new file mode 100644 (file)
index 0000000..10f5774
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+//
+// Actions Semi Owl SoCs Reset Management Unit driver
+//
+// Copyright (c) 2018 Linaro Ltd.
+// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+#ifndef _OWL_RESET_H_
+#define _OWL_RESET_H_
+
+#include <linux/reset-controller.h>
+
+struct owl_reset_map {
+       u32     reg;
+       u32     bit;
+};
+
+struct owl_reset {
+       struct reset_controller_dev     rcdev;
+       const struct owl_reset_map      *reset_map;
+       struct regmap                   *regmap;
+};
+
+static inline struct owl_reset *to_owl_reset(struct reset_controller_dev *rcdev)
+{
+       return container_of(rcdev, struct owl_reset, rcdev);
+}
+
+extern const struct reset_control_ops owl_reset_ops;
+
+#endif /* _OWL_RESET_H_ */
index 5e9531392ee57cb03a2bb22dbb5e91ac058d7e20..a2f34d13fb54304357eed076ceb11e31863e76d2 100644 (file)
 #include "owl-gate.h"
 #include "owl-mux.h"
 #include "owl-pll.h"
+#include "owl-reset.h"
 
 #include <dt-bindings/clock/actions,s700-cmu.h>
+#include <dt-bindings/reset/actions,s700-reset.h>
 
 #define CMU_COREPLL            (0x0000)
 #define CMU_DEVPLL             (0x0004)
@@ -569,20 +571,69 @@ static struct clk_hw_onecell_data s700_hw_clks = {
                .num    = CLK_NR_CLKS,
 };
 
-static const struct owl_clk_desc s700_clk_desc = {
+static const struct owl_reset_map s700_resets[] = {
+       [RESET_DE]      = { CMU_DEVRST0, BIT(0) },
+       [RESET_LCD0]    = { CMU_DEVRST0, BIT(1) },
+       [RESET_DSI]     = { CMU_DEVRST0, BIT(2) },
+       [RESET_CSI]     = { CMU_DEVRST0, BIT(13) },
+       [RESET_SI]      = { CMU_DEVRST0, BIT(14) },
+       [RESET_I2C0]    = { CMU_DEVRST1, BIT(0) },
+       [RESET_I2C1]    = { CMU_DEVRST1, BIT(1) },
+       [RESET_I2C2]    = { CMU_DEVRST1, BIT(2) },
+       [RESET_I2C3]    = { CMU_DEVRST1, BIT(3) },
+       [RESET_SPI0]    = { CMU_DEVRST1, BIT(4) },
+       [RESET_SPI1]    = { CMU_DEVRST1, BIT(5) },
+       [RESET_SPI2]    = { CMU_DEVRST1, BIT(6) },
+       [RESET_SPI3]    = { CMU_DEVRST1, BIT(7) },
+       [RESET_UART0]   = { CMU_DEVRST1, BIT(8) },
+       [RESET_UART1]   = { CMU_DEVRST1, BIT(9) },
+       [RESET_UART2]   = { CMU_DEVRST1, BIT(10) },
+       [RESET_UART3]   = { CMU_DEVRST1, BIT(11) },
+       [RESET_UART4]   = { CMU_DEVRST1, BIT(12) },
+       [RESET_UART5]   = { CMU_DEVRST1, BIT(13) },
+       [RESET_UART6]   = { CMU_DEVRST1, BIT(14) },
+       [RESET_KEY]     = { CMU_DEVRST1, BIT(24) },
+       [RESET_GPIO]    = { CMU_DEVRST1, BIT(25) },
+       [RESET_AUDIO]   = { CMU_DEVRST1, BIT(29) },
+};
+
+static struct owl_clk_desc s700_clk_desc = {
        .clks       = s700_clks,
        .num_clks   = ARRAY_SIZE(s700_clks),
 
        .hw_clks    = &s700_hw_clks,
+
+       .resets     = s700_resets,
+       .num_resets = ARRAY_SIZE(s700_resets),
 };
 
 static int s700_clk_probe(struct platform_device *pdev)
 {
-       const struct owl_clk_desc *desc;
+       struct owl_clk_desc *desc;
+       struct owl_reset *reset;
+       int ret;
 
        desc = &s700_clk_desc;
        owl_clk_regmap_init(pdev, desc);
 
+       /*
+        * FIXME: Reset controller registration should be moved to
+        * common code, once all SoCs of Owl family supports it.
+        */
+       reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+       if (!reset)
+               return -ENOMEM;
+
+       reset->rcdev.of_node = pdev->dev.of_node;
+       reset->rcdev.ops = &owl_reset_ops;
+       reset->rcdev.nr_resets = desc->num_resets;
+       reset->reset_map = desc->resets;
+       reset->regmap = desc->regmap;
+
+       ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to register reset controller\n");
+
        return owl_clk_probe(&pdev->dev, desc->hw_clks);
 }
 
index 7f60ed6afe639e159c5bf771bfe5cbfccd0e669b..790890978424a241c8229c7592c2843b1fdb694d 100644 (file)
 #include "owl-gate.h"
 #include "owl-mux.h"
 #include "owl-pll.h"
+#include "owl-reset.h"
 
 #include <dt-bindings/clock/actions,s900-cmu.h>
+#include <dt-bindings/reset/actions,s900-reset.h>
 
 #define CMU_COREPLL            (0x0000)
 #define CMU_DEVPLL             (0x0004)
@@ -684,20 +686,100 @@ static struct clk_hw_onecell_data s900_hw_clks = {
        .num    = CLK_NR_CLKS,
 };
 
-static const struct owl_clk_desc s900_clk_desc = {
+static const struct owl_reset_map s900_resets[] = {
+       [RESET_DMAC]            = { CMU_DEVRST0, BIT(0) },
+       [RESET_SRAMI]           = { CMU_DEVRST0, BIT(1) },
+       [RESET_DDR_CTL_PHY]     = { CMU_DEVRST0, BIT(2) },
+       [RESET_NANDC0]          = { CMU_DEVRST0, BIT(3) },
+       [RESET_SD0]             = { CMU_DEVRST0, BIT(4) },
+       [RESET_SD1]             = { CMU_DEVRST0, BIT(5) },
+       [RESET_PCM1]            = { CMU_DEVRST0, BIT(6) },
+       [RESET_DE]              = { CMU_DEVRST0, BIT(7) },
+       [RESET_LVDS]            = { CMU_DEVRST0, BIT(8) },
+       [RESET_SD2]             = { CMU_DEVRST0, BIT(9) },
+       [RESET_DSI]             = { CMU_DEVRST0, BIT(10) },
+       [RESET_CSI0]            = { CMU_DEVRST0, BIT(11) },
+       [RESET_BISP_AXI]        = { CMU_DEVRST0, BIT(12) },
+       [RESET_CSI1]            = { CMU_DEVRST0, BIT(13) },
+       [RESET_GPIO]            = { CMU_DEVRST0, BIT(15) },
+       [RESET_EDP]             = { CMU_DEVRST0, BIT(16) },
+       [RESET_AUDIO]           = { CMU_DEVRST0, BIT(17) },
+       [RESET_PCM0]            = { CMU_DEVRST0, BIT(18) },
+       [RESET_HDE]             = { CMU_DEVRST0, BIT(21) },
+       [RESET_GPU3D_PA]        = { CMU_DEVRST0, BIT(22) },
+       [RESET_IMX]             = { CMU_DEVRST0, BIT(23) },
+       [RESET_SE]              = { CMU_DEVRST0, BIT(24) },
+       [RESET_NANDC1]          = { CMU_DEVRST0, BIT(25) },
+       [RESET_SD3]             = { CMU_DEVRST0, BIT(26) },
+       [RESET_GIC]             = { CMU_DEVRST0, BIT(27) },
+       [RESET_GPU3D_PB]        = { CMU_DEVRST0, BIT(28) },
+       [RESET_DDR_CTL_PHY_AXI] = { CMU_DEVRST0, BIT(29) },
+       [RESET_CMU_DDR]         = { CMU_DEVRST0, BIT(30) },
+       [RESET_DMM]             = { CMU_DEVRST0, BIT(31) },
+       [RESET_USB2HUB]         = { CMU_DEVRST1, BIT(0) },
+       [RESET_USB2HSIC]        = { CMU_DEVRST1, BIT(1) },
+       [RESET_HDMI]            = { CMU_DEVRST1, BIT(2) },
+       [RESET_HDCP2TX]         = { CMU_DEVRST1, BIT(3) },
+       [RESET_UART6]           = { CMU_DEVRST1, BIT(4) },
+       [RESET_UART0]           = { CMU_DEVRST1, BIT(5) },
+       [RESET_UART1]           = { CMU_DEVRST1, BIT(6) },
+       [RESET_UART2]           = { CMU_DEVRST1, BIT(7) },
+       [RESET_SPI0]            = { CMU_DEVRST1, BIT(8) },
+       [RESET_SPI1]            = { CMU_DEVRST1, BIT(9) },
+       [RESET_SPI2]            = { CMU_DEVRST1, BIT(10) },
+       [RESET_SPI3]            = { CMU_DEVRST1, BIT(11) },
+       [RESET_I2C0]            = { CMU_DEVRST1, BIT(12) },
+       [RESET_I2C1]            = { CMU_DEVRST1, BIT(13) },
+       [RESET_USB3]            = { CMU_DEVRST1, BIT(14) },
+       [RESET_UART3]           = { CMU_DEVRST1, BIT(15) },
+       [RESET_UART4]           = { CMU_DEVRST1, BIT(16) },
+       [RESET_UART5]           = { CMU_DEVRST1, BIT(17) },
+       [RESET_I2C2]            = { CMU_DEVRST1, BIT(18) },
+       [RESET_I2C3]            = { CMU_DEVRST1, BIT(19) },
+       [RESET_ETHERNET]        = { CMU_DEVRST1, BIT(20) },
+       [RESET_CHIPID]          = { CMU_DEVRST1, BIT(21) },
+       [RESET_I2C4]            = { CMU_DEVRST1, BIT(22) },
+       [RESET_I2C5]            = { CMU_DEVRST1, BIT(23) },
+       [RESET_CPU_SCNT]        = { CMU_DEVRST1, BIT(30) }
+};
+
+static struct owl_clk_desc s900_clk_desc = {
        .clks       = s900_clks,
        .num_clks   = ARRAY_SIZE(s900_clks),
 
        .hw_clks    = &s900_hw_clks,
+
+       .resets     = s900_resets,
+       .num_resets = ARRAY_SIZE(s900_resets),
 };
 
 static int s900_clk_probe(struct platform_device *pdev)
 {
-       const struct owl_clk_desc *desc;
+       struct owl_clk_desc *desc;
+       struct owl_reset *reset;
+       int ret;
 
        desc = &s900_clk_desc;
        owl_clk_regmap_init(pdev, desc);
 
+       /*
+        * FIXME: Reset controller registration should be moved to
+        * common code, once all SoCs of Owl family supports it.
+        */
+       reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
+       if (!reset)
+               return -ENOMEM;
+
+       reset->rcdev.of_node = pdev->dev.of_node;
+       reset->rcdev.ops = &owl_reset_ops;
+       reset->rcdev.nr_resets = desc->num_resets;
+       reset->reset_map = desc->resets;
+       reset->regmap = desc->regmap;
+
+       ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to register reset controller\n");
+
        return owl_clk_probe(&pdev->dev, desc->hw_clks);
 }
 
index facc169ebb68a256366d93dd9c217549be0da5ad..c75df1cad60e646294a1f5e44871a8c82b2ff6e3 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for at91 specific clk
 #
 
-obj-y += pmc.o sckc.o
+obj-y += pmc.o sckc.o dt-compat.o
 obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
 obj-y += clk-system.o clk-peripheral.o clk-programmable.o
 
@@ -14,3 +14,6 @@ obj-$(CONFIG_HAVE_AT91_SMD)           += clk-smd.o
 obj-$(CONFIG_HAVE_AT91_H32MX)          += clk-h32mx.o
 obj-$(CONFIG_HAVE_AT91_GENERATED_CLK)  += clk-generated.o
 obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK)    += clk-i2s-mux.o
+obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
+obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
+obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
new file mode 100644 (file)
index 0000000..b1af5a3
--- /dev/null
@@ -0,0 +1,494 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+struct sck {
+       char *n;
+       char *p;
+       u8 id;
+};
+
+struct pck {
+       char *n;
+       u8 id;
+};
+
+struct at91sam926x_data {
+       const struct clk_pll_layout *plla_layout;
+       const struct clk_pll_characteristics *plla_characteristics;
+       const struct clk_pll_layout *pllb_layout;
+       const struct clk_pll_characteristics *pllb_characteristics;
+       const struct clk_master_characteristics *mck_characteristics;
+       const struct sck *sck;
+       const struct pck *pck;
+       u8 num_sck;
+       u8 num_pck;
+       u8 num_progck;
+       bool has_slck;
+};
+
+static const struct clk_master_characteristics sam9260_mck_characteristics = {
+       .output = { .min = 0, .max = 105000000 },
+       .divisors = { 1, 2, 4, 0 },
+};
+
+static u8 sam9260_plla_out[] = { 0, 2 };
+
+static u16 sam9260_plla_icpll[] = { 1, 1 };
+
+static struct clk_range sam9260_plla_outputs[] = {
+       { .min = 80000000, .max = 160000000 },
+       { .min = 150000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9260_plla_characteristics = {
+       .input = { .min = 1000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(sam9260_plla_outputs),
+       .output = sam9260_plla_outputs,
+       .icpll = sam9260_plla_icpll,
+       .out = sam9260_plla_out,
+};
+
+static u8 sam9260_pllb_out[] = { 1 };
+
+static u16 sam9260_pllb_icpll[] = { 1 };
+
+static struct clk_range sam9260_pllb_outputs[] = {
+       { .min = 70000000, .max = 130000000 },
+};
+
+static const struct clk_pll_characteristics sam9260_pllb_characteristics = {
+       .input = { .min = 1000000, .max = 5000000 },
+       .num_output = ARRAY_SIZE(sam9260_pllb_outputs),
+       .output = sam9260_pllb_outputs,
+       .icpll = sam9260_pllb_icpll,
+       .out = sam9260_pllb_out,
+};
+
+static const struct sck at91sam9260_systemck[] = {
+       { .n = "uhpck", .p = "usbck",    .id = 6 },
+       { .n = "udpck", .p = "usbck",    .id = 7 },
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+};
+
+static const struct pck at91sam9260_periphck[] = {
+       { .n = "pioA_clk",   .id = 2 },
+       { .n = "pioB_clk",   .id = 3 },
+       { .n = "pioC_clk",   .id = 4 },
+       { .n = "adc_clk",    .id = 5 },
+       { .n = "usart0_clk", .id = 6 },
+       { .n = "usart1_clk", .id = 7 },
+       { .n = "usart2_clk", .id = 8 },
+       { .n = "mci0_clk",   .id = 9 },
+       { .n = "udc_clk",    .id = 10 },
+       { .n = "twi0_clk",   .id = 11 },
+       { .n = "spi0_clk",   .id = 12 },
+       { .n = "spi1_clk",   .id = 13 },
+       { .n = "ssc0_clk",   .id = 14 },
+       { .n = "tc0_clk",    .id = 17 },
+       { .n = "tc1_clk",    .id = 18 },
+       { .n = "tc2_clk",    .id = 19 },
+       { .n = "ohci_clk",   .id = 20 },
+       { .n = "macb0_clk",  .id = 21 },
+       { .n = "isi_clk",    .id = 22 },
+       { .n = "usart3_clk", .id = 23 },
+       { .n = "uart0_clk",  .id = 24 },
+       { .n = "uart1_clk",  .id = 25 },
+       { .n = "tc3_clk",    .id = 26 },
+       { .n = "tc4_clk",    .id = 27 },
+       { .n = "tc5_clk",    .id = 28 },
+};
+
+static struct at91sam926x_data at91sam9260_data = {
+       .plla_layout = &at91rm9200_pll_layout,
+       .plla_characteristics = &sam9260_plla_characteristics,
+       .pllb_layout = &at91rm9200_pll_layout,
+       .pllb_characteristics = &sam9260_pllb_characteristics,
+       .mck_characteristics = &sam9260_mck_characteristics,
+       .sck = at91sam9260_systemck,
+       .num_sck = ARRAY_SIZE(at91sam9260_systemck),
+       .pck = at91sam9260_periphck,
+       .num_pck = ARRAY_SIZE(at91sam9260_periphck),
+       .num_progck = 2,
+       .has_slck = true,
+};
+
+static const struct clk_master_characteristics sam9g20_mck_characteristics = {
+       .output = { .min = 0, .max = 133000000 },
+       .divisors = { 1, 2, 4, 6 },
+};
+
+static u8 sam9g20_plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
+
+static u16 sam9g20_plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
+
+static struct clk_range sam9g20_plla_outputs[] = {
+       { .min = 745000000, .max = 800000000 },
+       { .min = 695000000, .max = 750000000 },
+       { .min = 645000000, .max = 700000000 },
+       { .min = 595000000, .max = 650000000 },
+       { .min = 545000000, .max = 600000000 },
+       { .min = 495000000, .max = 550000000 },
+       { .min = 445000000, .max = 500000000 },
+       { .min = 400000000, .max = 450000000 },
+};
+
+static const struct clk_pll_characteristics sam9g20_plla_characteristics = {
+       .input = { .min = 2000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(sam9g20_plla_outputs),
+       .output = sam9g20_plla_outputs,
+       .icpll = sam9g20_plla_icpll,
+       .out = sam9g20_plla_out,
+};
+
+static u8 sam9g20_pllb_out[] = { 0 };
+
+static u16 sam9g20_pllb_icpll[] = { 0 };
+
+static struct clk_range sam9g20_pllb_outputs[] = {
+       { .min = 30000000, .max = 100000000 },
+};
+
+static const struct clk_pll_characteristics sam9g20_pllb_characteristics = {
+       .input = { .min = 2000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(sam9g20_pllb_outputs),
+       .output = sam9g20_pllb_outputs,
+       .icpll = sam9g20_pllb_icpll,
+       .out = sam9g20_pllb_out,
+};
+
+static struct at91sam926x_data at91sam9g20_data = {
+       .plla_layout = &at91sam9g45_pll_layout,
+       .plla_characteristics = &sam9g20_plla_characteristics,
+       .pllb_layout = &at91sam9g20_pllb_layout,
+       .pllb_characteristics = &sam9g20_pllb_characteristics,
+       .mck_characteristics = &sam9g20_mck_characteristics,
+       .sck = at91sam9260_systemck,
+       .num_sck = ARRAY_SIZE(at91sam9260_systemck),
+       .pck = at91sam9260_periphck,
+       .num_pck = ARRAY_SIZE(at91sam9260_periphck),
+       .num_progck = 2,
+       .has_slck = true,
+};
+
+static const struct clk_master_characteristics sam9261_mck_characteristics = {
+       .output = { .min = 0, .max = 94000000 },
+       .divisors = { 1, 2, 4, 0 },
+};
+
+static struct clk_range sam9261_plla_outputs[] = {
+       { .min = 80000000, .max = 200000000 },
+       { .min = 190000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9261_plla_characteristics = {
+       .input = { .min = 1000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(sam9261_plla_outputs),
+       .output = sam9261_plla_outputs,
+       .icpll = sam9260_plla_icpll,
+       .out = sam9260_plla_out,
+};
+
+static u8 sam9261_pllb_out[] = { 1 };
+
+static u16 sam9261_pllb_icpll[] = { 1 };
+
+static struct clk_range sam9261_pllb_outputs[] = {
+       { .min = 70000000, .max = 130000000 },
+};
+
+static const struct clk_pll_characteristics sam9261_pllb_characteristics = {
+       .input = { .min = 1000000, .max = 5000000 },
+       .num_output = ARRAY_SIZE(sam9261_pllb_outputs),
+       .output = sam9261_pllb_outputs,
+       .icpll = sam9261_pllb_icpll,
+       .out = sam9261_pllb_out,
+};
+
+static const struct sck at91sam9261_systemck[] = {
+       { .n = "uhpck", .p = "usbck",    .id = 6 },
+       { .n = "udpck", .p = "usbck",    .id = 7 },
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+       { .n = "pck2",  .p = "prog2",    .id = 10 },
+       { .n = "pck3",  .p = "prog3",    .id = 11 },
+       { .n = "hclk0", .p = "masterck", .id = 16 },
+       { .n = "hclk1", .p = "masterck", .id = 17 },
+};
+
+static const struct pck at91sam9261_periphck[] = {
+       { .n = "pioA_clk",   .id = 2, },
+       { .n = "pioB_clk",   .id = 3, },
+       { .n = "pioC_clk",   .id = 4, },
+       { .n = "usart0_clk", .id = 6, },
+       { .n = "usart1_clk", .id = 7, },
+       { .n = "usart2_clk", .id = 8, },
+       { .n = "mci0_clk",   .id = 9, },
+       { .n = "udc_clk",    .id = 10, },
+       { .n = "twi0_clk",   .id = 11, },
+       { .n = "spi0_clk",   .id = 12, },
+       { .n = "spi1_clk",   .id = 13, },
+       { .n = "ssc0_clk",   .id = 14, },
+       { .n = "ssc1_clk",   .id = 15, },
+       { .n = "ssc2_clk",   .id = 16, },
+       { .n = "tc0_clk",    .id = 17, },
+       { .n = "tc1_clk",    .id = 18, },
+       { .n = "tc2_clk",    .id = 19, },
+       { .n = "ohci_clk",   .id = 20, },
+       { .n = "lcd_clk",    .id = 21, },
+};
+
+static struct at91sam926x_data at91sam9261_data = {
+       .plla_layout = &at91rm9200_pll_layout,
+       .plla_characteristics = &sam9261_plla_characteristics,
+       .pllb_layout = &at91rm9200_pll_layout,
+       .pllb_characteristics = &sam9261_pllb_characteristics,
+       .mck_characteristics = &sam9261_mck_characteristics,
+       .sck = at91sam9261_systemck,
+       .num_sck = ARRAY_SIZE(at91sam9261_systemck),
+       .pck = at91sam9261_periphck,
+       .num_pck = ARRAY_SIZE(at91sam9261_periphck),
+       .num_progck = 4,
+};
+
+static const struct clk_master_characteristics sam9263_mck_characteristics = {
+       .output = { .min = 0, .max = 120000000 },
+       .divisors = { 1, 2, 4, 0 },
+};
+
+static struct clk_range sam9263_pll_outputs[] = {
+       { .min = 80000000, .max = 200000000 },
+       { .min = 190000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9263_pll_characteristics = {
+       .input = { .min = 1000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(sam9263_pll_outputs),
+       .output = sam9263_pll_outputs,
+       .icpll = sam9260_plla_icpll,
+       .out = sam9260_plla_out,
+};
+
+static const struct sck at91sam9263_systemck[] = {
+       { .n = "uhpck", .p = "usbck",    .id = 6 },
+       { .n = "udpck", .p = "usbck",    .id = 7 },
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+       { .n = "pck2",  .p = "prog2",    .id = 10 },
+       { .n = "pck3",  .p = "prog3",    .id = 11 },
+};
+
+static const struct pck at91sam9263_periphck[] = {
+       { .n = "pioA_clk",   .id = 2, },
+       { .n = "pioB_clk",   .id = 3, },
+       { .n = "pioCDE_clk", .id = 4, },
+       { .n = "usart0_clk", .id = 7, },
+       { .n = "usart1_clk", .id = 8, },
+       { .n = "usart2_clk", .id = 9, },
+       { .n = "mci0_clk",   .id = 10, },
+       { .n = "mci1_clk",   .id = 11, },
+       { .n = "can_clk",    .id = 12, },
+       { .n = "twi0_clk",   .id = 13, },
+       { .n = "spi0_clk",   .id = 14, },
+       { .n = "spi1_clk",   .id = 15, },
+       { .n = "ssc0_clk",   .id = 16, },
+       { .n = "ssc1_clk",   .id = 17, },
+       { .n = "ac97_clk",   .id = 18, },
+       { .n = "tcb_clk",    .id = 19, },
+       { .n = "pwm_clk",    .id = 20, },
+       { .n = "macb0_clk",  .id = 21, },
+       { .n = "g2de_clk",   .id = 23, },
+       { .n = "udc_clk",    .id = 24, },
+       { .n = "isi_clk",    .id = 25, },
+       { .n = "lcd_clk",    .id = 26, },
+       { .n = "dma_clk",    .id = 27, },
+       { .n = "ohci_clk",   .id = 29, },
+};
+
+static struct at91sam926x_data at91sam9263_data = {
+       .plla_layout = &at91rm9200_pll_layout,
+       .plla_characteristics = &sam9263_pll_characteristics,
+       .pllb_layout = &at91rm9200_pll_layout,
+       .pllb_characteristics = &sam9263_pll_characteristics,
+       .mck_characteristics = &sam9263_mck_characteristics,
+       .sck = at91sam9263_systemck,
+       .num_sck = ARRAY_SIZE(at91sam9263_systemck),
+       .pck = at91sam9263_periphck,
+       .num_pck = ARRAY_SIZE(at91sam9263_periphck),
+       .num_progck = 4,
+};
+
+static void __init at91sam926x_pmc_setup(struct device_node *np,
+                                        struct at91sam926x_data *data)
+{
+       const char *slowxtal_name, *mainxtal_name;
+       struct pmc_data *at91sam9260_pmc;
+       u32 usb_div[] = { 1, 2, 4, 0 };
+       const char *parent_names[6];
+       const char *slck_name;
+       struct regmap *regmap;
+       struct clk_hw *hw;
+       int i;
+       bool bypass;
+
+       i = of_property_match_string(np, "clock-names", "slow_xtal");
+       if (i < 0)
+               return;
+
+       slowxtal_name = of_clk_get_parent_name(np, i);
+
+       i = of_property_match_string(np, "clock-names", "main_xtal");
+       if (i < 0)
+               return;
+       mainxtal_name = of_clk_get_parent_name(np, i);
+
+       regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(regmap))
+               return;
+
+       at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
+                                           ndck(data->sck, data->num_sck),
+                                           ndck(data->pck, data->num_pck), 0);
+       if (!at91sam9260_pmc)
+               return;
+
+       bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+       hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
+                                       bypass);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9260_pmc->chws[PMC_MAIN] = hw;
+
+       if (data->has_slck) {
+               hw = clk_hw_register_fixed_rate_with_accuracy(NULL,
+                                                             "slow_rc_osc",
+                                                             NULL, 0, 32768,
+                                                             50000000);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               parent_names[0] = "slow_rc_osc";
+               parent_names[1] = "slow_xtal";
+               hw = at91_clk_register_sam9260_slow(regmap, "slck",
+                                                   parent_names, 2);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9260_pmc->chws[PMC_SLOW] = hw;
+               slck_name = "slck";
+       } else {
+               slck_name = slowxtal_name;
+       }
+
+       hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+                                  data->plla_layout,
+                                  data->plla_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
+                                  data->pllb_layout,
+                                  data->pllb_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "pllack";
+       parent_names[3] = "pllbck";
+       hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+                                     &at91rm9200_master_layout,
+                                     data->mck_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9260_pmc->chws[PMC_MCK] = hw;
+
+       hw = at91rm9200_clk_register_usb(regmap, "usbck", "pllbck", usb_div);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "pllack";
+       parent_names[3] = "pllbck";
+       for (i = 0; i < data->num_progck; i++) {
+               char name[6];
+
+               snprintf(name, sizeof(name), "prog%d", i);
+
+               hw = at91_clk_register_programmable(regmap, name,
+                                                   parent_names, 4, i,
+                                                   &at91rm9200_programmable_layout);
+               if (IS_ERR(hw))
+                       goto err_free;
+       }
+
+       for (i = 0; i < data->num_sck; i++) {
+               hw = at91_clk_register_system(regmap, data->sck[i].n,
+                                             data->sck[i].p,
+                                             data->sck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9260_pmc->shws[data->sck[i].id] = hw;
+       }
+
+       for (i = 0; i < data->num_pck; i++) {
+               hw = at91_clk_register_peripheral(regmap,
+                                                 data->pck[i].n,
+                                                 "masterck",
+                                                 data->pck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9260_pmc->phws[data->pck[i].id] = hw;
+       }
+
+       of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9260_pmc);
+
+       return;
+
+err_free:
+       pmc_data_free(at91sam9260_pmc);
+}
+
+static void __init at91sam9260_pmc_setup(struct device_node *np)
+{
+       at91sam926x_pmc_setup(np, &at91sam9260_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9260_pmc, "atmel,at91sam9260-pmc",
+                     at91sam9260_pmc_setup);
+
+static void __init at91sam9261_pmc_setup(struct device_node *np)
+{
+       at91sam926x_pmc_setup(np, &at91sam9261_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9261_pmc, "atmel,at91sam9261-pmc",
+                     at91sam9261_pmc_setup);
+
+static void __init at91sam9263_pmc_setup(struct device_node *np)
+{
+       at91sam926x_pmc_setup(np, &at91sam9263_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9263_pmc, "atmel,at91sam9263-pmc",
+                     at91sam9263_pmc_setup);
+
+static void __init at91sam9g20_pmc_setup(struct device_node *np)
+{
+       at91sam926x_pmc_setup(np, &at91sam9g20_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g20_pmc, "atmel,at91sam9g20-pmc",
+                     at91sam9g20_pmc_setup);
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
new file mode 100644 (file)
index 0000000..5aeef68
--- /dev/null
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics sam9rl_mck_characteristics = {
+       .output = { .min = 0, .max = 94000000 },
+       .divisors = { 1, 2, 4, 0 },
+};
+
+static u8 sam9rl_plla_out[] = { 0, 2 };
+
+static struct clk_range sam9rl_plla_outputs[] = {
+       { .min = 80000000, .max = 200000000 },
+       { .min = 190000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9rl_plla_characteristics = {
+       .input = { .min = 1000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(sam9rl_plla_outputs),
+       .output = sam9rl_plla_outputs,
+       .out = sam9rl_plla_out,
+};
+
+static const struct {
+       char *n;
+       char *p;
+       u8 id;
+} at91sam9rl_systemck[] = {
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+};
+
+static const struct {
+       char *n;
+       u8 id;
+} at91sam9rl_periphck[] = {
+       { .n = "pioA_clk",   .id = 2, },
+       { .n = "pioB_clk",   .id = 3, },
+       { .n = "pioC_clk",   .id = 4, },
+       { .n = "pioD_clk",   .id = 5, },
+       { .n = "usart0_clk", .id = 6, },
+       { .n = "usart1_clk", .id = 7, },
+       { .n = "usart2_clk", .id = 8, },
+       { .n = "usart3_clk", .id = 9, },
+       { .n = "mci0_clk",   .id = 10, },
+       { .n = "twi0_clk",   .id = 11, },
+       { .n = "twi1_clk",   .id = 12, },
+       { .n = "spi0_clk",   .id = 13, },
+       { .n = "ssc0_clk",   .id = 14, },
+       { .n = "ssc1_clk",   .id = 15, },
+       { .n = "tc0_clk",    .id = 16, },
+       { .n = "tc1_clk",    .id = 17, },
+       { .n = "tc2_clk",    .id = 18, },
+       { .n = "pwm_clk",    .id = 19, },
+       { .n = "adc_clk",    .id = 20, },
+       { .n = "dma0_clk",   .id = 21, },
+       { .n = "udphs_clk",  .id = 22, },
+       { .n = "lcd_clk",    .id = 23, },
+};
+
+static void __init at91sam9rl_pmc_setup(struct device_node *np)
+{
+       const char *slck_name, *mainxtal_name;
+       struct pmc_data *at91sam9rl_pmc;
+       const char *parent_names[6];
+       struct regmap *regmap;
+       struct clk_hw *hw;
+       int i;
+
+       i = of_property_match_string(np, "clock-names", "slow_clk");
+       if (i < 0)
+               return;
+
+       slck_name = of_clk_get_parent_name(np, i);
+
+       i = of_property_match_string(np, "clock-names", "main_xtal");
+       if (i < 0)
+               return;
+       mainxtal_name = of_clk_get_parent_name(np, i);
+
+       regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(regmap))
+               return;
+
+       at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
+                                          nck(at91sam9rl_systemck),
+                                          nck(at91sam9rl_periphck), 0);
+       if (!at91sam9rl_pmc)
+               return;
+
+       hw = at91_clk_register_rm9200_main(regmap, "mainck", mainxtal_name);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9rl_pmc->chws[PMC_MAIN] = hw;
+
+       hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+                                  &at91rm9200_pll_layout,
+                                  &sam9rl_plla_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9rl_pmc->chws[PMC_UTMI] = hw;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "pllack";
+       parent_names[3] = "utmick";
+       hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+                                     &at91rm9200_master_layout,
+                                     &sam9rl_mck_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9rl_pmc->chws[PMC_MCK] = hw;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "pllack";
+       parent_names[3] = "utmick";
+       parent_names[4] = "masterck";
+       for (i = 0; i < 2; i++) {
+               char name[6];
+
+               snprintf(name, sizeof(name), "prog%d", i);
+
+               hw = at91_clk_register_programmable(regmap, name,
+                                                   parent_names, 5, i,
+                                                   &at91rm9200_programmable_layout);
+               if (IS_ERR(hw))
+                       goto err_free;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
+               hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n,
+                                             at91sam9rl_systemck[i].p,
+                                             at91sam9rl_systemck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9rl_pmc->shws[at91sam9rl_systemck[i].id] = hw;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) {
+               hw = at91_clk_register_peripheral(regmap,
+                                                 at91sam9rl_periphck[i].n,
+                                                 "masterck",
+                                                 at91sam9rl_periphck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9rl_pmc->phws[at91sam9rl_periphck[i].id] = hw;
+       }
+
+       of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9rl_pmc);
+
+       return;
+
+err_free:
+       pmc_data_free(at91sam9rl_pmc);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
new file mode 100644 (file)
index 0000000..2fe225a
--- /dev/null
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics mck_characteristics = {
+       .output = { .min = 0, .max = 133333333 },
+       .divisors = { 1, 2, 4, 3 },
+       .have_div3_pres = 1,
+};
+
+static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
+
+static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
+
+static struct clk_range plla_outputs[] = {
+       { .min = 745000000, .max = 800000000 },
+       { .min = 695000000, .max = 750000000 },
+       { .min = 645000000, .max = 700000000 },
+       { .min = 595000000, .max = 650000000 },
+       { .min = 545000000, .max = 600000000 },
+       { .min = 495000000, .max = 555000000 },
+       { .min = 445000000, .max = 500000000 },
+       { .min = 400000000, .max = 450000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+       .input = { .min = 2000000, .max = 32000000 },
+       .num_output = ARRAY_SIZE(plla_outputs),
+       .output = plla_outputs,
+       .icpll = plla_icpll,
+       .out = plla_out,
+};
+
+static const struct {
+       char *n;
+       char *p;
+       u8 id;
+} at91sam9x5_systemck[] = {
+       { .n = "ddrck", .p = "masterck", .id = 2 },
+       { .n = "smdck", .p = "smdclk",   .id = 4 },
+       { .n = "uhpck", .p = "usbck",    .id = 6 },
+       { .n = "udpck", .p = "usbck",    .id = 7 },
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+};
+
+struct pck {
+       char *n;
+       u8 id;
+};
+
+static const struct pck at91sam9x5_periphck[] = {
+       { .n = "pioAB_clk",  .id = 2, },
+       { .n = "pioCD_clk",  .id = 3, },
+       { .n = "smd_clk",    .id = 4, },
+       { .n = "usart0_clk", .id = 5, },
+       { .n = "usart1_clk", .id = 6, },
+       { .n = "usart2_clk", .id = 7, },
+       { .n = "twi0_clk",   .id = 9, },
+       { .n = "twi1_clk",   .id = 10, },
+       { .n = "twi2_clk",   .id = 11, },
+       { .n = "mci0_clk",   .id = 12, },
+       { .n = "spi0_clk",   .id = 13, },
+       { .n = "spi1_clk",   .id = 14, },
+       { .n = "uart0_clk",  .id = 15, },
+       { .n = "uart1_clk",  .id = 16, },
+       { .n = "tcb0_clk",   .id = 17, },
+       { .n = "pwm_clk",    .id = 18, },
+       { .n = "adc_clk",    .id = 19, },
+       { .n = "dma0_clk",   .id = 20, },
+       { .n = "dma1_clk",   .id = 21, },
+       { .n = "uhphs_clk",  .id = 22, },
+       { .n = "udphs_clk",  .id = 23, },
+       { .n = "mci1_clk",   .id = 26, },
+       { .n = "ssc0_clk",   .id = 28, },
+};
+
+static const struct pck at91sam9g15_periphck[] = {
+       { .n = "lcdc_clk", .id = 25, },
+       { /* sentinel */}
+};
+
+static const struct pck at91sam9g25_periphck[] = {
+       { .n = "usart3_clk", .id = 8, },
+       { .n = "macb0_clk", .id = 24, },
+       { .n = "isi_clk", .id = 25, },
+       { /* sentinel */}
+};
+
+static const struct pck at91sam9g35_periphck[] = {
+       { .n = "macb0_clk", .id = 24, },
+       { .n = "lcdc_clk", .id = 25, },
+       { /* sentinel */}
+};
+
+static const struct pck at91sam9x25_periphck[] = {
+       { .n = "usart3_clk", .id = 8, },
+       { .n = "macb0_clk", .id = 24, },
+       { .n = "macb1_clk", .id = 27, },
+       { .n = "can0_clk", .id = 29, },
+       { .n = "can1_clk", .id = 30, },
+       { /* sentinel */}
+};
+
+static const struct pck at91sam9x35_periphck[] = {
+       { .n = "macb0_clk", .id = 24, },
+       { .n = "lcdc_clk", .id = 25, },
+       { .n = "can0_clk", .id = 29, },
+       { .n = "can1_clk", .id = 30, },
+       { /* sentinel */}
+};
+
+static void __init at91sam9x5_pmc_setup(struct device_node *np,
+                                       const struct pck *extra_pcks,
+                                       bool has_lcdck)
+{
+       struct clk_range range = CLK_RANGE(0, 0);
+       const char *slck_name, *mainxtal_name;
+       struct pmc_data *at91sam9x5_pmc;
+       const char *parent_names[6];
+       struct regmap *regmap;
+       struct clk_hw *hw;
+       int i;
+       bool bypass;
+
+       i = of_property_match_string(np, "clock-names", "slow_clk");
+       if (i < 0)
+               return;
+
+       slck_name = of_clk_get_parent_name(np, i);
+
+       i = of_property_match_string(np, "clock-names", "main_xtal");
+       if (i < 0)
+               return;
+       mainxtal_name = of_clk_get_parent_name(np, i);
+
+       regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(regmap))
+               return;
+
+       at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
+                                          nck(at91sam9x5_systemck),
+                                          nck(at91sam9x35_periphck), 0);
+       if (!at91sam9x5_pmc)
+               return;
+
+       hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+                                          50000000);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+       hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
+                                       bypass);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = "main_rc_osc";
+       parent_names[1] = "main_osc";
+       hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9x5_pmc->chws[PMC_MAIN] = hw;
+
+       hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+                                  &at91rm9200_pll_layout, &plla_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9x5_pmc->chws[PMC_UTMI] = hw;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+                                     &at91sam9x5_master_layout,
+                                     &mck_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       at91sam9x5_pmc->chws[PMC_MCK] = hw;
+
+       parent_names[0] = "plladivck";
+       parent_names[1] = "utmick";
+       hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       parent_names[4] = "mck";
+       for (i = 0; i < 2; i++) {
+               char name[6];
+
+               snprintf(name, sizeof(name), "prog%d", i);
+
+               hw = at91_clk_register_programmable(regmap, name,
+                                                   parent_names, 5, i,
+                                                   &at91sam9x5_programmable_layout);
+               if (IS_ERR(hw))
+                       goto err_free;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
+               hw = at91_clk_register_system(regmap, at91sam9x5_systemck[i].n,
+                                             at91sam9x5_systemck[i].p,
+                                             at91sam9x5_systemck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9x5_pmc->shws[at91sam9x5_systemck[i].id] = hw;
+       }
+
+       if (has_lcdck) {
+               hw = at91_clk_register_system(regmap, "lcdck", "masterck", 3);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9x5_pmc->shws[3] = hw;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) {
+               hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+                                                        at91sam9x5_periphck[i].n,
+                                                        "masterck",
+                                                        at91sam9x5_periphck[i].id,
+                                                        &range);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9x5_pmc->phws[at91sam9x5_periphck[i].id] = hw;
+       }
+
+       for (i = 0; extra_pcks[i].id; i++) {
+               hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+                                                        extra_pcks[i].n,
+                                                        "masterck",
+                                                        extra_pcks[i].id,
+                                                        &range);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               at91sam9x5_pmc->phws[extra_pcks[i].id] = hw;
+       }
+
+       of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9x5_pmc);
+
+       return;
+
+err_free:
+       pmc_data_free(at91sam9x5_pmc);
+}
+
+static void __init at91sam9g15_pmc_setup(struct device_node *np)
+{
+       at91sam9x5_pmc_setup(np, at91sam9g15_periphck, true);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g15_pmc, "atmel,at91sam9g15-pmc",
+                     at91sam9g15_pmc_setup);
+
+static void __init at91sam9g25_pmc_setup(struct device_node *np)
+{
+       at91sam9x5_pmc_setup(np, at91sam9g25_periphck, false);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g25_pmc, "atmel,at91sam9g25-pmc",
+                     at91sam9g25_pmc_setup);
+
+static void __init at91sam9g35_pmc_setup(struct device_node *np)
+{
+       at91sam9x5_pmc_setup(np, at91sam9g35_periphck, true);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g35_pmc, "atmel,at91sam9g35-pmc",
+                     at91sam9g35_pmc_setup);
+
+static void __init at91sam9x25_pmc_setup(struct device_node *np)
+{
+       at91sam9x5_pmc_setup(np, at91sam9x25_periphck, false);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9x25_pmc, "atmel,at91sam9x25-pmc",
+                     at91sam9x25_pmc_setup);
+
+static void __init at91sam9x35_pmc_setup(struct device_node *np)
+{
+       at91sam9x5_pmc_setup(np, at91sam9x35_periphck, true);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9x35_pmc, "atmel,at91sam9x35-pmc",
+                     at91sam9x35_pmc_setup);
index da7bafcfbe706cef631e86f3df8dc86536f5900c..36d77146a3bd428c3f42aa5b73c3e69253fd58ea 100644 (file)
@@ -43,6 +43,8 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
+#include "pmc.h"
+
 #define AUDIO_PLL_DIV_FRAC     BIT(22)
 #define AUDIO_PLL_ND_MAX       (AT91_PMC_AUDIO_PLL_ND_MASK >> \
                                        AT91_PMC_AUDIO_PLL_ND_OFFSET)
@@ -444,93 +446,94 @@ static const struct clk_ops audio_pll_pmc_ops = {
        .set_rate = clk_audio_pll_pmc_set_rate,
 };
 
-static int of_sama5d2_clk_audio_pll_setup(struct device_node *np,
-                                         struct clk_init_data *init,
-                                         struct clk_hw *hw,
-                                         struct regmap **clk_audio_regmap)
-{
-       struct regmap *regmap;
-       const char *parent_names[1];
-       int ret;
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return PTR_ERR(regmap);
-
-       init->name = np->name;
-       of_clk_parent_fill(np, parent_names, 1);
-       init->parent_names = parent_names;
-       init->num_parents = 1;
-
-       hw->init = init;
-       *clk_audio_regmap = regmap;
-
-       ret = clk_hw_register(NULL, hw);
-       if (ret)
-               return ret;
-
-       return of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-
-static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
+struct clk_hw * __init
+at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
+                                const char *parent_name)
 {
        struct clk_audio_frac *frac_ck;
        struct clk_init_data init = {};
+       int ret;
 
        frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL);
        if (!frac_ck)
-               return;
+               return ERR_PTR(-ENOMEM);
 
+       init.name = name;
        init.ops = &audio_pll_frac_ops;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
        init.flags = CLK_SET_RATE_GATE;
 
-       if (of_sama5d2_clk_audio_pll_setup(np, &init, &frac_ck->hw,
-                                          &frac_ck->regmap))
+       frac_ck->hw.init = &init;
+       frac_ck->regmap = regmap;
+
+       ret = clk_hw_register(NULL, &frac_ck->hw);
+       if (ret) {
                kfree(frac_ck);
+               return ERR_PTR(ret);
+       }
+
+       return &frac_ck->hw;
 }
 
-static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
+struct clk_hw * __init
+at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
+                               const char *parent_name)
 {
        struct clk_audio_pad *apad_ck;
-       struct clk_init_data init = {};
+       struct clk_init_data init;
+       int ret;
 
        apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL);
        if (!apad_ck)
-               return;
+               return ERR_PTR(-ENOMEM);
 
+       init.name = name;
        init.ops = &audio_pll_pad_ops;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
        init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
                CLK_SET_RATE_PARENT;
 
-       if (of_sama5d2_clk_audio_pll_setup(np, &init, &apad_ck->hw,
-                                          &apad_ck->regmap))
+       apad_ck->hw.init = &init;
+       apad_ck->regmap = regmap;
+
+       ret = clk_hw_register(NULL, &apad_ck->hw);
+       if (ret) {
                kfree(apad_ck);
+               return ERR_PTR(ret);
+       }
+
+       return &apad_ck->hw;
 }
 
-static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
+struct clk_hw * __init
+at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
+                               const char *parent_name)
 {
-       struct clk_audio_pad *apmc_ck;
-       struct clk_init_data init = {};
+       struct clk_audio_pmc *apmc_ck;
+       struct clk_init_data init;
+       int ret;
 
        apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL);
        if (!apmc_ck)
-               return;
+               return ERR_PTR(-ENOMEM);
 
+       init.name = name;
        init.ops = &audio_pll_pmc_ops;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
        init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
                CLK_SET_RATE_PARENT;
 
-       if (of_sama5d2_clk_audio_pll_setup(np, &init, &apmc_ck->hw,
-                                          &apmc_ck->regmap))
+       apmc_ck->hw.init = &init;
+       apmc_ck->regmap = regmap;
+
+       ret = clk_hw_register(NULL, &apmc_ck->hw);
+       if (ret) {
                kfree(apmc_ck);
-}
+               return ERR_PTR(ret);
+       }
 
-CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
-              "atmel,sama5d2-clk-audio-pll-frac",
-              of_sama5d2_clk_audio_pll_frac_setup);
-CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
-              "atmel,sama5d2-clk-audio-pll-pad",
-              of_sama5d2_clk_audio_pll_pad_setup);
-CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
-              "atmel,sama5d2-clk-audio-pll-pmc",
-              of_sama5d2_clk_audio_pll_pmc_setup);
+       return &apmc_ck->hw;
+}
index 33481368740e7dc038fe1e32065e2659d8cec730..66e7f7baf9580fe6b6ac7ec837581fb3c0b60d27 100644 (file)
 
 #include "pmc.h"
 
-#define PERIPHERAL_MAX         64
-#define PERIPHERAL_ID_MIN      2
-
-#define GENERATED_SOURCE_MAX   6
 #define GENERATED_MAX_DIV      255
 
-#define GCK_ID_SSC0            43
-#define GCK_ID_SSC1            44
-#define GCK_ID_I2S0            54
-#define GCK_ID_I2S1            55
-#define GCK_ID_CLASSD          59
 #define GCK_INDEX_DT_AUDIO_PLL 5
 
 struct clk_generated {
@@ -279,10 +270,10 @@ static void clk_generated_startup(struct clk_generated *gck)
                                        >> AT91_PMC_PCR_GCKDIV_OFFSET;
 }
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
                            const char *name, const char **parent_names,
-                           u8 num_parents, u8 id,
+                           u8 num_parents, u8 id, bool pll_audio,
                            const struct clk_range *range)
 {
        struct clk_generated *gck;
@@ -306,6 +297,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
        gck->regmap = regmap;
        gck->lock = lock;
        gck->range = *range;
+       gck->audio_pll_allowed = pll_audio;
 
        clk_generated_startup(gck);
        hw = &gck->hw;
@@ -319,70 +311,3 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
 
        return hw;
 }
-
-static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
-{
-       int num;
-       u32 id;
-       const char *name;
-       struct clk_hw *hw;
-       unsigned int num_parents;
-       const char *parent_names[GENERATED_SOURCE_MAX];
-       struct device_node *gcknp;
-       struct clk_range range = CLK_RANGE(0, 0);
-       struct regmap *regmap;
-       struct clk_generated *gck;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-
-       num = of_get_child_count(np);
-       if (!num || num > PERIPHERAL_MAX)
-               return;
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       for_each_child_of_node(np, gcknp) {
-               if (of_property_read_u32(gcknp, "reg", &id))
-                       continue;
-
-               if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
-                       continue;
-
-               if (of_property_read_string(np, "clock-output-names", &name))
-                       name = gcknp->name;
-
-               of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
-                                     &range);
-
-               hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
-                                                 parent_names, num_parents,
-                                                 id, &range);
-
-               gck = to_clk_generated(hw);
-
-               if (of_device_is_compatible(np,
-                                           "atmel,sama5d2-clk-generated")) {
-                       if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 ||
-                           gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 ||
-                           gck->id == GCK_ID_CLASSD)
-                               gck->audio_pll_allowed = true;
-                       else
-                               gck->audio_pll_allowed = false;
-               } else {
-                       gck->audio_pll_allowed = false;
-               }
-
-               if (IS_ERR(hw))
-                       continue;
-
-               of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
-       }
-}
-CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
-              of_sama5d2_clk_generated_setup);
index e0daa4a31f881c7b253a2bbc1e97e25f96c8219b..f0a2c6baab37312c365b424daf721e2ecb854c99 100644 (file)
@@ -86,25 +86,19 @@ static const struct clk_ops h32mx_ops = {
        .set_rate = clk_sama5d4_h32mx_set_rate,
 };
 
-static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
+struct clk_hw * __init
+at91_clk_register_h32mx(struct regmap *regmap, const char *name,
+                       const char *parent_name)
 {
        struct clk_sama5d4_h32mx *h32mxclk;
        struct clk_init_data init;
-       const char *parent_name;
-       struct regmap *regmap;
        int ret;
 
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
        h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL);
        if (!h32mxclk)
-               return;
-
-       parent_name = of_clk_get_parent_name(np, 0);
+               return ERR_PTR(-ENOMEM);
 
-       init.name = np->name;
+       init.name = name;
        init.ops = &h32mx_ops;
        init.parent_names = parent_name ? &parent_name : NULL;
        init.num_parents = parent_name ? 1 : 0;
@@ -116,10 +110,8 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
        ret = clk_hw_register(NULL, &h32mxclk->hw);
        if (ret) {
                kfree(h32mxclk);
-               return;
+               return ERR_PTR(ret);
        }
 
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
+       return &h32mxclk->hw;
 }
-CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
-              of_sama5d4_clk_h32mx_setup);
index f0c3c3079f042acec6c8ca84bdcb51449daa4252..fe6ce172b8b069a001c5f659a1adf05b418aca28 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <soc/at91/atmel-sfr.h>
 
-#define        I2S_BUS_NR      2
+#include "pmc.h"
 
 struct clk_i2s_mux {
        struct clk_hw hw;
@@ -48,7 +48,7 @@ static const struct clk_ops clk_i2s_mux_ops = {
        .determine_rate = __clk_mux_determine_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
                          const char * const *parent_names,
                          unsigned int num_parents, u8 bus_id)
@@ -78,39 +78,3 @@ at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
 
        return &i2s_ck->hw;
 }
-
-static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
-{
-       struct regmap *regmap_sfr;
-       u8 bus_id;
-       const char *parent_names[2];
-       struct device_node *i2s_mux_np;
-       struct clk_hw *hw;
-       int ret;
-
-       regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
-       if (IS_ERR(regmap_sfr))
-               return;
-
-       for_each_child_of_node(np, i2s_mux_np) {
-               if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
-                       continue;
-
-               if (bus_id > I2S_BUS_NR)
-                       continue;
-
-               ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
-               if (ret != 2)
-                       continue;
-
-               hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
-                                              parent_names, 2, bus_id);
-               if (IS_ERR(hw))
-                       continue;
-
-               of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
-       }
-}
-
-CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
-              of_sama5d2_clk_i2s_mux_setup);
index c813c27f2e58c6f8e62c523a1a9a8b1d212a96d8..7ac0facdb28b1b0e76f476da9e7faf54997bae33 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/clkdev.h>
 #include <linux/clk/at91_pmc.h>
 #include <linux/delay.h>
-#include <linux/of.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 
@@ -128,7 +127,7 @@ static const struct clk_ops main_osc_ops = {
        .is_prepared = clk_main_osc_is_prepared,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_main_osc(struct regmap *regmap,
                           const char *name,
                           const char *parent_name,
@@ -171,31 +170,6 @@ at91_clk_register_main_osc(struct regmap *regmap,
        return hw;
 }
 
-static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *name = np->name;
-       const char *parent_name;
-       struct regmap *regmap;
-       bool bypass;
-
-       of_property_read_string(np, "clock-output-names", &name);
-       bypass = of_property_read_bool(np, "atmel,osc-bypass");
-       parent_name = of_clk_get_parent_name(np, 0);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
-              of_at91rm9200_clk_main_osc_setup);
-
 static bool clk_main_rc_osc_ready(struct regmap *regmap)
 {
        unsigned int status;
@@ -275,7 +249,7 @@ static const struct clk_ops main_rc_osc_ops = {
        .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_main_rc_osc(struct regmap *regmap,
                              const char *name,
                              u32 frequency, u32 accuracy)
@@ -313,32 +287,6 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
        return hw;
 }
 
-static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       u32 frequency = 0;
-       u32 accuracy = 0;
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       of_property_read_string(np, "clock-output-names", &name);
-       of_property_read_u32(np, "clock-frequency", &frequency);
-       of_property_read_u32(np, "clock-accuracy", &accuracy);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
-              of_at91sam9x5_clk_main_rc_osc_setup);
-
-
 static int clk_main_probe_frequency(struct regmap *regmap)
 {
        unsigned long prep_time, timeout;
@@ -403,7 +351,7 @@ static const struct clk_ops rm9200_main_ops = {
        .recalc_rate = clk_rm9200_main_recalc_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_rm9200_main(struct regmap *regmap,
                              const char *name,
                              const char *parent_name)
@@ -442,29 +390,6 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
        return hw;
 }
 
-static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
-              of_at91rm9200_clk_main_setup);
-
 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
 {
        unsigned int status;
@@ -541,7 +466,7 @@ static const struct clk_ops sam9x5_main_ops = {
        .get_parent = clk_sam9x5_main_get_parent,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_sam9x5_main(struct regmap *regmap,
                              const char *name,
                              const char **parent_names,
@@ -583,32 +508,3 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
 
        return hw;
 }
-
-static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_names[2];
-       unsigned int num_parents;
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > 2)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
-                                           num_parents);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
-              of_at91sam9x5_clk_main_setup);
index e9cba9fc26d706181ea0e73406cd8e60997fde82..eb53b4a8fab635476d6f84449ca7696d006a464a 100644 (file)
 
 #include "pmc.h"
 
-#define MASTER_SOURCE_MAX      4
-
 #define MASTER_PRES_MASK       0x7
 #define MASTER_PRES_MAX                MASTER_PRES_MASK
 #define MASTER_DIV_SHIFT       8
 #define MASTER_DIV_MASK                0x3
 
-struct clk_master_characteristics {
-       struct clk_range output;
-       u32 divisors[4];
-       u8 have_div3_pres;
-};
-
-struct clk_master_layout {
-       u32 mask;
-       u8 pres_shift;
-};
-
 #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
 
 struct clk_master {
@@ -120,7 +107,7 @@ static const struct clk_ops master_ops = {
        .get_parent = clk_master_get_parent,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_master(struct regmap *regmap,
                const char *name, int num_parents,
                const char **parent_names,
@@ -161,92 +148,12 @@ at91_clk_register_master(struct regmap *regmap,
 }
 
 
-static const struct clk_master_layout at91rm9200_master_layout = {
+const struct clk_master_layout at91rm9200_master_layout = {
        .mask = 0x31F,
        .pres_shift = 2,
 };
 
-static const struct clk_master_layout at91sam9x5_master_layout = {
+const struct clk_master_layout at91sam9x5_master_layout = {
        .mask = 0x373,
        .pres_shift = 4,
 };
-
-
-static struct clk_master_characteristics * __init
-of_at91_clk_master_get_characteristics(struct device_node *np)
-{
-       struct clk_master_characteristics *characteristics;
-
-       characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
-       if (!characteristics)
-               return NULL;
-
-       if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
-               goto out_free_characteristics;
-
-       of_property_read_u32_array(np, "atmel,clk-divisors",
-                                  characteristics->divisors, 4);
-
-       characteristics->have_div3_pres =
-               of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
-
-       return characteristics;
-
-out_free_characteristics:
-       kfree(characteristics);
-       return NULL;
-}
-
-static void __init
-of_at91_clk_master_setup(struct device_node *np,
-                        const struct clk_master_layout *layout)
-{
-       struct clk_hw *hw;
-       unsigned int num_parents;
-       const char *parent_names[MASTER_SOURCE_MAX];
-       const char *name = np->name;
-       struct clk_master_characteristics *characteristics;
-       struct regmap *regmap;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       characteristics = of_at91_clk_master_get_characteristics(np);
-       if (!characteristics)
-               return;
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91_clk_register_master(regmap, name, num_parents,
-                                      parent_names, layout,
-                                      characteristics);
-       if (IS_ERR(hw))
-               goto out_free_characteristics;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-       return;
-
-out_free_characteristics:
-       kfree(characteristics);
-}
-
-static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
-{
-       of_at91_clk_master_setup(np, &at91rm9200_master_layout);
-}
-CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
-              of_at91rm9200_clk_master_setup);
-
-static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
-{
-       of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
-              of_at91sam9x5_clk_master_setup);
index 7701183692308e8870a669658e8c24b4d14700e4..65c1defa78e4a136c1ddcd0f04d8e2c5882b6811 100644 (file)
 
 DEFINE_SPINLOCK(pmc_pcr_lock);
 
-#define PERIPHERAL_MAX         64
-
-#define PERIPHERAL_AT91RM9200  0
-#define PERIPHERAL_AT91SAM9X5  1
-
 #define PERIPHERAL_ID_MIN      2
 #define PERIPHERAL_ID_MAX      31
 #define PERIPHERAL_MASK(id)    (1 << ((id) & PERIPHERAL_ID_MAX))
@@ -104,7 +99,7 @@ static const struct clk_ops peripheral_ops = {
        .is_enabled = clk_peripheral_is_enabled,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_peripheral(struct regmap *regmap, const char *name,
                             const char *parent_name, u32 id)
 {
@@ -331,7 +326,7 @@ static const struct clk_ops sam9x5_peripheral_ops = {
        .set_rate = clk_sam9x5_peripheral_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
                                    const char *name, const char *parent_name,
                                    u32 id, const struct clk_range *range)
@@ -374,75 +369,3 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
 
        return hw;
 }
-
-static void __init
-of_at91_clk_periph_setup(struct device_node *np, u8 type)
-{
-       int num;
-       u32 id;
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name;
-       struct device_node *periphclknp;
-       struct regmap *regmap;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-       if (!parent_name)
-               return;
-
-       num = of_get_child_count(np);
-       if (!num || num > PERIPHERAL_MAX)
-               return;
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       for_each_child_of_node(np, periphclknp) {
-               if (of_property_read_u32(periphclknp, "reg", &id))
-                       continue;
-
-               if (id >= PERIPHERAL_MAX)
-                       continue;
-
-               if (of_property_read_string(np, "clock-output-names", &name))
-                       name = periphclknp->name;
-
-               if (type == PERIPHERAL_AT91RM9200) {
-                       hw = at91_clk_register_peripheral(regmap, name,
-                                                          parent_name, id);
-               } else {
-                       struct clk_range range = CLK_RANGE(0, 0);
-
-                       of_at91_get_clk_range(periphclknp,
-                                             "atmel,clk-output-range",
-                                             &range);
-
-                       hw = at91_clk_register_sam9x5_peripheral(regmap,
-                                                                 &pmc_pcr_lock,
-                                                                 name,
-                                                                 parent_name,
-                                                                 id, &range);
-               }
-
-               if (IS_ERR(hw))
-                       continue;
-
-               of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
-       }
-}
-
-static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
-{
-       of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
-}
-CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
-              of_at91rm9200_clk_periph_setup);
-
-static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
-{
-       of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
-              of_at91sam9x5_clk_periph_setup);
-
index 72b6091eb7b944f50b6a2e3d9ceafa8077a851d2..b4138fcacf495156a5a14d684cc2e66309b9be6f 100644 (file)
 #define PLL_OUT_SHIFT          14
 #define PLL_MAX_ID             1
 
-struct clk_pll_characteristics {
-       struct clk_range input;
-       int num_output;
-       struct clk_range *output;
-       u16 *icpll;
-       u8 *out;
-};
-
-struct clk_pll_layout {
-       u32 pllr_mask;
-       u16 mul_mask;
-       u8 mul_shift;
-};
-
 #define to_clk_pll(hw) container_of(hw, struct clk_pll, hw)
 
 struct clk_pll {
@@ -133,6 +119,9 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 {
        struct clk_pll *pll = to_clk_pll(hw);
 
+       if (!pll->div || !pll->mul)
+               return 0;
+
        return (parent_rate / pll->div) * (pll->mul + 1);
 }
 
@@ -285,7 +274,7 @@ static const struct clk_ops pll_ops = {
        .set_rate = clk_pll_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_pll(struct regmap *regmap, const char *name,
                      const char *parent_name, u8 id,
                      const struct clk_pll_layout *layout,
@@ -331,189 +320,26 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
 }
 
 
-static const struct clk_pll_layout at91rm9200_pll_layout = {
+const struct clk_pll_layout at91rm9200_pll_layout = {
        .pllr_mask = 0x7FFFFFF,
        .mul_shift = 16,
        .mul_mask = 0x7FF,
 };
 
-static const struct clk_pll_layout at91sam9g45_pll_layout = {
+const struct clk_pll_layout at91sam9g45_pll_layout = {
        .pllr_mask = 0xFFFFFF,
        .mul_shift = 16,
        .mul_mask = 0xFF,
 };
 
-static const struct clk_pll_layout at91sam9g20_pllb_layout = {
+const struct clk_pll_layout at91sam9g20_pllb_layout = {
        .pllr_mask = 0x3FFFFF,
        .mul_shift = 16,
        .mul_mask = 0x3F,
 };
 
-static const struct clk_pll_layout sama5d3_pll_layout = {
+const struct clk_pll_layout sama5d3_pll_layout = {
        .pllr_mask = 0x1FFFFFF,
        .mul_shift = 18,
        .mul_mask = 0x7F,
 };
-
-
-static struct clk_pll_characteristics * __init
-of_at91_clk_pll_get_characteristics(struct device_node *np)
-{
-       int i;
-       int offset;
-       u32 tmp;
-       int num_output;
-       u32 num_cells;
-       struct clk_range input;
-       struct clk_range *output;
-       u8 *out = NULL;
-       u16 *icpll = NULL;
-       struct clk_pll_characteristics *characteristics;
-
-       if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
-               return NULL;
-
-       if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
-                                &num_cells))
-               return NULL;
-
-       if (num_cells < 2 || num_cells > 4)
-               return NULL;
-
-       if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
-               return NULL;
-       num_output = tmp / (sizeof(u32) * num_cells);
-
-       characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
-       if (!characteristics)
-               return NULL;
-
-       output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
-       if (!output)
-               goto out_free_characteristics;
-
-       if (num_cells > 2) {
-               out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
-               if (!out)
-                       goto out_free_output;
-       }
-
-       if (num_cells > 3) {
-               icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
-               if (!icpll)
-                       goto out_free_output;
-       }
-
-       for (i = 0; i < num_output; i++) {
-               offset = i * num_cells;
-               if (of_property_read_u32_index(np,
-                                              "atmel,pll-clk-output-ranges",
-                                              offset, &tmp))
-                       goto out_free_output;
-               output[i].min = tmp;
-               if (of_property_read_u32_index(np,
-                                              "atmel,pll-clk-output-ranges",
-                                              offset + 1, &tmp))
-                       goto out_free_output;
-               output[i].max = tmp;
-
-               if (num_cells == 2)
-                       continue;
-
-               if (of_property_read_u32_index(np,
-                                              "atmel,pll-clk-output-ranges",
-                                              offset + 2, &tmp))
-                       goto out_free_output;
-               out[i] = tmp;
-
-               if (num_cells == 3)
-                       continue;
-
-               if (of_property_read_u32_index(np,
-                                              "atmel,pll-clk-output-ranges",
-                                              offset + 3, &tmp))
-                       goto out_free_output;
-               icpll[i] = tmp;
-       }
-
-       characteristics->input = input;
-       characteristics->num_output = num_output;
-       characteristics->output = output;
-       characteristics->out = out;
-       characteristics->icpll = icpll;
-       return characteristics;
-
-out_free_output:
-       kfree(icpll);
-       kfree(out);
-       kfree(output);
-out_free_characteristics:
-       kfree(characteristics);
-       return NULL;
-}
-
-static void __init
-of_at91_clk_pll_setup(struct device_node *np,
-                     const struct clk_pll_layout *layout)
-{
-       u32 id;
-       struct clk_hw *hw;
-       struct regmap *regmap;
-       const char *parent_name;
-       const char *name = np->name;
-       struct clk_pll_characteristics *characteristics;
-
-       if (of_property_read_u32(np, "reg", &id))
-               return;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       characteristics = of_at91_clk_pll_get_characteristics(np);
-       if (!characteristics)
-               return;
-
-       hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
-                                   characteristics);
-       if (IS_ERR(hw))
-               goto out_free_characteristics;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-       return;
-
-out_free_characteristics:
-       kfree(characteristics);
-}
-
-static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
-{
-       of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
-}
-CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
-              of_at91rm9200_clk_pll_setup);
-
-static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
-{
-       of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
-}
-CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
-              of_at91sam9g45_clk_pll_setup);
-
-static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
-{
-       of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
-}
-CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
-              of_at91sam9g20_clk_pllb_setup);
-
-static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
-{
-       of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
-}
-CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
-              of_sama5d3_clk_pll_setup);
index b4afaf22f3fdc93277582746976b4d3ff0af5267..e8c4f8b02f28085a11fb215d3a39f0429e5f4fdc 100644 (file)
@@ -75,7 +75,7 @@ static const struct clk_ops plldiv_ops = {
        .set_rate = clk_plldiv_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_plldiv(struct regmap *regmap, const char *name,
                         const char *parent_name)
 {
@@ -106,28 +106,3 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
 
        return hw;
 }
-
-static void __init
-of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91_clk_register_plldiv(regmap, name, parent_name);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
-              of_at91sam9x5_clk_plldiv_setup);
index 0e6aab1252fc40dc6a4896abe875f51d9c9b8eb6..5bc68b9c5498496b6f6af33ad87422804dd62ef4 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "pmc.h"
 
-#define PROG_SOURCE_MAX                5
 #define PROG_ID_MAX            7
 
 #define PROG_STATUS_MASK(id)   (1 << ((id) + 8))
 #define PROG_PRES(layout, pckr)        ((pckr >> layout->pres_shift) & PROG_PRES_MASK)
 #define PROG_MAX_RM9200_CSS    3
 
-struct clk_programmable_layout {
-       u8 pres_shift;
-       u8 css_mask;
-       u8 have_slck_mck;
-};
-
 struct clk_programmable {
        struct clk_hw hw;
        struct regmap *regmap;
@@ -170,7 +163,7 @@ static const struct clk_ops programmable_ops = {
        .set_rate = clk_programmable_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_programmable(struct regmap *regmap,
                               const char *name, const char **parent_names,
                               u8 num_parents, u8 id,
@@ -211,86 +204,20 @@ at91_clk_register_programmable(struct regmap *regmap,
        return hw;
 }
 
-static const struct clk_programmable_layout at91rm9200_programmable_layout = {
+const struct clk_programmable_layout at91rm9200_programmable_layout = {
        .pres_shift = 2,
        .css_mask = 0x3,
        .have_slck_mck = 0,
 };
 
-static const struct clk_programmable_layout at91sam9g45_programmable_layout = {
+const struct clk_programmable_layout at91sam9g45_programmable_layout = {
        .pres_shift = 2,
        .css_mask = 0x3,
        .have_slck_mck = 1,
 };
 
-static const struct clk_programmable_layout at91sam9x5_programmable_layout = {
+const struct clk_programmable_layout at91sam9x5_programmable_layout = {
        .pres_shift = 4,
        .css_mask = 0x7,
        .have_slck_mck = 0,
 };
-
-static void __init
-of_at91_clk_prog_setup(struct device_node *np,
-                      const struct clk_programmable_layout *layout)
-{
-       int num;
-       u32 id;
-       struct clk_hw *hw;
-       unsigned int num_parents;
-       const char *parent_names[PROG_SOURCE_MAX];
-       const char *name;
-       struct device_node *progclknp;
-       struct regmap *regmap;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-
-       num = of_get_child_count(np);
-       if (!num || num > (PROG_ID_MAX + 1))
-               return;
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       for_each_child_of_node(np, progclknp) {
-               if (of_property_read_u32(progclknp, "reg", &id))
-                       continue;
-
-               if (of_property_read_string(np, "clock-output-names", &name))
-                       name = progclknp->name;
-
-               hw = at91_clk_register_programmable(regmap, name,
-                                                    parent_names, num_parents,
-                                                    id, layout);
-               if (IS_ERR(hw))
-                       continue;
-
-               of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
-       }
-}
-
-
-static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
-{
-       of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
-}
-CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
-              of_at91rm9200_clk_prog_setup);
-
-static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
-{
-       of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
-}
-CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
-              of_at91sam9g45_clk_prog_setup);
-
-static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
-{
-       of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
-              of_at91sam9x5_clk_prog_setup);
index 560a8b9abf9312bd921311bcf88d121727750c83..cbb146912f7af0b542bb836398b5f7b1d6eafd6f 100644 (file)
@@ -40,7 +40,7 @@ static const struct clk_ops sam9260_slow_ops = {
        .get_parent = clk_sam9260_slow_get_parent,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_sam9260_slow(struct regmap *regmap,
                               const char *name,
                               const char **parent_names,
@@ -79,33 +79,3 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
 
        return hw;
 }
-
-static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_names[2];
-       unsigned int num_parents;
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents != 2)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
-                                            num_parents);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-
-CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
-              of_at91sam9260_clk_slow_setup);
index 965c662b90a5ab6f3dfdcd5b4cd2382d79f4422e..75679fd8a9c742e387103296c9e8ee3fd6418881 100644 (file)
@@ -17,8 +17,6 @@
 
 #include "pmc.h"
 
-#define SMD_SOURCE_MAX         2
-
 #define SMD_DIV_SHIFT          8
 #define SMD_MAX_DIV            0xf
 
@@ -111,7 +109,7 @@ static const struct clk_ops at91sam9x5_smd_ops = {
        .set_rate = at91sam9x5_clk_smd_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
                            const char **parent_names, u8 num_parents)
 {
@@ -142,33 +140,3 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
 
        return hw;
 }
-
-static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       unsigned int num_parents;
-       const char *parent_names[SMD_SOURCE_MAX];
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
-                                         num_parents);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
-              of_at91sam9x5_clk_smd_setup);
index 86a36809765de84c94b9e29e55e129b2905b65ae..47bfca93340320130ca50386764bce6e975ea2cf 100644 (file)
@@ -88,7 +88,7 @@ static const struct clk_ops system_ops = {
        .is_prepared = clk_system_is_prepared,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_system(struct regmap *regmap, const char *name,
                         const char *parent_name, u8 id)
 {
@@ -123,40 +123,3 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
 
        return hw;
 }
-
-static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
-{
-       int num;
-       u32 id;
-       struct clk_hw *hw;
-       const char *name;
-       struct device_node *sysclknp;
-       const char *parent_name;
-       struct regmap *regmap;
-
-       num = of_get_child_count(np);
-       if (num > (SYSTEM_MAX_ID + 1))
-               return;
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       for_each_child_of_node(np, sysclknp) {
-               if (of_property_read_u32(sysclknp, "reg", &id))
-                       continue;
-
-               if (of_property_read_string(np, "clock-output-names", &name))
-                       name = sysclknp->name;
-
-               parent_name = of_clk_get_parent_name(sysclknp, 0);
-
-               hw = at91_clk_register_system(regmap, name, parent_name, id);
-               if (IS_ERR(hw))
-                       continue;
-
-               of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
-       }
-}
-CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
-              of_at91rm9200_clk_sys_setup);
index 791770a563fcce83d5538a52b5cc86bcc7a925c7..79ee1c760f2a5ba41a7cfaf3a7d748b30ef11f8c 100644 (file)
@@ -17,8 +17,6 @@
 
 #include "pmc.h"
 
-#define USB_SOURCE_MAX         2
-
 #define SAM9X5_USB_DIV_SHIFT   8
 #define SAM9X5_USB_MAX_DIV     0xf
 
@@ -192,7 +190,7 @@ static const struct clk_ops at91sam9n12_usb_ops = {
        .set_rate = at91sam9x5_clk_usb_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
                            const char **parent_names, u8 num_parents)
 {
@@ -225,7 +223,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
        return hw;
 }
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
                             const char *parent_name)
 {
@@ -342,7 +340,7 @@ static const struct clk_ops at91rm9200_usb_ops = {
        .set_rate = at91rm9200_clk_usb_set_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
                            const char *parent_name, const u32 *divisors)
 {
@@ -374,89 +372,3 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
 
        return hw;
 }
-
-static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       unsigned int num_parents;
-       const char *parent_names[USB_SOURCE_MAX];
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
-                                        num_parents);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
-              of_at91sam9x5_clk_usb_setup);
-
-static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name = np->name;
-       struct regmap *regmap;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-       if (!parent_name)
-               return;
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-
-       hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
-              of_at91sam9n12_clk_usb_setup);
-
-static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name = np->name;
-       u32 divisors[4] = {0, 0, 0, 0};
-       struct regmap *regmap;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-       if (!parent_name)
-               return;
-
-       of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
-       if (!divisors[0])
-               return;
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap))
-               return;
-       hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
-              of_at91rm9200_clk_usb_setup);
index cd8d689138ff9917822aec3416a101bd0eb665c6..9a970abf34898963e9c689868aa7d9857de22559 100644 (file)
@@ -125,7 +125,7 @@ static const struct clk_ops utmi_ops = {
        .recalc_rate = clk_utmi_recalc_rate,
 };
 
-static struct clk_hw * __init
+struct clk_hw * __init
 at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
                       const char *name, const char *parent_name)
 {
@@ -157,46 +157,3 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
 
        return hw;
 }
-
-static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
-{
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name = np->name;
-       struct regmap *regmap_pmc, *regmap_sfr;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
-       if (IS_ERR(regmap_pmc))
-               return;
-
-       /*
-        * If the device supports different mainck rates, this value has to be
-        * set in the UTMI Clock Trimming register.
-        * - 9x5: mainck supports several rates but it is indicated that a
-        *   12 MHz is needed in case of USB.
-        * - sama5d3 and sama5d2: mainck supports several rates. Configuring
-        *   the FREQ field of the UTMI Clock Trimming register is mandatory.
-        * - sama5d4: mainck is at 12 MHz.
-        *
-        * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
-        */
-       regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
-       if (IS_ERR(regmap_sfr)) {
-               regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
-               if (IS_ERR(regmap_sfr))
-                       regmap_sfr = NULL;
-       }
-
-       hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-       return;
-}
-CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
-              of_at91sam9x5_clk_utmi_setup);
diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c
new file mode 100644 (file)
index 0000000..b95bb4e
--- /dev/null
@@ -0,0 +1,961 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include "pmc.h"
+
+#define MASTER_SOURCE_MAX      4
+
+#define PERIPHERAL_AT91RM9200  0
+#define PERIPHERAL_AT91SAM9X5  1
+
+#define PERIPHERAL_MAX         64
+
+#define PERIPHERAL_ID_MIN      2
+
+#define PROG_SOURCE_MAX                5
+#define PROG_ID_MAX            7
+
+#define SYSTEM_MAX_ID          31
+
+#ifdef CONFIG_HAVE_AT91_AUDIO_PLL
+static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *name = np->name;
+       const char *parent_name;
+       struct regmap *regmap;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
+              "atmel,sama5d2-clk-audio-pll-frac",
+              of_sama5d2_clk_audio_pll_frac_setup);
+
+static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *name = np->name;
+       const char *parent_name;
+       struct regmap *regmap;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
+              "atmel,sama5d2-clk-audio-pll-pad",
+              of_sama5d2_clk_audio_pll_pad_setup);
+
+static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *name = np->name;
+       const char *parent_name;
+       struct regmap *regmap;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
+              "atmel,sama5d2-clk-audio-pll-pmc",
+              of_sama5d2_clk_audio_pll_pmc_setup);
+#endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
+
+#ifdef CONFIG_HAVE_AT91_GENERATED_CLK
+#define GENERATED_SOURCE_MAX   6
+
+#define GCK_ID_I2S0            54
+#define GCK_ID_I2S1            55
+#define GCK_ID_CLASSD          59
+
+static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
+{
+       int num;
+       u32 id;
+       const char *name;
+       struct clk_hw *hw;
+       unsigned int num_parents;
+       const char *parent_names[GENERATED_SOURCE_MAX];
+       struct device_node *gcknp;
+       struct clk_range range = CLK_RANGE(0, 0);
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       num = of_get_child_count(np);
+       if (!num || num > PERIPHERAL_MAX)
+               return;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       for_each_child_of_node(np, gcknp) {
+               bool pll_audio = false;
+
+               if (of_property_read_u32(gcknp, "reg", &id))
+                       continue;
+
+               if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
+                       continue;
+
+               if (of_property_read_string(np, "clock-output-names", &name))
+                       name = gcknp->name;
+
+               of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
+                                     &range);
+
+               if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") &&
+                   (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 ||
+                    id == GCK_ID_CLASSD))
+                       pll_audio = true;
+
+               hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
+                                                parent_names, num_parents,
+                                                id, pll_audio, &range);
+               if (IS_ERR(hw))
+                       continue;
+
+               of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
+       }
+}
+CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
+              of_sama5d2_clk_generated_setup);
+#endif /* CONFIG_HAVE_AT91_GENERATED_CLK */
+
+#ifdef CONFIG_HAVE_AT91_H32MX
+static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *name = np->name;
+       const char *parent_name;
+       struct regmap *regmap;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       hw = at91_clk_register_h32mx(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
+              of_sama5d4_clk_h32mx_setup);
+#endif /* CONFIG_HAVE_AT91_H32MX */
+
+#ifdef CONFIG_HAVE_AT91_I2S_MUX_CLK
+#define        I2S_BUS_NR      2
+
+static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
+{
+       struct regmap *regmap_sfr;
+       u8 bus_id;
+       const char *parent_names[2];
+       struct device_node *i2s_mux_np;
+       struct clk_hw *hw;
+       int ret;
+
+       regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+       if (IS_ERR(regmap_sfr))
+               return;
+
+       for_each_child_of_node(np, i2s_mux_np) {
+               if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
+                       continue;
+
+               if (bus_id > I2S_BUS_NR)
+                       continue;
+
+               ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
+               if (ret != 2)
+                       continue;
+
+               hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
+                                              parent_names, 2, bus_id);
+               if (IS_ERR(hw))
+                       continue;
+
+               of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
+       }
+}
+CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
+              of_sama5d2_clk_i2s_mux_setup);
+#endif /* CONFIG_HAVE_AT91_I2S_MUX_CLK */
+
+static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *name = np->name;
+       const char *parent_name;
+       struct regmap *regmap;
+       bool bypass;
+
+       of_property_read_string(np, "clock-output-names", &name);
+       bypass = of_property_read_bool(np, "atmel,osc-bypass");
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
+              of_at91rm9200_clk_main_osc_setup);
+
+static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       u32 frequency = 0;
+       u32 accuracy = 0;
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       of_property_read_string(np, "clock-output-names", &name);
+       of_property_read_u32(np, "clock-frequency", &frequency);
+       of_property_read_u32(np, "clock-accuracy", &accuracy);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
+              of_at91sam9x5_clk_main_rc_osc_setup);
+
+static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
+              of_at91rm9200_clk_main_setup);
+
+static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_names[2];
+       unsigned int num_parents;
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > 2)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
+                                          num_parents);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
+              of_at91sam9x5_clk_main_setup);
+
+static struct clk_master_characteristics * __init
+of_at91_clk_master_get_characteristics(struct device_node *np)
+{
+       struct clk_master_characteristics *characteristics;
+
+       characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
+       if (!characteristics)
+               return NULL;
+
+       if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
+               goto out_free_characteristics;
+
+       of_property_read_u32_array(np, "atmel,clk-divisors",
+                                  characteristics->divisors, 4);
+
+       characteristics->have_div3_pres =
+               of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
+
+       return characteristics;
+
+out_free_characteristics:
+       kfree(characteristics);
+       return NULL;
+}
+
+static void __init
+of_at91_clk_master_setup(struct device_node *np,
+                        const struct clk_master_layout *layout)
+{
+       struct clk_hw *hw;
+       unsigned int num_parents;
+       const char *parent_names[MASTER_SOURCE_MAX];
+       const char *name = np->name;
+       struct clk_master_characteristics *characteristics;
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       characteristics = of_at91_clk_master_get_characteristics(np);
+       if (!characteristics)
+               return;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91_clk_register_master(regmap, name, num_parents,
+                                     parent_names, layout,
+                                     characteristics);
+       if (IS_ERR(hw))
+               goto out_free_characteristics;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+       return;
+
+out_free_characteristics:
+       kfree(characteristics);
+}
+
+static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
+{
+       of_at91_clk_master_setup(np, &at91rm9200_master_layout);
+}
+CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
+              of_at91rm9200_clk_master_setup);
+
+static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
+{
+       of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
+              of_at91sam9x5_clk_master_setup);
+
+static void __init
+of_at91_clk_periph_setup(struct device_node *np, u8 type)
+{
+       int num;
+       u32 id;
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name;
+       struct device_node *periphclknp;
+       struct regmap *regmap;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       num = of_get_child_count(np);
+       if (!num || num > PERIPHERAL_MAX)
+               return;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       for_each_child_of_node(np, periphclknp) {
+               if (of_property_read_u32(periphclknp, "reg", &id))
+                       continue;
+
+               if (id >= PERIPHERAL_MAX)
+                       continue;
+
+               if (of_property_read_string(np, "clock-output-names", &name))
+                       name = periphclknp->name;
+
+               if (type == PERIPHERAL_AT91RM9200) {
+                       hw = at91_clk_register_peripheral(regmap, name,
+                                                         parent_name, id);
+               } else {
+                       struct clk_range range = CLK_RANGE(0, 0);
+
+                       of_at91_get_clk_range(periphclknp,
+                                             "atmel,clk-output-range",
+                                             &range);
+
+                       hw = at91_clk_register_sam9x5_peripheral(regmap,
+                                                                &pmc_pcr_lock,
+                                                                name,
+                                                                parent_name,
+                                                                id, &range);
+               }
+
+               if (IS_ERR(hw))
+                       continue;
+
+               of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
+       }
+}
+
+static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
+{
+       of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
+}
+CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
+              of_at91rm9200_clk_periph_setup);
+
+static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
+{
+       of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
+              of_at91sam9x5_clk_periph_setup);
+
+static struct clk_pll_characteristics * __init
+of_at91_clk_pll_get_characteristics(struct device_node *np)
+{
+       int i;
+       int offset;
+       u32 tmp;
+       int num_output;
+       u32 num_cells;
+       struct clk_range input;
+       struct clk_range *output;
+       u8 *out = NULL;
+       u16 *icpll = NULL;
+       struct clk_pll_characteristics *characteristics;
+
+       if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
+               return NULL;
+
+       if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
+                                &num_cells))
+               return NULL;
+
+       if (num_cells < 2 || num_cells > 4)
+               return NULL;
+
+       if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
+               return NULL;
+       num_output = tmp / (sizeof(u32) * num_cells);
+
+       characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
+       if (!characteristics)
+               return NULL;
+
+       output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
+       if (!output)
+               goto out_free_characteristics;
+
+       if (num_cells > 2) {
+               out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
+               if (!out)
+                       goto out_free_output;
+       }
+
+       if (num_cells > 3) {
+               icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
+               if (!icpll)
+                       goto out_free_output;
+       }
+
+       for (i = 0; i < num_output; i++) {
+               offset = i * num_cells;
+               if (of_property_read_u32_index(np,
+                                              "atmel,pll-clk-output-ranges",
+                                              offset, &tmp))
+                       goto out_free_output;
+               output[i].min = tmp;
+               if (of_property_read_u32_index(np,
+                                              "atmel,pll-clk-output-ranges",
+                                              offset + 1, &tmp))
+                       goto out_free_output;
+               output[i].max = tmp;
+
+               if (num_cells == 2)
+                       continue;
+
+               if (of_property_read_u32_index(np,
+                                              "atmel,pll-clk-output-ranges",
+                                              offset + 2, &tmp))
+                       goto out_free_output;
+               out[i] = tmp;
+
+               if (num_cells == 3)
+                       continue;
+
+               if (of_property_read_u32_index(np,
+                                              "atmel,pll-clk-output-ranges",
+                                              offset + 3, &tmp))
+                       goto out_free_output;
+               icpll[i] = tmp;
+       }
+
+       characteristics->input = input;
+       characteristics->num_output = num_output;
+       characteristics->output = output;
+       characteristics->out = out;
+       characteristics->icpll = icpll;
+       return characteristics;
+
+out_free_output:
+       kfree(icpll);
+       kfree(out);
+       kfree(output);
+out_free_characteristics:
+       kfree(characteristics);
+       return NULL;
+}
+
+static void __init
+of_at91_clk_pll_setup(struct device_node *np,
+                     const struct clk_pll_layout *layout)
+{
+       u32 id;
+       struct clk_hw *hw;
+       struct regmap *regmap;
+       const char *parent_name;
+       const char *name = np->name;
+       struct clk_pll_characteristics *characteristics;
+
+       if (of_property_read_u32(np, "reg", &id))
+               return;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       characteristics = of_at91_clk_pll_get_characteristics(np);
+       if (!characteristics)
+               return;
+
+       hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
+                                  characteristics);
+       if (IS_ERR(hw))
+               goto out_free_characteristics;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+       return;
+
+out_free_characteristics:
+       kfree(characteristics);
+}
+
+static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
+{
+       of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
+}
+CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
+              of_at91rm9200_clk_pll_setup);
+
+static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
+{
+       of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
+}
+CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
+              of_at91sam9g45_clk_pll_setup);
+
+static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
+{
+       of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
+}
+CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
+              of_at91sam9g20_clk_pllb_setup);
+
+static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
+{
+       of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
+}
+CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
+              of_sama5d3_clk_pll_setup);
+
+static void __init
+of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91_clk_register_plldiv(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
+              of_at91sam9x5_clk_plldiv_setup);
+
+static void __init
+of_at91_clk_prog_setup(struct device_node *np,
+                      const struct clk_programmable_layout *layout)
+{
+       int num;
+       u32 id;
+       struct clk_hw *hw;
+       unsigned int num_parents;
+       const char *parent_names[PROG_SOURCE_MAX];
+       const char *name;
+       struct device_node *progclknp;
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       num = of_get_child_count(np);
+       if (!num || num > (PROG_ID_MAX + 1))
+               return;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       for_each_child_of_node(np, progclknp) {
+               if (of_property_read_u32(progclknp, "reg", &id))
+                       continue;
+
+               if (of_property_read_string(np, "clock-output-names", &name))
+                       name = progclknp->name;
+
+               hw = at91_clk_register_programmable(regmap, name,
+                                                   parent_names, num_parents,
+                                                   id, layout);
+               if (IS_ERR(hw))
+                       continue;
+
+               of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
+       }
+}
+
+static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
+{
+       of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
+}
+CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
+              of_at91rm9200_clk_prog_setup);
+
+static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
+{
+       of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
+}
+CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
+              of_at91sam9g45_clk_prog_setup);
+
+static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
+{
+       of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
+              of_at91sam9x5_clk_prog_setup);
+
+static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_names[2];
+       unsigned int num_parents;
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents != 2)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
+                                           num_parents);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
+              of_at91sam9260_clk_slow_setup);
+
+#ifdef CONFIG_HAVE_AT91_SMD
+#define SMD_SOURCE_MAX         2
+
+static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       unsigned int num_parents;
+       const char *parent_names[SMD_SOURCE_MAX];
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
+                                        num_parents);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
+              of_at91sam9x5_clk_smd_setup);
+#endif /* CONFIG_HAVE_AT91_SMD */
+
+static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
+{
+       int num;
+       u32 id;
+       struct clk_hw *hw;
+       const char *name;
+       struct device_node *sysclknp;
+       const char *parent_name;
+       struct regmap *regmap;
+
+       num = of_get_child_count(np);
+       if (num > (SYSTEM_MAX_ID + 1))
+               return;
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       for_each_child_of_node(np, sysclknp) {
+               if (of_property_read_u32(sysclknp, "reg", &id))
+                       continue;
+
+               if (of_property_read_string(np, "clock-output-names", &name))
+                       name = sysclknp->name;
+
+               parent_name = of_clk_get_parent_name(sysclknp, 0);
+
+               hw = at91_clk_register_system(regmap, name, parent_name, id);
+               if (IS_ERR(hw))
+                       continue;
+
+               of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
+       }
+}
+CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
+              of_at91rm9200_clk_sys_setup);
+
+#ifdef CONFIG_HAVE_AT91_USB_CLK
+#define USB_SOURCE_MAX         2
+
+static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       unsigned int num_parents;
+       const char *parent_names[USB_SOURCE_MAX];
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
+                                        num_parents);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
+              of_at91sam9x5_clk_usb_setup);
+
+static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name = np->name;
+       struct regmap *regmap;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+
+       hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
+              of_at91sam9n12_clk_usb_setup);
+
+static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name = np->name;
+       u32 divisors[4] = {0, 0, 0, 0};
+       struct regmap *regmap;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       if (!parent_name)
+               return;
+
+       of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
+       if (!divisors[0])
+               return;
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
+       hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
+              of_at91rm9200_clk_usb_setup);
+#endif /* CONFIG_HAVE_AT91_USB_CLK */
+
+#ifdef CONFIG_HAVE_AT91_UTMI
+static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
+{
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name = np->name;
+       struct regmap *regmap_pmc, *regmap_sfr;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap_pmc))
+               return;
+
+       /*
+        * If the device supports different mainck rates, this value has to be
+        * set in the UTMI Clock Trimming register.
+        * - 9x5: mainck supports several rates but it is indicated that a
+        *   12 MHz is needed in case of USB.
+        * - sama5d3 and sama5d2: mainck supports several rates. Configuring
+        *   the FREQ field of the UTMI Clock Trimming register is mandatory.
+        * - sama5d4: mainck is at 12 MHz.
+        *
+        * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
+        */
+       regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
+       if (IS_ERR(regmap_sfr)) {
+               regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+               if (IS_ERR(regmap_sfr))
+                       regmap_sfr = NULL;
+       }
+
+       hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
+              of_at91sam9x5_clk_utmi_setup);
+#endif /* CONFIG_HAVE_AT91_UTMI */
index 1fa27f4ea5386304841317fedadca3fd1ab6dd33..db24539d57405253d26c4d4ebc3b6626045d0517 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <asm/proc-fns.h>
 
+#include <dt-bindings/clock/at91.h>
+
 #include "pmc.h"
 
 #define PMC_MAX_IDS 128
@@ -47,6 +49,82 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname,
 }
 EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
 
+struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
+{
+       unsigned int type = clkspec->args[0];
+       unsigned int idx = clkspec->args[1];
+       struct pmc_data *pmc_data = data;
+
+       switch (type) {
+       case PMC_TYPE_CORE:
+               if (idx < pmc_data->ncore)
+                       return pmc_data->chws[idx];
+               break;
+       case PMC_TYPE_SYSTEM:
+               if (idx < pmc_data->nsystem)
+                       return pmc_data->shws[idx];
+               break;
+       case PMC_TYPE_PERIPHERAL:
+               if (idx < pmc_data->nperiph)
+                       return pmc_data->phws[idx];
+               break;
+       case PMC_TYPE_GCK:
+               if (idx < pmc_data->ngck)
+                       return pmc_data->ghws[idx];
+               break;
+       default:
+               break;
+       }
+
+       pr_err("%s: invalid type (%u) or index (%u)\n", __func__, type, idx);
+
+       return ERR_PTR(-EINVAL);
+}
+
+void pmc_data_free(struct pmc_data *pmc_data)
+{
+       kfree(pmc_data->chws);
+       kfree(pmc_data->shws);
+       kfree(pmc_data->phws);
+       kfree(pmc_data->ghws);
+}
+
+struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
+                                  unsigned int nperiph, unsigned int ngck)
+{
+       struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
+
+       if (!pmc_data)
+               return NULL;
+
+       pmc_data->ncore = ncore;
+       pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
+       if (!pmc_data->chws)
+               goto err;
+
+       pmc_data->nsystem = nsystem;
+       pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
+       if (!pmc_data->shws)
+               goto err;
+
+       pmc_data->nperiph = nperiph;
+       pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
+       if (!pmc_data->phws)
+               goto err;
+
+       pmc_data->ngck = ngck;
+       pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
+       if (!pmc_data->ghws)
+               goto err;
+
+       return pmc_data;
+
+err:
+       pmc_data_free(pmc_data);
+
+       return NULL;
+}
+
 #ifdef CONFIG_PM
 static struct regmap *pmcreg;
 
index d22b1fa9ecdce8fa621dc3d7eaa66a4580585911..672a79bda88c960d7655a600834705152f5a4eaf 100644 (file)
 
 extern spinlock_t pmc_pcr_lock;
 
+struct pmc_data {
+       unsigned int ncore;
+       struct clk_hw **chws;
+       unsigned int nsystem;
+       struct clk_hw **shws;
+       unsigned int nperiph;
+       struct clk_hw **phws;
+       unsigned int ngck;
+       struct clk_hw **ghws;
+};
+
 struct clk_range {
        unsigned long min;
        unsigned long max;
@@ -26,9 +37,157 @@ struct clk_range {
 
 #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
 
+struct clk_master_layout {
+       u32 mask;
+       u8 pres_shift;
+};
+
+extern const struct clk_master_layout at91rm9200_master_layout;
+extern const struct clk_master_layout at91sam9x5_master_layout;
+
+struct clk_master_characteristics {
+       struct clk_range output;
+       u32 divisors[4];
+       u8 have_div3_pres;
+};
+
+struct clk_pll_layout {
+       u32 pllr_mask;
+       u16 mul_mask;
+       u8 mul_shift;
+};
+
+extern const struct clk_pll_layout at91rm9200_pll_layout;
+extern const struct clk_pll_layout at91sam9g45_pll_layout;
+extern const struct clk_pll_layout at91sam9g20_pllb_layout;
+extern const struct clk_pll_layout sama5d3_pll_layout;
+
+struct clk_pll_characteristics {
+       struct clk_range input;
+       int num_output;
+       struct clk_range *output;
+       u16 *icpll;
+       u8 *out;
+};
+
+struct clk_programmable_layout {
+       u8 pres_shift;
+       u8 css_mask;
+       u8 have_slck_mck;
+};
+
+extern const struct clk_programmable_layout at91rm9200_programmable_layout;
+extern const struct clk_programmable_layout at91sam9g45_programmable_layout;
+extern const struct clk_programmable_layout at91sam9x5_programmable_layout;
+
+#define ndck(a, s) (a[s - 1].id + 1)
+#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
+struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
+                                  unsigned int nperiph, unsigned int ngck);
+void pmc_data_free(struct pmc_data *pmc_data);
+
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
                          struct clk_range *range);
 
+struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data);
+
+struct clk_hw * __init
+at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
+                                const char *parent_name);
+
+struct clk_hw * __init
+at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
+                               const char *parent_name);
+
+struct clk_hw * __init
+at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
+                               const char *parent_name);
+
+struct clk_hw * __init
+at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
+                           const char *name, const char **parent_names,
+                           u8 num_parents, u8 id, bool pll_audio,
+                           const struct clk_range *range);
+
+struct clk_hw * __init
+at91_clk_register_h32mx(struct regmap *regmap, const char *name,
+                       const char *parent_name);
+
+struct clk_hw * __init
+at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
+                         const char * const *parent_names,
+                         unsigned int num_parents, u8 bus_id);
+
+struct clk_hw * __init
+at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name,
+                             u32 frequency, u32 accuracy);
+struct clk_hw * __init
+at91_clk_register_main_osc(struct regmap *regmap, const char *name,
+                          const char *parent_name, bool bypass);
+struct clk_hw * __init
+at91_clk_register_rm9200_main(struct regmap *regmap,
+                             const char *name,
+                             const char *parent_name);
+struct clk_hw * __init
+at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name,
+                             const char **parent_names, int num_parents);
+
+struct clk_hw * __init
+at91_clk_register_master(struct regmap *regmap, const char *name,
+                        int num_parents, const char **parent_names,
+                        const struct clk_master_layout *layout,
+                        const struct clk_master_characteristics *characteristics);
+
+struct clk_hw * __init
+at91_clk_register_peripheral(struct regmap *regmap, const char *name,
+                            const char *parent_name, u32 id);
+struct clk_hw * __init
+at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
+                                   const char *name, const char *parent_name,
+                                   u32 id, const struct clk_range *range);
+
+struct clk_hw * __init
+at91_clk_register_pll(struct regmap *regmap, const char *name,
+                     const char *parent_name, u8 id,
+                     const struct clk_pll_layout *layout,
+                     const struct clk_pll_characteristics *characteristics);
+struct clk_hw * __init
+at91_clk_register_plldiv(struct regmap *regmap, const char *name,
+                        const char *parent_name);
+
+struct clk_hw * __init
+at91_clk_register_programmable(struct regmap *regmap, const char *name,
+                              const char **parent_names, u8 num_parents, u8 id,
+                              const struct clk_programmable_layout *layout);
+
+struct clk_hw * __init
+at91_clk_register_sam9260_slow(struct regmap *regmap,
+                              const char *name,
+                              const char **parent_names,
+                              int num_parents);
+
+struct clk_hw * __init
+at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
+                           const char **parent_names, u8 num_parents);
+
+struct clk_hw * __init
+at91_clk_register_system(struct regmap *regmap, const char *name,
+                        const char *parent_name, u8 id);
+
+struct clk_hw * __init
+at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
+                           const char **parent_names, u8 num_parents);
+struct clk_hw * __init
+at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
+                            const char *parent_name);
+struct clk_hw * __init
+at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
+                           const char *parent_name, const u32 *divisors);
+
+struct clk_hw * __init
+at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
+                      const char *name, const char *parent_name);
+
 #ifdef CONFIG_PM
 void pmc_register_id(u8 id);
 void pmc_register_pck(u8 pck);
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
new file mode 100644 (file)
index 0000000..d69ad96
--- /dev/null
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics mck_characteristics = {
+       .output = { .min = 124000000, .max = 166000000 },
+       .divisors = { 1, 2, 4, 3 },
+};
+
+static u8 plla_out[] = { 0 };
+
+static u16 plla_icpll[] = { 0 };
+
+static struct clk_range plla_outputs[] = {
+       { .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+       .input = { .min = 12000000, .max = 12000000 },
+       .num_output = ARRAY_SIZE(plla_outputs),
+       .output = plla_outputs,
+       .icpll = plla_icpll,
+       .out = plla_out,
+};
+
+static const struct {
+       char *n;
+       char *p;
+       u8 id;
+} sama5d2_systemck[] = {
+       { .n = "ddrck", .p = "masterck", .id = 2 },
+       { .n = "lcdck", .p = "masterck", .id = 3 },
+       { .n = "uhpck", .p = "usbck",    .id = 6 },
+       { .n = "udpck", .p = "usbck",    .id = 7 },
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+       { .n = "pck2",  .p = "prog2",    .id = 10 },
+       { .n = "iscck", .p = "masterck", .id = 18 },
+};
+
+static const struct {
+       char *n;
+       u8 id;
+       struct clk_range r;
+} sama5d2_periph32ck[] = {
+       { .n = "macb0_clk",   .id = 5,  .r = { .min = 0, .max = 83000000 }, },
+       { .n = "tdes_clk",    .id = 11, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "matrix1_clk", .id = 14, },
+       { .n = "hsmc_clk",    .id = 17, },
+       { .n = "pioA_clk",    .id = 18, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "flx0_clk",    .id = 19, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "flx1_clk",    .id = 20, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "flx2_clk",    .id = 21, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "flx3_clk",    .id = 22, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "flx4_clk",    .id = 23, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "uart0_clk",   .id = 24, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "uart1_clk",   .id = 25, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "uart2_clk",   .id = 26, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "uart3_clk",   .id = 27, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "uart4_clk",   .id = 28, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "twi0_clk",    .id = 29, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "twi1_clk",    .id = 30, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "spi0_clk",    .id = 33, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "spi1_clk",    .id = 34, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "tcb0_clk",    .id = 35, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "tcb1_clk",    .id = 36, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "pwm_clk",     .id = 38, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "adc_clk",     .id = 40, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "uhphs_clk",   .id = 41, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "udphs_clk",   .id = 42, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "ssc0_clk",    .id = 43, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "ssc1_clk",    .id = 44, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "trng_clk",    .id = 47, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "pdmic_clk",   .id = 48, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "securam_clk", .id = 51, },
+       { .n = "i2s0_clk",    .id = 54, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "i2s1_clk",    .id = 55, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "can0_clk",    .id = 56, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "can1_clk",    .id = 57, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "classd_clk",  .id = 59, .r = { .min = 0, .max = 83000000 }, },
+};
+
+static const struct {
+       char *n;
+       u8 id;
+} sama5d2_periphck[] = {
+       { .n = "dma0_clk",    .id = 6, },
+       { .n = "dma1_clk",    .id = 7, },
+       { .n = "aes_clk",     .id = 9, },
+       { .n = "aesb_clk",    .id = 10, },
+       { .n = "sha_clk",     .id = 12, },
+       { .n = "mpddr_clk",   .id = 13, },
+       { .n = "matrix0_clk", .id = 15, },
+       { .n = "sdmmc0_hclk", .id = 31, },
+       { .n = "sdmmc1_hclk", .id = 32, },
+       { .n = "lcdc_clk",    .id = 45, },
+       { .n = "isc_clk",     .id = 46, },
+       { .n = "qspi0_clk",   .id = 52, },
+       { .n = "qspi1_clk",   .id = 53, },
+};
+
+static const struct {
+       char *n;
+       u8 id;
+       struct clk_range r;
+       bool pll;
+} sama5d2_gck[] = {
+       { .n = "sdmmc0_gclk", .id = 31, },
+       { .n = "sdmmc1_gclk", .id = 32, },
+       { .n = "tcb0_gclk",   .id = 35, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "tcb1_gclk",   .id = 36, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "pwm_gclk",    .id = 38, .r = { .min = 0, .max = 83000000 }, },
+       { .n = "isc_gclk",    .id = 46, },
+       { .n = "pdmic_gclk",  .id = 48, },
+       { .n = "i2s0_gclk",   .id = 54, .pll = true },
+       { .n = "i2s1_gclk",   .id = 55, .pll = true },
+       { .n = "can0_gclk",   .id = 56, .r = { .min = 0, .max = 80000000 }, },
+       { .n = "can1_gclk",   .id = 57, .r = { .min = 0, .max = 80000000 }, },
+       { .n = "classd_gclk", .id = 59, .r = { .min = 0, .max = 100000000 },
+         .pll = true },
+};
+
+static void __init sama5d2_pmc_setup(struct device_node *np)
+{
+       struct clk_range range = CLK_RANGE(0, 0);
+       const char *slck_name, *mainxtal_name;
+       struct pmc_data *sama5d2_pmc;
+       const char *parent_names[6];
+       struct regmap *regmap, *regmap_sfr;
+       struct clk_hw *hw;
+       int i;
+       bool bypass;
+
+       i = of_property_match_string(np, "clock-names", "slow_clk");
+       if (i < 0)
+               return;
+
+       slck_name = of_clk_get_parent_name(np, i);
+
+       i = of_property_match_string(np, "clock-names", "main_xtal");
+       if (i < 0)
+               return;
+       mainxtal_name = of_clk_get_parent_name(np, i);
+
+       regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(regmap))
+               return;
+
+       sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
+                                       nck(sama5d2_systemck),
+                                       nck(sama5d2_periph32ck),
+                                       nck(sama5d2_gck));
+       if (!sama5d2_pmc)
+               return;
+
+       hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+                                          100000000);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+       hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
+                                       bypass);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = "main_rc_osc";
+       parent_names[1] = "main_osc";
+       hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d2_pmc->chws[PMC_MAIN] = hw;
+
+       hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+                                  &sama5d3_pll_layout, &plla_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
+                                             "mainck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_audio_pll_pad(regmap, "audiopll_padck",
+                                            "audiopll_fracck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_audio_pll_pmc(regmap, "audiopll_pmcck",
+                                            "audiopll_fracck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+       if (IS_ERR(regmap_sfr))
+               regmap_sfr = NULL;
+
+       hw = at91_clk_register_utmi(regmap, regmap_sfr, "utmick", "mainck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d2_pmc->chws[PMC_UTMI] = hw;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+                                     &at91sam9x5_master_layout,
+                                     &mck_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d2_pmc->chws[PMC_MCK] = hw;
+
+       hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d2_pmc->chws[PMC_MCK2] = hw;
+
+       parent_names[0] = "plladivck";
+       parent_names[1] = "utmick";
+       hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       parent_names[4] = "mck";
+       for (i = 0; i < 3; i++) {
+               char name[6];
+
+               snprintf(name, sizeof(name), "prog%d", i);
+
+               hw = at91_clk_register_programmable(regmap, name,
+                                                   parent_names, 5, i,
+                                                   &at91sam9x5_programmable_layout);
+               if (IS_ERR(hw))
+                       goto err_free;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
+               hw = at91_clk_register_system(regmap, sama5d2_systemck[i].n,
+                                             sama5d2_systemck[i].p,
+                                             sama5d2_systemck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d2_pmc->shws[sama5d2_systemck[i].id] = hw;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sama5d2_periphck); i++) {
+               hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+                                                        sama5d2_periphck[i].n,
+                                                        "masterck",
+                                                        sama5d2_periphck[i].id,
+                                                        &range);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d2_pmc->phws[sama5d2_periphck[i].id] = hw;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sama5d2_periph32ck); i++) {
+               hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+                                                        sama5d2_periph32ck[i].n,
+                                                        "h32mxck",
+                                                        sama5d2_periph32ck[i].id,
+                                                        &sama5d2_periph32ck[i].r);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d2_pmc->phws[sama5d2_periph32ck[i].id] = hw;
+       }
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       parent_names[4] = "mck";
+       parent_names[5] = "audiopll_pmcck";
+       for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) {
+               hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+                                                sama5d2_gck[i].n,
+                                                parent_names, 6,
+                                                sama5d2_gck[i].id,
+                                                sama5d2_gck[i].pll,
+                                                &sama5d2_gck[i].r);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d2_pmc->ghws[sama5d2_gck[i].id] = hw;
+       }
+
+       if (regmap_sfr) {
+               parent_names[0] = "i2s0_clk";
+               parent_names[1] = "i2s0_gclk";
+               hw = at91_clk_i2s_mux_register(regmap_sfr, "i2s0_muxclk",
+                                              parent_names, 2, 0);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d2_pmc->chws[PMC_I2S0_MUX] = hw;
+
+               parent_names[0] = "i2s1_clk";
+               parent_names[1] = "i2s1_gclk";
+               hw = at91_clk_i2s_mux_register(regmap_sfr, "i2s1_muxclk",
+                                              parent_names, 2, 1);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d2_pmc->chws[PMC_I2S1_MUX] = hw;
+       }
+
+       of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama5d2_pmc);
+
+       return;
+
+err_free:
+       pmc_data_free(sama5d2_pmc);
+}
+CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
new file mode 100644 (file)
index 0000000..e358be7
--- /dev/null
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics mck_characteristics = {
+       .output = { .min = 125000000, .max = 200000000 },
+       .divisors = { 1, 2, 4, 3 },
+};
+
+static u8 plla_out[] = { 0 };
+
+static u16 plla_icpll[] = { 0 };
+
+static struct clk_range plla_outputs[] = {
+       { .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+       .input = { .min = 12000000, .max = 12000000 },
+       .num_output = ARRAY_SIZE(plla_outputs),
+       .output = plla_outputs,
+       .icpll = plla_icpll,
+       .out = plla_out,
+};
+
+static const struct {
+       char *n;
+       char *p;
+       u8 id;
+} sama5d4_systemck[] = {
+       { .n = "ddrck", .p = "masterck", .id = 2 },
+       { .n = "lcdck", .p = "masterck", .id = 3 },
+       { .n = "smdck", .p = "smdclk",   .id = 4 },
+       { .n = "uhpck", .p = "usbck",    .id = 6 },
+       { .n = "udpck", .p = "usbck",    .id = 7 },
+       { .n = "pck0",  .p = "prog0",    .id = 8 },
+       { .n = "pck1",  .p = "prog1",    .id = 9 },
+       { .n = "pck2",  .p = "prog2",    .id = 10 },
+};
+
+static const struct {
+       char *n;
+       u8 id;
+} sama5d4_periph32ck[] = {
+       { .n = "pioD_clk", .id = 5 },
+       { .n = "usart0_clk", .id = 6 },
+       { .n = "usart1_clk", .id = 7 },
+       { .n = "icm_clk", .id = 9 },
+       { .n = "aes_clk", .id = 12 },
+       { .n = "tdes_clk", .id = 14 },
+       { .n = "sha_clk", .id = 15 },
+       { .n = "matrix1_clk", .id = 17 },
+       { .n = "hsmc_clk", .id = 22 },
+       { .n = "pioA_clk", .id = 23 },
+       { .n = "pioB_clk", .id = 24 },
+       { .n = "pioC_clk", .id = 25 },
+       { .n = "pioE_clk", .id = 26 },
+       { .n = "uart0_clk", .id = 27 },
+       { .n = "uart1_clk", .id = 28 },
+       { .n = "usart2_clk", .id = 29 },
+       { .n = "usart3_clk", .id = 30 },
+       { .n = "usart4_clk", .id = 31 },
+       { .n = "twi0_clk", .id = 32 },
+       { .n = "twi1_clk", .id = 33 },
+       { .n = "twi2_clk", .id = 34 },
+       { .n = "mci0_clk", .id = 35 },
+       { .n = "mci1_clk", .id = 36 },
+       { .n = "spi0_clk", .id = 37 },
+       { .n = "spi1_clk", .id = 38 },
+       { .n = "spi2_clk", .id = 39 },
+       { .n = "tcb0_clk", .id = 40 },
+       { .n = "tcb1_clk", .id = 41 },
+       { .n = "tcb2_clk", .id = 42 },
+       { .n = "pwm_clk", .id = 43 },
+       { .n = "adc_clk", .id = 44 },
+       { .n = "dbgu_clk", .id = 45 },
+       { .n = "uhphs_clk", .id = 46 },
+       { .n = "udphs_clk", .id = 47 },
+       { .n = "ssc0_clk", .id = 48 },
+       { .n = "ssc1_clk", .id = 49 },
+       { .n = "trng_clk", .id = 53 },
+       { .n = "macb0_clk", .id = 54 },
+       { .n = "macb1_clk", .id = 55 },
+       { .n = "fuse_clk", .id = 57 },
+       { .n = "securam_clk", .id = 59 },
+       { .n = "smd_clk", .id = 61 },
+       { .n = "twi3_clk", .id = 62 },
+       { .n = "catb_clk", .id = 63 },
+};
+
+static const struct {
+       char *n;
+       u8 id;
+} sama5d4_periphck[] = {
+       { .n = "dma0_clk", .id = 8 },
+       { .n = "cpkcc_clk", .id = 10 },
+       { .n = "aesb_clk", .id = 13 },
+       { .n = "mpddr_clk", .id = 16 },
+       { .n = "matrix0_clk", .id = 18 },
+       { .n = "vdec_clk", .id = 19 },
+       { .n = "dma1_clk", .id = 50 },
+       { .n = "lcdc_clk", .id = 51 },
+       { .n = "isi_clk", .id = 52 },
+};
+
+static void __init sama5d4_pmc_setup(struct device_node *np)
+{
+       struct clk_range range = CLK_RANGE(0, 0);
+       const char *slck_name, *mainxtal_name;
+       struct pmc_data *sama5d4_pmc;
+       const char *parent_names[5];
+       struct regmap *regmap;
+       struct clk_hw *hw;
+       int i;
+       bool bypass;
+
+       i = of_property_match_string(np, "clock-names", "slow_clk");
+       if (i < 0)
+               return;
+
+       slck_name = of_clk_get_parent_name(np, i);
+
+       i = of_property_match_string(np, "clock-names", "main_xtal");
+       if (i < 0)
+               return;
+       mainxtal_name = of_clk_get_parent_name(np, i);
+
+       regmap = syscon_node_to_regmap(np);
+       if (IS_ERR(regmap))
+               return;
+
+       sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
+                                       nck(sama5d4_systemck),
+                                       nck(sama5d4_periph32ck), 0);
+       if (!sama5d4_pmc)
+               return;
+
+       hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+                                          100000000);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+       hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
+                                       bypass);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = "main_rc_osc";
+       parent_names[1] = "main_osc";
+       hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+                                  &sama5d3_pll_layout, &plla_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d4_pmc->chws[PMC_UTMI] = hw;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+                                     &at91sam9x5_master_layout,
+                                     &mck_characteristics);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d4_pmc->chws[PMC_MCK] = hw;
+
+       hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck");
+       if (IS_ERR(hw))
+               goto err_free;
+
+       sama5d4_pmc->chws[PMC_MCK2] = hw;
+
+       parent_names[0] = "plladivck";
+       parent_names[1] = "utmick";
+       hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = "plladivck";
+       parent_names[1] = "utmick";
+       hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2);
+       if (IS_ERR(hw))
+               goto err_free;
+
+       parent_names[0] = slck_name;
+       parent_names[1] = "mainck";
+       parent_names[2] = "plladivck";
+       parent_names[3] = "utmick";
+       parent_names[4] = "mck";
+       for (i = 0; i < 3; i++) {
+               char name[6];
+
+               snprintf(name, sizeof(name), "prog%d", i);
+
+               hw = at91_clk_register_programmable(regmap, name,
+                                                   parent_names, 5, i,
+                                                   &at91sam9x5_programmable_layout);
+               if (IS_ERR(hw))
+                       goto err_free;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
+               hw = at91_clk_register_system(regmap, sama5d4_systemck[i].n,
+                                             sama5d4_systemck[i].p,
+                                             sama5d4_systemck[i].id);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d4_pmc->shws[sama5d4_systemck[i].id] = hw;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) {
+               hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+                                                        sama5d4_periphck[i].n,
+                                                        "masterck",
+                                                        sama5d4_periphck[i].id,
+                                                        &range);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d4_pmc->phws[sama5d4_periphck[i].id] = hw;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) {
+               hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+                                                        sama5d4_periph32ck[i].n,
+                                                        "h32mxck",
+                                                        sama5d4_periph32ck[i].id,
+                                                        &range);
+               if (IS_ERR(hw))
+                       goto err_free;
+
+               sama5d4_pmc->phws[sama5d4_periph32ck[i].id] = hw;
+       }
+
+       of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama5d4_pmc);
+
+       return;
+
+err_free:
+       pmc_data_free(sama5d4_pmc);
+}
+CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
index 25d8c240ddfb0f5d2fc61847f11b35badc69d441..c68dada973168474ff063b2eba98a11bfec5556e 100644 (file)
@@ -301,13 +301,13 @@ static void __init of_axs10x_pll_clk_setup(struct device_node *node)
 
        ret = clk_hw_register(NULL, &pll_clk->hw);
        if (ret) {
-               pr_err("failed to register %s clock\n", node->name);
+               pr_err("failed to register %pOFn clock\n", node);
                goto err_unmap_lock;
        }
 
        ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw);
        if (ret) {
-               pr_err("failed to add hw provider for %s clock\n", node->name);
+               pr_err("failed to add hw provider for %pOFn clock\n", node);
                goto err_unregister_clk;
        }
 
index 281f4322355c135eded2fc5533a54498a0f0f49f..e65eeef9cbaf16ad3ba4238f0f17a12e70eb6915 100644 (file)
@@ -808,29 +808,29 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
 
        ret = of_address_to_resource(node, 0, &res);
        if (ret) {
-               pr_err("%s: no valid CCU registers found for %s\n", __func__,
-                       node->name);
+               pr_err("%s: no valid CCU registers found for %pOFn\n", __func__,
+                       node);
                goto out_err;
        }
 
        range = resource_size(&res);
        if (range > (resource_size_t)U32_MAX) {
-               pr_err("%s: address range too large for %s\n", __func__,
-                       node->name);
+               pr_err("%s: address range too large for %pOFn\n", __func__,
+                       node);
                goto out_err;
        }
 
        ccu->range = (u32)range;
 
        if (!ccu_data_valid(ccu)) {
-               pr_err("%s: ccu data not valid for %s\n", __func__, node->name);
+               pr_err("%s: ccu data not valid for %pOFn\n", __func__, node);
                goto out_err;
        }
 
        ccu->base = ioremap(res.start, ccu->range);
        if (!ccu->base) {
-               pr_err("%s: unable to map CCU registers for %s\n", __func__,
-                       node->name);
+               pr_err("%s: unable to map CCU registers for %pOFn\n", __func__,
+                       node);
                goto out_err;
        }
        ccu->node = of_node_get(node);
@@ -848,16 +848,16 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
 
        ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu);
        if (ret) {
-               pr_err("%s: error adding ccu %s as provider (%d)\n", __func__,
-                               node->name, ret);
+               pr_err("%s: error adding ccu %pOFn as provider (%d)\n", __func__,
+                               node, ret);
                goto out_err;
        }
 
        if (!kona_ccu_init(ccu))
-               pr_err("Broadcom %s initialization had errors\n", node->name);
+               pr_err("Broadcom %pOFn initialization had errors\n", node);
 
        return;
 out_err:
        kona_ccu_teardown(ccu);
-       pr_err("Broadcom %s setup aborted\n", node->name);
+       pr_err("Broadcom %pOFn setup aborted\n", node);
 }
index 44b5441571210468e99cce9d9269dfc57c4bca46..d571a00b5282d2b18774efc21c3d6aea0c660e09 100644 (file)
@@ -281,7 +281,7 @@ static void __init asm9260_acc_init(struct device_node *np)
 
        base = of_io_request_and_map(np, 0, np->name);
        if (IS_ERR(base))
-               panic("%s: unable to map resource", np->name);
+               panic("%pOFn: unable to map resource", np);
 
        /* register pll */
        rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
@@ -292,7 +292,7 @@ static void __init asm9260_acc_init(struct device_node *np)
                        ref_clk, 0, rate, accuracy);
 
        if (IS_ERR(hw))
-               panic("%s: can't register REFCLK. Check DT!", np->name);
+               panic("%pOFn: can't register REFCLK. Check DT!", np);
 
        for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
                const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
index 6904ed6da504b0690b3e0a3525370848d080f566..6a7118d4250a6a0409a1d080936e1d1e74bbfb42 100644 (file)
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/export.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
+                                       struct clk_bulk_data *clks)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < num_clks; i++)
+               clks[i].clk = NULL;
+
+       for (i = 0; i < num_clks; i++) {
+               clks[i].clk = of_clk_get(np, i);
+               if (IS_ERR(clks[i].clk)) {
+                       ret = PTR_ERR(clks[i].clk);
+                       pr_err("%pOF: Failed to get clk index: %d ret: %d\n",
+                              np, i, ret);
+                       clks[i].clk = NULL;
+                       goto err;
+               }
+       }
+
+       return 0;
+
+err:
+       clk_bulk_put(i, clks);
+
+       return ret;
+}
+
+static int __must_check of_clk_bulk_get_all(struct device_node *np,
+                                           struct clk_bulk_data **clks)
+{
+       struct clk_bulk_data *clk_bulk;
+       int num_clks;
+       int ret;
+
+       num_clks = of_clk_get_parent_count(np);
+       if (!num_clks)
+               return 0;
+
+       clk_bulk = kmalloc_array(num_clks, sizeof(*clk_bulk), GFP_KERNEL);
+       if (!clk_bulk)
+               return -ENOMEM;
+
+       ret = of_clk_bulk_get(np, num_clks, clk_bulk);
+       if (ret) {
+               kfree(clk_bulk);
+               return ret;
+       }
+
+       *clks = clk_bulk;
+
+       return num_clks;
+}
 
 void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
 {
@@ -59,6 +116,29 @@ err:
 }
 EXPORT_SYMBOL(clk_bulk_get);
 
+void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks)
+{
+       if (IS_ERR_OR_NULL(clks))
+               return;
+
+       clk_bulk_put(num_clks, clks);
+
+       kfree(clks);
+}
+EXPORT_SYMBOL(clk_bulk_put_all);
+
+int __must_check clk_bulk_get_all(struct device *dev,
+                                 struct clk_bulk_data **clks)
+{
+       struct device_node *np = dev_of_node(dev);
+
+       if (!np)
+               return 0;
+
+       return of_clk_bulk_get_all(np, clks);
+}
+EXPORT_SYMBOL(clk_bulk_get_all);
+
 #ifdef CONFIG_HAVE_CLK_PREPARE
 
 /**
index 0a7e7d5a750605c5be12d953ac912f3fb9105962..23c9326ea48c5ef0bc3b5ef00bf9fbbd67e166c8 100644 (file)
@@ -669,8 +669,8 @@ static int cdce925_probe(struct i2c_client *client,
 
        /* Register PLL clocks */
        for (i = 0; i < data->chip_info->num_plls; ++i) {
-               pll_clk_name[i] = kasprintf(GFP_KERNEL, "%s.pll%d",
-                       client->dev.of_node->name, i);
+               pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d",
+                       client->dev.of_node, i);
                init.name = pll_clk_name[i];
                data->pll[i].chip = data;
                data->pll[i].hw.init = &init;
@@ -703,6 +703,7 @@ static int cdce925_probe(struct i2c_client *client,
                                0x12 + (i*CDCE925_OFFSET_PLL),
                                0x07, value & 0x07);
                }
+               of_node_put(np_output);
        }
 
        /* Register output clock Y1 */
@@ -710,7 +711,7 @@ static int cdce925_probe(struct i2c_client *client,
        init.flags = 0;
        init.num_parents = 1;
        init.parent_names = &parent_name; /* Mux Y1 to input */
-       init.name = kasprintf(GFP_KERNEL, "%s.Y1", client->dev.of_node->name);
+       init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node);
        data->clk[0].chip = data;
        data->clk[0].hw.init = &init;
        data->clk[0].index = 0;
@@ -727,8 +728,8 @@ static int cdce925_probe(struct i2c_client *client,
        init.flags = CLK_SET_RATE_PARENT;
        init.num_parents = 1;
        for (i = 1; i < data->chip_info->num_outputs; ++i) {
-               init.name = kasprintf(GFP_KERNEL, "%s.Y%d",
-                       client->dev.of_node->name, i+1);
+               init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d",
+                       client->dev.of_node, i+1);
                data->clk[i].chip = data;
                data->clk[i].hw.init = &init;
                data->clk[i].index = i;
index d854e26a8ddbca3dfb96aad123e974f2175cc455..12c87457eca1e73d4c568bc34a98296c961c6c3c 100644 (file)
@@ -70,6 +70,30 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
 }
 EXPORT_SYMBOL_GPL(devm_clk_bulk_get);
 
+int __must_check devm_clk_bulk_get_all(struct device *dev,
+                                      struct clk_bulk_data **clks)
+{
+       struct clk_bulk_devres *devres;
+       int ret;
+
+       devres = devres_alloc(devm_clk_bulk_release,
+                             sizeof(*devres), GFP_KERNEL);
+       if (!devres)
+               return -ENOMEM;
+
+       ret = clk_bulk_get_all(dev, &devres->clks);
+       if (ret > 0) {
+               *clks = devres->clks;
+               devres->num_clks = ret;
+               devres_add(dev, devres);
+       } else {
+               devres_free(devres);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
        struct clk **c = res;
index 20724abd38bd132205713cce2e7960324652d12b..ef0ca9414f371bc3275b7afce529029e10b49f68 100644 (file)
@@ -158,14 +158,14 @@ static struct clk *_of_fixed_factor_clk_setup(struct device_node *node)
        int ret;
 
        if (of_property_read_u32(node, "clock-div", &div)) {
-               pr_err("%s Fixed factor clock <%s> must have a clock-div property\n",
-                       __func__, node->name);
+               pr_err("%s Fixed factor clock <%pOFn> must have a clock-div property\n",
+                       __func__, node);
                return ERR_PTR(-EIO);
        }
 
        if (of_property_read_u32(node, "clock-mult", &mult)) {
-               pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n",
-                       __func__, node->name);
+               pr_err("%s Fixed factor clock <%pOFn> must have a clock-mult property\n",
+                       __func__, node);
                return ERR_PTR(-EIO);
        }
 
index b5c46b3f8764d491da0f8586de8b18eb6d6f4527..6d6475c32ee51612df97f7fcce8c952a004ccdeb 100644 (file)
@@ -200,6 +200,7 @@ static int of_fixed_clk_remove(struct platform_device *pdev)
 {
        struct clk *clk = platform_get_drvdata(pdev);
 
+       of_clk_del_provider(pdev->dev.of_node);
        clk_unregister_fixed_rate(clk);
 
        return 0;
index 40af4fbab4d23f24acda1ab07fe1df887131c243..6a43ce420492f143be8eee203633d2faa2b7942e 100644 (file)
@@ -233,11 +233,11 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
        if (IS_ERR(gpiod)) {
                ret = PTR_ERR(gpiod);
                if (ret == -EPROBE_DEFER)
-                       pr_debug("%s: %s: GPIOs not yet available, retry later\n",
-                                       node->name, __func__);
+                       pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n",
+                                       node, __func__);
                else
-                       pr_err("%s: %s: Can't get '%s' named GPIO property\n",
-                                       node->name, __func__,
+                       pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n",
+                                       node, __func__,
                                        gpio_name);
                return ret;
        }
index c4ee280f454d9213b2bd1a82ac576e7fd790fb42..a47c2b600f20c188fde5c037321afe960dbcd7d9 100644 (file)
@@ -390,13 +390,13 @@ static void __init of_hsdk_pll_clk_setup(struct device_node *node)
 
        ret = clk_hw_register(NULL, &pll_clk->hw);
        if (ret) {
-               pr_err("failed to register %s clock\n", node->name);
+               pr_err("failed to register %pOFn clock\n", node);
                goto err_unmap_spec_regs;
        }
 
        ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw);
        if (ret) {
-               pr_err("failed to add hw provider for %s clock\n", node->name);
+               pr_err("failed to add hw provider for %pOFn clock\n", node);
                goto err_unmap_spec_regs;
        }
 
index eb953d3b0b69bef048312fe9b6ec3c2678d815bb..02551fe4b87c5461c69d88a66b5b2f5b8fefbd6d 100644 (file)
@@ -1,24 +1,9 @@
-/*
- * clk-max77686.c - Clock driver for Maxim 77686/MAX77802
- *
- * Copyright (C) 2012 Samsung Electornics
- * Jonghwa Lee <jonghwa3.lee@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// clk-max77686.c - Clock driver for Maxim 77686/MAX77802
+//
+// Copyright (C) 2012 Samsung Electornics
+// Jonghwa Lee <jonghwa3.lee@samsung.com>
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
index 13ad6d1e509082f12b0466acb127c3cffc858cba..84a24875c6298a3e6ee1ba9688bcef826056e3ca 100644 (file)
@@ -97,8 +97,8 @@ static void __init nomadik_src_init(void)
        }
        src_base = of_iomap(np, 0);
        if (!src_base) {
-               pr_err("%s: must have src parent node with REGS (%s)\n",
-                      __func__, np->name);
+               pr_err("%s: must have src parent node with REGS (%pOFn)\n",
+                      __func__, np);
                return;
        }
 
index c5edf8f2fd1969337b7803ef96884ee9164495fb..27a86b7a34dbf64df553ac8283904310cc2da24c 100644 (file)
@@ -549,7 +549,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
 
        ret = of_address_to_resource(clk_np, 0, &res);
        if (ret) {
-               pr_err("%s: failed to get resource, ret %d\n", clk_np->name,
+               pr_err("%pOFn: failed to get resource, ret %d\n", clk_np,
                        ret);
                return;
        }
index 7f51c01085abee76a30828f08b52bac935f172d5..e9612e7068e9e80175e81645d8641b898c68d358 100644 (file)
@@ -195,8 +195,8 @@ static void palmas_clks_get_clk_data(struct platform_device *pdev,
                prop = PALMAS_EXT_CONTROL_NSLEEP;
                break;
        default:
-               dev_warn(&pdev->dev, "%s: Invalid ext control option: %u\n",
-                        node->name, prop);
+               dev_warn(&pdev->dev, "%pOFn: Invalid ext control option: %u\n",
+                        node, prop);
                prop = 0;
                break;
        }
index 3a1812f65e5d823242d4428672736ce04f865a33..4c30b6e799ed1ea1e22dcc8f920ec54309a024f6 100644 (file)
@@ -945,8 +945,8 @@ static void __init core_mux_init(struct device_node *np)
 
        rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
        if (rc) {
-               pr_err("%s: Couldn't register clk provider for node %s: %d\n",
-                      __func__, np->name, rc);
+               pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n",
+                      __func__, np, rc);
                return;
        }
 }
@@ -1199,8 +1199,8 @@ static void __init legacy_pll_init(struct device_node *np, int idx)
 
        rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
        if (rc) {
-               pr_err("%s: Couldn't register clk provider for node %s: %d\n",
-                      __func__, np->name, rc);
+               pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n",
+                      __func__, np, rc);
                goto err_cell;
        }
 
@@ -1360,7 +1360,7 @@ static void __init clockgen_init(struct device_node *np)
                is_old_ls1021a = true;
        }
        if (!clockgen.regs) {
-               pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name);
+               pr_err("%s(): %pOFn: of_iomap() failed\n", __func__, np);
                return;
        }
 
@@ -1406,8 +1406,8 @@ static void __init clockgen_init(struct device_node *np)
 
        ret = of_clk_add_provider(np, clockgen_clk_get, &clockgen);
        if (ret) {
-               pr_err("%s: Couldn't register clk provider for node %s: %d\n",
-                      __func__, np->name, ret);
+               pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n",
+                      __func__, np, ret);
        }
 
        return;
index d44e0eea31ec6de81e471469eee884f37a559fca..5b419b82f7ca1c57d8e687c459f33753b7014f7a 100644 (file)
@@ -1,19 +1,8 @@
-/*
- * clk-s2mps11.c - Clock driver for S2MPS11.
- *
- * Copyright (C) 2013,2014 Samsung Electornics
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// clk-s2mps11.c - Clock driver for S2MPS11.
+//
+// Copyright (C) 2013,2014 Samsung Electornics
 
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/mfd/samsung/s5m8767.h>
 #include <linux/mfd/samsung/core.h>
 
-enum {
-       S2MPS11_CLK_AP = 0,
-       S2MPS11_CLK_CP,
-       S2MPS11_CLK_BT,
-       S2MPS11_CLKS_NUM,
-};
+#include <dt-bindings/clock/samsung,s2mps11.h>
 
 struct s2mps11_clk {
        struct sec_pmic_dev *iodev;
@@ -245,6 +229,36 @@ static const struct platform_device_id s2mps11_clk_id[] = {
 };
 MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
 
+#ifdef CONFIG_OF
+/*
+ * Device is instantiated through parent MFD device and device matching is done
+ * through platform_device_id.
+ *
+ * However if device's DT node contains proper clock compatible and driver is
+ * built as a module, then the *module* matching will be done trough DT aliases.
+ * This requires of_device_id table.  In the same time this will not change the
+ * actual *device* matching so do not add .of_match_table.
+ */
+static const struct of_device_id s2mps11_dt_match[] __used = {
+       {
+               .compatible = "samsung,s2mps11-clk",
+               .data = (void *)S2MPS11X,
+       }, {
+               .compatible = "samsung,s2mps13-clk",
+               .data = (void *)S2MPS13X,
+       }, {
+               .compatible = "samsung,s2mps14-clk",
+               .data = (void *)S2MPS14X,
+       }, {
+               .compatible = "samsung,s5m8767-clk",
+               .data = (void *)S5M8767X,
+       }, {
+               /* Sentinel */
+       },
+};
+MODULE_DEVICE_TABLE(of, s2mps11_dt_match);
+#endif
+
 static struct platform_driver s2mps11_clk_driver = {
        .driver = {
                .name  = "s2mps11-clk",
index a985bf5e1ac61e6df1a56e153ed75640e0161072..a2287c770d5c07408365b89a49450c554f48d55a 100644 (file)
@@ -132,7 +132,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 
        count = handle->clk_ops->count_get(handle);
        if (count < 0) {
-               dev_err(dev, "%s: invalid clock output count\n", np->name);
+               dev_err(dev, "%pOFn: invalid clock output count\n", np);
                return -EINVAL;
        }
 
index 25854722810ed7791afd9830de51794e20ad676f..d3ccc1cfccd5e10619acb4056d40c5b1fe963b56 100644 (file)
@@ -207,7 +207,7 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
 
        count = of_property_count_strings(np, "clock-output-names");
        if (count < 0) {
-               dev_err(dev, "%s: invalid clock output count\n", np->name);
+               dev_err(dev, "%pOFn: invalid clock output count\n", np);
                return -EINVAL;
        }
 
@@ -232,13 +232,13 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
 
                if (of_property_read_string_index(np, "clock-output-names",
                                                  idx, &name)) {
-                       dev_err(dev, "invalid clock name @ %s\n", np->name);
+                       dev_err(dev, "invalid clock name @ %pOFn\n", np);
                        return -EINVAL;
                }
 
                if (of_property_read_u32_index(np, "clock-indices",
                                               idx, &val)) {
-                       dev_err(dev, "invalid clock index @ %s\n", np->name);
+                       dev_err(dev, "invalid clock index @ %pOFn\n", np);
                        return -EINVAL;
                }
 
index 50e7c341e97e91c6faaaef55bbdd27645248679c..8bdf91b560125afb47b0afc20b72c3373aa917d0 100644 (file)
@@ -1215,8 +1215,8 @@ static int si5351_dt_parse(struct i2c_client *client,
        /* per clkout properties */
        for_each_child_of_node(np, child) {
                if (of_property_read_u32(child, "reg", &num)) {
-                       dev_err(&client->dev, "missing reg property of %s\n",
-                               child->name);
+                       dev_err(&client->dev, "missing reg property of %pOFn\n",
+                               child);
                        goto put_child;
                }
 
index 294850bdc195d7923f684dd5d5f17eb7f883ed68..cdaa567c8042eea0e5ee29ec7775bdc97e295a3d 100644 (file)
@@ -1433,7 +1433,7 @@ static void __init stm32f4_rcc_init(struct device_node *np)
 
        base = of_iomap(np, 0);
        if (!base) {
-               pr_err("%s: unable to map resource\n", np->name);
+               pr_err("%pOFn: unable to map resource\n", np);
                return;
        }
 
index d3271eca3779026d3a0316c381de13ca2d10411e..0ea7261d15e07ca0b7d859b29412f62a323d3e4f 100644 (file)
@@ -1216,7 +1216,7 @@ static void __init stm32h7_rcc_init(struct device_node *np)
        /* get RCC base @ from DT */
        base = of_iomap(np, 0);
        if (!base) {
-               pr_err("%s: unable to map resource", np->name);
+               pr_err("%pOFn: unable to map resource", np);
                goto err_free_clks;
        }
 
index a907555b2a3d8f5c7882e5be1e080eed5fda1767..4f48342bc2802bd7a9c9402594e035a1c97ad91a 100644 (file)
@@ -2088,7 +2088,7 @@ static void stm32mp1_rcc_init(struct device_node *np)
 
        base = of_iomap(np, 0);
        if (!base) {
-               pr_err("%s: unable to map resource", np->name);
+               pr_err("%pOFn: unable to map resource", np);
                of_node_put(np);
                return;
        }
index 34b22b7930fbc0483611c8e752fb93db30e64b8d..fe12a43f7a4008011aa9c8af774150abbeb19354 100644 (file)
@@ -54,13 +54,13 @@ static void __init tango4_clkgen_setup(struct device_node *np)
        const char *parent = of_clk_get_parent_name(np, 0);
 
        if (!base)
-               panic("%s: invalid address\n", np->name);
+               panic("%pOFn: invalid address\n", np);
 
        if (readl(base + CPUCLK_DIV) & DIV_BYPASS)
-               panic("%s: unsupported cpuclk setup\n", np->name);
+               panic("%pOFn: unsupported cpuclk setup\n", np);
 
        if (readl(base + SYSCLK_DIV) & DIV_BYPASS)
-               panic("%s: unsupported sysclk setup\n", np->name);
+               panic("%pOFn: unsupported sysclk setup\n", np);
 
        writel(0x100, base + CPUCLK_DIV); /* disable frequency ramping */
 
@@ -77,9 +77,9 @@ static void __init tango4_clkgen_setup(struct device_node *np)
        pp[3] = clk_register_fixed_factor(NULL, "sdio_clk", "cd6", 0, 1, 2);
 
        if (IS_ERR(pp[0]) || IS_ERR(pp[1]) || IS_ERR(pp[2]) || IS_ERR(pp[3]))
-               panic("%s: clk registration failed\n", np->name);
+               panic("%pOFn: clk registration failed\n", np);
 
        if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data))
-               panic("%s: clk provider registration failed\n", np->name);
+               panic("%pOFn: clk provider registration failed\n", np);
 }
 CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup);
index d31055ae6ec6f94c23409df9f47936f09b54c1bf..af011974d4ecbf1226fa0d4ecb3db66bf2514afc 100644 (file)
@@ -923,6 +923,101 @@ static int clk_core_enable_lock(struct clk_core *core)
        return ret;
 }
 
+/**
+ * clk_gate_restore_context - restore context for poweroff
+ * @hw: the clk_hw pointer of clock whose state is to be restored
+ *
+ * The clock gate restore context function enables or disables
+ * the gate clocks based on the enable_count. This is done in cases
+ * where the clock context is lost and based on the enable_count
+ * the clock either needs to be enabled/disabled. This
+ * helps restore the state of gate clocks.
+ */
+void clk_gate_restore_context(struct clk_hw *hw)
+{
+       struct clk_core *core = hw->core;
+
+       if (core->enable_count)
+               core->ops->enable(hw);
+       else
+               core->ops->disable(hw);
+}
+EXPORT_SYMBOL_GPL(clk_gate_restore_context);
+
+static int clk_core_save_context(struct clk_core *core)
+{
+       struct clk_core *child;
+       int ret = 0;
+
+       hlist_for_each_entry(child, &core->children, child_node) {
+               ret = clk_core_save_context(child);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (core->ops && core->ops->save_context)
+               ret = core->ops->save_context(core->hw);
+
+       return ret;
+}
+
+static void clk_core_restore_context(struct clk_core *core)
+{
+       struct clk_core *child;
+
+       if (core->ops && core->ops->restore_context)
+               core->ops->restore_context(core->hw);
+
+       hlist_for_each_entry(child, &core->children, child_node)
+               clk_core_restore_context(child);
+}
+
+/**
+ * clk_save_context - save clock context for poweroff
+ *
+ * Saves the context of the clock register for powerstates in which the
+ * contents of the registers will be lost. Occurs deep within the suspend
+ * code.  Returns 0 on success.
+ */
+int clk_save_context(void)
+{
+       struct clk_core *clk;
+       int ret;
+
+       hlist_for_each_entry(clk, &clk_root_list, child_node) {
+               ret = clk_core_save_context(clk);
+               if (ret < 0)
+                       return ret;
+       }
+
+       hlist_for_each_entry(clk, &clk_orphan_list, child_node) {
+               ret = clk_core_save_context(clk);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(clk_save_context);
+
+/**
+ * clk_restore_context - restore clock context after poweroff
+ *
+ * Restore the saved clock context upon resume.
+ *
+ */
+void clk_restore_context(void)
+{
+       struct clk_core *core;
+
+       hlist_for_each_entry(core, &clk_root_list, child_node)
+               clk_core_restore_context(core);
+
+       hlist_for_each_entry(core, &clk_orphan_list, child_node)
+               clk_core_restore_context(core);
+}
+EXPORT_SYMBOL_GPL(clk_restore_context);
+
 /**
  * clk_enable - ungate a clock
  * @clk: the clk being ungated
index fffbed5e263ba6d4ce851793d1ac4150e10fcddf..5b69e24a224f4797c263bcf3e43115fa09513bc1 100644 (file)
@@ -303,24 +303,6 @@ static int davinci_lpsc_clk_reset(struct clk *clk, bool reset)
        return 0;
 }
 
-/*
- * REVISIT: These exported functions can be removed after a non-DT lookup is
- * added to the reset controller framework and the davinci-rproc driver is
- * updated to use the generic reset controller framework.
- */
-
-int davinci_clk_reset_assert(struct clk *clk)
-{
-       return davinci_lpsc_clk_reset(clk, true);
-}
-EXPORT_SYMBOL(davinci_clk_reset_assert);
-
-int davinci_clk_reset_deassert(struct clk *clk)
-{
-       return davinci_lpsc_clk_reset(clk, false);
-}
-EXPORT_SYMBOL(davinci_clk_reset_deassert);
-
 static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev,
                                    unsigned long id)
 {
index becdb1dd21b5c66b18e112083ab7b6941820ff0f..30fad7ab0d886b68008d80e103826209f49e1d90 100644 (file)
@@ -21,6 +21,13 @@ config COMMON_CLK_HI3660
        help
          Build the clock driver for hi3660.
 
+config COMMON_CLK_HI3670
+       bool "Hi3670 Clock Driver"
+       depends on ARCH_HISI || COMPILE_TEST
+       default ARCH_HISI
+       help
+         Build the clock driver for hi3670.
+
 config COMMON_CLK_HI3798CV200
        tristate "Hi3798CV200 Clock Driver"
        depends on ARCH_HISI || COMPILE_TEST
index 2a714c0f965786f74bd1f3e671cb9d1d8fec4e1a..b2441b99f3d596ac4a36855a57c763ec552787df 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_ARCH_HIX5HD2)    += clk-hix5hd2.o
 obj-$(CONFIG_COMMON_CLK_HI3516CV300)   += crg-hi3516cv300.o
 obj-$(CONFIG_COMMON_CLK_HI3519)        += clk-hi3519.o
 obj-$(CONFIG_COMMON_CLK_HI3660) += clk-hi3660.o
+obj-$(CONFIG_COMMON_CLK_HI3670) += clk-hi3670.o
 obj-$(CONFIG_COMMON_CLK_HI3798CV200)   += crg-hi3798cv200.o
 obj-$(CONFIG_COMMON_CLK_HI6220)        += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)       += reset.o
diff --git a/drivers/clk/hisilicon/clk-hi3670.c b/drivers/clk/hisilicon/clk-hi3670.c
new file mode 100644 (file)
index 0000000..fd8c837
--- /dev/null
@@ -0,0 +1,1016 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2001-2021, Huawei Tech. Co., Ltd.
+ * Author: chenjun <chenjun14@huawei.com>
+ *
+ * Copyright (c) 2018, Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <dt-bindings/clock/hi3670-clock.h>
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk.h"
+
+static const struct hisi_fixed_rate_clock hi3670_fixed_rate_clks[] = {
+       { HI3670_CLKIN_SYS, "clkin_sys", NULL, 0, 19200000, },
+       { HI3670_CLKIN_REF, "clkin_ref", NULL, 0, 32764, },
+       { HI3670_CLK_FLL_SRC, "clk_fll_src", NULL, 0, 134400000, },
+       { HI3670_CLK_PPLL0, "clk_ppll0", NULL, 0, 1660000000, },
+       { HI3670_CLK_PPLL1, "clk_ppll1", NULL, 0, 1866000000, },
+       { HI3670_CLK_PPLL2, "clk_ppll2", NULL, 0, 1920000000, },
+       { HI3670_CLK_PPLL3, "clk_ppll3", NULL, 0, 1200000000, },
+       { HI3670_CLK_PPLL4, "clk_ppll4", NULL, 0, 900000000, },
+       { HI3670_CLK_PPLL6, "clk_ppll6", NULL, 0, 393216000, },
+       { HI3670_CLK_PPLL7, "clk_ppll7", NULL, 0, 1008000000, },
+       { HI3670_CLK_PPLL_PCIE, "clk_ppll_pcie", NULL, 0, 100000000, },
+       { HI3670_CLK_PCIEPLL_REV, "clk_pciepll_rev", NULL, 0, 100000000, },
+       { HI3670_CLK_SCPLL, "clk_scpll", NULL, 0, 245760000, },
+       { HI3670_PCLK, "pclk", NULL, 0, 20000000, },
+       { HI3670_CLK_UART0_DBG, "clk_uart0_dbg", NULL, 0, 19200000, },
+       { HI3670_CLK_UART6, "clk_uart6", NULL, 0, 19200000, },
+       { HI3670_OSC32K, "osc32k", NULL, 0, 32764, },
+       { HI3670_OSC19M, "osc19m", NULL, 0, 19200000, },
+       { HI3670_CLK_480M, "clk_480m", NULL, 0, 480000000, },
+       { HI3670_CLK_INVALID, "clk_invalid", NULL, 0, 10000000, },
+};
+
+/* crgctrl */
+static const struct hisi_fixed_factor_clock hi3670_crg_fixed_factor_clks[] = {
+       { HI3670_CLK_DIV_SYSBUS, "clk_div_sysbus", "clk_mux_sysbus",
+         1, 7, 0, },
+       { HI3670_CLK_FACTOR_MMC, "clk_factor_mmc", "clkin_sys",
+         1, 6, 0, },
+       { HI3670_CLK_SD_SYS, "clk_sd_sys", "clk_sd_sys_gt",
+         1, 6, 0, },
+       { HI3670_CLK_SDIO_SYS, "clk_sdio_sys", "clk_sdio_sys_gt",
+         1, 6, 0, },
+       { HI3670_CLK_DIV_A53HPM, "clk_div_a53hpm", "clk_a53hpm_andgt",
+         1, 4, 0, },
+       { HI3670_CLK_DIV_320M, "clk_div_320m", "clk_320m_pll_gt",
+         1, 5, 0, },
+       { HI3670_PCLK_GATE_UART0, "pclk_gate_uart0", "clk_mux_uartl",
+         1, 1, 0, },
+       { HI3670_CLK_FACTOR_UART0, "clk_factor_uart0", "clk_mux_uart0",
+         1, 1, 0, },
+       { HI3670_CLK_FACTOR_USB3PHY_PLL, "clk_factor_usb3phy_pll", "clk_ppll0",
+         1, 60, 0, },
+       { HI3670_CLK_GATE_ABB_USB, "clk_gate_abb_usb", "clk_gate_usb_tcxo_en",
+         1, 1, 0, },
+       { HI3670_CLK_GATE_UFSPHY_REF, "clk_gate_ufsphy_ref", "clkin_sys",
+         1, 1, 0, },
+       { HI3670_ICS_VOLT_HIGH, "ics_volt_high", "peri_volt_hold",
+         1, 1, 0, },
+       { HI3670_ICS_VOLT_MIDDLE, "ics_volt_middle", "peri_volt_middle",
+         1, 1, 0, },
+       { HI3670_VENC_VOLT_HOLD, "venc_volt_hold", "peri_volt_hold",
+         1, 1, 0, },
+       { HI3670_VDEC_VOLT_HOLD, "vdec_volt_hold", "peri_volt_hold",
+         1, 1, 0, },
+       { HI3670_EDC_VOLT_HOLD, "edc_volt_hold", "peri_volt_hold",
+         1, 1, 0, },
+       { HI3670_CLK_ISP_SNCLK_FAC, "clk_isp_snclk_fac", "clk_isp_snclk_angt",
+         1, 10, 0, },
+       { HI3670_CLK_FACTOR_RXDPHY, "clk_factor_rxdphy", "clk_andgt_rxdphy",
+         1, 6, 0, },
+};
+
+static const struct hisi_gate_clock hi3670_crgctrl_gate_sep_clks[] = {
+       { HI3670_PPLL1_EN_ACPU, "ppll1_en_acpu", "clk_ppll1",
+         CLK_SET_RATE_PARENT, 0x0, 0, 0, },
+       { HI3670_PPLL2_EN_ACPU, "ppll2_en_acpu", "clk_ppll2",
+         CLK_SET_RATE_PARENT, 0x0, 3, 0, },
+       { HI3670_PPLL3_EN_ACPU, "ppll3_en_acpu", "clk_ppll3",
+         CLK_SET_RATE_PARENT, 0x0, 27, 0, },
+       { HI3670_PPLL1_GT_CPU, "ppll1_gt_cpu", "clk_ppll1",
+         CLK_SET_RATE_PARENT, 0x460, 16, 0, },
+       { HI3670_PPLL2_GT_CPU, "ppll2_gt_cpu", "clk_ppll2",
+         CLK_SET_RATE_PARENT, 0x460, 18, 0, },
+       { HI3670_PPLL3_GT_CPU, "ppll3_gt_cpu", "clk_ppll3",
+         CLK_SET_RATE_PARENT, 0x460, 20, 0, },
+       { HI3670_CLK_GATE_PPLL2_MEDIA, "clk_gate_ppll2_media", "clk_ppll2",
+         CLK_SET_RATE_PARENT, 0x410, 27, 0, },
+       { HI3670_CLK_GATE_PPLL3_MEDIA, "clk_gate_ppll3_media", "clk_ppll3",
+         CLK_SET_RATE_PARENT, 0x410, 28, 0, },
+       { HI3670_CLK_GATE_PPLL4_MEDIA, "clk_gate_ppll4_media", "clk_ppll4",
+         CLK_SET_RATE_PARENT, 0x410, 26, 0, },
+       { HI3670_CLK_GATE_PPLL6_MEDIA, "clk_gate_ppll6_media", "clk_ppll6",
+         CLK_SET_RATE_PARENT, 0x410, 30, 0, },
+       { HI3670_CLK_GATE_PPLL7_MEDIA, "clk_gate_ppll7_media", "clk_ppll7",
+         CLK_SET_RATE_PARENT, 0x410, 29, 0, },
+       { HI3670_PCLK_GPIO0, "pclk_gpio0", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 0, 0, },
+       { HI3670_PCLK_GPIO1, "pclk_gpio1", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 1, 0, },
+       { HI3670_PCLK_GPIO2, "pclk_gpio2", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 2, 0, },
+       { HI3670_PCLK_GPIO3, "pclk_gpio3", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 3, 0, },
+       { HI3670_PCLK_GPIO4, "pclk_gpio4", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 4, 0, },
+       { HI3670_PCLK_GPIO5, "pclk_gpio5", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 5, 0, },
+       { HI3670_PCLK_GPIO6, "pclk_gpio6", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 6, 0, },
+       { HI3670_PCLK_GPIO7, "pclk_gpio7", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 7, 0, },
+       { HI3670_PCLK_GPIO8, "pclk_gpio8", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 8, 0, },
+       { HI3670_PCLK_GPIO9, "pclk_gpio9", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 9, 0, },
+       { HI3670_PCLK_GPIO10, "pclk_gpio10", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 10, 0, },
+       { HI3670_PCLK_GPIO11, "pclk_gpio11", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 11, 0, },
+       { HI3670_PCLK_GPIO12, "pclk_gpio12", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 12, 0, },
+       { HI3670_PCLK_GPIO13, "pclk_gpio13", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 13, 0, },
+       { HI3670_PCLK_GPIO14, "pclk_gpio14", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 14, 0, },
+       { HI3670_PCLK_GPIO15, "pclk_gpio15", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 15, 0, },
+       { HI3670_PCLK_GPIO16, "pclk_gpio16", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 16, 0, },
+       { HI3670_PCLK_GPIO17, "pclk_gpio17", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 17, 0, },
+       { HI3670_PCLK_GPIO20, "pclk_gpio20", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 20, 0, },
+       { HI3670_PCLK_GPIO21, "pclk_gpio21", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x10, 21, 0, },
+       { HI3670_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x50, 28, 0, },
+       { HI3670_PCLK_GATE_DSI1, "pclk_gate_dsi1", "clk_div_cfgbus",
+         CLK_SET_RATE_PARENT, 0x50, 29, 0, },
+       { HI3670_HCLK_GATE_USB3OTG, "hclk_gate_usb3otg", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x0, 25, 0, },
+       { HI3670_ACLK_GATE_USB3DVFS, "aclk_gate_usb3dvfs", "autodiv_emmc0bus",
+         CLK_SET_RATE_PARENT, 0x40, 1, 0, },
+       { HI3670_HCLK_GATE_SDIO, "hclk_gate_sdio", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x0, 21, 0, },
+       { HI3670_PCLK_GATE_PCIE_SYS, "pclk_gate_pcie_sys", "clk_div_mmc1bus",
+         CLK_SET_RATE_PARENT, 0x420, 7, 0, },
+       { HI3670_PCLK_GATE_PCIE_PHY, "pclk_gate_pcie_phy", "pclk_gate_mmc1_pcie",
+         CLK_SET_RATE_PARENT, 0x420, 9, 0, },
+       { HI3670_PCLK_GATE_MMC1_PCIE, "pclk_gate_mmc1_pcie", "pclk_div_mmc1_pcie",
+         CLK_SET_RATE_PARENT, 0x30, 12, 0, },
+       { HI3670_PCLK_GATE_MMC0_IOC, "pclk_gate_mmc0_ioc", "clk_div_mmc0bus",
+         CLK_SET_RATE_PARENT, 0x40, 13, 0, },
+       { HI3670_PCLK_GATE_MMC1_IOC, "pclk_gate_mmc1_ioc", "clk_div_mmc1bus",
+         CLK_SET_RATE_PARENT, 0x420, 21, 0, },
+       { HI3670_CLK_GATE_DMAC, "clk_gate_dmac", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x30, 1, 0, },
+       { HI3670_CLK_GATE_VCODECBUS2DDR, "clk_gate_vcodecbus2ddr", "clk_div_vcodecbus",
+         CLK_SET_RATE_PARENT, 0x0, 5, 0, },
+       { HI3670_CLK_CCI400_BYPASS, "clk_cci400_bypass", "clk_ddrc_freq",
+         CLK_SET_RATE_PARENT, 0x22C, 28, 0, },
+       { HI3670_CLK_GATE_CCI400, "clk_gate_cci400", "clk_ddrc_freq",
+         CLK_SET_RATE_PARENT, 0x50, 14, 0, },
+       { HI3670_CLK_GATE_SD, "clk_gate_sd", "clk_mux_sd_sys",
+         CLK_SET_RATE_PARENT, 0x40, 17, 0, },
+       { HI3670_HCLK_GATE_SD, "hclk_gate_sd", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x0, 30, 0, },
+       { HI3670_CLK_GATE_SDIO, "clk_gate_sdio", "clk_mux_sdio_sys",
+         CLK_SET_RATE_PARENT, 0x40, 19, 0, },
+       { HI3670_CLK_GATE_A57HPM, "clk_gate_a57hpm", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x050, 9, 0, },
+       { HI3670_CLK_GATE_A53HPM, "clk_gate_a53hpm", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x050, 13, 0, },
+       { HI3670_CLK_GATE_PA_A53, "clk_gate_pa_a53", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x480, 10, 0, },
+       { HI3670_CLK_GATE_PA_A57, "clk_gate_pa_a57", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x480, 9, 0, },
+       { HI3670_CLK_GATE_PA_G3D, "clk_gate_pa_g3d", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x480, 15, 0, },
+       { HI3670_CLK_GATE_GPUHPM, "clk_gate_gpuhpm", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x050, 15, 0, },
+       { HI3670_CLK_GATE_PERIHPM, "clk_gate_perihpm", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x050, 12, 0, },
+       { HI3670_CLK_GATE_AOHPM, "clk_gate_aohpm", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x050, 11, 0, },
+       { HI3670_CLK_GATE_UART1, "clk_gate_uart1", "clk_mux_uarth",
+         CLK_SET_RATE_PARENT, 0x20, 11, 0, },
+       { HI3670_CLK_GATE_UART4, "clk_gate_uart4", "clk_mux_uarth",
+         CLK_SET_RATE_PARENT, 0x20, 14, 0, },
+       { HI3670_PCLK_GATE_UART1, "pclk_gate_uart1", "clk_mux_uarth",
+         CLK_SET_RATE_PARENT, 0x20, 11, 0, },
+       { HI3670_PCLK_GATE_UART4, "pclk_gate_uart4", "clk_mux_uarth",
+         CLK_SET_RATE_PARENT, 0x20, 14, 0, },
+       { HI3670_CLK_GATE_UART2, "clk_gate_uart2", "clk_mux_uartl",
+         CLK_SET_RATE_PARENT, 0x20, 12, 0, },
+       { HI3670_CLK_GATE_UART5, "clk_gate_uart5", "clk_mux_uartl",
+         CLK_SET_RATE_PARENT, 0x20, 15, 0, },
+       { HI3670_PCLK_GATE_UART2, "pclk_gate_uart2", "clk_mux_uartl",
+         CLK_SET_RATE_PARENT, 0x20, 12, 0, },
+       { HI3670_PCLK_GATE_UART5, "pclk_gate_uart5", "clk_mux_uartl",
+         CLK_SET_RATE_PARENT, 0x20, 15, 0, },
+       { HI3670_CLK_GATE_UART0, "clk_gate_uart0", "clk_mux_uart0",
+         CLK_SET_RATE_PARENT, 0x20, 10, 0, },
+       { HI3670_CLK_GATE_I2C3, "clk_gate_i2c3", "clk_mux_i2c",
+         CLK_SET_RATE_PARENT, 0x20, 7, 0, },
+       { HI3670_CLK_GATE_I2C4, "clk_gate_i2c4", "clk_mux_i2c",
+         CLK_SET_RATE_PARENT, 0x20, 27, 0, },
+       { HI3670_CLK_GATE_I2C7, "clk_gate_i2c7", "clk_mux_i2c",
+         CLK_SET_RATE_PARENT, 0x10, 31, 0, },
+       { HI3670_PCLK_GATE_I2C3, "pclk_gate_i2c3", "clk_mux_i2c",
+         CLK_SET_RATE_PARENT, 0x20, 7, 0, },
+       { HI3670_PCLK_GATE_I2C4, "pclk_gate_i2c4", "clk_mux_i2c",
+         CLK_SET_RATE_PARENT, 0x20, 27, 0, },
+       { HI3670_PCLK_GATE_I2C7, "pclk_gate_i2c7", "clk_mux_i2c",
+         CLK_SET_RATE_PARENT, 0x10, 31, 0, },
+       { HI3670_CLK_GATE_SPI1, "clk_gate_spi1", "clk_mux_spi",
+         CLK_SET_RATE_PARENT, 0x20, 9, 0, },
+       { HI3670_CLK_GATE_SPI4, "clk_gate_spi4", "clk_mux_spi",
+         CLK_SET_RATE_PARENT, 0x40, 4, 0, },
+       { HI3670_PCLK_GATE_SPI1, "pclk_gate_spi1", "clk_mux_spi",
+         CLK_SET_RATE_PARENT, 0x20, 9, 0, },
+       { HI3670_PCLK_GATE_SPI4, "pclk_gate_spi4", "clk_mux_spi",
+         CLK_SET_RATE_PARENT, 0x40, 4, 0, },
+       { HI3670_CLK_GATE_USB3OTG_REF, "clk_gate_usb3otg_ref", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x40, 0, 0, },
+       { HI3670_CLK_GATE_USB2PHY_REF, "clk_gate_usb2phy_ref", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x410, 19, 0, },
+       { HI3670_CLK_GATE_PCIEAUX, "clk_gate_pcieaux", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x420, 8, 0, },
+       { HI3670_ACLK_GATE_PCIE, "aclk_gate_pcie", "clk_gate_mmc1_pcieaxi",
+         CLK_SET_RATE_PARENT, 0x420, 5, 0, },
+       { HI3670_CLK_GATE_MMC1_PCIEAXI, "clk_gate_mmc1_pcieaxi", "clk_div_pcieaxi",
+         CLK_SET_RATE_PARENT, 0x050, 4, 0, },
+       { HI3670_CLK_GATE_PCIEPHY_REF, "clk_gate_pciephy_ref", "clk_ppll_pcie",
+         CLK_SET_RATE_PARENT, 0x470, 14, 0, },
+       { HI3670_CLK_GATE_PCIE_DEBOUNCE, "clk_gate_pcie_debounce", "clk_ppll_pcie",
+         CLK_SET_RATE_PARENT, 0x470, 12, 0, },
+       { HI3670_CLK_GATE_PCIEIO, "clk_gate_pcieio", "clk_ppll_pcie",
+         CLK_SET_RATE_PARENT, 0x470, 13, 0, },
+       { HI3670_CLK_GATE_PCIE_HP, "clk_gate_pcie_hp", "clk_ppll_pcie",
+         CLK_SET_RATE_PARENT, 0x470, 15, 0, },
+       { HI3670_CLK_GATE_AO_ASP, "clk_gate_ao_asp", "clk_div_ao_asp",
+         CLK_SET_RATE_PARENT, 0x0, 26, 0, },
+       { HI3670_PCLK_GATE_PCTRL, "pclk_gate_pctrl", "clk_div_ptp",
+         CLK_SET_RATE_PARENT, 0x20, 31, 0, },
+       { HI3670_CLK_CSI_TRANS_GT, "clk_csi_trans_gt", "clk_div_csi_trans",
+         CLK_SET_RATE_PARENT, 0x30, 24, 0, },
+       { HI3670_CLK_DSI_TRANS_GT, "clk_dsi_trans_gt", "clk_div_dsi_trans",
+         CLK_SET_RATE_PARENT, 0x30, 25, 0, },
+       { HI3670_CLK_GATE_PWM, "clk_gate_pwm", "clk_div_ptp",
+         CLK_SET_RATE_PARENT, 0x20, 0, 0, },
+       { HI3670_ABB_AUDIO_EN0, "abb_audio_en0", "clk_gate_abb_192",
+         CLK_SET_RATE_PARENT, 0x30, 8, 0, },
+       { HI3670_ABB_AUDIO_EN1, "abb_audio_en1", "clk_gate_abb_192",
+         CLK_SET_RATE_PARENT, 0x30, 9, 0, },
+       { HI3670_ABB_AUDIO_GT_EN0, "abb_audio_gt_en0", "abb_audio_en0",
+         CLK_SET_RATE_PARENT, 0x30, 19, 0, },
+       { HI3670_ABB_AUDIO_GT_EN1, "abb_audio_gt_en1", "abb_audio_en1",
+         CLK_SET_RATE_PARENT, 0x40, 20, 0, },
+       { HI3670_CLK_GATE_DP_AUDIO_PLL_AO, "clk_gate_dp_audio_pll_ao", "clkdiv_dp_audio_pll_ao",
+         CLK_SET_RATE_PARENT, 0x00, 13, 0, },
+       { HI3670_PERI_VOLT_HOLD, "peri_volt_hold", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0, 1, 0, },
+       { HI3670_PERI_VOLT_MIDDLE, "peri_volt_middle", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0, 1, 0, },
+       { HI3670_CLK_GATE_ISP_SNCLK0, "clk_gate_isp_snclk0", "clk_isp_snclk_mux0",
+         CLK_SET_RATE_PARENT, 0x50, 16, 0, },
+       { HI3670_CLK_GATE_ISP_SNCLK1, "clk_gate_isp_snclk1", "clk_isp_snclk_mux1",
+         CLK_SET_RATE_PARENT, 0x50, 17, 0, },
+       { HI3670_CLK_GATE_ISP_SNCLK2, "clk_gate_isp_snclk2", "clk_isp_snclk_mux2",
+         CLK_SET_RATE_PARENT, 0x50, 18, 0, },
+       { HI3670_CLK_GATE_RXDPHY0_CFG, "clk_gate_rxdphy0_cfg", "clk_mux_rxdphy_cfg",
+         CLK_SET_RATE_PARENT, 0x030, 20, 0, },
+       { HI3670_CLK_GATE_RXDPHY1_CFG, "clk_gate_rxdphy1_cfg", "clk_mux_rxdphy_cfg",
+         CLK_SET_RATE_PARENT, 0x030, 21, 0, },
+       { HI3670_CLK_GATE_RXDPHY2_CFG, "clk_gate_rxdphy2_cfg", "clk_mux_rxdphy_cfg",
+         CLK_SET_RATE_PARENT, 0x030, 22, 0, },
+       { HI3670_CLK_GATE_TXDPHY0_CFG, "clk_gate_txdphy0_cfg", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x030, 28, 0, },
+       { HI3670_CLK_GATE_TXDPHY0_REF, "clk_gate_txdphy0_ref", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x030, 29, 0, },
+       { HI3670_CLK_GATE_TXDPHY1_CFG, "clk_gate_txdphy1_cfg", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x030, 30, 0, },
+       { HI3670_CLK_GATE_TXDPHY1_REF, "clk_gate_txdphy1_ref", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x030, 31, 0, },
+       { HI3670_CLK_GATE_MEDIA_TCXO, "clk_gate_media_tcxo", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x40, 6, 0, },
+};
+
+static const struct hisi_gate_clock hi3670_crgctrl_gate_clks[] = {
+       { HI3670_AUTODIV_SYSBUS, "autodiv_sysbus", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x404, 5, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_AUTODIV_EMMC0BUS, "autodiv_emmc0bus", "autodiv_sysbus",
+         CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_PCLK_ANDGT_MMC1_PCIE, "pclk_andgt_mmc1_pcie", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xf8, 13, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_GATE_VCODECBUS_GT, "clk_gate_vcodecbus_gt", "clk_mux_vcodecbus",
+         CLK_SET_RATE_PARENT, 0x0F0, 8, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_SD, "clk_andgt_sd", "clk_mux_sd_pll",
+         CLK_SET_RATE_PARENT, 0xF4, 3, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_SD_SYS_GT, "clk_sd_sys_gt", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0xF4, 5, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_SDIO, "clk_andgt_sdio", "clk_mux_sdio_pll",
+         CLK_SET_RATE_PARENT, 0xF4, 8, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_SDIO_SYS_GT, "clk_sdio_sys_gt", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0xF4, 6, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_A53HPM_ANDGT, "clk_a53hpm_andgt", "clk_mux_a53hpm",
+         CLK_SET_RATE_PARENT, 0x0F4, 7, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_320M_PLL_GT, "clk_320m_pll_gt", "clk_mux_320m",
+         CLK_SET_RATE_PARENT, 0xF8, 10, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_UARTH, "clk_andgt_uarth", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xF4, 11, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_UARTL, "clk_andgt_uartl", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xF4, 10, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_UART0, "clk_andgt_uart0", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xF4, 9, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_SPI, "clk_andgt_spi", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xF4, 13, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_PCIEAXI, "clk_andgt_pcieaxi", "clk_mux_pcieaxi",
+         CLK_SET_RATE_PARENT, 0xfc, 15, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_AO_ASP_GT, "clk_div_ao_asp_gt", "clk_mux_ao_asp",
+         CLK_SET_RATE_PARENT, 0xF4, 4, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_GATE_CSI_TRANS, "clk_gate_csi_trans", "clk_ppll2",
+         CLK_SET_RATE_PARENT, 0xF4, 14, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_GATE_DSI_TRANS, "clk_gate_dsi_trans", "clk_ppll2",
+         CLK_SET_RATE_PARENT, 0xF4, 1, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_PTP, "clk_andgt_ptp", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xF8, 5, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_OUT0, "clk_andgt_out0", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0xF0, 10, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_OUT1, "clk_andgt_out1", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0xF0, 11, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLKGT_DP_AUDIO_PLL_AO, "clkgt_dp_audio_pll_ao", "clk_ppll6",
+         CLK_SET_RATE_PARENT, 0xF8, 15, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_VDEC, "clk_andgt_vdec", "clk_mux_vdec",
+         CLK_SET_RATE_PARENT, 0xF0, 13, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_VENC, "clk_andgt_venc", "clk_mux_venc",
+         CLK_SET_RATE_PARENT, 0xF0, 9, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ISP_SNCLK_ANGT, "clk_isp_snclk_angt", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x108, 2, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_RXDPHY, "clk_andgt_rxdphy", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x0F0, 12, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_ICS, "clk_andgt_ics", "clk_mux_ics",
+         CLK_SET_RATE_PARENT, 0xf0, 14, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_AUTODIV_DMABUS, "autodiv_dmabus", "autodiv_sysbus",
+         CLK_SET_RATE_PARENT, 0x404, 3, CLK_GATE_HIWORD_MASK, 0, },
+};
+
+static const char *const
+clk_mux_sysbus_p[] = { "clk_ppll1", "clk_ppll0", };
+static const char *const
+clk_mux_vcodecbus_p[] = { "clk_invalid", "clk_ppll4", "clk_ppll0",
+                         "clk_invalid", "clk_ppll2", "clk_invalid",
+                         "clk_invalid", "clk_invalid", "clk_ppll3",
+                         "clk_invalid", "clk_invalid", "clk_invalid",
+                         "clk_invalid", "clk_invalid", "clk_invalid",
+                         "clk_invalid", };
+static const char *const
+clk_mux_sd_sys_p[] = { "clk_sd_sys", "clk_div_sd", };
+static const char *const
+clk_mux_sd_pll_p[] = { "clk_ppll0", "clk_ppll3", "clk_ppll2", "clk_ppll2", };
+static const char *const
+clk_mux_sdio_sys_p[] = { "clk_sdio_sys", "clk_div_sdio", };
+static const char *const
+clk_mux_sdio_pll_p[] = { "clk_ppll0", "clk_ppll3", "clk_ppll2", "clk_ppll2", };
+static const char *const
+clk_mux_a53hpm_p[] = { "clk_ppll0", "clk_ppll2", };
+static const char *const
+clk_mux_320m_p[] = { "clk_ppll2", "clk_ppll0", };
+static const char *const
+clk_mux_uarth_p[] = { "clkin_sys", "clk_div_uarth", };
+static const char *const
+clk_mux_uartl_p[] = { "clkin_sys", "clk_div_uartl", };
+static const char *const
+clk_mux_uart0_p[] = { "clkin_sys", "clk_div_uart0", };
+static const char *const
+clk_mux_i2c_p[] = { "clkin_sys", "clk_div_i2c", };
+static const char *const
+clk_mux_spi_p[] = { "clkin_sys", "clk_div_spi", };
+static const char *const
+clk_mux_pcieaxi_p[] = { "clkin_sys", "clk_ppll0", };
+static const char *const
+clk_mux_ao_asp_p[] = { "clk_ppll2", "clk_ppll3", };
+static const char *const
+clk_mux_vdec_p[] = { "clk_invalid", "clk_ppll4", "clk_ppll0", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", };
+static const char *const
+clk_mux_venc_p[] = { "clk_invalid", "clk_ppll4", "clk_ppll0", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", };
+static const char *const
+clk_isp_snclk_mux0_p[] = { "clkin_sys", "clk_isp_snclk_div0", };
+static const char *const
+clk_isp_snclk_mux1_p[] = { "clkin_sys", "clk_isp_snclk_div1", };
+static const char *const
+clk_isp_snclk_mux2_p[] = { "clkin_sys", "clk_isp_snclk_div2", };
+static const char *const
+clk_mux_rxdphy_cfg_p[] = { "clk_factor_rxdphy", "clkin_sys", };
+static const char *const
+clk_mux_ics_p[] = { "clk_invalid", "clk_ppll4", "clk_ppll0", "clk_invalid",
+                   "clk_ppll2", "clk_invalid", "clk_invalid", "clk_invalid",
+                   "clk_ppll3", "clk_invalid", "clk_invalid", "clk_invalid",
+                   "clk_invalid", "clk_invalid", "clk_invalid",
+                   "clk_invalid", };
+
+static const struct hisi_mux_clock hi3670_crgctrl_mux_clks[] = {
+       { HI3670_CLK_MUX_SYSBUS, "clk_mux_sysbus", clk_mux_sysbus_p,
+         ARRAY_SIZE(clk_mux_sysbus_p), CLK_SET_RATE_PARENT,
+         0xAC, 0, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_VCODECBUS, "clk_mux_vcodecbus", clk_mux_vcodecbus_p,
+         ARRAY_SIZE(clk_mux_vcodecbus_p), CLK_SET_RATE_PARENT,
+         0x0C8, 0, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_SD_SYS, "clk_mux_sd_sys", clk_mux_sd_sys_p,
+         ARRAY_SIZE(clk_mux_sd_sys_p), CLK_SET_RATE_PARENT,
+         0x0B8, 6, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_SD_PLL, "clk_mux_sd_pll", clk_mux_sd_pll_p,
+         ARRAY_SIZE(clk_mux_sd_pll_p), CLK_SET_RATE_PARENT,
+         0x0B8, 4, 2, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_SDIO_SYS, "clk_mux_sdio_sys", clk_mux_sdio_sys_p,
+         ARRAY_SIZE(clk_mux_sdio_sys_p), CLK_SET_RATE_PARENT,
+         0x0C0, 6, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_SDIO_PLL, "clk_mux_sdio_pll", clk_mux_sdio_pll_p,
+         ARRAY_SIZE(clk_mux_sdio_pll_p), CLK_SET_RATE_PARENT,
+         0x0C0, 4, 2, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_A53HPM, "clk_mux_a53hpm", clk_mux_a53hpm_p,
+         ARRAY_SIZE(clk_mux_a53hpm_p), CLK_SET_RATE_PARENT,
+         0x0D4, 9, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_320M, "clk_mux_320m", clk_mux_320m_p,
+         ARRAY_SIZE(clk_mux_320m_p), CLK_SET_RATE_PARENT,
+         0x100, 0, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_UARTH, "clk_mux_uarth", clk_mux_uarth_p,
+         ARRAY_SIZE(clk_mux_uarth_p), CLK_SET_RATE_PARENT,
+         0xAC, 4, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_UARTL, "clk_mux_uartl", clk_mux_uartl_p,
+         ARRAY_SIZE(clk_mux_uartl_p), CLK_SET_RATE_PARENT,
+         0xAC, 3, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_UART0, "clk_mux_uart0", clk_mux_uart0_p,
+         ARRAY_SIZE(clk_mux_uart0_p), CLK_SET_RATE_PARENT,
+         0xAC, 2, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_I2C, "clk_mux_i2c", clk_mux_i2c_p,
+         ARRAY_SIZE(clk_mux_i2c_p), CLK_SET_RATE_PARENT,
+         0xAC, 13, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_SPI, "clk_mux_spi", clk_mux_spi_p,
+         ARRAY_SIZE(clk_mux_spi_p), CLK_SET_RATE_PARENT,
+         0xAC, 8, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_PCIEAXI, "clk_mux_pcieaxi", clk_mux_pcieaxi_p,
+         ARRAY_SIZE(clk_mux_pcieaxi_p), CLK_SET_RATE_PARENT,
+         0xb4, 5, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_AO_ASP, "clk_mux_ao_asp", clk_mux_ao_asp_p,
+         ARRAY_SIZE(clk_mux_ao_asp_p), CLK_SET_RATE_PARENT,
+         0x100, 6, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_VDEC, "clk_mux_vdec", clk_mux_vdec_p,
+         ARRAY_SIZE(clk_mux_vdec_p), CLK_SET_RATE_PARENT,
+         0xC8, 8, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_VENC, "clk_mux_venc", clk_mux_venc_p,
+         ARRAY_SIZE(clk_mux_venc_p), CLK_SET_RATE_PARENT,
+         0xC8, 4, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_ISP_SNCLK_MUX0, "clk_isp_snclk_mux0", clk_isp_snclk_mux0_p,
+         ARRAY_SIZE(clk_isp_snclk_mux0_p), CLK_SET_RATE_PARENT,
+         0x108, 3, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_ISP_SNCLK_MUX1, "clk_isp_snclk_mux1", clk_isp_snclk_mux1_p,
+         ARRAY_SIZE(clk_isp_snclk_mux1_p), CLK_SET_RATE_PARENT,
+         0x10C, 13, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_ISP_SNCLK_MUX2, "clk_isp_snclk_mux2", clk_isp_snclk_mux2_p,
+         ARRAY_SIZE(clk_isp_snclk_mux2_p), CLK_SET_RATE_PARENT,
+         0x10C, 10, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_RXDPHY_CFG, "clk_mux_rxdphy_cfg", clk_mux_rxdphy_cfg_p,
+         ARRAY_SIZE(clk_mux_rxdphy_cfg_p), CLK_SET_RATE_PARENT,
+         0x0C4, 8, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_ICS, "clk_mux_ics", clk_mux_ics_p,
+         ARRAY_SIZE(clk_mux_ics_p), CLK_SET_RATE_PARENT,
+         0xc8, 12, 4, CLK_MUX_HIWORD_MASK, },
+};
+
+static const struct hisi_divider_clock hi3670_crgctrl_divider_clks[] = {
+       { HI3670_CLK_DIV_CFGBUS, "clk_div_cfgbus", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0xEC, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_MMC0BUS, "clk_div_mmc0bus", "autodiv_emmc0bus",
+         CLK_SET_RATE_PARENT, 0x0EC, 2, 1, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_MMC1BUS, "clk_div_mmc1bus", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x0EC, 3, 1, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_PCLK_DIV_MMC1_PCIE, "pclk_div_mmc1_pcie", "pclk_andgt_mmc1_pcie",
+         CLK_SET_RATE_PARENT, 0xb4, 6, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_VCODECBUS, "clk_div_vcodecbus", "clk_gate_vcodecbus_gt",
+         CLK_SET_RATE_PARENT, 0x0BC, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_SD, "clk_div_sd", "clk_andgt_sd",
+         CLK_SET_RATE_PARENT, 0xB8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_SDIO, "clk_div_sdio", "clk_andgt_sdio",
+         CLK_SET_RATE_PARENT, 0xC0, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_UARTH, "clk_div_uarth", "clk_andgt_uarth",
+         CLK_SET_RATE_PARENT, 0xB0, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_UARTL, "clk_div_uartl", "clk_andgt_uartl",
+         CLK_SET_RATE_PARENT, 0xB0, 8, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_UART0, "clk_div_uart0", "clk_andgt_uart0",
+         CLK_SET_RATE_PARENT, 0xB0, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m",
+         CLK_SET_RATE_PARENT, 0xE8, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi",
+         CLK_SET_RATE_PARENT, 0xC4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_PCIEAXI, "clk_div_pcieaxi", "clk_andgt_pcieaxi",
+         CLK_SET_RATE_PARENT, 0xb4, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_AO_ASP, "clk_div_ao_asp", "clk_div_ao_asp_gt",
+         CLK_SET_RATE_PARENT, 0x108, 6, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_CSI_TRANS, "clk_div_csi_trans", "clk_gate_csi_trans",
+         CLK_SET_RATE_PARENT, 0xD4, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_DSI_TRANS, "clk_div_dsi_trans", "clk_gate_dsi_trans",
+         CLK_SET_RATE_PARENT, 0xD4, 10, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_PTP, "clk_div_ptp", "clk_andgt_ptp",
+         CLK_SET_RATE_PARENT, 0xD8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_CLKOUT0_PLL, "clk_div_clkout0_pll", "clk_andgt_out0",
+         CLK_SET_RATE_PARENT, 0xe0, 4, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_CLKOUT1_PLL, "clk_div_clkout1_pll", "clk_andgt_out1",
+         CLK_SET_RATE_PARENT, 0xe0, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLKDIV_DP_AUDIO_PLL_AO, "clkdiv_dp_audio_pll_ao", "clkgt_dp_audio_pll_ao",
+         CLK_SET_RATE_PARENT, 0xBC, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_VDEC, "clk_div_vdec", "clk_andgt_vdec",
+         CLK_SET_RATE_PARENT, 0xC4, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_VENC, "clk_div_venc", "clk_andgt_venc",
+         CLK_SET_RATE_PARENT, 0xC0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_ISP_SNCLK_DIV0, "clk_isp_snclk_div0", "clk_isp_snclk_fac",
+         CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_ISP_SNCLK_DIV1, "clk_isp_snclk_div1", "clk_isp_snclk_fac",
+         CLK_SET_RATE_PARENT, 0x10C, 14, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_ISP_SNCLK_DIV2, "clk_isp_snclk_div2", "clk_isp_snclk_fac",
+         CLK_SET_RATE_PARENT, 0x10C, 11, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_ICS, "clk_div_ics", "clk_andgt_ics",
+         CLK_SET_RATE_PARENT, 0xE4, 9, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+};
+
+/* clk_pmuctrl */
+static const struct hisi_gate_clock hi3670_pmu_gate_clks[] = {
+       { HI3670_GATE_ABB_192, "clk_gate_abb_192", "clkin_sys",
+         CLK_SET_RATE_PARENT, (0x037 << 2), 0, 0, },
+};
+
+/* clk_pctrl */
+static const struct hisi_gate_clock hi3670_pctrl_gate_clks[] = {
+       { HI3670_GATE_UFS_TCXO_EN, "clk_gate_ufs_tcxo_en", "clk_gate_abb_192",
+         CLK_SET_RATE_PARENT, 0x10, 0, CLK_GATE_HIWORD_MASK, },
+       { HI3670_GATE_USB_TCXO_EN, "clk_gate_usb_tcxo_en", "clk_gate_abb_192",
+         CLK_SET_RATE_PARENT, 0x10, 1, CLK_GATE_HIWORD_MASK, },
+};
+
+/* clk_sctrl */
+static const struct hisi_gate_clock hi3670_sctrl_gate_sep_clks[] = {
+       { HI3670_PPLL0_EN_ACPU, "ppll0_en_acpu", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x190, 26, 0, },
+       { HI3670_PPLL0_GT_CPU, "ppll0_gt_cpu", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x190, 15, 0, },
+       { HI3670_CLK_GATE_PPLL0_MEDIA, "clk_gate_ppll0_media", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x1b0, 6, 0, },
+       { HI3670_PCLK_GPIO18, "pclk_gpio18", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x1B0, 9, 0, },
+       { HI3670_PCLK_GPIO19, "pclk_gpio19", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x1B0, 8, 0, },
+       { HI3670_CLK_GATE_SPI, "clk_gate_spi", "clk_div_ioperi",
+         CLK_SET_RATE_PARENT, 0x1B0, 10, 0, },
+       { HI3670_PCLK_GATE_SPI, "pclk_gate_spi", "clk_div_ioperi",
+         CLK_SET_RATE_PARENT, 0x1B0, 10, 0, },
+       { HI3670_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_ufs_subsys",
+         CLK_SET_RATE_PARENT, 0x1B0, 14, 0, },
+       { HI3670_CLK_GATE_UFSIO_REF, "clk_gate_ufsio_ref", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x1b0, 12, 0, },
+       { HI3670_PCLK_AO_GPIO0, "pclk_ao_gpio0", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 11, 0, },
+       { HI3670_PCLK_AO_GPIO1, "pclk_ao_gpio1", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 12, 0, },
+       { HI3670_PCLK_AO_GPIO2, "pclk_ao_gpio2", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 13, 0, },
+       { HI3670_PCLK_AO_GPIO3, "pclk_ao_gpio3", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 14, 0, },
+       { HI3670_PCLK_AO_GPIO4, "pclk_ao_gpio4", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 21, 0, },
+       { HI3670_PCLK_AO_GPIO5, "pclk_ao_gpio5", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 22, 0, },
+       { HI3670_PCLK_AO_GPIO6, "pclk_ao_gpio6", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 25, 0, },
+       { HI3670_CLK_GATE_OUT0, "clk_gate_out0", "clk_mux_clkout0",
+         CLK_SET_RATE_PARENT, 0x160, 16, 0, },
+       { HI3670_CLK_GATE_OUT1, "clk_gate_out1", "clk_mux_clkout1",
+         CLK_SET_RATE_PARENT, 0x160, 17, 0, },
+       { HI3670_PCLK_GATE_SYSCNT, "pclk_gate_syscnt", "clk_div_aobus",
+         CLK_SET_RATE_PARENT, 0x160, 19, 0, },
+       { HI3670_CLK_GATE_SYSCNT, "clk_gate_syscnt", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x160, 20, 0, },
+       { HI3670_CLK_GATE_ASP_SUBSYS_PERI, "clk_gate_asp_subsys_peri",
+         "clk_mux_asp_subsys_peri",
+         CLK_SET_RATE_PARENT, 0x170, 6, 0, },
+       { HI3670_CLK_GATE_ASP_SUBSYS, "clk_gate_asp_subsys", "clk_mux_asp_pll",
+         CLK_SET_RATE_PARENT, 0x170, 4, 0, },
+       { HI3670_CLK_GATE_ASP_TCXO, "clk_gate_asp_tcxo", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x160, 27, 0, },
+       { HI3670_CLK_GATE_DP_AUDIO_PLL, "clk_gate_dp_audio_pll",
+         "clk_gate_dp_audio_pll_ao",
+         CLK_SET_RATE_PARENT, 0x1B0, 7, 0, },
+};
+
+static const struct hisi_gate_clock hi3670_sctrl_gate_clks[] = {
+       { HI3670_CLK_ANDGT_IOPERI, "clk_andgt_ioperi", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x270, 6, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLKANDGT_ASP_SUBSYS_PERI, "clkandgt_asp_subsys_peri",
+         "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x268, 3, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANGT_ASP_SUBSYS, "clk_angt_asp_subsys", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x258, 0, CLK_GATE_HIWORD_MASK, 0, },
+};
+
+static const char *const
+clk_mux_ufs_subsys_p[] = { "clkin_sys", "clk_ppll0", };
+static const char *const
+clk_mux_clkout0_p[] = { "clkin_ref", "clk_div_clkout0_tcxo",
+                       "clk_div_clkout0_pll", "clk_div_clkout0_pll", };
+static const char *const
+clk_mux_clkout1_p[] = { "clkin_ref", "clk_div_clkout1_tcxo",
+                       "clk_div_clkout1_pll", "clk_div_clkout1_pll", };
+static const char *const
+clk_mux_asp_subsys_peri_p[] = { "clk_ppll0", "clk_fll_src", };
+static const char *const
+clk_mux_asp_pll_p[] = { "clk_ppll0", "clk_fll_src", "clk_gate_ao_asp",
+                       "clk_pciepll_rev", };
+
+static const struct hisi_mux_clock hi3670_sctrl_mux_clks[] = {
+       { HI3670_CLK_MUX_UFS_SUBSYS, "clk_mux_ufs_subsys", clk_mux_ufs_subsys_p,
+         ARRAY_SIZE(clk_mux_ufs_subsys_p), CLK_SET_RATE_PARENT,
+         0x274, 8, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_CLKOUT0, "clk_mux_clkout0", clk_mux_clkout0_p,
+         ARRAY_SIZE(clk_mux_clkout0_p), CLK_SET_RATE_PARENT,
+         0x254, 12, 2, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_CLKOUT1, "clk_mux_clkout1", clk_mux_clkout1_p,
+         ARRAY_SIZE(clk_mux_clkout1_p), CLK_SET_RATE_PARENT,
+         0x254, 14, 2, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_ASP_SUBSYS_PERI, "clk_mux_asp_subsys_peri",
+         clk_mux_asp_subsys_peri_p, ARRAY_SIZE(clk_mux_asp_subsys_peri_p),
+         CLK_SET_RATE_PARENT, 0x268, 8, 1, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_ASP_PLL, "clk_mux_asp_pll", clk_mux_asp_pll_p,
+         ARRAY_SIZE(clk_mux_asp_pll_p), CLK_SET_RATE_PARENT,
+         0x268, 9, 2, CLK_MUX_HIWORD_MASK, },
+};
+
+static const struct hisi_divider_clock hi3670_sctrl_divider_clks[] = {
+       { HI3670_CLK_DIV_AOBUS, "clk_div_aobus", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_UFS_SUBSYS, "clk_div_ufs_subsys", "clk_mux_ufs_subsys",
+         CLK_SET_RATE_PARENT, 0x274, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_andgt_ioperi",
+         CLK_SET_RATE_PARENT, 0x270, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_CLKOUT0_TCXO, "clk_div_clkout0_tcxo", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x254, 6, 3, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_CLKOUT1_TCXO, "clk_div_clkout1_tcxo", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x254, 9, 3, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_ASP_SUBSYS_PERI_DIV, "clk_asp_subsys_peri_div", "clkandgt_asp_subsys_peri",
+         CLK_SET_RATE_PARENT, 0x268, 0, 3, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_ASP_SUBSYS, "clk_div_asp_subsys", "clk_angt_asp_subsys",
+         CLK_SET_RATE_PARENT, 0x250, 0, 3, CLK_DIVIDER_HIWORD_MASK, 0, },
+};
+
+/* clk_iomcu */
+static const struct hisi_fixed_factor_clock hi3670_iomcu_fixed_factor_clks[] = {
+       { HI3670_CLK_GATE_I2C0, "clk_gate_i2c0", "clk_i2c0_gate_iomcu", 1, 4, 0, },
+       { HI3670_CLK_GATE_I2C1, "clk_gate_i2c1", "clk_i2c1_gate_iomcu", 1, 4, 0, },
+       { HI3670_CLK_GATE_I2C2, "clk_gate_i2c2", "clk_i2c2_gate_iomcu", 1, 4, 0, },
+       { HI3670_CLK_GATE_SPI0, "clk_gate_spi0", "clk_spi0_gate_iomcu", 1, 1, 0, },
+       { HI3670_CLK_GATE_SPI2, "clk_gate_spi2", "clk_spi2_gate_iomcu", 1, 1, 0, },
+       { HI3670_CLK_GATE_UART3, "clk_gate_uart3", "clk_uart3_gate_iomcu", 1, 16, 0, },
+};
+
+static const struct hisi_gate_clock hi3670_iomcu_gate_sep_clks[] = {
+       { HI3670_CLK_I2C0_GATE_IOMCU, "clk_i2c0_gate_iomcu", "clk_fll_src",
+         CLK_SET_RATE_PARENT, 0x10, 3, 0, },
+       { HI3670_CLK_I2C1_GATE_IOMCU, "clk_i2c1_gate_iomcu", "clk_fll_src",
+         CLK_SET_RATE_PARENT, 0x10, 4, 0, },
+       { HI3670_CLK_I2C2_GATE_IOMCU, "clk_i2c2_gate_iomcu", "clk_fll_src",
+         CLK_SET_RATE_PARENT, 0x10, 5, 0, },
+       { HI3670_CLK_SPI0_GATE_IOMCU, "clk_spi0_gate_iomcu", "clk_fll_src",
+         CLK_SET_RATE_PARENT, 0x10, 10, 0, },
+       { HI3670_CLK_SPI2_GATE_IOMCU, "clk_spi2_gate_iomcu", "clk_fll_src",
+         CLK_SET_RATE_PARENT, 0x10, 30, 0, },
+       { HI3670_CLK_UART3_GATE_IOMCU, "clk_uart3_gate_iomcu", "clk_gate_iomcu_peri0",
+         CLK_SET_RATE_PARENT, 0x10, 11, 0, },
+       { HI3670_CLK_GATE_PERI0_IOMCU, "clk_gate_iomcu_peri0", "clk_ppll0",
+         CLK_SET_RATE_PARENT, 0x90, 0, 0, },
+};
+
+/* clk_media1 */
+static const struct hisi_gate_clock hi3670_media1_gate_sep_clks[] = {
+       { HI3670_ACLK_GATE_NOC_DSS, "aclk_gate_noc_dss", "aclk_gate_disp_noc_subsys",
+         CLK_SET_RATE_PARENT, 0x10, 21, 0, },
+       { HI3670_PCLK_GATE_NOC_DSS_CFG, "pclk_gate_noc_dss_cfg", "pclk_gate_disp_noc_subsys",
+         CLK_SET_RATE_PARENT, 0x10, 22, 0, },
+       { HI3670_PCLK_GATE_MMBUF_CFG, "pclk_gate_mmbuf_cfg", "pclk_gate_disp_noc_subsys",
+         CLK_SET_RATE_PARENT, 0x20, 5, 0, },
+       { HI3670_PCLK_GATE_DISP_NOC_SUBSYS, "pclk_gate_disp_noc_subsys", "clk_div_sysbus",
+         CLK_SET_RATE_PARENT, 0x10, 18, 0, },
+       { HI3670_ACLK_GATE_DISP_NOC_SUBSYS, "aclk_gate_disp_noc_subsys", "clk_gate_vivobusfreq",
+         CLK_SET_RATE_PARENT, 0x10, 17, 0, },
+       { HI3670_PCLK_GATE_DSS, "pclk_gate_dss", "pclk_gate_disp_noc_subsys",
+         CLK_SET_RATE_PARENT, 0x00, 14, 0, },
+       { HI3670_ACLK_GATE_DSS, "aclk_gate_dss", "aclk_gate_disp_noc_subsys",
+         CLK_SET_RATE_PARENT, 0x00, 19, 0, },
+       { HI3670_CLK_GATE_VIVOBUSFREQ, "clk_gate_vivobusfreq", "clk_div_vivobus",
+         CLK_SET_RATE_PARENT, 0x00, 18, 0, },
+       { HI3670_CLK_GATE_EDC0, "clk_gate_edc0", "clk_div_edc0",
+         CLK_SET_RATE_PARENT, 0x00, 15, 0, },
+       { HI3670_CLK_GATE_LDI0, "clk_gate_ldi0", "clk_div_ldi0",
+         CLK_SET_RATE_PARENT, 0x00, 16, 0, },
+       { HI3670_CLK_GATE_LDI1FREQ, "clk_gate_ldi1freq", "clk_div_ldi1",
+         CLK_SET_RATE_PARENT, 0x00, 17, 0, },
+       { HI3670_CLK_GATE_BRG, "clk_gate_brg", "clk_media_common_div",
+         CLK_SET_RATE_PARENT, 0x00, 29, 0, },
+       { HI3670_ACLK_GATE_ASC, "aclk_gate_asc", "clk_gate_mmbuf",
+         CLK_SET_RATE_PARENT, 0x20, 3, 0, },
+       { HI3670_CLK_GATE_DSS_AXI_MM, "clk_gate_dss_axi_mm", "clk_gate_mmbuf",
+         CLK_SET_RATE_PARENT, 0x20, 4, 0, },
+       { HI3670_CLK_GATE_MMBUF, "clk_gate_mmbuf", "aclk_div_mmbuf",
+         CLK_SET_RATE_PARENT, 0x20, 0, 0, },
+       { HI3670_PCLK_GATE_MMBUF, "pclk_gate_mmbuf", "pclk_div_mmbuf",
+         CLK_SET_RATE_PARENT, 0x20, 1, 0, },
+       { HI3670_CLK_GATE_ATDIV_VIVO, "clk_gate_atdiv_vivo", "clk_div_vivobus",
+         CLK_SET_RATE_PARENT, 0x010, 1, 0, },
+};
+
+static const struct hisi_gate_clock hi3670_media1_gate_clks[] = {
+       { HI3670_CLK_GATE_VIVOBUS_ANDGT, "clk_gate_vivobus_andgt", "clk_mux_vivobus",
+         CLK_SET_RATE_PARENT, 0x84, 3, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_EDC0, "clk_andgt_edc0", "clk_mux_edc0",
+         CLK_SET_RATE_PARENT, 0x84, 7, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_LDI0, "clk_andgt_ldi0", "clk_mux_ldi0",
+         CLK_SET_RATE_PARENT, 0x84, 9, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_ANDGT_LDI1, "clk_andgt_ldi1", "clk_mux_ldi1",
+         CLK_SET_RATE_PARENT, 0x84, 8, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_CLK_MMBUF_PLL_ANDGT, "clk_mmbuf_pll_andgt", "clk_sw_mmbuf",
+         CLK_SET_RATE_PARENT, 0x84, 14, CLK_GATE_HIWORD_MASK, 0, },
+       { HI3670_PCLK_MMBUF_ANDGT, "pclk_mmbuf_andgt", "aclk_div_mmbuf",
+         CLK_SET_RATE_PARENT, 0x84, 15, CLK_GATE_HIWORD_MASK, 0, },
+};
+
+static const char *const
+clk_mux_vivobus_p[] = { "clk_invalid", "clk_invalid", "clk_gate_ppll0_media",
+                       "clk_invalid", "clk_gate_ppll2_media", "clk_invalid",
+                       "clk_invalid", "clk_invalid", "clk_gate_ppll3_media",
+                       "clk_invalid", "clk_invalid", "clk_invalid",
+                       "clk_invalid", "clk_invalid", "clk_invalid",
+                       "clk_invalid", };
+static const char *const
+clk_mux_edc0_p[] = { "clk_invalid", "clk_invalid", "clk_gate_ppll0_media",
+                    "clk_invalid", "clk_gate_ppll2_media", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_gate_ppll3_media",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", };
+static const char *const
+clk_mux_ldi0_p[] = { "clk_invalid", "clk_gate_ppll7_media",
+                    "clk_gate_ppll0_media", "clk_invalid",
+                    "clk_gate_ppll2_media", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_gate_ppll3_media", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", };
+static const char *const
+clk_mux_ldi1_p[] = { "clk_invalid", "clk_gate_ppll7_media",
+                    "clk_gate_ppll0_media", "clk_invalid",
+                    "clk_gate_ppll2_media", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_gate_ppll3_media", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", };
+static const char *const
+clk_sw_mmbuf_p[] = { "clk_invalid", "clk_invalid", "clk_gate_ppll0_media",
+                    "clk_invalid", "clk_gate_ppll2_media", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_gate_ppll3_media",
+                    "clk_invalid", "clk_invalid", "clk_invalid", "clk_invalid",
+                    "clk_invalid", "clk_invalid", "clk_invalid", };
+
+static const struct hisi_mux_clock hi3670_media1_mux_clks[] = {
+       { HI3670_CLK_MUX_VIVOBUS, "clk_mux_vivobus", clk_mux_vivobus_p,
+         ARRAY_SIZE(clk_mux_vivobus_p), CLK_SET_RATE_PARENT,
+         0x74, 6, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_EDC0, "clk_mux_edc0", clk_mux_edc0_p,
+         ARRAY_SIZE(clk_mux_edc0_p), CLK_SET_RATE_PARENT,
+         0x68, 6, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_LDI0, "clk_mux_ldi0", clk_mux_ldi0_p,
+         ARRAY_SIZE(clk_mux_ldi0_p), CLK_SET_RATE_PARENT,
+         0x60, 6, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_MUX_LDI1, "clk_mux_ldi1", clk_mux_ldi1_p,
+         ARRAY_SIZE(clk_mux_ldi1_p), CLK_SET_RATE_PARENT,
+         0x64, 6, 4, CLK_MUX_HIWORD_MASK, },
+       { HI3670_CLK_SW_MMBUF, "clk_sw_mmbuf", clk_sw_mmbuf_p,
+         ARRAY_SIZE(clk_sw_mmbuf_p), CLK_SET_RATE_PARENT,
+         0x88, 0, 4, CLK_MUX_HIWORD_MASK, },
+};
+
+static const struct hisi_divider_clock hi3670_media1_divider_clks[] = {
+       { HI3670_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_gate_vivobus_andgt",
+         CLK_SET_RATE_PARENT, 0x74, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_EDC0, "clk_div_edc0", "clk_andgt_edc0",
+         CLK_SET_RATE_PARENT, 0x68, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_LDI0, "clk_div_ldi0", "clk_andgt_ldi0",
+         CLK_SET_RATE_PARENT, 0x60, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_CLK_DIV_LDI1, "clk_div_ldi1", "clk_andgt_ldi1",
+         CLK_SET_RATE_PARENT, 0x64, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_ACLK_DIV_MMBUF, "aclk_div_mmbuf", "clk_mmbuf_pll_andgt",
+         CLK_SET_RATE_PARENT, 0x7C, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3670_PCLK_DIV_MMBUF, "pclk_div_mmbuf", "pclk_mmbuf_andgt",
+         CLK_SET_RATE_PARENT, 0x78, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
+};
+
+/* clk_media2 */
+static const struct hisi_gate_clock hi3670_media2_gate_sep_clks[] = {
+       { HI3670_CLK_GATE_VDECFREQ, "clk_gate_vdecfreq", "clk_div_vdec",
+         CLK_SET_RATE_PARENT, 0x00, 8, 0, },
+       { HI3670_CLK_GATE_VENCFREQ, "clk_gate_vencfreq", "clk_div_venc",
+         CLK_SET_RATE_PARENT, 0x00, 5, 0, },
+       { HI3670_CLK_GATE_ICSFREQ, "clk_gate_icsfreq", "clk_div_ics",
+         CLK_SET_RATE_PARENT, 0x00, 2, 0, },
+};
+
+static void hi3670_clk_crgctrl_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+
+       int nr = ARRAY_SIZE(hi3670_fixed_rate_clks) +
+                ARRAY_SIZE(hi3670_crgctrl_gate_sep_clks) +
+                ARRAY_SIZE(hi3670_crgctrl_gate_clks) +
+                ARRAY_SIZE(hi3670_crgctrl_mux_clks) +
+                ARRAY_SIZE(hi3670_crg_fixed_factor_clks) +
+                ARRAY_SIZE(hi3670_crgctrl_divider_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_fixed_rate(hi3670_fixed_rate_clks,
+                                    ARRAY_SIZE(hi3670_fixed_rate_clks),
+                                    clk_data);
+       hisi_clk_register_gate_sep(hi3670_crgctrl_gate_sep_clks,
+                                  ARRAY_SIZE(hi3670_crgctrl_gate_sep_clks),
+                                  clk_data);
+       hisi_clk_register_gate(hi3670_crgctrl_gate_clks,
+                              ARRAY_SIZE(hi3670_crgctrl_gate_clks),
+                              clk_data);
+       hisi_clk_register_mux(hi3670_crgctrl_mux_clks,
+                             ARRAY_SIZE(hi3670_crgctrl_mux_clks),
+                             clk_data);
+       hisi_clk_register_fixed_factor(hi3670_crg_fixed_factor_clks,
+                                      ARRAY_SIZE(hi3670_crg_fixed_factor_clks),
+                                      clk_data);
+       hisi_clk_register_divider(hi3670_crgctrl_divider_clks,
+                                 ARRAY_SIZE(hi3670_crgctrl_divider_clks),
+                                 clk_data);
+}
+
+static void hi3670_clk_pctrl_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+       int nr = ARRAY_SIZE(hi3670_pctrl_gate_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+       hisi_clk_register_gate(hi3670_pctrl_gate_clks,
+                              ARRAY_SIZE(hi3670_pctrl_gate_clks), clk_data);
+}
+
+static void hi3670_clk_pmuctrl_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+       int nr = ARRAY_SIZE(hi3670_pmu_gate_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_gate(hi3670_pmu_gate_clks,
+                              ARRAY_SIZE(hi3670_pmu_gate_clks), clk_data);
+}
+
+static void hi3670_clk_sctrl_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+       int nr = ARRAY_SIZE(hi3670_sctrl_gate_sep_clks) +
+                ARRAY_SIZE(hi3670_sctrl_gate_clks) +
+                ARRAY_SIZE(hi3670_sctrl_mux_clks) +
+                ARRAY_SIZE(hi3670_sctrl_divider_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_gate_sep(hi3670_sctrl_gate_sep_clks,
+                                  ARRAY_SIZE(hi3670_sctrl_gate_sep_clks),
+                                  clk_data);
+       hisi_clk_register_gate(hi3670_sctrl_gate_clks,
+                              ARRAY_SIZE(hi3670_sctrl_gate_clks),
+                              clk_data);
+       hisi_clk_register_mux(hi3670_sctrl_mux_clks,
+                             ARRAY_SIZE(hi3670_sctrl_mux_clks),
+                             clk_data);
+       hisi_clk_register_divider(hi3670_sctrl_divider_clks,
+                                 ARRAY_SIZE(hi3670_sctrl_divider_clks),
+                                 clk_data);
+}
+
+static void hi3670_clk_iomcu_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+       int nr = ARRAY_SIZE(hi3670_iomcu_gate_sep_clks) +
+                       ARRAY_SIZE(hi3670_iomcu_fixed_factor_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_gate(hi3670_iomcu_gate_sep_clks,
+                              ARRAY_SIZE(hi3670_iomcu_gate_sep_clks), clk_data);
+
+       hisi_clk_register_fixed_factor(hi3670_iomcu_fixed_factor_clks,
+                                      ARRAY_SIZE(hi3670_iomcu_fixed_factor_clks),
+                                      clk_data);
+}
+
+static void hi3670_clk_media1_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+
+       int nr = ARRAY_SIZE(hi3670_media1_gate_sep_clks) +
+                ARRAY_SIZE(hi3670_media1_gate_clks) +
+                ARRAY_SIZE(hi3670_media1_mux_clks) +
+                ARRAY_SIZE(hi3670_media1_divider_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_gate_sep(hi3670_media1_gate_sep_clks,
+                                  ARRAY_SIZE(hi3670_media1_gate_sep_clks),
+                                  clk_data);
+       hisi_clk_register_gate(hi3670_media1_gate_clks,
+                              ARRAY_SIZE(hi3670_media1_gate_clks),
+                              clk_data);
+       hisi_clk_register_mux(hi3670_media1_mux_clks,
+                             ARRAY_SIZE(hi3670_media1_mux_clks),
+                             clk_data);
+       hisi_clk_register_divider(hi3670_media1_divider_clks,
+                                 ARRAY_SIZE(hi3670_media1_divider_clks),
+                                 clk_data);
+}
+
+static void hi3670_clk_media2_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+
+       int nr = ARRAY_SIZE(hi3670_media2_gate_sep_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_gate_sep(hi3670_media2_gate_sep_clks,
+                                  ARRAY_SIZE(hi3670_media2_gate_sep_clks),
+                                  clk_data);
+}
+
+static const struct of_device_id hi3670_clk_match_table[] = {
+       { .compatible = "hisilicon,hi3670-crgctrl",
+         .data = hi3670_clk_crgctrl_init },
+       { .compatible = "hisilicon,hi3670-pctrl",
+         .data = hi3670_clk_pctrl_init },
+       { .compatible = "hisilicon,hi3670-pmuctrl",
+         .data = hi3670_clk_pmuctrl_init },
+       { .compatible = "hisilicon,hi3670-sctrl",
+         .data = hi3670_clk_sctrl_init },
+       { .compatible = "hisilicon,hi3670-iomcu",
+         .data = hi3670_clk_iomcu_init },
+       { .compatible = "hisilicon,hi3670-media1-crg",
+         .data = hi3670_clk_media1_init },
+       { .compatible = "hisilicon,hi3670-media2-crg",
+         .data = hi3670_clk_media2_init },
+       { }
+};
+
+static int hi3670_clk_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = pdev->dev.of_node;
+       void (*init_func)(struct device_node *np);
+
+       init_func = of_device_get_match_data(dev);
+       if (!init_func)
+               return -ENODEV;
+
+       init_func(np);
+
+       return 0;
+}
+
+static struct platform_driver hi3670_clk_driver = {
+       .probe          = hi3670_clk_probe,
+       .driver         = {
+               .name   = "hi3670-clk",
+               .of_match_table = hi3670_clk_match_table,
+       },
+};
+
+static int __init hi3670_clk_init(void)
+{
+       return platform_driver_register(&hi3670_clk_driver);
+}
+core_initcall(hi3670_clk_init);
index 2a5015c736ce6d604d371c0bcd2a894d1ae4015f..43e82fa644226894bb520f4134740f98577ac297 100644 (file)
@@ -109,9 +109,8 @@ struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
                return NULL;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       rstc->membase = devm_ioremap(&pdev->dev,
-                               res->start, resource_size(res));
-       if (!rstc->membase)
+       rstc->membase = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(rstc->membase))
                return NULL;
 
        spin_lock_init(&rstc->lock);
index 9d46eac87f45e7f4ec0e2f72aba0b179b574b9a6..ed1b7e97a0d351cb8519986117857e4d9e1b9141 100644 (file)
@@ -94,7 +94,7 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
 
        init.name = name;
        init.ops = &clk_cpu_ops;
-       init.flags = 0;
+       init.flags = CLK_IS_CRITICAL;
        init.parent_names = &parent_name;
        init.num_parents = 1;
 
index 8c7c2fcb8d9495a6597fa7020d3b297278ec961e..bbe0c60f4d09f868a0a5c7d5cca22d72e66e0013 100644 (file)
@@ -789,6 +789,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
                clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb",            "axi",               base + 0x74, 18);
        clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2_flags("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL);
        clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi",  "mmdc_ch1_axi_podf", base + 0x74, 22);
+       clk[IMX6QDL_CLK_MMDC_P0_IPG]  = imx_clk_gate2_flags("mmdc_p0_ipg",   "ipg",         base + 0x74, 24, CLK_IS_CRITICAL);
        clk[IMX6QDL_CLK_OCRAM]        = imx_clk_gate2("ocram",         "ahb",               base + 0x74, 28);
        clk[IMX6QDL_CLK_OPENVG_AXI]   = imx_clk_gate2("openvg_axi",    "axi",               base + 0x74, 30);
        clk[IMX6QDL_CLK_PCIE_AXI]     = imx_clk_gate2("pcie_axi",      "pcie_axi_sel",      base + 0x78, 0);
index eb6bcbf345a3bac4686f57343555a258f036e09b..6fcfbbd907a56fe0907f971f2a5c258b6f4c47d7 100644 (file)
@@ -386,6 +386,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        clks[IMX6SL_CLK_LCDIF_AXI]    = imx_clk_gate2("lcdif_axi",    "lcdif_axi_podf",    base + 0x74, 6);
        clks[IMX6SL_CLK_LCDIF_PIX]    = imx_clk_gate2("lcdif_pix",    "lcdif_pix_podf",    base + 0x74, 8);
        clks[IMX6SL_CLK_EPDC_PIX]     = imx_clk_gate2("epdc_pix",     "epdc_pix_podf",     base + 0x74, 10);
+       clks[IMX6SL_CLK_MMDC_P0_IPG]  = imx_clk_gate2_flags("mmdc_p0_ipg",  "ipg",         base + 0x74, 24, CLK_IS_CRITICAL);
+       clks[IMX6SL_CLK_MMDC_P1_IPG]  = imx_clk_gate2("mmdc_p1_ipg",  "ipg",               base + 0x74, 26);
        clks[IMX6SL_CLK_OCRAM]        = imx_clk_gate2("ocram",        "ocram_podf",        base + 0x74, 28);
        clks[IMX6SL_CLK_PWM1]         = imx_clk_gate2("pwm1",         "perclk",            base + 0x78, 16);
        clks[IMX6SL_CLK_PWM2]         = imx_clk_gate2("pwm2",         "perclk",            base + 0x78, 18);
index 52379ee49aece91fdd7fb5cd1ae1740f8732787c..3bd2044cf25c2618869f50d0aa17faa63ac1213e 100644 (file)
@@ -293,6 +293,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
        clks[IMX6SLL_CLK_WDOG1]         = imx_clk_gate2("wdog1",        "ipg",          base + 0x74, 16);
        clks[IMX6SLL_CLK_MMDC_P0_FAST]  = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf",  base + 0x74, 20, CLK_IS_CRITICAL);
        clks[IMX6SLL_CLK_MMDC_P0_IPG]   = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg",        base + 0x74, 24, CLK_IS_CRITICAL);
+       clks[IMX6SLL_CLK_MMDC_P1_IPG]   = imx_clk_gate2("mmdc_p1_ipg", "ipg",      base + 0x74, 26);
        clks[IMX6SLL_CLK_OCRAM]         = imx_clk_gate_flags("ocram","ahb",                base + 0x74, 28, CLK_IS_CRITICAL);
 
        /* CCGR4 */
index d9f2890ffe62bea5a42c2c3a485285e002cbc613..18527a335ace30c1c8b308085578561b4f61f483 100644 (file)
@@ -431,6 +431,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
        clks[IMX6SX_CLK_MLB]          = imx_clk_gate2("mlb",           "ahb",               base + 0x74, 18);
        clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL);
        clks[IMX6SX_CLK_MMDC_P0_IPG]  = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
+       clks[IMX6SX_CLK_MMDC_P1_IPG]  = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26);
        clks[IMX6SX_CLK_OCRAM]        = imx_clk_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL);
 
        /* CCGR4 */
index 361b43f9742e752c9d742e61416301be6e33e22a..fd60d1549f719076d05df587d21ca686d0ba7261 100644 (file)
@@ -408,6 +408,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
        clks[IMX6UL_CLK_WDOG1]          = imx_clk_gate2("wdog1",        "ipg",          base + 0x74,    16);
        clks[IMX6UL_CLK_MMDC_P0_FAST]   = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74,  20, CLK_IS_CRITICAL);
        clks[IMX6UL_CLK_MMDC_P0_IPG]    = imx_clk_gate2_flags("mmdc_p0_ipg",    "ipg",          base + 0x74,    24, CLK_IS_CRITICAL);
+       clks[IMX6UL_CLK_MMDC_P1_IPG]    = imx_clk_gate2("mmdc_p1_ipg",  "ipg",          base + 0x74,    26);
        clks[IMX6UL_CLK_AXI]            = imx_clk_gate_flags("axi",     "axi_podf",     base + 0x74,    28, CLK_IS_CRITICAL);
 
        /* CCGR4 */
index 881b772c4ac9708c20371d8276475e55997cee85..adb08f64c6918f040f3f9ef1e074fd4ba28da77f 100644 (file)
@@ -379,14 +379,6 @@ static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src
 static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", };
 static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", };
 
-static int const clks_init_on[] __initconst = {
-       IMX7D_ARM_A7_ROOT_CLK, IMX7D_MAIN_AXI_ROOT_CLK,
-       IMX7D_PLL_SYS_MAIN_480M_CLK, IMX7D_NAND_USDHC_BUS_ROOT_CLK,
-       IMX7D_DRAM_PHYM_ROOT_CLK, IMX7D_DRAM_ROOT_CLK,
-       IMX7D_DRAM_PHYM_ALT_ROOT_CLK, IMX7D_DRAM_ALT_ROOT_CLK,
-       IMX7D_AHB_CHANNEL_ROOT_CLK, IMX7D_IPG_ROOT_CLK,
-};
-
 static struct clk_onecell_data clk_data;
 
 static struct clk ** const uart_clks[] __initconst = {
@@ -404,7 +396,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
        void __iomem *base;
-       int i;
 
        clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
        clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc");
@@ -467,7 +458,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4);
        clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2);
 
-       clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4);
+       clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis_flags("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4, CLK_IS_CRITICAL);
        clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5);
        clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6);
        clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12);
@@ -720,7 +711,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
        clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
        clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6);
-       clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider2("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2);
+       clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider_flags("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT);
        clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
        clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
        clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider2("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
@@ -784,17 +775,17 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
        clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
 
-       clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate4("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
+       clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2_flags("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0, CLK_OPS_PARENT_ENABLE);
        clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
-       clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate4("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
+       clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2_flags("main_axi_root_clk", "axi_post_div", base + 0x4040, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
        clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
        clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
        clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "main_axi_root_clk", base + 0x4110, 0);
        clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0);
-       clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
-       clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
-       clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
-       clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
+       clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2_flags("dram_root_clk", "dram_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
+       clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2_flags("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
+       clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
+       clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
        clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
        clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0);
        clks[IMX7D_MU_ROOT_CLK] = imx_clk_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0);
@@ -883,9 +874,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clk_data.clk_num = ARRAY_SIZE(clks);
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
-       for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
-               clk_prepare_enable(clks[clks_init_on[i]]);
-
        clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]);
        clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]);
        clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]);
index 8076ec040f375f2715c227d64f909e562ae178b5..5895e2237b6c2eee26d619ad77bc1baceb4afecb 100644 (file)
@@ -137,6 +137,13 @@ static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
                        shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
 }
 
+static inline struct clk *imx_clk_gate_dis_flags(const char *name, const char *parent,
+               void __iomem *reg, u8 shift, unsigned long flags)
+{
+       return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
+                       shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
                void __iomem *reg, u8 shift)
 {
diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
new file mode 100644 (file)
index 0000000..34dc0da
--- /dev/null
@@ -0,0 +1,47 @@
+menu "Ingenic JZ47xx CGU drivers"
+       depends on MIPS
+
+config INGENIC_CGU_COMMON
+       bool
+
+config INGENIC_CGU_JZ4740
+       bool "Ingenic JZ4740 CGU driver"
+       default MACH_JZ4740
+       select INGENIC_CGU_COMMON
+       help
+         Support the clocks provided by the CGU hardware on Ingenic JZ4740
+         and compatible SoCs.
+
+         If building for a JZ4740 SoC, you want to say Y here.
+
+config INGENIC_CGU_JZ4725B
+       bool "Ingenic JZ4725B CGU driver"
+       default MACH_JZ4725B
+       select INGENIC_CGU_COMMON
+       help
+         Support the clocks provided by the CGU hardware on Ingenic JZ4725B
+         and compatible SoCs.
+
+         If building for a JZ4725B SoC, you want to say Y here.
+
+config INGENIC_CGU_JZ4770
+       bool "Ingenic JZ4770 CGU driver"
+       default MACH_JZ4770
+       select INGENIC_CGU_COMMON
+       help
+         Support the clocks provided by the CGU hardware on Ingenic JZ4770
+         and compatible SoCs.
+
+         If building for a JZ4770 SoC, you want to say Y here.
+
+config INGENIC_CGU_JZ4780
+       bool "Ingenic JZ4780 CGU driver"
+       default MACH_JZ4780
+       select INGENIC_CGU_COMMON
+       help
+         Support the clocks provided by the CGU hardware on Ingenic JZ4780
+         and compatible SoCs.
+
+         If building for a JZ4780 SoC, you want to say Y here.
+
+endmenu
index 1456e4cdb5622faf68bc7a4f331e433057c5d0f4..00a79b2fba1083044eaa88fd20da115d0d609e99 100644 (file)
@@ -1,4 +1,5 @@
-obj-y                          += cgu.o
-obj-$(CONFIG_MACH_JZ4740)      += jz4740-cgu.o
-obj-$(CONFIG_MACH_JZ4770)      += jz4770-cgu.o
-obj-$(CONFIG_MACH_JZ4780)      += jz4780-cgu.o
+obj-$(CONFIG_INGENIC_CGU_COMMON)       += cgu.o
+obj-$(CONFIG_INGENIC_CGU_JZ4740)       += jz4740-cgu.o
+obj-$(CONFIG_INGENIC_CGU_JZ4725B)      += jz4725b-cgu.o
+obj-$(CONFIG_INGENIC_CGU_JZ4770)       += jz4770-cgu.o
+obj-$(CONFIG_INGENIC_CGU_JZ4780)       += jz4780-cgu.o
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
new file mode 100644 (file)
index 0000000..584ff4f
--- /dev/null
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ingenic JZ4725B SoC CGU driver
+ *
+ * Copyright (C) 2018 Paul Cercueil
+ * Author: Paul Cercueil <paul@crapouillou.net>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4725b-cgu.h>
+#include "cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR          0x00
+#define CGU_REG_LCR            0x04
+#define CGU_REG_CPPCR          0x10
+#define CGU_REG_CLKGR          0x20
+#define CGU_REG_OPCR           0x24
+#define CGU_REG_I2SCDR         0x60
+#define CGU_REG_LPCDR          0x64
+#define CGU_REG_MSCCDR         0x68
+#define CGU_REG_SSICDR         0x74
+#define CGU_REG_CIMCDR         0x78
+
+/* bits within the LCR register */
+#define LCR_SLEEP              BIT(0)
+
+static struct ingenic_cgu *cgu;
+
+static const s8 pll_od_encoding[4] = {
+       0x0, 0x1, -1, 0x3,
+};
+
+static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
+
+       /* External clocks */
+
+       [JZ4725B_CLK_EXT] = { "ext", CGU_CLK_EXT },
+       [JZ4725B_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
+
+       [JZ4725B_CLK_PLL] = {
+               "pll", CGU_CLK_PLL,
+               .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
+               .pll = {
+                       .reg = CGU_REG_CPPCR,
+                       .m_shift = 23,
+                       .m_bits = 9,
+                       .m_offset = 2,
+                       .n_shift = 18,
+                       .n_bits = 5,
+                       .n_offset = 2,
+                       .od_shift = 16,
+                       .od_bits = 2,
+                       .od_max = 4,
+                       .od_encoding = pll_od_encoding,
+                       .stable_bit = 10,
+                       .bypass_bit = 9,
+                       .enable_bit = 8,
+               },
+       },
+
+       /* Muxes & dividers */
+
+       [JZ4725B_CLK_PLL_HALF] = {
+               "pll half", CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1 },
+       },
+
+       [JZ4725B_CLK_CCLK] = {
+               "cclk", CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+       },
+
+       [JZ4725B_CLK_HCLK] = {
+               "hclk", CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
+       },
+
+       [JZ4725B_CLK_PCLK] = {
+               "pclk", CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 },
+       },
+
+       [JZ4725B_CLK_MCLK] = {
+               "mclk", CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 },
+       },
+
+       [JZ4725B_CLK_IPU] = {
+               "ipu", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 13 },
+       },
+
+       [JZ4725B_CLK_LCD] = {
+               "lcd", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_PLL_HALF, -1, -1, -1 },
+               .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 9 },
+       },
+
+       [JZ4725B_CLK_I2S] = {
+               "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 },
+               .mux = { CGU_REG_CPCCR, 31, 1 },
+               .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 6 },
+       },
+
+       [JZ4725B_CLK_SPI] = {
+               "spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL, -1, -1 },
+               .mux = { CGU_REG_SSICDR, 31, 1 },
+               .div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 4 },
+       },
+
+       [JZ4725B_CLK_MMC_MUX] = {
+               "mmc_mux", CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_PLL_HALF, -1, -1, -1 },
+               .div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
+       },
+
+       [JZ4725B_CLK_UDC] = {
+               "udc", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 },
+               .mux = { CGU_REG_CPCCR, 29, 1 },
+               .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
+       },
+
+       /* Gate-only clocks */
+
+       [JZ4725B_CLK_UART] = {
+               "uart", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 0 },
+       },
+
+       [JZ4725B_CLK_DMA] = {
+               "dma", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 12 },
+       },
+
+       [JZ4725B_CLK_ADC] = {
+               "adc", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 7 },
+       },
+
+       [JZ4725B_CLK_I2C] = {
+               "i2c", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 3 },
+       },
+
+       [JZ4725B_CLK_AIC] = {
+               "aic", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 5 },
+       },
+
+       [JZ4725B_CLK_MMC0] = {
+               "mmc0", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_MMC_MUX, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 6 },
+       },
+
+       [JZ4725B_CLK_MMC1] = {
+               "mmc1", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_MMC_MUX, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 16 },
+       },
+
+       [JZ4725B_CLK_BCH] = {
+               "bch", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_MCLK/* not sure */, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 11 },
+       },
+
+       [JZ4725B_CLK_TCU] = {
+               "tcu", CGU_CLK_GATE,
+               .parents = { JZ4725B_CLK_EXT/* not sure */, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 1 },
+       },
+
+       [JZ4725B_CLK_EXT512] = {
+               "ext/512", CGU_CLK_FIXDIV,
+               .parents = { JZ4725B_CLK_EXT },
+
+               /* Doc calls it EXT512, but it seems to be /256... */
+               .fixdiv = { 256 },
+       },
+
+       [JZ4725B_CLK_RTC] = {
+               "rtc", CGU_CLK_MUX,
+               .parents = { JZ4725B_CLK_EXT512, JZ4725B_CLK_OSC32K, -1, -1 },
+               .mux = { CGU_REG_OPCR, 2, 1},
+       },
+};
+
+static void __init jz4725b_cgu_init(struct device_node *np)
+{
+       int retval;
+
+       cgu = ingenic_cgu_new(jz4725b_cgu_clocks,
+                             ARRAY_SIZE(jz4725b_cgu_clocks), np);
+       if (!cgu) {
+               pr_err("%s: failed to initialise CGU\n", __func__);
+               return;
+       }
+
+       retval = ingenic_cgu_register_clocks(cgu);
+       if (retval)
+               pr_err("%s: failed to register CGU Clocks\n", __func__);
+}
+CLK_OF_DECLARE(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init);
index 7e9f0176578a6d09e2170105943d0c6505602f69..b04927d06cd1033924483ff33318d1e82f439f98 100644 (file)
@@ -7,7 +7,7 @@ config COMMON_CLK_KEYSTONE
 
 config TI_SCI_CLK
        tristate "TI System Control Interface clock drivers"
-       depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
+       depends on (ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST) && OF
        depends on TI_SCI_PROTOCOL
        default ARCH_KEYSTONE
        ---help---
index aed5af23895be786db801a2d11360fa3e4a63f2b..4ed9b29ba438a8d83aa5b8e6f34e578d05d178c9 100644 (file)
@@ -245,7 +245,7 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
                return;
        }
 
-       pr_err("%s: error registering clk %s\n", __func__, node->name);
+       pr_err("%s: error registering clk %pOFn\n", __func__, node);
 
 unmap_domain:
        iounmap(data->domain_base);
@@ -266,3 +266,8 @@ static void __init of_keystone_psc_clk_init(struct device_node *node)
 }
 CLK_OF_DECLARE(keystone_gate_clk, "ti,keystone,psc-clock",
                                        of_keystone_psc_clk_init);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Clock driver for Keystone 2 based devices");
+MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");
+MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");
index e7e840fb74eaf7cf58da79d31fbf8d2dd9daeea2..349540469fc085fb09dd13848b6e44ead0fada1c 100644 (file)
@@ -219,7 +219,7 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
        }
 
 out:
-       pr_err("%s: error initializing pll %s\n", __func__, node->name);
+       pr_err("%s: error initializing pll %pOFn\n", __func__, node);
        kfree(pll_data);
 }
 
@@ -338,3 +338,8 @@ static void __init of_pll_mux_clk_init(struct device_node *node)
                pr_err("%s: error registering mux %s\n", __func__, clk_name);
 }
 CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PLL clock driver for Keystone devices");
+MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");
+MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");
index 4dda8988b2f091a665860ae5b2f5dc4cc0492a23..ab6ab07f53e64b79cc7133929ebd3efb9bb1f71f 100644 (file)
@@ -249,11 +249,6 @@ static const char * const msdc30_parents[] = {
        "univpll2_d4"
 };
 
-static const char * const audio_parents[] = {
-       "clk26m",
-       "syspll1_d16"
-};
-
 static const char * const aud_intbus_parents[] = {
        "clk26m",
        "syspll1_d4",
index a0ed41e73bdef7a62b1995e62104d89d3341852f..5f6c860aa122c3a55882f04efbc7d30249453861 100644 (file)
@@ -101,10 +101,16 @@ static const char * const mst_mux_parent_names[] = {
        "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7",
 };
 
-#define AXG_MST_MCLK_MUX(_name, _reg)                                  \
-       AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, CLK_MUX_ROUND_CLOSEST, \
+#define AXG_MST_MUX(_name, _reg, _flag)                                \
+       AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag,          \
                    mst_mux_parent_names, CLK_SET_RATE_PARENT)
 
+#define AXG_MST_MCLK_MUX(_name, _reg)                          \
+       AXG_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST)
+
+#define AXG_MST_SYS_MUX(_name, _reg)                           \
+       AXG_MST_MUX(_name, _reg, 0)
+
 static AXG_MST_MCLK_MUX(mst_a_mclk,   AUDIO_MCLK_A_CTRL);
 static AXG_MST_MCLK_MUX(mst_b_mclk,   AUDIO_MCLK_B_CTRL);
 static AXG_MST_MCLK_MUX(mst_c_mclk,   AUDIO_MCLK_C_CTRL);
@@ -112,13 +118,19 @@ static AXG_MST_MCLK_MUX(mst_d_mclk,   AUDIO_MCLK_D_CTRL);
 static AXG_MST_MCLK_MUX(mst_e_mclk,   AUDIO_MCLK_E_CTRL);
 static AXG_MST_MCLK_MUX(mst_f_mclk,   AUDIO_MCLK_F_CTRL);
 static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
-static AXG_MST_MCLK_MUX(spdifin_clk,  AUDIO_CLK_SPDIFIN_CTRL);
 static AXG_MST_MCLK_MUX(pdm_dclk,     AUDIO_CLK_PDMIN_CTRL0);
-static AXG_MST_MCLK_MUX(pdm_sysclk,   AUDIO_CLK_PDMIN_CTRL1);
+static AXG_MST_SYS_MUX(spdifin_clk,   AUDIO_CLK_SPDIFIN_CTRL);
+static AXG_MST_SYS_MUX(pdm_sysclk,    AUDIO_CLK_PDMIN_CTRL1);
+
+#define AXG_MST_DIV(_name, _reg, _flag)                                \
+       AXG_AUD_DIV(_name##_div, _reg, 0, 16, _flag,            \
+                   "axg_"#_name"_sel", CLK_SET_RATE_PARENT)    \
+
+#define AXG_MST_MCLK_DIV(_name, _reg)                          \
+       AXG_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST)
 
-#define AXG_MST_MCLK_DIV(_name, _reg)                                  \
-       AXG_AUD_DIV(_name##_div, _reg, 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \
-                   "axg_"#_name"_sel", CLK_SET_RATE_PARENT)            \
+#define AXG_MST_SYS_DIV(_name, _reg)                           \
+       AXG_MST_DIV(_name, _reg, 0)
 
 static AXG_MST_MCLK_DIV(mst_a_mclk,   AUDIO_MCLK_A_CTRL);
 static AXG_MST_MCLK_DIV(mst_b_mclk,   AUDIO_MCLK_B_CTRL);
@@ -127,12 +139,12 @@ static AXG_MST_MCLK_DIV(mst_d_mclk,   AUDIO_MCLK_D_CTRL);
 static AXG_MST_MCLK_DIV(mst_e_mclk,   AUDIO_MCLK_E_CTRL);
 static AXG_MST_MCLK_DIV(mst_f_mclk,   AUDIO_MCLK_F_CTRL);
 static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
-static AXG_MST_MCLK_DIV(spdifin_clk,  AUDIO_CLK_SPDIFIN_CTRL);
 static AXG_MST_MCLK_DIV(pdm_dclk,     AUDIO_CLK_PDMIN_CTRL0);
-static AXG_MST_MCLK_DIV(pdm_sysclk,   AUDIO_CLK_PDMIN_CTRL1);
+static AXG_MST_SYS_DIV(spdifin_clk,   AUDIO_CLK_SPDIFIN_CTRL);
+static AXG_MST_SYS_DIV(pdm_sysclk,    AUDIO_CLK_PDMIN_CTRL1);
 
-#define AXG_MST_MCLK_GATE(_name, _reg)                                 \
-       AXG_AUD_GATE(_name, _reg, 31,  "axg_"#_name"_div",              \
+#define AXG_MST_MCLK_GATE(_name, _reg)                         \
+       AXG_AUD_GATE(_name, _reg, 31,  "axg_"#_name"_div",      \
                     CLK_SET_RATE_PARENT)
 
 static AXG_MST_MCLK_GATE(mst_a_mclk,   AUDIO_MCLK_A_CTRL);
index 00ce62ad6416cb5514d792db648e90e42c76e764..c981159b02c0f09c604a78005f26103c75962e9c 100644 (file)
 
 static DEFINE_SPINLOCK(meson_clk_lock);
 
-static struct clk_regmap axg_fixed_pll = {
+static struct clk_regmap axg_fixed_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_MPLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_MPLL_CNTL,
                        .shift   = 0,
@@ -34,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_MPLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_MPLL_CNTL2,
                        .shift   = 0,
@@ -56,15 +56,39 @@ static struct clk_regmap axg_fixed_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "fixed_pll",
+               .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
        },
 };
 
-static struct clk_regmap axg_sys_pll = {
+static struct clk_regmap axg_fixed_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_MPLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fixed_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .num_parents = 1,
+               /*
+                * This clock won't ever change at runtime so
+                * CLK_SET_RATE_PARENT is not required
+                */
+       },
+};
+
+static struct clk_regmap axg_sys_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_SYS_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_SYS_PLL_CNTL,
                        .shift   = 0,
@@ -75,11 +99,6 @@ static struct clk_regmap axg_sys_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_SYS_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .l = {
                        .reg_off = HHI_SYS_PLL_CNTL,
                        .shift   = 31,
@@ -92,102 +111,59 @@ static struct clk_regmap axg_sys_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "sys_pll",
+               .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
        },
 };
 
-static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
-       PLL_RATE(240000000, 40, 1, 2),
-       PLL_RATE(246000000, 41, 1, 2),
-       PLL_RATE(252000000, 42, 1, 2),
-       PLL_RATE(258000000, 43, 1, 2),
-       PLL_RATE(264000000, 44, 1, 2),
-       PLL_RATE(270000000, 45, 1, 2),
-       PLL_RATE(276000000, 46, 1, 2),
-       PLL_RATE(282000000, 47, 1, 2),
-       PLL_RATE(288000000, 48, 1, 2),
-       PLL_RATE(294000000, 49, 1, 2),
-       PLL_RATE(300000000, 50, 1, 2),
-       PLL_RATE(306000000, 51, 1, 2),
-       PLL_RATE(312000000, 52, 1, 2),
-       PLL_RATE(318000000, 53, 1, 2),
-       PLL_RATE(324000000, 54, 1, 2),
-       PLL_RATE(330000000, 55, 1, 2),
-       PLL_RATE(336000000, 56, 1, 2),
-       PLL_RATE(342000000, 57, 1, 2),
-       PLL_RATE(348000000, 58, 1, 2),
-       PLL_RATE(354000000, 59, 1, 2),
-       PLL_RATE(360000000, 60, 1, 2),
-       PLL_RATE(366000000, 61, 1, 2),
-       PLL_RATE(372000000, 62, 1, 2),
-       PLL_RATE(378000000, 63, 1, 2),
-       PLL_RATE(384000000, 64, 1, 2),
-       PLL_RATE(390000000, 65, 1, 3),
-       PLL_RATE(396000000, 66, 1, 3),
-       PLL_RATE(402000000, 67, 1, 3),
-       PLL_RATE(408000000, 68, 1, 3),
-       PLL_RATE(480000000, 40, 1, 1),
-       PLL_RATE(492000000, 41, 1, 1),
-       PLL_RATE(504000000, 42, 1, 1),
-       PLL_RATE(516000000, 43, 1, 1),
-       PLL_RATE(528000000, 44, 1, 1),
-       PLL_RATE(540000000, 45, 1, 1),
-       PLL_RATE(552000000, 46, 1, 1),
-       PLL_RATE(564000000, 47, 1, 1),
-       PLL_RATE(576000000, 48, 1, 1),
-       PLL_RATE(588000000, 49, 1, 1),
-       PLL_RATE(600000000, 50, 1, 1),
-       PLL_RATE(612000000, 51, 1, 1),
-       PLL_RATE(624000000, 52, 1, 1),
-       PLL_RATE(636000000, 53, 1, 1),
-       PLL_RATE(648000000, 54, 1, 1),
-       PLL_RATE(660000000, 55, 1, 1),
-       PLL_RATE(672000000, 56, 1, 1),
-       PLL_RATE(684000000, 57, 1, 1),
-       PLL_RATE(696000000, 58, 1, 1),
-       PLL_RATE(708000000, 59, 1, 1),
-       PLL_RATE(720000000, 60, 1, 1),
-       PLL_RATE(732000000, 61, 1, 1),
-       PLL_RATE(744000000, 62, 1, 1),
-       PLL_RATE(756000000, 63, 1, 1),
-       PLL_RATE(768000000, 64, 1, 1),
-       PLL_RATE(780000000, 65, 1, 1),
-       PLL_RATE(792000000, 66, 1, 1),
-       PLL_RATE(804000000, 67, 1, 1),
-       PLL_RATE(816000000, 68, 1, 1),
-       PLL_RATE(960000000, 40, 1, 0),
-       PLL_RATE(984000000, 41, 1, 0),
-       PLL_RATE(1008000000, 42, 1, 0),
-       PLL_RATE(1032000000, 43, 1, 0),
-       PLL_RATE(1056000000, 44, 1, 0),
-       PLL_RATE(1080000000, 45, 1, 0),
-       PLL_RATE(1104000000, 46, 1, 0),
-       PLL_RATE(1128000000, 47, 1, 0),
-       PLL_RATE(1152000000, 48, 1, 0),
-       PLL_RATE(1176000000, 49, 1, 0),
-       PLL_RATE(1200000000, 50, 1, 0),
-       PLL_RATE(1224000000, 51, 1, 0),
-       PLL_RATE(1248000000, 52, 1, 0),
-       PLL_RATE(1272000000, 53, 1, 0),
-       PLL_RATE(1296000000, 54, 1, 0),
-       PLL_RATE(1320000000, 55, 1, 0),
-       PLL_RATE(1344000000, 56, 1, 0),
-       PLL_RATE(1368000000, 57, 1, 0),
-       PLL_RATE(1392000000, 58, 1, 0),
-       PLL_RATE(1416000000, 59, 1, 0),
-       PLL_RATE(1440000000, 60, 1, 0),
-       PLL_RATE(1464000000, 61, 1, 0),
-       PLL_RATE(1488000000, 62, 1, 0),
-       PLL_RATE(1512000000, 63, 1, 0),
-       PLL_RATE(1536000000, 64, 1, 0),
-       PLL_RATE(1560000000, 65, 1, 0),
-       PLL_RATE(1584000000, 66, 1, 0),
-       PLL_RATE(1608000000, 67, 1, 0),
-       PLL_RATE(1632000000, 68, 1, 0),
+static struct clk_regmap axg_sys_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_SYS_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "sys_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct pll_params_table axg_gp0_pll_params_table[] = {
+       PLL_PARAMS(40, 1),
+       PLL_PARAMS(41, 1),
+       PLL_PARAMS(42, 1),
+       PLL_PARAMS(43, 1),
+       PLL_PARAMS(44, 1),
+       PLL_PARAMS(45, 1),
+       PLL_PARAMS(46, 1),
+       PLL_PARAMS(47, 1),
+       PLL_PARAMS(48, 1),
+       PLL_PARAMS(49, 1),
+       PLL_PARAMS(50, 1),
+       PLL_PARAMS(51, 1),
+       PLL_PARAMS(52, 1),
+       PLL_PARAMS(53, 1),
+       PLL_PARAMS(54, 1),
+       PLL_PARAMS(55, 1),
+       PLL_PARAMS(56, 1),
+       PLL_PARAMS(57, 1),
+       PLL_PARAMS(58, 1),
+       PLL_PARAMS(59, 1),
+       PLL_PARAMS(60, 1),
+       PLL_PARAMS(61, 1),
+       PLL_PARAMS(62, 1),
+       PLL_PARAMS(63, 1),
+       PLL_PARAMS(64, 1),
+       PLL_PARAMS(65, 1),
+       PLL_PARAMS(66, 1),
+       PLL_PARAMS(67, 1),
+       PLL_PARAMS(68, 1),
        { /* sentinel */ },
 };
 
@@ -197,11 +173,15 @@ static const struct reg_sequence axg_gp0_init_regs[] = {
        { .reg = HHI_GP0_PLL_CNTL3,     .def = 0x0a59a288 },
        { .reg = HHI_GP0_PLL_CNTL4,     .def = 0xc000004d },
        { .reg = HHI_GP0_PLL_CNTL5,     .def = 0x00078000 },
-       { .reg = HHI_GP0_PLL_CNTL,      .def = 0x40010250 },
 };
 
-static struct clk_regmap axg_gp0_pll = {
+static struct clk_regmap axg_gp0_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_GP0_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_GP0_PLL_CNTL,
                        .shift   = 0,
@@ -212,11 +192,6 @@ static struct clk_regmap axg_gp0_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_GP0_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_GP0_PLL_CNTL1,
                        .shift   = 0,
@@ -232,29 +207,49 @@ static struct clk_regmap axg_gp0_pll = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .table = axg_gp0_pll_rate_table,
+               .table = axg_gp0_pll_params_table,
                .init_regs = axg_gp0_init_regs,
                .init_count = ARRAY_SIZE(axg_gp0_init_regs),
        },
        .hw.init = &(struct clk_init_data){
-               .name = "gp0_pll",
+               .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
        },
 };
 
+static struct clk_regmap axg_gp0_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_GP0_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "gp0_pll",
+               .ops = &clk_regmap_divider_ops,
+               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 static const struct reg_sequence axg_hifi_init_regs[] = {
        { .reg = HHI_HIFI_PLL_CNTL1,    .def = 0xc084b000 },
        { .reg = HHI_HIFI_PLL_CNTL2,    .def = 0xb75020be },
        { .reg = HHI_HIFI_PLL_CNTL3,    .def = 0x0a6a3a88 },
        { .reg = HHI_HIFI_PLL_CNTL4,    .def = 0xc000004d },
        { .reg = HHI_HIFI_PLL_CNTL5,    .def = 0x00058000 },
-       { .reg = HHI_HIFI_PLL_CNTL,     .def = 0x40010250 },
 };
 
-static struct clk_regmap axg_hifi_pll = {
+static struct clk_regmap axg_hifi_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_HIFI_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_HIFI_PLL_CNTL,
                        .shift   = 0,
@@ -265,11 +260,6 @@ static struct clk_regmap axg_hifi_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_HIFI_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_HIFI_PLL_CNTL5,
                        .shift   = 0,
@@ -285,19 +275,35 @@ static struct clk_regmap axg_hifi_pll = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .table = axg_gp0_pll_rate_table,
+               .table = axg_gp0_pll_params_table,
                .init_regs = axg_hifi_init_regs,
                .init_count = ARRAY_SIZE(axg_hifi_init_regs),
                .flags = CLK_MESON_PLL_ROUND_CLOSEST,
        },
        .hw.init = &(struct clk_init_data){
-               .name = "hifi_pll",
+               .name = "hifi_pll_dco",
                .ops = &meson_clk_pll_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
        },
 };
 
+static struct clk_regmap axg_hifi_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HIFI_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "hifi_pll",
+               .ops = &clk_regmap_divider_ops,
+               .parent_names = (const char *[]){ "hifi_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 static struct clk_fixed_factor axg_fclk_div2_div = {
        .mult = 1,
        .div = 2,
@@ -625,29 +631,31 @@ static struct clk_regmap axg_mpll3 = {
        },
 };
 
-static const struct pll_rate_table axg_pcie_pll_rate_table[] = {
+static const struct pll_params_table axg_pcie_pll_params_table[] = {
        {
-               .rate   = 100000000,
-               .m      = 200,
-               .n      = 3,
-               .od     = 1,
-               .od2    = 3,
+               .m = 200,
+               .n = 3,
        },
        { /* sentinel */ },
 };
 
 static const struct reg_sequence axg_pcie_init_regs[] = {
-       { .reg = HHI_PCIE_PLL_CNTL,     .def = 0x400106c8 },
        { .reg = HHI_PCIE_PLL_CNTL1,    .def = 0x0084a2aa },
        { .reg = HHI_PCIE_PLL_CNTL2,    .def = 0xb75020be },
        { .reg = HHI_PCIE_PLL_CNTL3,    .def = 0x0a47488e },
        { .reg = HHI_PCIE_PLL_CNTL4,    .def = 0xc000004d },
        { .reg = HHI_PCIE_PLL_CNTL5,    .def = 0x00078000 },
        { .reg = HHI_PCIE_PLL_CNTL6,    .def = 0x002323c6 },
+       { .reg = HHI_PCIE_PLL_CNTL,     .def = 0x400106c8 },
 };
 
-static struct clk_regmap axg_pcie_pll = {
+static struct clk_regmap axg_pcie_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_PCIE_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_PCIE_PLL_CNTL,
                        .shift   = 0,
@@ -658,16 +666,6 @@ static struct clk_regmap axg_pcie_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_PCIE_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
-               .od2 = {
-                       .reg_off = HHI_PCIE_PLL_CNTL6,
-                       .shift   = 6,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_PCIE_PLL_CNTL1,
                        .shift   = 0,
@@ -683,29 +681,63 @@ static struct clk_regmap axg_pcie_pll = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .table = axg_pcie_pll_rate_table,
+               .table = axg_pcie_pll_params_table,
                .init_regs = axg_pcie_init_regs,
                .init_count = ARRAY_SIZE(axg_pcie_init_regs),
        },
        .hw.init = &(struct clk_init_data){
-               .name = "pcie_pll",
+               .name = "pcie_pll_dco",
                .ops = &meson_clk_pll_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
        },
 };
 
+static struct clk_regmap axg_pcie_pll_od = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_PCIE_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "pcie_pll_od",
+               .ops = &clk_regmap_divider_ops,
+               .parent_names = (const char *[]){ "pcie_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap axg_pcie_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_PCIE_PLL_CNTL6,
+               .shift = 6,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "pcie_pll",
+               .ops = &clk_regmap_divider_ops,
+               .parent_names = (const char *[]){ "pcie_pll_od" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 static struct clk_regmap axg_pcie_mux = {
        .data = &(struct clk_regmap_mux_data){
                .offset = HHI_PCIE_PLL_CNTL6,
                .mask = 0x1,
                .shift = 2,
+               /* skip the parent mpll3, reserved for debug */
+               .table = (u32[]){ 1 },
        },
        .hw.init = &(struct clk_init_data){
                .name = "pcie_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mpll3", "pcie_pll" },
-               .num_parents = 2,
+               .parent_names = (const char *[]){ "pcie_pll" },
+               .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1107,6 +1139,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
                [CLKID_GEN_CLK_SEL]             = &axg_gen_clk_sel.hw,
                [CLKID_GEN_CLK_DIV]             = &axg_gen_clk_div.hw,
                [CLKID_GEN_CLK]                 = &axg_gen_clk.hw,
+               [CLKID_SYS_PLL_DCO]             = &axg_sys_pll_dco.hw,
+               [CLKID_FIXED_PLL_DCO]           = &axg_fixed_pll_dco.hw,
+               [CLKID_GP0_PLL_DCO]             = &axg_gp0_pll_dco.hw,
+               [CLKID_HIFI_PLL_DCO]            = &axg_hifi_pll_dco.hw,
+               [CLKID_PCIE_PLL_DCO]            = &axg_pcie_pll_dco.hw,
+               [CLKID_PCIE_PLL_OD]             = &axg_pcie_pll_od.hw,
                [NR_CLKS]                       = NULL,
        },
        .num = NR_CLKS,
@@ -1185,6 +1223,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
        &axg_fclk_div4,
        &axg_fclk_div5,
        &axg_fclk_div7,
+       &axg_pcie_pll_dco,
+       &axg_pcie_pll_od,
        &axg_pcie_pll,
        &axg_pcie_mux,
        &axg_pcie_ref,
@@ -1194,6 +1234,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
        &axg_gen_clk_sel,
        &axg_gen_clk_div,
        &axg_gen_clk,
+       &axg_fixed_pll_dco,
+       &axg_sys_pll_dco,
+       &axg_gp0_pll_dco,
+       &axg_hifi_pll_dco,
+       &axg_pcie_pll_dco,
+       &axg_pcie_pll_od,
 };
 
 static const struct of_device_id clkc_match_table[] = {
index 1d04144a1b2cc2caee16096530719e45e86a6eba..0431dabac6294e43e29adf38dcbe3cfd77a8a685 100644 (file)
 #define CLKID_PCIE_REF                         78
 #define CLKID_GEN_CLK_SEL                      82
 #define CLKID_GEN_CLK_DIV                      83
+#define CLKID_SYS_PLL_DCO                      85
+#define CLKID_FIXED_PLL_DCO                    86
+#define CLKID_GP0_PLL_DCO                      87
+#define CLKID_HIFI_PLL_DCO                     88
+#define CLKID_PCIE_PLL_DCO                     89
+#define CLKID_PCIE_PLL_OD                      90
 
-#define NR_CLKS                                        85
+#define NR_CLKS                                        91
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
index 3e04617ac47f6f0f39d5bee94a06bbc026c7ca62..f5b5b3fabe3cbe48606565a77e947f82496b8b88 100644 (file)
  * In the most basic form, a Meson PLL is composed as follows:
  *
  *                     PLL
- *      +------------------------------+
- *      |                              |
- * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out
- *      |         ^        ^           |
- *      +------------------------------+
- *                |        |
- *               FREF     VCO
+ *        +--------------------------------+
+ *        |                                |
+ *        |             +--+               |
+ *  in >>-----[ /N ]--->|  |      +-----+  |
+ *        |             |  |------| DCO |---->> out
+ *        |  +--------->|  |      +--v--+  |
+ *        |  |          +--+         |     |
+ *        |  |                       |     |
+ *        |  +--[ *(M + (F/Fmax) ]<--+     |
+ *        |                                |
+ *        +--------------------------------+
  *
- * out = in * (m + frac / frac_max) / (n << sum(ods))
+ * out = in * (m + frac / frac_max) / n
  */
 
 #include <linux/clk-provider.h>
@@ -41,12 +45,11 @@ meson_clk_pll_data(struct clk_regmap *clk)
 }
 
 static unsigned long __pll_params_to_rate(unsigned long parent_rate,
-                                         const struct pll_rate_table *pllt,
+                                         const struct pll_params_table *pllt,
                                          u16 frac,
                                          struct meson_clk_pll_data *pll)
 {
        u64 rate = (u64)parent_rate * pllt->m;
-       unsigned int od = pllt->od + pllt->od2 + pllt->od3;
 
        if (frac && MESON_PARM_APPLICABLE(&pll->frac)) {
                u64 frac_rate = (u64)parent_rate * frac;
@@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate,
                                         (1 << pll->frac.width));
        }
 
-       return DIV_ROUND_UP_ULL(rate, pllt->n << od);
+       return DIV_ROUND_UP_ULL(rate, pllt->n);
 }
 
 static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
@@ -63,20 +66,11 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
-       struct pll_rate_table pllt;
+       struct pll_params_table pllt;
        u16 frac;
 
        pllt.n = meson_parm_read(clk->map, &pll->n);
        pllt.m = meson_parm_read(clk->map, &pll->m);
-       pllt.od = meson_parm_read(clk->map, &pll->od);
-
-       pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ?
-               meson_parm_read(clk->map, &pll->od2) :
-               0;
-
-       pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ?
-               meson_parm_read(clk->map, &pll->od3) :
-               0;
 
        frac = MESON_PARM_APPLICABLE(&pll->frac) ?
                meson_parm_read(clk->map, &pll->frac) :
@@ -87,14 +81,12 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
 
 static u16 __pll_params_with_frac(unsigned long rate,
                                  unsigned long parent_rate,
-                                 const struct pll_rate_table *pllt,
+                                 const struct pll_params_table *pllt,
                                  struct meson_clk_pll_data *pll)
 {
        u16 frac_max = (1 << pll->frac.width);
        u64 val = (u64)rate * pllt->n;
 
-       val <<= pllt->od + pllt->od2 + pllt->od3;
-
        if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
                val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate);
        else
@@ -105,29 +97,50 @@ static u16 __pll_params_with_frac(unsigned long rate,
        return min((u16)val, (u16)(frac_max - 1));
 }
 
-static const struct pll_rate_table *
+static bool meson_clk_pll_is_better(unsigned long rate,
+                                   unsigned long best,
+                                   unsigned long now,
+                                   struct meson_clk_pll_data *pll)
+{
+       if (!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
+           MESON_PARM_APPLICABLE(&pll->frac)) {
+               /* Round down */
+               if (now < rate && best < now)
+                       return true;
+       } else {
+               /* Round Closest */
+               if (abs(now - rate) < abs(best - rate))
+                       return true;
+       }
+
+       return false;
+}
+
+static const struct pll_params_table *
 meson_clk_get_pll_settings(unsigned long rate,
+                          unsigned long parent_rate,
                           struct meson_clk_pll_data *pll)
 {
-       const struct pll_rate_table *table = pll->table;
-       unsigned int i = 0;
+       const struct pll_params_table *table = pll->table;
+       unsigned long best = 0, now = 0;
+       unsigned int i, best_i = 0;
 
        if (!table)
                return NULL;
 
-       /* Find the first table element exceeding rate */
-       while (table[i].rate && table[i].rate <= rate)
-               i++;
+       for (i = 0; table[i].n; i++) {
+               now = __pll_params_to_rate(parent_rate, &table[i], 0, pll);
 
-       if (i != 0) {
-               if (MESON_PARM_APPLICABLE(&pll->frac) ||
-                   !(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
-                   (abs(rate - table[i - 1].rate) <
-                    abs(rate - table[i].rate)))
-                       i--;
+               /* If we get an exact match, don't bother any further */
+               if (now == rate) {
+                       return &table[i];
+               } else if (meson_clk_pll_is_better(rate, best, now, pll)) {
+                       best = now;
+                       best_i = i;
+               }
        }
 
-       return (struct pll_rate_table *)&table[i];
+       return (struct pll_params_table *)&table[best_i];
 }
 
 static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -135,16 +148,18 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
-       const struct pll_rate_table *pllt =
-               meson_clk_get_pll_settings(rate, pll);
+       const struct pll_params_table *pllt =
+               meson_clk_get_pll_settings(rate, *parent_rate, pll);
+       unsigned long round;
        u16 frac;
 
        if (!pllt)
                return meson_clk_pll_recalc_rate(hw, *parent_rate);
 
-       if (!MESON_PARM_APPLICABLE(&pll->frac)
-           || rate == pllt->rate)
-               return pllt->rate;
+       round = __pll_params_to_rate(*parent_rate, pllt, 0, pll);
+
+       if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round)
+               return round;
 
        /*
         * The rate provided by the setting is not an exact match, let's
@@ -185,12 +200,45 @@ static void meson_clk_pll_init(struct clk_hw *hw)
        }
 }
 
+static int meson_clk_pll_enable(struct clk_hw *hw)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
+
+       /* Make sure the pll is in reset */
+       meson_parm_write(clk->map, &pll->rst, 1);
+
+       /* Enable the pll */
+       meson_parm_write(clk->map, &pll->en, 1);
+
+       /* Take the pll out reset */
+       meson_parm_write(clk->map, &pll->rst, 0);
+
+       if (meson_clk_pll_wait_lock(hw))
+               return -EIO;
+
+       return 0;
+}
+
+static void meson_clk_pll_disable(struct clk_hw *hw)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
+
+       /* Put the pll is in reset */
+       meson_parm_write(clk->map, &pll->rst, 1);
+
+       /* Disable the pll */
+       meson_parm_write(clk->map, &pll->en, 0);
+}
+
 static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
                                  unsigned long parent_rate)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
-       const struct pll_rate_table *pllt;
+       const struct pll_params_table *pllt;
+       unsigned int enabled;
        unsigned long old_rate;
        u16 frac = 0;
 
@@ -199,32 +247,28 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 
        old_rate = rate;
 
-       pllt = meson_clk_get_pll_settings(rate, pll);
+       pllt = meson_clk_get_pll_settings(rate, parent_rate, pll);
        if (!pllt)
                return -EINVAL;
 
-       /* Put the pll in reset to write the params */
-       meson_parm_write(clk->map, &pll->rst, 1);
+       enabled = meson_parm_read(clk->map, &pll->en);
+       if (enabled)
+               meson_clk_pll_disable(hw);
 
        meson_parm_write(clk->map, &pll->n, pllt->n);
        meson_parm_write(clk->map, &pll->m, pllt->m);
-       meson_parm_write(clk->map, &pll->od, pllt->od);
 
-       if (MESON_PARM_APPLICABLE(&pll->od2))
-               meson_parm_write(clk->map, &pll->od2, pllt->od2);
-
-       if (MESON_PARM_APPLICABLE(&pll->od3))
-               meson_parm_write(clk->map, &pll->od3, pllt->od3);
 
        if (MESON_PARM_APPLICABLE(&pll->frac)) {
                frac = __pll_params_with_frac(rate, parent_rate, pllt, pll);
                meson_parm_write(clk->map, &pll->frac, frac);
        }
 
-       /* make sure the reset is cleared at this point */
-       meson_parm_write(clk->map, &pll->rst, 0);
+       /* If the pll is stopped, bail out now */
+       if (!enabled)
+               return 0;
 
-       if (meson_clk_pll_wait_lock(hw)) {
+       if (meson_clk_pll_enable(hw)) {
                pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
                        __func__, old_rate);
                /*
@@ -244,6 +288,8 @@ const struct clk_ops meson_clk_pll_ops = {
        .recalc_rate    = meson_clk_pll_recalc_rate,
        .round_rate     = meson_clk_pll_round_rate,
        .set_rate       = meson_clk_pll_set_rate,
+       .enable         = meson_clk_pll_enable,
+       .disable        = meson_clk_pll_disable
 };
 
 const struct clk_ops meson_clk_pll_ro_ops = {
index 24cec16b603868fc1040c699f88b916d10ff0f8d..6b96d55c047d69aae1732c75c0b9f3ee0f9b6197 100644 (file)
@@ -43,37 +43,29 @@ static inline void meson_parm_write(struct regmap *map, struct parm *p,
 }
 
 
-struct pll_rate_table {
-       unsigned long   rate;
+struct pll_params_table {
        u16             m;
        u16             n;
-       u16             od;
-       u16             od2;
-       u16             od3;
 };
 
-#define PLL_RATE(_r, _m, _n, _od)                                      \
+#define PLL_PARAMS(_m, _n)                                             \
        {                                                               \
-               .rate           = (_r),                                 \
                .m              = (_m),                                 \
                .n              = (_n),                                 \
-               .od             = (_od),                                \
        }
 
 #define CLK_MESON_PLL_ROUND_CLOSEST    BIT(0)
 
 struct meson_clk_pll_data {
+       struct parm en;
        struct parm m;
        struct parm n;
        struct parm frac;
-       struct parm od;
-       struct parm od2;
-       struct parm od3;
        struct parm l;
        struct parm rst;
        const struct reg_sequence *init_regs;
        unsigned int init_count;
-       const struct pll_rate_table *table;
+       const struct pll_params_table *table;
        u8 flags;
 };
 
index 86d3ae58e84c280c8ba982cf52e6848fd743db4e..9309cfaaa464ebd5f3e7d26e174c3c8449e16208 100644 (file)
 
 static DEFINE_SPINLOCK(meson_clk_lock);
 
-static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = {
-       PLL_RATE(96000000, 32, 1, 3),
-       PLL_RATE(99000000, 33, 1, 3),
-       PLL_RATE(102000000, 34, 1, 3),
-       PLL_RATE(105000000, 35, 1, 3),
-       PLL_RATE(108000000, 36, 1, 3),
-       PLL_RATE(111000000, 37, 1, 3),
-       PLL_RATE(114000000, 38, 1, 3),
-       PLL_RATE(117000000, 39, 1, 3),
-       PLL_RATE(120000000, 40, 1, 3),
-       PLL_RATE(123000000, 41, 1, 3),
-       PLL_RATE(126000000, 42, 1, 3),
-       PLL_RATE(129000000, 43, 1, 3),
-       PLL_RATE(132000000, 44, 1, 3),
-       PLL_RATE(135000000, 45, 1, 3),
-       PLL_RATE(138000000, 46, 1, 3),
-       PLL_RATE(141000000, 47, 1, 3),
-       PLL_RATE(144000000, 48, 1, 3),
-       PLL_RATE(147000000, 49, 1, 3),
-       PLL_RATE(150000000, 50, 1, 3),
-       PLL_RATE(153000000, 51, 1, 3),
-       PLL_RATE(156000000, 52, 1, 3),
-       PLL_RATE(159000000, 53, 1, 3),
-       PLL_RATE(162000000, 54, 1, 3),
-       PLL_RATE(165000000, 55, 1, 3),
-       PLL_RATE(168000000, 56, 1, 3),
-       PLL_RATE(171000000, 57, 1, 3),
-       PLL_RATE(174000000, 58, 1, 3),
-       PLL_RATE(177000000, 59, 1, 3),
-       PLL_RATE(180000000, 60, 1, 3),
-       PLL_RATE(183000000, 61, 1, 3),
-       PLL_RATE(186000000, 62, 1, 3),
-       PLL_RATE(192000000, 32, 1, 2),
-       PLL_RATE(198000000, 33, 1, 2),
-       PLL_RATE(204000000, 34, 1, 2),
-       PLL_RATE(210000000, 35, 1, 2),
-       PLL_RATE(216000000, 36, 1, 2),
-       PLL_RATE(222000000, 37, 1, 2),
-       PLL_RATE(228000000, 38, 1, 2),
-       PLL_RATE(234000000, 39, 1, 2),
-       PLL_RATE(240000000, 40, 1, 2),
-       PLL_RATE(246000000, 41, 1, 2),
-       PLL_RATE(252000000, 42, 1, 2),
-       PLL_RATE(258000000, 43, 1, 2),
-       PLL_RATE(264000000, 44, 1, 2),
-       PLL_RATE(270000000, 45, 1, 2),
-       PLL_RATE(276000000, 46, 1, 2),
-       PLL_RATE(282000000, 47, 1, 2),
-       PLL_RATE(288000000, 48, 1, 2),
-       PLL_RATE(294000000, 49, 1, 2),
-       PLL_RATE(300000000, 50, 1, 2),
-       PLL_RATE(306000000, 51, 1, 2),
-       PLL_RATE(312000000, 52, 1, 2),
-       PLL_RATE(318000000, 53, 1, 2),
-       PLL_RATE(324000000, 54, 1, 2),
-       PLL_RATE(330000000, 55, 1, 2),
-       PLL_RATE(336000000, 56, 1, 2),
-       PLL_RATE(342000000, 57, 1, 2),
-       PLL_RATE(348000000, 58, 1, 2),
-       PLL_RATE(354000000, 59, 1, 2),
-       PLL_RATE(360000000, 60, 1, 2),
-       PLL_RATE(366000000, 61, 1, 2),
-       PLL_RATE(372000000, 62, 1, 2),
-       PLL_RATE(384000000, 32, 1, 1),
-       PLL_RATE(396000000, 33, 1, 1),
-       PLL_RATE(408000000, 34, 1, 1),
-       PLL_RATE(420000000, 35, 1, 1),
-       PLL_RATE(432000000, 36, 1, 1),
-       PLL_RATE(444000000, 37, 1, 1),
-       PLL_RATE(456000000, 38, 1, 1),
-       PLL_RATE(468000000, 39, 1, 1),
-       PLL_RATE(480000000, 40, 1, 1),
-       PLL_RATE(492000000, 41, 1, 1),
-       PLL_RATE(504000000, 42, 1, 1),
-       PLL_RATE(516000000, 43, 1, 1),
-       PLL_RATE(528000000, 44, 1, 1),
-       PLL_RATE(540000000, 45, 1, 1),
-       PLL_RATE(552000000, 46, 1, 1),
-       PLL_RATE(564000000, 47, 1, 1),
-       PLL_RATE(576000000, 48, 1, 1),
-       PLL_RATE(588000000, 49, 1, 1),
-       PLL_RATE(600000000, 50, 1, 1),
-       PLL_RATE(612000000, 51, 1, 1),
-       PLL_RATE(624000000, 52, 1, 1),
-       PLL_RATE(636000000, 53, 1, 1),
-       PLL_RATE(648000000, 54, 1, 1),
-       PLL_RATE(660000000, 55, 1, 1),
-       PLL_RATE(672000000, 56, 1, 1),
-       PLL_RATE(684000000, 57, 1, 1),
-       PLL_RATE(696000000, 58, 1, 1),
-       PLL_RATE(708000000, 59, 1, 1),
-       PLL_RATE(720000000, 60, 1, 1),
-       PLL_RATE(732000000, 61, 1, 1),
-       PLL_RATE(744000000, 62, 1, 1),
-       PLL_RATE(768000000, 32, 1, 0),
-       PLL_RATE(792000000, 33, 1, 0),
-       PLL_RATE(816000000, 34, 1, 0),
-       PLL_RATE(840000000, 35, 1, 0),
-       PLL_RATE(864000000, 36, 1, 0),
-       PLL_RATE(888000000, 37, 1, 0),
-       PLL_RATE(912000000, 38, 1, 0),
-       PLL_RATE(936000000, 39, 1, 0),
-       PLL_RATE(960000000, 40, 1, 0),
-       PLL_RATE(984000000, 41, 1, 0),
-       PLL_RATE(1008000000, 42, 1, 0),
-       PLL_RATE(1032000000, 43, 1, 0),
-       PLL_RATE(1056000000, 44, 1, 0),
-       PLL_RATE(1080000000, 45, 1, 0),
-       PLL_RATE(1104000000, 46, 1, 0),
-       PLL_RATE(1128000000, 47, 1, 0),
-       PLL_RATE(1152000000, 48, 1, 0),
-       PLL_RATE(1176000000, 49, 1, 0),
-       PLL_RATE(1200000000, 50, 1, 0),
-       PLL_RATE(1224000000, 51, 1, 0),
-       PLL_RATE(1248000000, 52, 1, 0),
-       PLL_RATE(1272000000, 53, 1, 0),
-       PLL_RATE(1296000000, 54, 1, 0),
-       PLL_RATE(1320000000, 55, 1, 0),
-       PLL_RATE(1344000000, 56, 1, 0),
-       PLL_RATE(1368000000, 57, 1, 0),
-       PLL_RATE(1392000000, 58, 1, 0),
-       PLL_RATE(1416000000, 59, 1, 0),
-       PLL_RATE(1440000000, 60, 1, 0),
-       PLL_RATE(1464000000, 61, 1, 0),
-       PLL_RATE(1488000000, 62, 1, 0),
+static const struct pll_params_table gxbb_gp0_pll_params_table[] = {
+       PLL_PARAMS(32, 1),
+       PLL_PARAMS(33, 1),
+       PLL_PARAMS(34, 1),
+       PLL_PARAMS(35, 1),
+       PLL_PARAMS(36, 1),
+       PLL_PARAMS(37, 1),
+       PLL_PARAMS(38, 1),
+       PLL_PARAMS(39, 1),
+       PLL_PARAMS(40, 1),
+       PLL_PARAMS(41, 1),
+       PLL_PARAMS(42, 1),
+       PLL_PARAMS(43, 1),
+       PLL_PARAMS(44, 1),
+       PLL_PARAMS(45, 1),
+       PLL_PARAMS(46, 1),
+       PLL_PARAMS(47, 1),
+       PLL_PARAMS(48, 1),
+       PLL_PARAMS(49, 1),
+       PLL_PARAMS(50, 1),
+       PLL_PARAMS(51, 1),
+       PLL_PARAMS(52, 1),
+       PLL_PARAMS(53, 1),
+       PLL_PARAMS(54, 1),
+       PLL_PARAMS(55, 1),
+       PLL_PARAMS(56, 1),
+       PLL_PARAMS(57, 1),
+       PLL_PARAMS(58, 1),
+       PLL_PARAMS(59, 1),
+       PLL_PARAMS(60, 1),
+       PLL_PARAMS(61, 1),
+       PLL_PARAMS(62, 1),
        { /* sentinel */ },
 };
 
-static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
-       PLL_RATE(504000000, 42, 1, 1),
-       PLL_RATE(516000000, 43, 1, 1),
-       PLL_RATE(528000000, 44, 1, 1),
-       PLL_RATE(540000000, 45, 1, 1),
-       PLL_RATE(552000000, 46, 1, 1),
-       PLL_RATE(564000000, 47, 1, 1),
-       PLL_RATE(576000000, 48, 1, 1),
-       PLL_RATE(588000000, 49, 1, 1),
-       PLL_RATE(600000000, 50, 1, 1),
-       PLL_RATE(612000000, 51, 1, 1),
-       PLL_RATE(624000000, 52, 1, 1),
-       PLL_RATE(636000000, 53, 1, 1),
-       PLL_RATE(648000000, 54, 1, 1),
-       PLL_RATE(660000000, 55, 1, 1),
-       PLL_RATE(672000000, 56, 1, 1),
-       PLL_RATE(684000000, 57, 1, 1),
-       PLL_RATE(696000000, 58, 1, 1),
-       PLL_RATE(708000000, 59, 1, 1),
-       PLL_RATE(720000000, 60, 1, 1),
-       PLL_RATE(732000000, 61, 1, 1),
-       PLL_RATE(744000000, 62, 1, 1),
-       PLL_RATE(756000000, 63, 1, 1),
-       PLL_RATE(768000000, 64, 1, 1),
-       PLL_RATE(780000000, 65, 1, 1),
-       PLL_RATE(792000000, 66, 1, 1),
+static const struct pll_params_table gxl_gp0_pll_params_table[] = {
+       PLL_PARAMS(42, 1),
+       PLL_PARAMS(43, 1),
+       PLL_PARAMS(44, 1),
+       PLL_PARAMS(45, 1),
+       PLL_PARAMS(46, 1),
+       PLL_PARAMS(47, 1),
+       PLL_PARAMS(48, 1),
+       PLL_PARAMS(49, 1),
+       PLL_PARAMS(50, 1),
+       PLL_PARAMS(51, 1),
+       PLL_PARAMS(52, 1),
+       PLL_PARAMS(53, 1),
+       PLL_PARAMS(54, 1),
+       PLL_PARAMS(55, 1),
+       PLL_PARAMS(56, 1),
+       PLL_PARAMS(57, 1),
+       PLL_PARAMS(58, 1),
+       PLL_PARAMS(59, 1),
+       PLL_PARAMS(60, 1),
+       PLL_PARAMS(61, 1),
+       PLL_PARAMS(62, 1),
+       PLL_PARAMS(63, 1),
+       PLL_PARAMS(64, 1),
+       PLL_PARAMS(65, 1),
+       PLL_PARAMS(66, 1),
        { /* sentinel */ },
 };
 
-static struct clk_regmap gxbb_fixed_pll = {
+static struct clk_regmap gxbb_fixed_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_MPLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_MPLL_CNTL,
                        .shift   = 0,
@@ -187,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_MPLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_MPLL_CNTL2,
                        .shift   = 0,
@@ -209,11 +116,29 @@ static struct clk_regmap gxbb_fixed_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "fixed_pll",
+               .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_regmap gxbb_fixed_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_MPLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fixed_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .num_parents = 1,
+               /*
+                * This clock won't ever change at runtime so
+                * CLK_SET_RATE_PARENT is not required
+                */
        },
 };
 
@@ -228,8 +153,13 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
        },
 };
 
-static struct clk_regmap gxbb_hdmi_pll = {
+static struct clk_regmap gxbb_hdmi_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_HDMI_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_HDMI_PLL_CNTL,
                        .shift   = 0,
@@ -245,21 +175,6 @@ static struct clk_regmap gxbb_hdmi_pll = {
                        .shift   = 0,
                        .width   = 12,
                },
-               .od = {
-                       .reg_off = HHI_HDMI_PLL_CNTL2,
-                       .shift   = 16,
-                       .width   = 2,
-               },
-               .od2 = {
-                       .reg_off = HHI_HDMI_PLL_CNTL2,
-                       .shift   = 22,
-                       .width   = 2,
-               },
-               .od3 = {
-                       .reg_off = HHI_HDMI_PLL_CNTL2,
-                       .shift   = 18,
-                       .width   = 2,
-               },
                .l = {
                        .reg_off = HHI_HDMI_PLL_CNTL,
                        .shift   = 31,
@@ -272,74 +187,121 @@ static struct clk_regmap gxbb_hdmi_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "hdmi_pll",
+               .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "hdmi_pll_pre_mult" },
                .num_parents = 1,
+               /*
+                * Display directly handle hdmi pll registers ATM, we need
+                * NOCACHE to keep our view of the clock as accurate as possible
+                */
                .flags = CLK_GET_RATE_NOCACHE,
        },
 };
 
+static struct clk_regmap gxbb_hdmi_pll_od = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HDMI_PLL_CNTL2,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "hdmi_pll_od",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap gxbb_hdmi_pll_od2 = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HDMI_PLL_CNTL2,
+               .shift = 22,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "hdmi_pll_od2",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap gxbb_hdmi_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HDMI_PLL_CNTL2,
+               .shift = 18,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "hdmi_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap gxl_hdmi_pll_od = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HDMI_PLL_CNTL + 8,
+               .shift = 21,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "hdmi_pll_od",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap gxl_hdmi_pll_od2 = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HDMI_PLL_CNTL + 8,
+               .shift = 23,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "hdmi_pll_od2",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
+       },
+};
+
 static struct clk_regmap gxl_hdmi_pll = {
-       .data = &(struct meson_clk_pll_data){
-               .m = {
-                       .reg_off = HHI_HDMI_PLL_CNTL,
-                       .shift   = 0,
-                       .width   = 9,
-               },
-               .n = {
-                       .reg_off = HHI_HDMI_PLL_CNTL,
-                       .shift   = 9,
-                       .width   = 5,
-               },
-               .frac = {
-                       /*
-                        * On gxl, there is a register shift due to
-                        * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb,
-                        * so we compute the register offset based on the PLL
-                        * base to get it right
-                        */
-                       .reg_off = HHI_HDMI_PLL_CNTL + 4,
-                       .shift   = 0,
-                       .width   = 12,
-               },
-               .od = {
-                       .reg_off = HHI_HDMI_PLL_CNTL + 8,
-                       .shift   = 21,
-                       .width   = 2,
-               },
-               .od2 = {
-                       .reg_off = HHI_HDMI_PLL_CNTL + 8,
-                       .shift   = 23,
-                       .width   = 2,
-               },
-               .od3 = {
-                       .reg_off = HHI_HDMI_PLL_CNTL + 8,
-                       .shift   = 19,
-                       .width   = 2,
-               },
-               .l = {
-                       .reg_off = HHI_HDMI_PLL_CNTL,
-                       .shift   = 31,
-                       .width   = 1,
-               },
-               .rst = {
-                       .reg_off = HHI_HDMI_PLL_CNTL,
-                       .shift   = 29,
-                       .width   = 1,
-               },
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_HDMI_PLL_CNTL + 8,
+               .shift = 19,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
        },
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "hdmi_pll_od2" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
+               .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
 };
 
-static struct clk_regmap gxbb_sys_pll = {
+static struct clk_regmap gxbb_sys_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_SYS_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_SYS_PLL_CNTL,
                        .shift   = 0,
@@ -350,11 +312,6 @@ static struct clk_regmap gxbb_sys_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_SYS_PLL_CNTL,
-                       .shift   = 10,
-                       .width   = 2,
-               },
                .l = {
                        .reg_off = HHI_SYS_PLL_CNTL,
                        .shift   = 31,
@@ -367,11 +324,26 @@ static struct clk_regmap gxbb_sys_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "sys_pll",
+               .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_regmap gxbb_sys_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_SYS_PLL_CNTL,
+               .shift = 10,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "sys_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -379,11 +351,15 @@ static const struct reg_sequence gxbb_gp0_init_regs[] = {
        { .reg = HHI_GP0_PLL_CNTL2,     .def = 0x69c80000 },
        { .reg = HHI_GP0_PLL_CNTL3,     .def = 0x0a5590c4 },
        { .reg = HHI_GP0_PLL_CNTL4,     .def = 0x0000500d },
-       { .reg = HHI_GP0_PLL_CNTL,      .def = 0x4a000228 },
 };
 
-static struct clk_regmap gxbb_gp0_pll = {
+static struct clk_regmap gxbb_gp0_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_GP0_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_GP0_PLL_CNTL,
                        .shift   = 0,
@@ -394,11 +370,6 @@ static struct clk_regmap gxbb_gp0_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_GP0_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .l = {
                        .reg_off = HHI_GP0_PLL_CNTL,
                        .shift   = 31,
@@ -409,16 +380,15 @@ static struct clk_regmap gxbb_gp0_pll = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .table = gxbb_gp0_pll_rate_table,
+               .table = gxbb_gp0_pll_params_table,
                .init_regs = gxbb_gp0_init_regs,
                .init_count = ARRAY_SIZE(gxbb_gp0_init_regs),
        },
        .hw.init = &(struct clk_init_data){
-               .name = "gp0_pll",
+               .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
        },
 };
 
@@ -428,11 +398,15 @@ static const struct reg_sequence gxl_gp0_init_regs[] = {
        { .reg = HHI_GP0_PLL_CNTL3,     .def = 0x0a59a288 },
        { .reg = HHI_GP0_PLL_CNTL4,     .def = 0xc000004d },
        { .reg = HHI_GP0_PLL_CNTL5,     .def = 0x00078000 },
-       { .reg = HHI_GP0_PLL_CNTL,      .def = 0x40010250 },
 };
 
-static struct clk_regmap gxl_gp0_pll = {
+static struct clk_regmap gxl_gp0_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_GP0_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_GP0_PLL_CNTL,
                        .shift   = 0,
@@ -443,11 +417,6 @@ static struct clk_regmap gxl_gp0_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_GP0_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_GP0_PLL_CNTL1,
                        .shift   = 0,
@@ -463,16 +432,31 @@ static struct clk_regmap gxl_gp0_pll = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .table = gxl_gp0_pll_rate_table,
+               .table = gxl_gp0_pll_params_table,
                .init_regs = gxl_gp0_init_regs,
                .init_count = ARRAY_SIZE(gxl_gp0_init_regs),
        },
        .hw.init = &(struct clk_init_data){
-               .name = "gp0_pll",
+               .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_regmap gxbb_gp0_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_GP0_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "gp0_pll",
+               .ops = &clk_regmap_divider_ops,
+               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1933,6 +1917,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
                [CLKID_GEN_CLK_SEL]         = &gxbb_gen_clk_sel.hw,
                [CLKID_GEN_CLK_DIV]         = &gxbb_gen_clk_div.hw,
                [CLKID_GEN_CLK]             = &gxbb_gen_clk.hw,
+               [CLKID_FIXED_PLL_DCO]       = &gxbb_fixed_pll_dco.hw,
+               [CLKID_HDMI_PLL_DCO]        = &gxbb_hdmi_pll_dco.hw,
+               [CLKID_HDMI_PLL_OD]         = &gxbb_hdmi_pll_od.hw,
+               [CLKID_HDMI_PLL_OD2]        = &gxbb_hdmi_pll_od2.hw,
+               [CLKID_SYS_PLL_DCO]         = &gxbb_sys_pll_dco.hw,
+               [CLKID_GP0_PLL_DCO]         = &gxbb_gp0_pll_dco.hw,
                [NR_CLKS]                   = NULL,
        },
        .num = NR_CLKS,
@@ -1948,7 +1938,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
                [CLKID_FCLK_DIV4]           = &gxbb_fclk_div4.hw,
                [CLKID_FCLK_DIV5]           = &gxbb_fclk_div5.hw,
                [CLKID_FCLK_DIV7]           = &gxbb_fclk_div7.hw,
-               [CLKID_GP0_PLL]             = &gxl_gp0_pll.hw,
+               [CLKID_GP0_PLL]             = &gxbb_gp0_pll.hw,
                [CLKID_MPEG_SEL]            = &gxbb_mpeg_clk_sel.hw,
                [CLKID_MPEG_DIV]            = &gxbb_mpeg_clk_div.hw,
                [CLKID_CLK81]               = &gxbb_clk81.hw,
@@ -2098,19 +2088,29 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
                [CLKID_GEN_CLK_SEL]         = &gxbb_gen_clk_sel.hw,
                [CLKID_GEN_CLK_DIV]         = &gxbb_gen_clk_div.hw,
                [CLKID_GEN_CLK]             = &gxbb_gen_clk.hw,
+               [CLKID_FIXED_PLL_DCO]       = &gxbb_fixed_pll_dco.hw,
+               [CLKID_HDMI_PLL_DCO]        = &gxbb_hdmi_pll_dco.hw,
+               [CLKID_HDMI_PLL_OD]         = &gxl_hdmi_pll_od.hw,
+               [CLKID_HDMI_PLL_OD2]        = &gxl_hdmi_pll_od2.hw,
+               [CLKID_SYS_PLL_DCO]         = &gxbb_sys_pll_dco.hw,
+               [CLKID_GP0_PLL_DCO]         = &gxl_gp0_pll_dco.hw,
                [NR_CLKS]                   = NULL,
        },
        .num = NR_CLKS,
 };
 
 static struct clk_regmap *const gxbb_clk_regmaps[] = {
-       &gxbb_gp0_pll,
+       &gxbb_gp0_pll_dco,
        &gxbb_hdmi_pll,
+       &gxbb_hdmi_pll_od,
+       &gxbb_hdmi_pll_od2,
 };
 
 static struct clk_regmap *const gxl_clk_regmaps[] = {
-       &gxl_gp0_pll,
+       &gxl_gp0_pll_dco,
        &gxl_hdmi_pll,
+       &gxl_hdmi_pll_od,
+       &gxl_hdmi_pll_od2,
 };
 
 static struct clk_regmap *const gx_clk_regmaps[] = {
@@ -2265,6 +2265,10 @@ static struct clk_regmap *const gx_clk_regmaps[] = {
        &gxbb_gen_clk_sel,
        &gxbb_gen_clk_div,
        &gxbb_gen_clk,
+       &gxbb_fixed_pll_dco,
+       &gxbb_hdmi_pll_dco,
+       &gxbb_sys_pll_dco,
+       &gxbb_gp0_pll,
 };
 
 struct clkc_data {
index 20dfb1daf5b83c988b9b98974dbc27a97906af22..72bc077d96639c0d2e98d5ac4b3b161ceda3f691 100644 (file)
 #define CLKID_VDEC_HEVC_DIV      155
 #define CLKID_GEN_CLK_SEL        157
 #define CLKID_GEN_CLK_DIV        158
-
-#define NR_CLKS                          160
+#define CLKID_FIXED_PLL_DCO      160
+#define CLKID_HDMI_PLL_DCO       161
+#define CLKID_HDMI_PLL_OD        162
+#define CLKID_HDMI_PLL_OD2       163
+#define CLKID_SYS_PLL_DCO        164
+#define CLKID_GP0_PLL_DCO        165
+
+#define NR_CLKS                          166
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/gxbb-clkc.h>
index 7447d96a265f72e7d4b4277c29f5839df3ff43b6..346b9e165b7a9d55903d45839467349ca1bb3613 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/clk-provider.h>
 #include <linux/init.h>
 #include <linux/of_address.h>
-#include <linux/platform_device.h>
 #include <linux/reset-controller.h>
 #include <linux/slab.h>
 #include <linux/regmap.h>
 
 static DEFINE_SPINLOCK(meson_clk_lock);
 
-static void __iomem *clk_base;
-
 struct meson8b_clk_reset {
        struct reset_controller_dev reset;
-       void __iomem *base;
+       struct regmap *regmap;
 };
 
-static const struct pll_rate_table sys_pll_rate_table[] = {
-       PLL_RATE(312000000, 52, 1, 2),
-       PLL_RATE(336000000, 56, 1, 2),
-       PLL_RATE(360000000, 60, 1, 2),
-       PLL_RATE(384000000, 64, 1, 2),
-       PLL_RATE(408000000, 68, 1, 2),
-       PLL_RATE(432000000, 72, 1, 2),
-       PLL_RATE(456000000, 76, 1, 2),
-       PLL_RATE(480000000, 80, 1, 2),
-       PLL_RATE(504000000, 84, 1, 2),
-       PLL_RATE(528000000, 88, 1, 2),
-       PLL_RATE(552000000, 92, 1, 2),
-       PLL_RATE(576000000, 96, 1, 2),
-       PLL_RATE(600000000, 50, 1, 1),
-       PLL_RATE(624000000, 52, 1, 1),
-       PLL_RATE(648000000, 54, 1, 1),
-       PLL_RATE(672000000, 56, 1, 1),
-       PLL_RATE(696000000, 58, 1, 1),
-       PLL_RATE(720000000, 60, 1, 1),
-       PLL_RATE(744000000, 62, 1, 1),
-       PLL_RATE(768000000, 64, 1, 1),
-       PLL_RATE(792000000, 66, 1, 1),
-       PLL_RATE(816000000, 68, 1, 1),
-       PLL_RATE(840000000, 70, 1, 1),
-       PLL_RATE(864000000, 72, 1, 1),
-       PLL_RATE(888000000, 74, 1, 1),
-       PLL_RATE(912000000, 76, 1, 1),
-       PLL_RATE(936000000, 78, 1, 1),
-       PLL_RATE(960000000, 80, 1, 1),
-       PLL_RATE(984000000, 82, 1, 1),
-       PLL_RATE(1008000000, 84, 1, 1),
-       PLL_RATE(1032000000, 86, 1, 1),
-       PLL_RATE(1056000000, 88, 1, 1),
-       PLL_RATE(1080000000, 90, 1, 1),
-       PLL_RATE(1104000000, 92, 1, 1),
-       PLL_RATE(1128000000, 94, 1, 1),
-       PLL_RATE(1152000000, 96, 1, 1),
-       PLL_RATE(1176000000, 98, 1, 1),
-       PLL_RATE(1200000000, 50, 1, 0),
-       PLL_RATE(1224000000, 51, 1, 0),
-       PLL_RATE(1248000000, 52, 1, 0),
-       PLL_RATE(1272000000, 53, 1, 0),
-       PLL_RATE(1296000000, 54, 1, 0),
-       PLL_RATE(1320000000, 55, 1, 0),
-       PLL_RATE(1344000000, 56, 1, 0),
-       PLL_RATE(1368000000, 57, 1, 0),
-       PLL_RATE(1392000000, 58, 1, 0),
-       PLL_RATE(1416000000, 59, 1, 0),
-       PLL_RATE(1440000000, 60, 1, 0),
-       PLL_RATE(1464000000, 61, 1, 0),
-       PLL_RATE(1488000000, 62, 1, 0),
-       PLL_RATE(1512000000, 63, 1, 0),
-       PLL_RATE(1536000000, 64, 1, 0),
+static const struct pll_params_table sys_pll_params_table[] = {
+       PLL_PARAMS(50, 1),
+       PLL_PARAMS(51, 1),
+       PLL_PARAMS(52, 1),
+       PLL_PARAMS(53, 1),
+       PLL_PARAMS(54, 1),
+       PLL_PARAMS(55, 1),
+       PLL_PARAMS(56, 1),
+       PLL_PARAMS(57, 1),
+       PLL_PARAMS(58, 1),
+       PLL_PARAMS(59, 1),
+       PLL_PARAMS(60, 1),
+       PLL_PARAMS(61, 1),
+       PLL_PARAMS(62, 1),
+       PLL_PARAMS(63, 1),
+       PLL_PARAMS(64, 1),
        { /* sentinel */ },
 };
 
@@ -94,8 +54,13 @@ static struct clk_fixed_rate meson8b_xtal = {
        },
 };
 
-static struct clk_regmap meson8b_fixed_pll = {
+static struct clk_regmap meson8b_fixed_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_MPLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_MPLL_CNTL,
                        .shift   = 0,
@@ -106,11 +71,6 @@ static struct clk_regmap meson8b_fixed_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_MPLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .frac = {
                        .reg_off = HHI_MPLL_CNTL2,
                        .shift   = 0,
@@ -128,16 +88,39 @@ static struct clk_regmap meson8b_fixed_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "fixed_pll",
+               .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
        },
 };
 
-static struct clk_regmap meson8b_vid_pll = {
+static struct clk_regmap meson8b_fixed_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_MPLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fixed_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .num_parents = 1,
+               /*
+                * This clock won't ever change at runtime so
+                * CLK_SET_RATE_PARENT is not required
+                */
+       },
+};
+
+static struct clk_regmap meson8b_vid_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_VID_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_VID_PLL_CNTL,
                        .shift   = 0,
@@ -148,11 +131,6 @@ static struct clk_regmap meson8b_vid_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_VID_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .l = {
                        .reg_off = HHI_VID_PLL_CNTL,
                        .shift   = 31,
@@ -165,16 +143,36 @@ static struct clk_regmap meson8b_vid_pll = {
                },
        },
        .hw.init = &(struct clk_init_data){
-               .name = "vid_pll",
+               .name = "vid_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
        },
 };
 
-static struct clk_regmap meson8b_sys_pll = {
+static struct clk_regmap meson8b_vid_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_VID_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "vid_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "vid_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap meson8b_sys_pll_dco = {
        .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = HHI_SYS_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
                .m = {
                        .reg_off = HHI_SYS_PLL_CNTL,
                        .shift   = 0,
@@ -185,11 +183,6 @@ static struct clk_regmap meson8b_sys_pll = {
                        .shift   = 9,
                        .width   = 5,
                },
-               .od = {
-                       .reg_off = HHI_SYS_PLL_CNTL,
-                       .shift   = 16,
-                       .width   = 2,
-               },
                .l = {
                        .reg_off = HHI_SYS_PLL_CNTL,
                        .shift   = 31,
@@ -200,14 +193,29 @@ static struct clk_regmap meson8b_sys_pll = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .table = sys_pll_rate_table,
+               .table = sys_pll_params_table,
        },
        .hw.init = &(struct clk_init_data){
-               .name = "sys_pll",
+               .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
                .parent_names = (const char *[]){ "xtal" },
                .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_regmap meson8b_sys_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = HHI_SYS_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "sys_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -879,6 +887,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
                [CLKID_NAND_SEL]            = &meson8b_nand_clk_sel.hw,
                [CLKID_NAND_DIV]            = &meson8b_nand_clk_div.hw,
                [CLKID_NAND_CLK]            = &meson8b_nand_clk_gate.hw,
+               [CLKID_PLL_FIXED_DCO]       = &meson8b_fixed_pll_dco.hw,
+               [CLKID_PLL_VID_DCO]         = &meson8b_vid_pll_dco.hw,
+               [CLKID_PLL_SYS_DCO]         = &meson8b_sys_pll_dco.hw,
                [CLK_NR_CLKS]               = NULL,
        },
        .num = CLK_NR_CLKS,
@@ -987,6 +998,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
        &meson8b_nand_clk_sel,
        &meson8b_nand_clk_div,
        &meson8b_nand_clk_gate,
+       &meson8b_fixed_pll_dco,
+       &meson8b_vid_pll_dco,
+       &meson8b_sys_pll_dco,
 };
 
 static const struct meson8b_clk_reset_line {
@@ -1050,7 +1064,6 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
                container_of(rcdev, struct meson8b_clk_reset, reset);
        unsigned long flags;
        const struct meson8b_clk_reset_line *reset;
-       u32 val;
 
        if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
                return -EINVAL;
@@ -1059,12 +1072,12 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
 
        spin_lock_irqsave(&meson_clk_lock, flags);
 
-       val = readl(meson8b_clk_reset->base + reset->reg);
        if (assert)
-               val |= BIT(reset->bit_idx);
+               regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
+                                  BIT(reset->bit_idx), BIT(reset->bit_idx));
        else
-               val &= ~BIT(reset->bit_idx);
-       writel(val, meson8b_clk_reset->base + reset->reg);
+               regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
+                                  BIT(reset->bit_idx), 0);
 
        spin_unlock_irqrestore(&meson_clk_lock, flags);
 
@@ -1094,62 +1107,12 @@ static const struct regmap_config clkc_regmap_config = {
        .reg_stride     = 4,
 };
 
-static int meson8b_clkc_probe(struct platform_device *pdev)
-{
-       int ret, i;
-       struct device *dev = &pdev->dev;
-       struct regmap *map;
-
-       if (!clk_base)
-               return -ENXIO;
-
-       map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
-       if (IS_ERR(map))
-               return PTR_ERR(map);
-
-       /* Populate regmap for the regmap backed clocks */
-       for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
-               meson8b_clk_regmaps[i]->map = map;
-
-       /*
-        * register all clks
-        * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
-        */
-       for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
-               /* array might be sparse */
-               if (!meson8b_hw_onecell_data.hws[i])
-                       continue;
-
-               ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]);
-               if (ret)
-                       return ret;
-       }
-
-       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
-                                          &meson8b_hw_onecell_data);
-}
-
-static const struct of_device_id meson8b_clkc_match_table[] = {
-       { .compatible = "amlogic,meson8-clkc" },
-       { .compatible = "amlogic,meson8b-clkc" },
-       { .compatible = "amlogic,meson8m2-clkc" },
-       { }
-};
-
-static struct platform_driver meson8b_driver = {
-       .probe          = meson8b_clkc_probe,
-       .driver         = {
-               .name   = "meson8b-clkc",
-               .of_match_table = meson8b_clkc_match_table,
-       },
-};
-
-builtin_platform_driver(meson8b_driver);
-
-static void __init meson8b_clkc_reset_init(struct device_node *np)
+static void __init meson8b_clkc_init(struct device_node *np)
 {
        struct meson8b_clk_reset *rstc;
-       int ret;
+       void __iomem *clk_base;
+       struct regmap *map;
+       int i, ret;
 
        /* Generic clocks, PLLs and some of the reset-bits */
        clk_base = of_iomap(np, 1);
@@ -1158,12 +1121,16 @@ static void __init meson8b_clkc_reset_init(struct device_node *np)
                return;
        }
 
+       map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config);
+       if (IS_ERR(map))
+               return;
+
        rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
        if (!rstc)
                return;
 
        /* Reset Controller */
-       rstc->base = clk_base;
+       rstc->regmap = map;
        rstc->reset.ops = &meson8b_clk_reset_ops;
        rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
        rstc->reset.of_node = np;
@@ -1173,11 +1140,34 @@ static void __init meson8b_clkc_reset_init(struct device_node *np)
                       __func__, ret);
                return;
        }
+
+       /* Populate regmap for the regmap backed clocks */
+       for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
+               meson8b_clk_regmaps[i]->map = map;
+
+       /*
+        * register all clks
+        * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
+        */
+       for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
+               /* array might be sparse */
+               if (!meson8b_hw_onecell_data.hws[i])
+                       continue;
+
+               ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]);
+               if (ret)
+                       return;
+       }
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
+                                    &meson8b_hw_onecell_data);
+       if (ret)
+               pr_err("%s: failed to register clock provider\n", __func__);
 }
 
 CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
-                     meson8b_clkc_reset_init);
+                     meson8b_clkc_init);
 CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
-                     meson8b_clkc_reset_init);
+                     meson8b_clkc_init);
 CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
-                     meson8b_clkc_reset_init);
+                     meson8b_clkc_init);
index 5d09412b5084760460850550d9b1e85c8a7fe5f6..1c6fb180e6a29777e12b22ba60af7c7969009ad4 100644 (file)
 #define CLKID_FCLK_DIV7_DIV    109
 #define CLKID_NAND_SEL         110
 #define CLKID_NAND_DIV         111
+#define CLKID_PLL_FIXED_DCO    113
+#define CLKID_PLL_VID_DCO      114
+#define CLKID_PLL_SYS_DCO      115
 
-#define CLK_NR_CLKS            113
+#define CLK_NR_CLKS            116
 
 /*
  * include the CLKID and RESETID that have
index 0fc75c39595708f0d5c6296fcbeea4e3d61f5731..d083b860f08333ad1caf8082664efdeaf1e0099d 100644 (file)
@@ -227,8 +227,8 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
        /* The gate clocks has mux parent. */
        {MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
        {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
-       {MMP2_CLK_SDH1, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
-       {MMP2_CLK_SDH1, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
+       {MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
+       {MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
        {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
        {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
        {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock},
index fa2fbd2cef4a343b50ccec04224c7dfc07dd6c52..ea54a874bbdadd0a58843a637ef0885a1f65a02d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada AP806 System Controller
  *
@@ -5,9 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #define pr_fmt(fmt) "ap806-system-controller: " fmt
@@ -155,7 +153,6 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
                goto fail4;
        }
 
-       of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
        ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
        if (ret)
                goto fail_clk_add;
index 2c7c1085f88300ca84ac529831876af25376a047..7dedfaa6e152033bd3f5e1e60dec8c28c86edfe9 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada 370 SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index c7af2242b796866a9367b02c0a74827499901a1f..a7157c69023861c644173291cdd0ec89f8e0b99f 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada 375 SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 499f5962c8b062d70d40d36d3aadfc23cfeb43a2..1f1cff428d7888eb61a2e8e1a046f6d4b6847105 100644 (file)
 struct clk_periph_driver_data {
        struct clk_hw_onecell_data *hw_data;
        spinlock_t lock;
+       void __iomem *reg;
+
+       /* Storage registers for suspend/resume operations */
+       u32 tbg_sel;
+       u32 div_sel0;
+       u32 div_sel1;
+       u32 div_sel2;
+       u32 clk_sel;
+       u32 clk_dis;
 };
 
 struct clk_double_div {
@@ -672,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
        return PTR_ERR_OR_ZERO(*hw);
 }
 
+static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev)
+{
+       struct clk_periph_driver_data *data = dev_get_drvdata(dev);
+
+       data->tbg_sel = readl(data->reg + TBG_SEL);
+       data->div_sel0 = readl(data->reg + DIV_SEL0);
+       data->div_sel1 = readl(data->reg + DIV_SEL1);
+       data->div_sel2 = readl(data->reg + DIV_SEL2);
+       data->clk_sel = readl(data->reg + CLK_SEL);
+       data->clk_dis = readl(data->reg + CLK_DIS);
+
+       return 0;
+}
+
+static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev)
+{
+       struct clk_periph_driver_data *data = dev_get_drvdata(dev);
+
+       /* Follow the same order than what the Cortex-M3 does (ATF code) */
+       writel(data->clk_dis, data->reg + CLK_DIS);
+       writel(data->div_sel0, data->reg + DIV_SEL0);
+       writel(data->div_sel1, data->reg + DIV_SEL1);
+       writel(data->div_sel2, data->reg + DIV_SEL2);
+       writel(data->tbg_sel, data->reg + TBG_SEL);
+       writel(data->clk_sel, data->reg + CLK_SEL);
+
+       return 0;
+}
+
+static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend,
+                               armada_3700_periph_clock_resume)
+};
+
 static int armada_3700_periph_clock_probe(struct platform_device *pdev)
 {
        struct clk_periph_driver_data *driver_data;
@@ -680,7 +723,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        int num_periph = 0, i, ret;
        struct resource *res;
-       void __iomem *reg;
 
        data = of_device_get_match_data(dev);
        if (!data)
@@ -689,11 +731,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
        while (data[num_periph].name)
                num_periph++;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       reg = devm_ioremap_resource(dev, res);
-       if (IS_ERR(reg))
-               return PTR_ERR(reg);
-
        driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
        if (!driver_data)
                return -ENOMEM;
@@ -706,12 +743,16 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
                return -ENOMEM;
        driver_data->hw_data->num = num_periph;
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       driver_data->reg = devm_ioremap_resource(dev, res);
+       if (IS_ERR(driver_data->reg))
+               return PTR_ERR(driver_data->reg);
+
        spin_lock_init(&driver_data->lock);
 
        for (i = 0; i < num_periph; i++) {
                struct clk_hw **hw = &driver_data->hw_data->hws[i];
-
-               if (armada_3700_add_composite_clk(&data[i], reg,
+               if (armada_3700_add_composite_clk(&data[i], driver_data->reg,
                                                  &driver_data->lock, dev, hw))
                        dev_err(dev, "Can't register periph clock %s\n",
                                data[i].name);
@@ -749,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = {
        .driver         = {
                .name   = "marvell-armada-3700-periph-clock",
                .of_match_table = armada_3700_periph_clock_of_match,
+               .pm     = &armada_3700_periph_clock_pm_ops,
        },
 };
 
index 7ff041f73b5530b1bff020d9ad21c32b3f808050..ee272d4d8c24ffd6637944dafeaa8f875b53a269 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Marvell Armada 37xx SoC Time Base Generator clocks
  *
  * Copyright (C) 2016 Marvell
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2 or later. This program is licensed "as is"
- * without any warranty of any kind, whether express or implied.
  */
 
 #include <linux/clk-provider.h>
@@ -99,12 +96,13 @@ static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
        hw_tbg_data->num = NUM_TBG;
        platform_set_drvdata(pdev, hw_tbg_data);
 
-       parent = devm_clk_get(dev, NULL);
+       parent = clk_get(dev, NULL);
        if (IS_ERR(parent)) {
                dev_err(dev, "Could get the clock parent\n");
                return -EINVAL;
        }
        parent_name = __clk_get_name(parent);
+       clk_put(parent);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        reg = devm_ioremap_resource(dev, res);
index 612d65ede10a0d2e0efc2e07954855972e35572a..e9e306d4e9af9d440f9f0e94f1f2977e23ce68cd 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada 37xx SoC xtal clocks
  *
@@ -5,9 +6,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/clk-provider.h>
index 9ff4ea63932d507c9a5b7289e34eddf125193652..ef2ab81f087dfd348ec3629ff985c3ad88642c5f 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada 380/385 SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 4fdfd32247a9cba1fbf3d855919fccacb02b0334..674ccfd6236e895cea2092d67f6f18cf3bee63f6 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada 39x SoC clocks
  *
@@ -8,9 +9,6 @@
  * Andrew Lunn <andrew@lunn.ch>
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 0ec44ae9a2a2676ea383925d3841cffa0dd93a67..e8f03293ec833a97886269f21c648dff00f9d6fb 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada XP SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 68f05c53d40e1a67c77ea1a49d1f6d4fe53cbe01..1fc84b0e72eec18ef5cddd7c3ba6d9ff4ea5e70c 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * MVEBU Core divider clock
  *
@@ -5,9 +6,6 @@
  *
  * Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 3045067448fb985f5a8400b97d23287902bc25de..c2af3395cf132e96b0d12727947c5e2fe861db48 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell MVEBU CPU clock handling.
  *
@@ -5,9 +6,6 @@
  *
  * Gregory CLEMENT <gregory.clement@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 #include <linux/kernel.h>
 #include <linux/slab.h>
index 472c88b90256945e1d70b7c5574a6b38a237c432..6ab3c2e627c715fa99a219b19c178e264bd1f8e7 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell EBU SoC common clock handling
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index f0de6c8a494a3ca65e18d340c3918e0b4396a43c..d1ab79b43105c007db9ff1aedf78cd312b9552dd 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Marvell EBU SoC common clock handling
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * 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 __CLK_MVEBU_COMMON_H_
index 75bf7b8f282fc4e4cc0e342e16d5594b7cba1274..9781b1bf599884d6ae37b06dea03453dc8caac35 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Armada CP110 System Controller
  *
@@ -5,9 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 /*
index 59fad9546c847946d71bd8348dcff615f936e0e4..e0dd99f36bf43dcdd8788e4e97c474a944daaa0b 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Dove SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index a2a8d614039da91a1b3f99272aa98e5952b79037..6f784167bda4a84c902b4f835070aa55cdd88b17 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Kirkwood SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 6e203af73cac1dff2fd409c7700a02376186085a..0a74cf7a7725a01bcd647752c7d14656bc1c79ad 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell MV98DX3236 SoC clocks
  *
@@ -7,9 +8,6 @@
  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
  * Andrew Lunn <andrew@lunn.ch>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index a6e5bee233855fcdc230480027ab071bec2f1275..f681a65be20a8651d4e94703d62e1134f6788be5 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Marvell Orion SoC clocks
  *
@@ -5,9 +6,6 @@
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
index 064768699fe734f6c142499f29ad2875151507dc..a611531df115e42ffd4840023c5ee6d5c2899d17 100644 (file)
@@ -1,3 +1,7 @@
+config KRAIT_CLOCKS
+       bool
+       select KRAIT_L2_ACCESSORS
+
 config QCOM_GDSC
        bool
        select PM_GENERIC_DOMAINS if PM
@@ -235,6 +239,31 @@ config MSM_GCC_8998
          Say Y if you want to use peripheral devices such as UART, SPI,
          i2c, USB, UFS, SD/eMMC, PCIe, etc.
 
+config QCS_GCC_404
+       tristate "QCS404 Global Clock Controller"
+       depends on COMMON_CLK_QCOM
+       help
+         Support for the global clock controller on QCS404 devices.
+         Say Y if you want to use multimedia devices or peripheral
+         devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
+
+config SDM_CAMCC_845
+       tristate "SDM845 Camera Clock Controller"
+       depends on COMMON_CLK_QCOM
+       select SDM_GCC_845
+       help
+         Support for the camera clock controller on SDM845 devices.
+         Say Y if you want to support camera devices and camera functionality.
+
+config SDM_GCC_660
+       tristate "SDM660 Global Clock Controller"
+       select QCOM_GDSC
+       depends on COMMON_CLK_QCOM
+       help
+         Support for the global clock controller on SDM660 devices.
+         Say Y if you want to use peripheral devices such as UART, SPI,
+         i2C, USB, UFS, SDDC, PCIe, etc.
+
 config SDM_GCC_845
        tristate "SDM845 Global Clock Controller"
        select QCOM_GDSC
@@ -272,3 +301,27 @@ config SPMI_PMIC_CLKDIV
          Technologies, Inc. SPMI PMIC. It configures the frequency of
          clkdiv outputs of the PMIC. These clocks are typically wired
          through alternate functions on GPIO pins.
+
+config QCOM_HFPLL
+       tristate "High-Frequency PLL (HFPLL) Clock Controller"
+       depends on COMMON_CLK_QCOM
+       help
+         Support for the high-frequency PLLs present on Qualcomm devices.
+         Say Y if you want to support CPU frequency scaling on devices
+         such as MSM8974, APQ8084, etc.
+
+config KPSS_XCC
+       tristate "KPSS Clock Controller"
+       depends on COMMON_CLK_QCOM
+       help
+         Support for the Krait ACC and GCC clock controllers. Say Y
+         if you want to support CPU frequency scaling on devices such
+         as MSM8960, APQ8064, etc.
+
+config KRAITCC
+       tristate "Krait Clock Controller"
+       depends on COMMON_CLK_QCOM && ARM
+       select KRAIT_CLOCKS
+       help
+         Support for the Krait CPU clocks on Qualcomm devices.
+         Say Y if you want to support CPU frequency scaling.
index 21a45035930d04531d39f0ece1ea9df490e2a3a2..981882e16189ae61334b98806ae4e40b32a6e7ba 100644 (file)
@@ -11,6 +11,8 @@ clk-qcom-y += clk-branch.o
 clk-qcom-y += clk-regmap-divider.o
 clk-qcom-y += clk-regmap-mux.o
 clk-qcom-y += clk-regmap-mux-div.o
+clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
+clk-qcom-y += clk-hfpll.o
 clk-qcom-y += reset.o
 clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 
@@ -39,7 +41,13 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
 obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
+obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
+obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
 obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
+obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
+obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
+obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
+obj-$(CONFIG_KRAITCC) += krait-cc.o
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
new file mode 100644 (file)
index 0000000..1b2cefe
--- /dev/null
@@ -0,0 +1,1745 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "gdsc.h"
+
+enum {
+       P_BI_TCXO,
+       P_CAM_CC_PLL0_OUT_EVEN,
+       P_CAM_CC_PLL1_OUT_EVEN,
+       P_CAM_CC_PLL2_OUT_EVEN,
+       P_CAM_CC_PLL3_OUT_EVEN,
+       P_CORE_BI_PLL_TEST_SE,
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_CAM_CC_PLL2_OUT_EVEN, 1 },
+       { P_CAM_CC_PLL1_OUT_EVEN, 2 },
+       { P_CAM_CC_PLL3_OUT_EVEN, 5 },
+       { P_CAM_CC_PLL0_OUT_EVEN, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const cam_cc_parent_names_0[] = {
+       "bi_tcxo",
+       "cam_cc_pll2_out_even",
+       "cam_cc_pll1_out_even",
+       "cam_cc_pll3_out_even",
+       "cam_cc_pll0_out_even",
+       "core_bi_pll_test_se",
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_pll0",
+                       .parent_names = (const char *[]){ "bi_tcxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+       { 0x0, 1 },
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_pll0_out_even",
+               .parent_names = (const char *[]){ "cam_cc_pll0" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+       .offset = 0x1000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_pll1",
+                       .parent_names = (const char *[]){ "bi_tcxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+       .offset = 0x1000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_pll1_out_even",
+               .parent_names = (const char *[]){ "cam_cc_pll1" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll cam_cc_pll2 = {
+       .offset = 0x2000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_pll2",
+                       .parent_names = (const char *[]){ "bi_tcxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = {
+       .offset = 0x2000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_pll2_out_even",
+               .parent_names = (const char *[]){ "cam_cc_pll2" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll cam_cc_pll3 = {
+       .offset = 0x3000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_pll3",
+                       .parent_names = (const char *[]){ "bi_tcxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = {
+       .offset = 0x3000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_pll3_out_even",
+               .parent_names = (const char *[]){ "cam_cc_pll3" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+       F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0),
+       F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0),
+       F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0),
+       F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+/*
+ * As per HW design, some of the CAMCC RCGs needs to
+ * move to XO clock during their clock disable so using
+ * clk_rcg2_shared_ops for such RCGs. This is required
+ * to power down the camera memories gracefully.
+ * Also, use CLK_SET_RATE_PARENT flag for the RCGs which
+ * have CAM_CC_PLL2_OUT_EVEN PLL as parent in frequency
+ * table and requires reconfiguration of the PLL frequency.
+ */
+static struct clk_rcg2 cam_cc_bps_clk_src = {
+       .cmd_rcgr = 0x600c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_bps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_bps_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_cci_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0),
+       F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0),
+       F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_cci_clk_src = {
+       .cmd_rcgr = 0xb0d8,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_cci_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_cci_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_cphy_rx_clk_src = {
+       .cmd_rcgr = 0x9060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_cphy_rx_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(240000000, P_CAM_CC_PLL2_OUT_EVEN, 2, 0, 0),
+       F(269333333, P_CAM_CC_PLL1_OUT_EVEN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x5004,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_csi0phytimer_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x5028,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_csi1phytimer_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = {
+       .cmd_rcgr = 0x504c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_csi2phytimer_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = {
+       .cmd_rcgr = 0x5070,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_csi3phytimer_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0),
+       F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+       F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0),
+       F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0),
+       F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_fast_ahb_clk_src = {
+       .cmd_rcgr = 0x6038,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_fast_ahb_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_fd_core_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+       F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0),
+       F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0),
+       F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_fd_core_clk_src = {
+       .cmd_rcgr = 0xb0b0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_fd_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_fd_core_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+       F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0),
+       F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0),
+       F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_icp_clk_src = {
+       .cmd_rcgr = 0xb088,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_icp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_icp_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+       F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0),
+       F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0),
+       F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0),
+       F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_ife_0_clk_src = {
+       .cmd_rcgr = 0x900c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ife_0_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0),
+       F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+       F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = {
+       .cmd_rcgr = 0x9038,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ife_0_csid_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_ife_1_clk_src = {
+       .cmd_rcgr = 0xa00c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ife_1_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = {
+       .cmd_rcgr = 0xa030,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ife_1_csid_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_clk_src = {
+       .cmd_rcgr = 0xb004,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ife_lite_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = {
+       .cmd_rcgr = 0xb024,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ife_lite_csid_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_ipe_0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+       F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0),
+       F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0),
+       F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0),
+       F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0),
+       F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_ipe_0_clk_src = {
+       .cmd_rcgr = 0x700c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ipe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ipe_0_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_ipe_1_clk_src = {
+       .cmd_rcgr = 0x800c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_ipe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_ipe_1_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_jpeg_clk_src = {
+       .cmd_rcgr = 0xb04c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_bps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_jpeg_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_lrme_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+       F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0),
+       F(269333333, P_CAM_CC_PLL1_OUT_EVEN, 3, 0, 0),
+       F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0),
+       F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_lrme_clk_src = {
+       .cmd_rcgr = 0xb0f8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_lrme_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_lrme_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(24000000, P_CAM_CC_PLL2_OUT_EVEN, 10, 1, 2),
+       F(33333333, P_CAM_CC_PLL0_OUT_EVEN, 2, 1, 9),
+       F(34285714, P_CAM_CC_PLL2_OUT_EVEN, 14, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_mclk0_clk_src = {
+       .cmd_rcgr = 0x4004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_mclk0_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_mclk1_clk_src = {
+       .cmd_rcgr = 0x4024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_mclk1_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_mclk2_clk_src = {
+       .cmd_rcgr = 0x4044,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_mclk2_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 cam_cc_mclk3_clk_src = {
+       .cmd_rcgr = 0x4064,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_mclk3_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(60000000, P_CAM_CC_PLL0_OUT_EVEN, 10, 0, 0),
+       F(66666667, P_CAM_CC_PLL0_OUT_EVEN, 9, 0, 0),
+       F(73846154, P_CAM_CC_PLL2_OUT_EVEN, 6.5, 0, 0),
+       F(80000000, P_CAM_CC_PLL2_OUT_EVEN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cam_cc_slow_ahb_clk_src = {
+       .cmd_rcgr = 0x6054,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = cam_cc_parent_map_0,
+       .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cam_cc_slow_ahb_clk_src",
+               .parent_names = cam_cc_parent_names_0,
+               .num_parents = 6,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch cam_cc_bps_ahb_clk = {
+       .halt_reg = 0x606c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x606c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_bps_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_slow_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_bps_areg_clk = {
+       .halt_reg = 0x6050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_bps_areg_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_fast_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_bps_axi_clk = {
+       .halt_reg = 0x6034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_bps_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_bps_clk = {
+       .halt_reg = 0x6024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_bps_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_bps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_camnoc_atb_clk = {
+       .halt_reg = 0xb12c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb12c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_camnoc_atb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_camnoc_axi_clk = {
+       .halt_reg = 0xb124,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb124,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_camnoc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_cci_clk = {
+       .halt_reg = 0xb0f0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb0f0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_cci_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cci_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_cpas_ahb_clk = {
+       .halt_reg = 0xb11c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb11c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_cpas_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_slow_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csi0phytimer_clk = {
+       .halt_reg = 0x501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csi0phytimer_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_csi0phytimer_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csi1phytimer_clk = {
+       .halt_reg = 0x5040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csi1phytimer_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_csi1phytimer_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csi2phytimer_clk = {
+       .halt_reg = 0x5064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csi2phytimer_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_csi2phytimer_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csi3phytimer_clk = {
+       .halt_reg = 0x5088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csi3phytimer_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_csi3phytimer_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csiphy0_clk = {
+       .halt_reg = 0x5020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csiphy0_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csiphy1_clk = {
+       .halt_reg = 0x5044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csiphy1_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csiphy2_clk = {
+       .halt_reg = 0x5068,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csiphy2_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_csiphy3_clk = {
+       .halt_reg = 0x508c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x508c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_csiphy3_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_fd_core_clk = {
+       .halt_reg = 0xb0c8,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb0c8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_fd_core_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_fd_core_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_fd_core_uar_clk = {
+       .halt_reg = 0xb0d0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb0d0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_fd_core_uar_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_fd_core_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_icp_apb_clk = {
+       .halt_reg = 0xb084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_icp_apb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_icp_atb_clk = {
+       .halt_reg = 0xb078,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_icp_atb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_icp_clk = {
+       .halt_reg = 0xb0a0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb0a0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_icp_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_icp_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_icp_cti_clk = {
+       .halt_reg = 0xb07c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_icp_cti_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_icp_ts_clk = {
+       .halt_reg = 0xb080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_icp_ts_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_0_axi_clk = {
+       .halt_reg = 0x907c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x907c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_0_clk = {
+       .halt_reg = 0x9024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_0_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_0_cphy_rx_clk = {
+       .halt_reg = 0x9078,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_0_cphy_rx_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_0_csid_clk = {
+       .halt_reg = 0x9050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_0_csid_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_0_csid_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_0_dsp_clk = {
+       .halt_reg = 0x9034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_0_dsp_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_1_axi_clk = {
+       .halt_reg = 0xa054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_1_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_1_clk = {
+       .halt_reg = 0xa024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_1_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_1_cphy_rx_clk = {
+       .halt_reg = 0xa050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_1_cphy_rx_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_1_csid_clk = {
+       .halt_reg = 0xa048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_1_csid_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_1_csid_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_1_dsp_clk = {
+       .halt_reg = 0xa02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_1_dsp_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_lite_clk = {
+       .halt_reg = 0xb01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_lite_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_lite_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = {
+       .halt_reg = 0xb044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_lite_cphy_rx_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_cphy_rx_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ife_lite_csid_clk = {
+       .halt_reg = 0xb03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ife_lite_csid_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ife_lite_csid_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_0_ahb_clk = {
+       .halt_reg = 0x703c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x703c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_0_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_slow_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_0_areg_clk = {
+       .halt_reg = 0x7038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x7038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_0_areg_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_fast_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_0_axi_clk = {
+       .halt_reg = 0x7034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x7034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_0_clk = {
+       .halt_reg = 0x7024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x7024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_0_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ipe_0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_1_ahb_clk = {
+       .halt_reg = 0x803c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x803c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_1_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_slow_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_1_areg_clk = {
+       .halt_reg = 0x8038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_1_areg_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_fast_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_1_axi_clk = {
+       .halt_reg = 0x8034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_1_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_ipe_1_clk = {
+       .halt_reg = 0x8024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_ipe_1_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_ipe_1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_jpeg_clk = {
+       .halt_reg = 0xb064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_jpeg_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_jpeg_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_lrme_clk = {
+       .halt_reg = 0xb110,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb110,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_lrme_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_lrme_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_mclk0_clk = {
+       .halt_reg = 0x401c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x401c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_mclk0_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_mclk0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_mclk1_clk = {
+       .halt_reg = 0x403c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x403c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_mclk1_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_mclk1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_mclk2_clk = {
+       .halt_reg = 0x405c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x405c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_mclk2_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_mclk2_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_mclk3_clk = {
+       .halt_reg = 0x407c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x407c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_mclk3_clk",
+                       .parent_names = (const char *[]){
+                               "cam_cc_mclk3_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_soc_ahb_clk = {
+       .halt_reg = 0xb13c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb13c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_soc_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch cam_cc_sys_tmr_clk = {
+       .halt_reg = 0xb0a8,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xb0a8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "cam_cc_sys_tmr_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc bps_gdsc = {
+       .gdscr = 0x6004,
+       .pd = {
+               .name = "bps_gdsc",
+       },
+       .flags = HW_CTRL | POLL_CFG_GDSCR,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ipe_0_gdsc = {
+       .gdscr = 0x7004,
+       .pd = {
+               .name = "ipe_0_gdsc",
+       },
+       .flags = HW_CTRL | POLL_CFG_GDSCR,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ipe_1_gdsc = {
+       .gdscr = 0x8004,
+       .pd = {
+               .name = "ipe_1_gdsc",
+       },
+       .flags = HW_CTRL | POLL_CFG_GDSCR,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ife_0_gdsc = {
+       .gdscr = 0x9004,
+       .pd = {
+               .name = "ife_0_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ife_1_gdsc = {
+       .gdscr = 0xa004,
+       .pd = {
+               .name = "ife_1_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc titan_top_gdsc = {
+       .gdscr = 0xb134,
+       .pd = {
+               .name = "titan_top_gdsc",
+       },
+       .flags = POLL_CFG_GDSCR,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *cam_cc_sdm845_clocks[] = {
+       [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr,
+       [CAM_CC_BPS_AREG_CLK] = &cam_cc_bps_areg_clk.clkr,
+       [CAM_CC_BPS_AXI_CLK] = &cam_cc_bps_axi_clk.clkr,
+       [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr,
+       [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr,
+       [CAM_CC_CAMNOC_ATB_CLK] = &cam_cc_camnoc_atb_clk.clkr,
+       [CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr,
+       [CAM_CC_CCI_CLK] = &cam_cc_cci_clk.clkr,
+       [CAM_CC_CCI_CLK_SRC] = &cam_cc_cci_clk_src.clkr,
+       [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr,
+       [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr,
+       [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr,
+       [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr,
+       [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr,
+       [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr,
+       [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr,
+       [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr,
+       [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr,
+       [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr,
+       [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr,
+       [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr,
+       [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr,
+       [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr,
+       [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr,
+       [CAM_CC_FD_CORE_CLK] = &cam_cc_fd_core_clk.clkr,
+       [CAM_CC_FD_CORE_CLK_SRC] = &cam_cc_fd_core_clk_src.clkr,
+       [CAM_CC_FD_CORE_UAR_CLK] = &cam_cc_fd_core_uar_clk.clkr,
+       [CAM_CC_ICP_APB_CLK] = &cam_cc_icp_apb_clk.clkr,
+       [CAM_CC_ICP_ATB_CLK] = &cam_cc_icp_atb_clk.clkr,
+       [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr,
+       [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr,
+       [CAM_CC_ICP_CTI_CLK] = &cam_cc_icp_cti_clk.clkr,
+       [CAM_CC_ICP_TS_CLK] = &cam_cc_icp_ts_clk.clkr,
+       [CAM_CC_IFE_0_AXI_CLK] = &cam_cc_ife_0_axi_clk.clkr,
+       [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr,
+       [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr,
+       [CAM_CC_IFE_0_CPHY_RX_CLK] = &cam_cc_ife_0_cphy_rx_clk.clkr,
+       [CAM_CC_IFE_0_CSID_CLK] = &cam_cc_ife_0_csid_clk.clkr,
+       [CAM_CC_IFE_0_CSID_CLK_SRC] = &cam_cc_ife_0_csid_clk_src.clkr,
+       [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr,
+       [CAM_CC_IFE_1_AXI_CLK] = &cam_cc_ife_1_axi_clk.clkr,
+       [CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr,
+       [CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr,
+       [CAM_CC_IFE_1_CPHY_RX_CLK] = &cam_cc_ife_1_cphy_rx_clk.clkr,
+       [CAM_CC_IFE_1_CSID_CLK] = &cam_cc_ife_1_csid_clk.clkr,
+       [CAM_CC_IFE_1_CSID_CLK_SRC] = &cam_cc_ife_1_csid_clk_src.clkr,
+       [CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr,
+       [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr,
+       [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr,
+       [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr,
+       [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr,
+       [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr,
+       [CAM_CC_IPE_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr,
+       [CAM_CC_IPE_0_AREG_CLK] = &cam_cc_ipe_0_areg_clk.clkr,
+       [CAM_CC_IPE_0_AXI_CLK] = &cam_cc_ipe_0_axi_clk.clkr,
+       [CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr,
+       [CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr,
+       [CAM_CC_IPE_1_AHB_CLK] = &cam_cc_ipe_1_ahb_clk.clkr,
+       [CAM_CC_IPE_1_AREG_CLK] = &cam_cc_ipe_1_areg_clk.clkr,
+       [CAM_CC_IPE_1_AXI_CLK] = &cam_cc_ipe_1_axi_clk.clkr,
+       [CAM_CC_IPE_1_CLK] = &cam_cc_ipe_1_clk.clkr,
+       [CAM_CC_IPE_1_CLK_SRC] = &cam_cc_ipe_1_clk_src.clkr,
+       [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr,
+       [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr,
+       [CAM_CC_LRME_CLK] = &cam_cc_lrme_clk.clkr,
+       [CAM_CC_LRME_CLK_SRC] = &cam_cc_lrme_clk_src.clkr,
+       [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr,
+       [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr,
+       [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr,
+       [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr,
+       [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr,
+       [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr,
+       [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr,
+       [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr,
+       [CAM_CC_PLL0] = &cam_cc_pll0.clkr,
+       [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr,
+       [CAM_CC_PLL1] = &cam_cc_pll1.clkr,
+       [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr,
+       [CAM_CC_PLL2] = &cam_cc_pll2.clkr,
+       [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr,
+       [CAM_CC_PLL3] = &cam_cc_pll3.clkr,
+       [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr,
+       [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr,
+       [CAM_CC_SOC_AHB_CLK] = &cam_cc_soc_ahb_clk.clkr,
+       [CAM_CC_SYS_TMR_CLK] = &cam_cc_sys_tmr_clk.clkr,
+};
+
+static struct gdsc *cam_cc_sdm845_gdscs[] = {
+       [BPS_GDSC] = &bps_gdsc,
+       [IPE_0_GDSC] = &ipe_0_gdsc,
+       [IPE_1_GDSC] = &ipe_1_gdsc,
+       [IFE_0_GDSC] = &ife_0_gdsc,
+       [IFE_1_GDSC] = &ife_1_gdsc,
+       [TITAN_TOP_GDSC] = &titan_top_gdsc,
+};
+
+static const struct regmap_config cam_cc_sdm845_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0xd004,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc cam_cc_sdm845_desc = {
+       .config = &cam_cc_sdm845_regmap_config,
+       .clks = cam_cc_sdm845_clocks,
+       .num_clks = ARRAY_SIZE(cam_cc_sdm845_clocks),
+       .gdscs = cam_cc_sdm845_gdscs,
+       .num_gdscs = ARRAY_SIZE(cam_cc_sdm845_gdscs),
+};
+
+static const struct of_device_id cam_cc_sdm845_match_table[] = {
+       { .compatible = "qcom,sdm845-camcc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, cam_cc_sdm845_match_table);
+
+static int cam_cc_sdm845_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       struct alpha_pll_config cam_cc_pll_config = { };
+
+       regmap = qcom_cc_map(pdev, &cam_cc_sdm845_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       cam_cc_pll_config.l = 0x1f;
+       cam_cc_pll_config.alpha = 0x4000;
+       clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll_config);
+
+       cam_cc_pll_config.l = 0x2a;
+       cam_cc_pll_config.alpha = 0x1556;
+       clk_fabia_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll_config);
+
+       cam_cc_pll_config.l = 0x32;
+       cam_cc_pll_config.alpha = 0x0;
+       clk_fabia_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll_config);
+
+       cam_cc_pll_config.l = 0x14;
+       clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll_config);
+
+       return qcom_cc_really_probe(pdev, &cam_cc_sdm845_desc, regmap);
+}
+
+static struct platform_driver cam_cc_sdm845_driver = {
+       .probe  = cam_cc_sdm845_probe,
+       .driver = {
+               .name = "sdm845-camcc",
+               .of_match_table = cam_cc_sdm845_match_table,
+       },
+};
+
+static int __init cam_cc_sdm845_init(void)
+{
+       return platform_driver_register(&cam_cc_sdm845_driver);
+}
+subsys_initcall(cam_cc_sdm845_init);
+
+static void __exit cam_cc_sdm845_exit(void)
+{
+       platform_driver_unregister(&cam_cc_sdm845_driver);
+}
+module_exit(cam_cc_sdm845_exit);
+
+MODULE_DESCRIPTION("QTI CAM_CC SDM845 Driver");
+MODULE_LICENSE("GPL v2");
index a91d97cecbad0b554ebbdfd70df628c236dfd91c..0ced4a5a9a171e9025fc9696833fca1f9f3db82d 100644 (file)
@@ -220,6 +220,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
        if (pll->flags & SUPPORTS_FSM_MODE)
                qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
+EXPORT_SYMBOL_GPL(clk_alpha_pll_configure);
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
index bc2205c450b641c35194fc8d1b4b12b19ee072fc..99446bf630aaad4282669c25c73cf85fcd4f549a 100644 (file)
@@ -18,7 +18,7 @@ static bool clk_branch_in_hwcg_mode(const struct clk_branch *br)
        u32 val;
 
        if (!br->hwcg_reg)
-               return 0;
+               return false;
 
        regmap_read(br->clkr.regmap, br->hwcg_reg, &val);
 
diff --git a/drivers/clk/qcom/clk-hfpll.c b/drivers/clk/qcom/clk-hfpll.c
new file mode 100644 (file)
index 0000000..3c04805
--- /dev/null
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+
+#include "clk-regmap.h"
+#include "clk-hfpll.h"
+
+#define PLL_OUTCTRL    BIT(0)
+#define PLL_BYPASSNL   BIT(1)
+#define PLL_RESET_N    BIT(2)
+
+/* Initialize a HFPLL at a given rate and enable it. */
+static void __clk_hfpll_init_once(struct clk_hw *hw)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+
+       if (likely(h->init_done))
+               return;
+
+       /* Configure PLL parameters for integer mode. */
+       if (hd->config_val)
+               regmap_write(regmap, hd->config_reg, hd->config_val);
+       regmap_write(regmap, hd->m_reg, 0);
+       regmap_write(regmap, hd->n_reg, 1);
+
+       if (hd->user_reg) {
+               u32 regval = hd->user_val;
+               unsigned long rate;
+
+               rate = clk_hw_get_rate(hw);
+
+               /* Pick the right VCO. */
+               if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
+                       regval |= hd->user_vco_mask;
+               regmap_write(regmap, hd->user_reg, regval);
+       }
+
+       if (hd->droop_reg)
+               regmap_write(regmap, hd->droop_reg, hd->droop_val);
+
+       h->init_done = true;
+}
+
+static void __clk_hfpll_enable(struct clk_hw *hw)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+       u32 val;
+
+       __clk_hfpll_init_once(hw);
+
+       /* Disable PLL bypass mode. */
+       regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL);
+
+       /*
+        * H/W requires a 5us delay between disabling the bypass and
+        * de-asserting the reset. Delay 10us just to be safe.
+        */
+       udelay(10);
+
+       /* De-assert active-low PLL reset. */
+       regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N);
+
+       /* Wait for PLL to lock. */
+       if (hd->status_reg) {
+               do {
+                       regmap_read(regmap, hd->status_reg, &val);
+               } while (!(val & BIT(hd->lock_bit)));
+       } else {
+               udelay(60);
+       }
+
+       /* Enable PLL output. */
+       regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL);
+}
+
+/* Enable an already-configured HFPLL. */
+static int clk_hfpll_enable(struct clk_hw *hw)
+{
+       unsigned long flags;
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+       u32 mode;
+
+       spin_lock_irqsave(&h->lock, flags);
+       regmap_read(regmap, hd->mode_reg, &mode);
+       if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)))
+               __clk_hfpll_enable(hw);
+       spin_unlock_irqrestore(&h->lock, flags);
+
+       return 0;
+}
+
+static void __clk_hfpll_disable(struct clk_hfpll *h)
+{
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+
+       /*
+        * Disable the PLL output, disable test mode, enable the bypass mode,
+        * and assert the reset.
+        */
+       regmap_update_bits(regmap, hd->mode_reg,
+                          PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
+}
+
+static void clk_hfpll_disable(struct clk_hw *hw)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(&h->lock, flags);
+       __clk_hfpll_disable(h);
+       spin_unlock_irqrestore(&h->lock, flags);
+}
+
+static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate,
+                                unsigned long *parent_rate)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       unsigned long rrate;
+
+       rate = clamp(rate, hd->min_rate, hd->max_rate);
+
+       rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate;
+       if (rrate > hd->max_rate)
+               rrate -= *parent_rate;
+
+       return rrate;
+}
+
+/*
+ * For optimization reasons, assumes no downstream clocks are actively using
+ * it.
+ */
+static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long parent_rate)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+       unsigned long flags;
+       u32 l_val, val;
+       bool enabled;
+
+       l_val = rate / parent_rate;
+
+       spin_lock_irqsave(&h->lock, flags);
+
+       enabled = __clk_is_enabled(hw->clk);
+       if (enabled)
+               __clk_hfpll_disable(h);
+
+       /* Pick the right VCO. */
+       if (hd->user_reg && hd->user_vco_mask) {
+               regmap_read(regmap, hd->user_reg, &val);
+               if (rate <= hd->low_vco_max_rate)
+                       val &= ~hd->user_vco_mask;
+               else
+                       val |= hd->user_vco_mask;
+               regmap_write(regmap, hd->user_reg, val);
+       }
+
+       regmap_write(regmap, hd->l_reg, l_val);
+
+       if (enabled)
+               __clk_hfpll_enable(hw);
+
+       spin_unlock_irqrestore(&h->lock, flags);
+
+       return 0;
+}
+
+static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
+                                          unsigned long parent_rate)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+       u32 l_val;
+
+       regmap_read(regmap, hd->l_reg, &l_val);
+
+       return l_val * parent_rate;
+}
+
+static void clk_hfpll_init(struct clk_hw *hw)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+       u32 mode, status;
+
+       regmap_read(regmap, hd->mode_reg, &mode);
+       if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
+               __clk_hfpll_init_once(hw);
+               return;
+       }
+
+       if (hd->status_reg) {
+               regmap_read(regmap, hd->status_reg, &status);
+               if (!(status & BIT(hd->lock_bit))) {
+                       WARN(1, "HFPLL %s is ON, but not locked!\n",
+                            __clk_get_name(hw->clk));
+                       clk_hfpll_disable(hw);
+                       __clk_hfpll_init_once(hw);
+               }
+       }
+}
+
+static int hfpll_is_enabled(struct clk_hw *hw)
+{
+       struct clk_hfpll *h = to_clk_hfpll(hw);
+       struct hfpll_data const *hd = h->d;
+       struct regmap *regmap = h->clkr.regmap;
+       u32 mode;
+
+       regmap_read(regmap, hd->mode_reg, &mode);
+       mode &= 0x7;
+       return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL);
+}
+
+const struct clk_ops clk_ops_hfpll = {
+       .enable = clk_hfpll_enable,
+       .disable = clk_hfpll_disable,
+       .is_enabled = hfpll_is_enabled,
+       .round_rate = clk_hfpll_round_rate,
+       .set_rate = clk_hfpll_set_rate,
+       .recalc_rate = clk_hfpll_recalc_rate,
+       .init = clk_hfpll_init,
+};
+EXPORT_SYMBOL_GPL(clk_ops_hfpll);
diff --git a/drivers/clk/qcom/clk-hfpll.h b/drivers/clk/qcom/clk-hfpll.h
new file mode 100644 (file)
index 0000000..2a57b2f
--- /dev/null
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __QCOM_CLK_HFPLL_H__
+#define __QCOM_CLK_HFPLL_H__
+
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include "clk-regmap.h"
+
+struct hfpll_data {
+       u32 mode_reg;
+       u32 l_reg;
+       u32 m_reg;
+       u32 n_reg;
+       u32 user_reg;
+       u32 droop_reg;
+       u32 config_reg;
+       u32 status_reg;
+       u8  lock_bit;
+
+       u32 droop_val;
+       u32 config_val;
+       u32 user_val;
+       u32 user_vco_mask;
+       unsigned long low_vco_max_rate;
+
+       unsigned long min_rate;
+       unsigned long max_rate;
+};
+
+struct clk_hfpll {
+       struct hfpll_data const *d;
+       int init_done;
+
+       struct clk_regmap clkr;
+       spinlock_t lock;
+};
+
+#define to_clk_hfpll(_hw) \
+       container_of(to_clk_regmap(_hw), struct clk_hfpll, clkr)
+
+extern const struct clk_ops clk_ops_hfpll;
+
+#endif
diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
new file mode 100644 (file)
index 0000000..59f1af4
--- /dev/null
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+
+#include <asm/krait-l2-accessors.h>
+
+#include "clk-krait.h"
+
+/* Secondary and primary muxes share the same cp15 register */
+static DEFINE_SPINLOCK(krait_clock_reg_lock);
+
+#define LPL_SHIFT      8
+static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
+{
+       unsigned long flags;
+       u32 regval;
+
+       spin_lock_irqsave(&krait_clock_reg_lock, flags);
+       regval = krait_get_l2_indirect_reg(mux->offset);
+       regval &= ~(mux->mask << mux->shift);
+       regval |= (sel & mux->mask) << mux->shift;
+       if (mux->lpl) {
+               regval &= ~(mux->mask << (mux->shift + LPL_SHIFT));
+               regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
+       }
+       krait_set_l2_indirect_reg(mux->offset, regval);
+       spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
+
+       /* Wait for switch to complete. */
+       mb();
+       udelay(1);
+}
+
+static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct krait_mux_clk *mux = to_krait_mux_clk(hw);
+       u32 sel;
+
+       sel = clk_mux_index_to_val(mux->parent_map, 0, index);
+       mux->en_mask = sel;
+       /* Don't touch mux if CPU is off as it won't work */
+       if (__clk_is_enabled(hw->clk))
+               __krait_mux_set_sel(mux, sel);
+
+       mux->reparent = true;
+
+       return 0;
+}
+
+static u8 krait_mux_get_parent(struct clk_hw *hw)
+{
+       struct krait_mux_clk *mux = to_krait_mux_clk(hw);
+       u32 sel;
+
+       sel = krait_get_l2_indirect_reg(mux->offset);
+       sel >>= mux->shift;
+       sel &= mux->mask;
+       mux->en_mask = sel;
+
+       return clk_mux_val_to_index(hw, mux->parent_map, 0, sel);
+}
+
+const struct clk_ops krait_mux_clk_ops = {
+       .set_parent = krait_mux_set_parent,
+       .get_parent = krait_mux_get_parent,
+       .determine_rate = __clk_mux_determine_rate_closest,
+};
+EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
+
+/* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */
+static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *parent_rate)
+{
+       *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2);
+       return DIV_ROUND_UP(*parent_rate, 2);
+}
+
+static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct krait_div2_clk *d = to_krait_div2_clk(hw);
+       unsigned long flags;
+       u32 val;
+       u32 mask = BIT(d->width) - 1;
+
+       if (d->lpl)
+               mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
+
+       spin_lock_irqsave(&krait_clock_reg_lock, flags);
+       val = krait_get_l2_indirect_reg(d->offset);
+       val &= ~mask;
+       krait_set_l2_indirect_reg(d->offset, val);
+       spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
+
+       return 0;
+}
+
+static unsigned long
+krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct krait_div2_clk *d = to_krait_div2_clk(hw);
+       u32 mask = BIT(d->width) - 1;
+       u32 div;
+
+       div = krait_get_l2_indirect_reg(d->offset);
+       div >>= d->shift;
+       div &= mask;
+       div = (div + 1) * 2;
+
+       return DIV_ROUND_UP(parent_rate, div);
+}
+
+const struct clk_ops krait_div2_clk_ops = {
+       .round_rate = krait_div2_round_rate,
+       .set_rate = krait_div2_set_rate,
+       .recalc_rate = krait_div2_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(krait_div2_clk_ops);
diff --git a/drivers/clk/qcom/clk-krait.h b/drivers/clk/qcom/clk-krait.h
new file mode 100644 (file)
index 0000000..9120bd2
--- /dev/null
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __QCOM_CLK_KRAIT_H
+#define __QCOM_CLK_KRAIT_H
+
+#include <linux/clk-provider.h>
+
+struct krait_mux_clk {
+       unsigned int    *parent_map;
+       u32             offset;
+       u32             mask;
+       u32             shift;
+       u32             en_mask;
+       bool            lpl;
+       u8              safe_sel;
+       u8              old_index;
+       bool            reparent;
+
+       struct clk_hw   hw;
+       struct notifier_block   clk_nb;
+};
+
+#define to_krait_mux_clk(_hw) container_of(_hw, struct krait_mux_clk, hw)
+
+extern const struct clk_ops krait_mux_clk_ops;
+
+struct krait_div2_clk {
+       u32             offset;
+       u8              width;
+       u32             shift;
+       bool            lpl;
+
+       struct clk_hw   hw;
+};
+
+#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw)
+
+extern const struct clk_ops krait_div2_clk_ops;
+
+#endif
index dbd5a9e8355416a9edabeb09d474f7e9005a85c4..e5eca8a1abe484a6c5abb30f72e51164b762eaae 100644 (file)
@@ -163,4 +163,15 @@ extern const struct clk_ops clk_pixel_ops;
 extern const struct clk_ops clk_gfx3d_ops;
 extern const struct clk_ops clk_rcg2_shared_ops;
 
+struct clk_rcg_dfs_data {
+       struct clk_rcg2 *rcg;
+       struct clk_init_data *init;
+};
+
+#define DEFINE_RCG_DFS(r) \
+       { .rcg = &r##_src, .init = &r##_init }
+
+extern int qcom_cc_register_rcg_dfs(struct regmap *regmap,
+                                   const struct clk_rcg_dfs_data *rcgs,
+                                   size_t len);
 #endif
index 52208d4165f432ac7398e423139af52f84722844..6e3bd195d012fc17565a17d03b3d7770252d7075 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/regmap.h>
 #include <linux/math64.h>
+#include <linux/slab.h>
 
 #include <asm/div64.h>
 
 #define N_REG                  0xc
 #define D_REG                  0x10
 
+/* Dynamic Frequency Scaling */
+#define MAX_PERF_LEVEL         8
+#define SE_CMD_DFSR_OFFSET     0x14
+#define SE_CMD_DFS_EN          BIT(0)
+#define SE_PERF_DFSR(level)    (0x1c + 0x4 * (level))
+#define SE_PERF_M_DFSR(level)  (0x5c + 0x4 * (level))
+#define SE_PERF_N_DFSR(level)  (0x9c + 0x4 * (level))
+
 enum freq_policy {
        FLOOR,
        CEIL,
@@ -929,3 +938,189 @@ const struct clk_ops clk_rcg2_shared_ops = {
        .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
+
+/* Common APIs to be used for DFS based RCGR */
+static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l,
+                                      struct freq_tbl *f)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       struct clk_hw *p;
+       unsigned long prate = 0;
+       u32 val, mask, cfg, mode;
+       int i, num_parents;
+
+       regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg);
+
+       mask = BIT(rcg->hid_width) - 1;
+       f->pre_div = 1;
+       if (cfg & mask)
+               f->pre_div = cfg & mask;
+
+       cfg &= CFG_SRC_SEL_MASK;
+       cfg >>= CFG_SRC_SEL_SHIFT;
+
+       num_parents = clk_hw_get_num_parents(hw);
+       for (i = 0; i < num_parents; i++) {
+               if (cfg == rcg->parent_map[i].cfg) {
+                       f->src = rcg->parent_map[i].src;
+                       p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
+                       prate = clk_hw_get_rate(p);
+               }
+       }
+
+       mode = cfg & CFG_MODE_MASK;
+       mode >>= CFG_MODE_SHIFT;
+       if (mode) {
+               mask = BIT(rcg->mnd_width) - 1;
+               regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_M_DFSR(l),
+                           &val);
+               val &= mask;
+               f->m = val;
+
+               regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_N_DFSR(l),
+                           &val);
+               val = ~val;
+               val &= mask;
+               val += f->m;
+               f->n = val;
+       }
+
+       f->freq = calc_rate(prate, f->m, f->n, mode, f->pre_div);
+}
+
+static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg)
+{
+       struct freq_tbl *freq_tbl;
+       int i;
+
+       /* Allocate space for 1 extra since table is NULL terminated */
+       freq_tbl = kcalloc(MAX_PERF_LEVEL + 1, sizeof(*freq_tbl), GFP_KERNEL);
+       if (!freq_tbl)
+               return -ENOMEM;
+       rcg->freq_tbl = freq_tbl;
+
+       for (i = 0; i < MAX_PERF_LEVEL; i++)
+               clk_rcg2_dfs_populate_freq(&rcg->clkr.hw, i, freq_tbl + i);
+
+       return 0;
+}
+
+static int clk_rcg2_dfs_determine_rate(struct clk_hw *hw,
+                                  struct clk_rate_request *req)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       int ret;
+
+       if (!rcg->freq_tbl) {
+               ret = clk_rcg2_dfs_populate_freq_table(rcg);
+               if (ret) {
+                       pr_err("Failed to update DFS tables for %s\n",
+                                       clk_hw_get_name(hw));
+                       return ret;
+               }
+       }
+
+       return clk_rcg2_determine_rate(hw, req);
+}
+
+static unsigned long
+clk_rcg2_dfs_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       u32 level, mask, cfg, m = 0, n = 0, mode, pre_div;
+
+       regmap_read(rcg->clkr.regmap,
+                   rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &level);
+       level &= GENMASK(4, 1);
+       level >>= 1;
+
+       if (rcg->freq_tbl)
+               return rcg->freq_tbl[level].freq;
+
+       /*
+        * Assume that parent_rate is actually the parent because
+        * we can't do any better at figuring it out when the table
+        * hasn't been populated yet. We only populate the table
+        * in determine_rate because we can't guarantee the parents
+        * will be registered with the framework until then.
+        */
+       regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(level),
+                   &cfg);
+
+       mask = BIT(rcg->hid_width) - 1;
+       pre_div = 1;
+       if (cfg & mask)
+               pre_div = cfg & mask;
+
+       mode = cfg & CFG_MODE_MASK;
+       mode >>= CFG_MODE_SHIFT;
+       if (mode) {
+               mask = BIT(rcg->mnd_width) - 1;
+               regmap_read(rcg->clkr.regmap,
+                           rcg->cmd_rcgr + SE_PERF_M_DFSR(level), &m);
+               m &= mask;
+
+               regmap_read(rcg->clkr.regmap,
+                           rcg->cmd_rcgr + SE_PERF_N_DFSR(level), &n);
+               n = ~n;
+               n &= mask;
+               n += m;
+       }
+
+       return calc_rate(parent_rate, m, n, mode, pre_div);
+}
+
+static const struct clk_ops clk_rcg2_dfs_ops = {
+       .is_enabled = clk_rcg2_is_enabled,
+       .get_parent = clk_rcg2_get_parent,
+       .determine_rate = clk_rcg2_dfs_determine_rate,
+       .recalc_rate = clk_rcg2_dfs_recalc_rate,
+};
+
+static int clk_rcg2_enable_dfs(const struct clk_rcg_dfs_data *data,
+                              struct regmap *regmap)
+{
+       struct clk_rcg2 *rcg = data->rcg;
+       struct clk_init_data *init = data->init;
+       u32 val;
+       int ret;
+
+       ret = regmap_read(regmap, rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &val);
+       if (ret)
+               return -EINVAL;
+
+       if (!(val & SE_CMD_DFS_EN))
+               return 0;
+
+       /*
+        * Rate changes with consumer writing a register in
+        * their own I/O region
+        */
+       init->flags |= CLK_GET_RATE_NOCACHE;
+       init->ops = &clk_rcg2_dfs_ops;
+
+       rcg->freq_tbl = NULL;
+
+       pr_debug("DFS registered for clk %s\n", init->name);
+
+       return 0;
+}
+
+int qcom_cc_register_rcg_dfs(struct regmap *regmap,
+                            const struct clk_rcg_dfs_data *rcgs, size_t len)
+{
+       int i, ret;
+
+       for (i = 0; i < len; i++) {
+               ret = clk_rcg2_enable_dfs(&rcgs[i], regmap);
+               if (ret) {
+                       const char *name = rcgs[i].init->name;
+
+                       pr_err("DFS register failed for clk %s\n", name);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs);
index 5f61225657abbe879781ecf09d6cdbe67bb0ed58..33d1bc5c6a4654bae03399718a525a270acd74ba 100644 (file)
@@ -30,6 +30,7 @@
 #include "clk-pll.h"
 #include "clk-rcg.h"
 #include "clk-branch.h"
+#include "clk-hfpll.h"
 #include "reset.h"
 
 static struct clk_pll pll0 = {
@@ -113,6 +114,84 @@ static struct clk_regmap pll8_vote = {
        },
 };
 
+static struct hfpll_data hfpll0_data = {
+       .mode_reg = 0x3200,
+       .l_reg = 0x3208,
+       .m_reg = 0x320c,
+       .n_reg = 0x3210,
+       .config_reg = 0x3204,
+       .status_reg = 0x321c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3214,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll0 = {
+       .d = &hfpll0_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll0",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
+};
+
+static struct hfpll_data hfpll1_data = {
+       .mode_reg = 0x3240,
+       .l_reg = 0x3248,
+       .m_reg = 0x324c,
+       .n_reg = 0x3250,
+       .config_reg = 0x3244,
+       .status_reg = 0x325c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3314,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll1 = {
+       .d = &hfpll1_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll1",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
+};
+
+static struct hfpll_data hfpll_l2_data = {
+       .mode_reg = 0x3300,
+       .l_reg = 0x3308,
+       .m_reg = 0x330c,
+       .n_reg = 0x3310,
+       .config_reg = 0x3304,
+       .status_reg = 0x331c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3314,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll_l2 = {
+       .d = &hfpll_l2_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll_l2",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
+};
+
 static struct clk_pll pll14 = {
        .l_reg = 0x31c4,
        .m_reg = 0x31c8,
@@ -2797,6 +2876,9 @@ static struct clk_regmap *gcc_ipq806x_clks[] = {
        [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
        [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
        [NSSTCM_CLK] = &nss_tcm_clk.clkr,
+       [PLL9] = &hfpll0.clkr,
+       [PLL10] = &hfpll1.clkr,
+       [PLL12] = &hfpll_l2.clkr,
 };
 
 static const struct qcom_reset_map gcc_ipq806x_resets[] = {
index fd495e0471bb4d9825ba453c235b4e40fb0d6bca..399474755654f3c0809f0d4d8878d007e104a90c 100644 (file)
@@ -30,6 +30,7 @@
 #include "clk-pll.h"
 #include "clk-rcg.h"
 #include "clk-branch.h"
+#include "clk-hfpll.h"
 #include "reset.h"
 
 static struct clk_pll pll3 = {
@@ -86,6 +87,164 @@ static struct clk_regmap pll8_vote = {
        },
 };
 
+static struct hfpll_data hfpll0_data = {
+       .mode_reg = 0x3200,
+       .l_reg = 0x3208,
+       .m_reg = 0x320c,
+       .n_reg = 0x3210,
+       .config_reg = 0x3204,
+       .status_reg = 0x321c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3214,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll0 = {
+       .d = &hfpll0_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll0",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
+};
+
+static struct hfpll_data hfpll1_8064_data = {
+       .mode_reg = 0x3240,
+       .l_reg = 0x3248,
+       .m_reg = 0x324c,
+       .n_reg = 0x3250,
+       .config_reg = 0x3244,
+       .status_reg = 0x325c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3254,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct hfpll_data hfpll1_data = {
+       .mode_reg = 0x3300,
+       .l_reg = 0x3308,
+       .m_reg = 0x330c,
+       .n_reg = 0x3310,
+       .config_reg = 0x3304,
+       .status_reg = 0x331c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3314,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll1 = {
+       .d = &hfpll1_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll1",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
+};
+
+static struct hfpll_data hfpll2_data = {
+       .mode_reg = 0x3280,
+       .l_reg = 0x3288,
+       .m_reg = 0x328c,
+       .n_reg = 0x3290,
+       .config_reg = 0x3284,
+       .status_reg = 0x329c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3294,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll2 = {
+       .d = &hfpll2_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll2",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll2.lock),
+};
+
+static struct hfpll_data hfpll3_data = {
+       .mode_reg = 0x32c0,
+       .l_reg = 0x32c8,
+       .m_reg = 0x32cc,
+       .n_reg = 0x32d0,
+       .config_reg = 0x32c4,
+       .status_reg = 0x32dc,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x32d4,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll3 = {
+       .d = &hfpll3_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll3",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll3.lock),
+};
+
+static struct hfpll_data hfpll_l2_8064_data = {
+       .mode_reg = 0x3300,
+       .l_reg = 0x3308,
+       .m_reg = 0x330c,
+       .n_reg = 0x3310,
+       .config_reg = 0x3304,
+       .status_reg = 0x331c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3314,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct hfpll_data hfpll_l2_data = {
+       .mode_reg = 0x3400,
+       .l_reg = 0x3408,
+       .m_reg = 0x340c,
+       .n_reg = 0x3410,
+       .config_reg = 0x3404,
+       .status_reg = 0x341c,
+       .config_val = 0x7845c665,
+       .droop_reg = 0x3414,
+       .droop_val = 0x0108c000,
+       .min_rate = 600000000UL,
+       .max_rate = 1800000000UL,
+};
+
+static struct clk_hfpll hfpll_l2 = {
+       .d = &hfpll_l2_data,
+       .clkr.hw.init = &(struct clk_init_data){
+               .parent_names = (const char *[]){ "pxo" },
+               .num_parents = 1,
+               .name = "hfpll_l2",
+               .ops = &clk_ops_hfpll,
+               .flags = CLK_IGNORE_UNUSED,
+       },
+       .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
+};
+
 static struct clk_pll pll14 = {
        .l_reg = 0x31c4,
        .m_reg = 0x31c8,
@@ -3107,6 +3266,9 @@ static struct clk_regmap *gcc_msm8960_clks[] = {
        [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
        [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
        [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
+       [PLL9] = &hfpll0.clkr,
+       [PLL10] = &hfpll1.clkr,
+       [PLL12] = &hfpll_l2.clkr,
 };
 
 static const struct qcom_reset_map gcc_msm8960_resets[] = {
@@ -3318,6 +3480,11 @@ static struct clk_regmap *gcc_apq8064_clks[] = {
        [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
        [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
        [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
+       [PLL9] = &hfpll0.clkr,
+       [PLL10] = &hfpll1.clkr,
+       [PLL12] = &hfpll_l2.clkr,
+       [PLL16] = &hfpll2.clkr,
+       [PLL17] = &hfpll3.clkr,
 };
 
 static const struct qcom_reset_map gcc_apq8064_resets[] = {
@@ -3477,6 +3644,11 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       if (match->data == &gcc_apq8064_desc) {
+               hfpll1.d = &hfpll1_8064_data;
+               hfpll_l2.d = &hfpll_l2_8064_data;
+       }
+
        tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1,
                                              NULL, 0);
        if (IS_ERR(tsens))
index 9a3290fdd01b18eb0b8eb6a7ab90a16550fd9c3c..9d136172c27ca460172bd913af850ee4a3e32d55 100644 (file)
@@ -260,6 +260,36 @@ static struct clk_alpha_pll_postdiv gpll0 = {
        },
 };
 
+static struct clk_branch gcc_mmss_gpll0_div_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_gpll0_div_clk",
+                       .parent_names = (const char *[]){ "gpll0" },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_gpll0_div_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_gpll0_div_clk",
+                       .parent_names = (const char *[]){ "gpll0" },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops
+               },
+       },
+};
+
 static struct clk_alpha_pll gpll4_early = {
        .offset = 0x77000,
        .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
@@ -2951,6 +2981,20 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
        },
 };
 
+static struct clk_branch gcc_aggre1_pnoc_ahb_clk = {
+       .halt_reg = 0x82014,
+       .clkr = {
+               .enable_reg = 0x82014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre1_pnoc_ahb_clk",
+                       .parent_names = (const char *[]){ "periph_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_aggre2_ufs_axi_clk = {
        .halt_reg = 0x83014,
        .clkr = {
@@ -2981,6 +3025,34 @@ static struct clk_branch gcc_aggre2_usb3_axi_clk = {
        },
 };
 
+static struct clk_branch gcc_dcc_ahb_clk = {
+       .halt_reg = 0x84004,
+       .clkr = {
+               .enable_reg = 0x84004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_ahb_clk",
+                       .parent_names = (const char *[]){ "config_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = {
+       .halt_reg = 0x85000,
+       .clkr = {
+               .enable_reg = 0x85000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk",
+                       .parent_names = (const char *[]){ "config_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_qspi_ahb_clk = {
        .halt_reg = 0x8b004,
        .clkr = {
@@ -3039,6 +3111,20 @@ static struct clk_branch gcc_hdmi_clkref_clk = {
        },
 };
 
+static struct clk_branch gcc_edp_clkref_clk = {
+       .halt_reg = 0x88004,
+       .clkr = {
+               .enable_reg = 0x88004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_edp_clkref_clk",
+                       .parent_names = (const char *[]){ "xo" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_ufs_clkref_clk = {
        .halt_reg = 0x88008,
        .clkr = {
@@ -3095,6 +3181,62 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = {
        },
 };
 
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+       .halt_reg = 0x8a000,
+       .clkr = {
+               .enable_reg = 0x8a000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_cfg_ahb_clk",
+                       .parent_names = (const char *[]){ "config_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
+       .halt_reg = 0x8a004,
+       .clkr = {
+               .enable_reg = 0x8a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_mnoc_bimc_axi_clk",
+                       .parent_names = (const char *[]){ "system_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_snoc_axi_clk = {
+       .halt_reg = 0x8a024,
+       .clkr = {
+               .enable_reg = 0x8a024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_snoc_axi_clk",
+                       .parent_names = (const char *[]){ "system_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x8a028,
+       .clkr = {
+               .enable_reg = 0x8a028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .parent_names = (const char *[]){ "system_noc_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_hw *gcc_msm8996_hws[] = {
        &xo.hw,
        &gpll0_early_div.hw,
@@ -3355,6 +3497,7 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
        [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr,
        [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr,
        [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr,
+       [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr,
        [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr,
        [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr,
        [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr,
@@ -3365,6 +3508,15 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
        [GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr,
        [GCC_RX2_USB2_CLKREF_CLK] = &gcc_rx2_usb2_clkref_clk.clkr,
        [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr,
+       [GCC_EDP_CLKREF_CLK] = &gcc_edp_clkref_clk.clkr,
+       [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+       [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+       [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+       [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
+       [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr,
+       [GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK] = &gcc_aggre0_noc_mpu_cfg_ahb_clk.clkr,
+       [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr,
+       [GCC_MSS_GPLL0_DIV_CLK] = &gcc_mss_gpll0_div_clk.clkr,
 };
 
 static struct gdsc *gcc_msm8996_gdscs[] = {
diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
new file mode 100644 (file)
index 0000000..e4ca6a4
--- /dev/null
@@ -0,0 +1,2744 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-qcs404.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "reset.h"
+
+enum {
+       P_CORE_BI_PLL_TEST_SE,
+       P_DSI0_PHY_PLL_OUT_BYTECLK,
+       P_DSI0_PHY_PLL_OUT_DSICLK,
+       P_GPLL0_OUT_AUX,
+       P_GPLL0_OUT_MAIN,
+       P_GPLL1_OUT_MAIN,
+       P_GPLL3_OUT_MAIN,
+       P_GPLL4_OUT_AUX,
+       P_GPLL4_OUT_MAIN,
+       P_GPLL6_OUT_AUX,
+       P_HDMI_PHY_PLL_CLK,
+       P_PCIE_0_PIPE_CLK,
+       P_SLEEP_CLK,
+       P_XO,
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_0[] = {
+       "cxo",
+       "gpll0_out_main",
+       "core_bi_pll_test_se",
+};
+
+static const char * const gcc_parent_names_ao_0[] = {
+       "cxo",
+       "gpll0_ao_out_main",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_XO, 0 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_1[] = {
+       "cxo",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL6_OUT_AUX, 2 },
+       { P_SLEEP_CLK, 6 },
+};
+
+static const char * const gcc_parent_names_2[] = {
+       "cxo",
+       "gpll0_out_main",
+       "gpll6_out_aux",
+       "sleep_clk",
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL6_OUT_AUX, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_3[] = {
+       "cxo",
+       "gpll0_out_main",
+       "gpll6_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_XO, 0 },
+       { P_GPLL1_OUT_MAIN, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_4[] = {
+       "cxo",
+       "gpll1_out_main",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_XO, 0 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+       { P_GPLL0_OUT_AUX, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_5[] = {
+       "cxo",
+       "dsi0pll_byteclk_src",
+       "gpll0_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_XO, 0 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+       { P_GPLL0_OUT_AUX, 3 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_6[] = {
+       "cxo",
+       "dsi0_phy_pll_out_byteclk",
+       "gpll0_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL3_OUT_MAIN, 2 },
+       { P_GPLL6_OUT_AUX, 3 },
+       { P_GPLL4_OUT_AUX, 4 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_7[] = {
+       "cxo",
+       "gpll0_out_main",
+       "gpll3_out_main",
+       "gpll6_out_aux",
+       "gpll4_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+       { P_XO, 0 },
+       { P_HDMI_PHY_PLL_CLK, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_8[] = {
+       "cxo",
+       "hdmi_phy_pll_clk",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_DSI0_PHY_PLL_OUT_DSICLK, 2 },
+       { P_GPLL6_OUT_AUX, 3 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_9[] = {
+       "cxo",
+       "gpll0_out_main",
+       "dsi0_phy_pll_out_dsiclk",
+       "gpll6_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+       { P_XO, 0 },
+       { P_SLEEP_CLK, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_10[] = {
+       "cxo",
+       "sleep_clk",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_11[] = {
+       { P_XO, 0 },
+       { P_PCIE_0_PIPE_CLK, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_11[] = {
+       "cxo",
+       "pcie_0_pipe_clk",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_12[] = {
+       { P_XO, 0 },
+       { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+       { P_GPLL0_OUT_AUX, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_12[] = {
+       "cxo",
+       "dsi0pll_pclk_src",
+       "gpll0_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_13[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL4_OUT_MAIN, 2 },
+       { P_GPLL6_OUT_AUX, 3 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_13[] = {
+       "cxo",
+       "gpll0_out_main",
+       "gpll4_out_main",
+       "gpll6_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_14[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL4_OUT_AUX, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_14[] = {
+       "cxo",
+       "gpll0_out_main",
+       "gpll4_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static const struct parent_map gcc_parent_map_15[] = {
+       { P_XO, 0 },
+       { P_GPLL0_OUT_AUX, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const gcc_parent_names_15[] = {
+       "cxo",
+       "gpll0_out_aux",
+       "core_bi_pll_test_se",
+};
+
+static struct clk_fixed_factor cxo = {
+       .mult = 1,
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "cxo",
+               .parent_names = (const char *[]){ "xo_board" },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll0_sleep_clk_src = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45008,
+               .enable_mask = BIT(23),
+               .enable_is_inverted = true,
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_sleep_clk_src",
+                       .parent_names = (const char *[]){ "cxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll0_out_main = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .flags = SUPPORTS_FSM_MODE,
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_out_main",
+                       .parent_names = (const char *[])
+                                       { "gpll0_sleep_clk_src" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll0_ao_out_main = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .flags = SUPPORTS_FSM_MODE,
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_ao_out_main",
+                       .parent_names = (const char *[]){ "cxo" },
+                       .num_parents = 1,
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll1_out_main = {
+       .offset = 0x20000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll1_out_main",
+                       .parent_names = (const char *[]){ "cxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+/* 930MHz configuration */
+static const struct alpha_pll_config gpll3_config = {
+       .l = 48,
+       .alpha = 0x0,
+       .alpha_en_mask = BIT(24),
+       .post_div_mask = 0xf << 8,
+       .post_div_val = 0x1 << 8,
+       .vco_mask = 0x3 << 20,
+       .main_output_mask = 0x1,
+       .config_ctl_val = 0x4001055b,
+};
+
+static const struct pll_vco gpll3_vco[] = {
+       { 700000000, 1400000000, 0 },
+};
+
+static struct clk_alpha_pll gpll3_out_main = {
+       .offset = 0x22000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = gpll3_vco,
+       .num_vco = ARRAY_SIZE(gpll3_vco),
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll3_out_main",
+                       .parent_names = (const char *[]){ "cxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll4_out_main = {
+       .offset = 0x24000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4_out_main",
+                       .parent_names = (const char *[]){ "cxo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_pll gpll6 = {
+       .l_reg = 0x37004,
+       .m_reg = 0x37008,
+       .n_reg = 0x3700C,
+       .config_reg = 0x37014,
+       .mode_reg = 0x37000,
+       .status_reg = 0x3701C,
+       .status_bit = 17,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6",
+               .parent_names = (const char *[]){ "cxo" },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap gpll6_out_aux = {
+       .enable_reg = 0x45000,
+       .enable_mask = BIT(7),
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll6_out_aux",
+               .parent_names = (const char *[]){ "gpll6" },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_apss_ahb_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 apss_ahb_clk_src = {
+       .cmd_rcgr = 0x46000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_apss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "apss_ahb_clk_src",
+               .parent_names = gcc_parent_names_ao_0,
+               .num_parents = 3,
+               .flags = CLK_IS_CRITICAL,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup0_i2c_apps_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup0_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x602c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup0_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup0_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 1, 2),
+       F(4800000, P_XO, 4, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup0_spi_apps_clk_src = {
+       .cmd_rcgr = 0x6034,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup0_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x200c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = {
+       F(960000,   P_XO, 10, 1, 2),
+       F(4800000,  P_XO, 4, 0, 0),
+       F(9600000,  P_XO, 2, 0, 0),
+       F(10480000, P_GPLL0_OUT_MAIN, 1, 3, 229),
+       F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(20961000, P_GPLL0_OUT_MAIN, 1, 6, 229),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x3000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup2_spi_apps_clk_src[] = {
+       F(960000,   P_XO, 10, 1, 2),
+       F(4800000,  P_XO, 4, 0, 0),
+       F(9600000,  P_XO, 2, 0, 0),
+       F(15000000, P_GPLL0_OUT_MAIN, 1,  3, 160),
+       F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(30000000, P_GPLL0_OUT_MAIN, 1,  3, 80),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x3014,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup2_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x4000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x4024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x5000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x5024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_uart0_apps_clk_src[] = {
+       F(3686400, P_GPLL0_OUT_MAIN, 1, 72, 15625),
+       F(7372800, P_GPLL0_OUT_MAIN, 1, 144, 15625),
+       F(14745600, P_GPLL0_OUT_MAIN, 1, 288, 15625),
+       F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0_OUT_MAIN, 1, 3, 100),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25),
+       F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20),
+       F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 500),
+       F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50),
+       F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125),
+       F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100),
+       F(58982400, P_GPLL0_OUT_MAIN, 1, 1152, 15625),
+       F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40),
+       F(64000000, P_GPLL0_OUT_MAIN, 1, 2, 25),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart0_apps_clk_src = {
+       .cmd_rcgr = 0x600c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_uart0_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart0_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x2044,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_uart0_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x3034,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_uart0_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+       .cmd_rcgr = 0x4014,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_uart0_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart3_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup0_i2c_apps_clk_src = {
+       .cmd_rcgr = 0xc00c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup0_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup0_spi_apps_clk_src = {
+       .cmd_rcgr = 0xc024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_qup0_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup0_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_uart0_apps_clk_src = {
+       .cmd_rcgr = 0xc044,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_blsp1_uart0_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart0_apps_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+       .cmd_rcgr = 0x4d044,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte0_clk_src",
+               .parent_names = gcc_parent_names_5,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_emac_clk_src[] = {
+       F(5000000,   P_GPLL1_OUT_MAIN, 2, 1, 50),
+       F(50000000,  P_GPLL1_OUT_MAIN, 10, 0, 0),
+       F(125000000, P_GPLL1_OUT_MAIN, 4, 0, 0),
+       F(250000000, P_GPLL1_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 emac_clk_src = {
+       .cmd_rcgr = 0x4e01c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_emac_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "emac_clk_src",
+               .parent_names = gcc_parent_names_4,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_emac_ptp_clk_src[] = {
+       F(50000000,  P_GPLL1_OUT_MAIN, 10, 0, 0),
+       F(125000000, P_GPLL1_OUT_MAIN, 4, 0, 0),
+       F(250000000, P_GPLL1_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 emac_ptp_clk_src = {
+       .cmd_rcgr = 0x4e014,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_emac_ptp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "emac_ptp_clk_src",
+               .parent_names = gcc_parent_names_4,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_esc0_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+       .cmd_rcgr = 0x4d05c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc0_clk_src",
+               .parent_names = gcc_parent_names_6,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
+       F(19200000,  P_XO, 1, 0, 0),
+       F(50000000,  P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000,  P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(228571429, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
+       F(240000000, P_GPLL6_OUT_AUX,  4.5, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(270000000, P_GPLL6_OUT_AUX,  4, 0, 0),
+       F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(484800000, P_GPLL3_OUT_MAIN, 1, 0, 0),
+       F(523200000, P_GPLL3_OUT_MAIN, 1, 0, 0),
+       F(550000000, P_GPLL3_OUT_MAIN, 1, 0, 0),
+       F(598000000, P_GPLL3_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gfx3d_clk_src = {
+       .cmd_rcgr = 0x59000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gfx3d_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gfx3d_clk_src",
+               .parent_names = gcc_parent_names_7,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gp1_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+       .cmd_rcgr = 0x8004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp1_clk_src",
+               .parent_names = gcc_parent_names_2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+       .cmd_rcgr = 0x9004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp2_clk_src",
+               .parent_names = gcc_parent_names_2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+       .cmd_rcgr = 0xa004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp3_clk_src",
+               .parent_names = gcc_parent_names_2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 hdmi_app_clk_src = {
+       .cmd_rcgr = 0x4d0e4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hdmi_app_clk_src",
+               .parent_names = gcc_parent_names_1,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 hdmi_pclk_clk_src = {
+       .cmd_rcgr = 0x4d0dc,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hdmi_pclk_clk_src",
+               .parent_names = gcc_parent_names_8,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src[] = {
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(145454545, P_GPLL0_OUT_MAIN, 5.5, 0, 0),
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+       .cmd_rcgr = 0x4d014,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_9,
+       .freq_tbl = ftbl_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mdp_clk_src",
+               .parent_names = gcc_parent_names_9,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pcie_0_aux_clk_src[] = {
+       F(1200000, P_XO, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pcie_0_aux_clk_src = {
+       .cmd_rcgr = 0x3e024,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_10,
+       .freq_tbl = ftbl_pcie_0_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie_0_aux_clk_src",
+               .parent_names = gcc_parent_names_10,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pcie_0_pipe_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(125000000, P_PCIE_0_PIPE_CLK, 2, 0, 0),
+       F(250000000, P_PCIE_0_PIPE_CLK, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pcie_0_pipe_clk_src = {
+       .cmd_rcgr = 0x3e01c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_11,
+       .freq_tbl = ftbl_pcie_0_pipe_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie_0_pipe_clk_src",
+               .parent_names = gcc_parent_names_11,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+       .cmd_rcgr = 0x4d000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_12,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk0_clk_src",
+               .parent_names = gcc_parent_names_12,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_pixel_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pdm2_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+       .cmd_rcgr = 0x44010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pdm2_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(192000000, P_GPLL4_OUT_MAIN, 6, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(384000000, P_GPLL4_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x42004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_13,
+       .freq_tbl = ftbl_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_apps_clk_src",
+               .parent_names = gcc_parent_names_13,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = {
+       F(160000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x5d000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_ice_core_clk_src",
+               .parent_names = gcc_parent_names_3,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4),
+       F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+       F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x43004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_14,
+       .freq_tbl = ftbl_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc2_apps_clk_src",
+               .parent_names = gcc_parent_names_14,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 usb20_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x41048,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_mock_utmi_clk_src",
+               .parent_names = gcc_parent_names_1,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb30_master_clk_src = {
+       .cmd_rcgr = 0x39028,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_usb30_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_master_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x3901c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_mock_utmi_clk_src",
+               .parent_names = gcc_parent_names_1,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 usb3_phy_aux_clk_src = {
+       .cmd_rcgr = 0x3903c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_pcie_0_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb3_phy_aux_clk_src",
+               .parent_names = gcc_parent_names_1,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb_hs_system_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(80000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb_hs_system_clk_src = {
+       .cmd_rcgr = 0x41010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_usb_hs_system_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb_hs_system_clk_src",
+               .parent_names = gcc_parent_names_3,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+       .cmd_rcgr = 0x4d02c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_15,
+       .freq_tbl = ftbl_esc0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vsync_clk_src",
+               .parent_names = gcc_parent_names_15,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_apss_ahb_clk = {
+       .halt_reg = 0x4601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "apss_ahb_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_apss_tcu_clk = {
+       .halt_reg = 0x5b004,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_tcu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x59034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+                       .parent_names = (const char *[]){
+                               "gcc_apss_tcu_clk",
+                       },
+
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gpu_clk = {
+       .halt_reg = 0x59030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gpu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_mdss_clk = {
+       .halt_reg = 0x31038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x31038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_mdss_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x1008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_dcc_clk = {
+       .halt_reg = 0x77004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x77004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_dcc_xo_clk = {
+       .halt_reg = 0x77008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x77008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_xo_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup0_i2c_apps_clk = {
+       .halt_reg = 0x6028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup0_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup0_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup0_spi_apps_clk = {
+       .halt_reg = 0x6024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup0_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup0_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x2008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup1_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x2004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup1_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x3010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup2_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup2_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x4020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup3_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x401c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x401c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup3_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x5020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup4_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup4_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart0_apps_clk = {
+       .halt_reg = 0x6004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart0_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart0_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x203c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart1_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x302c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x302c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart2_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+       .halt_reg = 0x400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart3_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart3_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_ahb_clk = {
+       .halt_reg = 0xb008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup0_i2c_apps_clk = {
+       .halt_reg = 0xc008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup0_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup0_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup0_spi_apps_clk = {
+       .halt_reg = 0xc004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup0_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup0_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_uart0_apps_clk = {
+       .halt_reg = 0xc03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xc03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart0_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_uart0_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x1300c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_ahb_clk = {
+       .halt_reg = 0x16024,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_axi_clk = {
+       .halt_reg = 0x16020,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_clk = {
+       .halt_reg = 0x1601c,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_eth_axi_clk = {
+       .halt_reg = 0x4e010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_eth_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_eth_ptp_clk = {
+       .halt_reg = 0x4e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_eth_ptp_clk",
+                       .parent_names = (const char *[]){
+                               "emac_ptp_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_eth_rgmii_clk = {
+       .halt_reg = 0x4e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_eth_rgmii_clk",
+                       .parent_names = (const char *[]){
+                               "emac_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_eth_slave_ahb_clk = {
+       .halt_reg = 0x4e00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_eth_slave_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_geni_ir_s_clk = {
+       .halt_reg = 0xf008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_geni_ir_s_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_geni_ir_h_clk = {
+       .halt_reg = 0xf004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_geni_ir_h_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gfx_tcu_clk = {
+       .halt_reg = 0x12020,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500C,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gfx_tcu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gfx_tbu_clk = {
+       .halt_reg = 0x12010,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500C,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gfx_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x8000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_names = (const char *[]){
+                               "gp1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x9000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_names = (const char *[]){
+                               "gp2_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0xa000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_names = (const char *[]){
+                               "gp3_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gtcu_ahb_clk = {
+       .halt_reg = 0x12044,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gtcu_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdp_tbu_clk = {
+       .halt_reg = 0x1201c,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdp_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_ahb_clk = {
+       .halt_reg = 0x4d07c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_axi_clk = {
+       .halt_reg = 0x4d080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_byte0_clk = {
+       .halt_reg = 0x4d094,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d094,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_byte0_clk",
+                       .parent_names = (const char *[]){
+                               "byte0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_esc0_clk = {
+       .halt_reg = 0x4d098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_esc0_clk",
+                       .parent_names = (const char *[]){
+                               "esc0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_hdmi_app_clk = {
+       .halt_reg = 0x4d0d8,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d0d8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_hdmi_app_clk",
+                       .parent_names = (const char *[]){
+                               "hdmi_app_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_hdmi_pclk_clk = {
+       .halt_reg = 0x4d0d4,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d0d4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_hdmi_pclk_clk",
+                       .parent_names = (const char *[]){
+                               "hdmi_pclk_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_mdp_clk = {
+       .halt_reg = 0x4d088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_mdp_clk",
+                       .parent_names = (const char *[]){
+                               "mdp_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_pclk0_clk = {
+       .halt_reg = 0x4d084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_pclk0_clk",
+                       .parent_names = (const char *[]){
+                               "pclk0_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdss_vsync_clk = {
+       .halt_reg = 0x4d090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdss_vsync_clk",
+                       .parent_names = (const char *[]){
+                               "vsync_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_ahb_clk = {
+       .halt_reg = 0x59028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_oxili_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_oxili_gfx3d_clk = {
+       .halt_reg = 0x59020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_oxili_gfx3d_clk",
+                       .parent_names = (const char *[]){
+                               "gfx3d_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+       .halt_reg = 0x3e014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_aux_clk",
+                       .parent_names = (const char *[]){
+                               "pcie_0_aux_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+       .halt_reg = 0x3e008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+       .halt_reg = 0x3e018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(18),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_mstr_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+       .halt_reg = 0x3e00c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(28),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_pipe_clk",
+                       .parent_names = (const char *[]){
+                               "pcie_0_pipe_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+       .halt_reg = 0x3e010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_slv_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcnoc_usb2_clk = {
+       .halt_reg = 0x27008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x27008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcnoc_usb2_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcnoc_usb3_clk = {
+       .halt_reg = 0x2700c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2700c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcnoc_usb3_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x4400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_names = (const char *[]){
+                               "pdm2_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x44004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x44004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x13004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* PWM clks do not have XO as parent as src clk is a balance root */
+static struct clk_branch gcc_pwm0_xo512_clk = {
+       .halt_reg = 0x44018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x44018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pwm0_xo512_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pwm1_xo512_clk = {
+       .halt_reg = 0x49004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pwm1_xo512_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pwm2_xo512_clk = {
+       .halt_reg = 0x4a004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pwm2_xo512_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qdss_dap_clk = {
+       .halt_reg = 0x29084,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(21),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qdss_dap_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x4201c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x42018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x42018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_names = (const char *[]){
+                               "sdcc1_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x5d014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5d014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_names = (const char *[]){
+                               "sdcc1_ice_core_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x4301c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4301c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x43018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x43018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_names = (const char *[]){
+                               "sdcc2_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_smmu_cfg_clk = {
+       .halt_reg = 0x12038,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x3600C,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_smmu_cfg_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_usb3_clk = {
+       .halt_reg = 0x26014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x26014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_usb3_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_master_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_hs_inactivity_timers_clk = {
+       .halt_reg = 0x4100C,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4100C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_hs_inactivity_timers_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb20_mock_utmi_clk = {
+       .halt_reg = 0x41044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x41044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_mock_utmi_clk",
+                       .parent_names = (const char *[]){
+                               "usb20_mock_utmi_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb2a_phy_sleep_clk = {
+       .halt_reg = 0x4102c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4102c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb2a_phy_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_master_clk = {
+       .halt_reg = 0x3900c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3900c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_master_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_master_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_mock_utmi_clk = {
+       .halt_reg = 0x39014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x39014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_mock_utmi_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_mock_utmi_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_sleep_clk = {
+       .halt_reg = 0x39010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x39010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_phy_aux_clk = {
+       .halt_reg = 0x39044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x39044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_aux_clk",
+                       .parent_names = (const char *[]){
+                               "usb3_phy_aux_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_phy_pipe_clk = {
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x39018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = {
+       .halt_reg = 0x41030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x41030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_hs_phy_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_hs_system_clk = {
+       .halt_reg = 0x41004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x41004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_hs_system_clk",
+                       .parent_names = (const char *[]){
+                               "usb_hs_system_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_hw *gcc_qcs404_hws[] = {
+       &cxo.hw,
+};
+
+static struct clk_regmap *gcc_qcs404_clocks[] = {
+       [GCC_APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+       [GCC_BLSP1_QUP0_I2C_APPS_CLK_SRC] = &blsp1_qup0_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP0_SPI_APPS_CLK_SRC] = &blsp1_qup0_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [GCC_BLSP1_UART0_APPS_CLK_SRC] = &blsp1_uart0_apps_clk_src.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [GCC_BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr,
+       [GCC_BLSP2_QUP0_I2C_APPS_CLK_SRC] = &blsp2_qup0_i2c_apps_clk_src.clkr,
+       [GCC_BLSP2_QUP0_SPI_APPS_CLK_SRC] = &blsp2_qup0_spi_apps_clk_src.clkr,
+       [GCC_BLSP2_UART0_APPS_CLK_SRC] = &blsp2_uart0_apps_clk_src.clkr,
+       [GCC_BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+       [GCC_EMAC_CLK_SRC] = &emac_clk_src.clkr,
+       [GCC_EMAC_PTP_CLK_SRC] = &emac_ptp_clk_src.clkr,
+       [GCC_ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+       [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
+       [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+       [GCC_BIMC_MDSS_CLK] = &gcc_bimc_mdss_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP1_QUP0_I2C_APPS_CLK] = &gcc_blsp1_qup0_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP0_SPI_APPS_CLK] = &gcc_blsp1_qup0_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART0_APPS_CLK] = &gcc_blsp1_uart0_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr,
+       [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr,
+       [GCC_BLSP2_QUP0_I2C_APPS_CLK] = &gcc_blsp2_qup0_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP0_SPI_APPS_CLK] = &gcc_blsp2_qup0_spi_apps_clk.clkr,
+       [GCC_BLSP2_UART0_APPS_CLK] = &gcc_blsp2_uart0_apps_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_ETH_AXI_CLK] = &gcc_eth_axi_clk.clkr,
+       [GCC_ETH_PTP_CLK] = &gcc_eth_ptp_clk.clkr,
+       [GCC_ETH_RGMII_CLK] = &gcc_eth_rgmii_clk.clkr,
+       [GCC_ETH_SLAVE_AHB_CLK] = &gcc_eth_slave_ahb_clk.clkr,
+       [GCC_GENI_IR_S_CLK] = &gcc_geni_ir_s_clk.clkr,
+       [GCC_GENI_IR_H_CLK] = &gcc_geni_ir_h_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr,
+       [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr,
+       [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr,
+       [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr,
+       [GCC_MDSS_HDMI_APP_CLK] = &gcc_mdss_hdmi_app_clk.clkr,
+       [GCC_MDSS_HDMI_PCLK_CLK] = &gcc_mdss_hdmi_pclk_clk.clkr,
+       [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr,
+       [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr,
+       [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr,
+       [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr,
+       [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr,
+       [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
+       [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
+       [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+       [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+       [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
+       [GCC_PCNOC_USB2_CLK] = &gcc_pcnoc_usb2_clk.clkr,
+       [GCC_PCNOC_USB3_CLK] = &gcc_pcnoc_usb3_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_PWM0_XO512_CLK] = &gcc_pwm0_xo512_clk.clkr,
+       [GCC_PWM1_XO512_CLK] = &gcc_pwm1_xo512_clk.clkr,
+       [GCC_PWM2_XO512_CLK] = &gcc_pwm2_xo512_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SYS_NOC_USB3_CLK] = &gcc_sys_noc_usb3_clk.clkr,
+       [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr,
+       [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr,
+       [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
+       [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
+       [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
+       [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
+       [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+       [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr,
+       [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
+       [GCC_GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
+       [GCC_GP1_CLK_SRC] = &gp1_clk_src.clkr,
+       [GCC_GP2_CLK_SRC] = &gp2_clk_src.clkr,
+       [GCC_GP3_CLK_SRC] = &gp3_clk_src.clkr,
+       [GCC_GPLL0_OUT_MAIN] = &gpll0_out_main.clkr,
+       [GCC_GPLL0_AO_OUT_MAIN] = &gpll0_ao_out_main.clkr,
+       [GCC_GPLL0_SLEEP_CLK_SRC] = &gpll0_sleep_clk_src.clkr,
+       [GCC_GPLL1_OUT_MAIN] = &gpll1_out_main.clkr,
+       [GCC_GPLL3_OUT_MAIN] = &gpll3_out_main.clkr,
+       [GCC_GPLL4_OUT_MAIN] = &gpll4_out_main.clkr,
+       [GCC_GPLL6] = &gpll6.clkr,
+       [GCC_GPLL6_OUT_AUX] = &gpll6_out_aux,
+       [GCC_HDMI_APP_CLK_SRC] = &hdmi_app_clk_src.clkr,
+       [GCC_HDMI_PCLK_CLK_SRC] = &hdmi_pclk_clk_src.clkr,
+       [GCC_MDP_CLK_SRC] = &mdp_clk_src.clkr,
+       [GCC_PCIE_0_AUX_CLK_SRC] = &pcie_0_aux_clk_src.clkr,
+       [GCC_PCIE_0_PIPE_CLK_SRC] = &pcie_0_pipe_clk_src.clkr,
+       [GCC_PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+       [GCC_PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+       [GCC_SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr,
+       [GCC_SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+       [GCC_USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr,
+       [GCC_USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
+       [GCC_USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
+       [GCC_USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
+       [GCC_USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
+       [GCC_VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+       [GCC_USB_HS_INACTIVITY_TIMERS_CLK] =
+                       &gcc_usb_hs_inactivity_timers_clk.clkr,
+       [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
+       [GCC_GTCU_AHB_CLK] = &gcc_gtcu_ahb_clk.clkr,
+       [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
+       [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr,
+       [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
+       [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
+       [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
+       [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
+       [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
+       [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr,
+       [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr,
+       [GCC_DCC_CLK] = &gcc_dcc_clk.clkr,
+       [GCC_DCC_XO_CLK] = &gcc_dcc_xo_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_qcs404_resets[] = {
+       [GCC_GENI_IR_BCR] = { 0x0F000 },
+       [GCC_USB_HS_BCR] = { 0x41000 },
+       [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
+       [GCC_QUSB2_PHY_BCR] = { 0x4103c },
+       [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 },
+       [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 },
+       [GCC_USB3_PHY_BCR] = { 0x39004 },
+       [GCC_USB_30_BCR] = { 0x39000 },
+       [GCC_USB3PHY_PHY_BCR] = { 0x39008 },
+       [GCC_PCIE_0_BCR] = { 0x3e000 },
+       [GCC_PCIE_0_PHY_BCR] = { 0x3e004 },
+       [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 },
+       [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c },
+       [GCC_EMAC_BCR] = { 0x4e000 },
+};
+
+static const struct regmap_config gcc_qcs404_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x7f000,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_qcs404_desc = {
+       .config = &gcc_qcs404_regmap_config,
+       .clks = gcc_qcs404_clocks,
+       .num_clks = ARRAY_SIZE(gcc_qcs404_clocks),
+       .resets = gcc_qcs404_resets,
+       .num_resets = ARRAY_SIZE(gcc_qcs404_resets),
+};
+
+static const struct of_device_id gcc_qcs404_match_table[] = {
+       { .compatible = "qcom,gcc-qcs404" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_qcs404_match_table);
+
+static int gcc_qcs404_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret, i;
+
+       regmap = qcom_cc_map(pdev, &gcc_qcs404_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config);
+
+       for (i = 0; i < ARRAY_SIZE(gcc_qcs404_hws); i++) {
+               ret = devm_clk_hw_register(&pdev->dev, gcc_qcs404_hws[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap);
+}
+
+static struct platform_driver gcc_qcs404_driver = {
+       .probe = gcc_qcs404_probe,
+       .driver = {
+               .name = "gcc-qcs404",
+               .of_match_table = gcc_qcs404_match_table,
+       },
+};
+
+static int __init gcc_qcs404_init(void)
+{
+       return platform_driver_register(&gcc_qcs404_driver);
+}
+subsys_initcall(gcc_qcs404_init);
+
+static void __exit gcc_qcs404_exit(void)
+{
+       platform_driver_unregister(&gcc_qcs404_driver);
+}
+module_exit(gcc_qcs404_exit);
+
+MODULE_DESCRIPTION("Qualcomm GCC QCS404 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
new file mode 100644 (file)
index 0000000..ba239ea
--- /dev/null
@@ -0,0 +1,2480 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, Craig Tatlor.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-sdm660.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-alpha-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+#include "gdsc.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+       P_XO,
+       P_SLEEP_CLK,
+       P_GPLL0,
+       P_GPLL1,
+       P_GPLL4,
+       P_GPLL0_EARLY_DIV,
+       P_GPLL1_EARLY_DIV,
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div[] = {
+       "xo",
+       "gpll0",
+       "gpll0_early_div",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0[] = {
+       "xo",
+       "gpll0",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_SLEEP_CLK, 5 },
+       { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+       "xo",
+       "gpll0",
+       "sleep_clk",
+       "gpll0_early_div",
+};
+
+static const struct parent_map gcc_parent_map_xo_sleep_clk[] = {
+       { P_XO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const char * const gcc_parent_names_xo_sleep_clk[] = {
+       "xo",
+       "sleep_clk",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll4[] = {
+       { P_XO, 0 },
+       { P_GPLL4, 5 },
+};
+
+static const char * const gcc_parent_names_xo_gpll4[] = {
+       "xo",
+       "gpll4",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_EARLY_DIV, 3 },
+       { P_GPLL1, 4 },
+       { P_GPLL4, 5 },
+       { P_GPLL1_EARLY_DIV, 6 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = {
+       "xo",
+       "gpll0",
+       "gpll0_early_div",
+       "gpll1",
+       "gpll4",
+       "gpll1_early_div",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL4, 5 },
+       { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div[] = {
+       "xo",
+       "gpll0",
+       "gpll4",
+       "gpll0_early_div",
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_EARLY_DIV, 2 },
+       { P_GPLL4, 5 },
+};
+
+static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4[] = {
+       "xo",
+       "gpll0",
+       "gpll0_early_div",
+       "gpll4",
+};
+
+static struct clk_fixed_factor xo = {
+       .mult = 1,
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "xo",
+               .parent_names = (const char *[]){ "xo_board" },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll0_early = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_early",
+                       .parent_names = (const char *[]){ "xo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll0_early_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_early_div",
+               .parent_names = (const char *[]){ "gpll0_early" },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+       .offset = 0x00000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+               .parent_names = (const char *[]){ "gpll0_early" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll1_early = {
+       .offset = 0x1000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll1_early",
+                       .parent_names = (const char *[]){ "xo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll1_early_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll1_early_div",
+               .parent_names = (const char *[]){ "gpll1_early" },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll1 = {
+       .offset = 0x1000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll1",
+               .parent_names = (const char *[]){ "gpll1_early" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll4_early = {
+       .offset = 0x77000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4_early",
+                       .parent_names = (const char *[]){ "xo" },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll4 = {
+       .offset = 0x77000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data)
+       {
+               .name = "gpll4",
+               .parent_names = (const char *[]) { "gpll4_early" },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup1_i2c_apps_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x19020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 1, 2),
+       F(4800000, P_XO, 4, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(15000000, P_GPLL0, 10, 1, 4),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0, 12, 1, 2),
+       F(50000000, P_GPLL0, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x1900c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x1b020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x1b00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x1d020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x1d00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x1f020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x1f00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_uart1_apps_clk_src[] = {
+       F(3686400, P_GPLL0, 1, 96, 15625),
+       F(7372800, P_GPLL0, 1, 192, 15625),
+       F(14745600, P_GPLL0, 1, 384, 15625),
+       F(16000000, P_GPLL0, 5, 2, 15),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0, 5, 1, 5),
+       F(32000000, P_GPLL0, 1, 4, 75),
+       F(40000000, P_GPLL0, 15, 0, 0),
+       F(46400000, P_GPLL0, 1, 29, 375),
+       F(48000000, P_GPLL0, 12.5, 0, 0),
+       F(51200000, P_GPLL0, 1, 32, 375),
+       F(56000000, P_GPLL0, 1, 7, 75),
+       F(58982400, P_GPLL0, 1, 1536, 15625),
+       F(60000000, P_GPLL0, 10, 0, 0),
+       F(63157895, P_GPLL0, 9.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x1a00c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x1c00c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x26020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2600c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x28020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2800c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x2a020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2a00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x2c020,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_i2c_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x2c00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_spi_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x2700c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart1_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x2900c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart2_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gp1_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+       .cmd_rcgr = 0x64004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp1_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+       .cmd_rcgr = 0x65004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp2_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+       .cmd_rcgr = 0x66004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div,
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp3_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_hmss_gpll0_clk_src[] = {
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(600000000, P_GPLL0, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 hmss_gpll0_clk_src = {
+       .cmd_rcgr = 0x4805c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_hmss_gpll0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_gpll0_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_hmss_gpll4_clk_src[] = {
+       F(384000000, P_GPLL4, 4, 0, 0),
+       F(768000000, P_GPLL4, 2, 0, 0),
+       F(1536000000, P_GPLL4, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 hmss_gpll4_clk_src = {
+       .cmd_rcgr = 0x48074,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll4,
+       .freq_tbl = ftbl_hmss_gpll4_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_gpll4_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll4,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_hmss_rbcpr_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 hmss_rbcpr_clk_src = {
+       .cmd_rcgr = 0x48044,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_hmss_rbcpr_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_rbcpr_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pdm2_clk_src[] = {
+       F(60000000, P_GPLL0, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+       .cmd_rcgr = 0x33010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pdm2_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_qspi_ser_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(80200000, P_GPLL1_EARLY_DIV, 5, 0, 0),
+       F(160400000, P_GPLL1, 5, 0, 0),
+       F(267333333, P_GPLL1, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 qspi_ser_clk_src = {
+       .cmd_rcgr = 0x4d00c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div,
+       .freq_tbl = ftbl_qspi_ser_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qspi_ser_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_EARLY_DIV, 5, 1, 3),
+       F(25000000, P_GPLL0_EARLY_DIV, 6, 1, 2),
+       F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(192000000, P_GPLL4, 8, 0, 0),
+       F(384000000, P_GPLL4, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x1602c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div,
+       .freq_tbl = ftbl_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = {
+       F(75000000, P_GPLL0_EARLY_DIV, 4, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x16010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_ice_core_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_EARLY_DIV, 5, 1, 3),
+       F(25000000, P_GPLL0_EARLY_DIV, 6, 1, 2),
+       F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(192000000, P_GPLL4, 8, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x14010,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4,
+       .freq_tbl = ftbl_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc2_apps_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_ufs_axi_clk_src[] = {
+       F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ufs_axi_clk_src = {
+       .cmd_rcgr = 0x75018,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_ufs_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_axi_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_ufs_ice_core_clk_src[] = {
+       F(75000000, P_GPLL0_EARLY_DIV, 4, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ufs_ice_core_clk_src = {
+       .cmd_rcgr = 0x76010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_ufs_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_ice_core_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 ufs_phy_aux_clk_src = {
+       .cmd_rcgr = 0x76044,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_sleep_clk,
+       .freq_tbl = ftbl_hmss_rbcpr_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_phy_aux_clk_src",
+               .parent_names = gcc_parent_names_xo_sleep_clk,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_ufs_unipro_core_clk_src[] = {
+       F(37500000, P_GPLL0_EARLY_DIV, 8, 0, 0),
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ufs_unipro_core_clk_src = {
+       .cmd_rcgr = 0x76028,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_ufs_unipro_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_unipro_core_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb20_master_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(60000000, P_GPLL0, 10, 0, 0),
+       F(120000000, P_GPLL0, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb20_master_clk_src = {
+       .cmd_rcgr = 0x2f010,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_usb20_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_master_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb20_mock_utmi_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(60000000, P_GPLL0, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb20_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x2f024,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_usb20_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_mock_utmi_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(66666667, P_GPLL0_EARLY_DIV, 4.5, 0, 0),
+       F(120000000, P_GPLL0, 5, 0, 0),
+       F(133333333, P_GPLL0, 4.5, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb30_master_clk_src = {
+       .cmd_rcgr = 0xf014,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_usb30_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_master_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(40000000, P_GPLL0_EARLY_DIV, 7.5, 0, 0),
+       F(60000000, P_GPLL0, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+       .cmd_rcgr = 0xf028,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
+       .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_mock_utmi_clk_src",
+               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb3_phy_aux_clk_src[] = {
+       F(1200000, P_XO, 16, 0, 0),
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb3_phy_aux_clk_src = {
+       .cmd_rcgr = 0x5000c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_xo_sleep_clk,
+       .freq_tbl = ftbl_usb3_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb3_phy_aux_clk_src",
+               .parent_names = gcc_parent_names_xo_sleep_clk,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_aggre2_ufs_axi_clk = {
+       .halt_reg = 0x75034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x75034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre2_ufs_axi_clk",
+                       .parent_names = (const char *[]){
+                               "ufs_axi_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre2_usb3_axi_clk = {
+       .halt_reg = 0xf03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre2_usb3_axi_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_master_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x7106c,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x7106c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_hmss_axi_clk = {
+       .halt_reg = 0x48004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_hmss_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_mss_q6_axi_clk = {
+       .halt_reg = 0x4401c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4401c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_mss_q6_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x17004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x19008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x19008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup1_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x19004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x19004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup1_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x1b008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1b008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup2_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x1b004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1b004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup2_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x1d008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1d008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup3_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x1d004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup3_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x1f008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1f008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup4_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x1f004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup4_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x1a004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart1_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x1c004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart2_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_ahb_clk = {
+       .halt_reg = 0x25004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
+       .halt_reg = 0x26008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x26008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup1_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup1_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
+       .halt_reg = 0x26004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x26004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup1_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup1_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
+       .halt_reg = 0x28008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x28008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup2_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup2_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
+       .halt_reg = 0x28004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x28004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup2_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup2_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
+       .halt_reg = 0x2a008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2a008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup3_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup3_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
+       .halt_reg = 0x2a004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup3_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup3_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
+       .halt_reg = 0x2c008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2c008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup4_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup4_i2c_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
+       .halt_reg = 0x2c004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup4_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_qup4_spi_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_uart1_apps_clk = {
+       .halt_reg = 0x27004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x27004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart1_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_uart1_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp2_uart2_apps_clk = {
+       .halt_reg = 0x29004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x29004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart2_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp2_uart2_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x38004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb2_axi_clk = {
+       .halt_reg = 0x5058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb2_axi_clk",
+                       .parent_names = (const char *[]){
+                               "usb20_master_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_axi_clk = {
+       .halt_reg = 0x5018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_axi_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_master_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_dcc_ahb_clk = {
+       .halt_reg = 0x84004,
+       .clkr = {
+               .enable_reg = 0x84004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x64000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x64000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_names = (const char *[]){
+                               "gp1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x65000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x65000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_names = (const char *[]){
+                               "gp2_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x66000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x66000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_names = (const char *[]){
+                               "gp3_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_bimc_gfx_clk = {
+       .halt_reg = 0x71010,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x71010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_bimc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x71004,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x71004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_clk = {
+       .halt_reg = 0x5200c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_clk",
+                       .parent_names = (const char *[]){
+                               "gpll0",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk = {
+       .halt_reg = 0x5200c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_div_clk",
+                       .parent_names = (const char *[]){
+                               "gpll0_early_div",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_hmss_dvm_bus_clk = {
+       .halt_reg = 0x4808c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4808c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_hmss_dvm_bus_clk",
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_IGNORE_UNUSED,
+               },
+       },
+};
+
+static struct clk_branch gcc_hmss_rbcpr_clk = {
+       .halt_reg = 0x48008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x48008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_hmss_rbcpr_clk",
+                       .parent_names = (const char *[]){
+                               "hmss_rbcpr_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mmss_gpll0_clk = {
+       .halt_reg = 0x5200c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_gpll0_clk",
+                       .parent_names = (const char *[]){
+                               "gpll0",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mmss_gpll0_div_clk = {
+       .halt_reg = 0x5200c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x5200c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_gpll0_div_clk",
+                       .parent_names = (const char *[]){
+                               "gpll0_early_div",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
+       .halt_reg = 0x9004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_noc_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mmss_sys_noc_axi_clk = {
+       .halt_reg = 0x9000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_sys_noc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+       .halt_reg = 0x8a000,
+       .clkr = {
+               .enable_reg = 0x8a000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
+       .halt_reg = 0x8a004,
+       .clkr = {
+               .enable_reg = 0x8a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_mnoc_bimc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x8a040,
+       .clkr = {
+               .enable_reg = 0x8a040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mss_snoc_axi_clk = {
+       .halt_reg = 0x8a03c,
+       .clkr = {
+               .enable_reg = 0x8a03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_snoc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x3300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_names = (const char *[]){
+                               "pdm2_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x33004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x33004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x34004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qspi_ahb_clk = {
+       .halt_reg = 0x4d004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qspi_ser_clk = {
+       .halt_reg = 0x4d008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_ser_clk",
+                       .parent_names = (const char *[]){
+                               "qspi_ser_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_rx0_usb2_clkref_clk = {
+       .halt_reg = 0x88018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x88018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_rx0_usb2_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_rx1_usb2_clkref_clk = {
+       .halt_reg = 0x88014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x88014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_rx1_usb2_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x16008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x16008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x16004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x16004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_names = (const char *[]){
+                               "sdcc1_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x1600c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_names = (const char *[]){
+                               "sdcc1_ice_core_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x14008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x14008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x14004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x14004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_names = (const char *[]){
+                               "sdcc2_apps_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_ahb_clk = {
+       .halt_reg = 0x7500c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x7500c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_axi_clk = {
+       .halt_reg = 0x75008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x75008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_axi_clk",
+                       .parent_names = (const char *[]){
+                               "ufs_axi_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_clkref_clk = {
+       .halt_reg = 0x88008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x88008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_ice_core_clk = {
+       .halt_reg = 0x7600c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x7600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_ice_core_clk",
+                       .parent_names = (const char *[]){
+                               "ufs_ice_core_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_aux_clk = {
+       .halt_reg = 0x76040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x76040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_aux_clk",
+                       .parent_names = (const char *[]){
+                               "ufs_phy_aux_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
+       .halt_reg = 0x75014,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x75014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_rx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
+       .halt_reg = 0x7605c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x7605c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_rx_symbol_1_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
+       .halt_reg = 0x75010,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x75010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_tx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_unipro_core_clk = {
+       .halt_reg = 0x76008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x76008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_unipro_core_clk",
+                       .parent_names = (const char *[]){
+                               "ufs_unipro_core_clk_src",
+                       },
+                       .flags = CLK_SET_RATE_PARENT,
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb20_master_clk = {
+       .halt_reg = 0x2f004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_master_clk",
+                       .parent_names = (const char *[]){
+                               "usb20_master_clk_src"
+                       },
+                       .flags = CLK_SET_RATE_PARENT,
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb20_mock_utmi_clk = {
+       .halt_reg = 0x2f00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2f00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_mock_utmi_clk",
+                       .parent_names = (const char *[]){
+                               "usb20_mock_utmi_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb20_sleep_clk = {
+       .halt_reg = 0x2f008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2f008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_master_clk = {
+       .halt_reg = 0xf008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_master_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_master_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_mock_utmi_clk = {
+       .halt_reg = 0xf010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_mock_utmi_clk",
+                       .parent_names = (const char *[]){
+                               "usb30_mock_utmi_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_sleep_clk = {
+       .halt_reg = 0xf00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xf00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_clkref_clk = {
+       .halt_reg = 0x8800c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8800c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_phy_aux_clk = {
+       .halt_reg = 0x50000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x50000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_aux_clk",
+                       .parent_names = (const char *[]){
+                               "usb3_phy_aux_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_phy_pipe_clk = {
+       .halt_reg = 0x50004,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x50004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
+       .halt_reg = 0x6a004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_phy_cfg_ahb2phy_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc ufs_gdsc = {
+       .gdscr = 0x75004,
+       .gds_hw_ctrl = 0x0,
+       .pd = {
+               .name = "ufs_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc usb_30_gdsc = {
+       .gdscr = 0xf004,
+       .gds_hw_ctrl = 0x0,
+       .pd = {
+               .name = "usb_30_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc pcie_0_gdsc = {
+       .gdscr = 0x6b004,
+       .gds_hw_ctrl = 0x0,
+       .pd = {
+               .name = "pcie_0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct clk_hw *gcc_sdm660_hws[] = {
+       &xo.hw,
+       &gpll0_early_div.hw,
+       &gpll1_early_div.hw,
+};
+
+static struct clk_regmap *gcc_sdm660_clocks[] = {
+       [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr,
+       [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr,
+       [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr,
+       [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr,
+       [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr,
+       [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr,
+       [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr,
+       [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr,
+       [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+       [GCC_BIMC_HMSS_AXI_CLK] = &gcc_bimc_hmss_axi_clk.clkr,
+       [GCC_BIMC_MSS_Q6_AXI_CLK] = &gcc_bimc_mss_q6_axi_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr,
+       [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr,
+       [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CFG_NOC_USB2_AXI_CLK] = &gcc_cfg_noc_usb2_axi_clk.clkr,
+       [GCC_CFG_NOC_USB3_AXI_CLK] = &gcc_cfg_noc_usb3_axi_clk.clkr,
+       [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr,
+       [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_GPLL0_CLK] = &gcc_gpu_gpll0_clk.clkr,
+       [GCC_GPU_GPLL0_DIV_CLK] = &gcc_gpu_gpll0_div_clk.clkr,
+       [GCC_HMSS_DVM_BUS_CLK] = &gcc_hmss_dvm_bus_clk.clkr,
+       [GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr,
+       [GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr,
+       [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr,
+       [GCC_MMSS_NOC_CFG_AHB_CLK] = &gcc_mmss_noc_cfg_ahb_clk.clkr,
+       [GCC_MMSS_SYS_NOC_AXI_CLK] = &gcc_mmss_sys_noc_axi_clk.clkr,
+       [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+       [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
+       [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+       [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr,
+       [GCC_QSPI_SER_CLK] = &gcc_qspi_ser_clk.clkr,
+       [GCC_RX0_USB2_CLKREF_CLK] = &gcc_rx0_usb2_clkref_clk.clkr,
+       [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr,
+       [GCC_UFS_AXI_CLK] = &gcc_ufs_axi_clk.clkr,
+       [GCC_UFS_CLKREF_CLK] = &gcc_ufs_clkref_clk.clkr,
+       [GCC_UFS_ICE_CORE_CLK] = &gcc_ufs_ice_core_clk.clkr,
+       [GCC_UFS_PHY_AUX_CLK] = &gcc_ufs_phy_aux_clk.clkr,
+       [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr,
+       [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr,
+       [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr,
+       [GCC_UFS_UNIPRO_CORE_CLK] = &gcc_ufs_unipro_core_clk.clkr,
+       [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr,
+       [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr,
+       [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr,
+       [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
+       [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
+       [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
+       [GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr,
+       [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
+       [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+       [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
+       [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+       [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+       [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_EARLY] = &gpll0_early.clkr,
+       [GPLL1] = &gpll1.clkr,
+       [GPLL1_EARLY] = &gpll1_early.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [GPLL4_EARLY] = &gpll4_early.clkr,
+       [HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr,
+       [HMSS_GPLL4_CLK_SRC] = &hmss_gpll4_clk_src.clkr,
+       [HMSS_RBCPR_CLK_SRC] = &hmss_rbcpr_clk_src.clkr,
+       [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+       [QSPI_SER_CLK_SRC] = &qspi_ser_clk_src.clkr,
+       [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+       [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr,
+       [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+       [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
+       [UFS_ICE_CORE_CLK_SRC] = &ufs_ice_core_clk_src.clkr,
+       [UFS_PHY_AUX_CLK_SRC] = &ufs_phy_aux_clk_src.clkr,
+       [UFS_UNIPRO_CORE_CLK_SRC] = &ufs_unipro_core_clk_src.clkr,
+       [USB20_MASTER_CLK_SRC] = &usb20_master_clk_src.clkr,
+       [USB20_MOCK_UTMI_CLK_SRC] = &usb20_mock_utmi_clk_src.clkr,
+       [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
+       [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
+       [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
+};
+
+static struct gdsc *gcc_sdm660_gdscs[] = {
+       [UFS_GDSC] = &ufs_gdsc,
+       [USB_30_GDSC] = &usb_30_gdsc,
+       [PCIE_0_GDSC] = &pcie_0_gdsc,
+};
+
+static const struct qcom_reset_map gcc_sdm660_resets[] = {
+       [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
+       [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
+       [GCC_UFS_BCR] = { 0x75000 },
+       [GCC_USB3_DP_PHY_BCR] = { 0x50028 },
+       [GCC_USB3_PHY_BCR] = { 0x50020 },
+       [GCC_USB3PHY_PHY_BCR] = { 0x50024 },
+       [GCC_USB_20_BCR] = { 0x2f000 },
+       [GCC_USB_30_BCR] = { 0xf000 },
+       [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
+};
+
+static const struct regmap_config gcc_sdm660_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x94000,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_sdm660_desc = {
+       .config = &gcc_sdm660_regmap_config,
+       .clks = gcc_sdm660_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sdm660_clocks),
+       .resets = gcc_sdm660_resets,
+       .num_resets = ARRAY_SIZE(gcc_sdm660_resets),
+       .gdscs = gcc_sdm660_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sdm660_gdscs),
+};
+
+static const struct of_device_id gcc_sdm660_match_table[] = {
+       { .compatible = "qcom,gcc-sdm630" },
+       { .compatible = "qcom,gcc-sdm660" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sdm660_match_table);
+
+static int gcc_sdm660_probe(struct platform_device *pdev)
+{
+       int i, ret;
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &gcc_sdm660_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /*
+        * Set the HMSS_AHB_CLK_SLEEP_ENA bit to allow the hmss_ahb_clk to be
+        * turned off by hardware during certain apps low power modes.
+        */
+       ret = regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
+       if (ret)
+               return ret;
+
+       /* Register the hws */
+       for (i = 0; i < ARRAY_SIZE(gcc_sdm660_hws); i++) {
+               ret = devm_clk_hw_register(&pdev->dev, gcc_sdm660_hws[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap);
+}
+
+static struct platform_driver gcc_sdm660_driver = {
+       .probe          = gcc_sdm660_probe,
+       .driver         = {
+               .name   = "gcc-sdm660",
+               .of_match_table = gcc_sdm660_match_table,
+       },
+};
+
+static int __init gcc_sdm660_init(void)
+{
+       return platform_driver_register(&gcc_sdm660_driver);
+}
+core_initcall_sync(gcc_sdm660_init);
+
+static void __exit gcc_sdm660_exit(void)
+{
+       platform_driver_unregister(&gcc_sdm660_driver);
+}
+module_exit(gcc_sdm660_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("QCOM GCC sdm660 Driver");
index fa1a196350f1542ab5acf95528b7b329ecaddb98..f133b7f5652fbf5ab054379d795d251c58111b92 100644 (file)
@@ -99,22 +99,6 @@ static const char * const gcc_parent_names_4[] = {
        "core_bi_pll_test_se",
 };
 
-static const struct parent_map gcc_parent_map_5[] = {
-       { P_BI_TCXO, 0 },
-       { P_GPLL0_OUT_MAIN, 1 },
-       { P_GPLL4_OUT_MAIN, 5 },
-       { P_GPLL0_OUT_EVEN, 6 },
-       { P_CORE_BI_PLL_TEST_SE, 7 },
-};
-
-static const char * const gcc_parent_names_5[] = {
-       "bi_tcxo",
-       "gpll0",
-       "gpll4",
-       "gpll0_out_even",
-       "core_bi_pll_test_se",
-};
-
 static const struct parent_map gcc_parent_map_6[] = {
        { P_BI_TCXO, 0 },
        { P_GPLL0_OUT_MAIN, 1 },
@@ -356,6 +340,28 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = {
        },
 };
 
+static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+       F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+       .cmd_rcgr = 0x4b008,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qspi_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_qspi_core_clk_src",
+               .parent_names = gcc_parent_names_0,
+               .num_parents = 4,
+               .ops = &clk_rcg2_floor_ops,
+       },
+};
+
 static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
        F(9600000, P_BI_TCXO, 2, 0, 0),
        F(19200000, P_BI_TCXO, 1, 0, 0),
@@ -396,18 +402,27 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
        { }
 };
 
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = {
+       .name = "gcc_qupv3_wrap0_s0_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
+};
+
 static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
        .cmd_rcgr = 0x17034,
        .mnd_width = 16,
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s0_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = {
+       .name = "gcc_qupv3_wrap0_s1_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -416,12 +431,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s1_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = {
+       .name = "gcc_qupv3_wrap0_s2_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -430,12 +447,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s2_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = {
+       .name = "gcc_qupv3_wrap0_s3_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -444,12 +463,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s3_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = {
+       .name = "gcc_qupv3_wrap0_s4_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -458,12 +479,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s4_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = {
+       .name = "gcc_qupv3_wrap0_s5_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -472,12 +495,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s5_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = {
+       .name = "gcc_qupv3_wrap0_s6_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -486,12 +511,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s6_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = {
+       .name = "gcc_qupv3_wrap0_s7_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -500,12 +527,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap0_s7_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = {
+       .name = "gcc_qupv3_wrap1_s0_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -514,12 +543,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s0_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = {
+       .name = "gcc_qupv3_wrap1_s1_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -528,12 +559,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s1_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = {
+       .name = "gcc_qupv3_wrap1_s2_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -542,12 +575,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s2_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = {
+       .name = "gcc_qupv3_wrap1_s3_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -556,12 +591,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s3_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = {
+       .name = "gcc_qupv3_wrap1_s4_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -570,12 +607,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s4_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = {
+       .name = "gcc_qupv3_wrap1_s5_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -584,12 +623,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s5_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = {
+       .name = "gcc_qupv3_wrap1_s6_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
@@ -598,12 +639,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s6_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = {
+       .name = "gcc_qupv3_wrap1_s7_clk_src",
+       .parent_names = gcc_parent_names_0,
+       .num_parents = 4,
+       .ops = &clk_rcg2_shared_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
@@ -612,12 +655,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
        .hid_width = 5,
        .parent_map = gcc_parent_map_0,
        .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gcc_qupv3_wrap1_s7_clk_src",
-               .parent_names = gcc_parent_names_0,
-               .num_parents = 4,
-               .ops = &clk_rcg2_shared_ops,
-       },
+       .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_init,
 };
 
 static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
@@ -1933,6 +1971,37 @@ static struct clk_branch gcc_qmip_video_ahb_clk = {
        },
 };
 
+static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = {
+       .halt_reg = 0x4b000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4b000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_cnoc_periph_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qspi_core_clk = {
+       .halt_reg = 0x4b004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4b004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_core_clk",
+                       .parent_names = (const char *[]){
+                               "gcc_qspi_core_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
        .halt_reg = 0x17030,
        .halt_check = BRANCH_HALT_VOTED,
@@ -3381,6 +3450,9 @@ static struct clk_regmap *gcc_sdm845_clocks[] = {
        [GPLL4] = &gpll4.clkr,
        [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr,
        [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+       [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+       [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+       [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
 };
 
 static const struct qcom_reset_map gcc_sdm845_resets[] = {
@@ -3458,9 +3530,29 @@ static const struct of_device_id gcc_sdm845_match_table[] = {
 };
 MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table);
 
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk),
+};
+
 static int gcc_sdm845_probe(struct platform_device *pdev)
 {
        struct regmap *regmap;
+       int ret;
 
        regmap = qcom_cc_map(pdev, &gcc_sdm845_desc);
        if (IS_ERR(regmap))
@@ -3470,6 +3562,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev)
        regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3);
        regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
 
+       ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+                                       ARRAY_SIZE(gcc_dfs_clocks));
+       if (ret)
+               return ret;
+
        return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap);
 }
 
diff --git a/drivers/clk/qcom/hfpll.c b/drivers/clk/qcom/hfpll.c
new file mode 100644 (file)
index 0000000..a6de710
--- /dev/null
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include "clk-regmap.h"
+#include "clk-hfpll.h"
+
+static const struct hfpll_data hdata = {
+       .mode_reg = 0x00,
+       .l_reg = 0x04,
+       .m_reg = 0x08,
+       .n_reg = 0x0c,
+       .user_reg = 0x10,
+       .config_reg = 0x14,
+       .config_val = 0x430405d,
+       .status_reg = 0x1c,
+       .lock_bit = 16,
+
+       .user_val = 0x8,
+       .user_vco_mask = 0x100000,
+       .low_vco_max_rate = 1248000000,
+       .min_rate = 537600000UL,
+       .max_rate = 2900000000UL,
+};
+
+static const struct of_device_id qcom_hfpll_match_table[] = {
+       { .compatible = "qcom,hfpll" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table);
+
+static const struct regmap_config hfpll_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x30,
+       .fast_io        = true,
+};
+
+static int qcom_hfpll_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct device *dev = &pdev->dev;
+       void __iomem *base;
+       struct regmap *regmap;
+       struct clk_hfpll *h;
+       struct clk_init_data init = {
+               .parent_names = (const char *[]){ "xo" },
+               .num_parents = 1,
+               .ops = &clk_ops_hfpll,
+       };
+
+       h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
+       if (!h)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       if (of_property_read_string_index(dev->of_node, "clock-output-names",
+                                         0, &init.name))
+               return -ENODEV;
+
+       h->d = &hdata;
+       h->clkr.hw.init = &init;
+       spin_lock_init(&h->lock);
+
+       return devm_clk_register_regmap(&pdev->dev, &h->clkr);
+}
+
+static struct platform_driver qcom_hfpll_driver = {
+       .probe          = qcom_hfpll_probe,
+       .driver         = {
+               .name   = "qcom-hfpll",
+               .of_match_table = qcom_hfpll_match_table,
+       },
+};
+module_platform_driver(qcom_hfpll_driver);
+
+MODULE_DESCRIPTION("QCOM HFPLL Clock Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:qcom-hfpll");
diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c
new file mode 100644 (file)
index 0000000..8590b5e
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+static const char *aux_parents[] = {
+       "pll8_vote",
+       "pxo",
+};
+
+static unsigned int aux_parent_map[] = {
+       3,
+       0,
+};
+
+static const struct of_device_id kpss_xcc_match_table[] = {
+       { .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL },
+       { .compatible = "qcom,kpss-gcc" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
+
+static int kpss_xcc_driver_probe(struct platform_device *pdev)
+{
+       const struct of_device_id *id;
+       struct clk *clk;
+       struct resource *res;
+       void __iomem *base;
+       const char *name;
+
+       id = of_match_device(kpss_xcc_match_table, &pdev->dev);
+       if (!id)
+               return -ENODEV;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       if (id->data) {
+               if (of_property_read_string_index(pdev->dev.of_node,
+                                                 "clock-output-names",
+                                                 0, &name))
+                       return -ENODEV;
+               base += 0x14;
+       } else {
+               name = "acpu_l2_aux";
+               base += 0x28;
+       }
+
+       clk = clk_register_mux_table(&pdev->dev, name, aux_parents,
+                                    ARRAY_SIZE(aux_parents), 0, base, 0, 0x3,
+                                    0, aux_parent_map, NULL);
+
+       platform_set_drvdata(pdev, clk);
+
+       return PTR_ERR_OR_ZERO(clk);
+}
+
+static int kpss_xcc_driver_remove(struct platform_device *pdev)
+{
+       clk_unregister_mux(platform_get_drvdata(pdev));
+       return 0;
+}
+
+static struct platform_driver kpss_xcc_driver = {
+       .probe = kpss_xcc_driver_probe,
+       .remove = kpss_xcc_driver_remove,
+       .driver = {
+               .name = "kpss-xcc",
+               .of_match_table = kpss_xcc_match_table,
+       },
+};
+module_platform_driver(kpss_xcc_driver);
+
+MODULE_DESCRIPTION("Krait Processor Sub System (KPSS) Clock Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:kpss-xcc");
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
new file mode 100644 (file)
index 0000000..4d4b657
--- /dev/null
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+
+#include "clk-krait.h"
+
+static unsigned int sec_mux_map[] = {
+       2,
+       0,
+};
+
+static unsigned int pri_mux_map[] = {
+       1,
+       2,
+       0,
+};
+
+/*
+ * Notifier function for switching the muxes to safe parent
+ * while the hfpll is getting reprogrammed.
+ */
+static int krait_notifier_cb(struct notifier_block *nb,
+                            unsigned long event,
+                            void *data)
+{
+       int ret = 0;
+       struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk,
+                                                clk_nb);
+       /* Switch to safe parent */
+       if (event == PRE_RATE_CHANGE) {
+               mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw);
+               ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel);
+               mux->reparent = false;
+       /*
+        * By the time POST_RATE_CHANGE notifier is called,
+        * clk framework itself would have changed the parent for the new rate.
+        * Only otherwise, put back to the old parent.
+        */
+       } else if (event == POST_RATE_CHANGE) {
+               if (!mux->reparent)
+                       ret = krait_mux_clk_ops.set_parent(&mux->hw,
+                                                          mux->old_index);
+       }
+
+       return notifier_from_errno(ret);
+}
+
+static int krait_notifier_register(struct device *dev, struct clk *clk,
+                                  struct krait_mux_clk *mux)
+{
+       int ret = 0;
+
+       mux->clk_nb.notifier_call = krait_notifier_cb;
+       ret = clk_notifier_register(clk, &mux->clk_nb);
+       if (ret)
+               dev_err(dev, "failed to register clock notifier: %d\n", ret);
+
+       return ret;
+}
+
+static int
+krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
+{
+       struct krait_div2_clk *div;
+       struct clk_init_data init = {
+               .num_parents = 1,
+               .ops = &krait_div2_clk_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       };
+       const char *p_names[1];
+       struct clk *clk;
+
+       div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
+       if (!div)
+               return -ENOMEM;
+
+       div->width = 2;
+       div->shift = 6;
+       div->lpl = id >= 0;
+       div->offset = offset;
+       div->hw.init = &init;
+
+       init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
+       if (!init.name)
+               return -ENOMEM;
+
+       init.parent_names = p_names;
+       p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
+       if (!p_names[0]) {
+               kfree(init.name);
+               return -ENOMEM;
+       }
+
+       clk = devm_clk_register(dev, &div->hw);
+       kfree(p_names[0]);
+       kfree(init.name);
+
+       return PTR_ERR_OR_ZERO(clk);
+}
+
+static int
+krait_add_sec_mux(struct device *dev, int id, const char *s,
+                 unsigned int offset, bool unique_aux)
+{
+       int ret;
+       struct krait_mux_clk *mux;
+       static const char *sec_mux_list[] = {
+               "acpu_aux",
+               "qsb",
+       };
+       struct clk_init_data init = {
+               .parent_names = sec_mux_list,
+               .num_parents = ARRAY_SIZE(sec_mux_list),
+               .ops = &krait_mux_clk_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       };
+       struct clk *clk;
+
+       mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+       if (!mux)
+               return -ENOMEM;
+
+       mux->offset = offset;
+       mux->lpl = id >= 0;
+       mux->mask = 0x3;
+       mux->shift = 2;
+       mux->parent_map = sec_mux_map;
+       mux->hw.init = &init;
+       mux->safe_sel = 0;
+
+       init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
+       if (!init.name)
+               return -ENOMEM;
+
+       if (unique_aux) {
+               sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
+               if (!sec_mux_list[0]) {
+                       clk = ERR_PTR(-ENOMEM);
+                       goto err_aux;
+               }
+       }
+
+       clk = devm_clk_register(dev, &mux->hw);
+
+       ret = krait_notifier_register(dev, clk, mux);
+       if (ret)
+               goto unique_aux;
+
+unique_aux:
+       if (unique_aux)
+               kfree(sec_mux_list[0]);
+err_aux:
+       kfree(init.name);
+       return PTR_ERR_OR_ZERO(clk);
+}
+
+static struct clk *
+krait_add_pri_mux(struct device *dev, int id, const char *s,
+                 unsigned int offset)
+{
+       int ret;
+       struct krait_mux_clk *mux;
+       const char *p_names[3];
+       struct clk_init_data init = {
+               .parent_names = p_names,
+               .num_parents = ARRAY_SIZE(p_names),
+               .ops = &krait_mux_clk_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       };
+       struct clk *clk;
+
+       mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+       if (!mux)
+               return ERR_PTR(-ENOMEM);
+
+       mux->mask = 0x3;
+       mux->shift = 0;
+       mux->offset = offset;
+       mux->lpl = id >= 0;
+       mux->parent_map = pri_mux_map;
+       mux->hw.init = &init;
+       mux->safe_sel = 2;
+
+       init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
+       if (!init.name)
+               return ERR_PTR(-ENOMEM);
+
+       p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
+       if (!p_names[0]) {
+               clk = ERR_PTR(-ENOMEM);
+               goto err_p0;
+       }
+
+       p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
+       if (!p_names[1]) {
+               clk = ERR_PTR(-ENOMEM);
+               goto err_p1;
+       }
+
+       p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
+       if (!p_names[2]) {
+               clk = ERR_PTR(-ENOMEM);
+               goto err_p2;
+       }
+
+       clk = devm_clk_register(dev, &mux->hw);
+
+       ret = krait_notifier_register(dev, clk, mux);
+       if (ret)
+               goto err_p3;
+err_p3:
+       kfree(p_names[2]);
+err_p2:
+       kfree(p_names[1]);
+err_p1:
+       kfree(p_names[0]);
+err_p0:
+       kfree(init.name);
+       return clk;
+}
+
+/* id < 0 for L2, otherwise id == physical CPU number */
+static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
+{
+       int ret;
+       unsigned int offset;
+       void *p = NULL;
+       const char *s;
+       struct clk *clk;
+
+       if (id >= 0) {
+               offset = 0x4501 + (0x1000 * id);
+               s = p = kasprintf(GFP_KERNEL, "%d", id);
+               if (!s)
+                       return ERR_PTR(-ENOMEM);
+       } else {
+               offset = 0x500;
+               s = "_l2";
+       }
+
+       ret = krait_add_div(dev, id, s, offset);
+       if (ret) {
+               clk = ERR_PTR(ret);
+               goto err;
+       }
+
+       ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
+       if (ret) {
+               clk = ERR_PTR(ret);
+               goto err;
+       }
+
+       clk = krait_add_pri_mux(dev, id, s, offset);
+err:
+       kfree(p);
+       return clk;
+}
+
+static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data)
+{
+       unsigned int idx = clkspec->args[0];
+       struct clk **clks = data;
+
+       if (idx >= 5) {
+               pr_err("%s: invalid clock index %d\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return clks[idx] ? : ERR_PTR(-ENODEV);
+}
+
+static const struct of_device_id krait_cc_match_table[] = {
+       { .compatible = "qcom,krait-cc-v1", (void *)1UL },
+       { .compatible = "qcom,krait-cc-v2" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, krait_cc_match_table);
+
+static int krait_cc_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       const struct of_device_id *id;
+       unsigned long cur_rate, aux_rate;
+       int cpu;
+       struct clk *clk;
+       struct clk **clks;
+       struct clk *l2_pri_mux_clk;
+
+       id = of_match_device(krait_cc_match_table, dev);
+       if (!id)
+               return -ENODEV;
+
+       /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
+       clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       if (!id->data) {
+               clk = clk_register_fixed_factor(dev, "acpu_aux",
+                                               "gpll0_vote", 0, 1, 2);
+               if (IS_ERR(clk))
+                       return PTR_ERR(clk);
+       }
+
+       /* Krait configurations have at most 4 CPUs and one L2 */
+       clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL);
+       if (!clks)
+               return -ENOMEM;
+
+       for_each_possible_cpu(cpu) {
+               clk = krait_add_clks(dev, cpu, id->data);
+               if (IS_ERR(clk))
+                       return PTR_ERR(clk);
+               clks[cpu] = clk;
+       }
+
+       l2_pri_mux_clk = krait_add_clks(dev, -1, id->data);
+       if (IS_ERR(l2_pri_mux_clk))
+               return PTR_ERR(l2_pri_mux_clk);
+       clks[4] = l2_pri_mux_clk;
+
+       /*
+        * We don't want the CPU or L2 clocks to be turned off at late init
+        * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the
+        * refcount of these clocks. Any cpufreq/hotplug manager can assume
+        * that the clocks have already been prepared and enabled by the time
+        * they take over.
+        */
+       for_each_online_cpu(cpu) {
+               clk_prepare_enable(l2_pri_mux_clk);
+               WARN(clk_prepare_enable(clks[cpu]),
+                    "Unable to turn on CPU%d clock", cpu);
+       }
+
+       /*
+        * Force reinit of HFPLLs and muxes to overwrite any potential
+        * incorrect configuration of HFPLLs and muxes by the bootloader.
+        * While at it, also make sure the cores are running at known rates
+        * and print the current rate.
+        *
+        * The clocks are set to aux clock rate first to make sure the
+        * secondary mux is not sourcing off of QSB. The rate is then set to
+        * two different rates to force a HFPLL reinit under all
+        * circumstances.
+        */
+       cur_rate = clk_get_rate(l2_pri_mux_clk);
+       aux_rate = 384000000;
+       if (cur_rate == 1) {
+               pr_info("L2 @ QSB rate. Forcing new rate.\n");
+               cur_rate = aux_rate;
+       }
+       clk_set_rate(l2_pri_mux_clk, aux_rate);
+       clk_set_rate(l2_pri_mux_clk, 2);
+       clk_set_rate(l2_pri_mux_clk, cur_rate);
+       pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
+       for_each_possible_cpu(cpu) {
+               clk = clks[cpu];
+               cur_rate = clk_get_rate(clk);
+               if (cur_rate == 1) {
+                       pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu);
+                       cur_rate = aux_rate;
+               }
+
+               clk_set_rate(clk, aux_rate);
+               clk_set_rate(clk, 2);
+               clk_set_rate(clk, cur_rate);
+               pr_info("CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000);
+       }
+
+       of_clk_add_provider(dev->of_node, krait_of_get, clks);
+
+       return 0;
+}
+
+static struct platform_driver krait_cc_driver = {
+       .probe = krait_cc_probe,
+       .driver = {
+               .name = "krait-cc",
+               .of_match_table = krait_cc_match_table,
+       },
+};
+module_platform_driver(krait_cc_driver);
+
+MODULE_DESCRIPTION("Krait CPU Clock Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:krait-cc");
index 9022bbe1297e7f3c2c351ff55e854227f3d4049b..b879e3e3a6b426aed8e9d3729d0c9cee48bcde15 100644 (file)
@@ -1,13 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+
 config CLK_RENESAS
        bool "Renesas SoC clock support" if COMPILE_TEST && !ARCH_RENESAS
        default y if ARCH_RENESAS
        select CLK_EMEV2 if ARCH_EMEV2
        select CLK_RZA1 if ARCH_R7S72100
+       select CLK_R7S9210 if ARCH_R7S9210
        select CLK_R8A73A4 if ARCH_R8A73A4
        select CLK_R8A7740 if ARCH_R8A7740
-       select CLK_R8A7743 if ARCH_R8A7743
+       select CLK_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744
        select CLK_R8A7745 if ARCH_R8A7745
        select CLK_R8A77470 if ARCH_R8A77470
+       select CLK_R8A774A1 if ARCH_R8A774A1
+       select CLK_R8A774C0 if ARCH_R8A774C0
        select CLK_R8A7778 if ARCH_R8A7778
        select CLK_R8A7779 if ARCH_R8A7779
        select CLK_R8A7790 if ARCH_R8A7790
@@ -45,6 +50,10 @@ config CLK_RZA1
        bool "RZ/A1H clock support" if COMPILE_TEST
        select CLK_RENESAS_CPG_MSTP
 
+config CLK_R7S9210
+       bool "RZ/A2 clock support" if COMPILE_TEST
+       select CLK_RENESAS_CPG_MSSR
+
 config CLK_R8A73A4
        bool "R-Mobile APE6 clock support" if COMPILE_TEST
        select CLK_RENESAS_CPG_MSTP
@@ -67,6 +76,14 @@ config CLK_R8A77470
        bool "RZ/G1C clock support" if COMPILE_TEST
        select CLK_RCAR_GEN2_CPG
 
+config CLK_R8A774A1
+       bool "RZ/G2M clock support" if COMPILE_TEST
+       select CLK_RCAR_GEN3_CPG
+
+config CLK_R8A774C0
+       bool "RZ/G2E clock support" if COMPILE_TEST
+       select CLK_RCAR_GEN3_CPG
+
 config CLK_R8A7778
        bool "R-Car M1A clock support" if COMPILE_TEST
        select CLK_RENESAS_CPG_MSTP
index e4aa3d6143d2436a86f2daf997da8b0eb3a45f2f..c793e3cc9452af5fdbd7335302787633e7ab175c 100644 (file)
@@ -2,11 +2,14 @@
 # SoC
 obj-$(CONFIG_CLK_EMEV2)                        += clk-emev2.o
 obj-$(CONFIG_CLK_RZA1)                 += clk-rz.o
+obj-$(CONFIG_CLK_R7S9210)              += r7s9210-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A73A4)              += clk-r8a73a4.o
 obj-$(CONFIG_CLK_R8A7740)              += clk-r8a7740.o
 obj-$(CONFIG_CLK_R8A7743)              += r8a7743-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7745)              += r8a7745-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77470)             += r8a77470-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A774A1)             += r8a774a1-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A774C0)             += r8a774c0-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A7778)              += clk-r8a7778.o
 obj-$(CONFIG_CLK_R8A7779)              += clk-r8a7779.o
 obj-$(CONFIG_CLK_R8A7790)              += r8a7790-cpg-mssr.o
index 9febbf42c3df6979a8c667c8d08a1e7846acba8d..57c9341643065a9234fcf80514b6eb3a79e639e9 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7790 Common Clock Framework support
  *
  * Copyright (C) 2013  Renesas Solutions Corp.
  *
  * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -312,8 +309,8 @@ static void __init cpg_div6_clock_init(struct device_node *np)
 
        num_parents = of_clk_get_parent_count(np);
        if (num_parents < 1) {
-               pr_err("%s: no parent found for %s DIV6 clock\n",
-                      __func__, np->name);
+               pr_err("%s: no parent found for %pOFn DIV6 clock\n",
+                      __func__, np);
                return;
        }
 
@@ -324,8 +321,8 @@ static void __init cpg_div6_clock_init(struct device_node *np)
 
        reg = of_iomap(np, 0);
        if (reg == NULL) {
-               pr_err("%s: failed to map %s DIV6 clock register\n",
-                      __func__, np->name);
+               pr_err("%s: failed to map %pOFn DIV6 clock register\n",
+                      __func__, np);
                goto error;
        }
 
@@ -337,8 +334,8 @@ static void __init cpg_div6_clock_init(struct device_node *np)
 
        clk = cpg_div6_register(clk_name, num_parents, parent_names, reg, NULL);
        if (IS_ERR(clk)) {
-               pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
-                      __func__, np->name, PTR_ERR(clk));
+               pr_err("%s: failed to register %pOFn DIV6 clock (%ld)\n",
+                      __func__, np, PTR_ERR(clk));
                goto error;
        }
 
index a91825471c79acd28f68ea5f0f2c998d54a571d9..7807b30a5bbb590139a5c4d785e10699325253bc 100644 (file)
@@ -1,21 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * EMMA Mobile EV2 common clock framework support
  *
  * Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
  * Copyright (C) 2012 Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
@@ -86,8 +74,8 @@ static void __init emev2_smu_clkdiv_init(struct device_node *np)
        clk = clk_register_divider(NULL, np->name, parent_name, 0,
                                   smu_base + reg[0], reg[1], 8, 0, &lock);
        of_clk_add_provider(np, of_clk_src_simple_get, clk);
-       clk_register_clkdev(clk, np->name, NULL);
-       pr_debug("## %s %s %p\n", __func__, np->name, clk);
+       clk_register_clkdev(clk, np->full_name, NULL);
+       pr_debug("## %s %pOFn %p\n", __func__, np, clk);
 }
 CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv",
                emev2_smu_clkdiv_init);
@@ -104,7 +92,7 @@ static void __init emev2_smu_gclk_init(struct device_node *np)
        clk = clk_register_gate(NULL, np->name, parent_name, 0,
                                smu_base + reg[0], reg[1], 0, &lock);
        of_clk_add_provider(np, of_clk_src_simple_get, clk);
-       clk_register_clkdev(clk, np->name, NULL);
-       pr_debug("## %s %s %p\n", __func__, np->name, clk);
+       clk_register_clkdev(clk, np->full_name, NULL);
+       pr_debug("## %s %pOFn %p\n", __func__, np, clk);
 }
 CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init);
index e82adcb16a52a3b790c34fc2a49079615a7bf907..1c1768c2cc8251cd2715839f464773ce5b2eb0b5 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car MSTP clocks
  *
@@ -5,10 +6,6 @@
  * Copyright (C) 2015 Glider bvba
  *
  * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk.h>
@@ -239,8 +236,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
                        break;
 
                if (clkidx >= MSTP_MAX_CLOCKS) {
-                       pr_err("%s: invalid clock %s %s index %u\n",
-                              __func__, np->name, name, clkidx);
+                       pr_err("%s: invalid clock %pOFn %s index %u\n",
+                              __func__, np, name, clkidx);
                        continue;
                }
 
@@ -259,8 +256,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
                         */
                        clk_register_clkdev(clks[clkidx], name, NULL);
                } else {
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clks[clkidx]));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clks[clkidx]));
                }
        }
 
index 7b903ce4c9015ad76a476c7f45707bd5960d390b..2719c248c67beb5fe1317c1c3bdd41ee5e2067f4 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a73a4 Core CPG Clocks
  *
  * Copyright (C) 2014  Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -228,8 +225,8 @@ static void __init r8a73a4_cpg_clocks_init(struct device_node *np)
 
                clk = r8a73a4_cpg_register_clock(np, cpg, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
index a7a30d2eca418f6e15febe5cf47aac91d426ec32..5967656c13cca91fd1b2822cd06ae27c407b906e 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7740 Core CPG Clocks
  *
  * Copyright (C) 2014  Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -187,8 +184,8 @@ static void __init r8a7740_cpg_clocks_init(struct device_node *np)
 
                clk = r8a7740_cpg_register_clock(np, cpg, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
index 886a8380e91247a199f2852177b9fda5cff8f0ad..3ccc53685bdd22f57d95a2ed60daa64a3ff9f1ff 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7778 Core CPG Clocks
  *
  * Copyright (C) 2014  Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -130,8 +127,8 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np)
 
                clk = r8a7778_cpg_register_clock(np, cpg, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
index 5adcca4656c33303e9630f6a3624b09b50242ddb..9f3b5522eef59a1269c679bd07735bbef511b6b1 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7779 Core CPG Clocks
  *
  * Copyright (C) 2013, 2014 Horms Solutions Ltd.
  *
  * Contact: Simon Horman <horms@verge.net.au>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -164,8 +161,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
                clk = r8a7779_cpg_register_clock(np, cpg, config,
                                                 plla_mult, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
index bccd62f2cb092fac27416764d4eba89d98e305ba..2913b414815748632686b6a1e980e84d5ce48c0d 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * rcar_gen2 Core CPG Clocks
  *
  * Copyright (C) 2013  Ideas On Board SPRL
  *
  * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -445,8 +442,8 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 
                clk = rcar_gen2_cpg_register_clock(np, cpg, config, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
index ac2f86d626b694be3824c7465c7e7aae3897a9af..3cda53a97f4e6b4a0d5b90bd2d70c279e8aa83e1 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * RZ/A1 Core CPG Clocks
  *
  * Copyright (C) 2013 Ideas On Board SPRL
  * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -113,8 +110,8 @@ static void __init rz_cpg_clocks_init(struct device_node *np)
 
                clk = rz_cpg_register_clock(np, cpg, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
index bab33610eb6caedfd5bd41e60874fea0cb00a906..dc8ffc7c727a73a226912e826382e466e8049b0e 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * sh73a0 Core CPG Clocks
  *
  * Copyright (C) 2014  Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk-provider.h>
@@ -206,8 +203,8 @@ static void __init sh73a0_cpg_clocks_init(struct device_node *np)
 
                clk = sh73a0_cpg_register_clock(np, cpg, name);
                if (IS_ERR(clk))
-                       pr_err("%s: failed to register %s %s clock (%ld)\n",
-                              __func__, np->name, name, PTR_ERR(clk));
+                       pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
+                              __func__, np, name, PTR_ERR(clk));
                else
                        cpg->data.clks[i] = clk;
        }
diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c
new file mode 100644 (file)
index 0000000..5135f13
--- /dev/null
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * R7S9210 Clock Pulse Generator / Module Standby
+ *
+ * Based on r8a7795-cpg-mssr.c
+ *
+ * Copyright (C) 2018 Chris Brandt
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <dt-bindings/clock/r7s9210-cpg-mssr.h>
+#include "renesas-cpg-mssr.h"
+
+#define CPG_FRQCR      0x00
+
+static u8 cpg_mode;
+
+/* Internal Clock ratio table */
+static const struct {
+       unsigned int i;
+       unsigned int g;
+       unsigned int b;
+       unsigned int p1;
+       /* p0 is always 32 */;
+} ratio_tab[5] = {     /* I,  G,  B, P1 */
+                       {  2,  4,  8, 16},      /* FRQCR = 0x012 */
+                       {  4,  4,  8, 16},      /* FRQCR = 0x112 */
+                       {  8,  4,  8, 16},      /* FRQCR = 0x212 */
+                       { 16,  8, 16, 16},      /* FRQCR = 0x322 */
+                       { 16, 16, 32, 32},      /* FRQCR = 0x333 */
+                       };
+
+enum rz_clk_types {
+       CLK_TYPE_RZA_MAIN = CLK_TYPE_CUSTOM,
+       CLK_TYPE_RZA_PLL,
+};
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R7S9210_CLK_P0,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static struct cpg_core_clk r7s9210_early_core_clks[] = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",     CLK_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll",       CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN),
+
+       /* Core Clock Outputs */
+       DEF_FIXED("p1c",    R7S9210_CLK_P1C,   CLK_PLL,         16, 1),
+};
+
+static const struct mssr_mod_clk r7s9210_early_mod_clks[] __initconst = {
+       DEF_MOD_STB("ostm2",     34,    R7S9210_CLK_P1C),
+       DEF_MOD_STB("ostm1",     35,    R7S9210_CLK_P1C),
+       DEF_MOD_STB("ostm0",     36,    R7S9210_CLK_P1C),
+};
+
+static struct cpg_core_clk r7s9210_core_clks[] = {
+       /* Core Clock Outputs */
+       DEF_FIXED("i",      R7S9210_CLK_I,     CLK_PLL,          2, 1),
+       DEF_FIXED("g",      R7S9210_CLK_G,     CLK_PLL,          4, 1),
+       DEF_FIXED("b",      R7S9210_CLK_B,     CLK_PLL,          8, 1),
+       DEF_FIXED("p1",     R7S9210_CLK_P1,    CLK_PLL,         16, 1),
+       DEF_FIXED("p0",     R7S9210_CLK_P0,    CLK_PLL,         32, 1),
+};
+
+static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = {
+       DEF_MOD_STB("scif4",     43,    R7S9210_CLK_P1C),
+       DEF_MOD_STB("scif3",     44,    R7S9210_CLK_P1C),
+       DEF_MOD_STB("scif2",     45,    R7S9210_CLK_P1C),
+       DEF_MOD_STB("scif1",     46,    R7S9210_CLK_P1C),
+       DEF_MOD_STB("scif0",     47,    R7S9210_CLK_P1C),
+
+       DEF_MOD_STB("ether1",    64,    R7S9210_CLK_B),
+       DEF_MOD_STB("ether0",    65,    R7S9210_CLK_B),
+
+       DEF_MOD_STB("i2c3",      84,    R7S9210_CLK_P1),
+       DEF_MOD_STB("i2c2",      85,    R7S9210_CLK_P1),
+       DEF_MOD_STB("i2c1",      86,    R7S9210_CLK_P1),
+       DEF_MOD_STB("i2c0",      87,    R7S9210_CLK_P1),
+
+       DEF_MOD_STB("spi2",      95,    R7S9210_CLK_P1),
+       DEF_MOD_STB("spi1",      96,    R7S9210_CLK_P1),
+       DEF_MOD_STB("spi0",      97,    R7S9210_CLK_P1),
+};
+
+/* The clock dividers in the table vary based on DT and register settings */
+static void __init r7s9210_update_clk_table(struct clk *extal_clk,
+                                           void __iomem *base)
+{
+       int i;
+       u16 frqcr;
+       u8 index;
+
+       /* If EXTAL is above 12MHz, then we know it is Mode 1 */
+       if (clk_get_rate(extal_clk) > 12000000)
+               cpg_mode = 1;
+
+       frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF;
+       if (frqcr == 0x012)
+               index = 0;
+       else if (frqcr == 0x112)
+               index = 1;
+       else if (frqcr == 0x212)
+               index = 2;
+       else if (frqcr == 0x322)
+               index = 3;
+       else if (frqcr == 0x333)
+               index = 4;
+       else
+               BUG_ON(1);      /* Illegal FRQCR value */
+
+       for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) {
+               switch (r7s9210_core_clks[i].id) {
+               case R7S9210_CLK_I:
+                       r7s9210_core_clks[i].div = ratio_tab[index].i;
+                       break;
+               case R7S9210_CLK_G:
+                       r7s9210_core_clks[i].div = ratio_tab[index].g;
+                       break;
+               case R7S9210_CLK_B:
+                       r7s9210_core_clks[i].div = ratio_tab[index].b;
+                       break;
+               case R7S9210_CLK_P1:
+               case R7S9210_CLK_P1C:
+                       r7s9210_core_clks[i].div = ratio_tab[index].p1;
+                       break;
+               case R7S9210_CLK_P0:
+                       r7s9210_core_clks[i].div = 32;
+                       break;
+               }
+       }
+}
+
+struct clk * __init rza2_cpg_clk_register(struct device *dev,
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
+{
+       struct clk *parent;
+       unsigned int mult = 1;
+       unsigned int div = 1;
+
+       parent = clks[core->parent];
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       switch (core->id) {
+       case CLK_MAIN:
+               break;
+
+       case CLK_PLL:
+               if (cpg_mode)
+                       mult = 44;      /* Divider 1 is 1/2 */
+               else
+                       mult = 88;      /* Divider 1 is 1 */
+               break;
+
+       default:
+               return ERR_PTR(-EINVAL);
+       }
+
+       if (core->id == CLK_MAIN)
+               r7s9210_update_clk_table(parent, base);
+
+       return clk_register_fixed_factor(NULL, core->name,
+                                        __clk_get_name(parent), 0, mult, div);
+}
+
+const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = {
+       /* Early Clocks */
+       .early_core_clks = r7s9210_early_core_clks,
+       .num_early_core_clks = ARRAY_SIZE(r7s9210_early_core_clks),
+       .early_mod_clks = r7s9210_early_mod_clks,
+       .num_early_mod_clks = ARRAY_SIZE(r7s9210_early_mod_clks),
+
+       /* Core Clocks */
+       .core_clks = r7s9210_core_clks,
+       .num_core_clks = ARRAY_SIZE(r7s9210_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r7s9210_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r7s9210_mod_clks),
+       .num_hw_mod_clks = 11 * 32, /* includes STBCR0 which doesn't exist */
+
+       /* Callbacks */
+       .cpg_clk_register = rza2_cpg_clk_register,
+
+       /* RZ/A2 has Standby Control Registers */
+       .stbyctrl = true,
+};
+
+static void __init r7s9210_cpg_mssr_early_init(struct device_node *np)
+{
+       cpg_mssr_early_init(np, &r7s9210_cpg_mssr_info);
+}
+
+CLK_OF_DECLARE_DRIVER(cpg_mstp_clks, "renesas,r7s9210-cpg-mssr",
+                     r7s9210_cpg_mssr_early_init);
index 011c170ec3f95d65f7a83384b42431bcbfc86e55..c01d9af2525a181a3614a40b2444138126310fa5 100644 (file)
@@ -1,16 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7743 Clock Pulse Generator / Module Standby and Software Reset
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation; of the License.
  */
 
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/of.h>
 #include <linux/soc/renesas/rcar-rst.h>
 
 #include <dt-bindings/clock/r8a7743-cpg-mssr.h>
@@ -37,7 +35,7 @@ enum clk_ids {
        MOD_CLK_BASE
 };
 
-static const struct cpg_core_clk r8a7743_core_clks[] __initconst = {
+static struct cpg_core_clk r8a7743_core_clks[] __initdata = {
        /* External Clock Inputs */
        DEF_INPUT("extal",      CLK_EXTAL),
        DEF_INPUT("usb_extal",  CLK_USB_EXTAL),
@@ -238,6 +236,8 @@ static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
 static int __init r8a7743_cpg_mssr_init(struct device *dev)
 {
        const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
+       struct device_node *np = dev->of_node;
+       unsigned int i;
        u32 cpg_mode;
        int error;
 
@@ -247,6 +247,14 @@ static int __init r8a7743_cpg_mssr_init(struct device *dev)
 
        cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
 
+       if (of_device_is_compatible(np, "renesas,r8a7744-cpg-mssr")) {
+               /* RZ/G1N uses a 1/5 divider for ZG */
+               for (i = 0; i < ARRAY_SIZE(r8a7743_core_clks); i++)
+                       if (r8a7743_core_clks[i].id == R8A7743_CLK_ZG) {
+                               r8a7743_core_clks[i].div = 5;
+                               break;
+                       }
+       }
        return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode);
 }
 
index 4b0a9243b7481176ca2c8701451f03421bd3de59..493874e5ebeeb6bb50aef7cb780289d406ea5c8f 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7745 Clock Pulse Generator / Module Standby and Software Reset
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation; of the License.
  */
 
 #include <linux/device.h>
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
new file mode 100644 (file)
index 0000000..b0da342
--- /dev/null
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a774a1 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * Based on r8a7796-cpg-mssr.c
+ *
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a774a1-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A774A1_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_EXTALR,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL2,
+       CLK_PLL3,
+       CLK_PLL4,
+       CLK_PLL1_DIV2,
+       CLK_PLL1_DIV4,
+       CLK_S0,
+       CLK_S1,
+       CLK_S2,
+       CLK_S3,
+       CLK_SDSRC,
+       CLK_RINT,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",      CLK_EXTAL),
+       DEF_INPUT("extalr",     CLK_EXTALR),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
+       DEF_BASE(".pll2",       CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
+       DEF_BASE(".pll4",       CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2,     CLK_PLL1,       2, 1),
+       DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4,     CLK_PLL1_DIV2,  2, 1),
+       DEF_FIXED(".s0",        CLK_S0,            CLK_PLL1_DIV2,  2, 1),
+       DEF_FIXED(".s1",        CLK_S1,            CLK_PLL1_DIV2,  3, 1),
+       DEF_FIXED(".s2",        CLK_S2,            CLK_PLL1_DIV2,  4, 1),
+       DEF_FIXED(".s3",        CLK_S3,            CLK_PLL1_DIV2,  6, 1),
+       DEF_FIXED(".sdsrc",     CLK_SDSRC,         CLK_PLL1_DIV2,  2, 1),
+
+       DEF_GEN3_OSC(".r",      CLK_RINT,          CLK_EXTAL,      32),
+
+       /* Core Clock Outputs */
+       DEF_BASE("z",           R8A774A1_CLK_Z,     CLK_TYPE_GEN3_Z, CLK_PLL0),
+       DEF_BASE("z2",          R8A774A1_CLK_Z2,    CLK_TYPE_GEN3_Z2, CLK_PLL2),
+       DEF_FIXED("ztr",        R8A774A1_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
+       DEF_FIXED("ztrd2",      R8A774A1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+       DEF_FIXED("zt",         R8A774A1_CLK_ZT,    CLK_PLL1_DIV2,  4, 1),
+       DEF_FIXED("zx",         R8A774A1_CLK_ZX,    CLK_PLL1_DIV2,  2, 1),
+       DEF_FIXED("s0d1",       R8A774A1_CLK_S0D1,  CLK_S0,         1, 1),
+       DEF_FIXED("s0d2",       R8A774A1_CLK_S0D2,  CLK_S0,         2, 1),
+       DEF_FIXED("s0d3",       R8A774A1_CLK_S0D3,  CLK_S0,         3, 1),
+       DEF_FIXED("s0d4",       R8A774A1_CLK_S0D4,  CLK_S0,         4, 1),
+       DEF_FIXED("s0d6",       R8A774A1_CLK_S0D6,  CLK_S0,         6, 1),
+       DEF_FIXED("s0d8",       R8A774A1_CLK_S0D8,  CLK_S0,         8, 1),
+       DEF_FIXED("s0d12",      R8A774A1_CLK_S0D12, CLK_S0,        12, 1),
+       DEF_FIXED("s1d2",       R8A774A1_CLK_S1D2,  CLK_S1,         2, 1),
+       DEF_FIXED("s1d4",       R8A774A1_CLK_S1D4,  CLK_S1,         4, 1),
+       DEF_FIXED("s2d1",       R8A774A1_CLK_S2D1,  CLK_S2,         1, 1),
+       DEF_FIXED("s2d2",       R8A774A1_CLK_S2D2,  CLK_S2,         2, 1),
+       DEF_FIXED("s2d4",       R8A774A1_CLK_S2D4,  CLK_S2,         4, 1),
+       DEF_FIXED("s3d1",       R8A774A1_CLK_S3D1,  CLK_S3,         1, 1),
+       DEF_FIXED("s3d2",       R8A774A1_CLK_S3D2,  CLK_S3,         2, 1),
+       DEF_FIXED("s3d4",       R8A774A1_CLK_S3D4,  CLK_S3,         4, 1),
+
+       DEF_GEN3_SD("sd0",      R8A774A1_CLK_SD0,   CLK_SDSRC,     0x074),
+       DEF_GEN3_SD("sd1",      R8A774A1_CLK_SD1,   CLK_SDSRC,     0x078),
+       DEF_GEN3_SD("sd2",      R8A774A1_CLK_SD2,   CLK_SDSRC,     0x268),
+       DEF_GEN3_SD("sd3",      R8A774A1_CLK_SD3,   CLK_SDSRC,     0x26c),
+
+       DEF_FIXED("cl",         R8A774A1_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
+       DEF_FIXED("cp",         R8A774A1_CLK_CP,    CLK_EXTAL,      2, 1),
+
+       DEF_DIV6P1("csi0",      R8A774A1_CLK_CSI0,  CLK_PLL1_DIV4, 0x00c),
+       DEF_DIV6P1("mso",       R8A774A1_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
+       DEF_DIV6P1("hdmi",      R8A774A1_CLK_HDMI,  CLK_PLL1_DIV4, 0x250),
+
+       DEF_GEN3_OSC("osc",     R8A774A1_CLK_OSC,   CLK_EXTAL,     8),
+
+       DEF_BASE("r",           R8A774A1_CLK_R,     CLK_TYPE_GEN3_R, CLK_RINT),
+};
+
+static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
+       DEF_MOD("fdp1-0",                119,   R8A774A1_CLK_S0D1),
+       DEF_MOD("scif5",                 202,   R8A774A1_CLK_S3D4),
+       DEF_MOD("scif4",                 203,   R8A774A1_CLK_S3D4),
+       DEF_MOD("scif3",                 204,   R8A774A1_CLK_S3D4),
+       DEF_MOD("scif1",                 206,   R8A774A1_CLK_S3D4),
+       DEF_MOD("scif0",                 207,   R8A774A1_CLK_S3D4),
+       DEF_MOD("msiof3",                208,   R8A774A1_CLK_MSO),
+       DEF_MOD("msiof2",                209,   R8A774A1_CLK_MSO),
+       DEF_MOD("msiof1",                210,   R8A774A1_CLK_MSO),
+       DEF_MOD("msiof0",                211,   R8A774A1_CLK_MSO),
+       DEF_MOD("sys-dmac2",             217,   R8A774A1_CLK_S0D3),
+       DEF_MOD("sys-dmac1",             218,   R8A774A1_CLK_S0D3),
+       DEF_MOD("sys-dmac0",             219,   R8A774A1_CLK_S0D3),
+       DEF_MOD("cmt3",                  300,   R8A774A1_CLK_R),
+       DEF_MOD("cmt2",                  301,   R8A774A1_CLK_R),
+       DEF_MOD("cmt1",                  302,   R8A774A1_CLK_R),
+       DEF_MOD("cmt0",                  303,   R8A774A1_CLK_R),
+       DEF_MOD("scif2",                 310,   R8A774A1_CLK_S3D4),
+       DEF_MOD("sdif3",                 311,   R8A774A1_CLK_SD3),
+       DEF_MOD("sdif2",                 312,   R8A774A1_CLK_SD2),
+       DEF_MOD("sdif1",                 313,   R8A774A1_CLK_SD1),
+       DEF_MOD("sdif0",                 314,   R8A774A1_CLK_SD0),
+       DEF_MOD("pcie1",                 318,   R8A774A1_CLK_S3D1),
+       DEF_MOD("pcie0",                 319,   R8A774A1_CLK_S3D1),
+       DEF_MOD("usb3-if0",              328,   R8A774A1_CLK_S3D1),
+       DEF_MOD("usb-dmac0",             330,   R8A774A1_CLK_S3D1),
+       DEF_MOD("usb-dmac1",             331,   R8A774A1_CLK_S3D1),
+       DEF_MOD("rwdt",                  402,   R8A774A1_CLK_R),
+       DEF_MOD("intc-ex",               407,   R8A774A1_CLK_CP),
+       DEF_MOD("intc-ap",               408,   R8A774A1_CLK_S0D3),
+       DEF_MOD("audmac1",               501,   R8A774A1_CLK_S0D3),
+       DEF_MOD("audmac0",               502,   R8A774A1_CLK_S0D3),
+       DEF_MOD("hscif4",                516,   R8A774A1_CLK_S3D1),
+       DEF_MOD("hscif3",                517,   R8A774A1_CLK_S3D1),
+       DEF_MOD("hscif2",                518,   R8A774A1_CLK_S3D1),
+       DEF_MOD("hscif1",                519,   R8A774A1_CLK_S3D1),
+       DEF_MOD("hscif0",                520,   R8A774A1_CLK_S3D1),
+       DEF_MOD("thermal",               522,   R8A774A1_CLK_CP),
+       DEF_MOD("pwm",                   523,   R8A774A1_CLK_S0D12),
+       DEF_MOD("fcpvd2",                601,   R8A774A1_CLK_S0D2),
+       DEF_MOD("fcpvd1",                602,   R8A774A1_CLK_S0D2),
+       DEF_MOD("fcpvd0",                603,   R8A774A1_CLK_S0D2),
+       DEF_MOD("fcpvb0",                607,   R8A774A1_CLK_S0D1),
+       DEF_MOD("fcpvi0",                611,   R8A774A1_CLK_S0D1),
+       DEF_MOD("fcpf0",                 615,   R8A774A1_CLK_S0D1),
+       DEF_MOD("fcpci0",                617,   R8A774A1_CLK_S0D2),
+       DEF_MOD("fcpcs",                 619,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vspd2",                 621,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vspd1",                 622,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vspd0",                 623,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vspb",                  626,   R8A774A1_CLK_S0D1),
+       DEF_MOD("vspi0",                 631,   R8A774A1_CLK_S0D1),
+       DEF_MOD("ehci1",                 702,   R8A774A1_CLK_S3D4),
+       DEF_MOD("ehci0",                 703,   R8A774A1_CLK_S3D4),
+       DEF_MOD("hsusb",                 704,   R8A774A1_CLK_S3D4),
+       DEF_MOD("csi20",                 714,   R8A774A1_CLK_CSI0),
+       DEF_MOD("csi40",                 716,   R8A774A1_CLK_CSI0),
+       DEF_MOD("du2",                   722,   R8A774A1_CLK_S2D1),
+       DEF_MOD("du1",                   723,   R8A774A1_CLK_S2D1),
+       DEF_MOD("du0",                   724,   R8A774A1_CLK_S2D1),
+       DEF_MOD("lvds",                  727,   R8A774A1_CLK_S2D1),
+       DEF_MOD("hdmi0",                 729,   R8A774A1_CLK_HDMI),
+       DEF_MOD("vin7",                  804,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin6",                  805,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin5",                  806,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin4",                  807,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin3",                  808,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin2",                  809,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin1",                  810,   R8A774A1_CLK_S0D2),
+       DEF_MOD("vin0",                  811,   R8A774A1_CLK_S0D2),
+       DEF_MOD("etheravb",              812,   R8A774A1_CLK_S0D6),
+       DEF_MOD("gpio7",                 905,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio6",                 906,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio5",                 907,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio4",                 908,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio3",                 909,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio2",                 910,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio1",                 911,   R8A774A1_CLK_S3D4),
+       DEF_MOD("gpio0",                 912,   R8A774A1_CLK_S3D4),
+       DEF_MOD("can-if1",               915,   R8A774A1_CLK_S3D4),
+       DEF_MOD("can-if0",               916,   R8A774A1_CLK_S3D4),
+       DEF_MOD("i2c6",                  918,   R8A774A1_CLK_S0D6),
+       DEF_MOD("i2c5",                  919,   R8A774A1_CLK_S0D6),
+       DEF_MOD("i2c-dvfs",              926,   R8A774A1_CLK_CP),
+       DEF_MOD("i2c4",                  927,   R8A774A1_CLK_S0D6),
+       DEF_MOD("i2c3",                  928,   R8A774A1_CLK_S0D6),
+       DEF_MOD("i2c2",                  929,   R8A774A1_CLK_S3D2),
+       DEF_MOD("i2c1",                  930,   R8A774A1_CLK_S3D2),
+       DEF_MOD("i2c0",                  931,   R8A774A1_CLK_S3D2),
+       DEF_MOD("ssi-all",              1005,   R8A774A1_CLK_S3D4),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A774A1_CLK_S3D4),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
+};
+
+static const unsigned int r8a774a1_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-AP (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL2    PLL3    PLL4    OSC
+ * 14 13 19 17 (MHz)
+ *-------------------------------------------------------------------------
+ * 0  0  0  0  16.66 x 1       x180    x192    x144    x192    x144    /16
+ * 0  0  0  1  16.66 x 1       x180    x192    x144    x128    x144    /16
+ * 0  0  1  0  Prohibited setting
+ * 0  0  1  1  16.66 x 1       x180    x192    x144    x192    x144    /16
+ * 0  1  0  0  20    x 1       x150    x160    x120    x160    x120    /19
+ * 0  1  0  1  20    x 1       x150    x160    x120    x106    x120    /19
+ * 0  1  1  0  Prohibited setting
+ * 0  1  1  1  20    x 1       x150    x160    x120    x160    x120    /19
+ * 1  0  0  0  25    x 1       x120    x128    x96     x128    x96     /24
+ * 1  0  0  1  25    x 1       x120    x128    x96     x84     x96     /24
+ * 1  0  1  0  Prohibited setting
+ * 1  0  1  1  25    x 1       x120    x128    x96     x128    x96     /24
+ * 1  1  0  0  33.33 / 2       x180    x192    x144    x192    x144    /32
+ * 1  1  0  1  33.33 / 2       x180    x192    x144    x128    x144    /32
+ * 1  1  1  0  Prohibited setting
+ * 1  1  1  1  33.33 / 2       x180    x192    x144    x192    x144    /32
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 11) | \
+                                        (((md) & BIT(13)) >> 11) | \
+                                        (((md) & BIT(19)) >> 18) | \
+                                        (((md) & BIT(17)) >> 17))
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div   OSC prediv */
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            192,    1,      128,    1,      16,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            160,    1,      106,    1,      19,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 1,            128,    1,      84,     1,      24,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 2,            192,    1,      192,    1,      32,     },
+       { 2,            192,    1,      128,    1,      32,     },
+       { 0, /* Prohibited setting */                           },
+       { 2,            192,    1,      192,    1,      32,     },
+};
+
+static int __init r8a774a1_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+       if (!cpg_pll_config->extal_div) {
+               dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
+               return -EINVAL;
+       }
+
+       return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a774a1_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a774a1_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a774a1_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a774a1_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a774a1_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a774a1_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a774a1_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a774a1_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen3_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
new file mode 100644 (file)
index 0000000..10b9689
--- /dev/null
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * r8a774c0 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * Based on r8a77990-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a774c0-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen3-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A774C0_CLK_CPEX,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL0D4,
+       CLK_PLL0D8,
+       CLK_PLL0D20,
+       CLK_PLL0D24,
+       CLK_PLL1D2,
+       CLK_PE,
+       CLK_S0,
+       CLK_S1,
+       CLK_S2,
+       CLK_S3,
+       CLK_SDSRC,
+       CLK_RINT,
+       CLK_OCO,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",     CLK_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",      CLK_MAIN, CLK_TYPE_GEN3_MAIN,       CLK_EXTAL),
+       DEF_BASE(".pll1",      CLK_PLL1, CLK_TYPE_GEN3_PLL1,       CLK_MAIN),
+       DEF_BASE(".pll3",      CLK_PLL3, CLK_TYPE_GEN3_PLL3,       CLK_MAIN),
+
+       DEF_FIXED(".pll0",     CLK_PLL0,           CLK_MAIN,       1, 100),
+       DEF_FIXED(".pll0d4",   CLK_PLL0D4,         CLK_PLL0,       4, 1),
+       DEF_FIXED(".pll0d8",   CLK_PLL0D8,         CLK_PLL0,       8, 1),
+       DEF_FIXED(".pll0d20",  CLK_PLL0D20,        CLK_PLL0,      20, 1),
+       DEF_FIXED(".pll0d24",  CLK_PLL0D24,        CLK_PLL0,      24, 1),
+       DEF_FIXED(".pll1d2",   CLK_PLL1D2,         CLK_PLL1,       2, 1),
+       DEF_FIXED(".pe",       CLK_PE,             CLK_PLL0D20,    1, 1),
+       DEF_FIXED(".s0",       CLK_S0,             CLK_PLL1,       2, 1),
+       DEF_FIXED(".s1",       CLK_S1,             CLK_PLL1,       3, 1),
+       DEF_FIXED(".s2",       CLK_S2,             CLK_PLL1,       4, 1),
+       DEF_FIXED(".s3",       CLK_S3,             CLK_PLL1,       6, 1),
+       DEF_FIXED(".sdsrc",    CLK_SDSRC,          CLK_PLL1,       2, 1),
+
+       DEF_DIV6_RO(".r",      CLK_RINT,           CLK_EXTAL, CPG_RCKCR, 32),
+
+       DEF_RATE(".oco",       CLK_OCO,            8 * 1000 * 1000),
+
+       /* Core Clock Outputs */
+       DEF_FIXED("za2",       R8A774C0_CLK_ZA2,   CLK_PLL0D24,    1, 1),
+       DEF_FIXED("za8",       R8A774C0_CLK_ZA8,   CLK_PLL0D8,     1, 1),
+       DEF_FIXED("ztr",       R8A774C0_CLK_ZTR,   CLK_PLL1,       6, 1),
+       DEF_FIXED("zt",        R8A774C0_CLK_ZT,    CLK_PLL1,       4, 1),
+       DEF_FIXED("zx",        R8A774C0_CLK_ZX,    CLK_PLL1,       3, 1),
+       DEF_FIXED("s0d1",      R8A774C0_CLK_S0D1,  CLK_S0,         1, 1),
+       DEF_FIXED("s0d3",      R8A774C0_CLK_S0D3,  CLK_S0,         3, 1),
+       DEF_FIXED("s0d6",      R8A774C0_CLK_S0D6,  CLK_S0,         6, 1),
+       DEF_FIXED("s0d12",     R8A774C0_CLK_S0D12, CLK_S0,        12, 1),
+       DEF_FIXED("s0d24",     R8A774C0_CLK_S0D24, CLK_S0,        24, 1),
+       DEF_FIXED("s1d1",      R8A774C0_CLK_S1D1,  CLK_S1,         1, 1),
+       DEF_FIXED("s1d2",      R8A774C0_CLK_S1D2,  CLK_S1,         2, 1),
+       DEF_FIXED("s1d4",      R8A774C0_CLK_S1D4,  CLK_S1,         4, 1),
+       DEF_FIXED("s2d1",      R8A774C0_CLK_S2D1,  CLK_S2,         1, 1),
+       DEF_FIXED("s2d2",      R8A774C0_CLK_S2D2,  CLK_S2,         2, 1),
+       DEF_FIXED("s2d4",      R8A774C0_CLK_S2D4,  CLK_S2,         4, 1),
+       DEF_FIXED("s3d1",      R8A774C0_CLK_S3D1,  CLK_S3,         1, 1),
+       DEF_FIXED("s3d2",      R8A774C0_CLK_S3D2,  CLK_S3,         2, 1),
+       DEF_FIXED("s3d4",      R8A774C0_CLK_S3D4,  CLK_S3,         4, 1),
+
+       DEF_GEN3_SD("sd0",     R8A774C0_CLK_SD0,   CLK_SDSRC,     0x0074),
+       DEF_GEN3_SD("sd1",     R8A774C0_CLK_SD1,   CLK_SDSRC,     0x0078),
+       DEF_GEN3_SD("sd3",     R8A774C0_CLK_SD3,   CLK_SDSRC,     0x026c),
+
+       DEF_FIXED("cl",        R8A774C0_CLK_CL,    CLK_PLL1,      48, 1),
+       DEF_FIXED("cp",        R8A774C0_CLK_CP,    CLK_EXTAL,      2, 1),
+       DEF_FIXED("cpex",      R8A774C0_CLK_CPEX,  CLK_EXTAL,      4, 1),
+
+       DEF_DIV6_RO("osc",     R8A774C0_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
+
+       DEF_GEN3_PE("s0d6c",   R8A774C0_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2),
+       DEF_GEN3_PE("s3d1c",   R8A774C0_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1),
+       DEF_GEN3_PE("s3d2c",   R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
+       DEF_GEN3_PE("s3d4c",   R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
+
+       DEF_DIV6P1("csi0",     R8A774C0_CLK_CSI0,  CLK_PLL1D2, 0x00c),
+       DEF_DIV6P1("mso",      R8A774C0_CLK_MSO,   CLK_PLL1D2, 0x014),
+
+       DEF_GEN3_RCKSEL("r",   R8A774C0_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4),
+};
+
+static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
+       DEF_MOD("scif5",                 202,   R8A774C0_CLK_S3D4C),
+       DEF_MOD("scif4",                 203,   R8A774C0_CLK_S3D4C),
+       DEF_MOD("scif3",                 204,   R8A774C0_CLK_S3D4C),
+       DEF_MOD("scif1",                 206,   R8A774C0_CLK_S3D4C),
+       DEF_MOD("scif0",                 207,   R8A774C0_CLK_S3D4C),
+       DEF_MOD("msiof3",                208,   R8A774C0_CLK_MSO),
+       DEF_MOD("msiof2",                209,   R8A774C0_CLK_MSO),
+       DEF_MOD("msiof1",                210,   R8A774C0_CLK_MSO),
+       DEF_MOD("msiof0",                211,   R8A774C0_CLK_MSO),
+       DEF_MOD("sys-dmac2",             217,   R8A774C0_CLK_S3D1),
+       DEF_MOD("sys-dmac1",             218,   R8A774C0_CLK_S3D1),
+       DEF_MOD("sys-dmac0",             219,   R8A774C0_CLK_S3D1),
+
+       DEF_MOD("cmt3",                  300,   R8A774C0_CLK_R),
+       DEF_MOD("cmt2",                  301,   R8A774C0_CLK_R),
+       DEF_MOD("cmt1",                  302,   R8A774C0_CLK_R),
+       DEF_MOD("cmt0",                  303,   R8A774C0_CLK_R),
+       DEF_MOD("scif2",                 310,   R8A774C0_CLK_S3D4C),
+       DEF_MOD("sdif3",                 311,   R8A774C0_CLK_SD3),
+       DEF_MOD("sdif1",                 313,   R8A774C0_CLK_SD1),
+       DEF_MOD("sdif0",                 314,   R8A774C0_CLK_SD0),
+       DEF_MOD("pcie0",                 319,   R8A774C0_CLK_S3D1),
+       DEF_MOD("usb3-if0",              328,   R8A774C0_CLK_S3D1),
+       DEF_MOD("usb-dmac0",             330,   R8A774C0_CLK_S3D1),
+       DEF_MOD("usb-dmac1",             331,   R8A774C0_CLK_S3D1),
+
+       DEF_MOD("rwdt",                  402,   R8A774C0_CLK_R),
+       DEF_MOD("intc-ex",               407,   R8A774C0_CLK_CP),
+       DEF_MOD("intc-ap",               408,   R8A774C0_CLK_S0D3),
+
+       DEF_MOD("audmac0",               502,   R8A774C0_CLK_S3D4),
+       DEF_MOD("hscif4",                516,   R8A774C0_CLK_S3D1C),
+       DEF_MOD("hscif3",                517,   R8A774C0_CLK_S3D1C),
+       DEF_MOD("hscif2",                518,   R8A774C0_CLK_S3D1C),
+       DEF_MOD("hscif1",                519,   R8A774C0_CLK_S3D1C),
+       DEF_MOD("hscif0",                520,   R8A774C0_CLK_S3D1C),
+       DEF_MOD("thermal",               522,   R8A774C0_CLK_CP),
+       DEF_MOD("pwm",                   523,   R8A774C0_CLK_S3D4C),
+
+       DEF_MOD("fcpvd1",                602,   R8A774C0_CLK_S1D2),
+       DEF_MOD("fcpvd0",                603,   R8A774C0_CLK_S1D2),
+       DEF_MOD("fcpvb0",                607,   R8A774C0_CLK_S0D1),
+       DEF_MOD("fcpvi0",                611,   R8A774C0_CLK_S0D1),
+       DEF_MOD("fcpf0",                 615,   R8A774C0_CLK_S0D1),
+       DEF_MOD("fcpcs",                 619,   R8A774C0_CLK_S0D1),
+       DEF_MOD("vspd1",                 622,   R8A774C0_CLK_S1D2),
+       DEF_MOD("vspd0",                 623,   R8A774C0_CLK_S1D2),
+       DEF_MOD("vspb",                  626,   R8A774C0_CLK_S0D1),
+       DEF_MOD("vspi0",                 631,   R8A774C0_CLK_S0D1),
+
+       DEF_MOD("ehci0",                 703,   R8A774C0_CLK_S3D4),
+       DEF_MOD("hsusb",                 704,   R8A774C0_CLK_S3D4),
+       DEF_MOD("csi40",                 716,   R8A774C0_CLK_CSI0),
+       DEF_MOD("du1",                   723,   R8A774C0_CLK_S2D1),
+       DEF_MOD("du0",                   724,   R8A774C0_CLK_S2D1),
+       DEF_MOD("lvds",                  727,   R8A774C0_CLK_S2D1),
+
+       DEF_MOD("vin5",                  806,   R8A774C0_CLK_S1D2),
+       DEF_MOD("vin4",                  807,   R8A774C0_CLK_S1D2),
+       DEF_MOD("etheravb",              812,   R8A774C0_CLK_S3D2),
+
+       DEF_MOD("gpio6",                 906,   R8A774C0_CLK_S3D4),
+       DEF_MOD("gpio5",                 907,   R8A774C0_CLK_S3D4),
+       DEF_MOD("gpio4",                 908,   R8A774C0_CLK_S3D4),
+       DEF_MOD("gpio3",                 909,   R8A774C0_CLK_S3D4),
+       DEF_MOD("gpio2",                 910,   R8A774C0_CLK_S3D4),
+       DEF_MOD("gpio1",                 911,   R8A774C0_CLK_S3D4),
+       DEF_MOD("gpio0",                 912,   R8A774C0_CLK_S3D4),
+       DEF_MOD("can-if1",               915,   R8A774C0_CLK_S3D4),
+       DEF_MOD("can-if0",               916,   R8A774C0_CLK_S3D4),
+       DEF_MOD("i2c6",                  918,   R8A774C0_CLK_S3D2),
+       DEF_MOD("i2c5",                  919,   R8A774C0_CLK_S3D2),
+       DEF_MOD("i2c-dvfs",              926,   R8A774C0_CLK_CP),
+       DEF_MOD("i2c4",                  927,   R8A774C0_CLK_S3D2),
+       DEF_MOD("i2c3",                  928,   R8A774C0_CLK_S3D2),
+       DEF_MOD("i2c2",                  929,   R8A774C0_CLK_S3D2),
+       DEF_MOD("i2c1",                  930,   R8A774C0_CLK_S3D2),
+       DEF_MOD("i2c0",                  931,   R8A774C0_CLK_S3D2),
+
+       DEF_MOD("i2c7",                 1003,   R8A774C0_CLK_S3D2),
+       DEF_MOD("ssi-all",              1005,   R8A774C0_CLK_S3D4),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A774C0_CLK_S3D4),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
+};
+
+static const unsigned int r8a774c0_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-AP (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ * MD19                EXTAL (MHz)     PLL0            PLL1            PLL3
+ *--------------------------------------------------------------------
+ * 0           48 x 1          x100/1          x100/3          x100/3
+ * 1           48 x 1          x100/1          x100/3           x58/3
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       (((md) & BIT(19)) >> 19)
+
+static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = {
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
+       { 1,            100,    3,      100,    3,      },
+       { 1,            100,    3,       58,    3,      },
+};
+
+static int __init r8a774c0_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+       return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a774c0_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a774c0_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a774c0_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a774c0_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a774c0_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a774c0_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a774c0_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a774c0_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen3_cpg_clk_register,
+};
index f936cb74b6811678f8ba93a003a573afc0c0151d..c57cb93f831589f85eed013f616d99ceadf5c740 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7790 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -6,10 +7,6 @@
  * Based on clk-rcar-gen2.c
  *
  * Copyright (C) 2013 Ideas On Board SPRL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
index 1b91f03b7598076683f1300ce01b6ccd3b7a416d..65702debcabbf654a23ad9922415b3c5f95d77b5 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7791 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -6,10 +7,6 @@
  * Based on clk-rcar-gen2.c
  *
  * Copyright (C) 2013 Ideas On Board SPRL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
index 493e07859f5fa40deee18d36ee78bea180c932e3..cf8b84a3a06052fbdacf63e6975e0b60bc6b4456 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7792 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -6,10 +7,6 @@
  * Based on clk-rcar-gen2.c
  *
  * Copyright (C) 2013 Ideas On Board SPRL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
index 088f4b79fdfcdab4448a242ed6de89df97688716..c1948693c5c1c499b8262b12925c74a2ef1fb8e3 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7794 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -6,10 +7,6 @@
  * Based on clk-rcar-gen2.c
  *
  * Copyright (C) 2013 Ideas On Board SPRL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
index a85dd50e89110d5d4c571c791a5a8cb87a4d537a..119c024407263568e89d0a66bcf89be8a6259c43 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7795 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -6,10 +7,6 @@
  * Based on clk-rcar-gen3.c
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
@@ -73,6 +70,8 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
        DEF_FIXED(".s3",        CLK_S3,            CLK_PLL1_DIV2,  6, 1),
        DEF_FIXED(".sdsrc",     CLK_SDSRC,         CLK_PLL1_DIV2,  2, 1),
 
+       DEF_GEN3_OSC(".r",      CLK_RINT,          CLK_EXTAL,      32),
+
        /* Core Clock Outputs */
        DEF_BASE("z",           R8A7795_CLK_Z,     CLK_TYPE_GEN3_Z, CLK_PLL0),
        DEF_BASE("z2",          R8A7795_CLK_Z2,    CLK_TYPE_GEN3_Z2, CLK_PLL2),
@@ -111,8 +110,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
        DEF_DIV6P1("mso",       R8A7795_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
        DEF_DIV6P1("hdmi",      R8A7795_CLK_HDMI,  CLK_PLL1_DIV4, 0x250),
 
-       DEF_DIV6_RO("osc",      R8A7795_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
-       DEF_DIV6_RO("r_int",    CLK_RINT,          CLK_EXTAL, CPG_RCKCR, 32),
+       DEF_GEN3_OSC("osc",     R8A7795_CLK_OSC,   CLK_EXTAL,     8),
 
        DEF_BASE("r",           R8A7795_CLK_R,     CLK_TYPE_GEN3_R, CLK_RINT),
 };
@@ -283,25 +281,25 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
  */
 
 /*
- *   MD                EXTAL           PLL0    PLL1    PLL2    PLL3    PLL4
+ *   MD                EXTAL           PLL0    PLL1    PLL2    PLL3    PLL4    OSC
  * 14 13 19 17 (MHz)
- *-------------------------------------------------------------------
- * 0  0  0  0  16.66 x 1       x180    x192    x144    x192    x144
- * 0  0  0  1  16.66 x 1       x180    x192    x144    x128    x144
+ *-------------------------------------------------------------------------
+ * 0  0  0  0  16.66 x 1       x180    x192    x144    x192    x144    /16
+ * 0  0  0  1  16.66 x 1       x180    x192    x144    x128    x144    /16
  * 0  0  1  0  Prohibited setting
- * 0  0  1  1  16.66 x 1       x180    x192    x144    x192    x144
- * 0  1  0  0  20    x 1       x150    x160    x120    x160    x120
- * 0  1  0  1  20    x 1       x150    x160    x120    x106    x120
+ * 0  0  1  1  16.66 x 1       x180    x192    x144    x192    x144    /16
+ * 0  1  0  0  20    x 1       x150    x160    x120    x160    x120    /19
+ * 0  1  0  1  20    x 1       x150    x160    x120    x106    x120    /19
  * 0  1  1  0  Prohibited setting
- * 0  1  1  1  20    x 1       x150    x160    x120    x160    x120
- * 1  0  0  0  25    x 1       x120    x128    x96     x128    x96
- * 1  0  0  1  25    x 1       x120    x128    x96     x84     x96
+ * 0  1  1  1  20    x 1       x150    x160    x120    x160    x120    /19
+ * 1  0  0  0  25    x 1       x120    x128    x96     x128    x96     /24
+ * 1  0  0  1  25    x 1       x120    x128    x96     x84     x96     /24
  * 1  0  1  0  Prohibited setting
- * 1  0  1  1  25    x 1       x120    x128    x96     x128    x96
- * 1  1  0  0  33.33 / 2       x180    x192    x144    x192    x144
- * 1  1  0  1  33.33 / 2       x180    x192    x144    x128    x144
+ * 1  0  1  1  25    x 1       x120    x128    x96     x128    x96     /24
+ * 1  1  0  0  33.33 / 2       x180    x192    x144    x192    x144    /32
+ * 1  1  0  1  33.33 / 2       x180    x192    x144    x128    x144    /32
  * 1  1  1  0  Prohibited setting
- * 1  1  1  1  33.33 / 2       x180    x192    x144    x192    x144
+ * 1  1  1  1  33.33 / 2       x180    x192    x144    x192    x144    /32
  */
 #define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 11) | \
                                         (((md) & BIT(13)) >> 11) | \
@@ -309,23 +307,23 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
                                         (((md) & BIT(17)) >> 17))
 
 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
-       /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
-       { 1,            192,    1,      192,    1,      },
-       { 1,            192,    1,      128,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            192,    1,      192,    1,      },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            160,    1,      106,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            128,    1,      128,    1,      },
-       { 1,            128,    1,      84,     1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            128,    1,      128,    1,      },
-       { 2,            192,    1,      192,    1,      },
-       { 2,            192,    1,      128,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 2,            192,    1,      192,    1,      },
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div   OSC prediv */
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            192,    1,      128,    1,      16,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            160,    1,      106,    1,      19,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 1,            128,    1,      84,     1,      24,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 2,            192,    1,      192,    1,      32,     },
+       { 2,            192,    1,      128,    1,      32,     },
+       { 0, /* Prohibited setting */                           },
+       { 2,            192,    1,      192,    1,      32,     },
 };
 
 static const struct soc_device_attribute r8a7795es1[] __initconst = {
index dfb267a92f2a20d384b9f0ea1f04859eb71aeefc..10567386e6dd83eb8e9e4f9e448eaafa6bcdc95d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -7,10 +8,6 @@
  *
  * Copyright (C) 2015 Glider bvba
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
@@ -73,6 +70,8 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
        DEF_FIXED(".s3",        CLK_S3,            CLK_PLL1_DIV2,  6, 1),
        DEF_FIXED(".sdsrc",     CLK_SDSRC,         CLK_PLL1_DIV2,  2, 1),
 
+       DEF_GEN3_OSC(".r",      CLK_RINT,          CLK_EXTAL,      32),
+
        /* Core Clock Outputs */
        DEF_BASE("z",           R8A7796_CLK_Z,     CLK_TYPE_GEN3_Z, CLK_PLL0),
        DEF_BASE("z2",          R8A7796_CLK_Z2,    CLK_TYPE_GEN3_Z2, CLK_PLL2),
@@ -110,8 +109,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
        DEF_DIV6P1("mso",       R8A7796_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
        DEF_DIV6P1("hdmi",      R8A7796_CLK_HDMI,  CLK_PLL1_DIV4, 0x250),
 
-       DEF_DIV6_RO("osc",      R8A7796_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
-       DEF_DIV6_RO("r_int",    CLK_RINT,          CLK_EXTAL, CPG_RCKCR, 32),
+       DEF_GEN3_OSC("osc",     R8A7796_CLK_OSC,   CLK_EXTAL,     8),
 
        DEF_BASE("r",           R8A7796_CLK_R,     CLK_TYPE_GEN3_R, CLK_RINT),
 };
@@ -255,25 +253,25 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
  */
 
 /*
- *   MD                EXTAL           PLL0    PLL1    PLL2    PLL3    PLL4
+ *   MD                EXTAL           PLL0    PLL1    PLL2    PLL3    PLL4    OSC
  * 14 13 19 17 (MHz)
- *-------------------------------------------------------------------
- * 0  0  0  0  16.66 x 1       x180    x192    x144    x192    x144
- * 0  0  0  1  16.66 x 1       x180    x192    x144    x128    x144
+ *-------------------------------------------------------------------------
+ * 0  0  0  0  16.66 x 1       x180    x192    x144    x192    x144    /16
+ * 0  0  0  1  16.66 x 1       x180    x192    x144    x128    x144    /16
  * 0  0  1  0  Prohibited setting
- * 0  0  1  1  16.66 x 1       x180    x192    x144    x192    x144
- * 0  1  0  0  20    x 1       x150    x160    x120    x160    x120
- * 0  1  0  1  20    x 1       x150    x160    x120    x106    x120
+ * 0  0  1  1  16.66 x 1       x180    x192    x144    x192    x144    /16
+ * 0  1  0  0  20    x 1       x150    x160    x120    x160    x120    /19
+ * 0  1  0  1  20    x 1       x150    x160    x120    x106    x120    /19
  * 0  1  1  0  Prohibited setting
- * 0  1  1  1  20    x 1       x150    x160    x120    x160    x120
- * 1  0  0  0  25    x 1       x120    x128    x96     x128    x96
- * 1  0  0  1  25    x 1       x120    x128    x96     x84     x96
+ * 0  1  1  1  20    x 1       x150    x160    x120    x160    x120    /19
+ * 1  0  0  0  25    x 1       x120    x128    x96     x128    x96     /24
+ * 1  0  0  1  25    x 1       x120    x128    x96     x84     x96     /24
  * 1  0  1  0  Prohibited setting
- * 1  0  1  1  25    x 1       x120    x128    x96     x128    x96
- * 1  1  0  0  33.33 / 2       x180    x192    x144    x192    x144
- * 1  1  0  1  33.33 / 2       x180    x192    x144    x128    x144
+ * 1  0  1  1  25    x 1       x120    x128    x96     x128    x96     /24
+ * 1  1  0  0  33.33 / 2       x180    x192    x144    x192    x144    /32
+ * 1  1  0  1  33.33 / 2       x180    x192    x144    x128    x144    /32
  * 1  1  1  0  Prohibited setting
- * 1  1  1  1  33.33 / 2       x180    x192    x144    x192    x144
+ * 1  1  1  1  33.33 / 2       x180    x192    x144    x192    x144    /32
  */
 #define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 11) | \
                                         (((md) & BIT(13)) >> 11) | \
@@ -281,23 +279,23 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
                                         (((md) & BIT(17)) >> 17))
 
 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
-       /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
-       { 1,            192,    1,      192,    1,      },
-       { 1,            192,    1,      128,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            192,    1,      192,    1,      },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            160,    1,      106,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            128,    1,      128,    1,      },
-       { 1,            128,    1,      84,     1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            128,    1,      128,    1,      },
-       { 2,            192,    1,      192,    1,      },
-       { 2,            192,    1,      128,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 2,            192,    1,      192,    1,      },
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div   OSC prediv */
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            192,    1,      128,    1,      16,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            160,    1,      106,    1,      19,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 1,            128,    1,      84,     1,      24,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 2,            192,    1,      192,    1,      32,     },
+       { 2,            192,    1,      128,    1,      32,     },
+       { 0, /* Prohibited setting */                           },
+       { 2,            192,    1,      192,    1,      32,     },
 };
 
 static int __init r8a7796_cpg_mssr_init(struct device *dev)
index 8fae5e9c4a77242d9ea1615f14e1cf08e6507b8e..1fcc411502da5e5f317c7f44a30d69b84d5cf2bf 100644 (file)
@@ -68,6 +68,8 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = {
        DEF_FIXED(".s3",        CLK_S3,                 CLK_PLL1_DIV2,  6, 1),
        DEF_FIXED(".sdsrc",     CLK_SDSRC,              CLK_PLL1_DIV2,  2, 1),
 
+       DEF_GEN3_OSC(".r",      CLK_RINT,               CLK_EXTAL,      32),
+
        /* Core Clock Outputs */
        DEF_BASE("z",           R8A77965_CLK_Z,         CLK_TYPE_GEN3_Z, CLK_PLL0),
        DEF_FIXED("ztr",        R8A77965_CLK_ZTR,       CLK_PLL1_DIV2,  6, 1),
@@ -104,13 +106,13 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = {
        DEF_DIV6P1("mso",       R8A77965_CLK_MSO,       CLK_PLL1_DIV4,  0x014),
        DEF_DIV6P1("hdmi",      R8A77965_CLK_HDMI,      CLK_PLL1_DIV4,  0x250),
 
-       DEF_DIV6_RO("osc",      R8A77965_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8),
-       DEF_DIV6_RO("r_int",    CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
+       DEF_GEN3_OSC("osc",     R8A77965_CLK_OSC,       CLK_EXTAL,      8),
 
        DEF_BASE("r",           R8A77965_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
 };
 
 static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
+       DEF_MOD("fdp1-0",               119,    R8A77965_CLK_S0D1),
        DEF_MOD("scif5",                202,    R8A77965_CLK_S3D4),
        DEF_MOD("scif4",                203,    R8A77965_CLK_S3D4),
        DEF_MOD("scif3",                204,    R8A77965_CLK_S3D4),
@@ -192,6 +194,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
        DEF_MOD("vin1",                 810,    R8A77965_CLK_S0D2),
        DEF_MOD("vin0",                 811,    R8A77965_CLK_S0D2),
        DEF_MOD("etheravb",             812,    R8A77965_CLK_S0D6),
+       DEF_MOD("sata0",                815,    R8A77965_CLK_S3D2),
        DEF_MOD("imr1",                 822,    R8A77965_CLK_S0D2),
        DEF_MOD("imr0",                 823,    R8A77965_CLK_S0D2),
 
@@ -252,25 +255,25 @@ static const unsigned int r8a77965_crit_mod_clks[] __initconst = {
  */
 
 /*
- *   MD                EXTAL           PLL0    PLL1    PLL3    PLL4
+ *   MD                EXTAL           PLL0    PLL1    PLL3    PLL4    OSC
  * 14 13 19 17 (MHz)
- *-----------------------------------------------------------
- * 0  0  0  0  16.66 x 1       x180    x192    x192    x144
- * 0  0  0  1  16.66 x 1       x180    x192    x128    x144
+ *-----------------------------------------------------------------
+ * 0  0  0  0  16.66 x 1       x180    x192    x192    x144    /16
+ * 0  0  0  1  16.66 x 1       x180    x192    x128    x144    /16
  * 0  0  1  0  Prohibited setting
- * 0  0  1  1  16.66 x 1       x180    x192    x192    x144
- * 0  1  0  0  20    x 1       x150    x160    x160    x120
- * 0  1  0  1  20    x 1       x150    x160    x106    x120
+ * 0  0  1  1  16.66 x 1       x180    x192    x192    x144    /16
+ * 0  1  0  0  20    x 1       x150    x160    x160    x120    /19
+ * 0  1  0  1  20    x 1       x150    x160    x106    x120    /19
  * 0  1  1  0  Prohibited setting
- * 0  1  1  1  20    x 1       x150    x160    x160    x120
- * 1  0  0  0  25    x 1       x120    x128    x128    x96
- * 1  0  0  1  25    x 1       x120    x128    x84     x96
+ * 0  1  1  1  20    x 1       x150    x160    x160    x120    /19
+ * 1  0  0  0  25    x 1       x120    x128    x128    x96     /24
+ * 1  0  0  1  25    x 1       x120    x128    x84     x96     /24
  * 1  0  1  0  Prohibited setting
- * 1  0  1  1  25    x 1       x120    x128    x128    x96
- * 1  1  0  0  33.33 / 2       x180    x192    x192    x144
- * 1  1  0  1  33.33 / 2       x180    x192    x128    x144
+ * 1  0  1  1  25    x 1       x120    x128    x128    x96     /24
+ * 1  1  0  0  33.33 / 2       x180    x192    x192    x144    /32
+ * 1  1  0  1  33.33 / 2       x180    x192    x128    x144    /32
  * 1  1  1  0  Prohibited setting
- * 1  1  1  1  33.33 / 2       x180    x192    x192    x144
+ * 1  1  1  1  33.33 / 2       x180    x192    x192    x144    /32
  */
 #define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 11) | \
                                         (((md) & BIT(13)) >> 11) | \
@@ -278,23 +281,23 @@ static const unsigned int r8a77965_crit_mod_clks[] __initconst = {
                                         (((md) & BIT(17)) >> 17))
 
 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
-       /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
-       { 1,            192,    1,      192,    1,      },
-       { 1,            192,    1,      128,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            192,    1,      192,    1,      },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            160,    1,      106,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            128,    1,      128,    1,      },
-       { 1,            128,    1,      84,     1,      },
-       { 0, /* Prohibited setting */                   },
-       { 1,            128,    1,      128,    1,      },
-       { 2,            192,    1,      192,    1,      },
-       { 2,            192,    1,      128,    1,      },
-       { 0, /* Prohibited setting */                   },
-       { 2,            192,    1,      192,    1,      },
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div   OSC prediv */
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            192,    1,      128,    1,      16,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            160,    1,      106,    1,      19,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 1,            128,    1,      84,     1,      24,     },
+       { 0, /* Prohibited setting */                           },
+       { 1,            128,    1,      128,    1,      24,     },
+       { 2,            192,    1,      192,    1,      32,     },
+       { 2,            192,    1,      128,    1,      32,     },
+       { 0, /* Prohibited setting */                           },
+       { 2,            192,    1,      192,    1,      32,     },
 };
 
 static int __init r8a77965_cpg_mssr_init(struct device *dev)
index f55842917e8dd36ab86135113ffb468cd60798ba..2015e45543e948f23aa70160a4a5b34f9f61355d 100644 (file)
@@ -1,17 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a77970 Clock Pulse Generator / Module Standby and Software Reset
  *
- * Copyright (C) 2017 Cogent Embedded Inc.
+ * Copyright (C) 2017-2018 Cogent Embedded Inc.
  *
  * Based on r8a7795-cpg-mssr.c
  *
  * Copyright (C) 2015 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
+#include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include "renesas-cpg-mssr.h"
 #include "rcar-gen3-cpg.h"
 
+#define CPG_SD0CKCR            0x0074
+
+enum r8a77970_clk_types {
+       CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE,
+       CLK_TYPE_R8A77970_SD0,
+};
+
 enum clk_ids {
        /* Core Clock Outputs exported to DT */
        LAST_DT_CORE_CLK = R8A77970_CLK_OSC,
@@ -42,6 +47,20 @@ enum clk_ids {
        MOD_CLK_BASE
 };
 
+static spinlock_t cpg_lock;
+
+static const struct clk_div_table cpg_sd0h_div_table[] = {
+       {  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
+       {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+       {  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static const struct clk_div_table cpg_sd0_div_table[] = {
+       {  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+       {  8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
+       {  0,  0 },
+};
+
 static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
        /* External Clock Inputs */
        DEF_INPUT("extal",      CLK_EXTAL),
@@ -68,6 +87,10 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
        DEF_FIXED("s2d2",       R8A77970_CLK_S2D2,  CLK_PLL1_DIV2, 12, 1),
        DEF_FIXED("s2d4",       R8A77970_CLK_S2D4,  CLK_PLL1_DIV2, 24, 1),
 
+       DEF_BASE("sd0h", R8A77970_CLK_SD0H, CLK_TYPE_R8A77970_SD0H,
+                CLK_PLL1_DIV2),
+       DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2),
+
        DEF_FIXED("cl",         R8A77970_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A77970_CLK_CP,    CLK_EXTAL,      2, 1),
 
@@ -80,6 +103,11 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
 };
 
 static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+       DEF_MOD("tmu4",                  121,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu3",                  122,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu2",                  123,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu1",                  124,   R8A77970_CLK_S2D2),
+       DEF_MOD("tmu0",                  125,   R8A77970_CLK_CP),
        DEF_MOD("ivcp1e",                127,   R8A77970_CLK_S2D1),
        DEF_MOD("scif4",                 203,   R8A77970_CLK_S2D4),
        DEF_MOD("scif3",                 204,   R8A77970_CLK_S2D4),
@@ -92,6 +120,12 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
        DEF_MOD("mfis",                  213,   R8A77970_CLK_S2D2),
        DEF_MOD("sys-dmac2",             217,   R8A77970_CLK_S2D1),
        DEF_MOD("sys-dmac1",             218,   R8A77970_CLK_S2D1),
+       DEF_MOD("cmt3",                  300,   R8A77970_CLK_R),
+       DEF_MOD("cmt2",                  301,   R8A77970_CLK_R),
+       DEF_MOD("cmt1",                  302,   R8A77970_CLK_R),
+       DEF_MOD("cmt0",                  303,   R8A77970_CLK_R),
+       DEF_MOD("tpu0",                  304,   R8A77970_CLK_S2D4),
+       DEF_MOD("sd-if",                 314,   R8A77970_CLK_SD0),
        DEF_MOD("rwdt",                  402,   R8A77970_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A77970_CLK_CP),
        DEF_MOD("intc-ap",               408,   R8A77970_CLK_S2D1),
@@ -173,11 +207,46 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
        if (error)
                return error;
 
+       spin_lock_init(&cpg_lock);
+
        cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
 
        return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
 }
 
+static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
+       const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
+       struct clk **clks, void __iomem *base,
+       struct raw_notifier_head *notifiers)
+{
+       const struct clk_div_table *table;
+       const struct clk *parent;
+       unsigned int shift;
+
+       switch (core->type) {
+       case CLK_TYPE_R8A77970_SD0H:
+               table = cpg_sd0h_div_table;
+               shift = 8;
+               break;
+       case CLK_TYPE_R8A77970_SD0:
+               table = cpg_sd0_div_table;
+               shift = 4;
+               break;
+       default:
+               return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
+                                                 notifiers);
+       }
+
+       parent = clks[core->parent];
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       return clk_register_divider_table(NULL, core->name,
+                                         __clk_get_name(parent), 0,
+                                         base + CPG_SD0CKCR,
+                                         shift, 4, 0, table, &cpg_lock);
+}
+
 const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
        /* Core Clocks */
        .core_clks = r8a77970_core_clks,
@@ -196,5 +265,5 @@ const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
 
        /* Callbacks */
        .init = r8a77970_cpg_mssr_init,
-       .cpg_clk_register = rcar_gen3_cpg_clk_register,
+       .cpg_clk_register = r8a77970_cpg_clk_register,
 };
index d7ebd9ec00594fc8e12d8c90c9d8f321a8c1daed..25a3083b676413df960e6dbbe963c04524386511 100644 (file)
@@ -41,6 +41,7 @@ enum clk_ids {
        CLK_S2,
        CLK_S3,
        CLK_SDSRC,
+       CLK_OCO,
 
        /* Module Clocks */
        MOD_CLK_BASE
@@ -64,6 +65,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
        DEF_FIXED(".s2",        CLK_S2,            CLK_PLL1_DIV2,  4, 1),
        DEF_FIXED(".s3",        CLK_S3,            CLK_PLL1_DIV2,  6, 1),
        DEF_FIXED(".sdsrc",     CLK_SDSRC,         CLK_PLL1_DIV2,  2, 1),
+       DEF_RATE(".oco",        CLK_OCO,           32768),
 
        /* Core Clock Outputs */
        DEF_FIXED("ztr",        R8A77980_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
@@ -96,6 +98,9 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
        DEF_DIV6P1("canfd",     R8A77980_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
        DEF_DIV6P1("csi0",      R8A77980_CLK_CSI0,  CLK_PLL1_DIV4, 0x00c),
        DEF_DIV6P1("mso",       R8A77980_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
+
+       DEF_GEN3_OSC("osc",     R8A77980_CLK_OSC,   CLK_EXTAL,     8),
+       DEF_GEN3_MDSEL("r",     R8A77980_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
 };
 
 static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
@@ -114,9 +119,14 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
        DEF_MOD("msiof0",                211,   R8A77980_CLK_MSO),
        DEF_MOD("sys-dmac2",             217,   R8A77980_CLK_S0D3),
        DEF_MOD("sys-dmac1",             218,   R8A77980_CLK_S0D3),
+       DEF_MOD("cmt3",                  300,   R8A77980_CLK_R),
+       DEF_MOD("cmt2",                  301,   R8A77980_CLK_R),
+       DEF_MOD("cmt1",                  302,   R8A77980_CLK_R),
+       DEF_MOD("cmt0",                  303,   R8A77980_CLK_R),
        DEF_MOD("tpu0",                  304,   R8A77980_CLK_S3D4),
        DEF_MOD("sdif",                  314,   R8A77980_CLK_SD0),
        DEF_MOD("pciec0",                319,   R8A77980_CLK_S2D2),
+       DEF_MOD("rwdt",                  402,   R8A77980_CLK_R),
        DEF_MOD("intc-ex",               407,   R8A77980_CLK_CP),
        DEF_MOD("intc-ap",               408,   R8A77980_CLK_S0D3),
        DEF_MOD("hscif3",                517,   R8A77980_CLK_S3D1),
@@ -171,23 +181,23 @@ static const unsigned int r8a77980_crit_mod_clks[] __initconst = {
  */
 
 /*
- *   MD                EXTAL           PLL2    PLL1    PLL3
+ *   MD                EXTAL           PLL2    PLL1    PLL3    OSC
  * 14 13       (MHz)
- * --------------------------------------------------
- * 0  0                16.66 x 1       x240    x192    x192
- * 0  1                20    x 1       x200    x160    x160
- * 1  0                27    x 1       x148    x118    x118
- * 1  1                33.33 / 2       x240    x192    x192
+ * --------------------------------------------------------
+ * 0  0                16.66 x 1       x240    x192    x192    /16
+ * 0  1                20    x 1       x200    x160    x160    /19
+ * 1  0                27    x 1       x148    x118    x118    /26
+ * 1  1                33.33 / 2       x240    x192    x192    /32
  */
 #define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 13) | \
                                         (((md) & BIT(13)) >> 13))
 
 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[4] __initconst = {
-       /* EXTAL div    PLL1 mult/div   PLL3 mult/div */
-       { 1,            192,    1,      192,    1,      },
-       { 1,            160,    1,      160,    1,      },
-       { 1,            118,    1,      118,    1,      },
-       { 2,            192,    1,      192,    1,      },
+       /* EXTAL div    PLL1 mult/div   PLL3 mult/div   OSC prediv */
+       { 1,            192,    1,      192,    1,      16,     },
+       { 1,            160,    1,      160,    1,      19,     },
+       { 1,            118,    1,      118,    1,      26,     },
+       { 2,            192,    1,      192,    1,      32,     },
 };
 
 static int __init r8a77980_cpg_mssr_init(struct device *dev)
index 9e14f1486fbb93ccb887c9b85cae0a61757741f3..9eb80180eea0b1a627ace5e586656f53a26a6472 100644 (file)
@@ -44,6 +44,8 @@ enum clk_ids {
        CLK_S2,
        CLK_S3,
        CLK_SDSRC,
+       CLK_RINT,
+       CLK_OCO,
 
        /* Module Clocks */
        MOD_CLK_BASE
@@ -72,6 +74,10 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = {
        DEF_FIXED(".s3",       CLK_S3,             CLK_PLL1,       6, 1),
        DEF_FIXED(".sdsrc",    CLK_SDSRC,          CLK_PLL1,       2, 1),
 
+       DEF_DIV6_RO(".r",      CLK_RINT,           CLK_EXTAL, CPG_RCKCR, 32),
+
+       DEF_RATE(".oco",       CLK_OCO,            8 * 1000 * 1000),
+
        /* Core Clock Outputs */
        DEF_FIXED("za2",       R8A77990_CLK_ZA2,   CLK_PLL0D24,    1, 1),
        DEF_FIXED("za8",       R8A77990_CLK_ZA8,   CLK_PLL0D8,     1, 1),
@@ -100,8 +106,8 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = {
        DEF_FIXED("cl",        R8A77990_CLK_CL,    CLK_PLL1,      48, 1),
        DEF_FIXED("cp",        R8A77990_CLK_CP,    CLK_EXTAL,      2, 1),
        DEF_FIXED("cpex",      R8A77990_CLK_CPEX,  CLK_EXTAL,      4, 1),
-       DEF_FIXED("osc",       R8A77990_CLK_OSC,   CLK_EXTAL,    384, 1),
-       DEF_FIXED("r",         R8A77990_CLK_R,     CLK_EXTAL,   1536, 1),
+
+       DEF_DIV6_RO("osc",     R8A77990_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
 
        DEF_GEN3_PE("s0d6c",   R8A77990_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2),
        DEF_GEN3_PE("s3d1c",   R8A77990_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1),
@@ -111,6 +117,8 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = {
        DEF_DIV6P1("canfd",    R8A77990_CLK_CANFD, CLK_PLL0D6, 0x244),
        DEF_DIV6P1("csi0",     R8A77990_CLK_CSI0,  CLK_PLL1D2, 0x00c),
        DEF_DIV6P1("mso",      R8A77990_CLK_MSO,   CLK_PLL1D2, 0x014),
+
+       DEF_GEN3_RCKSEL("r",   R8A77990_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4),
 };
 
 static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = {
@@ -202,6 +210,7 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = {
        DEF_MOD("i2c1",                  930,   R8A77990_CLK_S3D2),
        DEF_MOD("i2c0",                  931,   R8A77990_CLK_S3D2),
 
+       DEF_MOD("i2c7",                 1003,   R8A77990_CLK_S3D2),
        DEF_MOD("ssi-all",              1005,   R8A77990_CLK_S3D4),
        DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
        DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
@@ -241,8 +250,8 @@ static const unsigned int r8a77990_crit_mod_clks[] __initconst = {
 /*
  * MD19                EXTAL (MHz)     PLL0            PLL1            PLL3
  *--------------------------------------------------------------------
- * 0           48 x 1          x100/4          x100/3          x100/3
- * 1           48 x 1          x100/4          x100/3           x58/3
+ * 0           48 x 1          x100/1          x100/3          x100/3
+ * 1           48 x 1          x100/1          x100/3           x58/3
  */
 #define CPG_PLL_CONFIG_INDEX(md)       (((md) & BIT(19)) >> 19)
 
index ea4cafbe6e851aca89c24f79b4912b1a2278d774..47e60e3dbe05ff18252c7513ec2bd5e3c5b39aff 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a77995 Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -7,10 +8,6 @@
  *
  * Copyright (C) 2015 Glider bvba
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/device.h>
@@ -46,6 +43,8 @@ enum clk_ids {
        CLK_S3,
        CLK_SDSRC,
        CLK_SSPSRC,
+       CLK_RINT,
+       CLK_OCO,
 
        /* Module Clocks */
        MOD_CLK_BASE
@@ -72,6 +71,10 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
        DEF_FIXED(".s3",       CLK_S3,             CLK_PLL1,       6, 1),
        DEF_FIXED(".sdsrc",    CLK_SDSRC,          CLK_PLL1,       2, 1),
 
+       DEF_DIV6_RO(".r",      CLK_RINT,           CLK_EXTAL, CPG_RCKCR, 32),
+
+       DEF_RATE(".oco",       CLK_OCO,            8 * 1000 * 1000),
+
        /* Core Clock Outputs */
        DEF_FIXED("z2",        R8A77995_CLK_Z2,    CLK_PLL0D3,     1, 1),
        DEF_FIXED("ztr",       R8A77995_CLK_ZTR,   CLK_PLL1,       6, 1),
@@ -90,8 +93,8 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
 
        DEF_FIXED("cl",        R8A77995_CLK_CL,    CLK_PLL1,      48, 1),
        DEF_FIXED("cp",        R8A77995_CLK_CP,    CLK_EXTAL,      2, 1),
-       DEF_FIXED("osc",       R8A77995_CLK_OSC,   CLK_EXTAL,    384, 1),
-       DEF_FIXED("r",         R8A77995_CLK_R,     CLK_EXTAL,   1536, 1),
+
+       DEF_DIV6_RO("osc",     R8A77995_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
 
        DEF_GEN3_PE("s1d4c",   R8A77995_CLK_S1D4C, CLK_S1, 4, CLK_PE, 2),
        DEF_GEN3_PE("s3d1c",   R8A77995_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1),
@@ -102,6 +105,8 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
 
        DEF_DIV6P1("canfd",    R8A77995_CLK_CANFD, CLK_PLL0D3,    0x244),
        DEF_DIV6P1("mso",      R8A77995_CLK_MSO,   CLK_PLL1D2,    0x014),
+
+       DEF_GEN3_RCKSEL("r",   R8A77995_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4),
 };
 
 static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = {
index a0b6ecdc63dd3bba3af1675da498c6429fb99904..6d2b56891559725d3d22bf53444b5854feb37a82 100644 (file)
@@ -539,7 +539,8 @@ r9a06g032_div_round_rate(struct clk_hw *hw,
         * several uarts attached to this divider, and changing this impacts
         * everyone.
         */
-       if (clk->index == R9A06G032_DIV_UART) {
+       if (clk->index == R9A06G032_DIV_UART ||
+           clk->index == R9A06G032_DIV_P2_PG) {
                pr_devel("%s div uart hack!\n", __func__);
                return clk_get_rate(hw->clk);
        }
index daf88bc2cdae177becd5adaea85c886a6c56ffc8..f596a2dafcf4d8d1548b53ed506063f984578816 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car Gen2 Clock Pulse Generator
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
  */
 
 #include <linux/bug.h>
index 020a3baad0154231fb397792912fed327f39a0c1..bff9551c7a38a01e90506cc8f424a9b267cb981a 100644 (file)
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * R-Car Gen2 Clock Pulse Generator
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation; version 2 of the License.
  */
 
 #ifndef __CLK_RENESAS_RCAR_GEN2_CPG_H__
index 628b63b85d3f09c5cfdf37dea4b565953e41264a..4ba38f98cc7bab8296631c04e1d3901870e4891e 100644 (file)
@@ -1,15 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car Gen3 Clock Pulse Generator
  *
- * Copyright (C) 2015-2016 Glider bvba
+ * Copyright (C) 2015-2018 Glider bvba
  *
  * Based on clk-rcar-gen3.c
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
@@ -31,6 +28,8 @@
 #define CPG_PLL2CR             0x002c
 #define CPG_PLL4CR             0x01f4
 
+#define CPG_RCKCR_CKSEL        BIT(15) /* RCLK Clock Source Select */
+
 struct cpg_simple_notifier {
        struct notifier_block nb;
        void __iomem *reg;
@@ -444,7 +443,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
        unsigned int div = 1;
        u32 value;
 
-       parent = clks[core->parent & 0xffff];   /* CLK_TYPE_PE uses high bits */
+       parent = clks[core->parent & 0xffff];   /* some types use high bits */
        if (IS_ERR(parent))
                return ERR_CAST(parent);
 
@@ -524,7 +523,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
 
                        if (clk_get_rate(clks[cpg_clk_extalr])) {
                                parent = clks[cpg_clk_extalr];
-                               value |= BIT(15);
+                               value |= CPG_RCKCR_CKSEL;
                        }
 
                        writel(value, csn->reg);
@@ -537,16 +536,14 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
                        parent = clks[cpg_clk_extalr];
                break;
 
-       case CLK_TYPE_GEN3_PE:
+       case CLK_TYPE_GEN3_MDSEL:
                /*
-                * Peripheral clock with a fixed divider, selectable between
-                * clean and spread spectrum parents using MD12
+                * Clock selectable between two parents and two fixed dividers
+                * using a mode pin
                 */
-               if (cpg_mode & BIT(12)) {
-                       /* Clean */
+               if (cpg_mode & BIT(core->offset)) {
                        div = core->div & 0xffff;
                } else {
-                       /* SCCG */
                        parent = clks[core->parent >> 16];
                        if (IS_ERR(parent))
                                return ERR_CAST(parent);
@@ -563,6 +560,28 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
                return cpg_z_clk_register(core->name, __clk_get_name(parent),
                                          base, CPG_FRQCRC_Z2FC_MASK);
 
+       case CLK_TYPE_GEN3_OSC:
+               /*
+                * Clock combining OSC EXTAL predivider and a fixed divider
+                */
+               div = cpg_pll_config->osc_prediv * core->div;
+               break;
+
+       case CLK_TYPE_GEN3_RCKSEL:
+               /*
+                * Clock selectable between two parents and two fixed dividers
+                * using RCKCR.CKSEL
+                */
+               if (readl(base + CPG_RCKCR) & CPG_RCKCR_CKSEL) {
+                       div = core->div & 0xffff;
+               } else {
+                       parent = clks[core->parent >> 16];
+                       if (IS_ERR(parent))
+                               return ERR_CAST(parent);
+                       div = core->div >> 16;
+               }
+               break;
+
        default:
                return ERR_PTR(-EINVAL);
        }
index ea4f8fc3c4c972e79418cef9a251bad3bd4fcbee..f4fb6cf16688cfb3d34a07f8add2764a181c46d9 100644 (file)
@@ -1,11 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * R-Car Gen3 Clock Pulse Generator
  *
- * Copyright (C) 2015-2016 Glider bvba
+ * Copyright (C) 2015-2018 Glider bvba
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #ifndef __CLK_RENESAS_RCAR_GEN3_CPG_H__
@@ -20,19 +18,35 @@ enum rcar_gen3_clk_types {
        CLK_TYPE_GEN3_PLL4,
        CLK_TYPE_GEN3_SD,
        CLK_TYPE_GEN3_R,
-       CLK_TYPE_GEN3_PE,
+       CLK_TYPE_GEN3_MDSEL,    /* Select parent/divider using mode pin */
        CLK_TYPE_GEN3_Z,
        CLK_TYPE_GEN3_Z2,
+       CLK_TYPE_GEN3_OSC,      /* OSC EXTAL predivider and fixed divider */
+       CLK_TYPE_GEN3_RCKSEL,   /* Select parent/divider using RCKCR.CKSEL */
+
+       /* SoC specific definitions start here */
+       CLK_TYPE_GEN3_SOC_BASE,
 };
 
 #define DEF_GEN3_SD(_name, _id, _parent, _offset)      \
        DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
 
+#define DEF_GEN3_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN3_MDSEL,       \
+                (_parent0) << 16 | (_parent1),         \
+                .div = (_div0) << 16 | (_div1), .offset = _md)
+
 #define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \
                    _div_clean) \
-       DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE,                  \
-                (_parent_sscg) << 16 | (_parent_clean),        \
-                .div = (_div_sscg) << 16 | (_div_clean))
+       DEF_GEN3_MDSEL(_name, _id, 12, _parent_sscg, _div_sscg, \
+                      _parent_clean, _div_clean)
+
+#define DEF_GEN3_OSC(_name, _id, _parent, _div)                \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN3_OSC, _parent, .div = _div)
+
+#define DEF_GEN3_RCKSEL(_name, _id, _parent0, _div0, _parent1, _div1) \
+       DEF_BASE(_name, _id, CLK_TYPE_GEN3_RCKSEL,      \
+                (_parent0) << 16 | (_parent1), .div = (_div0) << 16 | (_div1))
 
 struct rcar_gen3_cpg_pll_config {
        u8 extal_div;
@@ -40,6 +54,7 @@ struct rcar_gen3_cpg_pll_config {
        u8 pll1_div;
        u8 pll3_mult;
        u8 pll3_div;
+       u8 osc_prediv;
 };
 
 #define CPG_RCKCR      0x240
index 6cd030a589641335fb10e1137bf6a4d476dba182..b241f9ca3d7146ba85b27ffff0355cc0e9f32277 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car USB2.0 clock selector
  *
@@ -6,10 +7,6 @@
  * Based on renesas-cpg-mssr.c
  *
  * Copyright (C) 2015 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk.h>
index f4b013e9352d9efca6260c5ca763e8fcc53eb6f5..f7bb817420b4fdbb681680fb6bed29dbaf8b9bf4 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas Clock Pulse Generator / Module Standby and Software Reset
  *
@@ -7,10 +8,6 @@
  *
  * Copyright (C) 2013 Ideas On Board SPRL
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/clk.h>
@@ -73,6 +70,17 @@ static const u16 smstpcr[] = {
 
 #define        SMSTPCR(i)      smstpcr[i]
 
+/*
+ * Standby Control Register offsets (RZ/A)
+ * Base address is FRQCR register
+ */
+
+static const u16 stbcr[] = {
+       0xFFFF/*dummy*/, 0x010, 0x014, 0x410, 0x414, 0x418, 0x41C, 0x420,
+       0x424, 0x428, 0x42C,
+};
+
+#define        STBCR(i)        stbcr[i]
 
 /*
  * Software Reset Register offsets
@@ -110,6 +118,7 @@ static const u16 srcr[] = {
  * @notifiers: Notifier chain to save/restore clock state for system resume
  * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control
  * @smstpcr_saved[].val: Saved values of SMSTPCR[]
+ * @stbyctrl: This device has Standby Control Registers
  */
 struct cpg_mssr_priv {
 #ifdef CONFIG_RESET_CONTROLLER
@@ -118,11 +127,13 @@ struct cpg_mssr_priv {
        struct device *dev;
        void __iomem *base;
        spinlock_t rmw_lock;
+       struct device_node *np;
 
        struct clk **clks;
        unsigned int num_core_clks;
        unsigned int num_mod_clks;
        unsigned int last_dt_core_clk;
+       bool stbyctrl;
 
        struct raw_notifier_head notifiers;
        struct {
@@ -131,6 +142,7 @@ struct cpg_mssr_priv {
        } smstpcr_saved[ARRAY_SIZE(smstpcr)];
 };
 
+static struct cpg_mssr_priv *cpg_mssr_priv;
 
 /**
  * struct mstp_clock - MSTP gating clock
@@ -162,16 +174,29 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
                enable ? "ON" : "OFF");
        spin_lock_irqsave(&priv->rmw_lock, flags);
 
-       value = readl(priv->base + SMSTPCR(reg));
-       if (enable)
-               value &= ~bitmask;
-       else
-               value |= bitmask;
-       writel(value, priv->base + SMSTPCR(reg));
+       if (priv->stbyctrl) {
+               value = readb(priv->base + STBCR(reg));
+               if (enable)
+                       value &= ~bitmask;
+               else
+                       value |= bitmask;
+               writeb(value, priv->base + STBCR(reg));
+
+               /* dummy read to ensure write has completed */
+               readb(priv->base + STBCR(reg));
+               barrier_data(priv->base + STBCR(reg));
+       } else {
+               value = readl(priv->base + SMSTPCR(reg));
+               if (enable)
+                       value &= ~bitmask;
+               else
+                       value |= bitmask;
+               writel(value, priv->base + SMSTPCR(reg));
+       }
 
        spin_unlock_irqrestore(&priv->rmw_lock, flags);
 
-       if (!enable)
+       if (!enable || priv->stbyctrl)
                return 0;
 
        for (i = 1000; i > 0; --i) {
@@ -205,7 +230,10 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
        struct cpg_mssr_priv *priv = clock->priv;
        u32 value;
 
-       value = readl(priv->base + MSTPSR(clock->index / 32));
+       if (priv->stbyctrl)
+               value = readb(priv->base + STBCR(clock->index / 32));
+       else
+               value = readl(priv->base + MSTPSR(clock->index / 32));
 
        return !(value & BIT(clock->index % 32));
 }
@@ -226,6 +254,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
        unsigned int idx;
        const char *type;
        struct clk *clk;
+       int range_check;
 
        switch (clkspec->args[0]) {
        case CPG_CORE:
@@ -240,8 +269,14 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
 
        case CPG_MOD:
                type = "module";
-               idx = MOD_CLK_PACK(clkidx);
-               if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) {
+               if (priv->stbyctrl) {
+                       idx = MOD_CLK_PACK_10(clkidx);
+                       range_check = 7 - (clkidx % 10);
+               } else {
+                       idx = MOD_CLK_PACK(clkidx);
+                       range_check = 31 - (clkidx % 100);
+               }
+               if (range_check < 0 || idx >= priv->num_mod_clks) {
                        dev_err(dev, "Invalid %s clock index %u\n", type,
                                clkidx);
                        return ERR_PTR(-EINVAL);
@@ -283,7 +318,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
 
        switch (core->type) {
        case CLK_TYPE_IN:
-               clk = of_clk_get_by_name(priv->dev->of_node, core->name);
+               clk = of_clk_get_by_name(priv->np, core->name);
                break;
 
        case CLK_TYPE_FF:
@@ -313,6 +348,11 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
                }
                break;
 
+       case CLK_TYPE_FR:
+               clk = clk_register_fixed_rate(NULL, core->name, NULL, 0,
+                                             core->mult);
+               break;
+
        default:
                if (info->cpg_clk_register)
                        clk = info->cpg_clk_register(dev, core, info,
@@ -641,11 +681,22 @@ static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
 
 
 static const struct of_device_id cpg_mssr_match[] = {
+#ifdef CONFIG_CLK_R7S9210
+       {
+               .compatible = "renesas,r7s9210-cpg-mssr",
+               .data = &r7s9210_cpg_mssr_info,
+       },
+#endif
 #ifdef CONFIG_CLK_R8A7743
        {
                .compatible = "renesas,r8a7743-cpg-mssr",
                .data = &r8a7743_cpg_mssr_info,
        },
+       /* RZ/G1N is (almost) identical to RZ/G1M w.r.t. clocks. */
+       {
+               .compatible = "renesas,r8a7744-cpg-mssr",
+               .data = &r8a7743_cpg_mssr_info,
+       },
 #endif
 #ifdef CONFIG_CLK_R8A7745
        {
@@ -659,6 +710,18 @@ static const struct of_device_id cpg_mssr_match[] = {
                .data = &r8a77470_cpg_mssr_info,
        },
 #endif
+#ifdef CONFIG_CLK_R8A774A1
+       {
+               .compatible = "renesas,r8a774a1-cpg-mssr",
+               .data = &r8a774a1_cpg_mssr_info,
+       },
+#endif
+#ifdef CONFIG_CLK_R8A774C0
+       {
+               .compatible = "renesas,r8a774c0-cpg-mssr",
+               .data = &r8a774c0_cpg_mssr_info,
+       },
+#endif
 #ifdef CONFIG_CLK_R8A7790
        {
                .compatible = "renesas,r8a7790-cpg-mssr",
@@ -780,13 +843,23 @@ static int cpg_mssr_resume_noirq(struct device *dev)
                if (!mask)
                        continue;
 
-               oldval = readl(priv->base + SMSTPCR(reg));
+               if (priv->stbyctrl)
+                       oldval = readb(priv->base + STBCR(reg));
+               else
+                       oldval = readl(priv->base + SMSTPCR(reg));
                newval = oldval & ~mask;
                newval |= priv->smstpcr_saved[reg].val & mask;
                if (newval == oldval)
                        continue;
 
-               writel(newval, priv->base + SMSTPCR(reg));
+               if (priv->stbyctrl) {
+                       writeb(newval, priv->base + STBCR(reg));
+                       /* dummy read to ensure write has completed */
+                       readb(priv->base + STBCR(reg));
+                       barrier_data(priv->base + STBCR(reg));
+                       continue;
+               } else
+                       writel(newval, priv->base + SMSTPCR(reg));
 
                /* Wait until enabled clocks are really enabled */
                mask &= ~priv->smstpcr_saved[reg].val;
@@ -817,61 +890,115 @@ static const struct dev_pm_ops cpg_mssr_pm = {
 #define DEV_PM_OPS     NULL
 #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
 
-static int __init cpg_mssr_probe(struct platform_device *pdev)
+static int __init cpg_mssr_common_init(struct device *dev,
+                                      struct device_node *np,
+                                      const struct cpg_mssr_info *info)
 {
-       struct device *dev = &pdev->dev;
-       struct device_node *np = dev->of_node;
-       const struct cpg_mssr_info *info;
        struct cpg_mssr_priv *priv;
+       struct clk **clks = NULL;
        unsigned int nclks, i;
-       struct resource *res;
-       struct clk **clks;
        int error;
 
-       info = of_device_get_match_data(dev);
        if (info->init) {
                error = info->init(dev);
                if (error)
                        return error;
        }
 
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
+       priv->np = np;
        priv->dev = dev;
        spin_lock_init(&priv->rmw_lock);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(priv->base))
-               return PTR_ERR(priv->base);
+       priv->base = of_iomap(np, 0);
+       if (!priv->base) {
+               error = -ENOMEM;
+               goto out_err;
+       }
 
        nclks = info->num_total_core_clks + info->num_hw_mod_clks;
-       clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);
-       if (!clks)
-               return -ENOMEM;
+       clks = kmalloc_array(nclks, sizeof(*clks), GFP_KERNEL);
+       if (!clks) {
+               error = -ENOMEM;
+               goto out_err;
+       }
 
-       dev_set_drvdata(dev, priv);
+       cpg_mssr_priv = priv;
        priv->clks = clks;
        priv->num_core_clks = info->num_total_core_clks;
        priv->num_mod_clks = info->num_hw_mod_clks;
        priv->last_dt_core_clk = info->last_dt_core_clk;
        RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
+       priv->stbyctrl = info->stbyctrl;
 
        for (i = 0; i < nclks; i++)
                clks[i] = ERR_PTR(-ENOENT);
 
+       error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
+       if (error)
+               goto out_err;
+
+       return 0;
+
+out_err:
+       kfree(clks);
+       if (priv->base)
+               iounmap(priv->base);
+       kfree(priv);
+
+       return error;
+}
+
+void __init cpg_mssr_early_init(struct device_node *np,
+                               const struct cpg_mssr_info *info)
+{
+       int error;
+       int i;
+
+       error = cpg_mssr_common_init(NULL, np, info);
+       if (error)
+               return;
+
+       for (i = 0; i < info->num_early_core_clks; i++)
+               cpg_mssr_register_core_clk(&info->early_core_clks[i], info,
+                                          cpg_mssr_priv);
+
+       for (i = 0; i < info->num_early_mod_clks; i++)
+               cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info,
+                                         cpg_mssr_priv);
+
+}
+
+static int __init cpg_mssr_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       const struct cpg_mssr_info *info;
+       struct cpg_mssr_priv *priv;
+       unsigned int i;
+       int error;
+
+       info = of_device_get_match_data(dev);
+
+       if (!cpg_mssr_priv) {
+               error = cpg_mssr_common_init(dev, dev->of_node, info);
+               if (error)
+                       return error;
+       }
+
+       priv = cpg_mssr_priv;
+       priv->dev = dev;
+       dev_set_drvdata(dev, priv);
+
        for (i = 0; i < info->num_core_clks; i++)
                cpg_mssr_register_core_clk(&info->core_clks[i], info, priv);
 
        for (i = 0; i < info->num_mod_clks; i++)
                cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv);
 
-       error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
-       if (error)
-               return error;
-
        error = devm_add_action_or_reset(dev,
                                         cpg_mssr_del_clk_provider,
                                         np);
@@ -883,6 +1010,10 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
        if (error)
                return error;
 
+       /* Reset Controller not supported for Standby Control SoCs */
+       if (info->stbyctrl)
+               return 0;
+
        error = cpg_mssr_reset_controller_register(priv);
        if (error)
                return error;
index 642f720b9b055337f554357be8904463d38bce4d..c4ec9df146fd990e90bb3b93b78e93c1d14e811c 100644 (file)
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * Renesas Clock Pulse Generator / Module Standby and Software Reset
  *
  * Copyright (C) 2015 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #ifndef __CLK_RENESAS_CPG_MSSR_H__
@@ -38,6 +35,7 @@ enum clk_types {
        CLK_TYPE_FF,            /* Fixed Factor Clock */
        CLK_TYPE_DIV6P1,        /* DIV6 Clock with 1 parent clock */
        CLK_TYPE_DIV6_RO,       /* DIV6 Clock read only with extra divisor */
+       CLK_TYPE_FR,            /* Fixed Rate Clock */
 
        /* Custom definitions start here */
        CLK_TYPE_CUSTOM,
@@ -56,6 +54,8 @@ enum clk_types {
        DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
 #define DEF_DIV6_RO(_name, _id, _parent, _offset, _div)        \
        DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
+#define DEF_RATE(_name, _id, _rate)    \
+       DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate)
 
     /*
      * Definitions of Module Clocks
@@ -75,12 +75,24 @@ struct mssr_mod_clk {
 #define DEF_MOD(_name, _mod, _parent...)       \
        { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent }
 
+/* Convert from sparse base-10 to packed index space */
+#define MOD_CLK_PACK_10(x)     ((x / 10) * 32 + (x % 10))
+
+#define MOD_CLK_ID_10(x)       (MOD_CLK_BASE + MOD_CLK_PACK_10(x))
+
+#define DEF_MOD_STB(_name, _mod, _parent...)   \
+       { .name = _name, .id = MOD_CLK_ID_10(_mod), .parent = _parent }
 
 struct device_node;
 
     /**
      * SoC-specific CPG/MSSR Description
      *
+     * @early_core_clks: Array of Early Core Clock definitions
+     * @num_early_core_clks: Number of entries in early_core_clks[]
+     * @early_mod_clks: Array of Early Module Clock definitions
+     * @num_early_mod_clks: Number of entries in early_mod_clks[]
+     *
      * @core_clks: Array of Core Clock definitions
      * @num_core_clks: Number of entries in core_clks[]
      * @last_dt_core_clk: ID of the last Core Clock exported to DT
@@ -100,14 +112,25 @@ struct device_node;
      *
      * @init: Optional callback to perform SoC-specific initialization
      * @cpg_clk_register: Optional callback to handle special Core Clock types
+     *
+     * @stbyctrl: This device has Standby Control Registers which are 8-bits
+     *            wide, no status registers (MSTPSR) and have different address
+     *            offsets.
      */
 
 struct cpg_mssr_info {
+       /* Early Clocks */
+       const struct cpg_core_clk *early_core_clks;
+       unsigned int num_early_core_clks;
+       const struct mssr_mod_clk *early_mod_clks;
+       unsigned int num_early_mod_clks;
+
        /* Core Clocks */
        const struct cpg_core_clk *core_clks;
        unsigned int num_core_clks;
        unsigned int last_dt_core_clk;
        unsigned int num_total_core_clks;
+       bool stbyctrl;
 
        /* Module Clocks */
        const struct mssr_mod_clk *mod_clks;
@@ -131,9 +154,12 @@ struct cpg_mssr_info {
                                        struct raw_notifier_head *notifiers);
 };
 
+extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77470_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7790_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7791_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7792_cpg_mssr_info;
@@ -146,6 +172,8 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77990_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
 
+void __init cpg_mssr_early_init(struct device_node *np,
+                               const struct cpg_mssr_info *info);
 
     /*
      * Helpers for fixing up clock tables depending on SoC revision
index e8075359366b0d9ef9cf84611d6c36b19fc22c4a..ebce5260068b72a9e2013e3aeaddc61f7cf252d8 100644 (file)
@@ -80,16 +80,12 @@ static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
 static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
 {
        struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
-       int num_parents = clk_hw_get_num_parents(hw);
        u32 val;
 
        val = clk_readl(ddrclk->reg_base +
                        ddrclk->mux_offset) >> ddrclk->mux_shift;
        val &= GENMASK(ddrclk->mux_width - 1, 0);
 
-       if (val >= num_parents)
-               return -EINVAL;
-
        return val;
 }
 
index 67e73fd71f095c9b1164e26a5422c4d8f5edd6ee..fa25e35ce7d5d9670643e93093568640c2cad480 100644 (file)
@@ -645,7 +645,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
        GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
        GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
        GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
-       GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
+       GATE(HCLK_HDMI, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 
        GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(5), 14, GFLAGS),
index 450de24a1b4224cd9386881c7c25471f32899060..5a67b7869960e6c87ded5fee5508fa70088841a6 100644 (file)
@@ -83,22 +83,43 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
        RK3066_PLL_RATE( 768000000, 1, 64, 2),
        RK3066_PLL_RATE( 742500000, 8, 495, 2),
        RK3066_PLL_RATE( 696000000, 1, 58, 2),
+       RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1),
        RK3066_PLL_RATE( 600000000, 1, 50, 2),
        RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1),
        RK3066_PLL_RATE( 552000000, 1, 46, 2),
        RK3066_PLL_RATE( 504000000, 1, 84, 4),
        RK3066_PLL_RATE( 500000000, 3, 125, 2),
        RK3066_PLL_RATE( 456000000, 1, 76, 4),
+       RK3066_PLL_RATE( 428000000, 1, 107, 6),
        RK3066_PLL_RATE( 408000000, 1, 68, 4),
        RK3066_PLL_RATE( 400000000, 3, 100, 2),
+       RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1),
        RK3066_PLL_RATE( 384000000, 2, 128, 4),
        RK3066_PLL_RATE( 360000000, 1, 60, 4),
+       RK3066_PLL_RATE_NB( 356000000, 1, 178, 12, 1),
+       RK3066_PLL_RATE_NB( 324000000, 1, 189, 14, 1),
        RK3066_PLL_RATE( 312000000, 1, 52, 4),
-       RK3066_PLL_RATE( 300000000, 1, 50, 4),
-       RK3066_PLL_RATE( 297000000, 2, 198, 8),
+       RK3066_PLL_RATE_NB( 308000000, 1, 154, 12, 1),
+       RK3066_PLL_RATE_NB( 303000000, 1, 202, 16, 1),
+       RK3066_PLL_RATE( 300000000, 1, 75, 6),
+       RK3066_PLL_RATE_NB( 297750000, 2, 397, 16, 1),
+       RK3066_PLL_RATE_NB( 293250000, 2, 391, 16, 1),
+       RK3066_PLL_RATE_NB( 292500000, 1, 195, 16, 1),
+       RK3066_PLL_RATE( 273600000, 1, 114, 10),
+       RK3066_PLL_RATE_NB( 273000000, 1, 182, 16, 1),
+       RK3066_PLL_RATE_NB( 270000000, 1, 180, 16, 1),
+       RK3066_PLL_RATE_NB( 266250000, 2, 355, 16, 1),
+       RK3066_PLL_RATE_NB( 256500000, 1, 171, 16, 1),
        RK3066_PLL_RATE( 252000000, 1, 84, 8),
-       RK3066_PLL_RATE( 216000000, 1, 72, 8),
-       RK3066_PLL_RATE( 148500000, 2, 99, 8),
+       RK3066_PLL_RATE_NB( 250500000, 1, 167, 16, 1),
+       RK3066_PLL_RATE_NB( 243428571, 1, 142, 14, 1),
+       RK3066_PLL_RATE( 238000000, 1, 119, 12),
+       RK3066_PLL_RATE_NB( 219750000, 2, 293, 16, 1),
+       RK3066_PLL_RATE_NB( 216000000, 1, 144, 16, 1),
+       RK3066_PLL_RATE_NB( 213000000, 1, 142, 16, 1),
+       RK3066_PLL_RATE( 195428571, 1, 114, 14),
+       RK3066_PLL_RATE( 160000000, 1, 80, 12),
+       RK3066_PLL_RATE( 157500000, 1, 105, 16),
        RK3066_PLL_RATE( 126000000, 1, 84, 16),
        RK3066_PLL_RATE(  48000000, 1, 64, 32),
        { /* sentinel */ },
index 252366a5231f766dd6a9df28fb7a755b7a6021f7..2c54266077907a4cee349fbe9f5a80180477dad5 100644 (file)
@@ -813,22 +813,22 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
        MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc",
            RK3328_SDMMC_CON0, 1),
        MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc",
-           RK3328_SDMMC_CON1, 1),
+           RK3328_SDMMC_CON1, 0),
 
        MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio",
            RK3328_SDIO_CON0, 1),
        MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio",
-           RK3328_SDIO_CON1, 1),
+           RK3328_SDIO_CON1, 0),
 
        MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc",
            RK3328_EMMC_CON0, 1),
        MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc",
-           RK3328_EMMC_CON1, 1),
+           RK3328_EMMC_CON1, 0),
 
        MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext",
            RK3328_SDMMC_EXT_CON0, 1),
        MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext",
-           RK3328_SDMMC_EXT_CON1, 1),
+           RK3328_SDMMC_EXT_CON1, 0),
 };
 
 static const char *const rk3328_critical_clocks[] __initconst = {
index d2c99d8916b83e48c1b23d6c49dd98f43f81f2db..a5fddebbe530532be49c3c4dc7e3cfdf6d6deea0 100644 (file)
@@ -152,7 +152,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
                        struct exynos_cpuclk *cpuclk, void __iomem *base)
 {
        const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-       unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
+       unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
        unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
        unsigned long div0, div1 = 0, mux_reg;
        unsigned long flags;
@@ -280,7 +280,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
                        struct exynos_cpuclk *cpuclk, void __iomem *base)
 {
        const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
-       unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
+       unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
        unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
        unsigned long div0, div1 = 0, mux_reg;
        unsigned long flags;
@@ -432,7 +432,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
        else
                cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
 
-       cpuclk->alt_parent = __clk_lookup(alt_parent);
+       cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent));
        if (!cpuclk->alt_parent) {
                pr_err("%s: could not lookup alternate parent %s\n",
                                __func__, alt_parent);
index d4b6b517fe1b44689df28853cf894baa3799153d..bd38c6aa389706c92261cd72f4f0c8fd8906ba67 100644 (file)
@@ -49,7 +49,7 @@ struct exynos_cpuclk_cfg_data {
  */
 struct exynos_cpuclk {
        struct clk_hw                           hw;
-       struct clk                              *alt_parent;
+       struct clk_hw                           *alt_parent;
        void __iomem                            *ctrl_base;
        spinlock_t                              *lock;
        const struct exynos_cpuclk_cfg_data     *cfg;
index f659c5cbf1d5d6d70a965582166221e61911cfb1..8f8a0f9fc842d9f7d1a0ba38a9f871c01d324cff 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
-#include <linux/syscore_ops.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
index 27c9d23657b32fbab4b43ee6459fca3d11a46be8..0e9a41a4cac8da875ee71645fd6803aff005d513 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
-#include <linux/syscore_ops.h>
 
 #include <dt-bindings/clock/exynos3250.h>
 
index 0421960eb96333048e709c4df6308c3e8338fb7b..59d4d46667ce51d0043bb9d02e5f2d8b82179c93 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 
 #include "clk.h"
 #include "clk-cpu.h"
 #define CLKOUT_CMU_CPU         0x14a00
 #define PWR_CTRL1              0x15020
 #define E4X12_PWR_CTRL2                0x15024
-#define E4X12_DIV_ISP0         0x18300
-#define E4X12_DIV_ISP1         0x18304
-#define E4X12_GATE_ISP0                0x18800
-#define E4X12_GATE_ISP1                0x18804
 
 /* Below definitions are used for PWR_CTRL settings */
 #define PWR_CTRL1_CORE2_DOWN_RATIO(x)          (((x) & 0x7) << 28)
@@ -157,14 +152,6 @@ enum exynos4_plls {
 static void __iomem *reg_base;
 static enum exynos4_soc exynos4_soc;
 
-/*
- * Support for CMU save/restore across system suspends
- */
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos4_save_common;
-static struct samsung_clk_reg_dump *exynos4_save_soc;
-static struct samsung_clk_reg_dump *exynos4_save_pll;
-
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -192,7 +179,7 @@ static const unsigned long exynos4x12_clk_save[] __initconst = {
        E4X12_PWR_CTRL2,
 };
 
-static const unsigned long exynos4_clk_pll_regs[] __initconst = {
+static const unsigned long exynos4_clk_regs[] __initconst = {
        EPLL_LOCK,
        VPLL_LOCK,
        EPLL_CON0,
@@ -201,9 +188,6 @@ static const unsigned long exynos4_clk_pll_regs[] __initconst = {
        VPLL_CON0,
        VPLL_CON1,
        VPLL_CON2,
-};
-
-static const unsigned long exynos4_clk_regs[] __initconst = {
        SRC_LEFTBUS,
        DIV_LEFTBUS,
        GATE_IP_LEFTBUS,
@@ -276,6 +260,8 @@ static const unsigned long exynos4_clk_regs[] __initconst = {
 };
 
 static const struct samsung_clk_reg_dump src_mask_suspend[] = {
+       { .offset = VPLL_CON0,                  .value = 0x80600302, },
+       { .offset = EPLL_CON0,                  .value = 0x806F0302, },
        { .offset = SRC_MASK_TOP,               .value = 0x00000001, },
        { .offset = SRC_MASK_CAM,               .value = 0x11111111, },
        { .offset = SRC_MASK_TV,                .value = 0x00000111, },
@@ -291,123 +277,6 @@ static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = {
        { .offset = E4210_SRC_MASK_LCD1,        .value = 0x00001111, },
 };
 
-#define PLL_ENABLED    (1 << 31)
-#define PLL_LOCKED     (1 << 29)
-
-static void exynos4_clk_enable_pll(u32 reg)
-{
-       u32 pll_con = readl(reg_base + reg);
-       pll_con |= PLL_ENABLED;
-       writel(pll_con, reg_base + reg);
-
-       while (!(pll_con & PLL_LOCKED)) {
-               cpu_relax();
-               pll_con = readl(reg_base + reg);
-       }
-}
-
-static void exynos4_clk_wait_for_pll(u32 reg)
-{
-       u32 pll_con;
-
-       pll_con = readl(reg_base + reg);
-       if (!(pll_con & PLL_ENABLED))
-               return;
-
-       while (!(pll_con & PLL_LOCKED)) {
-               cpu_relax();
-               pll_con = readl(reg_base + reg);
-       }
-}
-
-static int exynos4_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, exynos4_save_common,
-                               ARRAY_SIZE(exynos4_clk_regs));
-       samsung_clk_save(reg_base, exynos4_save_pll,
-                               ARRAY_SIZE(exynos4_clk_pll_regs));
-
-       exynos4_clk_enable_pll(EPLL_CON0);
-       exynos4_clk_enable_pll(VPLL_CON0);
-
-       if (exynos4_soc == EXYNOS4210) {
-               samsung_clk_save(reg_base, exynos4_save_soc,
-                                       ARRAY_SIZE(exynos4210_clk_save));
-               samsung_clk_restore(reg_base, src_mask_suspend_e4210,
-                                       ARRAY_SIZE(src_mask_suspend_e4210));
-       } else {
-               samsung_clk_save(reg_base, exynos4_save_soc,
-                                       ARRAY_SIZE(exynos4x12_clk_save));
-       }
-
-       samsung_clk_restore(reg_base, src_mask_suspend,
-                                       ARRAY_SIZE(src_mask_suspend));
-
-       return 0;
-}
-
-static void exynos4_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, exynos4_save_pll,
-                               ARRAY_SIZE(exynos4_clk_pll_regs));
-
-       exynos4_clk_wait_for_pll(EPLL_CON0);
-       exynos4_clk_wait_for_pll(VPLL_CON0);
-
-       samsung_clk_restore(reg_base, exynos4_save_common,
-                               ARRAY_SIZE(exynos4_clk_regs));
-
-       if (exynos4_soc == EXYNOS4210)
-               samsung_clk_restore(reg_base, exynos4_save_soc,
-                                       ARRAY_SIZE(exynos4210_clk_save));
-       else
-               samsung_clk_restore(reg_base, exynos4_save_soc,
-                                       ARRAY_SIZE(exynos4x12_clk_save));
-}
-
-static struct syscore_ops exynos4_clk_syscore_ops = {
-       .suspend = exynos4_clk_suspend,
-       .resume = exynos4_clk_resume,
-};
-
-static void __init exynos4_clk_sleep_init(void)
-{
-       exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs,
-                                       ARRAY_SIZE(exynos4_clk_regs));
-       if (!exynos4_save_common)
-               goto err_warn;
-
-       if (exynos4_soc == EXYNOS4210)
-               exynos4_save_soc = samsung_clk_alloc_reg_dump(
-                                       exynos4210_clk_save,
-                                       ARRAY_SIZE(exynos4210_clk_save));
-       else
-               exynos4_save_soc = samsung_clk_alloc_reg_dump(
-                                       exynos4x12_clk_save,
-                                       ARRAY_SIZE(exynos4x12_clk_save));
-       if (!exynos4_save_soc)
-               goto err_common;
-
-       exynos4_save_pll = samsung_clk_alloc_reg_dump(exynos4_clk_pll_regs,
-                                       ARRAY_SIZE(exynos4_clk_pll_regs));
-       if (!exynos4_save_pll)
-               goto err_soc;
-
-       register_syscore_ops(&exynos4_clk_syscore_ops);
-       return;
-
-err_soc:
-       kfree(exynos4_save_soc);
-err_common:
-       kfree(exynos4_save_common);
-err_warn:
-       pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-               __func__);
-}
-#else
-static void __init exynos4_clk_sleep_init(void) {}
-#endif
-
 /* list of all parent clock list */
 PNAME(mout_apll_p)     = { "fin_pll", "fout_apll", };
 PNAME(mout_mpll_p)     = { "fin_pll", "fout_mpll", };
@@ -841,18 +710,6 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
        DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
 };
 
-static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
-       DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
-                                               CLK_GET_RATE_NOCACHE, 0),
-       DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
-                                               CLK_GET_RATE_NOCACHE, 0),
-       DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
-       DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
-                                               4, 3, CLK_GET_RATE_NOCACHE, 0),
-       DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
-                                               8, 3, CLK_GET_RATE_NOCACHE, 0),
-};
-
 /* list of gate clocks supported in all exynos4 soc's */
 static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
        GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0),
@@ -1150,61 +1007,6 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
                0),
 };
 
-static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
-       GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-       GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
-                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-};
-
 /*
  * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
  * resides in chipid register space, outside of the clock controller memory
@@ -1504,8 +1306,6 @@ static void __init exynos4_clk_init(struct device_node *np,
                        e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d),
                        CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
        } else {
-               struct resource res;
-
                samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
                        ARRAY_SIZE(exynos4x12_mux_clks));
                samsung_clk_register_div(ctx, exynos4x12_div_clks,
@@ -1516,14 +1316,6 @@ static void __init exynos4_clk_init(struct device_node *np,
                        exynos4x12_fixed_factor_clks,
                        ARRAY_SIZE(exynos4x12_fixed_factor_clks));
 
-               of_address_to_resource(np, 0, &res);
-               if (resource_size(&res) > 0x18000) {
-                       samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
-                               ARRAY_SIZE(exynos4x12_isp_div_clks));
-                       samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
-                               ARRAY_SIZE(exynos4x12_isp_gate_clks));
-               }
-
                exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
                        mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
                        e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
@@ -1532,7 +1324,17 @@ static void __init exynos4_clk_init(struct device_node *np,
 
        if (soc == EXYNOS4X12)
                exynos4x12_core_down_clock();
-       exynos4_clk_sleep_init();
+
+       samsung_clk_extended_sleep_init(reg_base,
+                       exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
+                       src_mask_suspend, ARRAY_SIZE(src_mask_suspend));
+       if (exynos4_soc == EXYNOS4210)
+               samsung_clk_extended_sleep_init(reg_base,
+                   exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save),
+                   src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210));
+       else
+               samsung_clk_sleep_init(reg_base, exynos4x12_clk_save,
+                                      ARRAY_SIZE(exynos4x12_clk_save));
 
        samsung_clk_of_add_provider(np, ctx);
 
index 347fd80c351b06211a34cfcf7fc934e35bb7483f..f14139bcb0c119f5a975dd7759ae62ab0791774f 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 
 #include "clk.h"
 #include "clk-cpu.h"
@@ -111,9 +110,6 @@ enum exynos5250_plls {
 
 static void __iomem *reg_base;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos5250_save;
-
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -172,41 +168,6 @@ static const unsigned long exynos5250_clk_regs[] __initconst = {
        GATE_IP_ISP1,
 };
 
-static int exynos5250_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, exynos5250_save,
-                               ARRAY_SIZE(exynos5250_clk_regs));
-
-       return 0;
-}
-
-static void exynos5250_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, exynos5250_save,
-                               ARRAY_SIZE(exynos5250_clk_regs));
-}
-
-static struct syscore_ops exynos5250_clk_syscore_ops = {
-       .suspend = exynos5250_clk_suspend,
-       .resume = exynos5250_clk_resume,
-};
-
-static void __init exynos5250_clk_sleep_init(void)
-{
-       exynos5250_save = samsung_clk_alloc_reg_dump(exynos5250_clk_regs,
-                                       ARRAY_SIZE(exynos5250_clk_regs));
-       if (!exynos5250_save) {
-               pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-                       __func__);
-               return;
-       }
-
-       register_syscore_ops(&exynos5250_clk_syscore_ops);
-}
-#else
-static void __init exynos5250_clk_sleep_init(void) {}
-#endif
-
 /* list of all parent clock list */
 PNAME(mout_apll_p)     = { "fin_pll", "fout_apll", };
 PNAME(mout_cpu_p)      = { "mout_apll", "mout_mpll", };
@@ -882,7 +843,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
                PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO);
        __raw_writel(tmp, reg_base + PWR_CTRL2);
 
-       exynos5250_clk_sleep_init();
+       samsung_clk_sleep_init(reg_base, exynos5250_clk_regs,
+                              ARRAY_SIZE(exynos5250_clk_regs));
        exynos5_subcmus_init(ctx, 1, &exynos5250_disp_subcmu);
 
        samsung_clk_of_add_provider(np, ctx);
index 95e1bf69449b75c1812c095f2db2483deac91dae..34cce3c5898f5afe80d36ed89b7112f793111302 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 
 #include "clk.h"
 #include "clk-cpu.h"
@@ -156,10 +155,6 @@ enum exynos5x_plls {
 static void __iomem *reg_base;
 static enum exynos5x_soc exynos5x_soc;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos5x_save;
-static struct samsung_clk_reg_dump *exynos5800_save;
-
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -281,68 +276,9 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = {
        { .offset = GATE_BUS_TOP,               .value = 0xffffffff, },
        { .offset = GATE_BUS_DISP1,             .value = 0xffffffff, },
        { .offset = GATE_IP_PERIC,              .value = 0xffffffff, },
+       { .offset = GATE_IP_PERIS,              .value = 0xffffffff, },
 };
 
-static int exynos5420_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, exynos5x_save,
-                               ARRAY_SIZE(exynos5x_clk_regs));
-
-       if (exynos5x_soc == EXYNOS5800)
-               samsung_clk_save(reg_base, exynos5800_save,
-                               ARRAY_SIZE(exynos5800_clk_regs));
-
-       samsung_clk_restore(reg_base, exynos5420_set_clksrc,
-                               ARRAY_SIZE(exynos5420_set_clksrc));
-
-       return 0;
-}
-
-static void exynos5420_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, exynos5x_save,
-                               ARRAY_SIZE(exynos5x_clk_regs));
-
-       if (exynos5x_soc == EXYNOS5800)
-               samsung_clk_restore(reg_base, exynos5800_save,
-                               ARRAY_SIZE(exynos5800_clk_regs));
-}
-
-static struct syscore_ops exynos5420_clk_syscore_ops = {
-       .suspend = exynos5420_clk_suspend,
-       .resume = exynos5420_clk_resume,
-};
-
-static void __init exynos5420_clk_sleep_init(void)
-{
-       exynos5x_save = samsung_clk_alloc_reg_dump(exynos5x_clk_regs,
-                                       ARRAY_SIZE(exynos5x_clk_regs));
-       if (!exynos5x_save) {
-               pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-                       __func__);
-               return;
-       }
-
-       if (exynos5x_soc == EXYNOS5800) {
-               exynos5800_save =
-                       samsung_clk_alloc_reg_dump(exynos5800_clk_regs,
-                                       ARRAY_SIZE(exynos5800_clk_regs));
-               if (!exynos5800_save)
-                       goto err_soc;
-       }
-
-       register_syscore_ops(&exynos5420_clk_syscore_ops);
-       return;
-err_soc:
-       kfree(exynos5x_save);
-       pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-               __func__);
-       return;
-}
-#else
-static void __init exynos5420_clk_sleep_init(void) {}
-#endif
-
 /* list of all parent clocks */
 PNAME(mout_mspll_cpu_p) = {"mout_sclk_cpll", "mout_sclk_dpll",
                                "mout_sclk_mpll", "mout_sclk_spll"};
@@ -633,6 +569,7 @@ static const struct samsung_div_clock exynos5420_div_clks[] __initconst = {
 };
 
 static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = {
+       GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
        GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk",
                        SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0),
 };
@@ -1162,8 +1099,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
        GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_IP_PERIS, 21, 0, 0),
        GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_IP_PERIS, 22, 0, 0),
 
-       GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
-
        /* GEN Block */
        GATE(CLK_ROTATOR, "rotator", "mout_user_aclk266", GATE_IP_GEN, 1, 0, 0),
        GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0),
@@ -1540,7 +1475,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
                mout_kfc_p[0], mout_kfc_p[1], 0x28200,
                exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
 
-       exynos5420_clk_sleep_init();
+       samsung_clk_extended_sleep_init(reg_base,
+               exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs),
+               exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc));
+       if (soc == EXYNOS5800)
+               samsung_clk_sleep_init(reg_base, exynos5800_clk_regs,
+                                      ARRAY_SIZE(exynos5800_clk_regs));
        exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus),
                             exynos5x_subcmus);
 
index 162de44df099bff5be3a70e4fd5b010e1fc584f5..751e2c4fb65b64faa046c1be2abed06f825289a1 100644 (file)
@@ -177,6 +177,17 @@ static const unsigned long top_clk_regs[] __initconst = {
        ENABLE_CMU_TOP_DIV_STAT,
 };
 
+static const struct samsung_clk_reg_dump top_suspend_regs[] = {
+       /* force all aclk clocks enabled */
+       { ENABLE_ACLK_TOP, 0x67ecffed },
+       /* force all sclk_uart clocks enabled */
+       { ENABLE_SCLK_TOP_PERIC, 0x38 },
+       /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */
+       { ISP_PLL_CON0, 0x85cc0502 },
+       /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */
+       { AUD_PLL_CON0, 0x84830202 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_aud_pll_p)          = { "oscclk", "fout_aud_pll", };
 PNAME(mout_isp_pll_p)          = { "oscclk", "fout_isp_pll", };
@@ -792,6 +803,8 @@ static const struct samsung_cmu_info top_cmu_info __initconst = {
        .nr_clk_ids             = TOP_NR_CLK,
        .clk_regs               = top_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(top_clk_regs),
+       .suspend_regs           = top_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(top_suspend_regs),
 };
 
 static void __init exynos5433_cmu_top_init(struct device_node *np)
@@ -822,6 +835,13 @@ static const unsigned long cpif_clk_regs[] __initconst = {
        ENABLE_SCLK_CPIF,
 };
 
+static const struct samsung_clk_reg_dump cpif_suspend_regs[] = {
+       /* force all sclk clocks enabled */
+       { ENABLE_SCLK_CPIF, 0x3ff },
+       /* MPHY PLL has to be enabled for suspend: reset value + ENABLE bit */
+       { MPHY_PLL_CON0, 0x81c70601 },
+};
+
 /* list of all parent clock list */
 PNAME(mout_mphy_pll_p)         = { "oscclk", "fout_mphy_pll", };
 
@@ -862,6 +882,8 @@ static const struct samsung_cmu_info cpif_cmu_info __initconst = {
        .nr_clk_ids             = CPIF_NR_CLK,
        .clk_regs               = cpif_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(cpif_clk_regs),
+       .suspend_regs           = cpif_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(cpif_suspend_regs),
 };
 
 static void __init exynos5433_cmu_cpif_init(struct device_node *np)
@@ -1547,6 +1569,13 @@ static const unsigned long peric_clk_regs[] __initconst = {
        ENABLE_IP_PERIC2,
 };
 
+static const struct samsung_clk_reg_dump peric_suspend_regs[] = {
+       /* pclk: sci, pmu, sysreg, gpio_{finger, ese, touch, nfc}, uart2-0 */
+       { ENABLE_PCLK_PERIC0, 0xe00ff000 },
+       /* sclk: uart2-0 */
+       { ENABLE_SCLK_PERIC, 0x7 },
+};
+
 static const struct samsung_div_clock peric_div_clks[] __initconst = {
        /* DIV_PERIC */
        DIV(CLK_DIV_SCLK_SCI, "div_sclk_sci", "oscclk", DIV_PERIC, 4, 4),
@@ -1705,6 +1734,8 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
        .nr_clk_ids             = PERIC_NR_CLK,
        .clk_regs               = peric_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(peric_clk_regs),
+       .suspend_regs           = peric_suspend_regs,
+       .nr_suspend_regs        = ARRAY_SIZE(peric_suspend_regs),
 };
 
 static void __init exynos5433_cmu_peric_init(struct device_node *np)
@@ -5630,7 +5661,7 @@ static const struct of_device_id exynos5433_cmu_of_match[] = {
 static const struct dev_pm_ops exynos5433_cmu_pm_ops = {
        SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume,
                           NULL)
-       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+       SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
                                     pm_runtime_force_resume)
 };
 
index a9c88747505428cf30a71316da0e313b7bd415a3..8cb868f062577a79fee2d9ee817e3d6d0704ef25 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 
 #include <dt-bindings/clock/s3c2410.h>
 
@@ -40,9 +39,6 @@ enum s3c2410_plls {
 
 static void __iomem *reg_base;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c2410_save;
-
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -57,42 +53,6 @@ static unsigned long s3c2410_clk_regs[] __initdata = {
        CAMDIVN,
 };
 
-static int s3c2410_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, s3c2410_save,
-                               ARRAY_SIZE(s3c2410_clk_regs));
-
-       return 0;
-}
-
-static void s3c2410_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, s3c2410_save,
-                               ARRAY_SIZE(s3c2410_clk_regs));
-}
-
-static struct syscore_ops s3c2410_clk_syscore_ops = {
-       .suspend = s3c2410_clk_suspend,
-       .resume = s3c2410_clk_resume,
-};
-
-static void __init s3c2410_clk_sleep_init(void)
-{
-       s3c2410_save = samsung_clk_alloc_reg_dump(s3c2410_clk_regs,
-                                               ARRAY_SIZE(s3c2410_clk_regs));
-       if (!s3c2410_save) {
-               pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-                       __func__);
-               return;
-       }
-
-       register_syscore_ops(&s3c2410_clk_syscore_ops);
-       return;
-}
-#else
-static void __init s3c2410_clk_sleep_init(void) {}
-#endif
-
 PNAME(fclk_p) = { "mpll", "div_slow" };
 
 static struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
@@ -461,7 +421,8 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
                        ARRAY_SIZE(s3c244x_common_aliases));
        }
 
-       s3c2410_clk_sleep_init();
+       samsung_clk_sleep_init(reg_base, s3c2410_clk_regs,
+                              ARRAY_SIZE(s3c2410_clk_regs));
 
        samsung_clk_of_add_provider(np, ctx);
 }
index 6bc94d3aff78f58eef7469f41a4af54ab08aa41f..dd1159050a5a54c498396d947756fb8f239f2f32 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 #include <linux/reboot.h>
 
 #include <dt-bindings/clock/s3c2412.h>
@@ -29,9 +28,6 @@
 
 static void __iomem *reg_base;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c2412_save;
-
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -45,42 +41,6 @@ static unsigned long s3c2412_clk_regs[] __initdata = {
        CLKSRC,
 };
 
-static int s3c2412_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, s3c2412_save,
-                               ARRAY_SIZE(s3c2412_clk_regs));
-
-       return 0;
-}
-
-static void s3c2412_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, s3c2412_save,
-                               ARRAY_SIZE(s3c2412_clk_regs));
-}
-
-static struct syscore_ops s3c2412_clk_syscore_ops = {
-       .suspend = s3c2412_clk_suspend,
-       .resume = s3c2412_clk_resume,
-};
-
-static void __init s3c2412_clk_sleep_init(void)
-{
-       s3c2412_save = samsung_clk_alloc_reg_dump(s3c2412_clk_regs,
-                                               ARRAY_SIZE(s3c2412_clk_regs));
-       if (!s3c2412_save) {
-               pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-                       __func__);
-               return;
-       }
-
-       register_syscore_ops(&s3c2412_clk_syscore_ops);
-       return;
-}
-#else
-static void __init s3c2412_clk_sleep_init(void) {}
-#endif
-
 static struct clk_div_table divxti_d[] = {
        { .val = 0, .div = 1 },
        { .val = 1, .div = 2 },
@@ -278,7 +238,8 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
        samsung_clk_register_alias(ctx, s3c2412_aliases,
                                   ARRAY_SIZE(s3c2412_aliases));
 
-       s3c2412_clk_sleep_init();
+       samsung_clk_sleep_init(reg_base, s3c2412_clk_regs,
+                              ARRAY_SIZE(s3c2412_clk_regs));
 
        samsung_clk_of_add_provider(np, ctx);
 
index c46e6d5bc9bccbe6472a2c13b7ff52e01cc0e948..884067e4f1a15e4b8bfd5c2dd43ba086d10b10fa 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 #include <linux/reboot.h>
 
 #include <dt-bindings/clock/s3c2443.h>
@@ -43,9 +42,6 @@ enum supported_socs {
 
 static void __iomem *reg_base;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c2443_save;
-
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -65,42 +61,6 @@ static unsigned long s3c2443_clk_regs[] __initdata = {
        SCLKCON,
 };
 
-static int s3c2443_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, s3c2443_save,
-                               ARRAY_SIZE(s3c2443_clk_regs));
-
-       return 0;
-}
-
-static void s3c2443_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, s3c2443_save,
-                               ARRAY_SIZE(s3c2443_clk_regs));
-}
-
-static struct syscore_ops s3c2443_clk_syscore_ops = {
-       .suspend = s3c2443_clk_suspend,
-       .resume = s3c2443_clk_resume,
-};
-
-static void __init s3c2443_clk_sleep_init(void)
-{
-       s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs,
-                                               ARRAY_SIZE(s3c2443_clk_regs));
-       if (!s3c2443_save) {
-               pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-                       __func__);
-               return;
-       }
-
-       register_syscore_ops(&s3c2443_clk_syscore_ops);
-       return;
-}
-#else
-static void __init s3c2443_clk_sleep_init(void) {}
-#endif
-
 PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" };
 PNAME(esysclk_p) = { "epllref", "epll" };
 PNAME(mpllref_p) = { "xti", "mdivclk" };
@@ -450,7 +410,8 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
                break;
        }
 
-       s3c2443_clk_sleep_init();
+       samsung_clk_sleep_init(reg_base, s3c2443_clk_regs,
+                              ARRAY_SIZE(s3c2443_clk_regs));
 
        samsung_clk_of_add_provider(np, ctx);
 
index 6db01cf5ab8364901905c68e584b6418c7cff509..54916c7bdb0672a6f1111292ae8e92e642528d4f 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 
 #include <dt-bindings/clock/samsung,s3c64xx-clock.h>
 
 static void __iomem *reg_base;
 static bool is_s3c6400;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c64xx_save_common;
-static struct samsung_clk_reg_dump *s3c64xx_save_soc;
-
 /*
  * List of controller registers to be saved and restored during
  * a suspend/resume cycle.
@@ -89,60 +84,6 @@ static unsigned long s3c6410_clk_regs[] __initdata = {
        MEM0_GATE,
 };
 
-static int s3c64xx_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, s3c64xx_save_common,
-                               ARRAY_SIZE(s3c64xx_clk_regs));
-
-       if (!is_s3c6400)
-               samsung_clk_save(reg_base, s3c64xx_save_soc,
-                                       ARRAY_SIZE(s3c6410_clk_regs));
-
-       return 0;
-}
-
-static void s3c64xx_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, s3c64xx_save_common,
-                               ARRAY_SIZE(s3c64xx_clk_regs));
-
-       if (!is_s3c6400)
-               samsung_clk_restore(reg_base, s3c64xx_save_soc,
-                                       ARRAY_SIZE(s3c6410_clk_regs));
-}
-
-static struct syscore_ops s3c64xx_clk_syscore_ops = {
-       .suspend = s3c64xx_clk_suspend,
-       .resume = s3c64xx_clk_resume,
-};
-
-static void __init s3c64xx_clk_sleep_init(void)
-{
-       s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs,
-                                               ARRAY_SIZE(s3c64xx_clk_regs));
-       if (!s3c64xx_save_common)
-               goto err_warn;
-
-       if (!is_s3c6400) {
-               s3c64xx_save_soc = samsung_clk_alloc_reg_dump(s3c6410_clk_regs,
-                                               ARRAY_SIZE(s3c6410_clk_regs));
-               if (!s3c64xx_save_soc)
-                       goto err_soc;
-       }
-
-       register_syscore_ops(&s3c64xx_clk_syscore_ops);
-       return;
-
-err_soc:
-       kfree(s3c64xx_save_common);
-err_warn:
-       pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
-               __func__);
-}
-#else
-static void __init s3c64xx_clk_sleep_init(void) {}
-#endif
-
 /* List of parent clocks common for all S3C64xx SoCs. */
 PNAME(spi_mmc_p)       = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
 PNAME(uart_p)          = { "mout_epll", "dout_mpll" };
@@ -508,7 +449,12 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
 
        samsung_clk_register_alias(ctx, s3c64xx_clock_aliases,
                                        ARRAY_SIZE(s3c64xx_clock_aliases));
-       s3c64xx_clk_sleep_init();
+
+       samsung_clk_sleep_init(reg_base, s3c64xx_clk_regs,
+                              ARRAY_SIZE(s3c64xx_clk_regs));
+       if (!is_s3c6400)
+               samsung_clk_sleep_init(reg_base, s3c6410_clk_regs,
+                                      ARRAY_SIZE(s3c6410_clk_regs));
 
        samsung_clk_of_add_provider(np, ctx);
 
index fd2725710a6fa968437e45a108555a7eb506dbc2..41d2337fe030c129396ec49b88b0f62b68e95850 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/syscore_ops.h>
 
 #include "clk.h"
 #include "clk-pll.h"
@@ -83,9 +82,6 @@ enum {
 
 static void __iomem *reg_base;
 
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s5pv210_clk_dump;
-
 /* List of registers that need to be preserved across suspend/resume. */
 static unsigned long s5pv210_clk_regs[] __initdata = {
        CLK_SRC0,
@@ -132,40 +128,6 @@ static unsigned long s5pv210_clk_regs[] __initdata = {
        CLK_OUT,
 };
 
-static int s5pv210_clk_suspend(void)
-{
-       samsung_clk_save(reg_base, s5pv210_clk_dump,
-                               ARRAY_SIZE(s5pv210_clk_regs));
-       return 0;
-}
-
-static void s5pv210_clk_resume(void)
-{
-       samsung_clk_restore(reg_base, s5pv210_clk_dump,
-                               ARRAY_SIZE(s5pv210_clk_regs));
-}
-
-static struct syscore_ops s5pv210_clk_syscore_ops = {
-       .suspend = s5pv210_clk_suspend,
-       .resume = s5pv210_clk_resume,
-};
-
-static void s5pv210_clk_sleep_init(void)
-{
-       s5pv210_clk_dump =
-               samsung_clk_alloc_reg_dump(s5pv210_clk_regs,
-                                          ARRAY_SIZE(s5pv210_clk_regs));
-       if (!s5pv210_clk_dump) {
-               pr_warn("%s: Failed to allocate sleep save data\n", __func__);
-               return;
-       }
-
-       register_syscore_ops(&s5pv210_clk_syscore_ops);
-}
-#else
-static inline void s5pv210_clk_sleep_init(void) { }
-#endif
-
 /* Mux parent lists. */
 static const char *const fin_pll_p[] __initconst = {
        "xxti",
@@ -822,7 +784,8 @@ static void __init __s5pv210_clk_init(struct device_node *np,
        samsung_clk_register_alias(ctx, s5pv210_aliases,
                                                ARRAY_SIZE(s5pv210_aliases));
 
-       s5pv210_clk_sleep_init();
+       samsung_clk_sleep_init(reg_base, s5pv210_clk_regs,
+                              ARRAY_SIZE(s5pv210_clk_regs));
 
        samsung_clk_of_add_provider(np, ctx);
 
index 8634884aa11ce421fb9a3485d6f1af2408bd5fd4..1f6e47cd327db413ec481ab5403c543b17797e56 100644 (file)
@@ -290,9 +290,12 @@ static int samsung_clk_suspend(void)
 {
        struct samsung_clock_reg_cache *reg_cache;
 
-       list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
+       list_for_each_entry(reg_cache, &clock_reg_cache_list, node) {
                samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,
                                reg_cache->rd_num);
+               samsung_clk_restore(reg_cache->reg_base, reg_cache->rsuspend,
+                               reg_cache->rsuspend_num);
+       }
        return 0;
 }
 
@@ -310,9 +313,11 @@ static struct syscore_ops samsung_clk_syscore_ops = {
        .resume = samsung_clk_resume,
 };
 
-void samsung_clk_sleep_init(void __iomem *reg_base,
+void samsung_clk_extended_sleep_init(void __iomem *reg_base,
                        const unsigned long *rdump,
-                       unsigned long nr_rdump)
+                       unsigned long nr_rdump,
+                       const struct samsung_clk_reg_dump *rsuspend,
+                       unsigned long nr_rsuspend)
 {
        struct samsung_clock_reg_cache *reg_cache;
 
@@ -330,13 +335,10 @@ void samsung_clk_sleep_init(void __iomem *reg_base,
 
        reg_cache->reg_base = reg_base;
        reg_cache->rd_num = nr_rdump;
+       reg_cache->rsuspend = rsuspend;
+       reg_cache->rsuspend_num = nr_rsuspend;
        list_add_tail(&reg_cache->node, &clock_reg_cache_list);
 }
-
-#else
-void samsung_clk_sleep_init(void __iomem *reg_base,
-                       const unsigned long *rdump,
-                       unsigned long nr_rdump) {}
 #endif
 
 /*
@@ -380,8 +382,9 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
                samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,
                        cmu->nr_fixed_factor_clks);
        if (cmu->clk_regs)
-               samsung_clk_sleep_init(reg_base, cmu->clk_regs,
-                       cmu->nr_clk_regs);
+               samsung_clk_extended_sleep_init(reg_base,
+                       cmu->clk_regs, cmu->nr_clk_regs,
+                       cmu->suspend_regs, cmu->nr_suspend_regs);
 
        samsung_clk_of_add_provider(np, ctx);
 
index 3880d2f9d5829df357f0c4b9f9639bbfd171599d..c3f309d7100dd2313592edd2b6a398afd65b738b 100644 (file)
@@ -279,6 +279,8 @@ struct samsung_clock_reg_cache {
        void __iomem *reg_base;
        struct samsung_clk_reg_dump *rdump;
        unsigned int rd_num;
+       const struct samsung_clk_reg_dump *rsuspend;
+       unsigned int rsuspend_num;
 };
 
 struct samsung_cmu_info {
@@ -358,9 +360,21 @@ extern struct samsung_clk_provider __init *samsung_cmu_register_one(
 
 extern unsigned long _get_rate(const char *clk_name);
 
-extern void samsung_clk_sleep_init(void __iomem *reg_base,
+#ifdef CONFIG_PM_SLEEP
+extern void samsung_clk_extended_sleep_init(void __iomem *reg_base,
                        const unsigned long *rdump,
-                       unsigned long nr_rdump);
+                       unsigned long nr_rdump,
+                       const struct samsung_clk_reg_dump *rsuspend,
+                       unsigned long nr_rsuspend);
+#else
+static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
+                       const unsigned long *rdump,
+                       unsigned long nr_rdump,
+                       const struct samsung_clk_reg_dump *rsuspend,
+                       unsigned long nr_rsuspend) {}
+#endif
+#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
+       samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
 
 extern void samsung_clk_save(void __iomem *base,
                        struct samsung_clk_reg_dump *rd,
index a79d81985c4e0251a6049d5d09b89415d0354ba3..cfa000007622d63dc08d590594e03e390e037a01 100644 (file)
@@ -936,7 +936,7 @@ static void __init st_of_quadfs_setup(struct device_node *np,
        if (!clk_parent_name)
                return;
 
-       pll_name = kasprintf(GFP_KERNEL, "%s.pll", np->name);
+       pll_name = kasprintf(GFP_KERNEL, "%pOFn.pll", np);
        if (!pll_name)
                return;
 
index ee9c12cf3f08c38d6c1757a646c043b25f7dd90e..5f80eb0180142c4a9f1bde5e758a3bebe3aa36b5 100644 (file)
@@ -64,17 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
                                   BIT(28),     /* lock */
                                   CLK_SET_RATE_UNGATE);
 
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
-                                       "osc24M", 0x010,
-                                       8, 7,           /* N */
-                                       0, 4,           /* M */
-                                       BIT(24),        /* frac enable */
-                                       BIT(25),        /* frac select */
-                                       270000000,      /* frac rate 0 */
-                                       297000000,      /* frac rate 1 */
-                                       BIT(31),        /* gate */
-                                       BIT(28),        /* lock */
-                                       CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
+                                               "osc24M", 0x010,
+                                               192000000,      /* Minimum rate */
+                                               1008000000,     /* Maximum rate */
+                                               8, 7,           /* N */
+                                               0, 4,           /* M */
+                                               BIT(24),        /* frac enable */
+                                               BIT(25),        /* frac select */
+                                               270000000,      /* frac rate 0 */
+                                               297000000,      /* frac rate 1 */
+                                               BIT(31),        /* gate */
+                                               BIT(28),        /* lock */
+                                               CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
                                        "osc24M", 0x018,
@@ -125,17 +127,19 @@ static struct ccu_nk pll_periph1_clk = {
        },
 };
 
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
-                                       "osc24M", 0x030,
-                                       8, 7,           /* N */
-                                       0, 4,           /* M */
-                                       BIT(24),        /* frac enable */
-                                       BIT(25),        /* frac select */
-                                       270000000,      /* frac rate 0 */
-                                       297000000,      /* frac rate 1 */
-                                       BIT(31),        /* gate */
-                                       BIT(28),        /* lock */
-                                       CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
+                                               "osc24M", 0x030,
+                                               192000000,      /* Minimum rate */
+                                               1008000000,     /* Maximum rate */
+                                               8, 7,           /* N */
+                                               0, 4,           /* M */
+                                               BIT(24),        /* frac enable */
+                                               BIT(25),        /* frac select */
+                                               270000000,      /* frac rate 0 */
+                                               297000000,      /* frac rate 1 */
+                                               BIT(31),        /* gate */
+                                               BIT(28),        /* lock */
+                                               CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
                                        "osc24M", 0x038,
index 061b6fbb4f9591c0b77a54e8aa6a4ac0bb993e66..cd415b968e8c289582403bb8db97dd4c29b8b434 100644 (file)
@@ -27,7 +27,9 @@
 #define CLK_PLL_AUDIO_2X               4
 #define CLK_PLL_AUDIO_4X               5
 #define CLK_PLL_AUDIO_8X               6
-#define CLK_PLL_VIDEO0                 7
+
+/* PLL_VIDEO0 exported for HDMI PHY */
+
 #define CLK_PLL_VIDEO0_2X              8
 #define CLK_PLL_VE                     9
 #define CLK_PLL_DDR0                   10
index bdbfe78fe1333c944434c8f66b130923617dc671..2193e1495086eb7439fe8fe55bc663552cd350da 100644 (file)
@@ -224,7 +224,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2",
                             psi_ahb1_ahb2_parents,
                             0x510,
                             0, 5,      /* M */
-                            16, 2,     /* P */
+                            8, 2,      /* P */
                             24, 2,     /* mux */
                             0);
 
@@ -233,19 +233,19 @@ static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k",
                                                       "pll-periph0" };
 static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c,
                             0, 5,      /* M */
-                            16, 2,     /* P */
+                            8, 2,      /* P */
                             24, 2,     /* mux */
                             0);
 
 static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520,
                             0, 5,      /* M */
-                            16, 2,     /* P */
+                            8, 2,      /* P */
                             24, 2,     /* mux */
                             0);
 
 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524,
                             0, 5,      /* M */
-                            16, 2,     /* P */
+                            8, 2,      /* P */
                             24, 2,     /* mux */
                             0);
 
@@ -352,7 +352,7 @@ static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2",
 static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2",
                      0x79c, BIT(0), 0);
 
-static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x79c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
 
 static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0);
 
@@ -408,26 +408,29 @@ static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0);
 
 static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x",
                                            "pll-periph1-2x" };
-static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830,
-                                       0, 4,   /* M */
-                                       8, 2,   /* N */
-                                       24, 3,  /* mux */
-                                       BIT(31),/* gate */
-                                       0);
-
-static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834,
-                                       0, 4,   /* M */
-                                       8, 2,   /* N */
-                                       24, 3,  /* mux */
-                                       BIT(31),/* gate */
-                                       0);
-
-static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838,
-                                       0, 4,   /* M */
-                                       8, 2,   /* N */
-                                       24, 3,  /* mux */
-                                       BIT(31),/* gate */
-                                       0);
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
+                                         0, 4,         /* M */
+                                         8, 2,         /* N */
+                                         24, 3,        /* mux */
+                                         BIT(31),      /* gate */
+                                         2,            /* post-div */
+                                         0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
+                                         0, 4,         /* M */
+                                         8, 2,         /* N */
+                                         24, 3,        /* mux */
+                                         BIT(31),      /* gate */
+                                         2,            /* post-div */
+                                         0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838,
+                                         0, 4,         /* M */
+                                         8, 2,         /* N */
+                                         24, 3,        /* mux */
+                                         BIT(31),      /* gate */
+                                         2,            /* post-div */
+                                         0);
 
 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
index 7d08015b980d33e7f53b5a5d48ee18894896fe6c..2d6555d7317058c1b892bc91dbd75dfe0fe1df6e 100644 (file)
@@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = {
        .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
        .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
        .p              = _SUNXI_CCU_DIV(0, 2), /* output divider */
+       .max_rate       = 3000000000UL,
        .common         = {
                .reg            = 0x010,
                .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
@@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = {
        .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
        .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
        .p              = _SUNXI_CCU_DIV(0, 2), /* external divider p */
+       .max_rate       = 3000000000UL,
        .common         = {
                .reg            = 0x04c,
                .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
index 77ed0b0ba6819d94317e12f31ac25896143e2a77..eb5c608428fa4ba3aab6a4935449487bdfe8adbe 100644 (file)
@@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
                                       BIT(28), /* lock */
                                       CLK_SET_RATE_UNGATE);
 
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video",
-                                           "osc24M", 0x0010,
-                                           192000000,  /* Minimum rate */
-                                           8, 7,       /* N */
-                                           0, 4,       /* M */
-                                           BIT(24),    /* frac enable */
-                                           BIT(25),    /* frac select */
-                                           270000000,  /* frac rate 0 */
-                                           297000000,  /* frac rate 1 */
-                                           BIT(31),    /* gate */
-                                           BIT(28),    /* lock */
-                                           CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video",
+                                               "osc24M", 0x0010,
+                                               192000000, /* Minimum rate */
+                                               912000000, /* Maximum rate */
+                                               8, 7,      /* N */
+                                               0, 4,      /* M */
+                                               BIT(24),   /* frac enable */
+                                               BIT(25),   /* frac select */
+                                               270000000, /* frac rate 0 */
+                                               297000000, /* frac rate 1 */
+                                               BIT(31),   /* gate */
+                                               BIT(28),   /* lock */
+                                               CLK_SET_RATE_UNGATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
                                        "osc24M", 0x0018,
index 0f388f6944d52e7a1d221778414ada120dd78994..582ebd41d20d9bb8c795f864b73e6b3bd938f59f 100644 (file)
@@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
                                   BIT(28),     /* lock */
                                   CLK_SET_RATE_UNGATE);
 
-/* TODO: The result of N/M is required to be in [8, 25] range. */
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0",
-                                           "osc24M", 0x0010,
-                                           192000000,  /* Minimum rate */
-                                           8, 7,       /* N */
-                                           0, 4,       /* M */
-                                           BIT(24),    /* frac enable */
-                                           BIT(25),    /* frac select */
-                                           270000000,  /* frac rate 0 */
-                                           297000000,  /* frac rate 1 */
-                                           BIT(31),    /* gate */
-                                           BIT(28),    /* lock */
-                                           CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
+                                               "osc24M", 0x0010,
+                                               192000000,  /* Minimum rate */
+                                               1008000000, /* Maximum rate */
+                                               8, 7,       /* N */
+                                               0, 4,       /* M */
+                                               BIT(24),    /* frac enable */
+                                               BIT(25),    /* frac select */
+                                               270000000,  /* frac rate 0 */
+                                               297000000,  /* frac rate 1 */
+                                               BIT(31),    /* gate */
+                                               BIT(28),    /* lock */
+                                               CLK_SET_RATE_UNGATE);
 
 /* TODO: The result of N/M is required to be in [8, 25] range. */
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
@@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = {
        },
 };
 
-/* TODO: The result of N/M is required to be in [8, 25] range. */
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1",
-                                           "osc24M", 0x030,
-                                           192000000,  /* Minimum rate */
-                                           8, 7,       /* N */
-                                           0, 4,       /* M */
-                                           BIT(24),    /* frac enable */
-                                           BIT(25),    /* frac select */
-                                           270000000,  /* frac rate 0 */
-                                           297000000,  /* frac rate 1 */
-                                           BIT(31),    /* gate */
-                                           BIT(28),    /* lock */
-                                           CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
+                                               "osc24M", 0x030,
+                                               192000000,  /* Minimum rate */
+                                               1008000000, /* Maximum rate */
+                                               8, 7,       /* N */
+                                               0, 4,       /* M */
+                                               BIT(24),    /* frac enable */
+                                               BIT(25),    /* frac select */
+                                               270000000,  /* frac rate 0 */
+                                               297000000,  /* frac rate 1 */
+                                               BIT(31),    /* gate */
+                                               BIT(28),    /* lock */
+                                               CLK_SET_RATE_UNGATE);
 
 static struct ccu_nkm pll_sata_clk = {
        .enable         = BIT(31),
index ebd9436d2c7cd382ed86a3bee1957a5db48b7530..9b49adb20d07c68ef8ddd01f8d35e73ed746f64f 100644 (file)
@@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
        if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
                rate *= nkmp->fixed_post_div;
 
+       if (nkmp->max_rate && rate > nkmp->max_rate) {
+               rate = nkmp->max_rate;
+               if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
+                       rate /= nkmp->fixed_post_div;
+               return rate;
+       }
+
        _nkmp.min_n = nkmp->n.min ?: 1;
        _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
        _nkmp.min_k = nkmp->k.min ?: 1;
index 6940503e7fc4665d36fd889e3ec25fa258a14f40..a9f8c116a7453b969019dfda27c4b340604e35dc 100644 (file)
@@ -35,6 +35,7 @@ struct ccu_nkmp {
        struct ccu_div_internal         p;
 
        unsigned int            fixed_post_div;
+       unsigned int            max_rate;
 
        struct ccu_common       common;
 };
index 4e2073307f34013e215fd827cc7048f6d4608bc6..6fe3c14f7b2dad94696afc14ab44ff213d78a093 100644 (file)
@@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
                return rate;
        }
 
+       if (nm->max_rate && rate > nm->max_rate) {
+               rate = nm->max_rate;
+               if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
+                       rate /= nm->fixed_post_div;
+               return rate;
+       }
+
        if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
                if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
                        rate /= nm->fixed_post_div;
index 1d8b459c50b7c8d90e2085eeacc402c61989641c..de232f2199a6ba3982670001062571ad12e0fa83 100644 (file)
@@ -38,6 +38,7 @@ struct ccu_nm {
 
        unsigned int            fixed_post_div;
        unsigned int            min_rate;
+       unsigned int            max_rate;
 
        struct ccu_common       common;
 };
@@ -115,6 +116,35 @@ struct ccu_nm {
                },                                                      \
        }
 
+#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name,       \
+                                                _parent, _reg,         \
+                                                _min_rate, _max_rate,  \
+                                                _nshift, _nwidth,      \
+                                                _mshift, _mwidth,      \
+                                                _frac_en, _frac_sel,   \
+                                                _frac_rate_0,          \
+                                                _frac_rate_1,          \
+                                                _gate, _lock, _flags)  \
+       struct ccu_nm _struct = {                                       \
+               .enable         = _gate,                                \
+               .lock           = _lock,                                \
+               .n              = _SUNXI_CCU_MULT(_nshift, _nwidth),    \
+               .m              = _SUNXI_CCU_DIV(_mshift, _mwidth),     \
+               .frac           = _SUNXI_CCU_FRAC(_frac_en, _frac_sel,  \
+                                                 _frac_rate_0,         \
+                                                 _frac_rate_1),        \
+               .min_rate       = _min_rate,                            \
+               .max_rate       = _max_rate,                            \
+               .common         = {                                     \
+                       .reg            = _reg,                         \
+                       .features       = CCU_FEATURE_FRACTIONAL,       \
+                       .hw.init        = CLK_HW_INIT(_name,            \
+                                                     _parent,          \
+                                                     &ccu_nm_ops,      \
+                                                     _flags),          \
+               },                                                      \
+       }
+
 #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg,     \
                                    _nshift, _nwidth,                   \
                                    _mshift, _mwidth,                   \
index a27c264cc9b4fb34f2b2d6d8748336ad102e4841..fc0278a1acc7ac6219617f499c11eca1c5c395a5 100644 (file)
@@ -140,8 +140,8 @@ static void __init sun9i_a80_mod0_setup(struct device_node *node)
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Could not get registers for mod0-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for mod0-clk: %pOFn\n",
+                      node);
                return;
        }
 
@@ -306,7 +306,7 @@ static void __init sunxi_mmc_setup(struct device_node *node,
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Couldn't map the %s clock registers\n", node->name);
+               pr_err("Couldn't map the %pOFn clock registers\n", node);
                return;
        }
 
index e9295c286d5d9017a110010a5c2102778824b104..7e21b2b10c946f92b9996160ce7d046fd754d426 100644 (file)
@@ -88,8 +88,8 @@ static void __init sun9i_a80_pll4_setup(struct device_node *node)
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Could not get registers for a80-pll4-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for a80-pll4-clk: %pOFn\n",
+                      node);
                return;
        }
 
@@ -142,8 +142,8 @@ static void __init sun9i_a80_gt_setup(struct device_node *node)
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Could not get registers for a80-gt-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for a80-gt-clk: %pOFn\n",
+                      node);
                return;
        }
 
@@ -197,8 +197,8 @@ static void __init sun9i_a80_ahb_setup(struct device_node *node)
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Could not get registers for a80-ahb-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for a80-ahb-clk: %pOFn\n",
+                      node);
                return;
        }
 
@@ -223,8 +223,8 @@ static void __init sun9i_a80_apb0_setup(struct device_node *node)
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Could not get registers for a80-apb0-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for a80-apb0-clk: %pOFn\n",
+                      node);
                return;
        }
 
@@ -280,8 +280,8 @@ static void __init sun9i_a80_apb1_setup(struct device_node *node)
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(reg)) {
-               pr_err("Could not get registers for a80-apb1-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for a80-apb1-clk: %pOFn\n",
+                      node);
                return;
        }
 
index 012714d94b429bcca04b277aed39983a140b08d0..892c29030b7b26772aa7a58b2598faab5c7bc94e 100644 (file)
@@ -568,8 +568,8 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
 
        reg = of_iomap(node, 0);
        if (!reg) {
-               pr_err("Could not get registers for factors-clk: %s\n",
-                      node->name);
+               pr_err("Could not get registers for factors-clk: %pOFn\n",
+                      node);
                return NULL;
        }
 
index 48ee43734e05117bec4d783431b7fc617daf3fb4..ebb0e1b6bf0156aacb7675dbfa5c694bfd14ea51 100644 (file)
@@ -1609,8 +1609,12 @@ int tegra_dfll_register(struct platform_device *pdev,
 
        td->vdd_reg = devm_regulator_get(td->dev, "vdd-cpu");
        if (IS_ERR(td->vdd_reg)) {
-               dev_err(td->dev, "couldn't get vdd_cpu regulator\n");
-               return PTR_ERR(td->vdd_reg);
+               ret = PTR_ERR(td->vdd_reg);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(td->dev, "couldn't get vdd_cpu regulator: %d\n",
+                               ret);
+
+               return ret;
        }
 
        td->dvco_rst = devm_reset_control_get(td->dev, "dvco");
index 9eb1cb14fce11ca5dd0ddd725102a343712d3b24..88f1943bd2b507aec617c98fafa50c5746406730 100644 (file)
@@ -27,6 +27,7 @@
 #include <dt-bindings/clock/tegra210-car.h>
 #include <dt-bindings/reset/tegra210-car.h>
 #include <linux/iopoll.h>
+#include <linux/sizes.h>
 #include <soc/tegra/pmc.h>
 
 #include "clk.h"
@@ -2603,7 +2604,7 @@ static struct tegra210_domain_mbist_war tegra210_pg_mbist_war[] = {
        [TEGRA_POWERGATE_MPE] = {
                .handle_lvl2_ovr = tegra210_generic_mbist_war,
                .lvl2_offset = LVL2_CLK_GATE_OVRE,
-               .lvl2_mask = BIT(2),
+               .lvl2_mask = BIT(29),
        },
        [TEGRA_POWERGATE_SOR] = {
                .handle_lvl2_ovr = tegra210_generic_mbist_war,
@@ -2654,14 +2655,14 @@ static struct tegra210_domain_mbist_war tegra210_pg_mbist_war[] = {
                .num_clks = ARRAY_SIZE(nvdec_slcg_clkids),
                .clk_init_data = nvdec_slcg_clkids,
                .handle_lvl2_ovr = tegra210_generic_mbist_war,
-               .lvl2_offset = LVL2_CLK_GATE_OVRC,
+               .lvl2_offset = LVL2_CLK_GATE_OVRE,
                .lvl2_mask = BIT(9) | BIT(31),
        },
        [TEGRA_POWERGATE_NVJPG] = {
                .num_clks = ARRAY_SIZE(nvjpg_slcg_clkids),
                .clk_init_data = nvjpg_slcg_clkids,
                .handle_lvl2_ovr = tegra210_generic_mbist_war,
-               .lvl2_offset = LVL2_CLK_GATE_OVRC,
+               .lvl2_offset = LVL2_CLK_GATE_OVRE,
                .lvl2_mask = BIT(9) | BIT(31),
        },
        [TEGRA_POWERGATE_AUD] = {
index 5ab295d2a3cb6790ae4d4ca1be297c958299ca54..5ca1e39dd88a6ae5777299a88ba0ab56d4bb9e0a 100644 (file)
@@ -6,7 +6,8 @@ clk-common                              = dpll.o composite.o divider.o gate.o \
                                          fixed-factor.o mux.o apll.o \
                                          clkt_dpll.o clkt_iclk.o clkt_dflt.o \
                                          clkctrl.o
-obj-$(CONFIG_SOC_AM33XX)               += $(clk-common) clk-33xx.o dpll3xxx.o
+obj-$(CONFIG_SOC_AM33XX)               += $(clk-common) clk-33xx.o dpll3xxx.o \
+                                         clk-33xx-compat.o
 obj-$(CONFIG_SOC_TI81XX)               += $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)               += $(clk-common) interface.o clk-2xxx.o
 obj-$(CONFIG_ARCH_OMAP3)               += $(clk-common) interface.o \
@@ -16,8 +17,10 @@ obj-$(CONFIG_ARCH_OMAP4)             += $(clk-common) clk-44xx.o \
 obj-$(CONFIG_SOC_OMAP5)                        += $(clk-common) clk-54xx.o \
                                           dpll3xxx.o dpll44xx.o
 obj-$(CONFIG_SOC_DRA7XX)               += $(clk-common) clk-7xx.o \
-                                          clk-dra7-atl.o dpll3xxx.o dpll44xx.o
-obj-$(CONFIG_SOC_AM43XX)               += $(clk-common) dpll3xxx.o clk-43xx.o
+                                          clk-dra7-atl.o dpll3xxx.o \
+                                          dpll44xx.o clk-7xx-compat.o
+obj-$(CONFIG_SOC_AM43XX)               += $(clk-common) dpll3xxx.o clk-43xx.o \
+                                          clk-43xx-compat.o
 
 endif  # CONFIG_ARCH_OMAP2PLUS
 
index 61c126a5d26ad88aacc4491c73f85248fe2d2f4f..222f68bc3f2ae5149d188ac683c36396750a7191 100644 (file)
@@ -143,8 +143,8 @@ static void __init omap_clk_register_apll(void *user,
 
        clk = of_clk_get(node, 0);
        if (IS_ERR(clk)) {
-               pr_debug("clk-ref for %s not ready, retry\n",
-                        node->name);
+               pr_debug("clk-ref for %pOFn not ready, retry\n",
+                        node);
                if (!ti_clk_retry_init(node, hw, omap_clk_register_apll))
                        return;
 
@@ -155,8 +155,8 @@ static void __init omap_clk_register_apll(void *user,
 
        clk = of_clk_get(node, 1);
        if (IS_ERR(clk)) {
-               pr_debug("clk-bypass for %s not ready, retry\n",
-                        node->name);
+               pr_debug("clk-bypass for %pOFn not ready, retry\n",
+                        node);
                if (!ti_clk_retry_init(node, hw, omap_clk_register_apll))
                        return;
 
@@ -202,7 +202,7 @@ static void __init of_dra7_apll_setup(struct device_node *node)
 
        init->num_parents = of_clk_get_parent_count(node);
        if (init->num_parents < 1) {
-               pr_err("dra7 apll %s must have parent(s)\n", node->name);
+               pr_err("dra7 apll %pOFn must have parent(s)\n", node);
                goto cleanup;
        }
 
@@ -366,7 +366,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
 
        init->num_parents = of_clk_get_parent_count(node);
        if (init->num_parents != 1) {
-               pr_err("%s must have one parent\n", node->name);
+               pr_err("%pOFn must have one parent\n", node);
                goto cleanup;
        }
 
@@ -374,13 +374,13 @@ static void __init of_omap2_apll_setup(struct device_node *node)
        init->parent_names = &parent_name;
 
        if (of_property_read_u32(node, "ti,clock-frequency", &val)) {
-               pr_err("%s missing clock-frequency\n", node->name);
+               pr_err("%pOFn missing clock-frequency\n", node);
                goto cleanup;
        }
        clk_hw->fixed_rate = val;
 
        if (of_property_read_u32(node, "ti,bit-shift", &val)) {
-               pr_err("%s missing bit-shift\n", node->name);
+               pr_err("%pOFn missing bit-shift\n", node);
                goto cleanup;
        }
 
@@ -389,7 +389,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
        ad->autoidle_mask = 0x3 << val;
 
        if (of_property_read_u32(node, "ti,idlest-shift", &val)) {
-               pr_err("%s missing idlest-shift\n", node->name);
+               pr_err("%pOFn missing idlest-shift\n", node);
                goto cleanup;
        }
 
diff --git a/drivers/clk/ti/clk-33xx-compat.c b/drivers/clk/ti/clk-33xx-compat.c
new file mode 100644 (file)
index 0000000..3e07f12
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * AM33XX Clock init
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc
+ *     Tero Kristo (t-kristo@ti.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+#include <dt-bindings/clock/am3.h>
+
+#include "clock.h"
+
+static const char * const am3_gpio1_dbclk_parents[] __initconst = {
+       "l4_per_cm:clk:0138:0",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am3_gpio2_bit_data[] __initconst = {
+       { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am3_gpio3_bit_data[] __initconst = {
+       { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = {
+       { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = {
+       { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
+       { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" },
+       { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" },
+       { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" },
+       { AM3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
+       { AM3_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" },
+       { AM3_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM3_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" },
+       { AM3_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" },
+       { AM3_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" },
+       { AM3_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" },
+       { AM3_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" },
+       { AM3_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" },
+       { AM3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" },
+       { AM3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_GPIO2_CLKCTRL, am3_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_GPIO3_CLKCTRL, am3_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_GPIO4_CLKCTRL, am3_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" },
+       { AM3_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" },
+       { AM3_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" },
+       { AM3_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" },
+       { AM3_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" },
+       { AM3_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM3_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" },
+       { AM3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM3_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l4hs_clkdm" },
+       { AM3_OCPWP_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_CLKDIV32K_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ck", "clk_24mhz_clkdm" },
+       { 0 },
+};
+
+static const char * const am3_gpio0_dbclk_parents[] __initconst = {
+       "gpio0_dbclk_mux_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am3_gpio1_bit_data[] __initconst = {
+       { 18, TI_CLK_GATE, am3_gpio0_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const char * const am3_dbg_sysclk_ck_parents[] __initconst = {
+       "sys_clkin_ck",
+       NULL,
+};
+
+static const char * const am3_trace_pmd_clk_mux_ck_parents[] __initconst = {
+       "l4_wkup_cm:clk:0010:19",
+       "l4_wkup_cm:clk:0010:30",
+       NULL,
+};
+
+static const char * const am3_trace_clk_div_ck_parents[] __initconst = {
+       "l4_wkup_cm:clk:0010:20",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data am3_trace_clk_div_ck_data __initconst = {
+       .max_div = 64,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const char * const am3_stm_clk_div_ck_parents[] __initconst = {
+       "l4_wkup_cm:clk:0010:22",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data am3_stm_clk_div_ck_data __initconst = {
+       .max_div = 64,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const char * const am3_dbg_clka_ck_parents[] __initconst = {
+       "dpll_core_m4_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am3_debugss_bit_data[] __initconst = {
+       { 19, TI_CLK_GATE, am3_dbg_sysclk_ck_parents, NULL },
+       { 20, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL },
+       { 22, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL },
+       { 24, TI_CLK_DIVIDER, am3_trace_clk_div_ck_parents, &am3_trace_clk_div_ck_data },
+       { 27, TI_CLK_DIVIDER, am3_stm_clk_div_ck_parents, &am3_stm_clk_div_ck_data },
+       { 30, TI_CLK_GATE, am3_dbg_clka_ck_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l4_wkup_clkctrl_regs[] __initconst = {
+       { AM3_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
+       { AM3_GPIO1_CLKCTRL, am3_gpio1_bit_data, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
+       { AM3_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
+       { AM3_DEBUGSS_CLKCTRL, am3_debugss_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0010:24", "l3_aon_clkdm" },
+       { AM3_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "dpll_core_m4_div2_ck", "l4_wkup_aon_clkdm" },
+       { AM3_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
+       { AM3_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
+       { AM3_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" },
+       { AM3_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" },
+       { AM3_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" },
+       { AM3_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" },
+       { AM3_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_mpu_clkctrl_regs[] __initconst = {
+       { AM3_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = {
+       { AM3_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = {
+       { AM3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l4_cefuse_clkctrl_regs[] __initconst = {
+       { AM3_CEFUSE_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" },
+       { 0 },
+};
+
+const struct omap_clkctrl_data am3_clkctrl_compat_data[] __initconst = {
+       { 0x44e00014, am3_l4_per_clkctrl_regs },
+       { 0x44e00404, am3_l4_wkup_clkctrl_regs },
+       { 0x44e00604, am3_mpu_clkctrl_regs },
+       { 0x44e00800, am3_l4_rtc_clkctrl_regs },
+       { 0x44e00904, am3_gfx_l3_clkctrl_regs },
+       { 0x44e00a20, am3_l4_cefuse_clkctrl_regs },
+       { 0 },
+};
+
+struct ti_dt_clk am33xx_compat_clks[] = {
+       DT_CLK(NULL, "timer_32k_ck", "l4_per_cm:0138:0"),
+       DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"),
+       DT_CLK(NULL, "clkdiv32k_ick", "l4_per_cm:0138:0"),
+       DT_CLK(NULL, "dbg_clka_ck", "l4_wkup_cm:0010:30"),
+       DT_CLK(NULL, "dbg_sysclk_ck", "l4_wkup_cm:0010:19"),
+       DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0004:18"),
+       DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0098:18"),
+       DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:009c:18"),
+       DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:00a0:18"),
+       DT_CLK(NULL, "stm_clk_div_ck", "l4_wkup_cm:0010:27"),
+       DT_CLK(NULL, "stm_pmd_clock_mux_ck", "l4_wkup_cm:0010:22"),
+       DT_CLK(NULL, "trace_clk_div_ck", "l4_wkup_cm:0010:24"),
+       DT_CLK(NULL, "trace_pmd_clk_mux_ck", "l4_wkup_cm:0010:20"),
+       { .node_name = NULL },
+};
index 12e0a2d1991124504c3ac9a0c5245b991b9921f4..a360d310955523161502d86c7240c2b7eb64c61f 100644 (file)
@@ -24,7 +24,7 @@
 #include "clock.h"
 
 static const char * const am3_gpio1_dbclk_parents[] __initconst = {
-       "l4_per_cm:clk:0138:0",
+       "clk-24mhz-clkctrl:0000:0",
        NULL,
 };
 
@@ -43,58 +43,86 @@ static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = {
-       { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
-       { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" },
-       { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" },
-       { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" },
-       { AM3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
-       { AM3_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" },
-       { AM3_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
-       { AM3_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" },
-       { AM3_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM3_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" },
-       { AM3_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" },
-       { AM3_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" },
-       { AM3_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" },
-       { AM3_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" },
-       { AM3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" },
-       { AM3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_GPIO2_CLKCTRL, am3_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_GPIO3_CLKCTRL, am3_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_GPIO4_CLKCTRL, am3_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" },
-       { AM3_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" },
-       { AM3_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" },
-       { AM3_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" },
-       { AM3_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" },
-       { AM3_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
-       { AM3_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" },
-       { AM3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM3_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l4hs_clkdm" },
-       { AM3_OCPWP_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM3_CLKDIV32K_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ck", "clk_24mhz_clkdm" },
+static const struct omap_clkctrl_reg_data am3_l4ls_clkctrl_regs[] __initconst = {
+       { AM3_L4LS_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM3_L4LS_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM3_L4LS_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" },
+       { AM3_L4LS_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" },
+       { AM3_L4LS_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" },
+       { AM3_L4LS_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" },
+       { AM3_L4LS_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" },
+       { AM3_L4LS_GPIO2_CLKCTRL, am3_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_GPIO3_CLKCTRL, am3_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_GPIO4_CLKCTRL, am3_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" },
+       { AM3_L4LS_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" },
+       { AM3_L4LS_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" },
+       { AM3_L4LS_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" },
+       { AM3_L4LS_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM3_L4LS_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM3_L4LS_OCPWP_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l3s_clkctrl_regs[] __initconst = {
+       { AM3_L3S_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck" },
+       { AM3_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" },
+       { AM3_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" },
+       { AM3_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" },
+       { AM3_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l3_clkctrl_regs[] __initconst = {
+       { AM3_L3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck" },
+       { AM3_L3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck" },
+       { AM3_L3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM3_L3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l4hs_clkctrl_regs[] __initconst = {
+       { AM3_L4HS_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_pruss_ocp_clkctrl_regs[] __initconst = {
+       { AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_cpsw_125mhz_clkctrl_regs[] __initconst = {
+       { AM3_CPSW_125MHZ_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_lcdc_clkctrl_regs[] __initconst = {
+       { AM3_LCDC_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_clk_24mhz_clkctrl_regs[] __initconst = {
+       { AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ck" },
        { 0 },
 };
 
@@ -108,19 +136,33 @@ static const struct omap_clkctrl_bit_data am3_gpio1_bit_data[] __initconst = {
        { 0 },
 };
 
+static const struct omap_clkctrl_reg_data am3_l4_wkup_clkctrl_regs[] __initconst = {
+       { AM3_L4_WKUP_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
+       { AM3_L4_WKUP_GPIO1_CLKCTRL, am3_gpio1_bit_data, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
+       { AM3_L4_WKUP_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
+       { AM3_L4_WKUP_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
+       { AM3_L4_WKUP_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
+       { AM3_L4_WKUP_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" },
+       { AM3_L4_WKUP_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" },
+       { AM3_L4_WKUP_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" },
+       { AM3_L4_WKUP_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" },
+       { AM3_L4_WKUP_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" },
+       { 0 },
+};
+
 static const char * const am3_dbg_sysclk_ck_parents[] __initconst = {
        "sys_clkin_ck",
        NULL,
 };
 
 static const char * const am3_trace_pmd_clk_mux_ck_parents[] __initconst = {
-       "l4_wkup_cm:clk:0010:19",
-       "l4_wkup_cm:clk:0010:30",
+       "l3-aon-clkctrl:0000:19",
+       "l3-aon-clkctrl:0000:30",
        NULL,
 };
 
 static const char * const am3_trace_clk_div_ck_parents[] __initconst = {
-       "l4_wkup_cm:clk:0010:20",
+       "l3-aon-clkctrl:0000:20",
        NULL,
 };
 
@@ -130,7 +172,7 @@ static const struct omap_clkctrl_div_data am3_trace_clk_div_ck_data __initconst
 };
 
 static const char * const am3_stm_clk_div_ck_parents[] __initconst = {
-       "l4_wkup_cm:clk:0010:22",
+       "l3-aon-clkctrl:0000:22",
        NULL,
 };
 
@@ -154,66 +196,69 @@ static const struct omap_clkctrl_bit_data am3_debugss_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_reg_data am3_l4_wkup_clkctrl_regs[] __initconst = {
-       { AM3_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
-       { AM3_GPIO1_CLKCTRL, am3_gpio1_bit_data, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
-       { AM3_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" },
-       { AM3_DEBUGSS_CLKCTRL, am3_debugss_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0010:24", "l3_aon_clkdm" },
-       { AM3_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "dpll_core_m4_div2_ck", "l4_wkup_aon_clkdm" },
-       { AM3_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
-       { AM3_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
-       { AM3_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" },
-       { AM3_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" },
-       { AM3_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" },
-       { AM3_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" },
-       { AM3_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" },
+static const struct omap_clkctrl_reg_data am3_l3_aon_clkctrl_regs[] __initconst = {
+       { AM3_L3_AON_DEBUGSS_CLKCTRL, am3_debugss_bit_data, CLKF_SW_SUP, "l3-aon-clkctrl:0000:24" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am3_l4_wkup_aon_clkctrl_regs[] __initconst = {
+       { AM3_L4_WKUP_AON_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "dpll_core_m4_div2_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am3_mpu_clkctrl_regs[] __initconst = {
-       { AM3_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" },
+       { AM3_MPU_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = {
-       { AM3_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" },
+       { AM3_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = {
-       { AM3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
+       { AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am3_l4_cefuse_clkctrl_regs[] __initconst = {
-       { AM3_CEFUSE_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" },
+       { AM3_L4_CEFUSE_CEFUSE_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" },
        { 0 },
 };
 
 const struct omap_clkctrl_data am3_clkctrl_data[] __initconst = {
-       { 0x44e00014, am3_l4_per_clkctrl_regs },
-       { 0x44e00404, am3_l4_wkup_clkctrl_regs },
-       { 0x44e00604, am3_mpu_clkctrl_regs },
+       { 0x44e00038, am3_l4ls_clkctrl_regs },
+       { 0x44e0001c, am3_l3s_clkctrl_regs },
+       { 0x44e00024, am3_l3_clkctrl_regs },
+       { 0x44e00120, am3_l4hs_clkctrl_regs },
+       { 0x44e000e8, am3_pruss_ocp_clkctrl_regs },
+       { 0x44e00000, am3_cpsw_125mhz_clkctrl_regs },
+       { 0x44e00018, am3_lcdc_clkctrl_regs },
+       { 0x44e0014c, am3_clk_24mhz_clkctrl_regs },
+       { 0x44e00400, am3_l4_wkup_clkctrl_regs },
+       { 0x44e00414, am3_l3_aon_clkctrl_regs },
+       { 0x44e004b0, am3_l4_wkup_aon_clkctrl_regs },
+       { 0x44e00600, am3_mpu_clkctrl_regs },
        { 0x44e00800, am3_l4_rtc_clkctrl_regs },
-       { 0x44e00904, am3_gfx_l3_clkctrl_regs },
-       { 0x44e00a20, am3_l4_cefuse_clkctrl_regs },
+       { 0x44e00900, am3_gfx_l3_clkctrl_regs },
+       { 0x44e00a00, am3_l4_cefuse_clkctrl_regs },
        { 0 },
 };
 
 static struct ti_dt_clk am33xx_clks[] = {
-       DT_CLK(NULL, "timer_32k_ck", "l4_per_cm:0138:0"),
+       DT_CLK(NULL, "timer_32k_ck", "clk-24mhz-clkctrl:0000:0"),
        DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"),
-       DT_CLK(NULL, "clkdiv32k_ick", "l4_per_cm:0138:0"),
-       DT_CLK(NULL, "dbg_clka_ck", "l4_wkup_cm:0010:30"),
-       DT_CLK(NULL, "dbg_sysclk_ck", "l4_wkup_cm:0010:19"),
-       DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0004:18"),
-       DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0098:18"),
-       DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:009c:18"),
-       DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:00a0:18"),
-       DT_CLK(NULL, "stm_clk_div_ck", "l4_wkup_cm:0010:27"),
-       DT_CLK(NULL, "stm_pmd_clock_mux_ck", "l4_wkup_cm:0010:22"),
-       DT_CLK(NULL, "trace_clk_div_ck", "l4_wkup_cm:0010:24"),
-       DT_CLK(NULL, "trace_pmd_clk_mux_ck", "l4_wkup_cm:0010:20"),
+       DT_CLK(NULL, "clkdiv32k_ick", "clk-24mhz-clkctrl:0000:0"),
+       DT_CLK(NULL, "dbg_clka_ck", "l3-aon-clkctrl:0000:30"),
+       DT_CLK(NULL, "dbg_sysclk_ck", "l3-aon-clkctrl:0000:19"),
+       DT_CLK(NULL, "gpio0_dbclk", "l4-wkup-clkctrl:0008:18"),
+       DT_CLK(NULL, "gpio1_dbclk", "l4ls-clkctrl:0074:18"),
+       DT_CLK(NULL, "gpio2_dbclk", "l4ls-clkctrl:0078:18"),
+       DT_CLK(NULL, "gpio3_dbclk", "l4ls-clkctrl:007c:18"),
+       DT_CLK(NULL, "stm_clk_div_ck", "l3-aon-clkctrl:0000:27"),
+       DT_CLK(NULL, "stm_pmd_clock_mux_ck", "l3-aon-clkctrl:0000:22"),
+       DT_CLK(NULL, "trace_clk_div_ck", "l3-aon-clkctrl:0000:24"),
+       DT_CLK(NULL, "trace_pmd_clk_mux_ck", "l3-aon-clkctrl:0000:20"),
        { .node_name = NULL },
 };
 
@@ -232,7 +277,10 @@ int __init am33xx_dt_clk_init(void)
 {
        struct clk *clk1, *clk2;
 
-       ti_dt_clocks_register(am33xx_clks);
+       if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+               ti_dt_clocks_register(am33xx_compat_clks);
+       else
+               ti_dt_clocks_register(am33xx_clks);
 
        omap2_clk_disable_autoidle_all();
 
diff --git a/drivers/clk/ti/clk-43xx-compat.c b/drivers/clk/ti/clk-43xx-compat.c
new file mode 100644 (file)
index 0000000..5130398
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * AM43XX Clock init
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc
+ *     Tero Kristo (t-kristo@ti.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+#include <dt-bindings/clock/am4.h>
+
+#include "clock.h"
+
+static const char * const am4_synctimer_32kclk_parents[] __initconst = {
+       "mux_synctimer32k_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am4_counter_32k_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_synctimer_32kclk_parents, NULL },
+       { 0 },
+};
+
+static const char * const am4_gpio0_dbclk_parents[] __initconst = {
+       "gpio0_dbclk_mux_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am4_gpio1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_gpio0_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_l4_wkup_clkctrl_regs[] __initconst = {
+       { AM4_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck", "l3s_tsc_clkdm" },
+       { AM4_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" },
+       { AM4_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "sys_clkin_ck" },
+       { AM4_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0210:8" },
+       { AM4_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck", "l4_wkup_clkdm" },
+       { AM4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck", "l4_wkup_clkdm" },
+       { AM4_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" },
+       { AM4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" },
+       { AM4_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck", "l4_wkup_clkdm" },
+       { AM4_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck", "l4_wkup_clkdm" },
+       { AM4_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" },
+       { AM4_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = {
+       { AM4_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = {
+       { AM4_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = {
+       { AM4_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" },
+       { 0 },
+};
+
+static const char * const am4_usb_otg_ss0_refclk960m_parents[] __initconst = {
+       "dpll_per_clkdcoldo",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am4_usb_otg_ss0_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am4_usb_otg_ss1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL },
+       { 0 },
+};
+
+static const char * const am4_gpio1_dbclk_parents[] __initconst = {
+       "clkdiv32k_ick",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data am4_gpio2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am4_gpio3_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am4_gpio4_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am4_gpio5_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data am4_gpio6_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst = {
+       { AM4_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" },
+       { AM4_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" },
+       { AM4_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" },
+       { AM4_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
+       { AM4_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l3_clkdm" },
+       { AM4_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
+       { AM4_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" },
+       { AM4_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" },
+       { AM4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" },
+       { AM4_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
+       { AM4_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
+       { AM4_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
+       { AM4_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" },
+       { AM4_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" },
+       { AM4_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" },
+       { AM4_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" },
+       { AM4_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM4_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM4_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" },
+       { AM4_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" },
+       { AM4_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" },
+       { AM4_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" },
+       { AM4_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" },
+       { AM4_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" },
+       { AM4_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" },
+       { AM4_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" },
+       { AM4_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" },
+       { AM4_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" },
+       { AM4_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" },
+       { AM4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" },
+       { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" },
+       { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
+       { 0 },
+};
+
+const struct omap_clkctrl_data am4_clkctrl_compat_data[] __initconst = {
+       { 0x44df2820, am4_l4_wkup_clkctrl_regs },
+       { 0x44df8320, am4_mpu_clkctrl_regs },
+       { 0x44df8420, am4_gfx_l3_clkctrl_regs },
+       { 0x44df8520, am4_l4_rtc_clkctrl_regs },
+       { 0x44df8820, am4_l4_per_clkctrl_regs },
+       { 0 },
+};
+
+const struct omap_clkctrl_data am438x_clkctrl_compat_data[] __initconst = {
+       { 0x44df2820, am4_l4_wkup_clkctrl_regs },
+       { 0x44df8320, am4_mpu_clkctrl_regs },
+       { 0x44df8420, am4_gfx_l3_clkctrl_regs },
+       { 0x44df8820, am4_l4_per_clkctrl_regs },
+       { 0 },
+};
+
+struct ti_dt_clk am43xx_compat_clks[] = {
+       DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"),
+       DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"),
+       DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0348:8"),
+       DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0458:8"),
+       DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:0460:8"),
+       DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:0468:8"),
+       DT_CLK(NULL, "gpio4_dbclk", "l4_per_cm:0470:8"),
+       DT_CLK(NULL, "gpio5_dbclk", "l4_per_cm:0478:8"),
+       DT_CLK(NULL, "synctimer_32kclk", "l4_wkup_cm:0210:8"),
+       DT_CLK(NULL, "usb_otg_ss0_refclk960m", "l4_per_cm:0240:8"),
+       DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l4_per_cm:0248:8"),
+       { .node_name = NULL },
+};
index 63c5ddb501876993f0584364f44ed56a28bc175d..2782d91838ac4368e49c8ea9421d01963dff1391 100644 (file)
 
 #include "clock.h"
 
+static const struct omap_clkctrl_reg_data am4_l3s_tsc_clkctrl_regs[] __initconst = {
+       { AM4_L3S_TSC_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" },
+       { 0 },
+};
+
 static const char * const am4_synctimer_32kclk_parents[] __initconst = {
        "mux_synctimer32k_ck",
        NULL,
@@ -33,6 +38,12 @@ static const struct omap_clkctrl_bit_data am4_counter_32k_bit_data[] __initconst
        { 0 },
 };
 
+static const struct omap_clkctrl_reg_data am4_l4_wkup_aon_clkctrl_regs[] __initconst = {
+       { AM4_L4_WKUP_AON_WKUP_M3_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "sys_clkin_ck" },
+       { AM4_L4_WKUP_AON_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4-wkup-aon-clkctrl:0008:8" },
+       { 0 },
+};
+
 static const char * const am4_gpio0_dbclk_parents[] __initconst = {
        "gpio0_dbclk_mux_ck",
        NULL,
@@ -44,33 +55,45 @@ static const struct omap_clkctrl_bit_data am4_gpio1_bit_data[] __initconst = {
 };
 
 static const struct omap_clkctrl_reg_data am4_l4_wkup_clkctrl_regs[] __initconst = {
-       { AM4_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck", "l3s_tsc_clkdm" },
-       { AM4_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" },
-       { AM4_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "sys_clkin_ck" },
-       { AM4_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0210:8" },
-       { AM4_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck", "l4_wkup_clkdm" },
-       { AM4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck", "l4_wkup_clkdm" },
-       { AM4_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" },
-       { AM4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" },
-       { AM4_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck", "l4_wkup_clkdm" },
-       { AM4_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck", "l4_wkup_clkdm" },
-       { AM4_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" },
-       { AM4_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" },
+       { AM4_L4_WKUP_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" },
+       { AM4_L4_WKUP_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" },
+       { AM4_L4_WKUP_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" },
+       { AM4_L4_WKUP_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
+       { AM4_L4_WKUP_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" },
+       { AM4_L4_WKUP_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" },
+       { AM4_L4_WKUP_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" },
+       { AM4_L4_WKUP_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" },
+       { AM4_L4_WKUP_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = {
-       { AM4_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" },
+       { AM4_MPU_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = {
-       { AM4_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
+       { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = {
-       { AM4_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" },
+       { AM4_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_l3_clkctrl_regs[] __initconst = {
+       { AM4_L3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck" },
+       { AM4_L3_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk" },
        { 0 },
 };
 
@@ -89,6 +112,24 @@ static const struct omap_clkctrl_bit_data am4_usb_otg_ss1_bit_data[] __initconst
        { 0 },
 };
 
+static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = {
+       { AM4_L3S_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3S_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" },
+       { AM4_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" },
+       { AM4_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" },
+       { AM4_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" },
+       { AM4_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM4_L3S_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" },
+       { AM4_L3S_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk" },
+       { AM4_L3S_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_pruss_ocp_clkctrl_regs[] __initconst = {
+       { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" },
+       { 0 },
+};
+
 static const char * const am4_gpio1_dbclk_parents[] __initconst = {
        "clkdiv32k_ick",
        NULL,
@@ -119,108 +160,115 @@ static const struct omap_clkctrl_bit_data am4_gpio6_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst = {
-       { AM4_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" },
-       { AM4_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" },
-       { AM4_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" },
-       { AM4_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
-       { AM4_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l3_clkdm" },
-       { AM4_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
-       { AM4_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" },
-       { AM4_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" },
-       { AM4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" },
-       { AM4_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
-       { AM4_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
-       { AM4_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" },
-       { AM4_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" },
-       { AM4_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" },
-       { AM4_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" },
-       { AM4_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" },
-       { AM4_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
-       { AM4_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
-       { AM4_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" },
-       { AM4_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" },
-       { AM4_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" },
-       { AM4_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" },
-       { AM4_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" },
-       { AM4_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" },
-       { AM4_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" },
-       { AM4_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" },
-       { AM4_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" },
-       { AM4_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" },
-       { AM4_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" },
-       { AM4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
-       { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
-       { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" },
-       { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" },
-       { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
+static const struct omap_clkctrl_reg_data am4_l4ls_clkctrl_regs[] __initconst = {
+       { AM4_L4LS_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" },
+       { AM4_L4LS_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" },
+       { AM4_L4LS_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" },
+       { AM4_L4LS_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM4_L4LS_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" },
+       { AM4_L4LS_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" },
+       { AM4_L4LS_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" },
+       { AM4_L4LS_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" },
+       { AM4_L4LS_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" },
+       { AM4_L4LS_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" },
+       { AM4_L4LS_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" },
+       { AM4_L4LS_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" },
+       { AM4_L4LS_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" },
+       { AM4_L4LS_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" },
+       { AM4_L4LS_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" },
+       { AM4_L4LS_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" },
+       { AM4_L4LS_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" },
+       { AM4_L4LS_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { AM4_L4LS_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_emif_clkctrl_regs[] __initconst = {
+       { AM4_EMIF_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_dss_clkctrl_regs[] __initconst = {
+       { AM4_DSS_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data am4_cpsw_125mhz_clkctrl_regs[] __initconst = {
+       { AM4_CPSW_125MHZ_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk" },
        { 0 },
 };
 
 const struct omap_clkctrl_data am4_clkctrl_data[] __initconst = {
-       { 0x44df2820, am4_l4_wkup_clkctrl_regs },
+       { 0x44df2920, am4_l3s_tsc_clkctrl_regs },
+       { 0x44df2a28, am4_l4_wkup_aon_clkctrl_regs },
+       { 0x44df2a20, am4_l4_wkup_clkctrl_regs },
        { 0x44df8320, am4_mpu_clkctrl_regs },
        { 0x44df8420, am4_gfx_l3_clkctrl_regs },
        { 0x44df8520, am4_l4_rtc_clkctrl_regs },
-       { 0x44df8820, am4_l4_per_clkctrl_regs },
+       { 0x44df8820, am4_l3_clkctrl_regs },
+       { 0x44df8868, am4_l3s_clkctrl_regs },
+       { 0x44df8b20, am4_pruss_ocp_clkctrl_regs },
+       { 0x44df8c20, am4_l4ls_clkctrl_regs },
+       { 0x44df8f20, am4_emif_clkctrl_regs },
+       { 0x44df9220, am4_dss_clkctrl_regs },
+       { 0x44df9320, am4_cpsw_125mhz_clkctrl_regs },
        { 0 },
 };
 
 const struct omap_clkctrl_data am438x_clkctrl_data[] __initconst = {
-       { 0x44df2820, am4_l4_wkup_clkctrl_regs },
+       { 0x44df2920, am4_l3s_tsc_clkctrl_regs },
+       { 0x44df2a28, am4_l4_wkup_aon_clkctrl_regs },
+       { 0x44df2a20, am4_l4_wkup_clkctrl_regs },
        { 0x44df8320, am4_mpu_clkctrl_regs },
        { 0x44df8420, am4_gfx_l3_clkctrl_regs },
-       { 0x44df8820, am4_l4_per_clkctrl_regs },
+       { 0x44df8820, am4_l3_clkctrl_regs },
+       { 0x44df8868, am4_l3s_clkctrl_regs },
+       { 0x44df8b20, am4_pruss_ocp_clkctrl_regs },
+       { 0x44df8c20, am4_l4ls_clkctrl_regs },
+       { 0x44df8f20, am4_emif_clkctrl_regs },
+       { 0x44df9220, am4_dss_clkctrl_regs },
+       { 0x44df9320, am4_cpsw_125mhz_clkctrl_regs },
        { 0 },
 };
 
 static struct ti_dt_clk am43xx_clks[] = {
        DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"),
        DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"),
-       DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0348:8"),
-       DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0458:8"),
-       DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:0460:8"),
-       DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:0468:8"),
-       DT_CLK(NULL, "gpio4_dbclk", "l4_per_cm:0470:8"),
-       DT_CLK(NULL, "gpio5_dbclk", "l4_per_cm:0478:8"),
-       DT_CLK(NULL, "synctimer_32kclk", "l4_wkup_cm:0210:8"),
-       DT_CLK(NULL, "usb_otg_ss0_refclk960m", "l4_per_cm:0240:8"),
-       DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l4_per_cm:0248:8"),
+       DT_CLK(NULL, "gpio0_dbclk", "l4-wkup-clkctrl:0148:8"),
+       DT_CLK(NULL, "gpio1_dbclk", "l4ls-clkctrl:0058:8"),
+       DT_CLK(NULL, "gpio2_dbclk", "l4ls-clkctrl:0060:8"),
+       DT_CLK(NULL, "gpio3_dbclk", "l4ls-clkctrl:0068:8"),
+       DT_CLK(NULL, "gpio4_dbclk", "l4ls-clkctrl:0070:8"),
+       DT_CLK(NULL, "gpio5_dbclk", "l4ls-clkctrl:0078:8"),
+       DT_CLK(NULL, "synctimer_32kclk", "l4-wkup-aon-clkctrl:0008:8"),
+       DT_CLK(NULL, "usb_otg_ss0_refclk960m", "l3s-clkctrl:01f8:8"),
+       DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3s-clkctrl:0200:8"),
        { .node_name = NULL },
 };
 
@@ -228,7 +276,10 @@ int __init am43xx_dt_clk_init(void)
 {
        struct clk *clk1, *clk2;
 
-       ti_dt_clocks_register(am43xx_clks);
+       if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+               ti_dt_clocks_register(am43xx_compat_clks);
+       else
+               ti_dt_clocks_register(am43xx_clks);
 
        omap2_clk_disable_autoidle_all();
 
diff --git a/drivers/clk/ti/clk-7xx-compat.c b/drivers/clk/ti/clk-7xx-compat.c
new file mode 100644 (file)
index 0000000..e3cb7f0
--- /dev/null
@@ -0,0 +1,823 @@
+/*
+ * DRA7 Clock init
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * Tero Kristo (t-kristo@ti.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk/ti.h>
+#include <dt-bindings/clock/dra7.h>
+
+#include "clock.h"
+
+#define DRA7_DPLL_GMAC_DEFFREQ                         1000000000
+#define DRA7_DPLL_USB_DEFFREQ                          960000000
+
+static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = {
+       { DRA7_MPU_CLKCTRL, NULL, 0, "dpll_mpu_m2_ck" },
+       { 0 },
+};
+
+static const char * const dra7_mcasp1_aux_gfclk_mux_parents[] __initconst = {
+       "per_abe_x1_gfclk2_div",
+       "video1_clk2_div",
+       "video2_clk2_div",
+       "hdmi_clk2_div",
+       NULL,
+};
+
+static const char * const dra7_mcasp1_ahclkx_mux_parents[] __initconst = {
+       "abe_24m_fclk",
+       "abe_sys_clk_div",
+       "func_24m_clk",
+       "atl_clkin3_ck",
+       "atl_clkin2_ck",
+       "atl_clkin1_ck",
+       "atl_clkin0_ck",
+       "sys_clkin2",
+       "ref_clkin0_ck",
+       "ref_clkin1_ck",
+       "ref_clkin2_ck",
+       "ref_clkin3_ck",
+       "mlb_clk",
+       "mlbp_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp1_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_timer5_gfclk_mux_parents[] __initconst = {
+       "timer_sys_clk_div",
+       "sys_32k_ck",
+       "sys_clkin2",
+       "ref_clkin0_ck",
+       "ref_clkin1_ck",
+       "ref_clkin2_ck",
+       "ref_clkin3_ck",
+       "abe_giclk_div",
+       "video1_div_clk",
+       "video2_div_clk",
+       "hdmi_div_clk",
+       "clkoutmux0_clk_mux",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer5_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer6_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer7_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer8_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_uart6_gfclk_mux_parents[] __initconst = {
+       "func_48m_fclk",
+       "dpll_per_m2x2_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart6_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = {
+       { DRA7_MCASP1_CLKCTRL, dra7_mcasp1_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0010:22" },
+       { DRA7_TIMER5_CLKCTRL, dra7_timer5_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0018:24" },
+       { DRA7_TIMER6_CLKCTRL, dra7_timer6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0020:24" },
+       { DRA7_TIMER7_CLKCTRL, dra7_timer7_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0028:24" },
+       { DRA7_TIMER8_CLKCTRL, dra7_timer8_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0030:24" },
+       { DRA7_I2C5_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_UART6_CLKCTRL, dra7_uart6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0040:24" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst = {
+       { DRA7_RTCSS_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = {
+       { DRA7_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
+       { DRA7_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initconst = {
+       { DRA7_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_TPCC_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_TPTC0_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_TPTC1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_VCP1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_VCP2_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_dma_clkctrl_regs[] __initconst = {
+       { DRA7_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_emif_clkctrl_regs[] __initconst = {
+       { DRA7_DMM_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { 0 },
+};
+
+static const char * const dra7_atl_dpll_clk_mux_parents[] __initconst = {
+       "sys_32k_ck",
+       "video1_clkin_ck",
+       "video2_clkin_ck",
+       "hdmi_clkin_ck",
+       NULL,
+};
+
+static const char * const dra7_atl_gfclk_mux_parents[] __initconst = {
+       "l3_iclk_div",
+       "dpll_abe_m2_ck",
+       "atl_cm:clk:0000:24",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_atl_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_atl_dpll_clk_mux_parents, NULL },
+       { 26, TI_CLK_MUX, dra7_atl_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_atl_clkctrl_regs[] __initconst = {
+       { DRA7_ATL_CLKCTRL, dra7_atl_bit_data, CLKF_SW_SUP, "atl_cm:clk:0000:26" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l4cfg_clkctrl_regs[] __initconst = {
+       { DRA7_L4_CFG_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_SPINLOCK_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX2_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX3_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX4_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX5_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX6_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX7_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX8_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX9_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX10_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX11_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX12_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_MAILBOX13_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l3instr_clkctrl_regs[] __initconst = {
+       { DRA7_L3_MAIN_2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { 0 },
+};
+
+static const char * const dra7_dss_dss_clk_parents[] __initconst = {
+       "dpll_per_h12x2_ck",
+       NULL,
+};
+
+static const char * const dra7_dss_48mhz_clk_parents[] __initconst = {
+       "func_48m_fclk",
+       NULL,
+};
+
+static const char * const dra7_dss_hdmi_clk_parents[] __initconst = {
+       "hdmi_dpll_clk_mux",
+       NULL,
+};
+
+static const char * const dra7_dss_32khz_clk_parents[] __initconst = {
+       "sys_32k_ck",
+       NULL,
+};
+
+static const char * const dra7_dss_video1_clk_parents[] __initconst = {
+       "video1_dpll_clk_mux",
+       NULL,
+};
+
+static const char * const dra7_dss_video2_clk_parents[] __initconst = {
+       "video2_dpll_clk_mux",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_dss_core_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_dss_clk_parents, NULL },
+       { 9, TI_CLK_GATE, dra7_dss_48mhz_clk_parents, NULL },
+       { 10, TI_CLK_GATE, dra7_dss_hdmi_clk_parents, NULL },
+       { 11, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 12, TI_CLK_GATE, dra7_dss_video1_clk_parents, NULL },
+       { 13, TI_CLK_GATE, dra7_dss_video2_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst = {
+       { DRA7_DSS_CORE_CLKCTRL, dra7_dss_core_bit_data, CLKF_SW_SUP, "dss_cm:clk:0000:8" },
+       { DRA7_BB2D_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_h24x2_ck" },
+       { 0 },
+};
+
+static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = {
+       "func_128m_clk",
+       "dpll_per_m2x2_ck",
+       NULL,
+};
+
+static const char * const dra7_mmc1_fclk_div_parents[] __initconst = {
+       "l3init_cm:clk:0008:24",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data dra7_mmc1_fclk_div_data __initconst = {
+       .max_div = 4,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const struct omap_clkctrl_bit_data dra7_mmc1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL },
+       { 25, TI_CLK_DIVIDER, dra7_mmc1_fclk_div_parents, &dra7_mmc1_fclk_div_data },
+       { 0 },
+};
+
+static const char * const dra7_mmc2_fclk_div_parents[] __initconst = {
+       "l3init_cm:clk:0010:24",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data dra7_mmc2_fclk_div_data __initconst = {
+       .max_div = 4,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const struct omap_clkctrl_bit_data dra7_mmc2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL },
+       { 25, TI_CLK_DIVIDER, dra7_mmc2_fclk_div_parents, &dra7_mmc2_fclk_div_data },
+       { 0 },
+};
+
+static const char * const dra7_usb_otg_ss2_refclk960m_parents[] __initconst = {
+       "l3init_960m_gfclk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_usb_otg_ss2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_sata_ref_clk_parents[] __initconst = {
+       "sys_clkin1",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_sata_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_sata_ref_clk_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_optfclk_pciephy1_clk_parents[] __initconst = {
+       "apll_pcie_ck",
+       NULL,
+};
+
+static const char * const dra7_optfclk_pciephy1_div_clk_parents[] __initconst = {
+       "optfclk_pciephy_div",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_pcie1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL },
+       { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_pcie2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL },
+       { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_rmii_50mhz_clk_mux_parents[] __initconst = {
+       "dpll_gmac_h11x2_ck",
+       "rmii_clk_ck",
+       NULL,
+};
+
+static const char * const dra7_gmac_rft_clk_mux_parents[] __initconst = {
+       "video1_clkin_ck",
+       "video2_clkin_ck",
+       "dpll_abe_m2_ck",
+       "hdmi_clkin_ck",
+       "l3_iclk_div",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_rmii_50mhz_clk_mux_parents, NULL },
+       { 25, TI_CLK_MUX, dra7_gmac_rft_clk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_usb_otg_ss1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst = {
+       { DRA7_MMC1_CLKCTRL, dra7_mmc1_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0008:25" },
+       { DRA7_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" },
+       { DRA7_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { DRA7_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { DRA7_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { DRA7_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" },
+       { DRA7_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" },
+       { DRA7_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck", "gmac_clkdm" },
+       { DRA7_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
+       { DRA7_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
+       { DRA7_USB_OTG_SS1_CLKCTRL, dra7_usb_otg_ss1_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { 0 },
+};
+
+static const char * const dra7_timer10_gfclk_mux_parents[] __initconst = {
+       "timer_sys_clk_div",
+       "sys_32k_ck",
+       "sys_clkin2",
+       "ref_clkin0_ck",
+       "ref_clkin1_ck",
+       "ref_clkin2_ck",
+       "ref_clkin3_ck",
+       "abe_giclk_div",
+       "video1_div_clk",
+       "video2_div_clk",
+       "hdmi_div_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer10_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer11_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer2_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer3_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer4_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer9_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio3_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio4_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio5_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio6_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer13_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer14_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer15_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio7_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio8_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_mmc3_gfclk_div_parents[] __initconst = {
+       "l4per_cm:clk:0120:24",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data dra7_mmc3_gfclk_div_data __initconst = {
+       .max_div = 4,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const struct omap_clkctrl_bit_data dra7_mmc3_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 25, TI_CLK_DIVIDER, dra7_mmc3_gfclk_div_parents, &dra7_mmc3_gfclk_div_data },
+       { 0 },
+};
+
+static const char * const dra7_mmc4_gfclk_div_parents[] __initconst = {
+       "l4per_cm:clk:0128:24",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data dra7_mmc4_gfclk_div_data __initconst = {
+       .max_div = 4,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const struct omap_clkctrl_bit_data dra7_mmc4_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 25, TI_CLK_DIVIDER, dra7_mmc4_gfclk_div_parents, &dra7_mmc4_gfclk_div_data },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer16_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_qspi_gfclk_mux_parents[] __initconst = {
+       "func_128m_clk",
+       "dpll_per_h13x2_ck",
+       NULL,
+};
+
+static const char * const dra7_qspi_gfclk_div_parents[] __initconst = {
+       "l4per_cm:clk:0138:24",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data dra7_qspi_gfclk_div_data __initconst = {
+       .max_div = 4,
+       .flags = CLK_DIVIDER_POWER_OF_TWO,
+};
+
+static const struct omap_clkctrl_bit_data dra7_qspi_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_qspi_gfclk_mux_parents, NULL },
+       { 25, TI_CLK_DIVIDER, dra7_qspi_gfclk_div_parents, &dra7_qspi_gfclk_div_data },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart2_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart3_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart4_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp2_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp3_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart5_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp5_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp8_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp4_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart7_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart8_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart9_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp6_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_mcasp7_bit_data[] __initconst = {
+       { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
+       { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst = {
+       { DRA7_L4_PER2_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per2_clkdm" },
+       { DRA7_L4_PER3_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per3_clkdm" },
+       { DRA7_TIMER10_CLKCTRL, dra7_timer10_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0028:24" },
+       { DRA7_TIMER11_CLKCTRL, dra7_timer11_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0030:24" },
+       { DRA7_TIMER2_CLKCTRL, dra7_timer2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0038:24" },
+       { DRA7_TIMER3_CLKCTRL, dra7_timer3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0040:24" },
+       { DRA7_TIMER4_CLKCTRL, dra7_timer4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0048:24" },
+       { DRA7_TIMER9_CLKCTRL, dra7_timer9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0050:24" },
+       { DRA7_ELM_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_GPIO2_CLKCTRL, dra7_gpio2_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_GPIO3_CLKCTRL, dra7_gpio3_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_GPIO4_CLKCTRL, dra7_gpio4_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_GPIO5_CLKCTRL, dra7_gpio5_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_GPIO6_CLKCTRL, dra7_gpio6_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" },
+       { DRA7_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" },
+       { DRA7_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" },
+       { DRA7_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_L4_PER1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" },
+       { DRA7_TIMER13_CLKCTRL, dra7_timer13_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00c8:24", "l4per3_clkdm" },
+       { DRA7_TIMER14_CLKCTRL, dra7_timer14_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d0:24", "l4per3_clkdm" },
+       { DRA7_TIMER15_CLKCTRL, dra7_timer15_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d8:24", "l4per3_clkdm" },
+       { DRA7_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_GPIO7_CLKCTRL, dra7_gpio7_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_GPIO8_CLKCTRL, dra7_gpio8_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_MMC3_CLKCTRL, dra7_mmc3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0120:25" },
+       { DRA7_MMC4_CLKCTRL, dra7_mmc4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0128:25" },
+       { DRA7_TIMER16_CLKCTRL, dra7_timer16_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0130:24", "l4per3_clkdm" },
+       { DRA7_QSPI_CLKCTRL, dra7_qspi_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0138:25", "l4per2_clkdm" },
+       { DRA7_UART1_CLKCTRL, dra7_uart1_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0140:24" },
+       { DRA7_UART2_CLKCTRL, dra7_uart2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0148:24" },
+       { DRA7_UART3_CLKCTRL, dra7_uart3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0150:24" },
+       { DRA7_UART4_CLKCTRL, dra7_uart4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0158:24" },
+       { DRA7_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0160:22", "l4per2_clkdm" },
+       { DRA7_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0168:22", "l4per2_clkdm" },
+       { DRA7_UART5_CLKCTRL, dra7_uart5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0170:24" },
+       { DRA7_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0178:22", "l4per2_clkdm" },
+       { DRA7_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0190:24", "l4per2_clkdm" },
+       { DRA7_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0198:22", "l4per2_clkdm" },
+       { DRA7_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
+       { DRA7_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
+       { DRA7_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
+       { DRA7_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
+       { DRA7_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
+       { DRA7_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01d0:24", "l4per2_clkdm" },
+       { DRA7_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e0:24", "l4per2_clkdm" },
+       { DRA7_UART9_CLKCTRL, dra7_uart9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e8:24", "l4per2_clkdm" },
+       { DRA7_DCAN2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin1", "l4per2_clkdm" },
+       { DRA7_MCASP6_CLKCTRL, dra7_mcasp6_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0204:22", "l4per2_clkdm" },
+       { DRA7_MCASP7_CLKCTRL, dra7_mcasp7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0208:22", "l4per2_clkdm" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpio1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart10_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const char * const dra7_dcan1_sys_clk_mux_parents[] __initconst = {
+       "sys_clkin1",
+       "sys_clkin2",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_dcan1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_dcan1_sys_clk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initconst = {
+       { DRA7_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
+       { DRA7_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { DRA7_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" },
+       { DRA7_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" },
+       { DRA7_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" },
+       { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
+       { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" },
+       { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" },
+       { DRA7_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk"},
+       { 0 },
+};
+
+const struct omap_clkctrl_data dra7_clkctrl_compat_data[] __initconst = {
+       { 0x4a005320, dra7_mpu_clkctrl_regs },
+       { 0x4a005540, dra7_ipu_clkctrl_regs },
+       { 0x4a005740, dra7_rtc_clkctrl_regs },
+       { 0x4a008620, dra7_coreaon_clkctrl_regs },
+       { 0x4a008720, dra7_l3main1_clkctrl_regs },
+       { 0x4a008a20, dra7_dma_clkctrl_regs },
+       { 0x4a008b20, dra7_emif_clkctrl_regs },
+       { 0x4a008c00, dra7_atl_clkctrl_regs },
+       { 0x4a008d20, dra7_l4cfg_clkctrl_regs },
+       { 0x4a008e20, dra7_l3instr_clkctrl_regs },
+       { 0x4a009120, dra7_dss_clkctrl_regs },
+       { 0x4a009320, dra7_l3init_clkctrl_regs },
+       { 0x4a009700, dra7_l4per_clkctrl_regs },
+       { 0x4ae07820, dra7_wkupaon_clkctrl_regs },
+       { 0 },
+};
+
+struct ti_dt_clk dra7xx_compat_clks[] = {
+       DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
+       DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"),
+       DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
+       DT_CLK(NULL, "atl_dpll_clk_mux", "atl_cm:0000:24"),
+       DT_CLK(NULL, "atl_gfclk_mux", "atl_cm:0000:26"),
+       DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon_cm:0068:24"),
+       DT_CLK(NULL, "dss_32khz_clk", "dss_cm:0000:11"),
+       DT_CLK(NULL, "dss_48mhz_clk", "dss_cm:0000:9"),
+       DT_CLK(NULL, "dss_dss_clk", "dss_cm:0000:8"),
+       DT_CLK(NULL, "dss_hdmi_clk", "dss_cm:0000:10"),
+       DT_CLK(NULL, "dss_video1_clk", "dss_cm:0000:12"),
+       DT_CLK(NULL, "dss_video2_clk", "dss_cm:0000:13"),
+       DT_CLK(NULL, "gmac_rft_clk_mux", "l3init_cm:00b0:25"),
+       DT_CLK(NULL, "gpio1_dbclk", "wkupaon_cm:0018:8"),
+       DT_CLK(NULL, "gpio2_dbclk", "l4per_cm:0060:8"),
+       DT_CLK(NULL, "gpio3_dbclk", "l4per_cm:0068:8"),
+       DT_CLK(NULL, "gpio4_dbclk", "l4per_cm:0070:8"),
+       DT_CLK(NULL, "gpio5_dbclk", "l4per_cm:0078:8"),
+       DT_CLK(NULL, "gpio6_dbclk", "l4per_cm:0080:8"),
+       DT_CLK(NULL, "gpio7_dbclk", "l4per_cm:0110:8"),
+       DT_CLK(NULL, "gpio8_dbclk", "l4per_cm:0118:8"),
+       DT_CLK(NULL, "mcasp1_ahclkr_mux", "ipu_cm:0010:28"),
+       DT_CLK(NULL, "mcasp1_ahclkx_mux", "ipu_cm:0010:24"),
+       DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "ipu_cm:0010:22"),
+       DT_CLK(NULL, "mcasp2_ahclkr_mux", "l4per_cm:0160:28"),
+       DT_CLK(NULL, "mcasp2_ahclkx_mux", "l4per_cm:0160:24"),
+       DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "l4per_cm:0160:22"),
+       DT_CLK(NULL, "mcasp3_ahclkx_mux", "l4per_cm:0168:24"),
+       DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "l4per_cm:0168:22"),
+       DT_CLK(NULL, "mcasp4_ahclkx_mux", "l4per_cm:0198:24"),
+       DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "l4per_cm:0198:22"),
+       DT_CLK(NULL, "mcasp5_ahclkx_mux", "l4per_cm:0178:24"),
+       DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "l4per_cm:0178:22"),
+       DT_CLK(NULL, "mcasp6_ahclkx_mux", "l4per_cm:0204:24"),
+       DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per_cm:0204:22"),
+       DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per_cm:0208:24"),
+       DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per_cm:0208:22"),
+       DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per_cm:0190:22"),
+       DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per_cm:0190:24"),
+       DT_CLK(NULL, "mmc1_clk32k", "l3init_cm:0008:8"),
+       DT_CLK(NULL, "mmc1_fclk_div", "l3init_cm:0008:25"),
+       DT_CLK(NULL, "mmc1_fclk_mux", "l3init_cm:0008:24"),
+       DT_CLK(NULL, "mmc2_clk32k", "l3init_cm:0010:8"),
+       DT_CLK(NULL, "mmc2_fclk_div", "l3init_cm:0010:25"),
+       DT_CLK(NULL, "mmc2_fclk_mux", "l3init_cm:0010:24"),
+       DT_CLK(NULL, "mmc3_clk32k", "l4per_cm:0120:8"),
+       DT_CLK(NULL, "mmc3_gfclk_div", "l4per_cm:0120:25"),
+       DT_CLK(NULL, "mmc3_gfclk_mux", "l4per_cm:0120:24"),
+       DT_CLK(NULL, "mmc4_clk32k", "l4per_cm:0128:8"),
+       DT_CLK(NULL, "mmc4_gfclk_div", "l4per_cm:0128:25"),
+       DT_CLK(NULL, "mmc4_gfclk_mux", "l4per_cm:0128:24"),
+       DT_CLK(NULL, "optfclk_pciephy1_32khz", "l3init_cm:0090:8"),
+       DT_CLK(NULL, "optfclk_pciephy1_clk", "l3init_cm:0090:9"),
+       DT_CLK(NULL, "optfclk_pciephy1_div_clk", "l3init_cm:0090:10"),
+       DT_CLK(NULL, "optfclk_pciephy2_32khz", "l3init_cm:0098:8"),
+       DT_CLK(NULL, "optfclk_pciephy2_clk", "l3init_cm:0098:9"),
+       DT_CLK(NULL, "optfclk_pciephy2_div_clk", "l3init_cm:0098:10"),
+       DT_CLK(NULL, "qspi_gfclk_div", "l4per_cm:0138:25"),
+       DT_CLK(NULL, "qspi_gfclk_mux", "l4per_cm:0138:24"),
+       DT_CLK(NULL, "rmii_50mhz_clk_mux", "l3init_cm:00b0:24"),
+       DT_CLK(NULL, "sata_ref_clk", "l3init_cm:0068:8"),
+       DT_CLK(NULL, "timer10_gfclk_mux", "l4per_cm:0028:24"),
+       DT_CLK(NULL, "timer11_gfclk_mux", "l4per_cm:0030:24"),
+       DT_CLK(NULL, "timer13_gfclk_mux", "l4per_cm:00c8:24"),
+       DT_CLK(NULL, "timer14_gfclk_mux", "l4per_cm:00d0:24"),
+       DT_CLK(NULL, "timer15_gfclk_mux", "l4per_cm:00d8:24"),
+       DT_CLK(NULL, "timer16_gfclk_mux", "l4per_cm:0130:24"),
+       DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon_cm:0020:24"),
+       DT_CLK(NULL, "timer2_gfclk_mux", "l4per_cm:0038:24"),
+       DT_CLK(NULL, "timer3_gfclk_mux", "l4per_cm:0040:24"),
+       DT_CLK(NULL, "timer4_gfclk_mux", "l4per_cm:0048:24"),
+       DT_CLK(NULL, "timer5_gfclk_mux", "ipu_cm:0018:24"),
+       DT_CLK(NULL, "timer6_gfclk_mux", "ipu_cm:0020:24"),
+       DT_CLK(NULL, "timer7_gfclk_mux", "ipu_cm:0028:24"),
+       DT_CLK(NULL, "timer8_gfclk_mux", "ipu_cm:0030:24"),
+       DT_CLK(NULL, "timer9_gfclk_mux", "l4per_cm:0050:24"),
+       DT_CLK(NULL, "uart10_gfclk_mux", "wkupaon_cm:0060:24"),
+       DT_CLK(NULL, "uart1_gfclk_mux", "l4per_cm:0140:24"),
+       DT_CLK(NULL, "uart2_gfclk_mux", "l4per_cm:0148:24"),
+       DT_CLK(NULL, "uart3_gfclk_mux", "l4per_cm:0150:24"),
+       DT_CLK(NULL, "uart4_gfclk_mux", "l4per_cm:0158:24"),
+       DT_CLK(NULL, "uart5_gfclk_mux", "l4per_cm:0170:24"),
+       DT_CLK(NULL, "uart6_gfclk_mux", "ipu_cm:0040:24"),
+       DT_CLK(NULL, "uart7_gfclk_mux", "l4per_cm:01d0:24"),
+       DT_CLK(NULL, "uart8_gfclk_mux", "l4per_cm:01e0:24"),
+       DT_CLK(NULL, "uart9_gfclk_mux", "l4per_cm:01e8:24"),
+       DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3init_cm:00d0:8"),
+       DT_CLK(NULL, "usb_otg_ss2_refclk960m", "l3init_cm:0020:8"),
+       { .node_name = NULL },
+};
index 71a122b2dc67eb6c4324da73ea75860117067160..597fb4a593180e087a24e80b6c5a512266dadc90 100644 (file)
 #define DRA7_DPLL_USB_DEFFREQ                          960000000
 
 static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = {
-       { DRA7_MPU_CLKCTRL, NULL, 0, "dpll_mpu_m2_ck" },
+       { DRA7_MPU_MPU_CLKCTRL, NULL, 0, "dpll_mpu_m2_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_dsp1_clkctrl_regs[] __initconst = {
+       { DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" },
+       { 0 },
+};
+
+static const char * const dra7_ipu1_gfclk_mux_parents[] __initconst = {
+       "dpll_abe_m2x2_ck",
+       "dpll_core_h22x2_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_mmu_ipu1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_ipu1_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_ipu1_clkctrl_regs[] __initconst = {
+       { DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP, "ipu1-clkctrl:0000:24" },
        { 0 },
 };
 
@@ -108,45 +129,55 @@ static const struct omap_clkctrl_bit_data dra7_uart6_bit_data[] __initconst = {
 };
 
 static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = {
-       { DRA7_MCASP1_CLKCTRL, dra7_mcasp1_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0010:22" },
-       { DRA7_TIMER5_CLKCTRL, dra7_timer5_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0018:24" },
-       { DRA7_TIMER6_CLKCTRL, dra7_timer6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0020:24" },
-       { DRA7_TIMER7_CLKCTRL, dra7_timer7_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0028:24" },
-       { DRA7_TIMER8_CLKCTRL, dra7_timer8_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0030:24" },
-       { DRA7_I2C5_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
-       { DRA7_UART6_CLKCTRL, dra7_uart6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0040:24" },
+       { DRA7_IPU_MCASP1_CLKCTRL, dra7_mcasp1_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0000:22" },
+       { DRA7_IPU_TIMER5_CLKCTRL, dra7_timer5_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0008:24" },
+       { DRA7_IPU_TIMER6_CLKCTRL, dra7_timer6_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0010:24" },
+       { DRA7_IPU_TIMER7_CLKCTRL, dra7_timer7_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0018:24" },
+       { DRA7_IPU_TIMER8_CLKCTRL, dra7_timer8_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0020:24" },
+       { DRA7_IPU_I2C5_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_IPU_UART6_CLKCTRL, dra7_uart6_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0030:24" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_dsp2_clkctrl_regs[] __initconst = {
+       { DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst = {
-       { DRA7_RTCSS_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { DRA7_RTC_RTCSS_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = {
-       { DRA7_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
-       { DRA7_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
+       { DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
+       { DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initconst = {
-       { DRA7_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_TPCC_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_TPTC0_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_TPTC1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_VCP1_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_VCP2_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L3MAIN1_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L3MAIN1_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L3MAIN1_TPCC_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L3MAIN1_TPTC0_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L3MAIN1_TPTC1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L3MAIN1_VCP1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L3MAIN1_VCP2_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_ipu2_clkctrl_regs[] __initconst = {
+       { DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_dma_clkctrl_regs[] __initconst = {
-       { DRA7_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_DMA_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_iclk_div" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_emif_clkctrl_regs[] __initconst = {
-       { DRA7_DMM_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_EMIF_DMM_CLKCTRL, NULL, 0, "l3_iclk_div" },
        { 0 },
 };
 
@@ -161,7 +192,7 @@ static const char * const dra7_atl_dpll_clk_mux_parents[] __initconst = {
 static const char * const dra7_atl_gfclk_mux_parents[] __initconst = {
        "l3_iclk_div",
        "dpll_abe_m2_ck",
-       "atl_cm:clk:0000:24",
+       "atl-clkctrl:0000:24",
        NULL,
 };
 
@@ -172,32 +203,32 @@ static const struct omap_clkctrl_bit_data dra7_atl_bit_data[] __initconst = {
 };
 
 static const struct omap_clkctrl_reg_data dra7_atl_clkctrl_regs[] __initconst = {
-       { DRA7_ATL_CLKCTRL, dra7_atl_bit_data, CLKF_SW_SUP, "atl_cm:clk:0000:26" },
+       { DRA7_ATL_ATL_CLKCTRL, dra7_atl_bit_data, CLKF_SW_SUP, "atl-clkctrl:0000:26" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_l4cfg_clkctrl_regs[] __initconst = {
-       { DRA7_L4_CFG_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_SPINLOCK_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX1_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX2_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX3_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX4_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX5_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX6_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX7_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX8_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX9_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX10_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX11_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX12_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_MAILBOX13_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_L4_CFG_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_SPINLOCK_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX2_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX3_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX4_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX5_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX6_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX7_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX8_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX9_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX10_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX11_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX12_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4CFG_MAILBOX13_CLKCTRL, NULL, 0, "l3_iclk_div" },
        { 0 },
 };
 
 static const struct omap_clkctrl_reg_data dra7_l3instr_clkctrl_regs[] __initconst = {
-       { DRA7_L3_MAIN_2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L3INSTR_L3_MAIN_2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L3INSTR_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { 0 },
 };
 
@@ -242,8 +273,8 @@ static const struct omap_clkctrl_bit_data dra7_dss_core_bit_data[] __initconst =
 };
 
 static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst = {
-       { DRA7_DSS_CORE_CLKCTRL, dra7_dss_core_bit_data, CLKF_SW_SUP, "dss_cm:clk:0000:8" },
-       { DRA7_BB2D_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_h24x2_ck" },
+       { DRA7_DSS_DSS_CORE_CLKCTRL, dra7_dss_core_bit_data, CLKF_SW_SUP, "dss-clkctrl:0000:8" },
+       { DRA7_DSS_BB2D_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_h24x2_ck" },
        { 0 },
 };
 
@@ -254,7 +285,7 @@ static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = {
 };
 
 static const char * const dra7_mmc1_fclk_div_parents[] __initconst = {
-       "l3init_cm:clk:0008:24",
+       "l3init-clkctrl:0008:24",
        NULL,
 };
 
@@ -271,7 +302,7 @@ static const struct omap_clkctrl_bit_data dra7_mmc1_bit_data[] __initconst = {
 };
 
 static const char * const dra7_mmc2_fclk_div_parents[] __initconst = {
-       "l3init_cm:clk:0010:24",
+       "l3init-clkctrl:0010:24",
        NULL,
 };
 
@@ -307,6 +338,24 @@ static const struct omap_clkctrl_bit_data dra7_sata_bit_data[] __initconst = {
        { 0 },
 };
 
+static const struct omap_clkctrl_bit_data dra7_usb_otg_ss1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst = {
+       { DRA7_L3INIT_MMC1_CLKCTRL, dra7_mmc1_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0008:25" },
+       { DRA7_L3INIT_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0010:25" },
+       { DRA7_L3INIT_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { DRA7_L3INIT_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { DRA7_L3INIT_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { DRA7_L3INIT_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_L3INIT_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
+       { DRA7_L3INIT_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
+       { DRA7_L3INIT_USB_OTG_SS1_CLKCTRL, dra7_usb_otg_ss1_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+       { 0 },
+};
+
 static const char * const dra7_optfclk_pciephy1_clk_parents[] __initconst = {
        "apll_pcie_ck",
        NULL,
@@ -331,6 +380,12 @@ static const struct omap_clkctrl_bit_data dra7_pcie2_bit_data[] __initconst = {
        { 0 },
 };
 
+static const struct omap_clkctrl_reg_data dra7_pcie_clkctrl_regs[] __initconst = {
+       { DRA7_PCIE_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div" },
+       { DRA7_PCIE_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div" },
+       { 0 },
+};
+
 static const char * const dra7_rmii_50mhz_clk_mux_parents[] __initconst = {
        "dpll_gmac_h11x2_ck",
        "rmii_clk_ck",
@@ -352,24 +407,8 @@ static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_bit_data dra7_usb_otg_ss1_bit_data[] __initconst = {
-       { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL },
-       { 0 },
-};
-
-static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst = {
-       { DRA7_MMC1_CLKCTRL, dra7_mmc1_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0008:25" },
-       { DRA7_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" },
-       { DRA7_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
-       { DRA7_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
-       { DRA7_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
-       { DRA7_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" },
-       { DRA7_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" },
-       { DRA7_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" },
-       { DRA7_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck", "gmac_clkdm" },
-       { DRA7_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
-       { DRA7_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
-       { DRA7_USB_OTG_SS1_CLKCTRL, dra7_usb_otg_ss1_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
+static const struct omap_clkctrl_reg_data dra7_gmac_clkctrl_regs[] __initconst = {
+       { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck" },
        { 0 },
 };
 
@@ -443,21 +482,6 @@ static const struct omap_clkctrl_bit_data dra7_gpio6_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_bit_data dra7_timer13_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
-static const struct omap_clkctrl_bit_data dra7_timer14_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
-static const struct omap_clkctrl_bit_data dra7_timer15_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
 static const struct omap_clkctrl_bit_data dra7_gpio7_bit_data[] __initconst = {
        { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL },
        { 0 },
@@ -469,7 +493,7 @@ static const struct omap_clkctrl_bit_data dra7_gpio8_bit_data[] __initconst = {
 };
 
 static const char * const dra7_mmc3_gfclk_div_parents[] __initconst = {
-       "l4per_cm:clk:0120:24",
+       "l4per-clkctrl:00f8:24",
        NULL,
 };
 
@@ -486,7 +510,7 @@ static const struct omap_clkctrl_bit_data dra7_mmc3_bit_data[] __initconst = {
 };
 
 static const char * const dra7_mmc4_gfclk_div_parents[] __initconst = {
-       "l4per_cm:clk:0128:24",
+       "l4per-clkctrl:0100:24",
        NULL,
 };
 
@@ -502,8 +526,72 @@ static const struct omap_clkctrl_bit_data dra7_mmc4_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_bit_data dra7_timer16_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+static const struct omap_clkctrl_bit_data dra7_uart1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart2_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart3_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart4_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_uart5_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst = {
+       { DRA7_L4PER_TIMER10_CLKCTRL, dra7_timer10_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0000:24" },
+       { DRA7_L4PER_TIMER11_CLKCTRL, dra7_timer11_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0008:24" },
+       { DRA7_L4PER_TIMER2_CLKCTRL, dra7_timer2_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0010:24" },
+       { DRA7_L4PER_TIMER3_CLKCTRL, dra7_timer3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0018:24" },
+       { DRA7_L4PER_TIMER4_CLKCTRL, dra7_timer4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0020:24" },
+       { DRA7_L4PER_TIMER9_CLKCTRL, dra7_timer9_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0028:24" },
+       { DRA7_L4PER_ELM_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4PER_GPIO2_CLKCTRL, dra7_gpio2_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_GPIO3_CLKCTRL, dra7_gpio3_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_GPIO4_CLKCTRL, dra7_gpio4_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_GPIO5_CLKCTRL, dra7_gpio5_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_GPIO6_CLKCTRL, dra7_gpio6_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" },
+       { DRA7_L4PER_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_L4PER_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_L4PER_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_L4PER_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { DRA7_L4PER_L4_PER1_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4PER_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_L4PER_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_L4PER_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_L4PER_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { DRA7_L4PER_GPIO7_CLKCTRL, dra7_gpio7_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_GPIO8_CLKCTRL, dra7_gpio8_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4PER_MMC3_CLKCTRL, dra7_mmc3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:00f8:25" },
+       { DRA7_L4PER_MMC4_CLKCTRL, dra7_mmc4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0100:25" },
+       { DRA7_L4PER_UART1_CLKCTRL, dra7_uart1_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0118:24" },
+       { DRA7_L4PER_UART2_CLKCTRL, dra7_uart2_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0120:24" },
+       { DRA7_L4PER_UART3_CLKCTRL, dra7_uart3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0128:24" },
+       { DRA7_L4PER_UART4_CLKCTRL, dra7_uart4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0130:24" },
+       { DRA7_L4PER_UART5_CLKCTRL, dra7_uart5_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0148:24" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst = {
+       { DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "" },
+       { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
        { 0 },
 };
 
@@ -514,7 +602,7 @@ static const char * const dra7_qspi_gfclk_mux_parents[] __initconst = {
 };
 
 static const char * const dra7_qspi_gfclk_div_parents[] __initconst = {
-       "l4per_cm:clk:0138:24",
+       "l4per2-clkctrl:012c:24",
        NULL,
 };
 
@@ -529,26 +617,6 @@ static const struct omap_clkctrl_bit_data dra7_qspi_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_bit_data dra7_uart1_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
-static const struct omap_clkctrl_bit_data dra7_uart2_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
-static const struct omap_clkctrl_bit_data dra7_uart3_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
-static const struct omap_clkctrl_bit_data dra7_uart4_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
 static const struct omap_clkctrl_bit_data dra7_mcasp2_bit_data[] __initconst = {
        { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
        { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
@@ -562,11 +630,6 @@ static const struct omap_clkctrl_bit_data dra7_mcasp3_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_bit_data dra7_uart5_bit_data[] __initconst = {
-       { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL },
-       { 0 },
-};
-
 static const struct omap_clkctrl_bit_data dra7_mcasp5_bit_data[] __initconst = {
        { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL },
        { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL },
@@ -612,64 +675,54 @@ static const struct omap_clkctrl_bit_data dra7_mcasp7_bit_data[] __initconst = {
        { 0 },
 };
 
-static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst = {
-       { DRA7_L4_PER2_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per2_clkdm" },
-       { DRA7_L4_PER3_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per3_clkdm" },
-       { DRA7_TIMER10_CLKCTRL, dra7_timer10_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0028:24" },
-       { DRA7_TIMER11_CLKCTRL, dra7_timer11_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0030:24" },
-       { DRA7_TIMER2_CLKCTRL, dra7_timer2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0038:24" },
-       { DRA7_TIMER3_CLKCTRL, dra7_timer3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0040:24" },
-       { DRA7_TIMER4_CLKCTRL, dra7_timer4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0048:24" },
-       { DRA7_TIMER9_CLKCTRL, dra7_timer9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0050:24" },
-       { DRA7_ELM_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_GPIO2_CLKCTRL, dra7_gpio2_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_GPIO3_CLKCTRL, dra7_gpio3_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_GPIO4_CLKCTRL, dra7_gpio4_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_GPIO5_CLKCTRL, dra7_gpio5_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_GPIO6_CLKCTRL, dra7_gpio6_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" },
-       { DRA7_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" },
-       { DRA7_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" },
-       { DRA7_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
-       { DRA7_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
-       { DRA7_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
-       { DRA7_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
-       { DRA7_L4_PER1_CLKCTRL, NULL, 0, "l3_iclk_div" },
-       { DRA7_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" },
-       { DRA7_TIMER13_CLKCTRL, dra7_timer13_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00c8:24", "l4per3_clkdm" },
-       { DRA7_TIMER14_CLKCTRL, dra7_timer14_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d0:24", "l4per3_clkdm" },
-       { DRA7_TIMER15_CLKCTRL, dra7_timer15_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d8:24", "l4per3_clkdm" },
-       { DRA7_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
-       { DRA7_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
-       { DRA7_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
-       { DRA7_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
-       { DRA7_GPIO7_CLKCTRL, dra7_gpio7_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_GPIO8_CLKCTRL, dra7_gpio8_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
-       { DRA7_MMC3_CLKCTRL, dra7_mmc3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0120:25" },
-       { DRA7_MMC4_CLKCTRL, dra7_mmc4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0128:25" },
-       { DRA7_TIMER16_CLKCTRL, dra7_timer16_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0130:24", "l4per3_clkdm" },
-       { DRA7_QSPI_CLKCTRL, dra7_qspi_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0138:25", "l4per2_clkdm" },
-       { DRA7_UART1_CLKCTRL, dra7_uart1_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0140:24" },
-       { DRA7_UART2_CLKCTRL, dra7_uart2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0148:24" },
-       { DRA7_UART3_CLKCTRL, dra7_uart3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0150:24" },
-       { DRA7_UART4_CLKCTRL, dra7_uart4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0158:24" },
-       { DRA7_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0160:22", "l4per2_clkdm" },
-       { DRA7_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0168:22", "l4per2_clkdm" },
-       { DRA7_UART5_CLKCTRL, dra7_uart5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0170:24" },
-       { DRA7_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0178:22", "l4per2_clkdm" },
-       { DRA7_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0190:24", "l4per2_clkdm" },
-       { DRA7_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0198:22", "l4per2_clkdm" },
-       { DRA7_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
-       { DRA7_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
-       { DRA7_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
-       { DRA7_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
-       { DRA7_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
-       { DRA7_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01d0:24", "l4per2_clkdm" },
-       { DRA7_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e0:24", "l4per2_clkdm" },
-       { DRA7_UART9_CLKCTRL, dra7_uart9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e8:24", "l4per2_clkdm" },
-       { DRA7_DCAN2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin1", "l4per2_clkdm" },
-       { DRA7_MCASP6_CLKCTRL, dra7_mcasp6_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0204:22", "l4per2_clkdm" },
-       { DRA7_MCASP7_CLKCTRL, dra7_mcasp7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0208:22", "l4per2_clkdm" },
+static const struct omap_clkctrl_reg_data dra7_l4per2_clkctrl_regs[] __initconst = {
+       { DRA7_L4PER2_L4_PER2_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4PER2_PRUSS1_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { DRA7_L4PER2_PRUSS2_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { DRA7_L4PER2_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" },
+       { DRA7_L4PER2_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" },
+       { DRA7_L4PER2_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" },
+       { DRA7_L4PER2_QSPI_CLKCTRL, dra7_qspi_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:012c:25" },
+       { DRA7_L4PER2_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0154:22" },
+       { DRA7_L4PER2_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:015c:22" },
+       { DRA7_L4PER2_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:016c:22" },
+       { DRA7_L4PER2_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0184:24" },
+       { DRA7_L4PER2_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:018c:22" },
+       { DRA7_L4PER2_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01c4:24" },
+       { DRA7_L4PER2_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01d4:24" },
+       { DRA7_L4PER2_UART9_CLKCTRL, dra7_uart9_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01dc:24" },
+       { DRA7_L4PER2_DCAN2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin1" },
+       { DRA7_L4PER2_MCASP6_CLKCTRL, dra7_mcasp6_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01f8:22" },
+       { DRA7_L4PER2_MCASP7_CLKCTRL, dra7_mcasp7_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01fc:22" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer13_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer14_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer15_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data dra7_timer16_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_l4per3_clkctrl_regs[] __initconst = {
+       { DRA7_L4PER3_L4_PER3_CLKCTRL, NULL, 0, "l3_iclk_div" },
+       { DRA7_L4PER3_TIMER13_CLKCTRL, dra7_timer13_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:00b4:24" },
+       { DRA7_L4PER3_TIMER14_CLKCTRL, dra7_timer14_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:00bc:24" },
+       { DRA7_L4PER3_TIMER15_CLKCTRL, dra7_timer15_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:00c4:24" },
+       { DRA7_L4PER3_TIMER16_CLKCTRL, dra7_timer16_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:011c:24" },
        { 0 },
 };
 
@@ -700,24 +753,28 @@ static const struct omap_clkctrl_bit_data dra7_dcan1_bit_data[] __initconst = {
 };
 
 static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initconst = {
-       { DRA7_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
-       { DRA7_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
-       { DRA7_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" },
-       { DRA7_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" },
-       { DRA7_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" },
-       { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
-       { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" },
-       { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" },
-       { DRA7_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk"},
+       { DRA7_WKUPAON_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
+       { DRA7_WKUPAON_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { DRA7_WKUPAON_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" },
+       { DRA7_WKUPAON_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0020:24" },
+       { DRA7_WKUPAON_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" },
+       { DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
+       { DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" },
+       { DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" },
+       { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk" },
        { 0 },
 };
 
 const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = {
        { 0x4a005320, dra7_mpu_clkctrl_regs },
-       { 0x4a005540, dra7_ipu_clkctrl_regs },
-       { 0x4a005740, dra7_rtc_clkctrl_regs },
+       { 0x4a005420, dra7_dsp1_clkctrl_regs },
+       { 0x4a005520, dra7_ipu1_clkctrl_regs },
+       { 0x4a005550, dra7_ipu_clkctrl_regs },
+       { 0x4a005620, dra7_dsp2_clkctrl_regs },
+       { 0x4a005720, dra7_rtc_clkctrl_regs },
        { 0x4a008620, dra7_coreaon_clkctrl_regs },
        { 0x4a008720, dra7_l3main1_clkctrl_regs },
+       { 0x4a008920, dra7_ipu2_clkctrl_regs },
        { 0x4a008a20, dra7_dma_clkctrl_regs },
        { 0x4a008b20, dra7_emif_clkctrl_regs },
        { 0x4a008c00, dra7_atl_clkctrl_regs },
@@ -725,7 +782,12 @@ const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = {
        { 0x4a008e20, dra7_l3instr_clkctrl_regs },
        { 0x4a009120, dra7_dss_clkctrl_regs },
        { 0x4a009320, dra7_l3init_clkctrl_regs },
-       { 0x4a009700, dra7_l4per_clkctrl_regs },
+       { 0x4a0093b0, dra7_pcie_clkctrl_regs },
+       { 0x4a0093d0, dra7_gmac_clkctrl_regs },
+       { 0x4a009728, dra7_l4per_clkctrl_regs },
+       { 0x4a0098a0, dra7_l4sec_clkctrl_regs },
+       { 0x4a00970c, dra7_l4per2_clkctrl_regs },
+       { 0x4a009714, dra7_l4per3_clkctrl_regs },
        { 0x4ae07820, dra7_wkupaon_clkctrl_regs },
        { 0 },
 };
@@ -734,91 +796,92 @@ static struct ti_dt_clk dra7xx_clks[] = {
        DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
        DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"),
        DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
-       DT_CLK(NULL, "atl_dpll_clk_mux", "atl_cm:0000:24"),
-       DT_CLK(NULL, "atl_gfclk_mux", "atl_cm:0000:26"),
-       DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon_cm:0068:24"),
-       DT_CLK(NULL, "dss_32khz_clk", "dss_cm:0000:11"),
-       DT_CLK(NULL, "dss_48mhz_clk", "dss_cm:0000:9"),
-       DT_CLK(NULL, "dss_dss_clk", "dss_cm:0000:8"),
-       DT_CLK(NULL, "dss_hdmi_clk", "dss_cm:0000:10"),
-       DT_CLK(NULL, "dss_video1_clk", "dss_cm:0000:12"),
-       DT_CLK(NULL, "dss_video2_clk", "dss_cm:0000:13"),
-       DT_CLK(NULL, "gmac_rft_clk_mux", "l3init_cm:00b0:25"),
-       DT_CLK(NULL, "gpio1_dbclk", "wkupaon_cm:0018:8"),
-       DT_CLK(NULL, "gpio2_dbclk", "l4per_cm:0060:8"),
-       DT_CLK(NULL, "gpio3_dbclk", "l4per_cm:0068:8"),
-       DT_CLK(NULL, "gpio4_dbclk", "l4per_cm:0070:8"),
-       DT_CLK(NULL, "gpio5_dbclk", "l4per_cm:0078:8"),
-       DT_CLK(NULL, "gpio6_dbclk", "l4per_cm:0080:8"),
-       DT_CLK(NULL, "gpio7_dbclk", "l4per_cm:0110:8"),
-       DT_CLK(NULL, "gpio8_dbclk", "l4per_cm:0118:8"),
-       DT_CLK(NULL, "mcasp1_ahclkr_mux", "ipu_cm:0010:28"),
-       DT_CLK(NULL, "mcasp1_ahclkx_mux", "ipu_cm:0010:24"),
-       DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "ipu_cm:0010:22"),
-       DT_CLK(NULL, "mcasp2_ahclkr_mux", "l4per_cm:0160:28"),
-       DT_CLK(NULL, "mcasp2_ahclkx_mux", "l4per_cm:0160:24"),
-       DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "l4per_cm:0160:22"),
-       DT_CLK(NULL, "mcasp3_ahclkx_mux", "l4per_cm:0168:24"),
-       DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "l4per_cm:0168:22"),
-       DT_CLK(NULL, "mcasp4_ahclkx_mux", "l4per_cm:0198:24"),
-       DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "l4per_cm:0198:22"),
-       DT_CLK(NULL, "mcasp5_ahclkx_mux", "l4per_cm:0178:24"),
-       DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "l4per_cm:0178:22"),
-       DT_CLK(NULL, "mcasp6_ahclkx_mux", "l4per_cm:0204:24"),
-       DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per_cm:0204:22"),
-       DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per_cm:0208:24"),
-       DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per_cm:0208:22"),
-       DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per_cm:0190:22"),
-       DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per_cm:0190:24"),
-       DT_CLK(NULL, "mmc1_clk32k", "l3init_cm:0008:8"),
-       DT_CLK(NULL, "mmc1_fclk_div", "l3init_cm:0008:25"),
-       DT_CLK(NULL, "mmc1_fclk_mux", "l3init_cm:0008:24"),
-       DT_CLK(NULL, "mmc2_clk32k", "l3init_cm:0010:8"),
-       DT_CLK(NULL, "mmc2_fclk_div", "l3init_cm:0010:25"),
-       DT_CLK(NULL, "mmc2_fclk_mux", "l3init_cm:0010:24"),
-       DT_CLK(NULL, "mmc3_clk32k", "l4per_cm:0120:8"),
-       DT_CLK(NULL, "mmc3_gfclk_div", "l4per_cm:0120:25"),
-       DT_CLK(NULL, "mmc3_gfclk_mux", "l4per_cm:0120:24"),
-       DT_CLK(NULL, "mmc4_clk32k", "l4per_cm:0128:8"),
-       DT_CLK(NULL, "mmc4_gfclk_div", "l4per_cm:0128:25"),
-       DT_CLK(NULL, "mmc4_gfclk_mux", "l4per_cm:0128:24"),
-       DT_CLK(NULL, "optfclk_pciephy1_32khz", "l3init_cm:0090:8"),
-       DT_CLK(NULL, "optfclk_pciephy1_clk", "l3init_cm:0090:9"),
-       DT_CLK(NULL, "optfclk_pciephy1_div_clk", "l3init_cm:0090:10"),
-       DT_CLK(NULL, "optfclk_pciephy2_32khz", "l3init_cm:0098:8"),
-       DT_CLK(NULL, "optfclk_pciephy2_clk", "l3init_cm:0098:9"),
-       DT_CLK(NULL, "optfclk_pciephy2_div_clk", "l3init_cm:0098:10"),
-       DT_CLK(NULL, "qspi_gfclk_div", "l4per_cm:0138:25"),
-       DT_CLK(NULL, "qspi_gfclk_mux", "l4per_cm:0138:24"),
-       DT_CLK(NULL, "rmii_50mhz_clk_mux", "l3init_cm:00b0:24"),
-       DT_CLK(NULL, "sata_ref_clk", "l3init_cm:0068:8"),
-       DT_CLK(NULL, "timer10_gfclk_mux", "l4per_cm:0028:24"),
-       DT_CLK(NULL, "timer11_gfclk_mux", "l4per_cm:0030:24"),
-       DT_CLK(NULL, "timer13_gfclk_mux", "l4per_cm:00c8:24"),
-       DT_CLK(NULL, "timer14_gfclk_mux", "l4per_cm:00d0:24"),
-       DT_CLK(NULL, "timer15_gfclk_mux", "l4per_cm:00d8:24"),
-       DT_CLK(NULL, "timer16_gfclk_mux", "l4per_cm:0130:24"),
-       DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon_cm:0020:24"),
-       DT_CLK(NULL, "timer2_gfclk_mux", "l4per_cm:0038:24"),
-       DT_CLK(NULL, "timer3_gfclk_mux", "l4per_cm:0040:24"),
-       DT_CLK(NULL, "timer4_gfclk_mux", "l4per_cm:0048:24"),
-       DT_CLK(NULL, "timer5_gfclk_mux", "ipu_cm:0018:24"),
-       DT_CLK(NULL, "timer6_gfclk_mux", "ipu_cm:0020:24"),
-       DT_CLK(NULL, "timer7_gfclk_mux", "ipu_cm:0028:24"),
-       DT_CLK(NULL, "timer8_gfclk_mux", "ipu_cm:0030:24"),
-       DT_CLK(NULL, "timer9_gfclk_mux", "l4per_cm:0050:24"),
-       DT_CLK(NULL, "uart10_gfclk_mux", "wkupaon_cm:0060:24"),
-       DT_CLK(NULL, "uart1_gfclk_mux", "l4per_cm:0140:24"),
-       DT_CLK(NULL, "uart2_gfclk_mux", "l4per_cm:0148:24"),
-       DT_CLK(NULL, "uart3_gfclk_mux", "l4per_cm:0150:24"),
-       DT_CLK(NULL, "uart4_gfclk_mux", "l4per_cm:0158:24"),
-       DT_CLK(NULL, "uart5_gfclk_mux", "l4per_cm:0170:24"),
-       DT_CLK(NULL, "uart6_gfclk_mux", "ipu_cm:0040:24"),
-       DT_CLK(NULL, "uart7_gfclk_mux", "l4per_cm:01d0:24"),
-       DT_CLK(NULL, "uart8_gfclk_mux", "l4per_cm:01e0:24"),
-       DT_CLK(NULL, "uart9_gfclk_mux", "l4per_cm:01e8:24"),
-       DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3init_cm:00d0:8"),
-       DT_CLK(NULL, "usb_otg_ss2_refclk960m", "l3init_cm:0020:8"),
+       DT_CLK(NULL, "atl_dpll_clk_mux", "atl-clkctrl:0000:24"),
+       DT_CLK(NULL, "atl_gfclk_mux", "atl-clkctrl:0000:26"),
+       DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon-clkctrl:0068:24"),
+       DT_CLK(NULL, "dss_32khz_clk", "dss-clkctrl:0000:11"),
+       DT_CLK(NULL, "dss_48mhz_clk", "dss-clkctrl:0000:9"),
+       DT_CLK(NULL, "dss_dss_clk", "dss-clkctrl:0000:8"),
+       DT_CLK(NULL, "dss_hdmi_clk", "dss-clkctrl:0000:10"),
+       DT_CLK(NULL, "dss_video1_clk", "dss-clkctrl:0000:12"),
+       DT_CLK(NULL, "dss_video2_clk", "dss-clkctrl:0000:13"),
+       DT_CLK(NULL, "gmac_rft_clk_mux", "gmac-clkctrl:0000:25"),
+       DT_CLK(NULL, "gpio1_dbclk", "wkupaon-clkctrl:0018:8"),
+       DT_CLK(NULL, "gpio2_dbclk", "l4per-clkctrl:0038:8"),
+       DT_CLK(NULL, "gpio3_dbclk", "l4per-clkctrl:0040:8"),
+       DT_CLK(NULL, "gpio4_dbclk", "l4per-clkctrl:0048:8"),
+       DT_CLK(NULL, "gpio5_dbclk", "l4per-clkctrl:0050:8"),
+       DT_CLK(NULL, "gpio6_dbclk", "l4per-clkctrl:0058:8"),
+       DT_CLK(NULL, "gpio7_dbclk", "l4per-clkctrl:00e8:8"),
+       DT_CLK(NULL, "gpio8_dbclk", "l4per-clkctrl:00f0:8"),
+       DT_CLK(NULL, "ipu1_gfclk_mux", "ipu1-clkctrl:0000:24"),
+       DT_CLK(NULL, "mcasp1_ahclkr_mux", "ipu-clkctrl:0000:28"),
+       DT_CLK(NULL, "mcasp1_ahclkx_mux", "ipu-clkctrl:0000:24"),
+       DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "ipu-clkctrl:0000:22"),
+       DT_CLK(NULL, "mcasp2_ahclkr_mux", "l4per2-clkctrl:0154:28"),
+       DT_CLK(NULL, "mcasp2_ahclkx_mux", "l4per2-clkctrl:0154:24"),
+       DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "l4per2-clkctrl:0154:22"),
+       DT_CLK(NULL, "mcasp3_ahclkx_mux", "l4per2-clkctrl:015c:24"),
+       DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "l4per2-clkctrl:015c:22"),
+       DT_CLK(NULL, "mcasp4_ahclkx_mux", "l4per2-clkctrl:018c:24"),
+       DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "l4per2-clkctrl:018c:22"),
+       DT_CLK(NULL, "mcasp5_ahclkx_mux", "l4per2-clkctrl:016c:24"),
+       DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "l4per2-clkctrl:016c:22"),
+       DT_CLK(NULL, "mcasp6_ahclkx_mux", "l4per2-clkctrl:01f8:24"),
+       DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per2-clkctrl:01f8:22"),
+       DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per2-clkctrl:01fc:24"),
+       DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per2-clkctrl:01fc:22"),
+       DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per2-clkctrl:0184:22"),
+       DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per2-clkctrl:0184:24"),
+       DT_CLK(NULL, "mmc1_clk32k", "l3init-clkctrl:0008:8"),
+       DT_CLK(NULL, "mmc1_fclk_div", "l3init-clkctrl:0008:25"),
+       DT_CLK(NULL, "mmc1_fclk_mux", "l3init-clkctrl:0008:24"),
+       DT_CLK(NULL, "mmc2_clk32k", "l3init-clkctrl:0010:8"),
+       DT_CLK(NULL, "mmc2_fclk_div", "l3init-clkctrl:0010:25"),
+       DT_CLK(NULL, "mmc2_fclk_mux", "l3init-clkctrl:0010:24"),
+       DT_CLK(NULL, "mmc3_clk32k", "l4per-clkctrl:00f8:8"),
+       DT_CLK(NULL, "mmc3_gfclk_div", "l4per-clkctrl:00f8:25"),
+       DT_CLK(NULL, "mmc3_gfclk_mux", "l4per-clkctrl:00f8:24"),
+       DT_CLK(NULL, "mmc4_clk32k", "l4per-clkctrl:0100:8"),
+       DT_CLK(NULL, "mmc4_gfclk_div", "l4per-clkctrl:0100:25"),
+       DT_CLK(NULL, "mmc4_gfclk_mux", "l4per-clkctrl:0100:24"),
+       DT_CLK(NULL, "optfclk_pciephy1_32khz", "pcie-clkctrl:0000:8"),
+       DT_CLK(NULL, "optfclk_pciephy1_clk", "pcie-clkctrl:0000:9"),
+       DT_CLK(NULL, "optfclk_pciephy1_div_clk", "pcie-clkctrl:0000:10"),
+       DT_CLK(NULL, "optfclk_pciephy2_32khz", "pcie-clkctrl:0008:8"),
+       DT_CLK(NULL, "optfclk_pciephy2_clk", "pcie-clkctrl:0008:9"),
+       DT_CLK(NULL, "optfclk_pciephy2_div_clk", "pcie-clkctrl:0008:10"),
+       DT_CLK(NULL, "qspi_gfclk_div", "l4per2-clkctrl:012c:25"),
+       DT_CLK(NULL, "qspi_gfclk_mux", "l4per2-clkctrl:012c:24"),
+       DT_CLK(NULL, "rmii_50mhz_clk_mux", "gmac-clkctrl:0000:24"),
+       DT_CLK(NULL, "sata_ref_clk", "l3init-clkctrl:0068:8"),
+       DT_CLK(NULL, "timer10_gfclk_mux", "l4per-clkctrl:0000:24"),
+       DT_CLK(NULL, "timer11_gfclk_mux", "l4per-clkctrl:0008:24"),
+       DT_CLK(NULL, "timer13_gfclk_mux", "l4per3-clkctrl:00b4:24"),
+       DT_CLK(NULL, "timer14_gfclk_mux", "l4per3-clkctrl:00bc:24"),
+       DT_CLK(NULL, "timer15_gfclk_mux", "l4per3-clkctrl:00c4:24"),
+       DT_CLK(NULL, "timer16_gfclk_mux", "l4per3-clkctrl:011c:24"),
+       DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon-clkctrl:0020:24"),
+       DT_CLK(NULL, "timer2_gfclk_mux", "l4per-clkctrl:0010:24"),
+       DT_CLK(NULL, "timer3_gfclk_mux", "l4per-clkctrl:0018:24"),
+       DT_CLK(NULL, "timer4_gfclk_mux", "l4per-clkctrl:0020:24"),
+       DT_CLK(NULL, "timer5_gfclk_mux", "ipu-clkctrl:0008:24"),
+       DT_CLK(NULL, "timer6_gfclk_mux", "ipu-clkctrl:0010:24"),
+       DT_CLK(NULL, "timer7_gfclk_mux", "ipu-clkctrl:0018:24"),
+       DT_CLK(NULL, "timer8_gfclk_mux", "ipu-clkctrl:0020:24"),
+       DT_CLK(NULL, "timer9_gfclk_mux", "l4per-clkctrl:0028:24"),
+       DT_CLK(NULL, "uart10_gfclk_mux", "wkupaon-clkctrl:0060:24"),
+       DT_CLK(NULL, "uart1_gfclk_mux", "l4per-clkctrl:0118:24"),
+       DT_CLK(NULL, "uart2_gfclk_mux", "l4per-clkctrl:0120:24"),
+       DT_CLK(NULL, "uart3_gfclk_mux", "l4per-clkctrl:0128:24"),
+       DT_CLK(NULL, "uart4_gfclk_mux", "l4per-clkctrl:0130:24"),
+       DT_CLK(NULL, "uart5_gfclk_mux", "l4per-clkctrl:0148:24"),
+       DT_CLK(NULL, "uart6_gfclk_mux", "ipu-clkctrl:0030:24"),
+       DT_CLK(NULL, "uart7_gfclk_mux", "l4per2-clkctrl:01c4:24"),
+       DT_CLK(NULL, "uart8_gfclk_mux", "l4per2-clkctrl:01d4:24"),
+       DT_CLK(NULL, "uart9_gfclk_mux", "l4per2-clkctrl:01dc:24"),
+       DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3init-clkctrl:00d0:8"),
+       DT_CLK(NULL, "usb_otg_ss2_refclk960m", "l3init-clkctrl:0020:8"),
        { .node_name = NULL },
 };
 
@@ -827,7 +890,10 @@ int __init dra7xx_dt_clk_init(void)
        int rc;
        struct clk *dpll_ck, *hdcp_ck;
 
-       ti_dt_clocks_register(dra7xx_clks);
+       if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+               ti_dt_clocks_register(dra7xx_compat_clks);
+       else
+               ti_dt_clocks_register(dra7xx_clks);
 
        omap2_clk_disable_autoidle_all();
 
index 14881547043130d1e686055387a6276e49fd11f9..a01ca9395179a77c9f0c620e5389fe98b1d0fba3 100644 (file)
@@ -190,8 +190,8 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
        init.num_parents = of_clk_get_parent_count(node);
 
        if (init.num_parents != 1) {
-               pr_err("%s: atl clock %s must have 1 parent\n", __func__,
-                      node->name);
+               pr_err("%s: atl clock %pOFn must have 1 parent\n", __func__,
+                      node);
                goto cleanup;
        }
 
index 7d22e1af224770d7084cd7d8ec29e24d3f87368f..d0cd58534781d8b51f62fc256f30d0d04d96182a 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/of_address.h>
 #include <linux/list.h>
 #include <linux/regmap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/device.h>
 
 #include "clock.h"
@@ -34,7 +34,7 @@
 struct ti_clk_ll_ops *ti_clk_ll_ops;
 static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
 
-static struct ti_clk_features ti_clk_features;
+struct ti_clk_features ti_clk_features;
 
 struct clk_iomap {
        struct regmap *regmap;
@@ -129,7 +129,7 @@ int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
 void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
 {
        struct ti_dt_clk *c;
-       struct device_node *node;
+       struct device_node *node, *parent;
        struct clk *clk;
        struct of_phandle_args clkspec;
        char buf[64];
@@ -140,6 +140,9 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
        int ret;
        static bool clkctrl_nodes_missing;
        static bool has_clkctrl_data;
+       static bool compat_mode;
+
+       compat_mode = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT;
 
        for (c = oclks; c->node_name != NULL; c++) {
                strcpy(buf, c->node_name);
@@ -164,8 +167,12 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
                        continue;
 
                node = of_find_node_by_name(NULL, buf);
-               if (num_args)
-                       node = of_find_node_by_name(node, "clk");
+               if (num_args && compat_mode) {
+                       parent = node;
+                       node = of_get_child_by_name(parent, "clk");
+                       of_node_put(parent);
+               }
+
                clkspec.np = node;
                clkspec.args_count = num_args;
                for (i = 0; i < num_args; i++) {
@@ -173,11 +180,12 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
                        if (ret) {
                                pr_warn("Bad tag in %s at %d: %s\n",
                                        c->node_name, i, tags[i]);
+                               of_node_put(node);
                                return;
                        }
                }
                clk = of_clk_get_from_provider(&clkspec);
-
+               of_node_put(node);
                if (!IS_ERR(clk)) {
                        c->lk.clk = clk;
                        clkdev_add(&c->lk);
@@ -223,7 +231,7 @@ int __init ti_clk_retry_init(struct device_node *node, void *user,
 {
        struct clk_init_item *retry;
 
-       pr_debug("%s: adding to retry list...\n", node->name);
+       pr_debug("%pOFn: adding to retry list...\n", node);
        retry = kzalloc(sizeof(*retry), GFP_KERNEL);
        if (!retry)
                return -ENOMEM;
@@ -258,14 +266,14 @@ int ti_clk_get_reg_addr(struct device_node *node, int index,
        }
 
        if (i == CLK_MAX_MEMMAPS) {
-               pr_err("clk-provider not found for %s!\n", node->name);
+               pr_err("clk-provider not found for %pOFn!\n", node);
                return -ENOENT;
        }
 
        reg->index = i;
 
        if (of_property_read_u32_index(node, "reg", index, &val)) {
-               pr_err("%s must have reg[%d]!\n", node->name, index);
+               pr_err("%pOFn must have reg[%d]!\n", node, index);
                return -EINVAL;
        }
 
@@ -312,7 +320,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index,
        /* get clocks for this parent */
        clocks = of_get_child_by_name(parent, "clocks");
        if (!clocks) {
-               pr_err("%s missing 'clocks' child node.\n", parent->name);
+               pr_err("%pOFn missing 'clocks' child node.\n", parent);
                return -EINVAL;
        }
 
@@ -342,7 +350,7 @@ void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
 {
        struct clk_iomap *io;
 
-       io = memblock_virt_alloc(sizeof(*io), 0);
+       io = memblock_alloc(sizeof(*io), SMP_CACHE_BYTES);
 
        io->mem = mem;
 
@@ -365,7 +373,7 @@ void ti_dt_clk_init_retry_clks(void)
 
        while (!list_empty(&retry_list) && retries) {
                list_for_each_entry_safe(retry, tmp, &retry_list, link) {
-                       pr_debug("retry-init: %s\n", retry->node->name);
+                       pr_debug("retry-init: %pOFn\n", retry->node);
                        retry->func(retry->user, retry->node);
                        list_del(&retry->link);
                        kfree(retry);
index 421b0539222058354d94ae6c29347d03b02ddd93..469f560ae1cf7c779a75d4d18dc30e0883e1d340 100644 (file)
@@ -259,8 +259,13 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
        struct omap_clkctrl_clk *clkctrl_clk;
        int ret = 0;
 
-       init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name,
-                             node->name, offset, bit);
+       if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+               init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d",
+                                     node->parent, node, offset,
+                                     bit);
+       else
+               init.name = kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", node,
+                                     offset, bit);
        clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
        if (!init.name || !clkctrl_clk) {
                ret = -ENOMEM;
@@ -440,6 +445,11 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
        const __be32 *addrp;
        u32 addr;
        int ret;
+       char *c;
+
+       if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) &&
+           !strcmp(node->name, "clk"))
+               ti_clk_features.flags |= TI_CLK_CLKCTRL_COMPAT;
 
        addrp = of_get_address(node, 0, NULL, NULL);
        addr = (u32)of_translate_address(node, addrp);
@@ -453,18 +463,35 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
                data = omap5_clkctrl_data;
 #endif
 #ifdef CONFIG_SOC_DRA7XX
-       if (of_machine_is_compatible("ti,dra7"))
-               data = dra7_clkctrl_data;
+       if (of_machine_is_compatible("ti,dra7")) {
+               if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+                       data = dra7_clkctrl_compat_data;
+               else
+                       data = dra7_clkctrl_data;
+       }
 #endif
 #ifdef CONFIG_SOC_AM33XX
-       if (of_machine_is_compatible("ti,am33xx"))
-               data = am3_clkctrl_data;
+       if (of_machine_is_compatible("ti,am33xx")) {
+               if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+                       data = am3_clkctrl_compat_data;
+               else
+                       data = am3_clkctrl_data;
+       }
 #endif
 #ifdef CONFIG_SOC_AM43XX
-       if (of_machine_is_compatible("ti,am4372"))
-               data = am4_clkctrl_data;
-       if (of_machine_is_compatible("ti,am438x"))
-               data = am438x_clkctrl_data;
+       if (of_machine_is_compatible("ti,am4372")) {
+               if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+                       data = am4_clkctrl_compat_data;
+               else
+                       data = am4_clkctrl_data;
+       }
+
+       if (of_machine_is_compatible("ti,am438x")) {
+               if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+                       data = am438x_clkctrl_compat_data;
+               else
+                       data = am438x_clkctrl_data;
+       }
 #endif
 #ifdef CONFIG_SOC_TI81XX
        if (of_machine_is_compatible("ti,dm814"))
@@ -492,21 +519,43 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
 
        provider->base = of_iomap(node, 0);
 
-       provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3,
-                                      GFP_KERNEL);
-       if (!provider->clkdm_name) {
-               kfree(provider);
-               return;
+       if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) {
+               provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent);
+               if (!provider->clkdm_name) {
+                       kfree(provider);
+                       return;
+               }
+
+               /*
+                * Create default clkdm name, replace _cm from end of parent
+                * node name with _clkdm
+                */
+               provider->clkdm_name[strlen(provider->clkdm_name) - 5] = 0;
+       } else {
+               provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFn", node);
+               if (!provider->clkdm_name) {
+                       kfree(provider);
+                       return;
+               }
+
+               /*
+                * Create default clkdm name, replace _clkctrl from end of
+                * node name with _clkdm
+                */
+               provider->clkdm_name[strlen(provider->clkdm_name) - 7] = 0;
        }
 
-       /*
-        * Create default clkdm name, replace _cm from end of parent node
-        * name with _clkdm
-        */
-       strcpy(provider->clkdm_name, node->parent->name);
-       provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0;
        strcat(provider->clkdm_name, "clkdm");
 
+       /* Replace any dash from the clkdm name with underscore */
+       c = provider->clkdm_name;
+
+       while (*c) {
+               if (*c == '-')
+                       *c = '_';
+               c++;
+       }
+
        INIT_LIST_HEAD(&provider->clocks);
 
        /* Generate clocks */
@@ -539,9 +588,13 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
                init.flags = 0;
                if (reg_data->flags & CLKF_SET_RATE_PARENT)
                        init.flags |= CLK_SET_RATE_PARENT;
-               init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
-                                     node->parent->name, node->name,
-                                     reg_data->offset, 0);
+               if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
+                       init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d",
+                                             node->parent, node,
+                                             reg_data->offset, 0);
+               else
+                       init.name = kasprintf(GFP_KERNEL, "%pOFn:%04x:%d",
+                                             node, reg_data->offset, 0);
                clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
                if (!init.name || !clkctrl_clk)
                        goto cleanup;
index b58278077226e75b2e38304bfa10a45d48fa7dfc..9f312a21951001bb6946737e52fbf03e3d294284 100644 (file)
@@ -24,6 +24,7 @@ struct clk_omap_divider {
        u8                      flags;
        s8                      latch;
        const struct clk_div_table      *table;
+       u32             context;
 };
 
 #define to_clk_omap_divider(_hw) container_of(_hw, struct clk_omap_divider, hw)
@@ -36,6 +37,7 @@ struct clk_omap_mux {
        u8                      shift;
        s8                      latch;
        u8                      flags;
+       u8                      saved_parent;
 };
 
 #define to_clk_omap_mux(_hw) container_of(_hw, struct clk_omap_mux, hw)
@@ -184,9 +186,16 @@ struct omap_clkctrl_data {
 extern const struct omap_clkctrl_data omap4_clkctrl_data[];
 extern const struct omap_clkctrl_data omap5_clkctrl_data[];
 extern const struct omap_clkctrl_data dra7_clkctrl_data[];
+extern const struct omap_clkctrl_data dra7_clkctrl_compat_data[];
+extern struct ti_dt_clk dra7xx_compat_clks[];
 extern const struct omap_clkctrl_data am3_clkctrl_data[];
+extern const struct omap_clkctrl_data am3_clkctrl_compat_data[];
+extern struct ti_dt_clk am33xx_compat_clks[];
 extern const struct omap_clkctrl_data am4_clkctrl_data[];
+extern const struct omap_clkctrl_data am4_clkctrl_compat_data[];
+extern struct ti_dt_clk am43xx_compat_clks[];
 extern const struct omap_clkctrl_data am438x_clkctrl_data[];
+extern const struct omap_clkctrl_data am438x_clkctrl_compat_data[];
 extern const struct omap_clkctrl_data dm814_clkctrl_data[];
 extern const struct omap_clkctrl_data dm816_clkctrl_data[];
 
@@ -233,6 +242,8 @@ extern const struct clk_ops ti_clk_divider_ops;
 extern const struct clk_ops ti_clk_mux_ops;
 extern const struct clk_ops omap_gate_clk_ops;
 
+extern struct ti_clk_features ti_clk_features;
+
 void omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
index 030e8b2c10500cde5f8805d5674140ded9a17b12..6a89936ba03afe26578a7494275e0c723dad69d4 100644 (file)
@@ -135,8 +135,8 @@ static void __init _register_composite(void *user,
 
                comp = _lookup_component(cclk->comp_nodes[i]);
                if (!comp) {
-                       pr_debug("component %s not ready for %s, retry\n",
-                                cclk->comp_nodes[i]->name, node->name);
+                       pr_debug("component %s not ready for %pOFn, retry\n",
+                                cclk->comp_nodes[i]->name, node);
                        if (!ti_clk_retry_init(node, hw,
                                               _register_composite))
                                return;
@@ -144,8 +144,8 @@ static void __init _register_composite(void *user,
                        goto cleanup;
                }
                if (cclk->comp_clks[comp->type] != NULL) {
-                       pr_err("duplicate component types for %s (%s)!\n",
-                              node->name, component_clk_types[comp->type]);
+                       pr_err("duplicate component types for %pOFn (%s)!\n",
+                              node, component_clk_types[comp->type]);
                        goto cleanup;
                }
 
@@ -168,7 +168,7 @@ static void __init _register_composite(void *user,
        }
 
        if (!num_parents) {
-               pr_err("%s: no parents found for %s!\n", __func__, node->name);
+               pr_err("%s: no parents found for %pOFn!\n", __func__, node);
                goto cleanup;
        }
 
@@ -212,7 +212,7 @@ static void __init of_ti_composite_clk_setup(struct device_node *node)
        num_clks = of_clk_get_parent_count(node);
 
        if (!num_clks) {
-               pr_err("composite clk %s must have component(s)\n", node->name);
+               pr_err("composite clk %pOFn must have component(s)\n", node);
                return;
        }
 
@@ -248,7 +248,7 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw,
        num_parents = of_clk_get_parent_count(node);
 
        if (!num_parents) {
-               pr_err("component-clock %s must have parent(s)\n", node->name);
+               pr_err("component-clock %pOFn must have parent(s)\n", node);
                return -EINVAL;
        }
 
index ccfb4d9a152aea55c3e414dc26d2ddd3ce792ee4..8d77090ad94aecd283ee085bb77a81491c9c6978 100644 (file)
@@ -268,10 +268,46 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        return 0;
 }
 
+/**
+ * clk_divider_save_context - Save the divider value
+ * @hw: pointer  struct clk_hw
+ *
+ * Save the divider value
+ */
+static int clk_divider_save_context(struct clk_hw *hw)
+{
+       struct clk_omap_divider *divider = to_clk_omap_divider(hw);
+       u32 val;
+
+       val = ti_clk_ll_ops->clk_readl(&divider->reg) >> divider->shift;
+       divider->context = val & div_mask(divider);
+
+       return 0;
+}
+
+/**
+ * clk_divider_restore_context - restore the saved the divider value
+ * @hw: pointer  struct clk_hw
+ *
+ * Restore the saved the divider value
+ */
+static void clk_divider_restore_context(struct clk_hw *hw)
+{
+       struct clk_omap_divider *divider = to_clk_omap_divider(hw);
+       u32 val;
+
+       val = ti_clk_ll_ops->clk_readl(&divider->reg);
+       val &= ~(div_mask(divider) << divider->shift);
+       val |= divider->context << divider->shift;
+       ti_clk_ll_ops->clk_writel(val, &divider->reg);
+}
+
 const struct clk_ops ti_clk_divider_ops = {
        .recalc_rate = ti_clk_divider_recalc_rate,
        .round_rate = ti_clk_divider_round_rate,
        .set_rate = ti_clk_divider_set_rate,
+       .save_context = clk_divider_save_context,
+       .restore_context = clk_divider_restore_context,
 };
 
 static struct clk *_register_divider(struct device *dev, const char *name,
@@ -492,7 +528,7 @@ __init ti_clk_get_div_table(struct device_node *node)
        }
 
        if (!valid_div) {
-               pr_err("no valid dividers for %s table\n", node->name);
+               pr_err("no valid dividers for %pOFn table\n", node);
                return ERR_PTR(-EINVAL);
        }
 
@@ -530,7 +566,7 @@ static int _get_divider_width(struct device_node *node,
                        min_div = 1;
 
                if (of_property_read_u32(node, "ti,max-div", &max_div)) {
-                       pr_err("no max-div for %s!\n", node->name);
+                       pr_err("no max-div for %pOFn!\n", node);
                        return -EINVAL;
                }
 
index dc86d07d09211e35a6b9bf9338381ac2f4ef9183..92e28af7afba8ef320eae1c3ef0f3680d1ad72ce 100644 (file)
@@ -39,6 +39,8 @@ static const struct clk_ops dpll_m4xen_ck_ops = {
        .set_rate_and_parent    = &omap3_noncore_dpll_set_rate_and_parent,
        .determine_rate = &omap4_dpll_regm4xen_determine_rate,
        .get_parent     = &omap2_init_dpll_parent,
+       .save_context   = &omap3_core_dpll_save_context,
+       .restore_context = &omap3_core_dpll_restore_context,
 };
 #else
 static const struct clk_ops dpll_m4xen_ck_ops = {};
@@ -62,6 +64,8 @@ static const struct clk_ops dpll_ck_ops = {
        .set_rate_and_parent    = &omap3_noncore_dpll_set_rate_and_parent,
        .determine_rate = &omap3_noncore_dpll_determine_rate,
        .get_parent     = &omap2_init_dpll_parent,
+       .save_context   = &omap3_noncore_dpll_save_context,
+       .restore_context = &omap3_noncore_dpll_restore_context,
 };
 
 static const struct clk_ops dpll_no_gate_ck_ops = {
@@ -72,6 +76,8 @@ static const struct clk_ops dpll_no_gate_ck_ops = {
        .set_parent     = &omap3_noncore_dpll_set_parent,
        .set_rate_and_parent    = &omap3_noncore_dpll_set_rate_and_parent,
        .determine_rate = &omap3_noncore_dpll_determine_rate,
+       .save_context   = &omap3_noncore_dpll_save_context,
+       .restore_context = &omap3_noncore_dpll_restore_context
 };
 #else
 static const struct clk_ops dpll_core_ck_ops = {};
@@ -162,8 +168,8 @@ static void __init _register_dpll(void *user,
 
        clk = of_clk_get(node, 0);
        if (IS_ERR(clk)) {
-               pr_debug("clk-ref missing for %s, retry later\n",
-                        node->name);
+               pr_debug("clk-ref missing for %pOFn, retry later\n",
+                        node);
                if (!ti_clk_retry_init(node, hw, _register_dpll))
                        return;
 
@@ -175,8 +181,8 @@ static void __init _register_dpll(void *user,
        clk = of_clk_get(node, 1);
 
        if (IS_ERR(clk)) {
-               pr_debug("clk-bypass missing for %s, retry later\n",
-                        node->name);
+               pr_debug("clk-bypass missing for %pOFn, retry later\n",
+                        node);
                if (!ti_clk_retry_init(node, hw, _register_dpll))
                        return;
 
@@ -226,7 +232,7 @@ static void _register_dpll_x2(struct device_node *node,
 
        parent_name = of_clk_get_parent_name(node, 0);
        if (!parent_name) {
-               pr_err("%s must have parent\n", node->name);
+               pr_err("%pOFn must have parent\n", node);
                return;
        }
 
@@ -305,7 +311,7 @@ static void __init of_ti_dpll_setup(struct device_node *node,
 
        init->num_parents = of_clk_get_parent_count(node);
        if (!init->num_parents) {
-               pr_err("%s must have parent(s)\n", node->name);
+               pr_err("%pOFn must have parent(s)\n", node);
                goto cleanup;
        }
 
index 4534de2ef455d6e734c592062d4bcf92d4a404d7..44b6b6403753c95845048910838c4567c79f91d4 100644 (file)
@@ -782,6 +782,130 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
        return rate;
 }
 
+/**
+ * omap3_core_dpll_save_context - Save the m and n values of the divider
+ * @hw: pointer  struct clk_hw
+ *
+ * Before the dpll registers are lost save the last rounded rate m and n
+ * and the enable mask.
+ */
+int omap3_core_dpll_save_context(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       struct dpll_data *dd;
+       u32 v;
+
+       dd = clk->dpll_data;
+
+       v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
+       clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask);
+
+       if (clk->context == DPLL_LOCKED) {
+               v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
+               dd->last_rounded_m = (v & dd->mult_mask) >>
+                                               __ffs(dd->mult_mask);
+               dd->last_rounded_n = ((v & dd->div1_mask) >>
+                                               __ffs(dd->div1_mask)) + 1;
+       }
+
+       return 0;
+}
+
+/**
+ * omap3_core_dpll_restore_context - restore the m and n values of the divider
+ * @hw: pointer  struct clk_hw
+ *
+ * Restore the last rounded rate m and n
+ * and the enable mask.
+ */
+void omap3_core_dpll_restore_context(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       const struct dpll_data *dd;
+       u32 v;
+
+       dd = clk->dpll_data;
+
+       if (clk->context == DPLL_LOCKED) {
+               _omap3_dpll_write_clken(clk, 0x4);
+               _omap3_wait_dpll_status(clk, 0);
+
+               v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
+               v &= ~(dd->mult_mask | dd->div1_mask);
+               v |= dd->last_rounded_m << __ffs(dd->mult_mask);
+               v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask);
+               ti_clk_ll_ops->clk_writel(v, &dd->mult_div1_reg);
+
+               _omap3_dpll_write_clken(clk, DPLL_LOCKED);
+               _omap3_wait_dpll_status(clk, 1);
+       } else {
+               _omap3_dpll_write_clken(clk, clk->context);
+       }
+}
+
+/**
+ * omap3_non_core_dpll_save_context - Save the m and n values of the divider
+ * @hw: pointer  struct clk_hw
+ *
+ * Before the dpll registers are lost save the last rounded rate m and n
+ * and the enable mask.
+ */
+int omap3_noncore_dpll_save_context(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       struct dpll_data *dd;
+       u32 v;
+
+       dd = clk->dpll_data;
+
+       v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
+       clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask);
+
+       if (clk->context == DPLL_LOCKED) {
+               v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
+               dd->last_rounded_m = (v & dd->mult_mask) >>
+                                               __ffs(dd->mult_mask);
+               dd->last_rounded_n = ((v & dd->div1_mask) >>
+                                               __ffs(dd->div1_mask)) + 1;
+       }
+
+       return 0;
+}
+
+/**
+ * omap3_core_dpll_restore_context - restore the m and n values of the divider
+ * @hw: pointer  struct clk_hw
+ *
+ * Restore the last rounded rate m and n
+ * and the enable mask.
+ */
+void omap3_noncore_dpll_restore_context(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       const struct dpll_data *dd;
+       u32 ctrl, mult_div1;
+
+       dd = clk->dpll_data;
+
+       ctrl = ti_clk_ll_ops->clk_readl(&dd->control_reg);
+       mult_div1 = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
+
+       if (clk->context == ((ctrl & dd->enable_mask) >>
+                            __ffs(dd->enable_mask)) &&
+           dd->last_rounded_m == ((mult_div1 & dd->mult_mask) >>
+                                  __ffs(dd->mult_mask)) &&
+           dd->last_rounded_n == ((mult_div1 & dd->div1_mask) >>
+                                  __ffs(dd->div1_mask)) + 1) {
+               /* nothing to be done */
+               return;
+       }
+
+       if (clk->context == DPLL_LOCKED)
+               omap3_noncore_dpll_program(clk, 0);
+       else
+               _omap3_dpll_write_clken(clk, clk->context);
+}
+
 /* OMAP3/4 non-CORE DPLL clkops */
 const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
        .allow_idle     = omap3_dpll_allow_idle,
index 071af44b1ba856d28ec4438f3373bc3ab9750475..ed24f20f63c73f4da764d3a3ec97a8079e3dd9d5 100644 (file)
@@ -555,7 +555,7 @@ static void __init ti_fapll_setup(struct device_node *node)
 
        init->num_parents = of_clk_get_parent_count(node);
        if (init->num_parents != 2) {
-               pr_err("%s must have two parents\n", node->name);
+               pr_err("%pOFn must have two parents\n", node);
                goto free;
        }
 
@@ -564,19 +564,19 @@ static void __init ti_fapll_setup(struct device_node *node)
 
        fd->clk_ref = of_clk_get(node, 0);
        if (IS_ERR(fd->clk_ref)) {
-               pr_err("%s could not get clk_ref\n", node->name);
+               pr_err("%pOFn could not get clk_ref\n", node);
                goto free;
        }
 
        fd->clk_bypass = of_clk_get(node, 1);
        if (IS_ERR(fd->clk_bypass)) {
-               pr_err("%s could not get clk_bypass\n", node->name);
+               pr_err("%pOFn could not get clk_bypass\n", node);
                goto free;
        }
 
        fd->base = of_iomap(node, 0);
        if (!fd->base) {
-               pr_err("%s could not get IO base\n", node->name);
+               pr_err("%pOFn could not get IO base\n", node);
                goto free;
        }
 
index 0174a51a4ba6c11dfa4cec9b2a57bc44e156ef67..7cbe896db07166532886c9b7613acc79f3efa068 100644 (file)
@@ -42,12 +42,12 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
        u32 flags = 0;
 
        if (of_property_read_u32(node, "ti,clock-div", &div)) {
-               pr_err("%s must have a clock-div property\n", node->name);
+               pr_err("%pOFn must have a clock-div property\n", node);
                return;
        }
 
        if (of_property_read_u32(node, "ti,clock-mult", &mult)) {
-               pr_err("%s must have a clock-mult property\n", node->name);
+               pr_err("%pOFn must have a clock-mult property\n", node);
                return;
        }
 
index 935b2de5fb88702af4f6caf045b03cd7c355e7ec..1c78fff5513c798b5e0f8e62887c5a83b1523be8 100644 (file)
@@ -33,6 +33,7 @@ static const struct clk_ops omap_gate_clkdm_clk_ops = {
        .init           = &omap2_init_clk_clkdm,
        .enable         = &omap2_clkops_enable_clkdm,
        .disable        = &omap2_clkops_disable_clkdm,
+       .restore_context = clk_gate_restore_context,
 };
 
 const struct clk_ops omap_gate_clk_ops = {
@@ -40,6 +41,7 @@ const struct clk_ops omap_gate_clk_ops = {
        .enable         = &omap2_dflt_clk_enable,
        .disable        = &omap2_dflt_clk_disable,
        .is_enabled     = &omap2_dflt_clk_is_enabled,
+       .restore_context = clk_gate_restore_context,
 };
 
 static const struct clk_ops omap_gate_clk_hsdiv_restore_ops = {
@@ -47,6 +49,7 @@ static const struct clk_ops omap_gate_clk_hsdiv_restore_ops = {
        .enable         = &omap36xx_gate_clk_enable_with_hsdiv_restore,
        .disable        = &omap2_dflt_clk_disable,
        .is_enabled     = &omap2_dflt_clk_is_enabled,
+       .restore_context = clk_gate_restore_context,
 };
 
 /**
@@ -179,7 +182,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
        }
 
        if (of_clk_get_parent_count(node) != 1) {
-               pr_err("%s must have 1 parent\n", node->name);
+               pr_err("%pOFn must have 1 parent\n", node);
                return;
        }
 
index 41ae7021670ea0179f43ef194be4bb73ed1fff33..87e00c2ee957d9dab2a6bd646f36b8c21040c358 100644 (file)
@@ -84,7 +84,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
 
        parent_name = of_clk_get_parent_name(node, 0);
        if (!parent_name) {
-               pr_err("%s must have a parent\n", node->name);
+               pr_err("%pOFn must have a parent\n", node);
                return;
        }
 
index 69a4308a5a983b9e027eb8610ac5da53c8b15cec..883bdde94d048643c1ff98239305b2f6393c1339 100644 (file)
@@ -91,10 +91,39 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index)
        return 0;
 }
 
+/**
+ * clk_mux_save_context - Save the parent selcted in the mux
+ * @hw: pointer  struct clk_hw
+ *
+ * Save the parent mux value.
+ */
+static int clk_mux_save_context(struct clk_hw *hw)
+{
+       struct clk_omap_mux *mux = to_clk_omap_mux(hw);
+
+       mux->saved_parent = ti_clk_mux_get_parent(hw);
+       return 0;
+}
+
+/**
+ * clk_mux_restore_context - Restore the parent in the mux
+ * @hw: pointer  struct clk_hw
+ *
+ * Restore the saved parent mux value.
+ */
+static void clk_mux_restore_context(struct clk_hw *hw)
+{
+       struct clk_omap_mux *mux = to_clk_omap_mux(hw);
+
+       ti_clk_mux_set_parent(hw, mux->saved_parent);
+}
+
 const struct clk_ops ti_clk_mux_ops = {
        .get_parent = ti_clk_mux_get_parent,
        .set_parent = ti_clk_mux_set_parent,
        .determine_rate = __clk_mux_determine_rate,
+       .save_context = clk_mux_save_context,
+       .restore_context = clk_mux_restore_context,
 };
 
 static struct clk *_register_mux(struct device *dev, const char *name,
@@ -186,7 +215,7 @@ static void of_mux_clk_setup(struct device_node *node)
 
        num_parents = of_clk_get_parent_count(node);
        if (num_parents < 2) {
-               pr_err("mux-clock %s must have parents\n", node->name);
+               pr_err("mux-clock %pOFn must have parents\n", node);
                return;
        }
        parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL);
@@ -278,7 +307,7 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
        num_parents = of_clk_get_parent_count(node);
 
        if (num_parents < 2) {
-               pr_err("%s must have parents\n", node->name);
+               pr_err("%pOFn must have parents\n", node);
                goto cleanup;
        }
 
index 88a2cab37f627b86bebe9512ffee9db720b327e1..d7b53ac8ad11520101c11823fd44c0b9eaec178f 100644 (file)
@@ -602,7 +602,7 @@ void __init zynq_clock_init(void)
        }
 
        if (of_address_to_resource(np, 0, &res)) {
-               pr_err("%s: failed to get resource\n", np->name);
+               pr_err("%pOFn: failed to get resource\n", np);
                goto np_err;
        }
 
@@ -611,7 +611,7 @@ void __init zynq_clock_init(void)
        if (slcr->data) {
                zynq_clkc_base = (__force void __iomem *)slcr->data + res.start;
        } else {
-               pr_err("%s: Unable to get I/O memory\n", np->name);
+               pr_err("%pOFn: Unable to get I/O memory\n", np);
                of_node_put(slcr);
                goto np_err;
        }
diff --git a/drivers/clk/zynqmp/Kconfig b/drivers/clk/zynqmp/Kconfig
new file mode 100644 (file)
index 0000000..1708605
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config COMMON_CLK_ZYNQMP
+       bool "Support for Xilinx ZynqMP Ultrascale+ clock controllers"
+       depends on ARCH_ZYNQMP || COMPILE_TEST
+       depends on ZYNQMP_FIRMWARE
+       help
+         Support for the Zynqmp Ultrascale clock controller.
+         It has a dependency on the PMU firmware.
+         Say Y if you want to include clock support.
diff --git a/drivers/clk/zynqmp/Makefile b/drivers/clk/zynqmp/Makefile
new file mode 100644 (file)
index 0000000..0ec24bf
--- /dev/null
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+# Zynq Ultrascale+ MPSoC clock specific Makefile
+
+obj-$(CONFIG_ARCH_ZYNQMP)      += pll.o clk-gate-zynqmp.o divider.o clk-mux-zynqmp.o clkc.o
diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
new file mode 100644 (file)
index 0000000..83b236f
--- /dev/null
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Zynq UltraScale+ MPSoC clock controller
+ *
+ *  Copyright (C) 2016-2018 Xilinx
+ *
+ * Gated clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include "clk-zynqmp.h"
+
+/**
+ * struct clk_gate - gating clock
+ * @hw:                handle between common and hardware-specific interfaces
+ * @flags:     hardware-specific flags
+ * @clk_id:    Id of clock
+ */
+struct zynqmp_clk_gate {
+       struct clk_hw hw;
+       u8 flags;
+       u32 clk_id;
+};
+
+#define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, hw)
+
+/**
+ * zynqmp_clk_gate_enable() - Enable clock
+ * @hw:                handle between common and hardware-specific interfaces
+ *
+ * Return: 0 on success else error code
+ */
+static int zynqmp_clk_gate_enable(struct clk_hw *hw)
+{
+       struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = gate->clk_id;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_enable(clk_id);
+
+       if (ret)
+               pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return ret;
+}
+
+/*
+ * zynqmp_clk_gate_disable() - Disable clock
+ * @hw:                handle between common and hardware-specific interfaces
+ */
+static void zynqmp_clk_gate_disable(struct clk_hw *hw)
+{
+       struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = gate->clk_id;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_disable(clk_id);
+
+       if (ret)
+               pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+}
+
+/**
+ * zynqmp_clk_gate_is_enable() - Check clock state
+ * @hw:                handle between common and hardware-specific interfaces
+ *
+ * Return: 1 if enabled, 0 if disabled else error code
+ */
+static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
+{
+       struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = gate->clk_id;
+       int state, ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_getstate(clk_id, &state);
+       if (ret) {
+               pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+               return -EIO;
+       }
+
+       return state ? 1 : 0;
+}
+
+static const struct clk_ops zynqmp_clk_gate_ops = {
+       .enable = zynqmp_clk_gate_enable,
+       .disable = zynqmp_clk_gate_disable,
+       .is_enabled = zynqmp_clk_gate_is_enabled,
+};
+
+/**
+ * zynqmp_clk_register_gate() - Register a gate clock with the clock framework
+ * @name:              Name of this clock
+ * @clk_id:            Id of this clock
+ * @parents:           Name of this clock's parents
+ * @num_parents:       Number of parents
+ * @nodes:             Clock topology node
+ *
+ * Return: clock hardware of the registered clock gate
+ */
+struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
+                                       const char * const *parents,
+                                       u8 num_parents,
+                                       const struct clock_topology *nodes)
+{
+       struct zynqmp_clk_gate *gate;
+       struct clk_hw *hw;
+       int ret;
+       struct clk_init_data init;
+
+       /* allocate the gate */
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &zynqmp_clk_gate_ops;
+       init.flags = nodes->flag;
+       init.parent_names = parents;
+       init.num_parents = 1;
+
+       /* struct clk_gate assignments */
+       gate->flags = nodes->type_flag;
+       gate->hw.init = &init;
+       gate->clk_id = clk_id;
+
+       hw = &gate->hw;
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
+               kfree(gate);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
new file mode 100644 (file)
index 0000000..4143f56
--- /dev/null
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Zynq UltraScale+ MPSoC mux
+ *
+ *  Copyright (C) 2016-2018 Xilinx
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include "clk-zynqmp.h"
+
+/*
+ * DOC: basic adjustable multiplexer clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is only affected by parent switching.  No clk_set_rate support
+ * parent - parent is adjustable through clk_set_parent
+ */
+
+/**
+ * struct zynqmp_clk_mux - multiplexer clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @flags:     hardware-specific flags
+ * @clk_id:    Id of clock
+ */
+struct zynqmp_clk_mux {
+       struct clk_hw hw;
+       u8 flags;
+       u32 clk_id;
+};
+
+#define to_zynqmp_clk_mux(_hw) container_of(_hw, struct zynqmp_clk_mux, hw)
+
+/**
+ * zynqmp_clk_mux_get_parent() - Get parent of clock
+ * @hw:                handle between common and hardware-specific interfaces
+ *
+ * Return: Parent index
+ */
+static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
+{
+       struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = mux->clk_id;
+       u32 val;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_getparent(clk_id, &val);
+
+       if (ret)
+               pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return val;
+}
+
+/**
+ * zynqmp_clk_mux_set_parent() - Set parent of clock
+ * @hw:                handle between common and hardware-specific interfaces
+ * @index:     Parent index
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = mux->clk_id;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_setparent(clk_id, index);
+
+       if (ret)
+               pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return ret;
+}
+
+static const struct clk_ops zynqmp_clk_mux_ops = {
+       .get_parent = zynqmp_clk_mux_get_parent,
+       .set_parent = zynqmp_clk_mux_set_parent,
+       .determine_rate = __clk_mux_determine_rate,
+};
+
+static const struct clk_ops zynqmp_clk_mux_ro_ops = {
+       .get_parent = zynqmp_clk_mux_get_parent,
+};
+
+/**
+ * zynqmp_clk_register_mux() - Register a mux table with the clock
+ *                            framework
+ * @name:              Name of this clock
+ * @clk_id:            Id of this clock
+ * @parents:           Name of this clock's parents
+ * @num_parents:       Number of parents
+ * @nodes:             Clock topology node
+ *
+ * Return: clock hardware of the registered clock mux
+ */
+struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,
+                                      const char * const *parents,
+                                      u8 num_parents,
+                                      const struct clock_topology *nodes)
+{
+       struct zynqmp_clk_mux *mux;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+
+       mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+       if (!mux)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       if (nodes->type_flag & CLK_MUX_READ_ONLY)
+               init.ops = &zynqmp_clk_mux_ro_ops;
+       else
+               init.ops = &zynqmp_clk_mux_ops;
+       init.flags = nodes->flag;
+       init.parent_names = parents;
+       init.num_parents = num_parents;
+       mux->flags = nodes->type_flag;
+       mux->hw.init = &init;
+       mux->clk_id = clk_id;
+
+       hw = &mux->hw;
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
+               kfree(hw);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(zynqmp_clk_register_mux);
diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
new file mode 100644 (file)
index 0000000..7ab163b
--- /dev/null
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright (C) 2016-2018 Xilinx
+ */
+
+#ifndef __LINUX_CLK_ZYNQMP_H_
+#define __LINUX_CLK_ZYNQMP_H_
+
+#include <linux/spinlock.h>
+
+#include <linux/firmware/xlnx-zynqmp.h>
+
+/* Clock APIs payload parameters */
+#define CLK_GET_NAME_RESP_LEN                          16
+#define CLK_GET_TOPOLOGY_RESP_WORDS                    3
+#define CLK_GET_PARENTS_RESP_WORDS                     3
+#define CLK_GET_ATTR_RESP_WORDS                                1
+
+enum topology_type {
+       TYPE_INVALID,
+       TYPE_MUX,
+       TYPE_PLL,
+       TYPE_FIXEDFACTOR,
+       TYPE_DIV1,
+       TYPE_DIV2,
+       TYPE_GATE,
+};
+
+/**
+ * struct clock_topology - Clock topology
+ * @type:      Type of topology
+ * @flag:      Topology flags
+ * @type_flag: Topology type specific flag
+ */
+struct clock_topology {
+       u32 type;
+       u32 flag;
+       u32 type_flag;
+};
+
+struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
+                                      const char * const *parents,
+                                      u8 num_parents,
+                                      const struct clock_topology *nodes);
+
+struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id,
+                                       const char * const *parents,
+                                       u8 num_parents,
+                                       const struct clock_topology *nodes);
+
+struct clk_hw *zynqmp_clk_register_divider(const char *name,
+                                          u32 clk_id,
+                                          const char * const *parents,
+                                          u8 num_parents,
+                                          const struct clock_topology *nodes);
+
+struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,
+                                      const char * const *parents,
+                                      u8 num_parents,
+                                      const struct clock_topology *nodes);
+
+struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name,
+                                       u32 clk_id,
+                                       const char * const *parents,
+                                       u8 num_parents,
+                                       const struct clock_topology *nodes);
+
+#endif
diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
new file mode 100644 (file)
index 0000000..9d7d297
--- /dev/null
@@ -0,0 +1,716 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Zynq UltraScale+ MPSoC clock controller
+ *
+ *  Copyright (C) 2016-2018 Xilinx
+ *
+ * Based on drivers/clk/zynq/clkc.c
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "clk-zynqmp.h"
+
+#define MAX_PARENT                     100
+#define MAX_NODES                      6
+#define MAX_NAME_LEN                   50
+
+#define CLK_TYPE_SHIFT                 2
+
+#define PM_API_PAYLOAD_LEN             3
+
+#define NA_PARENT                      0xFFFFFFFF
+#define DUMMY_PARENT                   0xFFFFFFFE
+
+#define CLK_TYPE_FIELD_LEN             4
+#define CLK_TOPOLOGY_NODE_OFFSET       16
+#define NODES_PER_RESP                 3
+
+#define CLK_TYPE_FIELD_MASK            0xF
+#define CLK_FLAG_FIELD_MASK            GENMASK(21, 8)
+#define CLK_TYPE_FLAG_FIELD_MASK       GENMASK(31, 24)
+
+#define CLK_PARENTS_ID_LEN             16
+#define CLK_PARENTS_ID_MASK            0xFFFF
+
+/* Flags for parents */
+#define PARENT_CLK_SELF                        0
+#define PARENT_CLK_NODE1               1
+#define PARENT_CLK_NODE2               2
+#define PARENT_CLK_NODE3               3
+#define PARENT_CLK_NODE4               4
+#define PARENT_CLK_EXTERNAL            5
+
+#define END_OF_CLK_NAME                        "END_OF_CLK"
+#define END_OF_TOPOLOGY_NODE           1
+#define END_OF_PARENTS                 1
+#define RESERVED_CLK_NAME              ""
+
+#define CLK_VALID_MASK                 0x1
+
+enum clk_type {
+       CLK_TYPE_OUTPUT,
+       CLK_TYPE_EXTERNAL,
+};
+
+/**
+ * struct clock_parent - Clock parent
+ * @name:      Parent name
+ * @id:                Parent clock ID
+ * @flag:      Parent flags
+ */
+struct clock_parent {
+       char name[MAX_NAME_LEN];
+       int id;
+       u32 flag;
+};
+
+/**
+ * struct zynqmp_clock - Clock
+ * @clk_name:          Clock name
+ * @valid:             Validity flag of clock
+ * @type:              Clock type (Output/External)
+ * @node:              Clock topology nodes
+ * @num_nodes:         Number of nodes present in topology
+ * @parent:            Parent of clock
+ * @num_parents:       Number of parents of clock
+ */
+struct zynqmp_clock {
+       char clk_name[MAX_NAME_LEN];
+       u32 valid;
+       enum clk_type type;
+       struct clock_topology node[MAX_NODES];
+       u32 num_nodes;
+       struct clock_parent parent[MAX_PARENT];
+       u32 num_parents;
+};
+
+static const char clk_type_postfix[][10] = {
+       [TYPE_INVALID] = "",
+       [TYPE_MUX] = "_mux",
+       [TYPE_GATE] = "",
+       [TYPE_DIV1] = "_div1",
+       [TYPE_DIV2] = "_div2",
+       [TYPE_FIXEDFACTOR] = "_ff",
+       [TYPE_PLL] = ""
+};
+
+static struct clk_hw *(* const clk_topology[]) (const char *name, u32 clk_id,
+                                       const char * const *parents,
+                                       u8 num_parents,
+                                       const struct clock_topology *nodes)
+                                       = {
+       [TYPE_INVALID] = NULL,
+       [TYPE_MUX] = zynqmp_clk_register_mux,
+       [TYPE_PLL] = zynqmp_clk_register_pll,
+       [TYPE_FIXEDFACTOR] = zynqmp_clk_register_fixed_factor,
+       [TYPE_DIV1] = zynqmp_clk_register_divider,
+       [TYPE_DIV2] = zynqmp_clk_register_divider,
+       [TYPE_GATE] = zynqmp_clk_register_gate
+};
+
+static struct zynqmp_clock *clock;
+static struct clk_hw_onecell_data *zynqmp_data;
+static unsigned int clock_max_idx;
+static const struct zynqmp_eemi_ops *eemi_ops;
+
+/**
+ * zynqmp_is_valid_clock() - Check whether clock is valid or not
+ * @clk_id:    Clock index
+ *
+ * Return: 1 if clock is valid, 0 if clock is invalid else error code
+ */
+static inline int zynqmp_is_valid_clock(u32 clk_id)
+{
+       if (clk_id > clock_max_idx)
+               return -ENODEV;
+
+       return clock[clk_id].valid;
+}
+
+/**
+ * zynqmp_get_clock_name() - Get name of clock from Clock index
+ * @clk_id:    Clock index
+ * @clk_name:  Name of clock
+ *
+ * Return: 0 on success else error code
+ */
+static int zynqmp_get_clock_name(u32 clk_id, char *clk_name)
+{
+       int ret;
+
+       ret = zynqmp_is_valid_clock(clk_id);
+       if (ret == 1) {
+               strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
+               return 0;
+       }
+
+       return ret == 0 ? -EINVAL : ret;
+}
+
+/**
+ * zynqmp_get_clock_type() - Get type of clock
+ * @clk_id:    Clock index
+ * @type:      Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL
+ *
+ * Return: 0 on success else error code
+ */
+static int zynqmp_get_clock_type(u32 clk_id, u32 *type)
+{
+       int ret;
+
+       ret = zynqmp_is_valid_clock(clk_id);
+       if (ret == 1) {
+               *type = clock[clk_id].type;
+               return 0;
+       }
+
+       return ret == 0 ? -EINVAL : ret;
+}
+
+/**
+ * zynqmp_pm_clock_get_num_clocks() - Get number of clocks in system
+ * @nclocks:   Number of clocks in system/board.
+ *
+ * Call firmware API to get number of clocks.
+ *
+ * Return: 0 on success else error code.
+ */
+static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks)
+{
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       qdata.qid = PM_QID_CLOCK_GET_NUM_CLOCKS;
+
+       ret = eemi_ops->query_data(qdata, ret_payload);
+       *nclocks = ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_clock_get_name() - Get the name of clock for given id
+ * @clock_id:  ID of the clock to be queried
+ * @name:      Name of given clock
+ *
+ * This function is used to get name of clock specified by given
+ * clock ID.
+ *
+ * Return: Returns 0, in case of error name would be 0
+ */
+static int zynqmp_pm_clock_get_name(u32 clock_id, char *name)
+{
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+
+       qdata.qid = PM_QID_CLOCK_GET_NAME;
+       qdata.arg1 = clock_id;
+
+       eemi_ops->query_data(qdata, ret_payload);
+       memcpy(name, ret_payload, CLK_GET_NAME_RESP_LEN);
+
+       return 0;
+}
+
+/**
+ * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id
+ * @clock_id:  ID of the clock to be queried
+ * @index:     Node index of clock topology
+ * @topology:  Buffer to store nodes in topology and flags
+ *
+ * This function is used to get topology information for the clock
+ * specified by given clock ID.
+ *
+ * This API will return 3 node of topology with a single response. To get
+ * other nodes, master should call same API in loop with new
+ * index till error is returned. E.g First call should have
+ * index 0 which will return nodes 0,1 and 2. Next call, index
+ * should be 3 which will return nodes 3,4 and 5 and so on.
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, u32 *topology)
+{
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY;
+       qdata.arg1 = clock_id;
+       qdata.arg2 = index;
+
+       ret = eemi_ops->query_data(qdata, ret_payload);
+       memcpy(topology, &ret_payload[1], CLK_GET_TOPOLOGY_RESP_WORDS * 4);
+
+       return ret;
+}
+
+/**
+ * zynqmp_clk_register_fixed_factor() - Register fixed factor with the
+ *                                     clock framework
+ * @name:              Name of this clock
+ * @clk_id:            Clock ID
+ * @parents:           Name of this clock's parents
+ * @num_parents:       Number of parents
+ * @nodes:             Clock topology node
+ *
+ * Return: clock hardware to the registered clock
+ */
+struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
+                                       const char * const *parents,
+                                       u8 num_parents,
+                                       const struct clock_topology *nodes)
+{
+       u32 mult, div;
+       struct clk_hw *hw;
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
+       qdata.arg1 = clk_id;
+
+       ret = eemi_ops->query_data(qdata, ret_payload);
+       mult = ret_payload[1];
+       div = ret_payload[2];
+
+       hw = clk_hw_register_fixed_factor(NULL, name,
+                                         parents[0],
+                                         nodes->flag, mult,
+                                         div);
+
+       return hw;
+}
+
+/**
+ * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id
+ * @clock_id:  Clock ID
+ * @index:     Parent index
+ * @parents:   3 parents of the given clock
+ *
+ * This function is used to get 3 parents for the clock specified by
+ * given clock ID.
+ *
+ * This API will return 3 parents with a single response. To get
+ * other parents, master should call same API in loop with new
+ * parent index till error is returned. E.g First call should have
+ * index 0 which will return parents 0,1 and 2. Next call, index
+ * should be 3 which will return parent 3,4 and 5 and so on.
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents)
+{
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       qdata.qid = PM_QID_CLOCK_GET_PARENTS;
+       qdata.arg1 = clock_id;
+       qdata.arg2 = index;
+
+       ret = eemi_ops->query_data(qdata, ret_payload);
+       memcpy(parents, &ret_payload[1], CLK_GET_PARENTS_RESP_WORDS * 4);
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id
+ * @clock_id:  Clock ID
+ * @attr:      Clock attributes
+ *
+ * This function is used to get clock's attributes(e.g. valid, clock type, etc).
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr)
+{
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES;
+       qdata.arg1 = clock_id;
+
+       ret = eemi_ops->query_data(qdata, ret_payload);
+       memcpy(attr, &ret_payload[1], CLK_GET_ATTR_RESP_WORDS * 4);
+
+       return ret;
+}
+
+/**
+ * __zynqmp_clock_get_topology() - Get topology data of clock from firmware
+ *                                response data
+ * @topology:          Clock topology
+ * @data:              Clock topology data received from firmware
+ * @nnodes:            Number of nodes
+ *
+ * Return: 0 on success else error+reason
+ */
+static int __zynqmp_clock_get_topology(struct clock_topology *topology,
+                                      u32 *data, u32 *nnodes)
+{
+       int i;
+
+       for (i = 0; i < PM_API_PAYLOAD_LEN; i++) {
+               if (!(data[i] & CLK_TYPE_FIELD_MASK))
+                       return END_OF_TOPOLOGY_NODE;
+               topology[*nnodes].type = data[i] & CLK_TYPE_FIELD_MASK;
+               topology[*nnodes].flag = FIELD_GET(CLK_FLAG_FIELD_MASK,
+                                                  data[i]);
+               topology[*nnodes].type_flag =
+                               FIELD_GET(CLK_TYPE_FLAG_FIELD_MASK, data[i]);
+               (*nnodes)++;
+       }
+
+       return 0;
+}
+
+/**
+ * zynqmp_clock_get_topology() - Get topology of clock from firmware using
+ *                              PM_API
+ * @clk_id:            Clock index
+ * @topology:          Clock topology
+ * @num_nodes:         Number of nodes
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_clock_get_topology(u32 clk_id,
+                                    struct clock_topology *topology,
+                                    u32 *num_nodes)
+{
+       int j, ret;
+       u32 pm_resp[PM_API_PAYLOAD_LEN] = {0};
+
+       *num_nodes = 0;
+       for (j = 0; j <= MAX_NODES; j += 3) {
+               ret = zynqmp_pm_clock_get_topology(clk_id, j, pm_resp);
+               if (ret)
+                       return ret;
+               ret = __zynqmp_clock_get_topology(topology, pm_resp, num_nodes);
+               if (ret == END_OF_TOPOLOGY_NODE)
+                       return 0;
+       }
+
+       return 0;
+}
+
+/**
+ * __zynqmp_clock_get_topology() - Get parents info of clock from firmware
+ *                                response data
+ * @parents:           Clock parents
+ * @data:              Clock parents data received from firmware
+ * @nparent:           Number of parent
+ *
+ * Return: 0 on success else error+reason
+ */
+static int __zynqmp_clock_get_parents(struct clock_parent *parents, u32 *data,
+                                     u32 *nparent)
+{
+       int i;
+       struct clock_parent *parent;
+
+       for (i = 0; i < PM_API_PAYLOAD_LEN; i++) {
+               if (data[i] == NA_PARENT)
+                       return END_OF_PARENTS;
+
+               parent = &parents[i];
+               parent->id = data[i] & CLK_PARENTS_ID_MASK;
+               if (data[i] == DUMMY_PARENT) {
+                       strcpy(parent->name, "dummy_name");
+                       parent->flag = 0;
+               } else {
+                       parent->flag = data[i] >> CLK_PARENTS_ID_LEN;
+                       if (zynqmp_get_clock_name(parent->id, parent->name))
+                               continue;
+               }
+               *nparent += 1;
+       }
+
+       return 0;
+}
+
+/**
+ * zynqmp_clock_get_parents() - Get parents info from firmware using PM_API
+ * @clk_id:            Clock index
+ * @parents:           Clock parents
+ * @num_parents:       Total number of parents
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
+                                   u32 *num_parents)
+{
+       int j = 0, ret;
+       u32 pm_resp[PM_API_PAYLOAD_LEN] = {0};
+
+       *num_parents = 0;
+       do {
+               /* Get parents from firmware */
+               ret = zynqmp_pm_clock_get_parents(clk_id, j, pm_resp);
+               if (ret)
+                       return ret;
+
+               ret = __zynqmp_clock_get_parents(&parents[j], pm_resp,
+                                                num_parents);
+               if (ret == END_OF_PARENTS)
+                       return 0;
+               j += PM_API_PAYLOAD_LEN;
+       } while (*num_parents <= MAX_PARENT);
+
+       return 0;
+}
+
+/**
+ * zynqmp_get_parent_list() - Create list of parents name
+ * @np:                        Device node
+ * @clk_id:            Clock index
+ * @parent_list:       List of parent's name
+ * @num_parents:       Total number of parents
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,
+                                 const char **parent_list, u32 *num_parents)
+{
+       int i = 0, ret;
+       u32 total_parents = clock[clk_id].num_parents;
+       struct clock_topology *clk_nodes;
+       struct clock_parent *parents;
+
+       clk_nodes = clock[clk_id].node;
+       parents = clock[clk_id].parent;
+
+       for (i = 0; i < total_parents; i++) {
+               if (!parents[i].flag) {
+                       parent_list[i] = parents[i].name;
+               } else if (parents[i].flag == PARENT_CLK_EXTERNAL) {
+                       ret = of_property_match_string(np, "clock-names",
+                                                      parents[i].name);
+                       if (ret < 0)
+                               strcpy(parents[i].name, "dummy_name");
+                       parent_list[i] = parents[i].name;
+               } else {
+                       strcat(parents[i].name,
+                              clk_type_postfix[clk_nodes[parents[i].flag - 1].
+                              type]);
+                       parent_list[i] = parents[i].name;
+               }
+       }
+
+       *num_parents = total_parents;
+       return 0;
+}
+
+/**
+ * zynqmp_register_clk_topology() - Register clock topology
+ * @clk_id:            Clock index
+ * @clk_name:          Clock Name
+ * @num_parents:       Total number of parents
+ * @parent_names:      List of parents name
+ *
+ * Return: Returns either clock hardware or error+reason
+ */
+static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
+                                                  int num_parents,
+                                                  const char **parent_names)
+{
+       int j;
+       u32 num_nodes;
+       char *clk_out = NULL;
+       struct clock_topology *nodes;
+       struct clk_hw *hw = NULL;
+
+       nodes = clock[clk_id].node;
+       num_nodes = clock[clk_id].num_nodes;
+
+       for (j = 0; j < num_nodes; j++) {
+               /*
+                * Clock name received from firmware is output clock name.
+                * Intermediate clock names are postfixed with type of clock.
+                */
+               if (j != (num_nodes - 1)) {
+                       clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name,
+                                           clk_type_postfix[nodes[j].type]);
+               } else {
+                       clk_out = kasprintf(GFP_KERNEL, "%s", clk_name);
+               }
+
+               if (!clk_topology[nodes[j].type])
+                       continue;
+
+               hw = (*clk_topology[nodes[j].type])(clk_out, clk_id,
+                                                   parent_names,
+                                                   num_parents,
+                                                   &nodes[j]);
+               if (IS_ERR(hw))
+                       pr_warn_once("%s() %s register fail with %ld\n",
+                                    __func__, clk_name, PTR_ERR(hw));
+
+               parent_names[0] = clk_out;
+       }
+       kfree(clk_out);
+       return hw;
+}
+
+/**
+ * zynqmp_register_clocks() - Register clocks
+ * @np:                Device node
+ *
+ * Return: 0 on success else error code
+ */
+static int zynqmp_register_clocks(struct device_node *np)
+{
+       int ret;
+       u32 i, total_parents = 0, type = 0;
+       const char *parent_names[MAX_PARENT];
+
+       for (i = 0; i < clock_max_idx; i++) {
+               char clk_name[MAX_NAME_LEN];
+
+               /* get clock name, continue to next clock if name not found */
+               if (zynqmp_get_clock_name(i, clk_name))
+                       continue;
+
+               /* Check if clock is valid and output clock.
+                * Do not register invalid or external clock.
+                */
+               ret = zynqmp_get_clock_type(i, &type);
+               if (ret || type != CLK_TYPE_OUTPUT)
+                       continue;
+
+               /* Get parents of clock*/
+               if (zynqmp_get_parent_list(np, i, parent_names,
+                                          &total_parents)) {
+                       WARN_ONCE(1, "No parents found for %s\n",
+                                 clock[i].clk_name);
+                       continue;
+               }
+
+               zynqmp_data->hws[i] =
+                       zynqmp_register_clk_topology(i, clk_name,
+                                                    total_parents,
+                                                    parent_names);
+       }
+
+       for (i = 0; i < clock_max_idx; i++) {
+               if (IS_ERR(zynqmp_data->hws[i])) {
+                       pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n",
+                              clock[i].clk_name, PTR_ERR(zynqmp_data->hws[i]));
+                       WARN_ON(1);
+               }
+       }
+       return 0;
+}
+
+/**
+ * zynqmp_get_clock_info() - Get clock information from firmware using PM_API
+ */
+static void zynqmp_get_clock_info(void)
+{
+       int i, ret;
+       u32 attr, type = 0;
+
+       for (i = 0; i < clock_max_idx; i++) {
+               zynqmp_pm_clock_get_name(i, clock[i].clk_name);
+               if (!strcmp(clock[i].clk_name, RESERVED_CLK_NAME))
+                       continue;
+
+               ret = zynqmp_pm_clock_get_attributes(i, &attr);
+               if (ret)
+                       continue;
+
+               clock[i].valid = attr & CLK_VALID_MASK;
+               clock[i].type = attr >> CLK_TYPE_SHIFT ? CLK_TYPE_EXTERNAL :
+                                                       CLK_TYPE_OUTPUT;
+       }
+
+       /* Get topology of all clock */
+       for (i = 0; i < clock_max_idx; i++) {
+               ret = zynqmp_get_clock_type(i, &type);
+               if (ret || type != CLK_TYPE_OUTPUT)
+                       continue;
+
+               ret = zynqmp_clock_get_topology(i, clock[i].node,
+                                               &clock[i].num_nodes);
+               if (ret)
+                       continue;
+
+               ret = zynqmp_clock_get_parents(i, clock[i].parent,
+                                              &clock[i].num_parents);
+               if (ret)
+                       continue;
+       }
+}
+
+/**
+ * zynqmp_clk_setup() - Setup the clock framework and register clocks
+ * @np:                Device node
+ *
+ * Return: 0 on success else error code
+ */
+static int zynqmp_clk_setup(struct device_node *np)
+{
+       int ret;
+
+       ret = zynqmp_pm_clock_get_num_clocks(&clock_max_idx);
+       if (ret)
+               return ret;
+
+       zynqmp_data = kzalloc(sizeof(*zynqmp_data) + sizeof(*zynqmp_data) *
+                                               clock_max_idx, GFP_KERNEL);
+       if (!zynqmp_data)
+               return -ENOMEM;
+
+       clock = kcalloc(clock_max_idx, sizeof(*clock), GFP_KERNEL);
+       if (!clock) {
+               kfree(zynqmp_data);
+               return -ENOMEM;
+       }
+
+       zynqmp_get_clock_info();
+       zynqmp_register_clocks(np);
+
+       zynqmp_data->num = clock_max_idx;
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, zynqmp_data);
+
+       return 0;
+}
+
+static int zynqmp_clock_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct device *dev = &pdev->dev;
+
+       eemi_ops = zynqmp_pm_get_eemi_ops();
+       if (!eemi_ops)
+               return -ENXIO;
+
+       ret = zynqmp_clk_setup(dev->of_node);
+
+       return ret;
+}
+
+static const struct of_device_id zynqmp_clock_of_match[] = {
+       {.compatible = "xlnx,zynqmp-clk"},
+       {},
+};
+MODULE_DEVICE_TABLE(of, zynqmp_clock_of_match);
+
+static struct platform_driver zynqmp_clock_driver = {
+       .driver = {
+               .name = "zynqmp_clock",
+               .of_match_table = zynqmp_clock_of_match,
+       },
+       .probe = zynqmp_clock_probe,
+};
+module_platform_driver(zynqmp_clock_driver);
diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
new file mode 100644 (file)
index 0000000..a371c66
--- /dev/null
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Zynq UltraScale+ MPSoC Divider support
+ *
+ *  Copyright (C) 2016-2018 Xilinx
+ *
+ * Adjustable divider clock implementation
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include "clk-zynqmp.h"
+
+/*
+ * DOC: basic adjustable divider clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk->rate = ceiling(parent->rate / divisor)
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_zynqmp_clk_divider(_hw)             \
+       container_of(_hw, struct zynqmp_clk_divider, hw)
+
+#define CLK_FRAC       BIT(13) /* has a fractional parent */
+
+/**
+ * struct zynqmp_clk_divider - adjustable divider clock
+ * @hw:                handle between common and hardware-specific interfaces
+ * @flags:     Hardware specific flags
+ * @clk_id:    Id of clock
+ * @div_type:  divisor type (TYPE_DIV1 or TYPE_DIV2)
+ */
+struct zynqmp_clk_divider {
+       struct clk_hw hw;
+       u8 flags;
+       u32 clk_id;
+       u32 div_type;
+};
+
+static inline int zynqmp_divider_get_val(unsigned long parent_rate,
+                                        unsigned long rate)
+{
+       return DIV_ROUND_CLOSEST(parent_rate, rate);
+}
+
+/**
+ * zynqmp_clk_divider_recalc_rate() - Recalc rate of divider clock
+ * @hw:                        handle between common and hardware-specific interfaces
+ * @parent_rate:       rate of parent clock
+ *
+ * Return: 0 on success else error+reason
+ */
+static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
+                                                   unsigned long parent_rate)
+{
+       struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = divider->clk_id;
+       u32 div_type = divider->div_type;
+       u32 div, value;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_getdivider(clk_id, &div);
+
+       if (ret)
+               pr_warn_once("%s() get divider failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       if (div_type == TYPE_DIV1)
+               value = div & 0xFFFF;
+       else
+               value = div >> 16;
+
+       return DIV_ROUND_UP_ULL(parent_rate, value);
+}
+
+/**
+ * zynqmp_clk_divider_round_rate() - Round rate of divider clock
+ * @hw:                        handle between common and hardware-specific interfaces
+ * @rate:              rate of clock to be set
+ * @prate:             rate of parent clock
+ *
+ * Return: 0 on success else error+reason
+ */
+static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
+                                         unsigned long rate,
+                                         unsigned long *prate)
+{
+       struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = divider->clk_id;
+       u32 div_type = divider->div_type;
+       u32 bestdiv;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       /* if read only, just return current value */
+       if (divider->flags & CLK_DIVIDER_READ_ONLY) {
+               ret = eemi_ops->clock_getdivider(clk_id, &bestdiv);
+
+               if (ret)
+                       pr_warn_once("%s() get divider failed for %s, ret = %d\n",
+                                    __func__, clk_name, ret);
+               if (div_type == TYPE_DIV1)
+                       bestdiv = bestdiv & 0xFFFF;
+               else
+                       bestdiv  = bestdiv >> 16;
+
+               return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
+       }
+
+       bestdiv = zynqmp_divider_get_val(*prate, rate);
+
+       if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) &&
+           (divider->flags & CLK_FRAC))
+               bestdiv = rate % *prate ? 1 : bestdiv;
+       *prate = rate * bestdiv;
+
+       return rate;
+}
+
+/**
+ * zynqmp_clk_divider_set_rate() - Set rate of divider clock
+ * @hw:                        handle between common and hardware-specific interfaces
+ * @rate:              rate of clock to be set
+ * @parent_rate:       rate of parent clock
+ *
+ * Return: 0 on success else error+reason
+ */
+static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+                                      unsigned long parent_rate)
+{
+       struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = divider->clk_id;
+       u32 div_type = divider->div_type;
+       u32 value, div;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       value = zynqmp_divider_get_val(parent_rate, rate);
+       if (div_type == TYPE_DIV1) {
+               div = value & 0xFFFF;
+               div |= 0xffff << 16;
+       } else {
+               div = 0xffff;
+               div |= value << 16;
+       }
+
+       ret = eemi_ops->clock_setdivider(clk_id, div);
+
+       if (ret)
+               pr_warn_once("%s() set divider failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return ret;
+}
+
+static const struct clk_ops zynqmp_clk_divider_ops = {
+       .recalc_rate = zynqmp_clk_divider_recalc_rate,
+       .round_rate = zynqmp_clk_divider_round_rate,
+       .set_rate = zynqmp_clk_divider_set_rate,
+};
+
+/**
+ * zynqmp_clk_register_divider() - Register a divider clock
+ * @name:              Name of this clock
+ * @clk_id:            Id of clock
+ * @parents:           Name of this clock's parents
+ * @num_parents:       Number of parents
+ * @nodes:             Clock topology node
+ *
+ * Return: clock hardware to registered clock divider
+ */
+struct clk_hw *zynqmp_clk_register_divider(const char *name,
+                                          u32 clk_id,
+                                          const char * const *parents,
+                                          u8 num_parents,
+                                          const struct clock_topology *nodes)
+{
+       struct zynqmp_clk_divider *div;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+
+       /* allocate the divider */
+       div = kzalloc(sizeof(*div), GFP_KERNEL);
+       if (!div)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &zynqmp_clk_divider_ops;
+       init.flags = nodes->flag;
+       init.parent_names = parents;
+       init.num_parents = 1;
+
+       /* struct clk_divider assignments */
+       div->flags = nodes->type_flag;
+       div->hw.init = &init;
+       div->clk_id = clk_id;
+       div->div_type = nodes->type;
+
+       hw = &div->hw;
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
+               kfree(div);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+EXPORT_SYMBOL_GPL(zynqmp_clk_register_divider);
diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
new file mode 100644 (file)
index 0000000..a541397
--- /dev/null
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Zynq UltraScale+ MPSoC PLL driver
+ *
+ *  Copyright (C) 2016-2018 Xilinx
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include "clk-zynqmp.h"
+
+/**
+ * struct zynqmp_pll - PLL clock
+ * @hw:                Handle between common and hardware-specific interfaces
+ * @clk_id:    PLL clock ID
+ */
+struct zynqmp_pll {
+       struct clk_hw hw;
+       u32 clk_id;
+};
+
+#define to_zynqmp_pll(_hw)     container_of(_hw, struct zynqmp_pll, hw)
+
+#define PLL_FBDIV_MIN  25
+#define PLL_FBDIV_MAX  125
+
+#define PS_PLL_VCO_MIN 1500000000
+#define PS_PLL_VCO_MAX 3000000000UL
+
+enum pll_mode {
+       PLL_MODE_INT,
+       PLL_MODE_FRAC,
+};
+
+#define FRAC_OFFSET 0x8
+#define PLLFCFG_FRAC_EN        BIT(31)
+#define FRAC_DIV  BIT(16)  /* 2^16 */
+
+/**
+ * zynqmp_pll_get_mode() - Get mode of PLL
+ * @hw:                Handle between common and hardware-specific interfaces
+ *
+ * Return: Mode of PLL
+ */
+static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       u32 clk_id = clk->clk_id;
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->ioctl(0, IOCTL_GET_PLL_FRAC_MODE, clk_id, 0,
+                             ret_payload);
+       if (ret)
+               pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return ret_payload[1];
+}
+
+/**
+ * zynqmp_pll_set_mode() - Set the PLL mode
+ * @hw:                Handle between common and hardware-specific interfaces
+ * @on:                Flag to determine the mode
+ */
+static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       u32 clk_id = clk->clk_id;
+       const char *clk_name = clk_hw_get_name(hw);
+       int ret;
+       u32 mode;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       if (on)
+               mode = PLL_MODE_FRAC;
+       else
+               mode = PLL_MODE_INT;
+
+       ret = eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_MODE, clk_id, mode, NULL);
+       if (ret)
+               pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+}
+
+/**
+ * zynqmp_pll_round_rate() - Round a clock frequency
+ * @hw:                Handle between common and hardware-specific interfaces
+ * @rate:      Desired clock frequency
+ * @prate:     Clock frequency of parent clock
+ *
+ * Return: Frequency closest to @rate the hardware can generate
+ */
+static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *prate)
+{
+       u32 fbdiv;
+       long rate_div, f;
+
+       /* Enable the fractional mode if needed */
+       rate_div = (rate * FRAC_DIV) / *prate;
+       f = rate_div % FRAC_DIV;
+       zynqmp_pll_set_mode(hw, !!f);
+
+       if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) {
+               if (rate > PS_PLL_VCO_MAX) {
+                       fbdiv = rate / PS_PLL_VCO_MAX;
+                       rate = rate / (fbdiv + 1);
+               }
+               if (rate < PS_PLL_VCO_MIN) {
+                       fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
+                       rate = rate * fbdiv;
+               }
+               return rate;
+       }
+
+       fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
+       fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
+       return *prate * fbdiv;
+}
+
+/**
+ * zynqmp_pll_recalc_rate() - Recalculate clock frequency
+ * @hw:                        Handle between common and hardware-specific interfaces
+ * @parent_rate:       Clock frequency of parent clock
+ *
+ * Return: Current clock frequency
+ */
+static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       u32 clk_id = clk->clk_id;
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 fbdiv, data;
+       unsigned long rate, frac;
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_getdivider(clk_id, &fbdiv);
+       if (ret)
+               pr_warn_once("%s() get divider failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       rate =  parent_rate * fbdiv;
+       if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) {
+               eemi_ops->ioctl(0, IOCTL_GET_PLL_FRAC_DATA, clk_id, 0,
+                               ret_payload);
+               data = ret_payload[1];
+               frac = (parent_rate * data) / FRAC_DIV;
+               rate = rate + frac;
+       }
+
+       return rate;
+}
+
+/**
+ * zynqmp_pll_set_rate() - Set rate of PLL
+ * @hw:                        Handle between common and hardware-specific interfaces
+ * @rate:              Frequency of clock to be set
+ * @parent_rate:       Clock frequency of parent clock
+ *
+ * Set PLL divider to set desired rate.
+ *
+ * Returns:            rate which is set on success else error code
+ */
+static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       u32 clk_id = clk->clk_id;
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 fbdiv;
+       long rate_div, frac, m, f;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) {
+               rate_div = (rate * FRAC_DIV) / parent_rate;
+               m = rate_div / FRAC_DIV;
+               f = rate_div % FRAC_DIV;
+               m = clamp_t(u32, m, (PLL_FBDIV_MIN), (PLL_FBDIV_MAX));
+               rate = parent_rate * m;
+               frac = (parent_rate * f) / FRAC_DIV;
+
+               ret = eemi_ops->clock_setdivider(clk_id, m);
+               if (ret)
+                       pr_warn_once("%s() set divider failed for %s, ret = %d\n",
+                                    __func__, clk_name, ret);
+
+               eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_DATA, clk_id, f, NULL);
+
+               return rate + frac;
+       }
+
+       fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate);
+       fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
+       ret = eemi_ops->clock_setdivider(clk_id, fbdiv);
+       if (ret)
+               pr_warn_once("%s() set divider failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return parent_rate * fbdiv;
+}
+
+/**
+ * zynqmp_pll_is_enabled() - Check if a clock is enabled
+ * @hw:                Handle between common and hardware-specific interfaces
+ *
+ * Return: 1 if the clock is enabled, 0 otherwise
+ */
+static int zynqmp_pll_is_enabled(struct clk_hw *hw)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = clk->clk_id;
+       unsigned int state;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       ret = eemi_ops->clock_getstate(clk_id, &state);
+       if (ret) {
+               pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+               return -EIO;
+       }
+
+       return state ? 1 : 0;
+}
+
+/**
+ * zynqmp_pll_enable() - Enable clock
+ * @hw:                Handle between common and hardware-specific interfaces
+ *
+ * Return: 0 on success else error code
+ */
+static int zynqmp_pll_enable(struct clk_hw *hw)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = clk->clk_id;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       if (zynqmp_pll_is_enabled(hw))
+               return 0;
+
+       ret = eemi_ops->clock_enable(clk_id);
+       if (ret)
+               pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+
+       return ret;
+}
+
+/**
+ * zynqmp_pll_disable() - Disable clock
+ * @hw:                Handle between common and hardware-specific interfaces
+ */
+static void zynqmp_pll_disable(struct clk_hw *hw)
+{
+       struct zynqmp_pll *clk = to_zynqmp_pll(hw);
+       const char *clk_name = clk_hw_get_name(hw);
+       u32 clk_id = clk->clk_id;
+       int ret;
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+
+       if (!zynqmp_pll_is_enabled(hw))
+               return;
+
+       ret = eemi_ops->clock_disable(clk_id);
+       if (ret)
+               pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
+                            __func__, clk_name, ret);
+}
+
+static const struct clk_ops zynqmp_pll_ops = {
+       .enable = zynqmp_pll_enable,
+       .disable = zynqmp_pll_disable,
+       .is_enabled = zynqmp_pll_is_enabled,
+       .round_rate = zynqmp_pll_round_rate,
+       .recalc_rate = zynqmp_pll_recalc_rate,
+       .set_rate = zynqmp_pll_set_rate,
+};
+
+/**
+ * zynqmp_clk_register_pll() - Register PLL with the clock framework
+ * @name:              PLL name
+ * @clk_id:            Clock ID
+ * @parents:           Name of this clock's parents
+ * @num_parents:       Number of parents
+ * @nodes:             Clock topology node
+ *
+ * Return: clock hardware to the registered clock
+ */
+struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id,
+                                      const char * const *parents,
+                                      u8 num_parents,
+                                      const struct clock_topology *nodes)
+{
+       struct zynqmp_pll *pll;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+
+       init.name = name;
+       init.ops = &zynqmp_pll_ops;
+       init.flags = nodes->flag;
+       init.parent_names = parents;
+       init.num_parents = 1;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       pll->hw.init = &init;
+       pll->clk_id = clk_id;
+
+       hw = &pll->hw;
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
+               kfree(pll);
+               return ERR_PTR(ret);
+       }
+
+       clk_hw_set_rate_range(hw, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX);
+       if (ret < 0)
+               pr_err("%s:ERROR clk_set_rate_range failed %d\n", name, ret);
+
+       return hw;
+}
index 0cd8eb76ad592b9e3c5531380c6f74e4d539b594..4e1131ef85ae109b7424cbf076d726afd611701a 100644 (file)
@@ -28,20 +28,13 @@ config ARM_ARMADA_37XX_CPUFREQ
 # big LITTLE core layer and glue drivers
 config ARM_BIG_LITTLE_CPUFREQ
        tristate "Generic ARM big LITTLE CPUfreq driver"
-       depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK
+       depends on ARM_CPU_TOPOLOGY && HAVE_CLK
        # if CPU_THERMAL is on and THERMAL=m, ARM_BIT_LITTLE_CPUFREQ cannot be =y
        depends on !CPU_THERMAL || THERMAL
        select PM_OPP
        help
          This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
 
-config ARM_DT_BL_CPUFREQ
-       tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver"
-       depends on ARM_BIG_LITTLE_CPUFREQ && OF
-       help
-         This enables probing via DT for Generic CPUfreq driver for ARM
-         big.LITTLE platform. This gets frequency tables from DT.
-
 config ARM_SCPI_CPUFREQ
        tristate "SCPI based CPUfreq driver"
        depends on ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
index c1ffeabe4ecfaf50cd56bf4981d3274c12f3d08a..d5ee4562ed06b44f17c7b4f149d4fb4d1ecd9683 100644 (file)
@@ -48,9 +48,6 @@ obj-$(CONFIG_X86_SFI_CPUFREQ)         += sfi-cpufreq.o
 ##################################################################################
 # ARM SoC drivers
 obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)   += arm_big_little.o
-# big LITTLE per platform glues. Keep DT_BL_CPUFREQ as the last entry in all big
-# LITTLE drivers, so that it is probed last.
-obj-$(CONFIG_ARM_DT_BL_CPUFREQ)                += arm_big_little_dt.o
 
 obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ)  += armada-37xx-cpufreq.o
 obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)  += brcmstb-avs-cpufreq.o
diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c
deleted file mode 100644 (file)
index b944f29..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Generic big.LITTLE CPUFreq Interface driver
- *
- * It provides necessary ops to arm_big_little cpufreq driver and gets
- * Frequency information from Device Tree. Freq table in DT must be in KHz.
- *
- * Copyright (C) 2013 Linaro.
- * Viresh Kumar <viresh.kumar@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/cpufreq.h>
-#include <linux/device.h>
-#include <linux/export.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/pm_opp.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include "arm_big_little.h"
-
-/* get cpu node with valid operating-points */
-static struct device_node *get_cpu_node_with_valid_op(int cpu)
-{
-       struct device_node *np = of_cpu_device_node_get(cpu);
-
-       if (!of_get_property(np, "operating-points", NULL)) {
-               of_node_put(np);
-               np = NULL;
-       }
-
-       return np;
-}
-
-static int dt_get_transition_latency(struct device *cpu_dev)
-{
-       struct device_node *np;
-       u32 transition_latency = CPUFREQ_ETERNAL;
-
-       np = of_node_get(cpu_dev->of_node);
-       if (!np) {
-               pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n");
-               return CPUFREQ_ETERNAL;
-       }
-
-       of_property_read_u32(np, "clock-latency", &transition_latency);
-       of_node_put(np);
-
-       pr_debug("%s: clock-latency: %d\n", __func__, transition_latency);
-       return transition_latency;
-}
-
-static const struct cpufreq_arm_bL_ops dt_bL_ops = {
-       .name   = "dt-bl",
-       .get_transition_latency = dt_get_transition_latency,
-       .init_opp_table = dev_pm_opp_of_cpumask_add_table,
-       .free_opp_table = dev_pm_opp_of_cpumask_remove_table,
-};
-
-static int generic_bL_probe(struct platform_device *pdev)
-{
-       struct device_node *np;
-
-       np = get_cpu_node_with_valid_op(0);
-       if (!np)
-               return -ENODEV;
-
-       of_node_put(np);
-       return bL_cpufreq_register(&dt_bL_ops);
-}
-
-static int generic_bL_remove(struct platform_device *pdev)
-{
-       bL_cpufreq_unregister(&dt_bL_ops);
-       return 0;
-}
-
-static struct platform_driver generic_bL_platdrv = {
-       .driver = {
-               .name   = "arm-bL-cpufreq-dt",
-       },
-       .probe          = generic_bL_probe,
-       .remove         = generic_bL_remove,
-};
-module_platform_driver(generic_bL_platdrv);
-
-MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
-MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT");
-MODULE_LICENSE("GPL v2");
index 49c0abf2d48f0f3189a7d57585710c2b7514da75..9578312e43f2f1ef5f10327e49225b61897f2a4b 100644 (file)
@@ -386,16 +386,11 @@ static int intel_pstate_get_cppc_guranteed(int cpu)
        return cppc_perf.guaranteed_perf;
 }
 
-#else
+#else /* CONFIG_ACPI_CPPC_LIB */
 static void intel_pstate_set_itmt_prio(int cpu)
 {
 }
-
-static int intel_pstate_get_cppc_guranteed(int cpu)
-{
-       return -ENOTSUPP;
-}
-#endif
+#endif /* CONFIG_ACPI_CPPC_LIB */
 
 static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
 {
@@ -477,7 +472,7 @@ static void intel_pstate_exit_perf_limits(struct cpufreq_policy *policy)
 
        acpi_processor_unregister_performance(policy->cpu);
 }
-#else
+#else /* CONFIG_ACPI */
 static inline void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
 {
 }
@@ -490,7 +485,14 @@ static inline bool intel_pstate_acpi_pm_profile_server(void)
 {
        return false;
 }
-#endif
+#endif /* CONFIG_ACPI */
+
+#ifndef CONFIG_ACPI_CPPC_LIB
+static int intel_pstate_get_cppc_guranteed(int cpu)
+{
+       return -ENOTSUPP;
+}
+#endif /* CONFIG_ACPI_CPPC_LIB */
 
 static inline void update_turbo_state(void)
 {
index 71979605246eebd1f9690c06f089dab31cd05c89..61316fc51548a1c72bcf86e1a2ae54b070491b16 100644 (file)
@@ -130,11 +130,6 @@ struct menu_device {
        int             interval_ptr;
 };
 
-static inline int get_loadavg(unsigned long load)
-{
-       return LOAD_INT(load) * 10 + LOAD_FRAC(load) / 10;
-}
-
 static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters)
 {
        int bucket = 0;
@@ -168,18 +163,10 @@ static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters
  * to be, the higher this multiplier, and thus the higher
  * the barrier to go to an expensive C state.
  */
-static inline int performance_multiplier(unsigned long nr_iowaiters, unsigned long load)
+static inline int performance_multiplier(unsigned long nr_iowaiters)
 {
-       int mult = 1;
-
-       /* for higher loadavg, we are more reluctant */
-
-       mult += 2 * get_loadavg(load);
-
-       /* for IO wait tasks (per cpu!) we add 5x each */
-       mult += 10 * nr_iowaiters;
-
-       return mult;
+       /* for IO wait tasks (per cpu!) we add 10x each */
+       return 1 + 10 * nr_iowaiters;
 }
 
 static DEFINE_PER_CPU(struct menu_device, menu_devices);
@@ -297,7 +284,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
        int idx;
        unsigned int interactivity_req;
        unsigned int predicted_us;
-       unsigned long nr_iowaiters, cpu_load;
+       unsigned long nr_iowaiters;
        ktime_t delta_next;
 
        if (data->needs_update) {
@@ -308,7 +295,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
        /* determine the expected residency time, round up */
        data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length(&delta_next));
 
-       get_iowait_load(&nr_iowaiters, &cpu_load);
+       nr_iowaiters = nr_iowait_cpu(dev->cpu);
        data->bucket = which_bucket(data->next_timer_us, nr_iowaiters);
 
        if (unlikely(drv->state_count <= 1 || latency_req == 0) ||
@@ -352,7 +339,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                 * Use the performance multiplier and the user-configurable
                 * latency_req to determine the maximum exit latency.
                 */
-               interactivity_req = predicted_us / performance_multiplier(nr_iowaiters, cpu_load);
+               interactivity_req = predicted_us / performance_multiplier(nr_iowaiters);
                if (latency_req > interactivity_req)
                        latency_req = interactivity_req;
        }
index 57304b2e989f2ca6ba45fe808cb933240273e7a0..df9467eef32a0e4b67090e56e1a5c0260a0f4037 100644 (file)
@@ -460,4 +460,18 @@ config EDAC_TI
          Support for error detection and correction on the
           TI SoCs.
 
+config EDAC_QCOM
+       tristate "QCOM EDAC Controller"
+       depends on ARCH_QCOM && QCOM_LLCC
+       help
+         Support for error detection and correction on the
+         Qualcomm Technologies, Inc. SoCs.
+
+         This driver reports Single Bit Errors (SBEs) and Double Bit Errors (DBEs).
+         As of now, it supports error reporting for Last Level Cache Controller (LLCC)
+         of Tag RAM and Data RAM.
+
+         For debugging issues having to do with stability and overall system
+         health, you should probably say 'Y' here.
+
 endif # EDAC
index 02b43a7d8c3ee3072863c8560d08eb871962feb7..716096d08ea00c6ee4a304c9adb88ca60752691d 100644 (file)
@@ -77,3 +77,4 @@ obj-$(CONFIG_EDAC_ALTERA)             += altera_edac.o
 obj-$(CONFIG_EDAC_SYNOPSYS)            += synopsys_edac.o
 obj-$(CONFIG_EDAC_XGENE)               += xgene_edac.o
 obj-$(CONFIG_EDAC_TI)                  += ti_edac.o
+obj-$(CONFIG_EDAC_QCOM)                        += qcom_edac.o
diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c
new file mode 100644 (file)
index 0000000..82bd775
--- /dev/null
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/edac.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/soc/qcom/llcc-qcom.h>
+
+#include "edac_mc.h"
+#include "edac_device.h"
+
+#define EDAC_LLCC                       "qcom_llcc"
+
+#define LLCC_ERP_PANIC_ON_UE            1
+
+#define TRP_SYN_REG_CNT                 6
+#define DRP_SYN_REG_CNT                 8
+
+#define LLCC_COMMON_STATUS0             0x0003000c
+#define LLCC_LB_CNT_MASK                GENMASK(31, 28)
+#define LLCC_LB_CNT_SHIFT               28
+
+/* Single & double bit syndrome register offsets */
+#define TRP_ECC_SB_ERR_SYN0             0x0002304c
+#define TRP_ECC_DB_ERR_SYN0             0x00020370
+#define DRP_ECC_SB_ERR_SYN0             0x0004204c
+#define DRP_ECC_DB_ERR_SYN0             0x00042070
+
+/* Error register offsets */
+#define TRP_ECC_ERROR_STATUS1           0x00020348
+#define TRP_ECC_ERROR_STATUS0           0x00020344
+#define DRP_ECC_ERROR_STATUS1           0x00042048
+#define DRP_ECC_ERROR_STATUS0           0x00042044
+
+/* TRP, DRP interrupt register offsets */
+#define DRP_INTERRUPT_STATUS            0x00041000
+#define TRP_INTERRUPT_0_STATUS          0x00020480
+#define DRP_INTERRUPT_CLEAR             0x00041008
+#define DRP_ECC_ERROR_CNTR_CLEAR        0x00040004
+#define TRP_INTERRUPT_0_CLEAR           0x00020484
+#define TRP_ECC_ERROR_CNTR_CLEAR        0x00020440
+
+/* Mask and shift macros */
+#define ECC_DB_ERR_COUNT_MASK           GENMASK(4, 0)
+#define ECC_DB_ERR_WAYS_MASK            GENMASK(31, 16)
+#define ECC_DB_ERR_WAYS_SHIFT           BIT(4)
+
+#define ECC_SB_ERR_COUNT_MASK           GENMASK(23, 16)
+#define ECC_SB_ERR_COUNT_SHIFT          BIT(4)
+#define ECC_SB_ERR_WAYS_MASK            GENMASK(15, 0)
+
+#define SB_ECC_ERROR                    BIT(0)
+#define DB_ECC_ERROR                    BIT(1)
+
+#define DRP_TRP_INT_CLEAR               GENMASK(1, 0)
+#define DRP_TRP_CNT_CLEAR               GENMASK(1, 0)
+
+/* Config registers offsets*/
+#define DRP_ECC_ERROR_CFG               0x00040000
+
+/* Tag RAM, Data RAM interrupt register offsets */
+#define CMN_INTERRUPT_0_ENABLE          0x0003001c
+#define CMN_INTERRUPT_2_ENABLE          0x0003003c
+#define TRP_INTERRUPT_0_ENABLE          0x00020488
+#define DRP_INTERRUPT_ENABLE            0x0004100c
+
+#define SB_ERROR_THRESHOLD              0x1
+#define SB_ERROR_THRESHOLD_SHIFT        24
+#define SB_DB_TRP_INTERRUPT_ENABLE      0x3
+#define TRP0_INTERRUPT_ENABLE           0x1
+#define DRP0_INTERRUPT_ENABLE           BIT(6)
+#define SB_DB_DRP_INTERRUPT_ENABLE      0x3
+
+enum {
+       LLCC_DRAM_CE = 0,
+       LLCC_DRAM_UE,
+       LLCC_TRAM_CE,
+       LLCC_TRAM_UE,
+};
+
+static const struct llcc_edac_reg_data edac_reg_data[] = {
+       [LLCC_DRAM_CE] = {
+               .name = "DRAM Single-bit",
+               .synd_reg = DRP_ECC_SB_ERR_SYN0,
+               .count_status_reg = DRP_ECC_ERROR_STATUS1,
+               .ways_status_reg = DRP_ECC_ERROR_STATUS0,
+               .reg_cnt = DRP_SYN_REG_CNT,
+               .count_mask = ECC_SB_ERR_COUNT_MASK,
+               .ways_mask = ECC_SB_ERR_WAYS_MASK,
+               .count_shift = ECC_SB_ERR_COUNT_SHIFT,
+       },
+       [LLCC_DRAM_UE] = {
+               .name = "DRAM Double-bit",
+               .synd_reg = DRP_ECC_DB_ERR_SYN0,
+               .count_status_reg = DRP_ECC_ERROR_STATUS1,
+               .ways_status_reg = DRP_ECC_ERROR_STATUS0,
+               .reg_cnt = DRP_SYN_REG_CNT,
+               .count_mask = ECC_DB_ERR_COUNT_MASK,
+               .ways_mask = ECC_DB_ERR_WAYS_MASK,
+               .ways_shift = ECC_DB_ERR_WAYS_SHIFT,
+       },
+       [LLCC_TRAM_CE] = {
+               .name = "TRAM Single-bit",
+               .synd_reg = TRP_ECC_SB_ERR_SYN0,
+               .count_status_reg = TRP_ECC_ERROR_STATUS1,
+               .ways_status_reg = TRP_ECC_ERROR_STATUS0,
+               .reg_cnt = TRP_SYN_REG_CNT,
+               .count_mask = ECC_SB_ERR_COUNT_MASK,
+               .ways_mask = ECC_SB_ERR_WAYS_MASK,
+               .count_shift = ECC_SB_ERR_COUNT_SHIFT,
+       },
+       [LLCC_TRAM_UE] = {
+               .name = "TRAM Double-bit",
+               .synd_reg = TRP_ECC_DB_ERR_SYN0,
+               .count_status_reg = TRP_ECC_ERROR_STATUS1,
+               .ways_status_reg = TRP_ECC_ERROR_STATUS0,
+               .reg_cnt = TRP_SYN_REG_CNT,
+               .count_mask = ECC_DB_ERR_COUNT_MASK,
+               .ways_mask = ECC_DB_ERR_WAYS_MASK,
+               .ways_shift = ECC_DB_ERR_WAYS_SHIFT,
+       },
+};
+
+static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap)
+{
+       u32 sb_err_threshold;
+       int ret;
+
+       /*
+        * Configure interrupt enable registers such that Tag, Data RAM related
+        * interrupts are propagated to interrupt controller for servicing
+        */
+       ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE,
+                                TRP0_INTERRUPT_ENABLE,
+                                TRP0_INTERRUPT_ENABLE);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(llcc_bcast_regmap, TRP_INTERRUPT_0_ENABLE,
+                                SB_DB_TRP_INTERRUPT_ENABLE,
+                                SB_DB_TRP_INTERRUPT_ENABLE);
+       if (ret)
+               return ret;
+
+       sb_err_threshold = (SB_ERROR_THRESHOLD << SB_ERROR_THRESHOLD_SHIFT);
+       ret = regmap_write(llcc_bcast_regmap, DRP_ECC_ERROR_CFG,
+                          sb_err_threshold);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE,
+                                DRP0_INTERRUPT_ENABLE,
+                                DRP0_INTERRUPT_ENABLE);
+       if (ret)
+               return ret;
+
+       ret = regmap_write(llcc_bcast_regmap, DRP_INTERRUPT_ENABLE,
+                          SB_DB_DRP_INTERRUPT_ENABLE);
+       return ret;
+}
+
+/* Clear the error interrupt and counter registers */
+static int
+qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv)
+{
+       int ret = 0;
+
+       switch (err_type) {
+       case LLCC_DRAM_CE:
+       case LLCC_DRAM_UE:
+               ret = regmap_write(drv->bcast_regmap, DRP_INTERRUPT_CLEAR,
+                                  DRP_TRP_INT_CLEAR);
+               if (ret)
+                       return ret;
+
+               ret = regmap_write(drv->bcast_regmap, DRP_ECC_ERROR_CNTR_CLEAR,
+                                  DRP_TRP_CNT_CLEAR);
+               if (ret)
+                       return ret;
+               break;
+       case LLCC_TRAM_CE:
+       case LLCC_TRAM_UE:
+               ret = regmap_write(drv->bcast_regmap, TRP_INTERRUPT_0_CLEAR,
+                                  DRP_TRP_INT_CLEAR);
+               if (ret)
+                       return ret;
+
+               ret = regmap_write(drv->bcast_regmap, TRP_ECC_ERROR_CNTR_CLEAR,
+                                  DRP_TRP_CNT_CLEAR);
+               if (ret)
+                       return ret;
+               break;
+       default:
+               ret = -EINVAL;
+               edac_printk(KERN_CRIT, EDAC_LLCC, "Unexpected error type: %d\n",
+                           err_type);
+       }
+       return ret;
+}
+
+/* Dump Syndrome registers data for Tag RAM, Data RAM bit errors*/
+static int
+dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
+{
+       struct llcc_edac_reg_data reg_data = edac_reg_data[err_type];
+       int err_cnt, err_ways, ret, i;
+       u32 synd_reg, synd_val;
+
+       for (i = 0; i < reg_data.reg_cnt; i++) {
+               synd_reg = reg_data.synd_reg + (i * 4);
+               ret = regmap_read(drv->regmap, drv->offsets[bank] + synd_reg,
+                                 &synd_val);
+               if (ret)
+                       goto clear;
+
+               edac_printk(KERN_CRIT, EDAC_LLCC, "%s: ECC_SYN%d: 0x%8x\n",
+                           reg_data.name, i, synd_val);
+       }
+
+       ret = regmap_read(drv->regmap,
+                         drv->offsets[bank] + reg_data.count_status_reg,
+                         &err_cnt);
+       if (ret)
+               goto clear;
+
+       err_cnt &= reg_data.count_mask;
+       err_cnt >>= reg_data.count_shift;
+       edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error count: 0x%4x\n",
+                   reg_data.name, err_cnt);
+
+       ret = regmap_read(drv->regmap,
+                         drv->offsets[bank] + reg_data.ways_status_reg,
+                         &err_ways);
+       if (ret)
+               goto clear;
+
+       err_ways &= reg_data.ways_mask;
+       err_ways >>= reg_data.ways_shift;
+
+       edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error ways: 0x%4x\n",
+                   reg_data.name, err_ways);
+
+clear:
+       return qcom_llcc_clear_error_status(err_type, drv);
+}
+
+static int
+dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank)
+{
+       struct llcc_drv_data *drv = edev_ctl->pvt_info;
+       int ret;
+
+       ret = dump_syn_reg_values(drv, bank, err_type);
+       if (ret)
+               return ret;
+
+       switch (err_type) {
+       case LLCC_DRAM_CE:
+               edac_device_handle_ce(edev_ctl, 0, bank,
+                                     "LLCC Data RAM correctable Error");
+               break;
+       case LLCC_DRAM_UE:
+               edac_device_handle_ue(edev_ctl, 0, bank,
+                                     "LLCC Data RAM uncorrectable Error");
+               break;
+       case LLCC_TRAM_CE:
+               edac_device_handle_ce(edev_ctl, 0, bank,
+                                     "LLCC Tag RAM correctable Error");
+               break;
+       case LLCC_TRAM_UE:
+               edac_device_handle_ue(edev_ctl, 0, bank,
+                                     "LLCC Tag RAM uncorrectable Error");
+               break;
+       default:
+               ret = -EINVAL;
+               edac_printk(KERN_CRIT, EDAC_LLCC, "Unexpected error type: %d\n",
+                           err_type);
+       }
+
+       return ret;
+}
+
+static irqreturn_t
+llcc_ecc_irq_handler(int irq, void *edev_ctl)
+{
+       struct edac_device_ctl_info *edac_dev_ctl = edev_ctl;
+       struct llcc_drv_data *drv = edac_dev_ctl->pvt_info;
+       irqreturn_t irq_rc = IRQ_NONE;
+       u32 drp_error, trp_error, i;
+       bool irq_handled;
+       int ret;
+
+       /* Iterate over the banks and look for Tag RAM or Data RAM errors */
+       for (i = 0; i < drv->num_banks; i++) {
+               ret = regmap_read(drv->regmap,
+                                 drv->offsets[i] + DRP_INTERRUPT_STATUS,
+                                 &drp_error);
+
+               if (!ret && (drp_error & SB_ECC_ERROR)) {
+                       edac_printk(KERN_CRIT, EDAC_LLCC,
+                                   "Single Bit Error detected in Data RAM\n");
+                       ret = dump_syn_reg(edev_ctl, LLCC_DRAM_CE, i);
+               } else if (!ret && (drp_error & DB_ECC_ERROR)) {
+                       edac_printk(KERN_CRIT, EDAC_LLCC,
+                                   "Double Bit Error detected in Data RAM\n");
+                       ret = dump_syn_reg(edev_ctl, LLCC_DRAM_UE, i);
+               }
+               if (!ret)
+                       irq_handled = true;
+
+               ret = regmap_read(drv->regmap,
+                                 drv->offsets[i] + TRP_INTERRUPT_0_STATUS,
+                                 &trp_error);
+
+               if (!ret && (trp_error & SB_ECC_ERROR)) {
+                       edac_printk(KERN_CRIT, EDAC_LLCC,
+                                   "Single Bit Error detected in Tag RAM\n");
+                       ret = dump_syn_reg(edev_ctl, LLCC_TRAM_CE, i);
+               } else if (!ret && (trp_error & DB_ECC_ERROR)) {
+                       edac_printk(KERN_CRIT, EDAC_LLCC,
+                                   "Double Bit Error detected in Tag RAM\n");
+                       ret = dump_syn_reg(edev_ctl, LLCC_TRAM_UE, i);
+               }
+               if (!ret)
+                       irq_handled = true;
+       }
+
+       if (irq_handled)
+               irq_rc = IRQ_HANDLED;
+
+       return irq_rc;
+}
+
+static int qcom_llcc_edac_probe(struct platform_device *pdev)
+{
+       struct llcc_drv_data *llcc_driv_data = pdev->dev.platform_data;
+       struct edac_device_ctl_info *edev_ctl;
+       struct device *dev = &pdev->dev;
+       int ecc_irq;
+       int rc;
+
+       rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap);
+       if (rc)
+               return rc;
+
+       /* Allocate edac control info */
+       edev_ctl = edac_device_alloc_ctl_info(0, "qcom-llcc", 1, "bank",
+                                             llcc_driv_data->num_banks, 1,
+                                             NULL, 0,
+                                             edac_device_alloc_index());
+
+       if (!edev_ctl)
+               return -ENOMEM;
+
+       edev_ctl->dev = dev;
+       edev_ctl->mod_name = dev_name(dev);
+       edev_ctl->dev_name = dev_name(dev);
+       edev_ctl->ctl_name = "llcc";
+       edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
+       edev_ctl->pvt_info = llcc_driv_data;
+
+       rc = edac_device_add_device(edev_ctl);
+       if (rc)
+               goto out_mem;
+
+       platform_set_drvdata(pdev, edev_ctl);
+
+       /* Request for ecc irq */
+       ecc_irq = llcc_driv_data->ecc_irq;
+       if (ecc_irq < 0) {
+               rc = -ENODEV;
+               goto out_dev;
+       }
+       rc = devm_request_irq(dev, ecc_irq, llcc_ecc_irq_handler,
+                             IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl);
+       if (rc)
+               goto out_dev;
+
+       return rc;
+
+out_dev:
+       edac_device_del_device(edev_ctl->dev);
+out_mem:
+       edac_device_free_ctl_info(edev_ctl);
+
+       return rc;
+}
+
+static int qcom_llcc_edac_remove(struct platform_device *pdev)
+{
+       struct edac_device_ctl_info *edev_ctl = dev_get_drvdata(&pdev->dev);
+
+       edac_device_del_device(edev_ctl->dev);
+       edac_device_free_ctl_info(edev_ctl);
+
+       return 0;
+}
+
+static struct platform_driver qcom_llcc_edac_driver = {
+       .probe = qcom_llcc_edac_probe,
+       .remove = qcom_llcc_edac_remove,
+       .driver = {
+               .name = "qcom_llcc_edac",
+       },
+};
+module_platform_driver(qcom_llcc_edac_driver);
+
+MODULE_DESCRIPTION("QCOM EDAC driver");
+MODULE_LICENSE("GPL v2");
index 6e83880046d787d978cddaa1fcf2c5b930843186..7273e5082b4175be3601e28775506ce8b5ee89d9 100644 (file)
@@ -145,34 +145,6 @@ config EFI_PCDP
          See DIG64_HCDPv20_042804.pdf available from
          <http://www.dig64.org/specifications/> 
 
-config DELL_RBU
-       tristate "BIOS update support for DELL systems via sysfs"
-       depends on X86
-       select FW_LOADER
-       select FW_LOADER_USER_HELPER
-       help
-        Say m if you want to have the option of updating the BIOS for your
-        DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
-        supporting application to communicate with the BIOS regarding the new
-        image for the image update to take effect.
-        See <file:Documentation/dell_rbu.txt> for more details on the driver.
-
-config DCDBAS
-       tristate "Dell Systems Management Base Driver"
-       depends on X86
-       help
-         The Dell Systems Management Base Driver provides a sysfs interface
-         for systems management software to perform System Management
-         Interrupts (SMIs) and Host Control Actions (system power cycle or
-         power off after OS shutdown) on certain Dell systems.
-
-         See <file:Documentation/dcdbas.txt> for more details on the driver
-         and the Dell systems on which Dell systems management software makes
-         use of this driver.
-
-         Say Y or M here to enable the driver for use by Dell systems
-         management software such as Dell OpenManage.
-
 config DMIID
     bool "Export DMI identification via sysfs to userspace"
     depends on DMI
@@ -289,7 +261,9 @@ config HAVE_ARM_SMCCC
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
+source "drivers/firmware/imx/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/tegra/Kconfig"
+source "drivers/firmware/xilinx/Kconfig"
 
 endmenu
index e18a041cfc53b738f5b4e22433e6055de41d8cc7..3158dffd9914e6afd44a51caf7acfd688c8984b3 100644 (file)
@@ -11,8 +11,6 @@ obj-$(CONFIG_DMI)             += dmi_scan.o
 obj-$(CONFIG_DMI_SYSFS)                += dmi-sysfs.o
 obj-$(CONFIG_EDD)              += edd.o
 obj-$(CONFIG_EFI_PCDP)         += pcdp.o
-obj-$(CONFIG_DELL_RBU)          += dell_rbu.o
-obj-$(CONFIG_DCDBAS)           += dcdbas.o
 obj-$(CONFIG_DMIID)            += dmi-id.o
 obj-$(CONFIG_ISCSI_IBFT_FIND)  += iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)       += iscsi_ibft.o
@@ -31,4 +29,6 @@ obj-y                         += meson/
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
 obj-$(CONFIG_EFI)              += efi/
 obj-$(CONFIG_UEFI_CPER)                += efi/
+obj-y                          += imx/
 obj-y                          += tegra/
+obj-y                          += xilinx/
index 9dff33ea6416f66879ea4de32e8dba6a22e37c01..204390297f4bd4e249a6f3987e992ff1eb2b7d56 100644 (file)
@@ -208,7 +208,7 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
 
        ret = scmi_do_xfer(handle, t);
        if (!ret)
-               memcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE);
+               strlcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE);
 
        scmi_xfer_put(handle, t);
 
index e4119eb34986cb5219b648d1b900a23c8686329b..30fc04e284312e9f19c165994dad1170966304b8 100644 (file)
@@ -111,7 +111,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle,
 
        ret = scmi_do_xfer(handle, t);
        if (!ret)
-               memcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
+               strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
        else
                clk->name[0] = '\0';
 
index 64342944d9175c54918100c36f0b43a20e6acae3..3c8ae7cc35de3cf1b10cb452adbd8f0282b39a27 100644 (file)
@@ -174,7 +174,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
                        dom_info->mult_factor =
                                        (dom_info->sustained_freq_khz * 1000) /
                                        dom_info->sustained_perf_level;
-               memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
+               strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
        }
 
        scmi_xfer_put(handle, t);
@@ -427,6 +427,33 @@ static int scmi_dvfs_freq_get(const struct scmi_handle *handle, u32 domain,
        return ret;
 }
 
+static int scmi_dvfs_est_power_get(const struct scmi_handle *handle, u32 domain,
+                                  unsigned long *freq, unsigned long *power)
+{
+       struct scmi_perf_info *pi = handle->perf_priv;
+       struct perf_dom_info *dom;
+       unsigned long opp_freq;
+       int idx, ret = -EINVAL;
+       struct scmi_opp *opp;
+
+       dom = pi->dom_info + domain;
+       if (!dom)
+               return -EIO;
+
+       for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) {
+               opp_freq = opp->perf * dom->mult_factor;
+               if (opp_freq < *freq)
+                       continue;
+
+               *freq = opp_freq;
+               *power = opp->power;
+               ret = 0;
+               break;
+       }
+
+       return ret;
+}
+
 static struct scmi_perf_ops perf_ops = {
        .limits_set = scmi_perf_limits_set,
        .limits_get = scmi_perf_limits_get,
@@ -437,6 +464,7 @@ static struct scmi_perf_ops perf_ops = {
        .device_opps_add = scmi_dvfs_device_opps_add,
        .freq_set = scmi_dvfs_freq_set,
        .freq_get = scmi_dvfs_freq_get,
+       .est_power_get = scmi_dvfs_est_power_get,
 };
 
 static int scmi_perf_protocol_init(struct scmi_handle *handle)
index cfa033b05aed5e568b2510e2a7dace5162d13327..62f3401a1f01e90d9ddceabbe462416471d67614 100644 (file)
@@ -106,7 +106,7 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
                dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags);
                dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags);
                dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags);
-               memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
+               strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
        }
 
        scmi_xfer_put(handle, t);
index 27f2092b9882aef307763e214eb74c69f4db2af5..b53d5cc9c9f6c57ebae04f6a43e42fb814fc27d9 100644 (file)
@@ -140,7 +140,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
                        s = &si->sensors[desc_index + cnt];
                        s->id = le32_to_cpu(buf->desc[cnt].id);
                        s->type = SENSOR_TYPE(attrh);
-                       memcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE);
+                       strlcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE);
                }
 
                desc_index += num_returned;
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
deleted file mode 100644 (file)
index 0bdea60..0000000
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- *  dcdbas.c: Dell Systems Management Base Driver
- *
- *  The Dell Systems Management Base Driver provides a sysfs interface for
- *  systems management software to perform System Management Interrupts (SMIs)
- *  and Host Control Actions (power cycle or power off after OS shutdown) on
- *  Dell systems.
- *
- *  See Documentation/dcdbas.txt for more information.
- *
- *  Copyright (C) 1995-2006 Dell Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License v2.0 as published by
- *  the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/cpu.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/mc146818rtc.h>
-#include <linux/module.h>
-#include <linux/reboot.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include <asm/io.h>
-
-#include "dcdbas.h"
-
-#define DRIVER_NAME            "dcdbas"
-#define DRIVER_VERSION         "5.6.0-3.2"
-#define DRIVER_DESCRIPTION     "Dell Systems Management Base Driver"
-
-static struct platform_device *dcdbas_pdev;
-
-static u8 *smi_data_buf;
-static dma_addr_t smi_data_buf_handle;
-static unsigned long smi_data_buf_size;
-static u32 smi_data_buf_phys_addr;
-static DEFINE_MUTEX(smi_data_lock);
-
-static unsigned int host_control_action;
-static unsigned int host_control_smi_type;
-static unsigned int host_control_on_shutdown;
-
-/**
- * smi_data_buf_free: free SMI data buffer
- */
-static void smi_data_buf_free(void)
-{
-       if (!smi_data_buf)
-               return;
-
-       dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
-               __func__, smi_data_buf_phys_addr, smi_data_buf_size);
-
-       dma_free_coherent(&dcdbas_pdev->dev, smi_data_buf_size, smi_data_buf,
-                         smi_data_buf_handle);
-       smi_data_buf = NULL;
-       smi_data_buf_handle = 0;
-       smi_data_buf_phys_addr = 0;
-       smi_data_buf_size = 0;
-}
-
-/**
- * smi_data_buf_realloc: grow SMI data buffer if needed
- */
-static int smi_data_buf_realloc(unsigned long size)
-{
-       void *buf;
-       dma_addr_t handle;
-
-       if (smi_data_buf_size >= size)
-               return 0;
-
-       if (size > MAX_SMI_DATA_BUF_SIZE)
-               return -EINVAL;
-
-       /* new buffer is needed */
-       buf = dma_alloc_coherent(&dcdbas_pdev->dev, size, &handle, GFP_KERNEL);
-       if (!buf) {
-               dev_dbg(&dcdbas_pdev->dev,
-                       "%s: failed to allocate memory size %lu\n",
-                       __func__, size);
-               return -ENOMEM;
-       }
-       /* memory zeroed by dma_alloc_coherent */
-
-       if (smi_data_buf)
-               memcpy(buf, smi_data_buf, smi_data_buf_size);
-
-       /* free any existing buffer */
-       smi_data_buf_free();
-
-       /* set up new buffer for use */
-       smi_data_buf = buf;
-       smi_data_buf_handle = handle;
-       smi_data_buf_phys_addr = (u32) virt_to_phys(buf);
-       smi_data_buf_size = size;
-
-       dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
-               __func__, smi_data_buf_phys_addr, smi_data_buf_size);
-
-       return 0;
-}
-
-static ssize_t smi_data_buf_phys_addr_show(struct device *dev,
-                                          struct device_attribute *attr,
-                                          char *buf)
-{
-       return sprintf(buf, "%x\n", smi_data_buf_phys_addr);
-}
-
-static ssize_t smi_data_buf_size_show(struct device *dev,
-                                     struct device_attribute *attr,
-                                     char *buf)
-{
-       return sprintf(buf, "%lu\n", smi_data_buf_size);
-}
-
-static ssize_t smi_data_buf_size_store(struct device *dev,
-                                      struct device_attribute *attr,
-                                      const char *buf, size_t count)
-{
-       unsigned long buf_size;
-       ssize_t ret;
-
-       buf_size = simple_strtoul(buf, NULL, 10);
-
-       /* make sure SMI data buffer is at least buf_size */
-       mutex_lock(&smi_data_lock);
-       ret = smi_data_buf_realloc(buf_size);
-       mutex_unlock(&smi_data_lock);
-       if (ret)
-               return ret;
-
-       return count;
-}
-
-static ssize_t smi_data_read(struct file *filp, struct kobject *kobj,
-                            struct bin_attribute *bin_attr,
-                            char *buf, loff_t pos, size_t count)
-{
-       ssize_t ret;
-
-       mutex_lock(&smi_data_lock);
-       ret = memory_read_from_buffer(buf, count, &pos, smi_data_buf,
-                                       smi_data_buf_size);
-       mutex_unlock(&smi_data_lock);
-       return ret;
-}
-
-static ssize_t smi_data_write(struct file *filp, struct kobject *kobj,
-                             struct bin_attribute *bin_attr,
-                             char *buf, loff_t pos, size_t count)
-{
-       ssize_t ret;
-
-       if ((pos + count) > MAX_SMI_DATA_BUF_SIZE)
-               return -EINVAL;
-
-       mutex_lock(&smi_data_lock);
-
-       ret = smi_data_buf_realloc(pos + count);
-       if (ret)
-               goto out;
-
-       memcpy(smi_data_buf + pos, buf, count);
-       ret = count;
-out:
-       mutex_unlock(&smi_data_lock);
-       return ret;
-}
-
-static ssize_t host_control_action_show(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       return sprintf(buf, "%u\n", host_control_action);
-}
-
-static ssize_t host_control_action_store(struct device *dev,
-                                        struct device_attribute *attr,
-                                        const char *buf, size_t count)
-{
-       ssize_t ret;
-
-       /* make sure buffer is available for host control command */
-       mutex_lock(&smi_data_lock);
-       ret = smi_data_buf_realloc(sizeof(struct apm_cmd));
-       mutex_unlock(&smi_data_lock);
-       if (ret)
-               return ret;
-
-       host_control_action = simple_strtoul(buf, NULL, 10);
-       return count;
-}
-
-static ssize_t host_control_smi_type_show(struct device *dev,
-                                         struct device_attribute *attr,
-                                         char *buf)
-{
-       return sprintf(buf, "%u\n", host_control_smi_type);
-}
-
-static ssize_t host_control_smi_type_store(struct device *dev,
-                                          struct device_attribute *attr,
-                                          const char *buf, size_t count)
-{
-       host_control_smi_type = simple_strtoul(buf, NULL, 10);
-       return count;
-}
-
-static ssize_t host_control_on_shutdown_show(struct device *dev,
-                                            struct device_attribute *attr,
-                                            char *buf)
-{
-       return sprintf(buf, "%u\n", host_control_on_shutdown);
-}
-
-static ssize_t host_control_on_shutdown_store(struct device *dev,
-                                             struct device_attribute *attr,
-                                             const char *buf, size_t count)
-{
-       host_control_on_shutdown = simple_strtoul(buf, NULL, 10);
-       return count;
-}
-
-static int raise_smi(void *par)
-{
-       struct smi_cmd *smi_cmd = par;
-
-       if (smp_processor_id() != 0) {
-               dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
-                       __func__);
-               return -EBUSY;
-       }
-
-       /* generate SMI */
-       /* inb to force posted write through and make SMI happen now */
-       asm volatile (
-               "outb %b0,%w1\n"
-               "inb %w1"
-               : /* no output args */
-               : "a" (smi_cmd->command_code),
-                 "d" (smi_cmd->command_address),
-                 "b" (smi_cmd->ebx),
-                 "c" (smi_cmd->ecx)
-               : "memory"
-       );
-
-       return 0;
-}
-/**
- * dcdbas_smi_request: generate SMI request
- *
- * Called with smi_data_lock.
- */
-int dcdbas_smi_request(struct smi_cmd *smi_cmd)
-{
-       int ret;
-
-       if (smi_cmd->magic != SMI_CMD_MAGIC) {
-               dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n",
-                        __func__);
-               return -EBADR;
-       }
-
-       /* SMI requires CPU 0 */
-       get_online_cpus();
-       ret = smp_call_on_cpu(0, raise_smi, smi_cmd, true);
-       put_online_cpus();
-
-       return ret;
-}
-
-/**
- * smi_request_store:
- *
- * The valid values are:
- * 0: zero SMI data buffer
- * 1: generate calling interface SMI
- * 2: generate raw SMI
- *
- * User application writes smi_cmd to smi_data before telling driver
- * to generate SMI.
- */
-static ssize_t smi_request_store(struct device *dev,
-                                struct device_attribute *attr,
-                                const char *buf, size_t count)
-{
-       struct smi_cmd *smi_cmd;
-       unsigned long val = simple_strtoul(buf, NULL, 10);
-       ssize_t ret;
-
-       mutex_lock(&smi_data_lock);
-
-       if (smi_data_buf_size < sizeof(struct smi_cmd)) {
-               ret = -ENODEV;
-               goto out;
-       }
-       smi_cmd = (struct smi_cmd *)smi_data_buf;
-
-       switch (val) {
-       case 2:
-               /* Raw SMI */
-               ret = dcdbas_smi_request(smi_cmd);
-               if (!ret)
-                       ret = count;
-               break;
-       case 1:
-               /* Calling Interface SMI */
-               smi_cmd->ebx = (u32) virt_to_phys(smi_cmd->command_buffer);
-               ret = dcdbas_smi_request(smi_cmd);
-               if (!ret)
-                       ret = count;
-               break;
-       case 0:
-               memset(smi_data_buf, 0, smi_data_buf_size);
-               ret = count;
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-
-out:
-       mutex_unlock(&smi_data_lock);
-       return ret;
-}
-EXPORT_SYMBOL(dcdbas_smi_request);
-
-/**
- * host_control_smi: generate host control SMI
- *
- * Caller must set up the host control command in smi_data_buf.
- */
-static int host_control_smi(void)
-{
-       struct apm_cmd *apm_cmd;
-       u8 *data;
-       unsigned long flags;
-       u32 num_ticks;
-       s8 cmd_status;
-       u8 index;
-
-       apm_cmd = (struct apm_cmd *)smi_data_buf;
-       apm_cmd->status = ESM_STATUS_CMD_UNSUCCESSFUL;
-
-       switch (host_control_smi_type) {
-       case HC_SMITYPE_TYPE1:
-               spin_lock_irqsave(&rtc_lock, flags);
-               /* write SMI data buffer physical address */
-               data = (u8 *)&smi_data_buf_phys_addr;
-               for (index = PE1300_CMOS_CMD_STRUCT_PTR;
-                    index < (PE1300_CMOS_CMD_STRUCT_PTR + 4);
-                    index++, data++) {
-                       outb(index,
-                            (CMOS_BASE_PORT + CMOS_PAGE2_INDEX_PORT_PIIX4));
-                       outb(*data,
-                            (CMOS_BASE_PORT + CMOS_PAGE2_DATA_PORT_PIIX4));
-               }
-
-               /* first set status to -1 as called by spec */
-               cmd_status = ESM_STATUS_CMD_UNSUCCESSFUL;
-               outb((u8) cmd_status, PCAT_APM_STATUS_PORT);
-
-               /* generate SMM call */
-               outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
-               spin_unlock_irqrestore(&rtc_lock, flags);
-
-               /* wait a few to see if it executed */
-               num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
-               while ((cmd_status = inb(PCAT_APM_STATUS_PORT))
-                      == ESM_STATUS_CMD_UNSUCCESSFUL) {
-                       num_ticks--;
-                       if (num_ticks == EXPIRED_TIMER)
-                               return -ETIME;
-               }
-               break;
-
-       case HC_SMITYPE_TYPE2:
-       case HC_SMITYPE_TYPE3:
-               spin_lock_irqsave(&rtc_lock, flags);
-               /* write SMI data buffer physical address */
-               data = (u8 *)&smi_data_buf_phys_addr;
-               for (index = PE1400_CMOS_CMD_STRUCT_PTR;
-                    index < (PE1400_CMOS_CMD_STRUCT_PTR + 4);
-                    index++, data++) {
-                       outb(index, (CMOS_BASE_PORT + CMOS_PAGE1_INDEX_PORT));
-                       outb(*data, (CMOS_BASE_PORT + CMOS_PAGE1_DATA_PORT));
-               }
-
-               /* generate SMM call */
-               if (host_control_smi_type == HC_SMITYPE_TYPE3)
-                       outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
-               else
-                       outb(ESM_APM_CMD, PE1400_APM_CONTROL_PORT);
-
-               /* restore RTC index pointer since it was written to above */
-               CMOS_READ(RTC_REG_C);
-               spin_unlock_irqrestore(&rtc_lock, flags);
-
-               /* read control port back to serialize write */
-               cmd_status = inb(PE1400_APM_CONTROL_PORT);
-
-               /* wait a few to see if it executed */
-               num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
-               while (apm_cmd->status == ESM_STATUS_CMD_UNSUCCESSFUL) {
-                       num_ticks--;
-                       if (num_ticks == EXPIRED_TIMER)
-                               return -ETIME;
-               }
-               break;
-
-       default:
-               dev_dbg(&dcdbas_pdev->dev, "%s: invalid SMI type %u\n",
-                       __func__, host_control_smi_type);
-               return -ENOSYS;
-       }
-
-       return 0;
-}
-
-/**
- * dcdbas_host_control: initiate host control
- *
- * This function is called by the driver after the system has
- * finished shutting down if the user application specified a
- * host control action to perform on shutdown.  It is safe to
- * use smi_data_buf at this point because the system has finished
- * shutting down and no userspace apps are running.
- */
-static void dcdbas_host_control(void)
-{
-       struct apm_cmd *apm_cmd;
-       u8 action;
-
-       if (host_control_action == HC_ACTION_NONE)
-               return;
-
-       action = host_control_action;
-       host_control_action = HC_ACTION_NONE;
-
-       if (!smi_data_buf) {
-               dev_dbg(&dcdbas_pdev->dev, "%s: no SMI buffer\n", __func__);
-               return;
-       }
-
-       if (smi_data_buf_size < sizeof(struct apm_cmd)) {
-               dev_dbg(&dcdbas_pdev->dev, "%s: SMI buffer too small\n",
-                       __func__);
-               return;
-       }
-
-       apm_cmd = (struct apm_cmd *)smi_data_buf;
-
-       /* power off takes precedence */
-       if (action & HC_ACTION_HOST_CONTROL_POWEROFF) {
-               apm_cmd->command = ESM_APM_POWER_CYCLE;
-               apm_cmd->reserved = 0;
-               *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 0;
-               host_control_smi();
-       } else if (action & HC_ACTION_HOST_CONTROL_POWERCYCLE) {
-               apm_cmd->command = ESM_APM_POWER_CYCLE;
-               apm_cmd->reserved = 0;
-               *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 20;
-               host_control_smi();
-       }
-}
-
-/**
- * dcdbas_reboot_notify: handle reboot notification for host control
- */
-static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code,
-                               void *unused)
-{
-       switch (code) {
-       case SYS_DOWN:
-       case SYS_HALT:
-       case SYS_POWER_OFF:
-               if (host_control_on_shutdown) {
-                       /* firmware is going to perform host control action */
-                       printk(KERN_WARNING "Please wait for shutdown "
-                              "action to complete...\n");
-                       dcdbas_host_control();
-               }
-               break;
-       }
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block dcdbas_reboot_nb = {
-       .notifier_call = dcdbas_reboot_notify,
-       .next = NULL,
-       .priority = INT_MIN
-};
-
-static DCDBAS_BIN_ATTR_RW(smi_data);
-
-static struct bin_attribute *dcdbas_bin_attrs[] = {
-       &bin_attr_smi_data,
-       NULL
-};
-
-static DCDBAS_DEV_ATTR_RW(smi_data_buf_size);
-static DCDBAS_DEV_ATTR_RO(smi_data_buf_phys_addr);
-static DCDBAS_DEV_ATTR_WO(smi_request);
-static DCDBAS_DEV_ATTR_RW(host_control_action);
-static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
-static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);
-
-static struct attribute *dcdbas_dev_attrs[] = {
-       &dev_attr_smi_data_buf_size.attr,
-       &dev_attr_smi_data_buf_phys_addr.attr,
-       &dev_attr_smi_request.attr,
-       &dev_attr_host_control_action.attr,
-       &dev_attr_host_control_smi_type.attr,
-       &dev_attr_host_control_on_shutdown.attr,
-       NULL
-};
-
-static const struct attribute_group dcdbas_attr_group = {
-       .attrs = dcdbas_dev_attrs,
-       .bin_attrs = dcdbas_bin_attrs,
-};
-
-static int dcdbas_probe(struct platform_device *dev)
-{
-       int error;
-
-       host_control_action = HC_ACTION_NONE;
-       host_control_smi_type = HC_SMITYPE_NONE;
-
-       dcdbas_pdev = dev;
-
-       /*
-        * BIOS SMI calls require buffer addresses be in 32-bit address space.
-        * This is done by setting the DMA mask below.
-        */
-       error = dma_set_coherent_mask(&dcdbas_pdev->dev, DMA_BIT_MASK(32));
-       if (error)
-               return error;
-
-       error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
-       if (error)
-               return error;
-
-       register_reboot_notifier(&dcdbas_reboot_nb);
-
-       dev_info(&dev->dev, "%s (version %s)\n",
-                DRIVER_DESCRIPTION, DRIVER_VERSION);
-
-       return 0;
-}
-
-static int dcdbas_remove(struct platform_device *dev)
-{
-       unregister_reboot_notifier(&dcdbas_reboot_nb);
-       sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
-
-       return 0;
-}
-
-static struct platform_driver dcdbas_driver = {
-       .driver         = {
-               .name   = DRIVER_NAME,
-       },
-       .probe          = dcdbas_probe,
-       .remove         = dcdbas_remove,
-};
-
-static const struct platform_device_info dcdbas_dev_info __initconst = {
-       .name           = DRIVER_NAME,
-       .id             = -1,
-       .dma_mask       = DMA_BIT_MASK(32),
-};
-
-static struct platform_device *dcdbas_pdev_reg;
-
-/**
- * dcdbas_init: initialize driver
- */
-static int __init dcdbas_init(void)
-{
-       int error;
-
-       error = platform_driver_register(&dcdbas_driver);
-       if (error)
-               return error;
-
-       dcdbas_pdev_reg = platform_device_register_full(&dcdbas_dev_info);
-       if (IS_ERR(dcdbas_pdev_reg)) {
-               error = PTR_ERR(dcdbas_pdev_reg);
-               goto err_unregister_driver;
-       }
-
-       return 0;
-
- err_unregister_driver:
-       platform_driver_unregister(&dcdbas_driver);
-       return error;
-}
-
-/**
- * dcdbas_exit: perform driver cleanup
- */
-static void __exit dcdbas_exit(void)
-{
-       /*
-        * make sure functions that use dcdbas_pdev are called
-        * before platform_device_unregister
-        */
-       unregister_reboot_notifier(&dcdbas_reboot_nb);
-
-       /*
-        * We have to free the buffer here instead of dcdbas_remove
-        * because only in module exit function we can be sure that
-        * all sysfs attributes belonging to this module have been
-        * released.
-        */
-       if (dcdbas_pdev)
-               smi_data_buf_free();
-       platform_device_unregister(dcdbas_pdev_reg);
-       platform_driver_unregister(&dcdbas_driver);
-}
-
-subsys_initcall_sync(dcdbas_init);
-module_exit(dcdbas_exit);
-
-MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_AUTHOR("Dell Inc.");
-MODULE_LICENSE("GPL");
-/* Any System or BIOS claiming to be by Dell */
-MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*");
diff --git a/drivers/firmware/dcdbas.h b/drivers/firmware/dcdbas.h
deleted file mode 100644 (file)
index ca3cb0a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  dcdbas.h: Definitions for Dell Systems Management Base driver
- *
- *  Copyright (C) 1995-2005 Dell Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License v2.0 as published by
- *  the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
-
-#ifndef _DCDBAS_H_
-#define _DCDBAS_H_
-
-#include <linux/device.h>
-#include <linux/sysfs.h>
-#include <linux/types.h>
-
-#define MAX_SMI_DATA_BUF_SIZE                  (256 * 1024)
-
-#define HC_ACTION_NONE                         (0)
-#define HC_ACTION_HOST_CONTROL_POWEROFF                BIT(1)
-#define HC_ACTION_HOST_CONTROL_POWERCYCLE      BIT(2)
-
-#define HC_SMITYPE_NONE                                (0)
-#define HC_SMITYPE_TYPE1                       (1)
-#define HC_SMITYPE_TYPE2                       (2)
-#define HC_SMITYPE_TYPE3                       (3)
-
-#define ESM_APM_CMD                            (0x0A0)
-#define ESM_APM_POWER_CYCLE                    (0x10)
-#define ESM_STATUS_CMD_UNSUCCESSFUL            (-1)
-
-#define CMOS_BASE_PORT                         (0x070)
-#define CMOS_PAGE1_INDEX_PORT                  (0)
-#define CMOS_PAGE1_DATA_PORT                   (1)
-#define CMOS_PAGE2_INDEX_PORT_PIIX4            (2)
-#define CMOS_PAGE2_DATA_PORT_PIIX4             (3)
-#define PE1400_APM_CONTROL_PORT                        (0x0B0)
-#define PCAT_APM_CONTROL_PORT                  (0x0B2)
-#define PCAT_APM_STATUS_PORT                   (0x0B3)
-#define PE1300_CMOS_CMD_STRUCT_PTR             (0x38)
-#define PE1400_CMOS_CMD_STRUCT_PTR             (0x70)
-
-#define MAX_SYSMGMT_SHORTCMD_PARMBUF_LEN       (14)
-#define MAX_SYSMGMT_LONGCMD_SGENTRY_NUM                (16)
-
-#define TIMEOUT_USEC_SHORT_SEMA_BLOCKING       (10000)
-#define EXPIRED_TIMER                          (0)
-
-#define SMI_CMD_MAGIC                          (0x534D4931)
-
-#define DCDBAS_DEV_ATTR_RW(_name) \
-       DEVICE_ATTR(_name,0600,_name##_show,_name##_store);
-
-#define DCDBAS_DEV_ATTR_RO(_name) \
-       DEVICE_ATTR(_name,0400,_name##_show,NULL);
-
-#define DCDBAS_DEV_ATTR_WO(_name) \
-       DEVICE_ATTR(_name,0200,NULL,_name##_store);
-
-#define DCDBAS_BIN_ATTR_RW(_name) \
-struct bin_attribute bin_attr_##_name = { \
-       .attr =  { .name = __stringify(_name), \
-                  .mode = 0600 }, \
-       .read =  _name##_read, \
-       .write = _name##_write, \
-}
-
-struct smi_cmd {
-       __u32 magic;
-       __u32 ebx;
-       __u32 ecx;
-       __u16 command_address;
-       __u8 command_code;
-       __u8 reserved;
-       __u8 command_buffer[1];
-} __attribute__ ((packed));
-
-struct apm_cmd {
-       __u8 command;
-       __s8 status;
-       __u16 reserved;
-       union {
-               struct {
-                       __u8 parm[MAX_SYSMGMT_SHORTCMD_PARMBUF_LEN];
-               } __attribute__ ((packed)) shortreq;
-
-               struct {
-                       __u16 num_sg_entries;
-                       struct {
-                               __u32 size;
-                               __u64 addr;
-                       } __attribute__ ((packed))
-                           sglist[MAX_SYSMGMT_LONGCMD_SGENTRY_NUM];
-               } __attribute__ ((packed)) longreq;
-       } __attribute__ ((packed)) parameters;
-} __attribute__ ((packed));
-
-int dcdbas_smi_request(struct smi_cmd *smi_cmd);
-
-#endif /* _DCDBAS_H_ */
-
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
deleted file mode 100644 (file)
index fb8af5c..0000000
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * dell_rbu.c
- * Bios Update driver for Dell systems
- * Author: Dell Inc
- *         Abhay Salunke <abhay_salunke@dell.com>
- *
- * Copyright (C) 2005 Dell Inc.
- *
- * Remote BIOS Update (rbu) driver is used for updating DELL BIOS by
- * creating entries in the /sys file systems on Linux 2.6 and higher
- * kernels. The driver supports two mechanism to update the BIOS namely
- * contiguous and packetized. Both these methods still require having some
- * application to set the CMOS bit indicating the BIOS to update itself
- * after a reboot.
- *
- * Contiguous method:
- * This driver writes the incoming data in a monolithic image by allocating
- * contiguous physical pages large enough to accommodate the incoming BIOS
- * image size.
- *
- * Packetized method:
- * The driver writes the incoming packet image by allocating a new packet
- * on every time the packet data is written. This driver requires an
- * application to break the BIOS image in to fixed sized packet chunks.
- *
- * See Documentation/dell_rbu.txt for more info.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License v2.0 as published by
- * the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/blkdev.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/moduleparam.h>
-#include <linux/firmware.h>
-#include <linux/dma-mapping.h>
-
-MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
-MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("3.2");
-
-#define BIOS_SCAN_LIMIT 0xffffffff
-#define MAX_IMAGE_LENGTH 16
-static struct _rbu_data {
-       void *image_update_buffer;
-       unsigned long image_update_buffer_size;
-       unsigned long bios_image_size;
-       int image_update_ordernum;
-       int dma_alloc;
-       spinlock_t lock;
-       unsigned long packet_read_count;
-       unsigned long num_packets;
-       unsigned long packetsize;
-       unsigned long imagesize;
-       int entry_created;
-} rbu_data;
-
-static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
-module_param_string(image_type, image_type, sizeof (image_type), 0);
-MODULE_PARM_DESC(image_type,
-       "BIOS image type. choose- mono or packet or init");
-
-static unsigned long allocation_floor = 0x100000;
-module_param(allocation_floor, ulong, 0644);
-MODULE_PARM_DESC(allocation_floor,
-    "Minimum address for allocations when using Packet mode");
-
-struct packet_data {
-       struct list_head list;
-       size_t length;
-       void *data;
-       int ordernum;
-};
-
-static struct packet_data packet_data_head;
-
-static struct platform_device *rbu_device;
-static int context;
-static dma_addr_t dell_rbu_dmaaddr;
-
-static void init_packet_head(void)
-{
-       INIT_LIST_HEAD(&packet_data_head.list);
-       rbu_data.packet_read_count = 0;
-       rbu_data.num_packets = 0;
-       rbu_data.packetsize = 0;
-       rbu_data.imagesize = 0;
-}
-
-static int create_packet(void *data, size_t length)
-{
-       struct packet_data *newpacket;
-       int ordernum = 0;
-       int retval = 0;
-       unsigned int packet_array_size = 0;
-       void **invalid_addr_packet_array = NULL;
-       void *packet_data_temp_buf = NULL;
-       unsigned int idx = 0;
-
-       pr_debug("create_packet: entry \n");
-
-       if (!rbu_data.packetsize) {
-               pr_debug("create_packet: packetsize not specified\n");
-               retval = -EINVAL;
-               goto out_noalloc;
-       }
-
-       spin_unlock(&rbu_data.lock);
-
-       newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
-
-       if (!newpacket) {
-               printk(KERN_WARNING
-                       "dell_rbu:%s: failed to allocate new "
-                       "packet\n", __func__);
-               retval = -ENOMEM;
-               spin_lock(&rbu_data.lock);
-               goto out_noalloc;
-       }
-
-       ordernum = get_order(length);
-
-       /*
-        * BIOS errata mean we cannot allocate packets below 1MB or they will
-        * be overwritten by BIOS.
-        *
-        * array to temporarily hold packets
-        * that are below the allocation floor
-        *
-        * NOTE: very simplistic because we only need the floor to be at 1MB
-        *       due to BIOS errata. This shouldn't be used for higher floors
-        *       or you will run out of mem trying to allocate the array.
-        */
-       packet_array_size = max(
-                       (unsigned int)(allocation_floor / rbu_data.packetsize),
-                       (unsigned int)1);
-       invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *),
-                                               GFP_KERNEL);
-
-       if (!invalid_addr_packet_array) {
-               printk(KERN_WARNING
-                       "dell_rbu:%s: failed to allocate "
-                       "invalid_addr_packet_array \n",
-                       __func__);
-               retval = -ENOMEM;
-               spin_lock(&rbu_data.lock);
-               goto out_alloc_packet;
-       }
-
-       while (!packet_data_temp_buf) {
-               packet_data_temp_buf = (unsigned char *)
-                       __get_free_pages(GFP_KERNEL, ordernum);
-               if (!packet_data_temp_buf) {
-                       printk(KERN_WARNING
-                               "dell_rbu:%s: failed to allocate new "
-                               "packet\n", __func__);
-                       retval = -ENOMEM;
-                       spin_lock(&rbu_data.lock);
-                       goto out_alloc_packet_array;
-               }
-
-               if ((unsigned long)virt_to_phys(packet_data_temp_buf)
-                               < allocation_floor) {
-                       pr_debug("packet 0x%lx below floor at 0x%lx.\n",
-                                       (unsigned long)virt_to_phys(
-                                               packet_data_temp_buf),
-                                       allocation_floor);
-                       invalid_addr_packet_array[idx++] = packet_data_temp_buf;
-                       packet_data_temp_buf = NULL;
-               }
-       }
-       spin_lock(&rbu_data.lock);
-
-       newpacket->data = packet_data_temp_buf;
-
-       pr_debug("create_packet: newpacket at physical addr %lx\n",
-               (unsigned long)virt_to_phys(newpacket->data));
-
-       /* packets may not have fixed size */
-       newpacket->length = length;
-       newpacket->ordernum = ordernum;
-       ++rbu_data.num_packets;
-
-       /* initialize the newly created packet headers */
-       INIT_LIST_HEAD(&newpacket->list);
-       list_add_tail(&newpacket->list, &packet_data_head.list);
-
-       memcpy(newpacket->data, data, length);
-
-       pr_debug("create_packet: exit \n");
-
-out_alloc_packet_array:
-       /* always free packet array */
-       for (;idx>0;idx--) {
-               pr_debug("freeing unused packet below floor 0x%lx.\n",
-                       (unsigned long)virt_to_phys(
-                               invalid_addr_packet_array[idx-1]));
-               free_pages((unsigned long)invalid_addr_packet_array[idx-1],
-                       ordernum);
-       }
-       kfree(invalid_addr_packet_array);
-
-out_alloc_packet:
-       /* if error, free data */
-       if (retval)
-               kfree(newpacket);
-
-out_noalloc:
-       return retval;
-}
-
-static int packetize_data(const u8 *data, size_t length)
-{
-       int rc = 0;
-       int done = 0;
-       int packet_length;
-       u8 *temp;
-       u8 *end = (u8 *) data + length;
-       pr_debug("packetize_data: data length %zd\n", length);
-       if (!rbu_data.packetsize) {
-               printk(KERN_WARNING
-                       "dell_rbu: packetsize not specified\n");
-               return -EIO;
-       }
-
-       temp = (u8 *) data;
-
-       /* packetize the hunk */
-       while (!done) {
-               if ((temp + rbu_data.packetsize) < end)
-                       packet_length = rbu_data.packetsize;
-               else {
-                       /* this is the last packet */
-                       packet_length = end - temp;
-                       done = 1;
-               }
-
-               if ((rc = create_packet(temp, packet_length)))
-                       return rc;
-
-               pr_debug("%p:%td\n", temp, (end - temp));
-               temp += packet_length;
-       }
-
-       rbu_data.imagesize = length;
-
-       return rc;
-}
-
-static int do_packet_read(char *data, struct list_head *ptemp_list,
-       int length, int bytes_read, int *list_read_count)
-{
-       void *ptemp_buf;
-       struct packet_data *newpacket = NULL;
-       int bytes_copied = 0;
-       int j = 0;
-
-       newpacket = list_entry(ptemp_list, struct packet_data, list);
-       *list_read_count += newpacket->length;
-
-       if (*list_read_count > bytes_read) {
-               /* point to the start of unread data */
-               j = newpacket->length - (*list_read_count - bytes_read);
-               /* point to the offset in the packet buffer */
-               ptemp_buf = (u8 *) newpacket->data + j;
-               /*
-                * check if there is enough room in
-                * * the incoming buffer
-                */
-               if (length > (*list_read_count - bytes_read))
-                       /*
-                        * copy what ever is there in this
-                        * packet and move on
-                        */
-                       bytes_copied = (*list_read_count - bytes_read);
-               else
-                       /* copy the remaining */
-                       bytes_copied = length;
-               memcpy(data, ptemp_buf, bytes_copied);
-       }
-       return bytes_copied;
-}
-
-static int packet_read_list(char *data, size_t * pread_length)
-{
-       struct list_head *ptemp_list;
-       int temp_count = 0;
-       int bytes_copied = 0;
-       int bytes_read = 0;
-       int remaining_bytes = 0;
-       char *pdest = data;
-
-       /* check if we have any packets */
-       if (0 == rbu_data.num_packets)
-               return -ENOMEM;
-
-       remaining_bytes = *pread_length;
-       bytes_read = rbu_data.packet_read_count;
-
-       ptemp_list = (&packet_data_head.list)->next;
-       while (!list_empty(ptemp_list)) {
-               bytes_copied = do_packet_read(pdest, ptemp_list,
-                       remaining_bytes, bytes_read, &temp_count);
-               remaining_bytes -= bytes_copied;
-               bytes_read += bytes_copied;
-               pdest += bytes_copied;
-               /*
-                * check if we reached end of buffer before reaching the
-                * last packet
-                */
-               if (remaining_bytes == 0)
-                       break;
-
-               ptemp_list = ptemp_list->next;
-       }
-       /*finally set the bytes read */
-       *pread_length = bytes_read - rbu_data.packet_read_count;
-       rbu_data.packet_read_count = bytes_read;
-       return 0;
-}
-
-static void packet_empty_list(void)
-{
-       struct list_head *ptemp_list;
-       struct list_head *pnext_list;
-       struct packet_data *newpacket;
-
-       ptemp_list = (&packet_data_head.list)->next;
-       while (!list_empty(ptemp_list)) {
-               newpacket =
-                       list_entry(ptemp_list, struct packet_data, list);
-               pnext_list = ptemp_list->next;
-               list_del(ptemp_list);
-               ptemp_list = pnext_list;
-               /*
-                * zero out the RBU packet memory before freeing
-                * to make sure there are no stale RBU packets left in memory
-                */
-               memset(newpacket->data, 0, rbu_data.packetsize);
-               free_pages((unsigned long) newpacket->data,
-                       newpacket->ordernum);
-               kfree(newpacket);
-       }
-       rbu_data.packet_read_count = 0;
-       rbu_data.num_packets = 0;
-       rbu_data.imagesize = 0;
-}
-
-/*
- * img_update_free: Frees the buffer allocated for storing BIOS image
- * Always called with lock held and returned with lock held
- */
-static void img_update_free(void)
-{
-       if (!rbu_data.image_update_buffer)
-               return;
-       /*
-        * zero out this buffer before freeing it to get rid of any stale
-        * BIOS image copied in memory.
-        */
-       memset(rbu_data.image_update_buffer, 0,
-               rbu_data.image_update_buffer_size);
-       if (rbu_data.dma_alloc == 1)
-               dma_free_coherent(NULL, rbu_data.bios_image_size,
-                       rbu_data.image_update_buffer, dell_rbu_dmaaddr);
-       else
-               free_pages((unsigned long) rbu_data.image_update_buffer,
-                       rbu_data.image_update_ordernum);
-
-       /*
-        * Re-initialize the rbu_data variables after a free
-        */
-       rbu_data.image_update_ordernum = -1;
-       rbu_data.image_update_buffer = NULL;
-       rbu_data.image_update_buffer_size = 0;
-       rbu_data.bios_image_size = 0;
-       rbu_data.dma_alloc = 0;
-}
-
-/*
- * img_update_realloc: This function allocates the contiguous pages to
- * accommodate the requested size of data. The memory address and size
- * values are stored globally and on every call to this function the new
- * size is checked to see if more data is required than the existing size.
- * If true the previous memory is freed and new allocation is done to
- * accommodate the new size. If the incoming size is less then than the
- * already allocated size, then that memory is reused. This function is
- * called with lock held and returns with lock held.
- */
-static int img_update_realloc(unsigned long size)
-{
-       unsigned char *image_update_buffer = NULL;
-       unsigned long rc;
-       unsigned long img_buf_phys_addr;
-       int ordernum;
-       int dma_alloc = 0;
-
-       /*
-        * check if the buffer of sufficient size has been
-        * already allocated
-        */
-       if (rbu_data.image_update_buffer_size >= size) {
-               /*
-                * check for corruption
-                */
-               if ((size != 0) && (rbu_data.image_update_buffer == NULL)) {
-                       printk(KERN_ERR "dell_rbu:%s: corruption "
-                               "check failed\n", __func__);
-                       return -EINVAL;
-               }
-               /*
-                * we have a valid pre-allocated buffer with
-                * sufficient size
-                */
-               return 0;
-       }
-
-       /*
-        * free any previously allocated buffer
-        */
-       img_update_free();
-
-       spin_unlock(&rbu_data.lock);
-
-       ordernum = get_order(size);
-       image_update_buffer =
-               (unsigned char *) __get_free_pages(GFP_KERNEL, ordernum);
-
-       img_buf_phys_addr =
-               (unsigned long) virt_to_phys(image_update_buffer);
-
-       if (img_buf_phys_addr > BIOS_SCAN_LIMIT) {
-               free_pages((unsigned long) image_update_buffer, ordernum);
-               ordernum = -1;
-               image_update_buffer = dma_alloc_coherent(NULL, size,
-                       &dell_rbu_dmaaddr, GFP_KERNEL);
-               dma_alloc = 1;
-       }
-
-       spin_lock(&rbu_data.lock);
-
-       if (image_update_buffer != NULL) {
-               rbu_data.image_update_buffer = image_update_buffer;
-               rbu_data.image_update_buffer_size = size;
-               rbu_data.bios_image_size =
-                       rbu_data.image_update_buffer_size;
-               rbu_data.image_update_ordernum = ordernum;
-               rbu_data.dma_alloc = dma_alloc;
-               rc = 0;
-       } else {
-               pr_debug("Not enough memory for image update:"
-                       "size = %ld\n", size);
-               rc = -ENOMEM;
-       }
-
-       return rc;
-}
-
-static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
-{
-       int retval;
-       size_t bytes_left;
-       size_t data_length;
-       char *ptempBuf = buffer;
-
-       /* check to see if we have something to return */
-       if (rbu_data.num_packets == 0) {
-               pr_debug("read_packet_data: no packets written\n");
-               retval = -ENOMEM;
-               goto read_rbu_data_exit;
-       }
-
-       if (pos > rbu_data.imagesize) {
-               retval = 0;
-               printk(KERN_WARNING "dell_rbu:read_packet_data: "
-                       "data underrun\n");
-               goto read_rbu_data_exit;
-       }
-
-       bytes_left = rbu_data.imagesize - pos;
-       data_length = min(bytes_left, count);
-
-       if ((retval = packet_read_list(ptempBuf, &data_length)) < 0)
-               goto read_rbu_data_exit;
-
-       if ((pos + count) > rbu_data.imagesize) {
-               rbu_data.packet_read_count = 0;
-               /* this was the last copy */
-               retval = bytes_left;
-       } else
-               retval = count;
-
-      read_rbu_data_exit:
-       return retval;
-}
-
-static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
-{
-       /* check to see if we have something to return */
-       if ((rbu_data.image_update_buffer == NULL) ||
-               (rbu_data.bios_image_size == 0)) {
-               pr_debug("read_rbu_data_mono: image_update_buffer %p ,"
-                       "bios_image_size %lu\n",
-                       rbu_data.image_update_buffer,
-                       rbu_data.bios_image_size);
-               return -ENOMEM;
-       }
-
-       return memory_read_from_buffer(buffer, count, &pos,
-                       rbu_data.image_update_buffer, rbu_data.bios_image_size);
-}
-
-static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj,
-                            struct bin_attribute *bin_attr,
-                            char *buffer, loff_t pos, size_t count)
-{
-       ssize_t ret_count = 0;
-
-       spin_lock(&rbu_data.lock);
-
-       if (!strcmp(image_type, "mono"))
-               ret_count = read_rbu_mono_data(buffer, pos, count);
-       else if (!strcmp(image_type, "packet"))
-               ret_count = read_packet_data(buffer, pos, count);
-       else
-               pr_debug("read_rbu_data: invalid image type specified\n");
-
-       spin_unlock(&rbu_data.lock);
-       return ret_count;
-}
-
-static void callbackfn_rbu(const struct firmware *fw, void *context)
-{
-       rbu_data.entry_created = 0;
-
-       if (!fw)
-               return;
-
-       if (!fw->size)
-               goto out;
-
-       spin_lock(&rbu_data.lock);
-       if (!strcmp(image_type, "mono")) {
-               if (!img_update_realloc(fw->size))
-                       memcpy(rbu_data.image_update_buffer,
-                               fw->data, fw->size);
-       } else if (!strcmp(image_type, "packet")) {
-               /*
-                * we need to free previous packets if a
-                * new hunk of packets needs to be downloaded
-                */
-               packet_empty_list();
-               if (packetize_data(fw->data, fw->size))
-                       /* Incase something goes wrong when we are
-                        * in middle of packetizing the data, we
-                        * need to free up whatever packets might
-                        * have been created before we quit.
-                        */
-                       packet_empty_list();
-       } else
-               pr_debug("invalid image type specified.\n");
-       spin_unlock(&rbu_data.lock);
- out:
-       release_firmware(fw);
-}
-
-static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
-                                  struct bin_attribute *bin_attr,
-                                  char *buffer, loff_t pos, size_t count)
-{
-       int size = 0;
-       if (!pos)
-               size = scnprintf(buffer, count, "%s\n", image_type);
-       return size;
-}
-
-static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
-                                   struct bin_attribute *bin_attr,
-                                   char *buffer, loff_t pos, size_t count)
-{
-       int rc = count;
-       int req_firm_rc = 0;
-       int i;
-       spin_lock(&rbu_data.lock);
-       /*
-        * Find the first newline or space
-        */
-       for (i = 0; i < count; ++i)
-               if (buffer[i] == '\n' || buffer[i] == ' ') {
-                       buffer[i] = '\0';
-                       break;
-               }
-       if (i == count)
-               buffer[count] = '\0';
-
-       if (strstr(buffer, "mono"))
-               strcpy(image_type, "mono");
-       else if (strstr(buffer, "packet"))
-               strcpy(image_type, "packet");
-       else if (strstr(buffer, "init")) {
-               /*
-                * If due to the user error the driver gets in a bad
-                * state where even though it is loaded , the
-                * /sys/class/firmware/dell_rbu entries are missing.
-                * to cover this situation the user can recreate entries
-                * by writing init to image_type.
-                */
-               if (!rbu_data.entry_created) {
-                       spin_unlock(&rbu_data.lock);
-                       req_firm_rc = request_firmware_nowait(THIS_MODULE,
-                               FW_ACTION_NOHOTPLUG, "dell_rbu",
-                               &rbu_device->dev, GFP_KERNEL, &context,
-                               callbackfn_rbu);
-                       if (req_firm_rc) {
-                               printk(KERN_ERR
-                                       "dell_rbu:%s request_firmware_nowait"
-                                       " failed %d\n", __func__, rc);
-                               rc = -EIO;
-                       } else
-                               rbu_data.entry_created = 1;
-
-                       spin_lock(&rbu_data.lock);
-               }
-       } else {
-               printk(KERN_WARNING "dell_rbu: image_type is invalid\n");
-               spin_unlock(&rbu_data.lock);
-               return -EINVAL;
-       }
-
-       /* we must free all previous allocations */
-       packet_empty_list();
-       img_update_free();
-       spin_unlock(&rbu_data.lock);
-
-       return rc;
-}
-
-static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj,
-                                   struct bin_attribute *bin_attr,
-                                   char *buffer, loff_t pos, size_t count)
-{
-       int size = 0;
-       if (!pos) {
-               spin_lock(&rbu_data.lock);
-               size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize);
-               spin_unlock(&rbu_data.lock);
-       }
-       return size;
-}
-
-static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj,
-                                    struct bin_attribute *bin_attr,
-                                    char *buffer, loff_t pos, size_t count)
-{
-       unsigned long temp;
-       spin_lock(&rbu_data.lock);
-       packet_empty_list();
-       sscanf(buffer, "%lu", &temp);
-       if (temp < 0xffffffff)
-               rbu_data.packetsize = temp;
-
-       spin_unlock(&rbu_data.lock);
-       return count;
-}
-
-static struct bin_attribute rbu_data_attr = {
-       .attr = {.name = "data", .mode = 0444},
-       .read = read_rbu_data,
-};
-
-static struct bin_attribute rbu_image_type_attr = {
-       .attr = {.name = "image_type", .mode = 0644},
-       .read = read_rbu_image_type,
-       .write = write_rbu_image_type,
-};
-
-static struct bin_attribute rbu_packet_size_attr = {
-       .attr = {.name = "packet_size", .mode = 0644},
-       .read = read_rbu_packet_size,
-       .write = write_rbu_packet_size,
-};
-
-static int __init dcdrbu_init(void)
-{
-       int rc;
-       spin_lock_init(&rbu_data.lock);
-
-       init_packet_head();
-       rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0);
-       if (IS_ERR(rbu_device)) {
-               printk(KERN_ERR
-                       "dell_rbu:%s:platform_device_register_simple "
-                       "failed\n", __func__);
-               return PTR_ERR(rbu_device);
-       }
-
-       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
-       if (rc)
-               goto out_devreg;
-       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
-       if (rc)
-               goto out_data;
-       rc = sysfs_create_bin_file(&rbu_device->dev.kobj,
-               &rbu_packet_size_attr);
-       if (rc)
-               goto out_imtype;
-
-       rbu_data.entry_created = 0;
-       return 0;
-
-out_imtype:
-       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
-out_data:
-       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
-out_devreg:
-       platform_device_unregister(rbu_device);
-       return rc;
-}
-
-static __exit void dcdrbu_exit(void)
-{
-       spin_lock(&rbu_data.lock);
-       packet_empty_list();
-       img_update_free();
-       spin_unlock(&rbu_data.lock);
-       platform_device_unregister(rbu_device);
-}
-
-module_exit(dcdrbu_exit);
-module_init(dcdrbu_init);
-
-/* vim:noet:ts=8:sw=8
-*/
index f2483548cde92d692f748d6a9c7da0cbf98274a3..099d83e4e910e25146f5a22e67e854bd003cd687 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/ctype.h>
 #include <linux/dmi.h>
 #include <linux/efi.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/random.h>
 #include <asm/dmi.h>
 #include <asm/unaligned.h>
index 60a95719ecb867a61183bb9a8959d00cc1bf5647..ac1654f74dc77aa4952bb8feb6514acc5c412cf6 100644 (file)
@@ -20,7 +20,7 @@
 
 #define pr_fmt(fmt) "apple-properties: " fmt
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/efi.h>
 #include <linux/io.h>
 #include <linux/platform_data/x86/apple.h>
@@ -235,7 +235,7 @@ static int __init map_properties(void)
                 */
                data->len = 0;
                memunmap(data);
-               free_bootmem_late(pa_data + sizeof(*data), data_len);
+               memblock_free_late(pa_data + sizeof(*data), data_len);
 
                return ret;
        }
index 5fc70520e04c4b57cd047c9dc6c0f5f7fab590f3..fa2904fb841fe459a6562b9fea237c5213fa97be 100644 (file)
@@ -15,7 +15,7 @@
 
 static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
 {
-       return memblock_alloc(size, 0);
+       return memblock_phys_alloc(size, SMP_CACHE_BYTES);
 }
 
 static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
new file mode 100644 (file)
index 0000000..b170c28
--- /dev/null
@@ -0,0 +1,11 @@
+config IMX_SCU
+       bool "IMX SCU Protocol driver"
+       depends on IMX_MBOX
+       help
+         The System Controller Firmware (SCFW) is a low-level system function
+         which runs on a dedicated Cortex-M core to provide power, clock, and
+         resource management. It exists on some i.MX8 processors. e.g. i.MX8QM
+         (QM, QP), and i.MX8QX (QXP, DX).
+
+         This driver manages the IPC interface between host CPU and the
+         SCU firmware running on M4.
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
new file mode 100644 (file)
index 0000000..0ac04df
--- /dev/null
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_IMX_SCU)  += imx-scu.o misc.o
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
new file mode 100644 (file)
index 0000000..2bb1a19
--- /dev/null
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ *  Author: Dong Aisheng <aisheng.dong@nxp.com>
+ *
+ * Implementation of the SCU IPC functions using MUs (client side).
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/firmware/imx/types.h>
+#include <linux/firmware/imx/ipc.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#define SCU_MU_CHAN_NUM                8
+#define MAX_RX_TIMEOUT         (msecs_to_jiffies(30))
+
+struct imx_sc_chan {
+       struct imx_sc_ipc *sc_ipc;
+
+       struct mbox_client cl;
+       struct mbox_chan *ch;
+       int idx;
+};
+
+struct imx_sc_ipc {
+       /* SCU uses 4 Tx and 4 Rx channels */
+       struct imx_sc_chan chans[SCU_MU_CHAN_NUM];
+       struct device *dev;
+       struct mutex lock;
+       struct completion done;
+
+       /* temporarily store the SCU msg */
+       u32 *msg;
+       u8 rx_size;
+       u8 count;
+};
+
+/*
+ * This type is used to indicate error response for most functions.
+ */
+enum imx_sc_error_codes {
+       IMX_SC_ERR_NONE = 0,    /* Success */
+       IMX_SC_ERR_VERSION = 1, /* Incompatible API version */
+       IMX_SC_ERR_CONFIG = 2,  /* Configuration error */
+       IMX_SC_ERR_PARM = 3,    /* Bad parameter */
+       IMX_SC_ERR_NOACCESS = 4,        /* Permission error (no access) */
+       IMX_SC_ERR_LOCKED = 5,  /* Permission error (locked) */
+       IMX_SC_ERR_UNAVAILABLE = 6,     /* Unavailable (out of resources) */
+       IMX_SC_ERR_NOTFOUND = 7,        /* Not found */
+       IMX_SC_ERR_NOPOWER = 8, /* No power */
+       IMX_SC_ERR_IPC = 9,             /* Generic IPC error */
+       IMX_SC_ERR_BUSY = 10,   /* Resource is currently busy/active */
+       IMX_SC_ERR_FAIL = 11,   /* General I/O failure */
+       IMX_SC_ERR_LAST
+};
+
+static int imx_sc_linux_errmap[IMX_SC_ERR_LAST] = {
+       0,       /* IMX_SC_ERR_NONE */
+       -EINVAL, /* IMX_SC_ERR_VERSION */
+       -EINVAL, /* IMX_SC_ERR_CONFIG */
+       -EINVAL, /* IMX_SC_ERR_PARM */
+       -EACCES, /* IMX_SC_ERR_NOACCESS */
+       -EACCES, /* IMX_SC_ERR_LOCKED */
+       -ERANGE, /* IMX_SC_ERR_UNAVAILABLE */
+       -EEXIST, /* IMX_SC_ERR_NOTFOUND */
+       -EPERM,  /* IMX_SC_ERR_NOPOWER */
+       -EPIPE,  /* IMX_SC_ERR_IPC */
+       -EBUSY,  /* IMX_SC_ERR_BUSY */
+       -EIO,    /* IMX_SC_ERR_FAIL */
+};
+
+static struct imx_sc_ipc *imx_sc_ipc_handle;
+
+static inline int imx_sc_to_linux_errno(int errno)
+{
+       if (errno >= IMX_SC_ERR_NONE && errno < IMX_SC_ERR_LAST)
+               return imx_sc_linux_errmap[errno];
+       return -EIO;
+}
+
+/*
+ * Get the default handle used by SCU
+ */
+int imx_scu_get_handle(struct imx_sc_ipc **ipc)
+{
+       if (!imx_sc_ipc_handle)
+               return -EPROBE_DEFER;
+
+       *ipc = imx_sc_ipc_handle;
+       return 0;
+}
+EXPORT_SYMBOL(imx_scu_get_handle);
+
+static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
+{
+       struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl);
+       struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc;
+       struct imx_sc_rpc_msg *hdr;
+       u32 *data = msg;
+
+       if (sc_chan->idx == 0) {
+               hdr = msg;
+               sc_ipc->rx_size = hdr->size;
+               dev_dbg(sc_ipc->dev, "msg rx size %u\n", sc_ipc->rx_size);
+               if (sc_ipc->rx_size > 4)
+                       dev_warn(sc_ipc->dev, "RPC does not support receiving over 4 words: %u\n",
+                                sc_ipc->rx_size);
+       }
+
+       sc_ipc->msg[sc_chan->idx] = *data;
+       sc_ipc->count++;
+
+       dev_dbg(sc_ipc->dev, "mu %u msg %u 0x%x\n", sc_chan->idx,
+               sc_ipc->count, *data);
+
+       if ((sc_ipc->rx_size != 0) && (sc_ipc->count == sc_ipc->rx_size))
+               complete(&sc_ipc->done);
+}
+
+static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
+{
+       struct imx_sc_rpc_msg *hdr = msg;
+       struct imx_sc_chan *sc_chan;
+       u32 *data = msg;
+       int ret;
+       int i;
+
+       /* Check size */
+       if (hdr->size > IMX_SC_RPC_MAX_MSG)
+               return -EINVAL;
+
+       dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr->svc,
+               hdr->func, hdr->size);
+
+       for (i = 0; i < hdr->size; i++) {
+               sc_chan = &sc_ipc->chans[i % 4];
+               ret = mbox_send_message(sc_chan->ch, &data[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * RPC command/response
+ */
+int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
+{
+       struct imx_sc_rpc_msg *hdr;
+       int ret;
+
+       if (WARN_ON(!sc_ipc || !msg))
+               return -EINVAL;
+
+       mutex_lock(&sc_ipc->lock);
+       reinit_completion(&sc_ipc->done);
+
+       sc_ipc->msg = msg;
+       sc_ipc->count = 0;
+       ret = imx_scu_ipc_write(sc_ipc, msg);
+       if (ret < 0) {
+               dev_err(sc_ipc->dev, "RPC send msg failed: %d\n", ret);
+               goto out;
+       }
+
+       if (have_resp) {
+               if (!wait_for_completion_timeout(&sc_ipc->done,
+                                                MAX_RX_TIMEOUT)) {
+                       dev_err(sc_ipc->dev, "RPC send msg timeout\n");
+                       mutex_unlock(&sc_ipc->lock);
+                       return -ETIMEDOUT;
+               }
+
+               /* response status is stored in hdr->func field */
+               hdr = msg;
+               ret = hdr->func;
+       }
+
+out:
+       mutex_unlock(&sc_ipc->lock);
+
+       dev_dbg(sc_ipc->dev, "RPC SVC done\n");
+
+       return imx_sc_to_linux_errno(ret);
+}
+EXPORT_SYMBOL(imx_scu_call_rpc);
+
+static int imx_scu_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct imx_sc_ipc *sc_ipc;
+       struct imx_sc_chan *sc_chan;
+       struct mbox_client *cl;
+       char *chan_name;
+       int ret;
+       int i;
+
+       sc_ipc = devm_kzalloc(dev, sizeof(*sc_ipc), GFP_KERNEL);
+       if (!sc_ipc)
+               return -ENOMEM;
+
+       for (i = 0; i < SCU_MU_CHAN_NUM; i++) {
+               if (i < 4)
+                       chan_name = kasprintf(GFP_KERNEL, "tx%d", i);
+               else
+                       chan_name = kasprintf(GFP_KERNEL, "rx%d", i - 4);
+
+               if (!chan_name)
+                       return -ENOMEM;
+
+               sc_chan = &sc_ipc->chans[i];
+               cl = &sc_chan->cl;
+               cl->dev = dev;
+               cl->tx_block = false;
+               cl->knows_txdone = true;
+               cl->rx_callback = imx_scu_rx_callback;
+
+               sc_chan->sc_ipc = sc_ipc;
+               sc_chan->idx = i % 4;
+               sc_chan->ch = mbox_request_channel_byname(cl, chan_name);
+               if (IS_ERR(sc_chan->ch)) {
+                       ret = PTR_ERR(sc_chan->ch);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "Failed to request mbox chan %s ret %d\n",
+                                       chan_name, ret);
+                       return ret;
+               }
+
+               dev_dbg(dev, "request mbox chan %s\n", chan_name);
+               /* chan_name is not used anymore by framework */
+               kfree(chan_name);
+       }
+
+       sc_ipc->dev = dev;
+       mutex_init(&sc_ipc->lock);
+       init_completion(&sc_ipc->done);
+
+       imx_sc_ipc_handle = sc_ipc;
+
+       dev_info(dev, "NXP i.MX SCU Initialized\n");
+
+       return devm_of_platform_populate(dev);
+}
+
+static const struct of_device_id imx_scu_match[] = {
+       { .compatible = "fsl,imx-scu", },
+       { /* Sentinel */ }
+};
+
+static struct platform_driver imx_scu_driver = {
+       .driver = {
+               .name = "imx-scu",
+               .of_match_table = imx_scu_match,
+       },
+       .probe = imx_scu_probe,
+};
+builtin_platform_driver(imx_scu_driver);
+
+MODULE_AUTHOR("Dong Aisheng <aisheng.dong@nxp.com>");
+MODULE_DESCRIPTION("IMX SCU firmware protocol driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/imx/misc.c b/drivers/firmware/imx/misc.c
new file mode 100644 (file)
index 0000000..97f5424
--- /dev/null
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *  Author: Dong Aisheng <aisheng.dong@nxp.com>
+ *
+ * File containing client-side RPC functions for the MISC service. These
+ * function are ported to clients that communicate to the SC.
+ *
+ */
+
+#include <linux/firmware/imx/svc/misc.h>
+
+struct imx_sc_msg_req_misc_set_ctrl {
+       struct imx_sc_rpc_msg hdr;
+       u32 ctrl;
+       u32 val;
+       u16 resource;
+} __packed;
+
+struct imx_sc_msg_req_misc_get_ctrl {
+       struct imx_sc_rpc_msg hdr;
+       u32 ctrl;
+       u16 resource;
+} __packed;
+
+struct imx_sc_msg_resp_misc_get_ctrl {
+       struct imx_sc_rpc_msg hdr;
+       u32 val;
+} __packed;
+
+/*
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to change
+ * @param[in]     val         value to apply to the control
+ *
+ * @return Returns 0 for success and < 0 for errors.
+ */
+
+int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource,
+                           u8 ctrl, u32 val)
+{
+       struct imx_sc_msg_req_misc_set_ctrl msg;
+       struct imx_sc_rpc_msg *hdr = &msg.hdr;
+
+       hdr->ver = IMX_SC_RPC_VERSION;
+       hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
+       hdr->func = (uint8_t)IMX_SC_MISC_FUNC_SET_CONTROL;
+       hdr->size = 4;
+
+       msg.ctrl = ctrl;
+       msg.val = val;
+       msg.resource = resource;
+
+       return imx_scu_call_rpc(ipc, &msg, true);
+}
+EXPORT_SYMBOL(imx_sc_misc_set_control);
+
+/*
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to get
+ * @param[out]    val         pointer to return the control value
+ *
+ * @return Returns 0 for success and < 0 for errors.
+ */
+
+int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource,
+                           u8 ctrl, u32 *val)
+{
+       struct imx_sc_msg_req_misc_get_ctrl msg;
+       struct imx_sc_msg_resp_misc_get_ctrl *resp;
+       struct imx_sc_rpc_msg *hdr = &msg.hdr;
+       int ret;
+
+       hdr->ver = IMX_SC_RPC_VERSION;
+       hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
+       hdr->func = (uint8_t)IMX_SC_MISC_FUNC_GET_CONTROL;
+       hdr->size = 3;
+
+       msg.ctrl = ctrl;
+       msg.resource = resource;
+
+       ret = imx_scu_call_rpc(ipc, &msg, true);
+       if (ret)
+               return ret;
+
+       resp = (struct imx_sc_msg_resp_misc_get_ctrl *)&msg;
+       if (val != NULL)
+               *val = resp->val;
+
+       return 0;
+}
+EXPORT_SYMBOL(imx_sc_misc_get_control);
index 2224f1dc074b1329d7ce9c80b78bef4fffc6e98b..72d9ea18270b572102cc622ac15dc3ec1cfa0127 100644 (file)
@@ -18,7 +18,7 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/blkdev.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
index 5de3ed29282c4aadfc164acb91384744686690ad..d168c87c7d3085655d1fd627a6b65b792129cb03 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 
@@ -333,7 +333,8 @@ int __init firmware_map_add_early(u64 start, u64 end, const char *type)
 {
        struct firmware_map_entry *entry;
 
-       entry = memblock_virt_alloc(sizeof(struct firmware_map_entry), 0);
+       entry = memblock_alloc(sizeof(struct firmware_map_entry),
+                              SMP_CACHE_BYTES);
        if (WARN_ON(!entry))
                return -ENOMEM;
 
index 0ec2ca87318c06c73976fb368f382667a78d3df1..29fbc818a573de695b07206f912181570c39040b 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/printk.h>
 #include <linux/types.h>
 #include <linux/sizes.h>
+ #include <linux/slab.h>
 
 #include <linux/firmware/meson/meson_sm.h>
 
@@ -48,6 +49,7 @@ struct meson_sm_chip gxbb_chip = {
                CMD(SM_EFUSE_READ,      0x82000030),
                CMD(SM_EFUSE_WRITE,     0x82000031),
                CMD(SM_EFUSE_USER_MAX,  0x82000033),
+               CMD(SM_GET_CHIP_ID,     0x82000044),
                { /* sentinel */ },
        },
 };
@@ -214,6 +216,57 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
 }
 EXPORT_SYMBOL(meson_sm_call_write);
 
+#define SM_CHIP_ID_LENGTH      119
+#define SM_CHIP_ID_OFFSET      4
+#define SM_CHIP_ID_SIZE                12
+
+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       uint8_t *id_buf;
+       int ret;
+
+       id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
+       if (!id_buf)
+               return -ENOMEM;
+
+       ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
+                                0, 0, 0, 0, 0);
+       if (ret < 0) {
+               kfree(id_buf);
+               return ret;
+       }
+
+       ret = sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                       id_buf[SM_CHIP_ID_OFFSET + 0],
+                       id_buf[SM_CHIP_ID_OFFSET + 1],
+                       id_buf[SM_CHIP_ID_OFFSET + 2],
+                       id_buf[SM_CHIP_ID_OFFSET + 3],
+                       id_buf[SM_CHIP_ID_OFFSET + 4],
+                       id_buf[SM_CHIP_ID_OFFSET + 5],
+                       id_buf[SM_CHIP_ID_OFFSET + 6],
+                       id_buf[SM_CHIP_ID_OFFSET + 7],
+                       id_buf[SM_CHIP_ID_OFFSET + 8],
+                       id_buf[SM_CHIP_ID_OFFSET + 9],
+                       id_buf[SM_CHIP_ID_OFFSET + 10],
+                       id_buf[SM_CHIP_ID_OFFSET + 11]);
+
+       kfree(id_buf);
+
+       return ret;
+}
+
+static DEVICE_ATTR_RO(serial);
+
+static struct attribute *meson_sm_sysfs_attributes[] = {
+       &dev_attr_serial.attr,
+       NULL,
+};
+
+static const struct attribute_group meson_sm_sysfs_attr_group = {
+       .attrs = meson_sm_sysfs_attributes,
+};
+
 static const struct of_device_id meson_sm_ids[] = {
        { .compatible = "amlogic,meson-gxbb-sm", .data = &gxbb_chip },
        { /* sentinel */ },
@@ -242,6 +295,9 @@ static int __init meson_sm_probe(struct platform_device *pdev)
        fw.chip = chip;
        pr_info("secure-monitor enabled\n");
 
+       if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
+               goto out_in_base;
+
        return 0;
 
 out_in_base:
index e778af766fae3c2c88d20e8f7ae6f47f9114935c..af4eee86919d86418245fd8e66fd47ed423dee13 100644 (file)
@@ -525,34 +525,44 @@ static int qcom_scm_probe(struct platform_device *pdev)
                return ret;
 
        clks = (unsigned long)of_device_get_match_data(&pdev->dev);
-       if (clks & SCM_HAS_CORE_CLK) {
-               scm->core_clk = devm_clk_get(&pdev->dev, "core");
-               if (IS_ERR(scm->core_clk)) {
-                       if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER)
-                               dev_err(&pdev->dev,
-                                       "failed to acquire core clk\n");
+
+       scm->core_clk = devm_clk_get(&pdev->dev, "core");
+       if (IS_ERR(scm->core_clk)) {
+               if (PTR_ERR(scm->core_clk) == -EPROBE_DEFER)
+                       return PTR_ERR(scm->core_clk);
+
+               if (clks & SCM_HAS_CORE_CLK) {
+                       dev_err(&pdev->dev, "failed to acquire core clk\n");
                        return PTR_ERR(scm->core_clk);
                }
+
+               scm->core_clk = NULL;
        }
 
-       if (clks & SCM_HAS_IFACE_CLK) {
-               scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
-               if (IS_ERR(scm->iface_clk)) {
-                       if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER)
-                               dev_err(&pdev->dev,
-                                       "failed to acquire iface clk\n");
+       scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
+       if (IS_ERR(scm->iface_clk)) {
+               if (PTR_ERR(scm->iface_clk) == -EPROBE_DEFER)
+                       return PTR_ERR(scm->iface_clk);
+
+               if (clks & SCM_HAS_IFACE_CLK) {
+                       dev_err(&pdev->dev, "failed to acquire iface clk\n");
                        return PTR_ERR(scm->iface_clk);
                }
+
+               scm->iface_clk = NULL;
        }
 
-       if (clks & SCM_HAS_BUS_CLK) {
-               scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
-               if (IS_ERR(scm->bus_clk)) {
-                       if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER)
-                               dev_err(&pdev->dev,
-                                       "failed to acquire bus clk\n");
+       scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
+       if (IS_ERR(scm->bus_clk)) {
+               if (PTR_ERR(scm->bus_clk) == -EPROBE_DEFER)
+                       return PTR_ERR(scm->bus_clk);
+
+               if (clks & SCM_HAS_BUS_CLK) {
+                       dev_err(&pdev->dev, "failed to acquire bus clk\n");
                        return PTR_ERR(scm->bus_clk);
                }
+
+               scm->bus_clk = NULL;
        }
 
        scm->reset.ops = &qcom_scm_pas_reset_ops;
@@ -594,23 +604,23 @@ static const struct of_device_id qcom_scm_dt_match[] = {
        { .compatible = "qcom,scm-apq8064",
          /* FIXME: This should have .data = (void *) SCM_HAS_CORE_CLK */
        },
-       { .compatible = "qcom,scm-msm8660",
-         .data = (void *) SCM_HAS_CORE_CLK,
-       },
-       { .compatible = "qcom,scm-msm8960",
-         .data = (void *) SCM_HAS_CORE_CLK,
-       },
-       { .compatible = "qcom,scm-msm8996",
-         .data = NULL, /* no clocks */
+       { .compatible = "qcom,scm-apq8084", .data = (void *)(SCM_HAS_CORE_CLK |
+                                                            SCM_HAS_IFACE_CLK |
+                                                            SCM_HAS_BUS_CLK)
        },
-       { .compatible = "qcom,scm-ipq4019",
-         .data = NULL, /* no clocks */
+       { .compatible = "qcom,scm-ipq4019" },
+       { .compatible = "qcom,scm-msm8660", .data = (void *) SCM_HAS_CORE_CLK },
+       { .compatible = "qcom,scm-msm8960", .data = (void *) SCM_HAS_CORE_CLK },
+       { .compatible = "qcom,scm-msm8916", .data = (void *)(SCM_HAS_CORE_CLK |
+                                                            SCM_HAS_IFACE_CLK |
+                                                            SCM_HAS_BUS_CLK)
        },
-       { .compatible = "qcom,scm",
-         .data = (void *)(SCM_HAS_CORE_CLK
-                          | SCM_HAS_IFACE_CLK
-                          | SCM_HAS_BUS_CLK),
+       { .compatible = "qcom,scm-msm8974", .data = (void *)(SCM_HAS_CORE_CLK |
+                                                            SCM_HAS_IFACE_CLK |
+                                                            SCM_HAS_BUS_CLK)
        },
+       { .compatible = "qcom,scm-msm8996" },
+       { .compatible = "qcom,scm" },
        {}
 };
 
index 14a456afa379a073ee4cd233f96153edc1a79a3c..a3d5b518c10e4a13deeba7c6e9309c13c33cdded 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/semaphore.h>
 #include <linux/sched/clock.h>
 
@@ -843,6 +844,23 @@ free_tx:
        return err;
 }
 
+static int __maybe_unused tegra_bpmp_resume(struct device *dev)
+{
+       struct tegra_bpmp *bpmp = dev_get_drvdata(dev);
+       unsigned int i;
+
+       /* reset message channels */
+       tegra_bpmp_channel_reset(bpmp->tx_channel);
+       tegra_bpmp_channel_reset(bpmp->rx_channel);
+
+       for (i = 0; i < bpmp->threaded.count; i++)
+               tegra_bpmp_channel_reset(&bpmp->threaded_channels[i]);
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(tegra_bpmp_pm_ops, NULL, tegra_bpmp_resume);
+
 static const struct tegra_bpmp_soc tegra186_soc = {
        .channels = {
                .cpu_tx = {
@@ -871,6 +889,7 @@ static struct platform_driver tegra_bpmp_driver = {
        .driver = {
                .name = "tegra-bpmp",
                .of_match_table = tegra_bpmp_match,
+               .pm = &tegra_bpmp_pm_ops,
        },
        .probe = tegra_bpmp_probe,
 };
index 7fa744793bc5c900eb5d6998848aba233bd1875f..69ed1464175c058cfdeda0eb47faf470914477bc 100644 (file)
@@ -66,14 +66,14 @@ struct ti_sci_xfers_info {
 
 /**
  * struct ti_sci_desc - Description of SoC integration
- * @host_id:           Host identifier representing the compute entity
+ * @default_host_id:   Host identifier representing the compute entity
  * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
  * @max_msgs: Maximum number of messages that can be pending
  *               simultaneously in the system
  * @max_msg_size: Maximum size of data per message that can be handled.
  */
 struct ti_sci_desc {
-       u8 host_id;
+       u8 default_host_id;
        int max_rx_timeout_ms;
        int max_msgs;
        int max_msg_size;
@@ -94,6 +94,7 @@ struct ti_sci_desc {
  * @chan_rx:   Receive mailbox channel
  * @minfo:     Message info
  * @node:      list head
+ * @host_id:   Host ID
  * @users:     Number of users of this instance
  */
 struct ti_sci_info {
@@ -110,6 +111,7 @@ struct ti_sci_info {
        struct mbox_chan *chan_rx;
        struct ti_sci_xfers_info minfo;
        struct list_head node;
+       u8 host_id;
        /* protected by ti_sci_list_mutex */
        int users;
 
@@ -370,7 +372,7 @@ static struct ti_sci_xfer *ti_sci_get_one_xfer(struct ti_sci_info *info,
 
        hdr->seq = xfer_id;
        hdr->type = msg_type;
-       hdr->host = info->desc->host_id;
+       hdr->host = info->host_id;
        hdr->flags = msg_flags;
 
        return xfer;
@@ -1793,7 +1795,7 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
 
 /* Description for K2G */
 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
-       .host_id = 2,
+       .default_host_id = 2,
        /* Conservative duration */
        .max_rx_timeout_ms = 1000,
        /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
@@ -1819,6 +1821,7 @@ static int ti_sci_probe(struct platform_device *pdev)
        int ret = -EINVAL;
        int i;
        int reboot = 0;
+       u32 h_id;
 
        of_id = of_match_device(ti_sci_of_match, dev);
        if (!of_id) {
@@ -1833,6 +1836,19 @@ static int ti_sci_probe(struct platform_device *pdev)
 
        info->dev = dev;
        info->desc = desc;
+       ret = of_property_read_u32(dev->of_node, "ti,host-id", &h_id);
+       /* if the property is not present in DT, use a default from desc */
+       if (ret < 0) {
+               info->host_id = info->desc->default_host_id;
+       } else {
+               if (!h_id) {
+                       dev_warn(dev, "Host ID 0 is reserved for firmware\n");
+                       info->host_id = info->desc->default_host_id;
+               } else {
+                       info->host_id = h_id;
+               }
+       }
+
        reboot = of_property_read_bool(dev->of_node,
                                       "ti,system-reboot-controller");
        INIT_LIST_HEAD(&info->node);
diff --git a/drivers/firmware/xilinx/Kconfig b/drivers/firmware/xilinx/Kconfig
new file mode 100644 (file)
index 0000000..8f44b9c
--- /dev/null
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0
+# Kconfig for Xilinx firmwares
+
+menu "Zynq MPSoC Firmware Drivers"
+       depends on ARCH_ZYNQMP
+
+config ZYNQMP_FIRMWARE
+       bool "Enable Xilinx Zynq MPSoC firmware interface"
+       help
+         Firmware interface driver is used by different
+         drivers to communicate with the firmware for
+         various platform management services.
+         Say yes to enable ZynqMP firmware interface driver.
+         If in doubt, say N.
+
+config ZYNQMP_FIRMWARE_DEBUG
+       bool "Enable Xilinx Zynq MPSoC firmware debug APIs"
+       depends on ZYNQMP_FIRMWARE && DEBUG_FS
+       help
+         Say yes to enable ZynqMP firmware interface debug APIs.
+         If in doubt, say N.
+
+endmenu
diff --git a/drivers/firmware/xilinx/Makefile b/drivers/firmware/xilinx/Makefile
new file mode 100644 (file)
index 0000000..875a537
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for Xilinx firmwares
+
+obj-$(CONFIG_ZYNQMP_FIRMWARE) += zynqmp.o
+obj-$(CONFIG_ZYNQMP_FIRMWARE_DEBUG) += zynqmp-debug.o
diff --git a/drivers/firmware/xilinx/zynqmp-debug.c b/drivers/firmware/xilinx/zynqmp-debug.c
new file mode 100644 (file)
index 0000000..2771df6
--- /dev/null
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Zynq MPSoC Firmware layer for debugfs APIs
+ *
+ *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *
+ *  Michal Simek <michal.simek@xilinx.com>
+ *  Davorin Mista <davorin.mista@aggios.com>
+ *  Jolly Shah <jollys@xilinx.com>
+ *  Rajan Vaja <rajanv@xilinx.com>
+ */
+
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <linux/firmware/xlnx-zynqmp.h>
+#include "zynqmp-debug.h"
+
+#define PM_API_NAME_LEN                        50
+
+struct pm_api_info {
+       u32 api_id;
+       char api_name[PM_API_NAME_LEN];
+       char api_name_len;
+};
+
+static char debugfs_buf[PAGE_SIZE];
+
+#define PM_API(id)              {id, #id, strlen(#id)}
+static struct pm_api_info pm_api_list[] = {
+       PM_API(PM_GET_API_VERSION),
+       PM_API(PM_QUERY_DATA),
+};
+
+struct dentry *firmware_debugfs_root;
+
+/**
+ * zynqmp_pm_argument_value() - Extract argument value from a PM-API request
+ * @arg:       Entered PM-API argument in string format
+ *
+ * Return: Argument value in unsigned integer format on success
+ *        0 otherwise
+ */
+static u64 zynqmp_pm_argument_value(char *arg)
+{
+       u64 value;
+
+       if (!arg)
+               return 0;
+
+       if (!kstrtou64(arg, 0, &value))
+               return value;
+
+       return 0;
+}
+
+/**
+ * get_pm_api_id() - Extract API-ID from a PM-API request
+ * @pm_api_req:                Entered PM-API argument in string format
+ * @pm_id:             API-ID
+ *
+ * Return: 0 on success else error code
+ */
+static int get_pm_api_id(char *pm_api_req, u32 *pm_id)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(pm_api_list) ; i++) {
+               if (!strncasecmp(pm_api_req, pm_api_list[i].api_name,
+                                pm_api_list[i].api_name_len)) {
+                       *pm_id = pm_api_list[i].api_id;
+                       break;
+               }
+       }
+
+       /* If no name was entered look for PM-API ID instead */
+       if (i == ARRAY_SIZE(pm_api_list) && kstrtouint(pm_api_req, 10, pm_id))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int process_api_request(u32 pm_id, u64 *pm_api_arg, u32 *pm_api_ret)
+{
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+       u32 pm_api_version;
+       int ret;
+       struct zynqmp_pm_query_data qdata = {0};
+
+       if (!eemi_ops)
+               return -ENXIO;
+
+       switch (pm_id) {
+       case PM_GET_API_VERSION:
+               ret = eemi_ops->get_api_version(&pm_api_version);
+               sprintf(debugfs_buf, "PM-API Version = %d.%d\n",
+                       pm_api_version >> 16, pm_api_version & 0xffff);
+               break;
+       case PM_QUERY_DATA:
+               qdata.qid = pm_api_arg[0];
+               qdata.arg1 = pm_api_arg[1];
+               qdata.arg2 = pm_api_arg[2];
+               qdata.arg3 = pm_api_arg[3];
+
+               ret = eemi_ops->query_data(qdata, pm_api_ret);
+               if (ret)
+                       break;
+
+               switch (qdata.qid) {
+               case PM_QID_CLOCK_GET_NAME:
+                       sprintf(debugfs_buf, "Clock name = %s\n",
+                               (char *)pm_api_ret);
+                       break;
+               case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
+                       sprintf(debugfs_buf, "Multiplier = %d, Divider = %d\n",
+                               pm_api_ret[1], pm_api_ret[2]);
+                       break;
+               default:
+                       sprintf(debugfs_buf,
+                               "data[0] = 0x%08x\ndata[1] = 0x%08x\n data[2] = 0x%08x\ndata[3] = 0x%08x\n",
+                               pm_api_ret[0], pm_api_ret[1],
+                               pm_api_ret[2], pm_api_ret[3]);
+               }
+               break;
+       default:
+               sprintf(debugfs_buf, "Unsupported PM-API request\n");
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_debugfs_api_write() - debugfs write function
+ * @file:      User file
+ * @ptr:       User entered PM-API string
+ * @len:       Length of the userspace buffer
+ * @off:       Offset within the file
+ *
+ * Used for triggering pm api functions by writing
+ * echo <pm_api_id>    > /sys/kernel/debug/zynqmp_pm/power or
+ * echo <pm_api_name>  > /sys/kernel/debug/zynqmp_pm/power
+ *
+ * Return: Number of bytes copied if PM-API request succeeds,
+ *        the corresponding error code otherwise
+ */
+static ssize_t zynqmp_pm_debugfs_api_write(struct file *file,
+                                          const char __user *ptr, size_t len,
+                                          loff_t *off)
+{
+       char *kern_buff, *tmp_buff;
+       char *pm_api_req;
+       u32 pm_id = 0;
+       u64 pm_api_arg[4] = {0, 0, 0, 0};
+       /* Return values from PM APIs calls */
+       u32 pm_api_ret[4] = {0, 0, 0, 0};
+
+       int ret;
+       int i = 0;
+
+       strcpy(debugfs_buf, "");
+
+       if (*off != 0 || len == 0)
+               return -EINVAL;
+
+       kern_buff = kzalloc(len, GFP_KERNEL);
+       if (!kern_buff)
+               return -ENOMEM;
+
+       tmp_buff = kern_buff;
+
+       ret = strncpy_from_user(kern_buff, ptr, len);
+       if (ret < 0) {
+               ret = -EFAULT;
+               goto err;
+       }
+
+       /* Read the API name from a user request */
+       pm_api_req = strsep(&kern_buff, " ");
+
+       ret = get_pm_api_id(pm_api_req, &pm_id);
+       if (ret < 0)
+               goto err;
+
+       /* Read node_id and arguments from the PM-API request */
+       pm_api_req = strsep(&kern_buff, " ");
+       while ((i < ARRAY_SIZE(pm_api_arg)) && pm_api_req) {
+               pm_api_arg[i++] = zynqmp_pm_argument_value(pm_api_req);
+               pm_api_req = strsep(&kern_buff, " ");
+       }
+
+       ret = process_api_request(pm_id, pm_api_arg, pm_api_ret);
+
+err:
+       kfree(tmp_buff);
+       if (ret)
+               return ret;
+
+       return len;
+}
+
+/**
+ * zynqmp_pm_debugfs_api_read() - debugfs read function
+ * @file:      User file
+ * @ptr:       Requested pm_api_version string
+ * @len:       Length of the userspace buffer
+ * @off:       Offset within the file
+ *
+ * Return: Length of the version string on success
+ *        else error code
+ */
+static ssize_t zynqmp_pm_debugfs_api_read(struct file *file, char __user *ptr,
+                                         size_t len, loff_t *off)
+{
+       return simple_read_from_buffer(ptr, len, off, debugfs_buf,
+                                      strlen(debugfs_buf));
+}
+
+/* Setup debugfs fops */
+static const struct file_operations fops_zynqmp_pm_dbgfs = {
+       .owner = THIS_MODULE,
+       .write = zynqmp_pm_debugfs_api_write,
+       .read = zynqmp_pm_debugfs_api_read,
+};
+
+/**
+ * zynqmp_pm_api_debugfs_init - Initialize debugfs interface
+ *
+ * Return:     None
+ */
+void zynqmp_pm_api_debugfs_init(void)
+{
+       /* Initialize debugfs interface */
+       firmware_debugfs_root = debugfs_create_dir("zynqmp-firmware", NULL);
+       debugfs_create_file("pm", 0660, firmware_debugfs_root, NULL,
+                           &fops_zynqmp_pm_dbgfs);
+}
+
+/**
+ * zynqmp_pm_api_debugfs_exit - Remove debugfs interface
+ *
+ * Return:     None
+ */
+void zynqmp_pm_api_debugfs_exit(void)
+{
+       debugfs_remove_recursive(firmware_debugfs_root);
+}
diff --git a/drivers/firmware/xilinx/zynqmp-debug.h b/drivers/firmware/xilinx/zynqmp-debug.h
new file mode 100644 (file)
index 0000000..9929f8b
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Xilinx Zynq MPSoC Firmware layer
+ *
+ *  Copyright (C) 2014-2018 Xilinx
+ *
+ *  Michal Simek <michal.simek@xilinx.com>
+ *  Davorin Mista <davorin.mista@aggios.com>
+ *  Jolly Shah <jollys@xilinx.com>
+ *  Rajan Vaja <rajanv@xilinx.com>
+ */
+
+#ifndef __FIRMWARE_ZYNQMP_DEBUG_H__
+#define __FIRMWARE_ZYNQMP_DEBUG_H__
+
+#if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE_DEBUG)
+void zynqmp_pm_api_debugfs_init(void);
+void zynqmp_pm_api_debugfs_exit(void);
+#else
+static inline void zynqmp_pm_api_debugfs_init(void) { }
+static inline void zynqmp_pm_api_debugfs_exit(void) { }
+#endif
+
+#endif /* __FIRMWARE_ZYNQMP_DEBUG_H__ */
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
new file mode 100644 (file)
index 0000000..9a1c72a
--- /dev/null
@@ -0,0 +1,565 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Zynq MPSoC Firmware layer
+ *
+ *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *
+ *  Michal Simek <michal.simek@xilinx.com>
+ *  Davorin Mista <davorin.mista@aggios.com>
+ *  Jolly Shah <jollys@xilinx.com>
+ *  Rajan Vaja <rajanv@xilinx.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/compiler.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include <linux/firmware/xlnx-zynqmp.h>
+#include "zynqmp-debug.h"
+
+/**
+ * zynqmp_pm_ret_code() - Convert PMU-FW error codes to Linux error codes
+ * @ret_status:                PMUFW return code
+ *
+ * Return: corresponding Linux error code
+ */
+static int zynqmp_pm_ret_code(u32 ret_status)
+{
+       switch (ret_status) {
+       case XST_PM_SUCCESS:
+       case XST_PM_DOUBLE_REQ:
+               return 0;
+       case XST_PM_NO_ACCESS:
+               return -EACCES;
+       case XST_PM_ABORT_SUSPEND:
+               return -ECANCELED;
+       case XST_PM_INTERNAL:
+       case XST_PM_CONFLICT:
+       case XST_PM_INVALID_NODE:
+       default:
+               return -EINVAL;
+       }
+}
+
+static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2,
+                                   u32 *ret_payload)
+{
+       return -ENODEV;
+}
+
+/*
+ * PM function call wrapper
+ * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration
+ */
+static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) = do_fw_call_fail;
+
+/**
+ * do_fw_call_smc() - Call system-level platform management layer (SMC)
+ * @arg0:              Argument 0 to SMC call
+ * @arg1:              Argument 1 to SMC call
+ * @arg2:              Argument 2 to SMC call
+ * @ret_payload:       Returned value array
+ *
+ * Invoke platform management function via SMC call (no hypervisor present).
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2,
+                                  u32 *ret_payload)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
+
+       if (ret_payload) {
+               ret_payload[0] = lower_32_bits(res.a0);
+               ret_payload[1] = upper_32_bits(res.a0);
+               ret_payload[2] = lower_32_bits(res.a1);
+               ret_payload[3] = upper_32_bits(res.a1);
+       }
+
+       return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
+}
+
+/**
+ * do_fw_call_hvc() - Call system-level platform management layer (HVC)
+ * @arg0:              Argument 0 to HVC call
+ * @arg1:              Argument 1 to HVC call
+ * @arg2:              Argument 2 to HVC call
+ * @ret_payload:       Returned value array
+ *
+ * Invoke platform management function via HVC
+ * HVC-based for communication through hypervisor
+ * (no direct communication with ATF).
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
+                                  u32 *ret_payload)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
+
+       if (ret_payload) {
+               ret_payload[0] = lower_32_bits(res.a0);
+               ret_payload[1] = upper_32_bits(res.a0);
+               ret_payload[2] = lower_32_bits(res.a1);
+               ret_payload[3] = upper_32_bits(res.a1);
+       }
+
+       return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
+}
+
+/**
+ * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
+ *                        caller function depending on the configuration
+ * @pm_api_id:         Requested PM-API call
+ * @arg0:              Argument 0 to requested PM-API call
+ * @arg1:              Argument 1 to requested PM-API call
+ * @arg2:              Argument 2 to requested PM-API call
+ * @arg3:              Argument 3 to requested PM-API call
+ * @ret_payload:       Returned value array
+ *
+ * Invoke platform management function for SMC or HVC call, depending on
+ * configuration.
+ * Following SMC Calling Convention (SMCCC) for SMC64:
+ * Pm Function Identifier,
+ * PM_SIP_SVC + PM_API_ID =
+ *     ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)
+ *     ((SMC_64) << FUNCID_CC_SHIFT)
+ *     ((SIP_START) << FUNCID_OEN_SHIFT)
+ *     ((PM_API_ID) & FUNCID_NUM_MASK))
+ *
+ * PM_SIP_SVC  - Registered ZynqMP SIP Service Call.
+ * PM_API_ID   - Platform Management API ID.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
+                       u32 arg2, u32 arg3, u32 *ret_payload)
+{
+       /*
+        * Added SIP service call Function Identifier
+        * Make sure to stay in x0 register
+        */
+       u64 smc_arg[4];
+
+       smc_arg[0] = PM_SIP_SVC | pm_api_id;
+       smc_arg[1] = ((u64)arg1 << 32) | arg0;
+       smc_arg[2] = ((u64)arg3 << 32) | arg2;
+
+       return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload);
+}
+
+static u32 pm_api_version;
+static u32 pm_tz_version;
+
+/**
+ * zynqmp_pm_get_api_version() - Get version number of PMU PM firmware
+ * @version:   Returned version value
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_get_api_version(u32 *version)
+{
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       if (!version)
+               return -EINVAL;
+
+       /* Check is PM API version already verified */
+       if (pm_api_version > 0) {
+               *version = pm_api_version;
+               return 0;
+       }
+       ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload);
+       *version = ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version
+ * @version:   Returned version value
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_get_trustzone_version(u32 *version)
+{
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       if (!version)
+               return -EINVAL;
+
+       /* Check is PM trustzone version already verified */
+       if (pm_tz_version > 0) {
+               *version = pm_tz_version;
+               return 0;
+       }
+       ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, 0, 0,
+                                 0, 0, ret_payload);
+       *version = ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * get_set_conduit_method() - Choose SMC or HVC based communication
+ * @np:                Pointer to the device_node structure
+ *
+ * Use SMC or HVC-based functions to communicate with EL2/EL3.
+ *
+ * Return: Returns 0 on success or error code
+ */
+static int get_set_conduit_method(struct device_node *np)
+{
+       const char *method;
+
+       if (of_property_read_string(np, "method", &method)) {
+               pr_warn("%s missing \"method\" property\n", __func__);
+               return -ENXIO;
+       }
+
+       if (!strcmp("hvc", method)) {
+               do_fw_call = do_fw_call_hvc;
+       } else if (!strcmp("smc", method)) {
+               do_fw_call = do_fw_call_smc;
+       } else {
+               pr_warn("%s Invalid \"method\" property: %s\n",
+                       __func__, method);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * zynqmp_pm_query_data() - Get query data from firmware
+ * @qdata:     Variable to the zynqmp_pm_query_data structure
+ * @out:       Returned output value
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)
+{
+       int ret;
+
+       ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1,
+                                 qdata.arg2, qdata.arg3, out);
+
+       /*
+        * For clock name query, all bytes in SMC response are clock name
+        * characters and return code is always success. For invalid clocks,
+        * clock name bytes would be zeros.
+        */
+       return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret;
+}
+
+/**
+ * zynqmp_pm_clock_enable() - Enable the clock for given id
+ * @clock_id:  ID of the clock to be enabled
+ *
+ * This function is used by master to enable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_enable(u32 clock_id)
+{
+       return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL);
+}
+
+/**
+ * zynqmp_pm_clock_disable() - Disable the clock for given id
+ * @clock_id:  ID of the clock to be disable
+ *
+ * This function is used by master to disable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_disable(u32 clock_id)
+{
+       return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL);
+}
+
+/**
+ * zynqmp_pm_clock_getstate() - Get the clock state for given id
+ * @clock_id:  ID of the clock to be queried
+ * @state:     1/0 (Enabled/Disabled)
+ *
+ * This function is used by master to get the state of clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
+{
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0,
+                                 0, 0, ret_payload);
+       *state = ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_clock_setdivider() - Set the clock divider for given id
+ * @clock_id:  ID of the clock
+ * @divider:   divider value
+ *
+ * This function is used by master to set divider for any clock
+ * to achieve desired rate.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
+{
+       return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider,
+                                  0, 0, NULL);
+}
+
+/**
+ * zynqmp_pm_clock_getdivider() - Get the clock divider for given id
+ * @clock_id:  ID of the clock
+ * @divider:   divider value
+ *
+ * This function is used by master to get divider values
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
+{
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0,
+                                 0, 0, ret_payload);
+       *divider = ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_clock_setrate() - Set the clock rate for given id
+ * @clock_id:  ID of the clock
+ * @rate:      rate value in hz
+ *
+ * This function is used by master to set rate for any clock.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate)
+{
+       return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id,
+                                  lower_32_bits(rate),
+                                  upper_32_bits(rate),
+                                  0, NULL);
+}
+
+/**
+ * zynqmp_pm_clock_getrate() - Get the clock rate for given id
+ * @clock_id:  ID of the clock
+ * @rate:      rate value in hz
+ *
+ * This function is used by master to get rate
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate)
+{
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0,
+                                 0, 0, ret_payload);
+       *rate = ((u64)ret_payload[2] << 32) | ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * zynqmp_pm_clock_setparent() - Set the clock parent for given id
+ * @clock_id:  ID of the clock
+ * @parent_id: parent id
+ *
+ * This function is used by master to set parent for any clock.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id)
+{
+       return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id,
+                                  parent_id, 0, 0, NULL);
+}
+
+/**
+ * zynqmp_pm_clock_getparent() - Get the clock parent for given id
+ * @clock_id:  ID of the clock
+ * @parent_id: parent id
+ *
+ * This function is used by master to get parent index
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)
+{
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0,
+                                 0, 0, ret_payload);
+       *parent_id = ret_payload[1];
+
+       return ret;
+}
+
+/**
+ * zynqmp_is_valid_ioctl() - Check whether IOCTL ID is valid or not
+ * @ioctl_id:  IOCTL ID
+ *
+ * Return: 1 if IOCTL is valid else 0
+ */
+static inline int zynqmp_is_valid_ioctl(u32 ioctl_id)
+{
+       switch (ioctl_id) {
+       case IOCTL_SET_PLL_FRAC_MODE:
+       case IOCTL_GET_PLL_FRAC_MODE:
+       case IOCTL_SET_PLL_FRAC_DATA:
+       case IOCTL_GET_PLL_FRAC_DATA:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/**
+ * zynqmp_pm_ioctl() - PM IOCTL API for device control and configs
+ * @node_id:   Node ID of the device
+ * @ioctl_id:  ID of the requested IOCTL
+ * @arg1:      Argument 1 to requested IOCTL call
+ * @arg2:      Argument 2 to requested IOCTL call
+ * @out:       Returned output value
+ *
+ * This function calls IOCTL to firmware for device control and configuration.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2,
+                          u32 *out)
+{
+       if (!zynqmp_is_valid_ioctl(ioctl_id))
+               return -EINVAL;
+
+       return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, ioctl_id,
+                                  arg1, arg2, out);
+}
+
+static const struct zynqmp_eemi_ops eemi_ops = {
+       .get_api_version = zynqmp_pm_get_api_version,
+       .query_data = zynqmp_pm_query_data,
+       .clock_enable = zynqmp_pm_clock_enable,
+       .clock_disable = zynqmp_pm_clock_disable,
+       .clock_getstate = zynqmp_pm_clock_getstate,
+       .clock_setdivider = zynqmp_pm_clock_setdivider,
+       .clock_getdivider = zynqmp_pm_clock_getdivider,
+       .clock_setrate = zynqmp_pm_clock_setrate,
+       .clock_getrate = zynqmp_pm_clock_getrate,
+       .clock_setparent = zynqmp_pm_clock_setparent,
+       .clock_getparent = zynqmp_pm_clock_getparent,
+       .ioctl = zynqmp_pm_ioctl,
+};
+
+/**
+ * zynqmp_pm_get_eemi_ops - Get eemi ops functions
+ *
+ * Return: Pointer of eemi_ops structure
+ */
+const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void)
+{
+       return &eemi_ops;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_get_eemi_ops);
+
+static int zynqmp_firmware_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np;
+       int ret;
+
+       np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp");
+       if (!np)
+               return 0;
+       of_node_put(np);
+
+       ret = get_set_conduit_method(dev->of_node);
+       if (ret)
+               return ret;
+
+       /* Check PM API version number */
+       zynqmp_pm_get_api_version(&pm_api_version);
+       if (pm_api_version < ZYNQMP_PM_VERSION) {
+               panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n",
+                     __func__,
+                     ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR,
+                     pm_api_version >> 16, pm_api_version & 0xFFFF);
+       }
+
+       pr_info("%s Platform Management API v%d.%d\n", __func__,
+               pm_api_version >> 16, pm_api_version & 0xFFFF);
+
+       /* Check trustzone version number */
+       ret = zynqmp_pm_get_trustzone_version(&pm_tz_version);
+       if (ret)
+               panic("Legacy trustzone found without version support\n");
+
+       if (pm_tz_version < ZYNQMP_TZ_VERSION)
+               panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n",
+                     __func__,
+                     ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR,
+                     pm_tz_version >> 16, pm_tz_version & 0xFFFF);
+
+       pr_info("%s Trustzone version v%d.%d\n", __func__,
+               pm_tz_version >> 16, pm_tz_version & 0xFFFF);
+
+       zynqmp_pm_api_debugfs_init();
+
+       return of_platform_populate(dev->of_node, NULL, NULL, dev);
+}
+
+static int zynqmp_firmware_remove(struct platform_device *pdev)
+{
+       zynqmp_pm_api_debugfs_exit();
+
+       return 0;
+}
+
+static const struct of_device_id zynqmp_firmware_of_match[] = {
+       {.compatible = "xlnx,zynqmp-firmware"},
+       {},
+};
+MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match);
+
+static struct platform_driver zynqmp_firmware_driver = {
+       .driver = {
+               .name = "zynqmp_firmware",
+               .of_match_table = zynqmp_firmware_of_match,
+       },
+       .probe = zynqmp_firmware_probe,
+       .remove = zynqmp_firmware_remove,
+};
+module_platform_driver(zynqmp_firmware_driver);
index 954eefe144e2d49764f9b345b2045738804c0e85..aa0e30a2ba18262573bc346f46bf2c5177812fd0 100644 (file)
@@ -232,7 +232,7 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code,
        case MEDIA_BUS_FMT_BGR565_2X8_LE:
        case MEDIA_BUS_FMT_RGB565_2X8_BE:
        case MEDIA_BUS_FMT_RGB565_2X8_LE:
-               if (mbus_type == V4L2_MBUS_CSI2)
+               if (mbus_type == V4L2_MBUS_CSI2_DPHY)
                        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
                else
                        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
@@ -359,7 +359,7 @@ static int fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg,
                else
                        csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE;
                break;
-       case V4L2_MBUS_CSI2:
+       case V4L2_MBUS_CSI2_DPHY:
                /*
                 * MIPI CSI-2 requires non gated clock mode, all other
                 * parameters are not applicable for MIPI CSI-2 bus.
@@ -611,7 +611,7 @@ int ipu_csi_set_mipi_datatype(struct ipu_csi *csi, u32 vc,
        if (vc > 3)
                return -EINVAL;
 
-       ret = mbus_code_to_bus_cfg(&cfg, mbus_fmt->code, V4L2_MBUS_CSI2);
+       ret = mbus_code_to_bus_cfg(&cfg, mbus_fmt->code, V4L2_MBUS_CSI2_DPHY);
        if (ret < 0)
                return ret;
 
index 5ed319e3b084d920cddf6adc5a665c5732c8c77c..41e9935fc5849e0992e3103912fbe01a5af2a555 100644 (file)
@@ -149,6 +149,7 @@ config HID_APPLEIR
 config HID_ASUS
        tristate "Asus"
        depends on LEDS_CLASS
+       depends on ASUS_WMI || ASUS_WMI=n
        ---help---
        Support for Asus notebook built-in keyboard and touchpad via i2c, and
        the Asus Republic of Gamers laptop keyboard special keys.
index 88a5672f42cd814187ede87e8783414023824bf2..dc6d6477e9611eb2ba93a8d687bfaf9d4e634ef8 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/dmi.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/platform_data/x86/asus-wmi.h>
 #include <linux/input/mt.h>
 #include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
 
@@ -349,6 +350,24 @@ static void asus_kbd_backlight_work(struct work_struct *work)
                hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret);
 }
 
+/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
+ * precedence. We only activate HID-based backlight control when the
+ * WMI control is not available.
+ */
+static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
+{
+       u32 value;
+       int ret;
+
+       ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2,
+                                      ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
+       hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
+       if (ret)
+               return false;
+
+       return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT);
+}
+
 static int asus_kbd_register_leds(struct hid_device *hdev)
 {
        struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
@@ -436,7 +455,9 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
 
        drvdata->input = input;
 
-       if (drvdata->enable_backlight && asus_kbd_register_leds(hdev))
+       if (drvdata->enable_backlight &&
+           !asus_kbd_wmi_led_control_present(hdev) &&
+           asus_kbd_register_leds(hdev))
                hid_warn(hdev, "Failed to initialize backlight.\n");
 
        return 0;
index 567c3bf64515d3599946c1d74aa79d52d9a61620..a2f74e6adc70d162adf641ac3f02ae452e3552a3 100644 (file)
@@ -1855,31 +1855,30 @@ EXPORT_SYMBOL_GPL(hidinput_disconnect);
 void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
                                      int hi_res_value)
 {
-       int low_res_scroll_amount;
-       /* Some wheels will rest 7/8ths of a notch from the previous notch
-        * after slow movement, so we want the threshold for low-res events to
-        * be in the middle of the notches (e.g. after 4/8ths) as opposed to on
-        * the notches themselves (8/8ths).
-        */
-       int threshold = counter->resolution_multiplier / 2;
+       int low_res_value, remainder, multiplier;
 
        input_report_rel(counter->dev, REL_WHEEL_HI_RES,
                         hi_res_value * counter->microns_per_hi_res_unit);
 
-       counter->remainder += hi_res_value;
-       if (abs(counter->remainder) >= threshold) {
-               /* Add (or subtract) 1 because we want to trigger when the wheel
-                * is half-way to the next notch (i.e. scroll 1 notch after a
-                * 1/2 notch movement, 2 notches after a 1 1/2 notch movement,
-                * etc.).
-                */
-               low_res_scroll_amount =
-                       counter->remainder / counter->resolution_multiplier
-                       + (hi_res_value > 0 ? 1 : -1);
-               input_report_rel(counter->dev, REL_WHEEL,
-                                low_res_scroll_amount);
-               counter->remainder -=
-                       low_res_scroll_amount * counter->resolution_multiplier;
-       }
+       /*
+        * Update the low-res remainder with the high-res value,
+        * but reset if the direction has changed.
+        */
+       remainder = counter->remainder;
+       if ((remainder ^ hi_res_value) < 0)
+               remainder = 0;
+       remainder += hi_res_value;
+
+       /*
+        * Then just use the resolution multiplier to see if
+        * we should send a low-res (aka regular wheel) event.
+        */
+       multiplier = counter->resolution_multiplier;
+       low_res_value = remainder / multiplier;
+       remainder -= low_res_value * multiplier;
+       counter->remainder = remainder;
+
+       if (low_res_value)
+               input_report_rel(counter->dev, REL_WHEEL, low_res_value);
 }
 EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
index 32747b7f917ee40ec63709df72bb5b3c53337445..bf6f29ca33151014d92fad911ee33f71fefaa68b 100644 (file)
@@ -45,7 +45,7 @@ int picolcd_raw_cir(struct picolcd_data *data,
 {
        unsigned long flags;
        int i, w, sz;
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        /* ignore if rc_dev is NULL or status is shunned */
        spin_lock_irqsave(&data->lock, flags);
@@ -67,7 +67,6 @@ int picolcd_raw_cir(struct picolcd_data *data,
         */
        sz = size > 0 ? min((int)raw_data[0], size-1) : 0;
        for (i = 0; i+1 < sz; i += 2) {
-               init_ir_raw_event(&rawir);
                w = (raw_data[i] << 8) | (raw_data[i+1]);
                rawir.pulse = !!(w & 0x8000);
                rawir.duration = US_TO_NS(rawir.pulse ? (65536 - w) : w);
index 451d4ae50e665bfcbcdabe7d7a0aceb8a0e1e29a..56ccb1ea7da5b405e904d90ac38b17303a3d2faa 100644 (file)
@@ -432,12 +432,13 @@ config I2C_BCM_KONA
          If you do not need KONA I2C interface, say N.
 
 config I2C_BRCMSTB
-       tristate "BRCM Settop I2C controller"
-       depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
+       tristate "BRCM Settop/DSL I2C controller"
+       depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_63XX || \
+                  COMPILE_TEST
        default y
        help
          If you say yes to this option, support will be included for the
-         I2C interface on the Broadcom Settop SoCs.
+         I2C interface on the Broadcom Settop/DSL SoCs.
 
          If you do not need I2C interface, say N.
 
index a4f956c6d567d4b380505b0da1eedba97b795360..8dc9161ced38adace56fcbd9c620c0afc8b9cd4a 100644 (file)
 #define ASPEED_I2CD_INTR_RX_DONE                       BIT(2)
 #define ASPEED_I2CD_INTR_TX_NAK                                BIT(1)
 #define ASPEED_I2CD_INTR_TX_ACK                                BIT(0)
+#define ASPEED_I2CD_INTR_MASTER_ERRORS                                        \
+               (ASPEED_I2CD_INTR_SDA_DL_TIMEOUT |                             \
+                ASPEED_I2CD_INTR_SCL_TIMEOUT |                                \
+                ASPEED_I2CD_INTR_ABNORMAL |                                   \
+                ASPEED_I2CD_INTR_ARBIT_LOSS)
 #define ASPEED_I2CD_INTR_ALL                                                  \
                (ASPEED_I2CD_INTR_SDA_DL_TIMEOUT |                             \
                 ASPEED_I2CD_INTR_BUS_RECOVER_DONE |                           \
@@ -137,7 +142,8 @@ struct aspeed_i2c_bus {
        /* Synchronizes I/O mem access to base. */
        spinlock_t                      lock;
        struct completion               cmd_complete;
-       u32                             (*get_clk_reg_val)(u32 divisor);
+       u32                             (*get_clk_reg_val)(struct device *dev,
+                                                          u32 divisor);
        unsigned long                   parent_clk_frequency;
        u32                             bus_frequency;
        /* Transaction state. */
@@ -227,32 +233,26 @@ reset_out:
 }
 
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
-static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
+static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
 {
-       u32 command, irq_status, status_ack = 0;
+       u32 command, irq_handled = 0;
        struct i2c_client *slave = bus->slave;
-       bool irq_handled = true;
        u8 value;
 
-       if (!slave) {
-               irq_handled = false;
-               goto out;
-       }
+       if (!slave)
+               return 0;
 
        command = readl(bus->base + ASPEED_I2C_CMD_REG);
-       irq_status = readl(bus->base + ASPEED_I2C_INTR_STS_REG);
 
        /* Slave was requested, restart state machine. */
        if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) {
-               status_ack |= ASPEED_I2CD_INTR_SLAVE_MATCH;
+               irq_handled |= ASPEED_I2CD_INTR_SLAVE_MATCH;
                bus->slave_state = ASPEED_I2C_SLAVE_START;
        }
 
        /* Slave is not currently active, irq was for someone else. */
-       if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) {
-               irq_handled = false;
-               goto out;
-       }
+       if (bus->slave_state == ASPEED_I2C_SLAVE_STOP)
+               return irq_handled;
 
        dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n",
                irq_status, command);
@@ -269,31 +269,31 @@ static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
                                bus->slave_state =
                                                ASPEED_I2C_SLAVE_WRITE_REQUESTED;
                }
-               status_ack |= ASPEED_I2CD_INTR_RX_DONE;
+               irq_handled |= ASPEED_I2CD_INTR_RX_DONE;
        }
 
        /* Slave was asked to stop. */
        if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
-               status_ack |= ASPEED_I2CD_INTR_NORMAL_STOP;
+               irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP;
                bus->slave_state = ASPEED_I2C_SLAVE_STOP;
        }
        if (irq_status & ASPEED_I2CD_INTR_TX_NAK) {
-               status_ack |= ASPEED_I2CD_INTR_TX_NAK;
+               irq_handled |= ASPEED_I2CD_INTR_TX_NAK;
                bus->slave_state = ASPEED_I2C_SLAVE_STOP;
        }
+       if (irq_status & ASPEED_I2CD_INTR_TX_ACK)
+               irq_handled |= ASPEED_I2CD_INTR_TX_ACK;
 
        switch (bus->slave_state) {
        case ASPEED_I2C_SLAVE_READ_REQUESTED:
                if (irq_status & ASPEED_I2CD_INTR_TX_ACK)
                        dev_err(bus->dev, "Unexpected ACK on read request.\n");
                bus->slave_state = ASPEED_I2C_SLAVE_READ_PROCESSED;
-
                i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value);
                writel(value, bus->base + ASPEED_I2C_BYTE_BUF_REG);
                writel(ASPEED_I2CD_S_TX_CMD, bus->base + ASPEED_I2C_CMD_REG);
                break;
        case ASPEED_I2C_SLAVE_READ_PROCESSED:
-               status_ack |= ASPEED_I2CD_INTR_TX_ACK;
                if (!(irq_status & ASPEED_I2CD_INTR_TX_ACK))
                        dev_err(bus->dev,
                                "Expected ACK after processed read.\n");
@@ -317,13 +317,6 @@ static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
                break;
        }
 
-       if (status_ack != irq_status)
-               dev_err(bus->dev,
-                       "irq handled != irq. expected %x, but was %x\n",
-                       irq_status, status_ack);
-       writel(status_ack, bus->base + ASPEED_I2C_INTR_STS_REG);
-
-out:
        return irq_handled;
 }
 #endif /* CONFIG_I2C_SLAVE */
@@ -380,21 +373,21 @@ static int aspeed_i2c_is_irq_error(u32 irq_status)
        return 0;
 }
 
-static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
+static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
 {
-       u32 irq_status, status_ack = 0, command = 0;
+       u32 irq_handled = 0, command = 0;
        struct i2c_msg *msg;
        u8 recv_byte;
        int ret;
 
-       irq_status = readl(bus->base + ASPEED_I2C_INTR_STS_REG);
-       /* Ack all interrupt bits. */
-       writel(irq_status, bus->base + ASPEED_I2C_INTR_STS_REG);
-
        if (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE) {
                bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
-               status_ack |= ASPEED_I2CD_INTR_BUS_RECOVER_DONE;
+               irq_handled |= ASPEED_I2CD_INTR_BUS_RECOVER_DONE;
                goto out_complete;
+       } else {
+               /* Master is not currently active, irq was for someone else. */
+               if (bus->master_state == ASPEED_I2C_MASTER_INACTIVE)
+                       goto out_no_complete;
        }
 
        /*
@@ -403,19 +396,22 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
         * INACTIVE state.
         */
        ret = aspeed_i2c_is_irq_error(irq_status);
-       if (ret < 0) {
+       if (ret) {
                dev_dbg(bus->dev, "received error interrupt: 0x%08x\n",
                        irq_status);
                bus->cmd_err = ret;
                bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
+               irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS);
                goto out_complete;
        }
 
        /* We are in an invalid state; reset bus to a known state. */
        if (!bus->msgs) {
-               dev_err(bus->dev, "bus in unknown state\n");
+               dev_err(bus->dev, "bus in unknown state. irq_status: 0x%x\n",
+                       irq_status);
                bus->cmd_err = -EIO;
-               if (bus->master_state != ASPEED_I2C_MASTER_STOP)
+               if (bus->master_state != ASPEED_I2C_MASTER_STOP &&
+                   bus->master_state != ASPEED_I2C_MASTER_INACTIVE)
                        aspeed_i2c_do_stop(bus);
                goto out_no_complete;
        }
@@ -428,13 +424,18 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
         */
        if (bus->master_state == ASPEED_I2C_MASTER_START) {
                if (unlikely(!(irq_status & ASPEED_I2CD_INTR_TX_ACK))) {
+                       if (unlikely(!(irq_status & ASPEED_I2CD_INTR_TX_NAK))) {
+                               bus->cmd_err = -ENXIO;
+                               bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
+                               goto out_complete;
+                       }
                        pr_devel("no slave present at %02x\n", msg->addr);
-                       status_ack |= ASPEED_I2CD_INTR_TX_NAK;
+                       irq_handled |= ASPEED_I2CD_INTR_TX_NAK;
                        bus->cmd_err = -ENXIO;
                        aspeed_i2c_do_stop(bus);
                        goto out_no_complete;
                }
-               status_ack |= ASPEED_I2CD_INTR_TX_ACK;
+               irq_handled |= ASPEED_I2CD_INTR_TX_ACK;
                if (msg->len == 0) { /* SMBUS_QUICK */
                        aspeed_i2c_do_stop(bus);
                        goto out_no_complete;
@@ -449,14 +450,14 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
        case ASPEED_I2C_MASTER_TX:
                if (unlikely(irq_status & ASPEED_I2CD_INTR_TX_NAK)) {
                        dev_dbg(bus->dev, "slave NACKed TX\n");
-                       status_ack |= ASPEED_I2CD_INTR_TX_NAK;
+                       irq_handled |= ASPEED_I2CD_INTR_TX_NAK;
                        goto error_and_stop;
                } else if (unlikely(!(irq_status & ASPEED_I2CD_INTR_TX_ACK))) {
                        dev_err(bus->dev, "slave failed to ACK TX\n");
                        goto error_and_stop;
                }
-               status_ack |= ASPEED_I2CD_INTR_TX_ACK;
-               /* fallthrough intended */
+               irq_handled |= ASPEED_I2CD_INTR_TX_ACK;
+               /* fall through */
        case ASPEED_I2C_MASTER_TX_FIRST:
                if (bus->buf_index < msg->len) {
                        bus->master_state = ASPEED_I2C_MASTER_TX;
@@ -472,13 +473,13 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
                /* RX may not have completed yet (only address cycle) */
                if (!(irq_status & ASPEED_I2CD_INTR_RX_DONE))
                        goto out_no_complete;
-               /* fallthrough intended */
+               /* fall through */
        case ASPEED_I2C_MASTER_RX:
                if (unlikely(!(irq_status & ASPEED_I2CD_INTR_RX_DONE))) {
                        dev_err(bus->dev, "master failed to RX\n");
                        goto error_and_stop;
                }
-               status_ack |= ASPEED_I2CD_INTR_RX_DONE;
+               irq_handled |= ASPEED_I2CD_INTR_RX_DONE;
 
                recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8;
                msg->buf[bus->buf_index++] = recv_byte;
@@ -506,11 +507,13 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
                goto out_no_complete;
        case ASPEED_I2C_MASTER_STOP:
                if (unlikely(!(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP))) {
-                       dev_err(bus->dev, "master failed to STOP\n");
+                       dev_err(bus->dev,
+                               "master failed to STOP. irq_status:0x%x\n",
+                               irq_status);
                        bus->cmd_err = -EIO;
                        /* Do not STOP as we have already tried. */
                } else {
-                       status_ack |= ASPEED_I2CD_INTR_NORMAL_STOP;
+                       irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP;
                }
 
                bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
@@ -540,33 +543,57 @@ out_complete:
                bus->master_xfer_result = bus->msgs_index + 1;
        complete(&bus->cmd_complete);
 out_no_complete:
-       if (irq_status != status_ack)
-               dev_err(bus->dev,
-                       "irq handled != irq. expected 0x%08x, but was 0x%08x\n",
-                       irq_status, status_ack);
-       return !!irq_status;
+       return irq_handled;
 }
 
 static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
 {
        struct aspeed_i2c_bus *bus = dev_id;
-       bool ret;
+       u32 irq_received, irq_remaining, irq_handled;
 
        spin_lock(&bus->lock);
+       irq_received = readl(bus->base + ASPEED_I2C_INTR_STS_REG);
+       /* Ack all interrupts except for Rx done */
+       writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
+              bus->base + ASPEED_I2C_INTR_STS_REG);
+       irq_remaining = irq_received;
 
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
-       if (aspeed_i2c_slave_irq(bus)) {
-               dev_dbg(bus->dev, "irq handled by slave.\n");
-               ret = true;
-               goto out;
+       /*
+        * In most cases, interrupt bits will be set one by one, although
+        * multiple interrupt bits could be set at the same time. It's also
+        * possible that master interrupt bits could be set along with slave
+        * interrupt bits. Each case needs to be handled using corresponding
+        * handlers depending on the current state.
+        */
+       if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) {
+               irq_handled = aspeed_i2c_master_irq(bus, irq_remaining);
+               irq_remaining &= ~irq_handled;
+               if (irq_remaining)
+                       irq_handled |= aspeed_i2c_slave_irq(bus, irq_remaining);
+       } else {
+               irq_handled = aspeed_i2c_slave_irq(bus, irq_remaining);
+               irq_remaining &= ~irq_handled;
+               if (irq_remaining)
+                       irq_handled |= aspeed_i2c_master_irq(bus,
+                                                            irq_remaining);
        }
+#else
+       irq_handled = aspeed_i2c_master_irq(bus, irq_remaining);
 #endif /* CONFIG_I2C_SLAVE */
 
-       ret = aspeed_i2c_master_irq(bus);
+       irq_remaining &= ~irq_handled;
+       if (irq_remaining)
+               dev_err(bus->dev,
+                       "irq handled != irq. expected 0x%08x, but was 0x%08x\n",
+                       irq_received, irq_handled);
 
-out:
+       /* Ack Rx done */
+       if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
+               writel(ASPEED_I2CD_INTR_RX_DONE,
+                      bus->base + ASPEED_I2C_INTR_STS_REG);
        spin_unlock(&bus->lock);
-       return ret ? IRQ_HANDLED : IRQ_NONE;
+       return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
 }
 
 static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
@@ -684,16 +711,27 @@ static const struct i2c_algorithm aspeed_i2c_algo = {
 #endif /* CONFIG_I2C_SLAVE */
 };
 
-static u32 aspeed_i2c_get_clk_reg_val(u32 clk_high_low_max, u32 divisor)
+static u32 aspeed_i2c_get_clk_reg_val(struct device *dev,
+                                     u32 clk_high_low_mask,
+                                     u32 divisor)
 {
-       u32 base_clk, clk_high, clk_low, tmp;
+       u32 base_clk_divisor, clk_high_low_max, clk_high, clk_low, tmp;
+
+       /*
+        * SCL_high and SCL_low represent a value 1 greater than what is stored
+        * since a zero divider is meaningless. Thus, the max value each can
+        * store is every bit set + 1. Since SCL_high and SCL_low are added
+        * together (see below), the max value of both is the max value of one
+        * them times two.
+        */
+       clk_high_low_max = (clk_high_low_mask + 1) * 2;
 
        /*
         * The actual clock frequency of SCL is:
         *      SCL_freq = APB_freq / (base_freq * (SCL_high + SCL_low))
         *               = APB_freq / divisor
         * where base_freq is a programmable clock divider; its value is
-        *      base_freq = 1 << base_clk
+        *      base_freq = 1 << base_clk_divisor
         * SCL_high is the number of base_freq clock cycles that SCL stays high
         * and SCL_low is the number of base_freq clock cycles that SCL stays
         * low for a period of SCL.
@@ -703,47 +741,59 @@ static u32 aspeed_i2c_get_clk_reg_val(u32 clk_high_low_max, u32 divisor)
         *      SCL_low  = clk_low + 1
         * Thus,
         *      SCL_freq = APB_freq /
-        *              ((1 << base_clk) * (clk_high + 1 + clk_low + 1))
+        *              ((1 << base_clk_divisor) * (clk_high + 1 + clk_low + 1))
         * The documentation recommends clk_high >= clk_high_max / 2 and
         * clk_low >= clk_low_max / 2 - 1 when possible; this last constraint
         * gives us the following solution:
         */
-       base_clk = divisor > clk_high_low_max ?
+       base_clk_divisor = divisor > clk_high_low_max ?
                        ilog2((divisor - 1) / clk_high_low_max) + 1 : 0;
-       tmp = (divisor + (1 << base_clk) - 1) >> base_clk;
-       clk_low = tmp / 2;
-       clk_high = tmp - clk_low;
 
-       if (clk_high)
-               clk_high--;
+       if (base_clk_divisor > ASPEED_I2CD_TIME_BASE_DIVISOR_MASK) {
+               base_clk_divisor = ASPEED_I2CD_TIME_BASE_DIVISOR_MASK;
+               clk_low = clk_high_low_mask;
+               clk_high = clk_high_low_mask;
+               dev_err(dev,
+                       "clamping clock divider: divider requested, %u, is greater than largest possible divider, %u.\n",
+                       divisor, (1 << base_clk_divisor) * clk_high_low_max);
+       } else {
+               tmp = (divisor + (1 << base_clk_divisor) - 1)
+                               >> base_clk_divisor;
+               clk_low = tmp / 2;
+               clk_high = tmp - clk_low;
+
+               if (clk_high)
+                       clk_high--;
 
-       if (clk_low)
-               clk_low--;
+               if (clk_low)
+                       clk_low--;
+       }
 
 
        return ((clk_high << ASPEED_I2CD_TIME_SCL_HIGH_SHIFT)
                & ASPEED_I2CD_TIME_SCL_HIGH_MASK)
                        | ((clk_low << ASPEED_I2CD_TIME_SCL_LOW_SHIFT)
                           & ASPEED_I2CD_TIME_SCL_LOW_MASK)
-                       | (base_clk & ASPEED_I2CD_TIME_BASE_DIVISOR_MASK);
+                       | (base_clk_divisor
+                          & ASPEED_I2CD_TIME_BASE_DIVISOR_MASK);
 }
 
-static u32 aspeed_i2c_24xx_get_clk_reg_val(u32 divisor)
+static u32 aspeed_i2c_24xx_get_clk_reg_val(struct device *dev, u32 divisor)
 {
        /*
         * clk_high and clk_low are each 3 bits wide, so each can hold a max
         * value of 8 giving a clk_high_low_max of 16.
         */
-       return aspeed_i2c_get_clk_reg_val(16, divisor);
+       return aspeed_i2c_get_clk_reg_val(dev, GENMASK(2, 0), divisor);
 }
 
-static u32 aspeed_i2c_25xx_get_clk_reg_val(u32 divisor)
+static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev, u32 divisor)
 {
        /*
         * clk_high and clk_low are each 4 bits wide, so each can hold a max
         * value of 16 giving a clk_high_low_max of 32.
         */
-       return aspeed_i2c_get_clk_reg_val(32, divisor);
+       return aspeed_i2c_get_clk_reg_val(dev, GENMASK(3, 0), divisor);
 }
 
 /* precondition: bus.lock has been acquired. */
@@ -756,7 +806,7 @@ static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus)
        clk_reg_val &= (ASPEED_I2CD_TIME_TBUF_MASK |
                        ASPEED_I2CD_TIME_THDSTA_MASK |
                        ASPEED_I2CD_TIME_TACST_MASK);
-       clk_reg_val |= bus->get_clk_reg_val(divisor);
+       clk_reg_val |= bus->get_clk_reg_val(bus->dev, divisor);
        writel(clk_reg_val, bus->base + ASPEED_I2C_AC_TIMING_REG1);
        writel(ASPEED_NO_TIMEOUT_CTRL, bus->base + ASPEED_I2C_AC_TIMING_REG2);
 
@@ -872,7 +922,8 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
        if (!match)
                bus->get_clk_reg_val = aspeed_i2c_24xx_get_clk_reg_val;
        else
-               bus->get_clk_reg_val = (u32 (*)(u32))match->data;
+               bus->get_clk_reg_val = (u32 (*)(struct device *, u32))
+                               match->data;
 
        /* Initialize the I2C adapter */
        spin_lock_init(&bus->lock);
index a2a275cfc1f694896bf112b2862f1bd8f2530ece..33da07d6449475317385bcc3b72eede8fd52d561 100644 (file)
  * Intel BayTrail PMIC I2C bus semaphore implementaion
  * Copyright (c) 2014, Intel Corporation.
  */
-#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
-#include <linux/pm_qos.h>
 
 #include <asm/iosf_mbi.h>
 
 #include "i2c-designware-core.h"
 
-#define SEMAPHORE_TIMEOUT      500
-#define PUNIT_SEMAPHORE                0x7
-#define PUNIT_SEMAPHORE_CHT    0x10e
-#define PUNIT_SEMAPHORE_BIT    BIT(0)
-#define PUNIT_SEMAPHORE_ACQUIRE        BIT(1)
-
-static unsigned long acquired;
-
-static u32 get_sem_addr(struct dw_i2c_dev *dev)
-{
-       if (dev->flags & MODEL_CHERRYTRAIL)
-               return PUNIT_SEMAPHORE_CHT;
-       else
-               return PUNIT_SEMAPHORE;
-}
-
-static int get_sem(struct dw_i2c_dev *dev, u32 *sem)
-{
-       u32 addr = get_sem_addr(dev);
-       u32 data;
-       int ret;
-
-       ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &data);
-       if (ret) {
-               dev_err(dev->dev, "iosf failed to read punit semaphore\n");
-               return ret;
-       }
-
-       *sem = data & PUNIT_SEMAPHORE_BIT;
-
-       return 0;
-}
-
-static void reset_semaphore(struct dw_i2c_dev *dev)
-{
-       if (iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, get_sem_addr(dev),
-                           0, PUNIT_SEMAPHORE_BIT))
-               dev_err(dev->dev, "iosf failed to reset punit semaphore during write\n");
-
-       pm_qos_update_request(&dev->pm_qos, PM_QOS_DEFAULT_VALUE);
-
-       iosf_mbi_call_pmic_bus_access_notifier_chain(MBI_PMIC_BUS_ACCESS_END,
-                                                    NULL);
-       iosf_mbi_punit_release();
-}
-
-static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
-{
-       u32 addr;
-       u32 sem = PUNIT_SEMAPHORE_ACQUIRE;
-       int ret;
-       unsigned long start, end;
-
-       might_sleep();
-
-       if (!dev || !dev->dev)
-               return -ENODEV;
-
-       if (!dev->release_lock)
-               return 0;
-
-       iosf_mbi_punit_acquire();
-       iosf_mbi_call_pmic_bus_access_notifier_chain(MBI_PMIC_BUS_ACCESS_BEGIN,
-                                                    NULL);
-
-       /*
-        * Disallow the CPU to enter C6 or C7 state, entering these states
-        * requires the punit to talk to the pmic and if this happens while
-        * we're holding the semaphore, the SoC hangs.
-        */
-       pm_qos_update_request(&dev->pm_qos, 0);
-
-       addr = get_sem_addr(dev);
-
-       /* host driver writes to side band semaphore register */
-       ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr, sem);
-       if (ret) {
-               dev_err(dev->dev, "iosf punit semaphore request failed\n");
-               goto out;
-       }
-
-       /* host driver waits for bit 0 to be set in semaphore register */
-       start = jiffies;
-       end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
-       do {
-               ret = get_sem(dev, &sem);
-               if (!ret && sem) {
-                       acquired = jiffies;
-                       dev_dbg(dev->dev, "punit semaphore acquired after %ums\n",
-                               jiffies_to_msecs(jiffies - start));
-                       return 0;
-               }
-
-               usleep_range(1000, 2000);
-       } while (time_before(jiffies, end));
-
-       dev_err(dev->dev, "punit semaphore timed out, resetting\n");
-out:
-       reset_semaphore(dev);
-
-       ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &sem);
-       if (ret)
-               dev_err(dev->dev, "iosf failed to read punit semaphore\n");
-       else
-               dev_err(dev->dev, "PUNIT SEM: %d\n", sem);
-
-       WARN_ON(1);
-
-       return -ETIMEDOUT;
-}
-
-static void baytrail_i2c_release(struct dw_i2c_dev *dev)
-{
-       if (!dev || !dev->dev)
-               return;
-
-       if (!dev->acquire_lock)
-               return;
-
-       reset_semaphore(dev);
-       dev_dbg(dev->dev, "punit semaphore held for %ums\n",
-               jiffies_to_msecs(jiffies - acquired));
-}
-
 int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev)
 {
        acpi_status status;
@@ -162,18 +36,9 @@ int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev)
                return -EPROBE_DEFER;
 
        dev_info(dev->dev, "I2C bus managed by PUNIT\n");
-       dev->acquire_lock = baytrail_i2c_acquire;
-       dev->release_lock = baytrail_i2c_release;
-       dev->pm_disabled = true;
-
-       pm_qos_add_request(&dev->pm_qos, PM_QOS_CPU_DMA_LATENCY,
-                          PM_QOS_DEFAULT_VALUE);
+       dev->acquire_lock = iosf_mbi_block_punit_i2c_access;
+       dev->release_lock = iosf_mbi_unblock_punit_i2c_access;
+       dev->shared_with_punit = true;
 
        return 0;
 }
-
-void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev)
-{
-       if (dev->acquire_lock)
-               pm_qos_remove_request(&dev->pm_qos);
-}
index 69ec4a791f23e78e1462c002eaca62c9e400da5a..a4730111d290317b246e29b410a82f2ec20630d4 100644 (file)
@@ -201,6 +201,8 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
                dev_dbg(dev->dev, "SDA Hold Time TX:RX = %d:%d\n",
                        dev->sda_hold_time & ~(u32)DW_IC_SDA_HOLD_RX_MASK,
                        dev->sda_hold_time >> DW_IC_SDA_HOLD_RX_SHIFT);
+       } else if (dev->set_sda_hold_time) {
+               dev->set_sda_hold_time(dev);
        } else if (dev->sda_hold_time) {
                dev_warn(dev->dev,
                        "Hardware too old to adjust SDA hold time.\n");
@@ -267,7 +269,7 @@ int i2c_dw_acquire_lock(struct dw_i2c_dev *dev)
        if (!dev->acquire_lock)
                return 0;
 
-       ret = dev->acquire_lock(dev);
+       ret = dev->acquire_lock();
        if (!ret)
                return 0;
 
@@ -279,7 +281,7 @@ int i2c_dw_acquire_lock(struct dw_i2c_dev *dev)
 void i2c_dw_release_lock(struct dw_i2c_dev *dev)
 {
        if (dev->release_lock)
-               dev->release_lock(dev);
+               dev->release_lock();
 }
 
 /*
index e367b1af4ab2cdebb120fa72e3dbc1a9f7c94171..b4a0b2b99a7821da40a21c396442436a41fedc07 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/i2c.h>
-#include <linux/pm_qos.h>
 
 #define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C |                    \
                                        I2C_FUNC_SMBUS_BYTE |           \
  * @fp_lcnt: fast plus LCNT value
  * @hs_hcnt: high speed HCNT value
  * @hs_lcnt: high speed LCNT value
- * @pm_qos: pm_qos_request used while holding a hardware lock on the bus
  * @acquire_lock: function to acquire a hardware lock on the bus
  * @release_lock: function to release a hardware lock on the bus
- * @pm_disabled: true if power-management should be disabled for this i2c-bus
+ * @shared_with_punit: true if this bus is shared with the SoCs PUNIT
  * @disable: function to disable the controller
  * @disable_int: function to disable all interrupts
  * @init: function to initialize the I2C hardware
 struct dw_i2c_dev {
        struct device           *dev;
        void __iomem            *base;
+       void __iomem            *ext;
        struct completion       cmd_complete;
        struct clk              *clk;
        struct reset_control    *rst;
@@ -262,13 +261,13 @@ struct dw_i2c_dev {
        u16                     fp_lcnt;
        u16                     hs_hcnt;
        u16                     hs_lcnt;
-       struct pm_qos_request   pm_qos;
-       int                     (*acquire_lock)(struct dw_i2c_dev *dev);
-       void                    (*release_lock)(struct dw_i2c_dev *dev);
-       bool                    pm_disabled;
+       int                     (*acquire_lock)(void);
+       void                    (*release_lock)(void);
+       bool                    shared_with_punit;
        void                    (*disable)(struct dw_i2c_dev *dev);
        void                    (*disable_int)(struct dw_i2c_dev *dev);
        int                     (*init)(struct dw_i2c_dev *dev);
+       int                     (*set_sda_hold_time)(struct dw_i2c_dev *dev);
        int                     mode;
        struct i2c_bus_recovery_info rinfo;
 };
@@ -276,8 +275,11 @@ struct dw_i2c_dev {
 #define ACCESS_SWAP            0x00000001
 #define ACCESS_16BIT           0x00000002
 #define ACCESS_INTR_MASK       0x00000004
+#define ACCESS_NO_IRQ_SUSPEND  0x00000008
 
 #define MODEL_CHERRYTRAIL      0x00000100
+#define MODEL_MSCC_OCELOT      0x00000200
+#define MODEL_MASK             0x00000f00
 
 u32 dw_readl(struct dw_i2c_dev *dev, int offset);
 void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
@@ -317,8 +319,6 @@ static inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; }
 
 #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL)
 extern int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev);
-extern void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev);
 #else
 static inline int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) { return 0; }
-static inline void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) {}
 #endif
index 18cc324f3ca94541d830f825693ee42b6cf60df9..8d1bc44d2530afd940bd083d6470af926f84428b 100644 (file)
@@ -709,7 +709,7 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
        adap->dev.parent = dev->dev;
        i2c_set_adapdata(adap, dev);
 
-       if (dev->pm_disabled) {
+       if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
                irq_flags = IRQF_NO_SUSPEND;
        } else {
                irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND;
index b5750fd851251e74b0558576774da4a82d81c757..9eaac3be1f63da4e4db4e7759042bd87de86ba2e 100644 (file)
@@ -85,10 +85,6 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
        struct i2c_timings *t = &dev->timings;
        u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
-       acpi_handle handle = ACPI_HANDLE(&pdev->dev);
-       const struct acpi_device_id *id;
-       struct acpi_device *adev;
-       const char *uid;
 
        dev->adapter.nr = -1;
        dev->tx_fifo_depth = 32;
@@ -119,22 +115,6 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
                break;
        }
 
-       id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
-       if (id && id->driver_data)
-               dev->flags |= (u32)id->driver_data;
-
-       if (acpi_bus_get_device(handle, &adev))
-               return -ENODEV;
-
-       /*
-        * Cherrytrail I2C7 gets used for the PMIC which gets accessed
-        * through ACPI opregions during late suspend / early resume
-        * disable pm for it.
-        */
-       uid = adev->pnp.unique_id;
-       if ((dev->flags & MODEL_CHERRYTRAIL) && !strcmp(uid, "7"))
-               dev->pm_disabled = true;
-
        return 0;
 }
 
@@ -143,8 +123,8 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "INT33C3", 0 },
        { "INT3432", 0 },
        { "INT3433", 0 },
-       { "80860F41", 0 },
-       { "808622C1", MODEL_CHERRYTRAIL },
+       { "80860F41", ACCESS_NO_IRQ_SUSPEND },
+       { "808622C1", ACCESS_NO_IRQ_SUSPEND | MODEL_CHERRYTRAIL },
        { "AMD0010", ACCESS_INTR_MASK },
        { "AMDI0010", ACCESS_INTR_MASK },
        { "AMDI0510", 0 },
@@ -161,6 +141,51 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
 }
 #endif
 
+#ifdef CONFIG_OF
+#define MSCC_ICPU_CFG_TWI_DELAY                0x0
+#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0)
+#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4
+
+static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
+{
+       writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
+              dev->ext + MSCC_ICPU_CFG_TWI_DELAY);
+
+       return 0;
+}
+
+static int dw_i2c_of_configure(struct platform_device *pdev)
+{
+       struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       struct resource *mem;
+
+       switch (dev->flags & MODEL_MASK) {
+       case MODEL_MSCC_OCELOT:
+               mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               dev->ext = devm_ioremap_resource(&pdev->dev, mem);
+               if (!IS_ERR(dev->ext))
+                       dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static const struct of_device_id dw_i2c_of_match[] = {
+       { .compatible = "snps,designware-i2c", },
+       { .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
+       {},
+};
+MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
+#else
+static inline int dw_i2c_of_configure(struct platform_device *pdev)
+{
+       return -ENODEV;
+}
+#endif
+
 static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
 {
        struct i2c_timings *t = &dev->timings;
@@ -221,7 +246,7 @@ static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
 {
        pm_runtime_disable(dev->dev);
 
-       if (dev->pm_disabled)
+       if (dev->shared_with_punit)
                pm_runtime_put_noidle(dev->dev);
 }
 
@@ -291,6 +316,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        else
                t->bus_freq_hz = 400000;
 
+       dev->flags |= (uintptr_t)device_get_match_data(&pdev->dev);
+
+       if (pdev->dev.of_node)
+               dw_i2c_of_configure(pdev);
+
        if (has_acpi_companion(&pdev->dev))
                dw_i2c_acpi_configure(pdev);
 
@@ -348,7 +378,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_set_active(&pdev->dev);
 
-       if (dev->pm_disabled)
+       if (dev->shared_with_punit)
                pm_runtime_get_noresume(&pdev->dev);
 
        pm_runtime_enable(&pdev->dev);
@@ -388,19 +418,9 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
        if (!IS_ERR_OR_NULL(dev->rst))
                reset_control_assert(dev->rst);
 
-       i2c_dw_remove_lock_support(dev);
-
        return 0;
 }
 
-#ifdef CONFIG_OF
-static const struct of_device_id dw_i2c_of_match[] = {
-       { .compatible = "snps,designware-i2c", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
-#endif
-
 #ifdef CONFIG_PM_SLEEP
 static int dw_i2c_plat_prepare(struct device *dev)
 {
@@ -434,7 +454,7 @@ static int dw_i2c_plat_suspend(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
-       if (i_dev->pm_disabled)
+       if (i_dev->shared_with_punit)
                return 0;
 
        i_dev->disable(i_dev);
@@ -447,7 +467,7 @@ static int dw_i2c_plat_resume(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
-       if (!i_dev->pm_disabled)
+       if (!i_dev->shared_with_punit)
                i2c_dw_prepare_clk(i_dev, true);
 
        i_dev->init(i_dev);
index 1e57f58fcb00151e9ef274e25e3adf22f2c197b8..a74ef76705e0c7d72667f0591292ca05bbbe3957 100644 (file)
@@ -441,6 +441,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
        u16 control_reg;
        u16 restart_flag = 0;
        u32 reg_4g_mode;
+       u8 *dma_rd_buf = NULL;
+       u8 *dma_wr_buf = NULL;
        dma_addr_t rpaddr = 0;
        dma_addr_t wpaddr = 0;
        int ret;
@@ -500,10 +502,18 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
        if (i2c->op == I2C_MASTER_RD) {
                writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG);
                writel(I2C_DMA_CON_RX, i2c->pdmabase + OFFSET_CON);
-               rpaddr = dma_map_single(i2c->dev, msgs->buf,
+
+               dma_rd_buf = i2c_get_dma_safe_msg_buf(msgs, 0);
+               if (!dma_rd_buf)
+                       return -ENOMEM;
+
+               rpaddr = dma_map_single(i2c->dev, dma_rd_buf,
                                        msgs->len, DMA_FROM_DEVICE);
-               if (dma_mapping_error(i2c->dev, rpaddr))
+               if (dma_mapping_error(i2c->dev, rpaddr)) {
+                       i2c_put_dma_safe_msg_buf(dma_rd_buf, msgs, false);
+
                        return -ENOMEM;
+               }
 
                if (i2c->dev_comp->support_33bits) {
                        reg_4g_mode = mtk_i2c_set_4g_mode(rpaddr);
@@ -515,10 +525,18 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
        } else if (i2c->op == I2C_MASTER_WR) {
                writel(I2C_DMA_INT_FLAG_NONE, i2c->pdmabase + OFFSET_INT_FLAG);
                writel(I2C_DMA_CON_TX, i2c->pdmabase + OFFSET_CON);
-               wpaddr = dma_map_single(i2c->dev, msgs->buf,
+
+               dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 0);
+               if (!dma_wr_buf)
+                       return -ENOMEM;
+
+               wpaddr = dma_map_single(i2c->dev, dma_wr_buf,
                                        msgs->len, DMA_TO_DEVICE);
-               if (dma_mapping_error(i2c->dev, wpaddr))
+               if (dma_mapping_error(i2c->dev, wpaddr)) {
+                       i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
+
                        return -ENOMEM;
+               }
 
                if (i2c->dev_comp->support_33bits) {
                        reg_4g_mode = mtk_i2c_set_4g_mode(wpaddr);
@@ -530,16 +548,39 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
        } else {
                writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_INT_FLAG);
                writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_CON);
-               wpaddr = dma_map_single(i2c->dev, msgs->buf,
+
+               dma_wr_buf = i2c_get_dma_safe_msg_buf(msgs, 0);
+               if (!dma_wr_buf)
+                       return -ENOMEM;
+
+               wpaddr = dma_map_single(i2c->dev, dma_wr_buf,
                                        msgs->len, DMA_TO_DEVICE);
-               if (dma_mapping_error(i2c->dev, wpaddr))
+               if (dma_mapping_error(i2c->dev, wpaddr)) {
+                       i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
+
                        return -ENOMEM;
-               rpaddr = dma_map_single(i2c->dev, (msgs + 1)->buf,
+               }
+
+               dma_rd_buf = i2c_get_dma_safe_msg_buf((msgs + 1), 0);
+               if (!dma_rd_buf) {
+                       dma_unmap_single(i2c->dev, wpaddr,
+                                        msgs->len, DMA_TO_DEVICE);
+
+                       i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
+
+                       return -ENOMEM;
+               }
+
+               rpaddr = dma_map_single(i2c->dev, dma_rd_buf,
                                        (msgs + 1)->len,
                                        DMA_FROM_DEVICE);
                if (dma_mapping_error(i2c->dev, rpaddr)) {
                        dma_unmap_single(i2c->dev, wpaddr,
                                         msgs->len, DMA_TO_DEVICE);
+
+                       i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, false);
+                       i2c_put_dma_safe_msg_buf(dma_rd_buf, (msgs + 1), false);
+
                        return -ENOMEM;
                }
 
@@ -578,14 +619,21 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
        if (i2c->op == I2C_MASTER_WR) {
                dma_unmap_single(i2c->dev, wpaddr,
                                 msgs->len, DMA_TO_DEVICE);
+
+               i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, true);
        } else if (i2c->op == I2C_MASTER_RD) {
                dma_unmap_single(i2c->dev, rpaddr,
                                 msgs->len, DMA_FROM_DEVICE);
+
+               i2c_put_dma_safe_msg_buf(dma_rd_buf, msgs, true);
        } else {
                dma_unmap_single(i2c->dev, wpaddr, msgs->len,
                                 DMA_TO_DEVICE);
                dma_unmap_single(i2c->dev, rpaddr, (msgs + 1)->len,
                                 DMA_FROM_DEVICE);
+
+               i2c_put_dma_safe_msg_buf(dma_wr_buf, msgs, true);
+               i2c_put_dma_safe_msg_buf(dma_rd_buf, (msgs + 1), true);
        }
 
        if (ret == 0) {
index 65d06a8193074814cb18a0864eaea9cbc3c044de..b1086bfb04656aa45422ff1f89a57647f53da369 100644 (file)
@@ -661,9 +661,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
        dev_dbg(omap->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
                msg->addr, msg->len, msg->flags, stop);
 
-       if (msg->len == 0)
-               return -EINVAL;
-
        omap->receiver = !!(msg->flags & I2C_M_RD);
        omap_i2c_resize_fifo(omap, msg->len, omap->receiver);
 
@@ -1179,6 +1176,10 @@ static const struct i2c_algorithm omap_i2c_algo = {
        .functionality  = omap_i2c_func,
 };
 
+static const struct i2c_adapter_quirks omap_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 #ifdef CONFIG_OF
 static struct omap_i2c_bus_platform_data omap2420_pdata = {
        .rev = OMAP_I2C_IP_VERSION_1,
@@ -1453,6 +1454,7 @@ omap_i2c_probe(struct platform_device *pdev)
        adap->class = I2C_CLASS_DEPRECATED;
        strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
        adap->algo = &omap_i2c_algo;
+       adap->quirks = &omap_i2c_quirks;
        adap->dev.parent = &pdev->dev;
        adap->dev.of_node = pdev->dev.of_node;
        adap->bus_recovery_info = &omap_i2c_bus_recovery_info;
index f2a2067525efb1c3c1bb9b317ba136586b03aed9..f6f4ed8afc9386ac34fe7be9ee40e575ac6e00ee 100644 (file)
@@ -388,9 +388,8 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap,
 static int i2c_powermac_probe(struct platform_device *dev)
 {
        struct pmac_i2c_bus *bus = dev_get_platdata(&dev->dev);
-       struct device_node *parent = NULL;
+       struct device_node *parent;
        struct i2c_adapter *adapter;
-       const char *basename;
        int rc;
 
        if (bus == NULL)
@@ -407,23 +406,25 @@ static int i2c_powermac_probe(struct platform_device *dev)
                parent = of_get_parent(pmac_i2c_get_controller(bus));
                if (parent == NULL)
                        return -EINVAL;
-               basename = parent->name;
+               snprintf(adapter->name, sizeof(adapter->name), "%pOFn %d",
+                        parent,
+                        pmac_i2c_get_channel(bus));
+               of_node_put(parent);
                break;
        case pmac_i2c_bus_pmu:
-               basename = "pmu";
+               snprintf(adapter->name, sizeof(adapter->name), "pmu %d",
+                        pmac_i2c_get_channel(bus));
                break;
        case pmac_i2c_bus_smu:
                /* This is not what we used to do but I'm fixing drivers at
                 * the same time as this change
                 */
-               basename = "smu";
+               snprintf(adapter->name, sizeof(adapter->name), "smu %d",
+                        pmac_i2c_get_channel(bus));
                break;
        default:
                return -EINVAL;
        }
-       snprintf(adapter->name, sizeof(adapter->name), "%s %d", basename,
-                pmac_i2c_get_channel(bus));
-       of_node_put(parent);
 
        platform_set_drvdata(dev, adapter);
        adapter->algo = &i2c_powermac_algorithm;
index 9f2eb02481d348c60512c69c1b58e375c698f36c..527f55c8c4c70e560a9787a610c68017fbb10235 100644 (file)
@@ -201,21 +201,23 @@ static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
 static irqreturn_t geni_i2c_irq(int irq, void *dev)
 {
        struct geni_i2c_dev *gi2c = dev;
-       int j;
+       void __iomem *base = gi2c->se.base;
+       int j, p;
        u32 m_stat;
        u32 rx_st;
        u32 dm_tx_st;
        u32 dm_rx_st;
        u32 dma;
+       u32 val;
        struct i2c_msg *cur;
        unsigned long flags;
 
        spin_lock_irqsave(&gi2c->lock, flags);
-       m_stat = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS);
-       rx_st = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFO_STATUS);
-       dm_tx_st = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT);
-       dm_rx_st = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT);
-       dma = readl_relaxed(gi2c->se.base + SE_GENI_DMA_MODE_EN);
+       m_stat = readl_relaxed(base + SE_GENI_M_IRQ_STATUS);
+       rx_st = readl_relaxed(base + SE_GENI_RX_FIFO_STATUS);
+       dm_tx_st = readl_relaxed(base + SE_DMA_TX_IRQ_STAT);
+       dm_rx_st = readl_relaxed(base + SE_DMA_RX_IRQ_STAT);
+       dma = readl_relaxed(base + SE_GENI_DMA_MODE_EN);
        cur = gi2c->cur;
 
        if (!cur ||
@@ -238,26 +240,17 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
 
                /* Disable the TX Watermark interrupt to stop TX */
                if (!dma)
-                       writel_relaxed(0, gi2c->se.base +
-                                          SE_GENI_TX_WATERMARK_REG);
-               goto irqret;
-       }
-
-       if (dma) {
+                       writel_relaxed(0, base + SE_GENI_TX_WATERMARK_REG);
+       } else if (dma) {
                dev_dbg(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n",
                        dm_tx_st, dm_rx_st);
-               goto irqret;
-       }
-
-       if (cur->flags & I2C_M_RD &&
-           m_stat & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) {
+       } else if (cur->flags & I2C_M_RD &&
+                  m_stat & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) {
                u32 rxcnt = rx_st & RX_FIFO_WC_MSK;
 
                for (j = 0; j < rxcnt; j++) {
-                       u32 val;
-                       int p = 0;
-
-                       val = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFOn);
+                       p = 0;
+                       val = readl_relaxed(base + SE_GENI_RX_FIFOn);
                        while (gi2c->cur_rd < cur->len && p < sizeof(val)) {
                                cur->buf[gi2c->cur_rd++] = val & 0xff;
                                val >>= 8;
@@ -270,44 +263,39 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
                   m_stat & M_TX_FIFO_WATERMARK_EN) {
                for (j = 0; j < gi2c->tx_wm; j++) {
                        u32 temp;
-                       u32 val = 0;
-                       int p = 0;
 
+                       val = 0;
+                       p = 0;
                        while (gi2c->cur_wr < cur->len && p < sizeof(val)) {
                                temp = cur->buf[gi2c->cur_wr++];
                                val |= temp << (p * 8);
                                p++;
                        }
-                       writel_relaxed(val, gi2c->se.base + SE_GENI_TX_FIFOn);
+                       writel_relaxed(val, base + SE_GENI_TX_FIFOn);
                        /* TX Complete, Disable the TX Watermark interrupt */
                        if (gi2c->cur_wr == cur->len) {
-                               writel_relaxed(0, gi2c->se.base +
-                                               SE_GENI_TX_WATERMARK_REG);
+                               writel_relaxed(0, base + SE_GENI_TX_WATERMARK_REG);
                                break;
                        }
                }
        }
-irqret:
+
        if (m_stat)
-               writel_relaxed(m_stat, gi2c->se.base + SE_GENI_M_IRQ_CLEAR);
+               writel_relaxed(m_stat, base + SE_GENI_M_IRQ_CLEAR);
+
+       if (dma && dm_tx_st)
+               writel_relaxed(dm_tx_st, base + SE_DMA_TX_IRQ_CLR);
+       if (dma && dm_rx_st)
+               writel_relaxed(dm_rx_st, base + SE_DMA_RX_IRQ_CLR);
 
-       if (dma) {
-               if (dm_tx_st)
-                       writel_relaxed(dm_tx_st, gi2c->se.base +
-                                               SE_DMA_TX_IRQ_CLR);
-               if (dm_rx_st)
-                       writel_relaxed(dm_rx_st, gi2c->se.base +
-                                               SE_DMA_RX_IRQ_CLR);
-       }
        /* if this is err with done-bit not set, handle that through timeout. */
-       if (m_stat & M_CMD_DONE_EN || m_stat & M_CMD_ABORT_EN)
-               complete(&gi2c->done);
-       else if (dm_tx_st & TX_DMA_DONE || dm_tx_st & TX_RESET_DONE)
-               complete(&gi2c->done);
-       else if (dm_rx_st & RX_DMA_DONE || dm_rx_st & RX_RESET_DONE)
+       if (m_stat & M_CMD_DONE_EN || m_stat & M_CMD_ABORT_EN ||
+           dm_tx_st & TX_DMA_DONE || dm_tx_st & TX_RESET_DONE ||
+           dm_rx_st & RX_DMA_DONE || dm_rx_st & RX_RESET_DONE)
                complete(&gi2c->done);
 
        spin_unlock_irqrestore(&gi2c->lock, flags);
+
        return IRQ_HANDLED;
 }
 
@@ -365,29 +353,24 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
                                u32 m_param)
 {
        dma_addr_t rx_dma;
-       enum geni_se_xfer_mode mode;
-       unsigned long time_left = XFER_TIMEOUT;
+       unsigned long time_left;
        void *dma_buf;
+       struct geni_se *se = &gi2c->se;
+       size_t len = msg->len;
 
-       gi2c->cur = msg;
-       mode = GENI_SE_FIFO;
        dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
        if (dma_buf)
-               mode = GENI_SE_DMA;
-
-       geni_se_select_mode(&gi2c->se, mode);
-       writel_relaxed(msg->len, gi2c->se.base + SE_I2C_RX_TRANS_LEN);
-       geni_se_setup_m_cmd(&gi2c->se, I2C_READ, m_param);
-       if (mode == GENI_SE_DMA) {
-               int ret;
-
-               ret = geni_se_rx_dma_prep(&gi2c->se, dma_buf, msg->len,
-                                                               &rx_dma);
-               if (ret) {
-                       mode = GENI_SE_FIFO;
-                       geni_se_select_mode(&gi2c->se, mode);
-                       i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-               }
+               geni_se_select_mode(se, GENI_SE_DMA);
+       else
+               geni_se_select_mode(se, GENI_SE_FIFO);
+
+       writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
+       geni_se_setup_m_cmd(se, I2C_READ, m_param);
+
+       if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
+               geni_se_select_mode(se, GENI_SE_FIFO);
+               i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+               dma_buf = NULL;
        }
 
        time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
@@ -395,12 +378,13 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
                geni_i2c_abort_xfer(gi2c);
 
        gi2c->cur_rd = 0;
-       if (mode == GENI_SE_DMA) {
+       if (dma_buf) {
                if (gi2c->err)
                        geni_i2c_rx_fsm_rst(gi2c);
-               geni_se_rx_dma_unprep(&gi2c->se, rx_dma, msg->len);
+               geni_se_rx_dma_unprep(se, rx_dma, len);
                i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
        }
+
        return gi2c->err;
 }
 
@@ -408,45 +392,41 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
                                u32 m_param)
 {
        dma_addr_t tx_dma;
-       enum geni_se_xfer_mode mode;
        unsigned long time_left;
        void *dma_buf;
+       struct geni_se *se = &gi2c->se;
+       size_t len = msg->len;
 
-       gi2c->cur = msg;
-       mode = GENI_SE_FIFO;
        dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
        if (dma_buf)
-               mode = GENI_SE_DMA;
-
-       geni_se_select_mode(&gi2c->se, mode);
-       writel_relaxed(msg->len, gi2c->se.base + SE_I2C_TX_TRANS_LEN);
-       geni_se_setup_m_cmd(&gi2c->se, I2C_WRITE, m_param);
-       if (mode == GENI_SE_DMA) {
-               int ret;
-
-               ret = geni_se_tx_dma_prep(&gi2c->se, dma_buf, msg->len,
-                                                               &tx_dma);
-               if (ret) {
-                       mode = GENI_SE_FIFO;
-                       geni_se_select_mode(&gi2c->se, mode);
-                       i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-               }
+               geni_se_select_mode(se, GENI_SE_DMA);
+       else
+               geni_se_select_mode(se, GENI_SE_FIFO);
+
+       writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
+       geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
+
+       if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
+               geni_se_select_mode(se, GENI_SE_FIFO);
+               i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+               dma_buf = NULL;
        }
 
-       if (mode == GENI_SE_FIFO) /* Get FIFO IRQ */
-               writel_relaxed(1, gi2c->se.base + SE_GENI_TX_WATERMARK_REG);
+       if (!dma_buf) /* Get FIFO IRQ */
+               writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);
 
        time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
        if (!time_left)
                geni_i2c_abort_xfer(gi2c);
 
        gi2c->cur_wr = 0;
-       if (mode == GENI_SE_DMA) {
+       if (dma_buf) {
                if (gi2c->err)
                        geni_i2c_tx_fsm_rst(gi2c);
-               geni_se_tx_dma_unprep(&gi2c->se, tx_dma, msg->len);
+               geni_se_tx_dma_unprep(se, tx_dma, len);
                i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
        }
+
        return gi2c->err;
 }
 
@@ -474,6 +454,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
 
                m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK);
 
+               gi2c->cur = &msgs[i];
                if (msgs[i].flags & I2C_M_RD)
                        ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param);
                else
index c86c3ae1318f200696f909f7563c8a114ee30995..e09cd0775ae91c60e052b22a748d870dfe037f7a 100644 (file)
@@ -1088,11 +1088,6 @@ static int qup_i2c_xfer(struct i2c_adapter *adap,
        writel(I2C_MINI_CORE | I2C_N_VAL, qup->base + QUP_CONFIG);
 
        for (idx = 0; idx < num; idx++) {
-               if (msgs[idx].len == 0) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-
                if (qup_i2c_poll_state_i2c_master(qup)) {
                        ret = -EIO;
                        goto out;
@@ -1520,9 +1515,6 @@ qup_i2c_determine_mode_v2(struct qup_i2c_dev *qup,
 
        /* All i2c_msgs should be transferred using either dma or cpu */
        for (idx = 0; idx < num; idx++) {
-               if (msgs[idx].len == 0)
-                       return -EINVAL;
-
                if (msgs[idx].flags & I2C_M_RD)
                        max_rx_len = max_t(unsigned int, max_rx_len,
                                           msgs[idx].len);
@@ -1636,9 +1628,14 @@ static const struct i2c_algorithm qup_i2c_algo_v2 = {
  * which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
  */
 static const struct i2c_adapter_quirks qup_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
        .max_read_len = QUP_READ_LIMIT,
 };
 
+static const struct i2c_adapter_quirks qup_i2c_quirks_v2 = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup)
 {
        clk_prepare_enable(qup->clk);
@@ -1701,6 +1698,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
                is_qup_v1 = true;
        } else {
                qup->adap.algo = &qup_i2c_algo_v2;
+               qup->adap.quirks = &qup_i2c_quirks_v2;
                is_qup_v1 = false;
                if (acpi_match_device(qup_i2c_acpi_match, qup->dev))
                        goto nodma;
index 818cab14e87c5ea47e5c6daaa7b76c818465df52..a7a7a9c3bc7c499b59f4672399adf7ec3691f667 100644 (file)
@@ -947,27 +947,9 @@ static int sh_mobile_i2c_remove(struct platform_device *dev)
        return 0;
 }
 
-static int sh_mobile_i2c_runtime_nop(struct device *dev)
-{
-       /* Runtime PM callback shared between ->runtime_suspend()
-        * and ->runtime_resume(). Simply returns success.
-        *
-        * This driver re-initializes all registers after
-        * pm_runtime_get_sync() anyway so there is no need
-        * to save and restore registers here.
-        */
-       return 0;
-}
-
-static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
-       .runtime_suspend = sh_mobile_i2c_runtime_nop,
-       .runtime_resume = sh_mobile_i2c_runtime_nop,
-};
-
 static struct platform_driver sh_mobile_i2c_driver = {
        .driver         = {
                .name           = "i2c-sh_mobile",
-               .pm             = &sh_mobile_i2c_dev_pm_ops,
                .of_match_table = sh_mobile_i2c_dt_ids,
        },
        .probe          = sh_mobile_i2c_probe,
index 915f5edbab3319212c1e22ae3274ce63de468d18..2184b7c3580e0e19052f5bc72e8f2c8b5e7c12e9 100644 (file)
@@ -404,7 +404,7 @@ static irqreturn_t synquacer_i2c_isr(int irq, void *dev_id)
                if (i2c->state == STATE_READ)
                        goto prepare_read;
 
-               /* fallthru */
+               /* fall through */
 
        case STATE_WRITE:
                if (bsr & SYNQUACER_I2C_BSR_LRB) {
index 60c8561fbe65e62d3bec217d8eb7157cd377609e..437294ea2f0ad9381035c19f00ffae82ada203c8 100644 (file)
@@ -684,9 +684,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
        tegra_i2c_flush_fifos(i2c_dev);
 
-       if (msg->len == 0)
-               return -EINVAL;
-
        i2c_dev->msg_buf = msg->buf;
        i2c_dev->msg_buf_remaining = msg->len;
        i2c_dev->msg_err = I2C_ERR_NONE;
@@ -831,6 +828,7 @@ static const struct i2c_algorithm tegra_i2c_algo = {
 
 /* payload size is only 12 bit */
 static const struct i2c_adapter_quirks tegra_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
        .max_read_len = 4096,
        .max_write_len = 4096,
 };
index a403e8579b652b6e2486f746b91b9357c3ab7381..dd384743dbbd0581ffc2b3c7f179e158bebdf10b 100644 (file)
@@ -98,6 +98,7 @@ struct uniphier_fi2c_priv {
        unsigned int flags;
        unsigned int busy_cnt;
        unsigned int clk_cycle;
+       spinlock_t lock;        /* IRQ synchronization */
 };
 
 static void uniphier_fi2c_fill_txfifo(struct uniphier_fi2c_priv *priv,
@@ -142,9 +143,10 @@ static void uniphier_fi2c_set_irqs(struct uniphier_fi2c_priv *priv)
        writel(priv->enabled_irqs, priv->membase + UNIPHIER_FI2C_IE);
 }
 
-static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv)
+static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv,
+                                    u32 mask)
 {
-       writel(-1, priv->membase + UNIPHIER_FI2C_IC);
+       writel(mask, priv->membase + UNIPHIER_FI2C_IC);
 }
 
 static void uniphier_fi2c_stop(struct uniphier_fi2c_priv *priv)
@@ -162,12 +164,17 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
        struct uniphier_fi2c_priv *priv = dev_id;
        u32 irq_status;
 
+       spin_lock(&priv->lock);
+
        irq_status = readl(priv->membase + UNIPHIER_FI2C_INT);
+       irq_status &= priv->enabled_irqs;
 
        dev_dbg(&priv->adap.dev,
                "interrupt: enabled_irqs=%04x, irq_status=%04x\n",
                priv->enabled_irqs, irq_status);
 
+       uniphier_fi2c_clear_irqs(priv, irq_status);
+
        if (irq_status & UNIPHIER_FI2C_INT_STOP)
                goto complete;
 
@@ -230,6 +237,8 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
                goto handled;
        }
 
+       spin_unlock(&priv->lock);
+
        return IRQ_NONE;
 
 data_done:
@@ -244,7 +253,7 @@ complete:
        }
 
 handled:
-       uniphier_fi2c_clear_irqs(priv);
+       spin_unlock(&priv->lock);
 
        return IRQ_HANDLED;
 }
@@ -252,6 +261,8 @@ handled:
 static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr)
 {
        priv->enabled_irqs |= UNIPHIER_FI2C_INT_TE;
+       uniphier_fi2c_set_irqs(priv);
+
        /* do not use TX byte counter */
        writel(0, priv->membase + UNIPHIER_FI2C_TBC);
        /* set slave address */
@@ -284,6 +295,8 @@ static void uniphier_fi2c_rx_init(struct uniphier_fi2c_priv *priv, u16 addr)
                priv->enabled_irqs |= UNIPHIER_FI2C_INT_RF;
        }
 
+       uniphier_fi2c_set_irqs(priv);
+
        /* set slave address with RD bit */
        writel(UNIPHIER_FI2C_DTTX_CMD | UNIPHIER_FI2C_DTTX_RD | addr << 1,
               priv->membase + UNIPHIER_FI2C_DTTX);
@@ -307,14 +320,16 @@ static void uniphier_fi2c_recover(struct uniphier_fi2c_priv *priv)
 }
 
 static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
-                                        struct i2c_msg *msg, bool stop)
+                                        struct i2c_msg *msg, bool repeat,
+                                        bool stop)
 {
        struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap);
        bool is_read = msg->flags & I2C_M_RD;
-       unsigned long time_left;
+       unsigned long time_left, flags;
 
-       dev_dbg(&adap->dev, "%s: addr=0x%02x, len=%d, stop=%d\n",
-               is_read ? "receive" : "transmit", msg->addr, msg->len, stop);
+       dev_dbg(&adap->dev, "%s: addr=0x%02x, len=%d, repeat=%d, stop=%d\n",
+               is_read ? "receive" : "transmit", msg->addr, msg->len,
+               repeat, stop);
 
        priv->len = msg->len;
        priv->buf = msg->buf;
@@ -326,22 +341,36 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
                priv->flags |= UNIPHIER_FI2C_STOP;
 
        reinit_completion(&priv->comp);
-       uniphier_fi2c_clear_irqs(priv);
+       uniphier_fi2c_clear_irqs(priv, U32_MAX);
        writel(UNIPHIER_FI2C_RST_TBRST | UNIPHIER_FI2C_RST_RBRST,
               priv->membase + UNIPHIER_FI2C_RST);      /* reset TX/RX FIFO */
 
+       spin_lock_irqsave(&priv->lock, flags);
+
        if (is_read)
                uniphier_fi2c_rx_init(priv, msg->addr);
        else
                uniphier_fi2c_tx_init(priv, msg->addr);
 
-       uniphier_fi2c_set_irqs(priv);
-
        dev_dbg(&adap->dev, "start condition\n");
-       writel(UNIPHIER_FI2C_CR_MST | UNIPHIER_FI2C_CR_STA,
-              priv->membase + UNIPHIER_FI2C_CR);
+       /*
+        * For a repeated START condition, writing a slave address to the FIFO
+        * kicks the controller. So, the UNIPHIER_FI2C_CR register should be
+        * written only for a non-repeated START condition.
+        */
+       if (!repeat)
+               writel(UNIPHIER_FI2C_CR_MST | UNIPHIER_FI2C_CR_STA,
+                      priv->membase + UNIPHIER_FI2C_CR);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->enabled_irqs = 0;
+       uniphier_fi2c_set_irqs(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
        if (!time_left) {
                dev_err(&adap->dev, "transaction timeout.\n");
                uniphier_fi2c_recover(priv);
@@ -394,6 +423,7 @@ static int uniphier_fi2c_master_xfer(struct i2c_adapter *adap,
                                     struct i2c_msg *msgs, int num)
 {
        struct i2c_msg *msg, *emsg = msgs + num;
+       bool repeat = false;
        int ret;
 
        ret = uniphier_fi2c_check_bus_busy(adap);
@@ -404,9 +434,11 @@ static int uniphier_fi2c_master_xfer(struct i2c_adapter *adap,
                /* Emit STOP if it is the last message or I2C_M_STOP is set. */
                bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
 
-               ret = uniphier_fi2c_master_xfer_one(adap, msg, stop);
+               ret = uniphier_fi2c_master_xfer_one(adap, msg, repeat, stop);
                if (ret)
                        return ret;
+
+               repeat = !stop;
        }
 
        return num;
@@ -529,6 +561,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
 
        priv->clk_cycle = clk_rate / bus_speed;
        init_completion(&priv->comp);
+       spin_lock_init(&priv->lock);
        priv->adap.owner = THIS_MODULE;
        priv->adap.algo = &uniphier_fi2c_algo;
        priv->adap.dev.parent = dev;
index 48281c1b30c6d56892cac6ad7388386aad586476..b8f9e020d80e6a1049ff0328788073b628f6777c 100644 (file)
@@ -281,9 +281,6 @@ static int zx2967_i2c_xfer_msg(struct zx2967_i2c *i2c,
        int ret;
        int i;
 
-       if (msg->len == 0)
-               return -EINVAL;
-
        zx2967_i2c_flush_fifos(i2c);
 
        i2c->cur_trans = msg->buf;
@@ -498,6 +495,10 @@ static const struct i2c_algorithm zx2967_i2c_algo = {
        .functionality = zx2967_i2c_func,
 };
 
+static const struct i2c_adapter_quirks zx2967_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static const struct of_device_id zx2967_i2c_of_match[] = {
        { .compatible = "zte,zx296718-i2c", },
        { },
@@ -568,6 +569,7 @@ static int zx2967_i2c_probe(struct platform_device *pdev)
        strlcpy(i2c->adap.name, "zx2967 i2c adapter",
                sizeof(i2c->adap.name));
        i2c->adap.algo = &zx2967_i2c_algo;
+       i2c->adap.quirks = &zx2967_i2c_quirks;
        i2c->adap.nr = pdev->id;
        i2c->adap.dev.parent = &pdev->dev;
        i2c->adap.dev.of_node = pdev->dev.of_node;
index 9200e349f29e411d53d2dc4126ea2f7a450a9288..dc78aa7369def416898f0a4c514fd017c147f0c0 100644 (file)
@@ -1922,6 +1922,11 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 {
        int ret;
 
+       if (!adap->algo->master_xfer) {
+               dev_dbg(&adap->dev, "I2C level transfers not supported\n");
+               return -EOPNOTSUPP;
+       }
+
        /* REVISIT the fault reporting model here is weak:
         *
         *  - When we get an error after receiving N bytes from a slave,
@@ -1938,35 +1943,19 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
         *    one (discarding status on the second message) or errno
         *    (discarding status on the first one).
         */
-
-       if (adap->algo->master_xfer) {
-#ifdef DEBUG
-               for (ret = 0; ret < num; ret++) {
-                       dev_dbg(&adap->dev,
-                               "master_xfer[%d] %c, addr=0x%02x, len=%d%s\n",
-                               ret, (msgs[ret].flags & I2C_M_RD) ? 'R' : 'W',
-                               msgs[ret].addr, msgs[ret].len,
-                               (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
-               }
-#endif
-
-               if (in_atomic() || irqs_disabled()) {
-                       ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT);
-                       if (!ret)
-                               /* I2C activity is ongoing. */
-                               return -EAGAIN;
-               } else {
-                       i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
-               }
-
-               ret = __i2c_transfer(adap, msgs, num);
-               i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
-
-               return ret;
+       if (in_atomic() || irqs_disabled()) {
+               ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT);
+               if (!ret)
+                       /* I2C activity is ongoing. */
+                       return -EAGAIN;
        } else {
-               dev_dbg(&adap->dev, "I2C level transfers not supported\n");
-               return -EOPNOTSUPP;
+               i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
        }
+
+       ret = __i2c_transfer(adap, msgs, num);
+       i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
+
+       return ret;
 }
 EXPORT_SYMBOL(i2c_transfer);
 
index 92cf5f48afe63a7fc458af0fce9e27efa6771c44..f60b670deff7003699438f104c5008696b658dfc 100644 (file)
@@ -120,8 +120,8 @@ static int i2c_mux_probe(struct platform_device *pdev)
 
                ret = of_property_read_u32(child, "reg", &chan);
                if (ret < 0) {
-                       dev_err(dev, "no reg property for node '%s'\n",
-                               child->name);
+                       dev_err(dev, "no reg property for node '%pOFn'\n",
+                               child);
                        goto err_children;
                }
 
index a9af93259b19df97c4a60da563ffb2174125b42c..83a714605cd67b036d97eb7e2924b546f5b87df2 100644 (file)
@@ -208,7 +208,7 @@ MODULE_DEVICE_TABLE(of, ltc4306_of_match);
 
 static int ltc4306_probe(struct i2c_client *client)
 {
-       struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+       struct i2c_adapter *adap = client->adapter;
        const struct chip_desc *chip;
        struct i2c_mux_core *muxc;
        struct ltc4306 *data;
index f2bf3e57ed67b15d0897ade8c250b92ddace812b..5ed55ca4fe9341d4045cfedce494880ca43c425e 100644 (file)
@@ -132,7 +132,7 @@ static int mlxcpld_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
 static int mlxcpld_mux_probe(struct i2c_client *client,
                             const struct i2c_device_id *id)
 {
-       struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+       struct i2c_adapter *adap = client->adapter;
        struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev);
        struct i2c_mux_core *muxc;
        int num, force;
index 24bd9275fde5fc8775407c56b80825aa1d4c1aaf..bfabf985e8308c809156bce0e11cc84f0ca8f901 100644 (file)
@@ -347,7 +347,7 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc)
 static int pca954x_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
-       struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+       struct i2c_adapter *adap = client->adapter;
        struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct device *dev = &client->dev;
        struct device_node *np = dev->of_node;
index 829dc96c9dd6fe527a616bd3c1b14f768192223c..7993a67bd35156e3aed7586cd666d93eb9854b7b 100644 (file)
@@ -60,6 +60,33 @@ config ADXL345_SPI
          will be called adxl345_spi and you will also get adxl345_core
          for the core module.
 
+config ADXL372
+       tristate
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+
+config ADXL372_SPI
+       tristate "Analog Devices ADXL372 3-Axis Accelerometer SPI Driver"
+       depends on SPI
+       select ADXL372
+       select REGMAP_SPI
+       help
+         Say yes here to add support for the Analog Devices ADXL372 triaxial
+         acceleration sensor.
+         To compile this driver as a module, choose M here: the
+         module will be called adxl372_spi.
+
+config ADXL372_I2C
+       tristate "Analog Devices ADXL372 3-Axis Accelerometer I2C Driver"
+       depends on I2C
+       select ADXL372
+       select REGMAP_I2C
+       help
+         Say yes here to add support for the Analog Devices ADXL372 triaxial
+         acceleration sensor.
+         To compile this driver as a module, choose M here: the
+         module will be called adxl372_i2c.
+
 config BMA180
        tristate "Bosch BMA180/BMA250 3-Axis Accelerometer Driver"
        depends on I2C
index 636d4d1b2990b70e703c22ca687af78016be03c3..56bd0215e0d4ded1be403b07b26d1aa4a3855305 100644 (file)
@@ -9,6 +9,9 @@ obj-$(CONFIG_ADIS16209) += adis16209.o
 obj-$(CONFIG_ADXL345) += adxl345_core.o
 obj-$(CONFIG_ADXL345_I2C) += adxl345_i2c.o
 obj-$(CONFIG_ADXL345_SPI) += adxl345_spi.o
+obj-$(CONFIG_ADXL372) += adxl372.o
+obj-$(CONFIG_ADXL372_I2C) += adxl372_i2c.o
+obj-$(CONFIG_ADXL372_SPI) += adxl372_spi.o
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMA220) += bma220_spi.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
index 785c89de91e7b28373addfcdda7c975147027d3d..f22f71315a0cdb912ffef6d5ed70adcfcfb7b71d 100644 (file)
@@ -27,6 +27,9 @@ static int adxl345_i2c_probe(struct i2c_client *client,
 {
        struct regmap *regmap;
 
+       if (!id)
+               return -ENODEV;
+
        regmap = devm_regmap_init_i2c(client, &adxl345_i2c_regmap_config);
        if (IS_ERR(regmap)) {
                dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
@@ -35,7 +38,7 @@ static int adxl345_i2c_probe(struct i2c_client *client,
        }
 
        return adxl345_core_probe(&client->dev, regmap, id->driver_data,
-                                 id ? id->name : NULL);
+                                 id->name);
 }
 
 static int adxl345_i2c_remove(struct i2c_client *client)
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
new file mode 100644 (file)
index 0000000..3b84cb2
--- /dev/null
@@ -0,0 +1,975 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ADXL372 3-Axis Digital Accelerometer core driver
+ *
+ * Copyright 2018 Analog Devices Inc.
+ */
+
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include "adxl372.h"
+
+/* ADXL372 registers definition */
+#define ADXL372_DEVID                  0x00
+#define ADXL372_DEVID_MST              0x01
+#define ADXL372_PARTID                 0x02
+#define ADXL372_STATUS_1               0x04
+#define ADXL372_STATUS_2               0x05
+#define ADXL372_FIFO_ENTRIES_2         0x06
+#define ADXL372_FIFO_ENTRIES_1         0x07
+#define ADXL372_X_DATA_H               0x08
+#define ADXL372_X_DATA_L               0x09
+#define ADXL372_Y_DATA_H               0x0A
+#define ADXL372_Y_DATA_L               0x0B
+#define ADXL372_Z_DATA_H               0x0C
+#define ADXL372_Z_DATA_L               0x0D
+#define ADXL372_X_MAXPEAK_H            0x15
+#define ADXL372_X_MAXPEAK_L            0x16
+#define ADXL372_Y_MAXPEAK_H            0x17
+#define ADXL372_Y_MAXPEAK_L            0x18
+#define ADXL372_Z_MAXPEAK_H            0x19
+#define ADXL372_Z_MAXPEAK_L            0x1A
+#define ADXL372_OFFSET_X               0x20
+#define ADXL372_OFFSET_Y               0x21
+#define ADXL372_OFFSET_Z               0x22
+#define ADXL372_X_THRESH_ACT_H         0x23
+#define ADXL372_X_THRESH_ACT_L         0x24
+#define ADXL372_Y_THRESH_ACT_H         0x25
+#define ADXL372_Y_THRESH_ACT_L         0x26
+#define ADXL372_Z_THRESH_ACT_H         0x27
+#define ADXL372_Z_THRESH_ACT_L         0x28
+#define ADXL372_TIME_ACT               0x29
+#define ADXL372_X_THRESH_INACT_H       0x2A
+#define ADXL372_X_THRESH_INACT_L       0x2B
+#define ADXL372_Y_THRESH_INACT_H       0x2C
+#define ADXL372_Y_THRESH_INACT_L       0x2D
+#define ADXL372_Z_THRESH_INACT_H       0x2E
+#define ADXL372_Z_THRESH_INACT_L       0x2F
+#define ADXL372_TIME_INACT_H           0x30
+#define ADXL372_TIME_INACT_L           0x31
+#define ADXL372_X_THRESH_ACT2_H                0x32
+#define ADXL372_X_THRESH_ACT2_L                0x33
+#define ADXL372_Y_THRESH_ACT2_H                0x34
+#define ADXL372_Y_THRESH_ACT2_L                0x35
+#define ADXL372_Z_THRESH_ACT2_H                0x36
+#define ADXL372_Z_THRESH_ACT2_L                0x37
+#define ADXL372_HPF                    0x38
+#define ADXL372_FIFO_SAMPLES           0x39
+#define ADXL372_FIFO_CTL               0x3A
+#define ADXL372_INT1_MAP               0x3B
+#define ADXL372_INT2_MAP               0x3C
+#define ADXL372_TIMING                 0x3D
+#define ADXL372_MEASURE                        0x3E
+#define ADXL372_POWER_CTL              0x3F
+#define ADXL372_SELF_TEST              0x40
+#define ADXL372_RESET                  0x41
+#define ADXL372_FIFO_DATA              0x42
+
+#define ADXL372_DEVID_VAL              0xAD
+#define ADXL372_PARTID_VAL             0xFA
+#define ADXL372_RESET_CODE             0x52
+
+/* ADXL372_POWER_CTL */
+#define ADXL372_POWER_CTL_MODE_MSK             GENMASK_ULL(1, 0)
+#define ADXL372_POWER_CTL_MODE(x)              (((x) & 0x3) << 0)
+
+/* ADXL372_MEASURE */
+#define ADXL372_MEASURE_LINKLOOP_MSK           GENMASK_ULL(5, 4)
+#define ADXL372_MEASURE_LINKLOOP_MODE(x)       (((x) & 0x3) << 4)
+#define ADXL372_MEASURE_BANDWIDTH_MSK          GENMASK_ULL(2, 0)
+#define ADXL372_MEASURE_BANDWIDTH_MODE(x)      (((x) & 0x7) << 0)
+
+/* ADXL372_TIMING */
+#define ADXL372_TIMING_ODR_MSK                 GENMASK_ULL(7, 5)
+#define ADXL372_TIMING_ODR_MODE(x)             (((x) & 0x7) << 5)
+
+/* ADXL372_FIFO_CTL */
+#define ADXL372_FIFO_CTL_FORMAT_MSK            GENMASK(5, 3)
+#define ADXL372_FIFO_CTL_FORMAT_MODE(x)                (((x) & 0x7) << 3)
+#define ADXL372_FIFO_CTL_MODE_MSK              GENMASK(2, 1)
+#define ADXL372_FIFO_CTL_MODE_MODE(x)          (((x) & 0x3) << 1)
+#define ADXL372_FIFO_CTL_SAMPLES_MSK           BIT(1)
+#define ADXL372_FIFO_CTL_SAMPLES_MODE(x)       (((x) > 0xFF) ? 1 : 0)
+
+/* ADXL372_STATUS_1 */
+#define ADXL372_STATUS_1_DATA_RDY(x)           (((x) >> 0) & 0x1)
+#define ADXL372_STATUS_1_FIFO_RDY(x)           (((x) >> 1) & 0x1)
+#define ADXL372_STATUS_1_FIFO_FULL(x)          (((x) >> 2) & 0x1)
+#define ADXL372_STATUS_1_FIFO_OVR(x)           (((x) >> 3) & 0x1)
+#define ADXL372_STATUS_1_USR_NVM_BUSY(x)       (((x) >> 5) & 0x1)
+#define ADXL372_STATUS_1_AWAKE(x)              (((x) >> 6) & 0x1)
+#define ADXL372_STATUS_1_ERR_USR_REGS(x)       (((x) >> 7) & 0x1)
+
+/* ADXL372_INT1_MAP */
+#define ADXL372_INT1_MAP_DATA_RDY_MSK          BIT(0)
+#define ADXL372_INT1_MAP_DATA_RDY_MODE(x)      (((x) & 0x1) << 0)
+#define ADXL372_INT1_MAP_FIFO_RDY_MSK          BIT(1)
+#define ADXL372_INT1_MAP_FIFO_RDY_MODE(x)      (((x) & 0x1) << 1)
+#define ADXL372_INT1_MAP_FIFO_FULL_MSK         BIT(2)
+#define ADXL372_INT1_MAP_FIFO_FULL_MODE(x)     (((x) & 0x1) << 2)
+#define ADXL372_INT1_MAP_FIFO_OVR_MSK          BIT(3)
+#define ADXL372_INT1_MAP_FIFO_OVR_MODE(x)      (((x) & 0x1) << 3)
+#define ADXL372_INT1_MAP_INACT_MSK             BIT(4)
+#define ADXL372_INT1_MAP_INACT_MODE(x)         (((x) & 0x1) << 4)
+#define ADXL372_INT1_MAP_ACT_MSK               BIT(5)
+#define ADXL372_INT1_MAP_ACT_MODE(x)           (((x) & 0x1) << 5)
+#define ADXL372_INT1_MAP_AWAKE_MSK             BIT(6)
+#define ADXL372_INT1_MAP_AWAKE_MODE(x)         (((x) & 0x1) << 6)
+#define ADXL372_INT1_MAP_LOW_MSK               BIT(7)
+#define ADXL372_INT1_MAP_LOW_MODE(x)           (((x) & 0x1) << 7)
+
+/* The ADXL372 includes a deep, 512 sample FIFO buffer */
+#define ADXL372_FIFO_SIZE                      512
+
+/*
+ * At +/- 200g with 12-bit resolution, scale is computed as:
+ * (200 + 200) * 9.81 / (2^12 - 1) = 0.958241
+ */
+#define ADXL372_USCALE 958241
+
+enum adxl372_op_mode {
+       ADXL372_STANDBY,
+       ADXL372_WAKE_UP,
+       ADXL372_INSTANT_ON,
+       ADXL372_FULL_BW_MEASUREMENT,
+};
+
+enum adxl372_act_proc_mode {
+       ADXL372_DEFAULT,
+       ADXL372_LINKED,
+       ADXL372_LOOPED,
+};
+
+enum adxl372_th_activity {
+       ADXL372_ACTIVITY,
+       ADXL372_ACTIVITY2,
+       ADXL372_INACTIVITY,
+};
+
+enum adxl372_odr {
+       ADXL372_ODR_400HZ,
+       ADXL372_ODR_800HZ,
+       ADXL372_ODR_1600HZ,
+       ADXL372_ODR_3200HZ,
+       ADXL372_ODR_6400HZ,
+};
+
+enum adxl372_bandwidth {
+       ADXL372_BW_200HZ,
+       ADXL372_BW_400HZ,
+       ADXL372_BW_800HZ,
+       ADXL372_BW_1600HZ,
+       ADXL372_BW_3200HZ,
+};
+
+static const unsigned int adxl372_th_reg_high_addr[3] = {
+       [ADXL372_ACTIVITY] = ADXL372_X_THRESH_ACT_H,
+       [ADXL372_ACTIVITY2] = ADXL372_X_THRESH_ACT2_H,
+       [ADXL372_INACTIVITY] = ADXL372_X_THRESH_INACT_H,
+};
+
+enum adxl372_fifo_format {
+       ADXL372_XYZ_FIFO,
+       ADXL372_X_FIFO,
+       ADXL372_Y_FIFO,
+       ADXL372_XY_FIFO,
+       ADXL372_Z_FIFO,
+       ADXL372_XZ_FIFO,
+       ADXL372_YZ_FIFO,
+       ADXL372_XYZ_PEAK_FIFO,
+};
+
+enum adxl372_fifo_mode {
+       ADXL372_FIFO_BYPASSED,
+       ADXL372_FIFO_STREAMED,
+       ADXL372_FIFO_TRIGGERED,
+       ADXL372_FIFO_OLD_SAVED
+};
+
+static const int adxl372_samp_freq_tbl[5] = {
+       400, 800, 1600, 3200, 6400,
+};
+
+static const int adxl372_bw_freq_tbl[5] = {
+       200, 400, 800, 1600, 3200,
+};
+
+struct adxl372_axis_lookup {
+       unsigned int bits;
+       enum adxl372_fifo_format fifo_format;
+};
+
+static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = {
+       { BIT(0), ADXL372_X_FIFO },
+       { BIT(1), ADXL372_Y_FIFO },
+       { BIT(2), ADXL372_Z_FIFO },
+       { BIT(0) | BIT(1), ADXL372_XY_FIFO },
+       { BIT(0) | BIT(2), ADXL372_XZ_FIFO },
+       { BIT(1) | BIT(2), ADXL372_YZ_FIFO },
+       { BIT(0) | BIT(1) | BIT(2), ADXL372_XYZ_FIFO },
+};
+
+#define ADXL372_ACCEL_CHANNEL(index, reg, axis) {                      \
+       .type = IIO_ACCEL,                                              \
+       .address = reg,                                                 \
+       .modified = 1,                                                  \
+       .channel2 = IIO_MOD_##axis,                                     \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
+                                   BIT(IIO_CHAN_INFO_SAMP_FREQ) |      \
+               BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),       \
+       .scan_index = index,                                            \
+       .scan_type = {                                                  \
+               .sign = 's',                                            \
+               .realbits = 12,                                         \
+               .storagebits = 16,                                      \
+               .shift = 4,                                             \
+       },                                                              \
+}
+
+static const struct iio_chan_spec adxl372_channels[] = {
+       ADXL372_ACCEL_CHANNEL(0, ADXL372_X_DATA_H, X),
+       ADXL372_ACCEL_CHANNEL(1, ADXL372_Y_DATA_H, Y),
+       ADXL372_ACCEL_CHANNEL(2, ADXL372_Z_DATA_H, Z),
+};
+
+struct adxl372_state {
+       int                             irq;
+       struct device                   *dev;
+       struct regmap                   *regmap;
+       struct iio_trigger              *dready_trig;
+       enum adxl372_fifo_mode          fifo_mode;
+       enum adxl372_fifo_format        fifo_format;
+       enum adxl372_op_mode            op_mode;
+       enum adxl372_act_proc_mode      act_proc_mode;
+       enum adxl372_odr                odr;
+       enum adxl372_bandwidth          bw;
+       u32                             act_time_ms;
+       u32                             inact_time_ms;
+       u8                              fifo_set_size;
+       u8                              int1_bitmask;
+       u8                              int2_bitmask;
+       u16                             watermark;
+       __be16                          fifo_buf[ADXL372_FIFO_SIZE];
+};
+
+static const unsigned long adxl372_channel_masks[] = {
+       BIT(0), BIT(1), BIT(2),
+       BIT(0) | BIT(1),
+       BIT(0) | BIT(2),
+       BIT(1) | BIT(2),
+       BIT(0) | BIT(1) | BIT(2),
+       0
+};
+
+static int adxl372_read_axis(struct adxl372_state *st, u8 addr)
+{
+       __be16 regval;
+       int ret;
+
+       ret = regmap_bulk_read(st->regmap, addr, &regval, sizeof(regval));
+       if (ret < 0)
+               return ret;
+
+       return be16_to_cpu(regval);
+}
+
+static int adxl372_set_op_mode(struct adxl372_state *st,
+                              enum adxl372_op_mode op_mode)
+{
+       int ret;
+
+       ret = regmap_update_bits(st->regmap, ADXL372_POWER_CTL,
+                                ADXL372_POWER_CTL_MODE_MSK,
+                                ADXL372_POWER_CTL_MODE(op_mode));
+       if (ret < 0)
+               return ret;
+
+       st->op_mode = op_mode;
+
+       return ret;
+}
+
+static int adxl372_set_odr(struct adxl372_state *st,
+                          enum adxl372_odr odr)
+{
+       int ret;
+
+       ret = regmap_update_bits(st->regmap, ADXL372_TIMING,
+                                ADXL372_TIMING_ODR_MSK,
+                                ADXL372_TIMING_ODR_MODE(odr));
+       if (ret < 0)
+               return ret;
+
+       st->odr = odr;
+
+       return ret;
+}
+
+static int adxl372_find_closest_match(const int *array,
+                                     unsigned int size, int val)
+{
+       int i;
+
+       for (i = 0; i < size; i++) {
+               if (val <= array[i])
+                       return i;
+       }
+
+       return size - 1;
+}
+
+static int adxl372_set_bandwidth(struct adxl372_state *st,
+                                enum adxl372_bandwidth bw)
+{
+       int ret;
+
+       ret = regmap_update_bits(st->regmap, ADXL372_MEASURE,
+                                ADXL372_MEASURE_BANDWIDTH_MSK,
+                                ADXL372_MEASURE_BANDWIDTH_MODE(bw));
+       if (ret < 0)
+               return ret;
+
+       st->bw = bw;
+
+       return ret;
+}
+
+static int adxl372_set_act_proc_mode(struct adxl372_state *st,
+                                    enum adxl372_act_proc_mode mode)
+{
+       int ret;
+
+       ret = regmap_update_bits(st->regmap,
+                                ADXL372_MEASURE,
+                                ADXL372_MEASURE_LINKLOOP_MSK,
+                                ADXL372_MEASURE_LINKLOOP_MODE(mode));
+       if (ret < 0)
+               return ret;
+
+       st->act_proc_mode = mode;
+
+       return ret;
+}
+
+static int adxl372_set_activity_threshold(struct adxl372_state *st,
+                                         enum adxl372_th_activity act,
+                                         bool ref_en, bool enable,
+                                         unsigned int threshold)
+{
+       unsigned char buf[6];
+       unsigned char th_reg_high_val, th_reg_low_val, th_reg_high_addr;
+
+       /* scale factor is 100 mg/code */
+       th_reg_high_val = (threshold / 100) >> 3;
+       th_reg_low_val = ((threshold / 100) << 5) | (ref_en << 1) | enable;
+       th_reg_high_addr = adxl372_th_reg_high_addr[act];
+
+       buf[0] = th_reg_high_val;
+       buf[1] = th_reg_low_val;
+       buf[2] = th_reg_high_val;
+       buf[3] = th_reg_low_val;
+       buf[4] = th_reg_high_val;
+       buf[5] = th_reg_low_val;
+
+       return regmap_bulk_write(st->regmap, th_reg_high_addr,
+                                buf, ARRAY_SIZE(buf));
+}
+
+static int adxl372_set_activity_time_ms(struct adxl372_state *st,
+                                       unsigned int act_time_ms)
+{
+       unsigned int reg_val, scale_factor;
+       int ret;
+
+       /*
+        * 3.3 ms per code is the scale factor of the TIME_ACT register for
+        * ODR = 6400 Hz. It is 6.6 ms per code for ODR = 3200 Hz and below.
+        */
+       if (st->odr == ADXL372_ODR_6400HZ)
+               scale_factor = 3300;
+       else
+               scale_factor = 6600;
+
+       reg_val = DIV_ROUND_CLOSEST(act_time_ms * 1000, scale_factor);
+
+       /* TIME_ACT register is 8 bits wide */
+       if (reg_val > 0xFF)
+               reg_val = 0xFF;
+
+       ret = regmap_write(st->regmap, ADXL372_TIME_ACT, reg_val);
+       if (ret < 0)
+               return ret;
+
+       st->act_time_ms = act_time_ms;
+
+       return ret;
+}
+
+static int adxl372_set_inactivity_time_ms(struct adxl372_state *st,
+                                         unsigned int inact_time_ms)
+{
+       unsigned int reg_val_h, reg_val_l, res, scale_factor;
+       int ret;
+
+       /*
+        * 13 ms per code is the scale factor of the TIME_INACT register for
+        * ODR = 6400 Hz. It is 26 ms per code for ODR = 3200 Hz and below.
+        */
+       if (st->odr == ADXL372_ODR_6400HZ)
+               scale_factor = 13;
+       else
+               scale_factor = 26;
+
+       res = DIV_ROUND_CLOSEST(inact_time_ms, scale_factor);
+       reg_val_h = (res >> 8) & 0xFF;
+       reg_val_l = res & 0xFF;
+
+       ret = regmap_write(st->regmap, ADXL372_TIME_INACT_H, reg_val_h);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_write(st->regmap, ADXL372_TIME_INACT_L, reg_val_l);
+       if (ret < 0)
+               return ret;
+
+       st->inact_time_ms = inact_time_ms;
+
+       return ret;
+}
+
+static int adxl372_set_interrupts(struct adxl372_state *st,
+                                 unsigned char int1_bitmask,
+                                 unsigned char int2_bitmask)
+{
+       int ret;
+
+       ret = regmap_write(st->regmap, ADXL372_INT1_MAP, int1_bitmask);
+       if (ret < 0)
+               return ret;
+
+       return regmap_write(st->regmap, ADXL372_INT2_MAP, int2_bitmask);
+}
+
+static int adxl372_configure_fifo(struct adxl372_state *st)
+{
+       unsigned int fifo_samples, fifo_ctl;
+       int ret;
+
+       /* FIFO must be configured while in standby mode */
+       ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
+       if (ret < 0)
+               return ret;
+
+       fifo_samples = st->watermark & 0xFF;
+       fifo_ctl = ADXL372_FIFO_CTL_FORMAT_MODE(st->fifo_format) |
+                  ADXL372_FIFO_CTL_MODE_MODE(st->fifo_mode) |
+                  ADXL372_FIFO_CTL_SAMPLES_MODE(st->watermark);
+
+       ret = regmap_write(st->regmap, ADXL372_FIFO_SAMPLES, fifo_samples);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_write(st->regmap, ADXL372_FIFO_CTL, fifo_ctl);
+       if (ret < 0)
+               return ret;
+
+       return adxl372_set_op_mode(st, ADXL372_FULL_BW_MEASUREMENT);
+}
+
+static int adxl372_get_status(struct adxl372_state *st,
+                             u8 *status1, u8 *status2,
+                             u16 *fifo_entries)
+{
+       __be32 buf;
+       u32 val;
+       int ret;
+
+       /* STATUS1, STATUS2, FIFO_ENTRIES2 and FIFO_ENTRIES are adjacent regs */
+       ret = regmap_bulk_read(st->regmap, ADXL372_STATUS_1,
+                              &buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       val = be32_to_cpu(buf);
+
+       *status1 = (val >> 24) & 0x0F;
+       *status2 = (val >> 16) & 0x0F;
+       /*
+        * FIFO_ENTRIES contains the least significant byte, and FIFO_ENTRIES2
+        * contains the two most significant bits
+        */
+       *fifo_entries = val & 0x3FF;
+
+       return ret;
+}
+
+static irqreturn_t adxl372_trigger_handler(int irq, void  *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct adxl372_state *st = iio_priv(indio_dev);
+       u8 status1, status2;
+       u16 fifo_entries;
+       int i, ret;
+
+       ret = adxl372_get_status(st, &status1, &status2, &fifo_entries);
+       if (ret < 0)
+               goto err;
+
+       if (st->fifo_mode != ADXL372_FIFO_BYPASSED &&
+           ADXL372_STATUS_1_FIFO_FULL(status1)) {
+               /*
+                * When reading data from multiple axes from the FIFO,
+                * to ensure that data is not overwritten and stored out
+                * of order at least one sample set must be left in the
+                * FIFO after every read.
+                */
+               fifo_entries -= st->fifo_set_size;
+
+               /* Read data from the FIFO */
+               ret = regmap_noinc_read(st->regmap, ADXL372_FIFO_DATA,
+                                       st->fifo_buf,
+                                       fifo_entries * sizeof(u16));
+               if (ret < 0)
+                       goto err;
+
+               /* Each sample is 2 bytes */
+               for (i = 0; i < fifo_entries * sizeof(u16);
+                    i += st->fifo_set_size * sizeof(u16))
+                       iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);
+       }
+err:
+       iio_trigger_notify_done(indio_dev->trig);
+       return IRQ_HANDLED;
+}
+
+static int adxl372_setup(struct adxl372_state *st)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADXL372_DEVID, &regval);
+       if (ret < 0)
+               return ret;
+
+       if (regval != ADXL372_DEVID_VAL) {
+               dev_err(st->dev, "Invalid chip id %x\n", regval);
+               return -ENODEV;
+       }
+
+       ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
+       if (ret < 0)
+               return ret;
+
+       /* Set threshold for activity detection to 1g */
+       ret = adxl372_set_activity_threshold(st, ADXL372_ACTIVITY,
+                                            true, true, 1000);
+       if (ret < 0)
+               return ret;
+
+       /* Set threshold for inactivity detection to 100mg */
+       ret = adxl372_set_activity_threshold(st, ADXL372_INACTIVITY,
+                                            true, true, 100);
+       if (ret < 0)
+               return ret;
+
+       /* Set activity processing in Looped mode */
+       ret = adxl372_set_act_proc_mode(st, ADXL372_LOOPED);
+       if (ret < 0)
+               return ret;
+
+       ret = adxl372_set_odr(st, ADXL372_ODR_6400HZ);
+       if (ret < 0)
+               return ret;
+
+       ret = adxl372_set_bandwidth(st, ADXL372_BW_3200HZ);
+       if (ret < 0)
+               return ret;
+
+       /* Set activity timer to 1ms */
+       ret = adxl372_set_activity_time_ms(st, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Set inactivity timer to 10s */
+       ret = adxl372_set_inactivity_time_ms(st, 10000);
+       if (ret < 0)
+               return ret;
+
+       /* Set the mode of operation to full bandwidth measurement mode */
+       return adxl372_set_op_mode(st, ADXL372_FULL_BW_MEASUREMENT);
+}
+
+static int adxl372_reg_access(struct iio_dev *indio_dev,
+                             unsigned int reg,
+                             unsigned int writeval,
+                             unsigned int *readval)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
+
+       if (readval)
+               return regmap_read(st->regmap, reg, readval);
+       else
+               return regmap_write(st->regmap, reg, writeval);
+}
+
+static int adxl372_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long info)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
+       int ret;
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
+                       return ret;
+
+               ret = adxl372_read_axis(st, chan->address);
+               iio_device_release_direct_mode(indio_dev);
+               if (ret < 0)
+                       return ret;
+
+               *val = sign_extend32(ret >> chan->scan_type.shift,
+                                    chan->scan_type.realbits - 1);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = ADXL372_USCALE;
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = adxl372_samp_freq_tbl[st->odr];
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+               *val = adxl372_bw_freq_tbl[st->bw];
+               return IIO_VAL_INT;
+       }
+
+       return -EINVAL;
+}
+
+static int adxl372_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long info)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
+       int odr_index, bw_index, ret;
+
+       switch (info) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               odr_index = adxl372_find_closest_match(adxl372_samp_freq_tbl,
+                                       ARRAY_SIZE(adxl372_samp_freq_tbl),
+                                       val);
+               ret = adxl372_set_odr(st, odr_index);
+               if (ret < 0)
+                       return ret;
+               /*
+                * The timer period depends on the ODR selected.
+                * At 3200 Hz and below, it is 6.6 ms; at 6400 Hz, it is 3.3 ms
+                */
+               ret = adxl372_set_activity_time_ms(st, st->act_time_ms);
+               if (ret < 0)
+                       return ret;
+               /*
+                * The timer period depends on the ODR selected.
+                * At 3200 Hz and below, it is 26 ms; at 6400 Hz, it is 13 ms
+                */
+               ret = adxl372_set_inactivity_time_ms(st, st->inact_time_ms);
+               if (ret < 0)
+                       return ret;
+               /*
+                * The maximum bandwidth is constrained to at most half of
+                * the ODR to ensure that the Nyquist criteria is not violated
+                */
+               if (st->bw > odr_index)
+                       ret = adxl372_set_bandwidth(st, odr_index);
+
+               return ret;
+       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+               bw_index = adxl372_find_closest_match(adxl372_bw_freq_tbl,
+                                       ARRAY_SIZE(adxl372_bw_freq_tbl),
+                                       val);
+               return adxl372_set_bandwidth(st, bw_index);
+       default:
+               return -EINVAL;
+       }
+}
+
+static ssize_t adxl372_show_filter_freq_avail(struct device *dev,
+                                             struct device_attribute *attr,
+                                             char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct adxl372_state *st = iio_priv(indio_dev);
+       int i;
+       size_t len = 0;
+
+       for (i = 0; i <= st->odr; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                                "%d ", adxl372_bw_freq_tbl[i]);
+
+       buf[len - 1] = '\n';
+
+       return len;
+}
+
+static ssize_t adxl372_get_fifo_enabled(struct device *dev,
+                                         struct device_attribute *attr,
+                                         char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct adxl372_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", st->fifo_mode);
+}
+
+static ssize_t adxl372_get_fifo_watermark(struct device *dev,
+                                         struct device_attribute *attr,
+                                         char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct adxl372_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", st->watermark);
+}
+
+static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
+static IIO_CONST_ATTR(hwfifo_watermark_max,
+                     __stringify(ADXL372_FIFO_SIZE));
+static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+                      adxl372_get_fifo_watermark, NULL, 0);
+static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+                      adxl372_get_fifo_enabled, NULL, 0);
+
+static const struct attribute *adxl372_fifo_attributes[] = {
+       &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
+       &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
+       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+       NULL,
+};
+
+static int adxl372_set_watermark(struct iio_dev *indio_dev, unsigned int val)
+{
+       struct adxl372_state *st  = iio_priv(indio_dev);
+
+       if (val > ADXL372_FIFO_SIZE)
+               val = ADXL372_FIFO_SIZE;
+
+       st->watermark = val;
+
+       return 0;
+}
+
+static int adxl372_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
+       unsigned int mask;
+       int i, ret;
+
+       ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0);
+       if (ret < 0)
+               return ret;
+
+       mask = *indio_dev->active_scan_mask;
+
+       for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) {
+               if (mask == adxl372_axis_lookup_table[i].bits)
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(adxl372_axis_lookup_table))
+               return -EINVAL;
+
+       st->fifo_format = adxl372_axis_lookup_table[i].fifo_format;
+       st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask,
+                                         indio_dev->masklength);
+       /*
+        * The 512 FIFO samples can be allotted in several ways, such as:
+        * 170 sample sets of concurrent 3-axis data
+        * 256 sample sets of concurrent 2-axis data (user selectable)
+        * 512 sample sets of single-axis data
+        */
+       if ((st->watermark * st->fifo_set_size) > ADXL372_FIFO_SIZE)
+               st->watermark = (ADXL372_FIFO_SIZE  / st->fifo_set_size);
+
+       st->fifo_mode = ADXL372_FIFO_STREAMED;
+
+       ret = adxl372_configure_fifo(st);
+       if (ret < 0) {
+               st->fifo_mode = ADXL372_FIFO_BYPASSED;
+               adxl372_set_interrupts(st, 0, 0);
+               return ret;
+       }
+
+       return iio_triggered_buffer_postenable(indio_dev);
+}
+
+static int adxl372_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
+       int ret;
+
+       ret = iio_triggered_buffer_predisable(indio_dev);
+       if (ret < 0)
+               return ret;
+
+       adxl372_set_interrupts(st, 0, 0);
+       st->fifo_mode = ADXL372_FIFO_BYPASSED;
+       adxl372_configure_fifo(st);
+
+       return 0;
+}
+
+static const struct iio_buffer_setup_ops adxl372_buffer_ops = {
+       .postenable = adxl372_buffer_postenable,
+       .predisable = adxl372_buffer_predisable,
+};
+
+static int adxl372_dready_trig_set_state(struct iio_trigger *trig,
+                                        bool state)
+{
+       struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+       struct adxl372_state *st = iio_priv(indio_dev);
+       unsigned long int mask = 0;
+
+       if (state)
+               mask = ADXL372_INT1_MAP_FIFO_FULL_MSK;
+
+       return adxl372_set_interrupts(st, mask, 0);
+}
+
+static int adxl372_validate_trigger(struct iio_dev *indio_dev,
+                                   struct iio_trigger *trig)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
+
+       if (st->dready_trig != trig)
+               return -EINVAL;
+
+       return 0;
+}
+
+static const struct iio_trigger_ops adxl372_trigger_ops = {
+       .validate_device = &iio_trigger_validate_own_device,
+       .set_trigger_state = adxl372_dready_trig_set_state,
+};
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400");
+static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
+                      0444, adxl372_show_filter_freq_avail, NULL, 0);
+
+static struct attribute *adxl372_attributes[] = {
+       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+       &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group adxl372_attrs_group = {
+       .attrs = adxl372_attributes,
+};
+
+static const struct iio_info adxl372_info = {
+       .validate_trigger = &adxl372_validate_trigger,
+       .attrs = &adxl372_attrs_group,
+       .read_raw = adxl372_read_raw,
+       .write_raw = adxl372_write_raw,
+       .debugfs_reg_access = &adxl372_reg_access,
+       .hwfifo_set_watermark = adxl372_set_watermark,
+};
+
+bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg)
+{
+       return (reg == ADXL372_FIFO_DATA);
+}
+EXPORT_SYMBOL_GPL(adxl372_readable_noinc_reg);
+
+int adxl372_probe(struct device *dev, struct regmap *regmap,
+                 int irq, const char *name)
+{
+       struct iio_dev *indio_dev;
+       struct adxl372_state *st;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       st = iio_priv(indio_dev);
+       dev_set_drvdata(dev, indio_dev);
+
+       st->dev = dev;
+       st->regmap = regmap;
+       st->irq = irq;
+
+       indio_dev->channels = adxl372_channels;
+       indio_dev->num_channels = ARRAY_SIZE(adxl372_channels);
+       indio_dev->available_scan_masks = adxl372_channel_masks;
+       indio_dev->dev.parent = dev;
+       indio_dev->name = name;
+       indio_dev->info = &adxl372_info;
+       indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
+
+       ret = adxl372_setup(st);
+       if (ret < 0) {
+               dev_err(dev, "ADXL372 setup failed\n");
+               return ret;
+       }
+
+       ret = devm_iio_triggered_buffer_setup(dev,
+                                             indio_dev, NULL,
+                                             adxl372_trigger_handler,
+                                             &adxl372_buffer_ops);
+       if (ret < 0)
+               return ret;
+
+       iio_buffer_set_attrs(indio_dev->buffer, adxl372_fifo_attributes);
+
+       if (st->irq) {
+               st->dready_trig = devm_iio_trigger_alloc(dev,
+                                                        "%s-dev%d",
+                                                        indio_dev->name,
+                                                        indio_dev->id);
+               if (st->dready_trig == NULL)
+                       return -ENOMEM;
+
+               st->dready_trig->ops = &adxl372_trigger_ops;
+               st->dready_trig->dev.parent = dev;
+               iio_trigger_set_drvdata(st->dready_trig, indio_dev);
+               ret = devm_iio_trigger_register(dev, st->dready_trig);
+               if (ret < 0)
+                       return ret;
+
+               indio_dev->trig = iio_trigger_get(st->dready_trig);
+
+               ret = devm_request_threaded_irq(dev, st->irq,
+                                       iio_trigger_generic_data_rdy_poll,
+                                       NULL,
+                                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                                       indio_dev->name, st->dready_trig);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return devm_iio_device_register(dev, indio_dev);
+}
+EXPORT_SYMBOL_GPL(adxl372_probe);
+
+MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/adxl372.h b/drivers/iio/accel/adxl372.h
new file mode 100644 (file)
index 0000000..80a0aa9
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * ADXL372 3-Axis Digital Accelerometer
+ *
+ * Copyright 2018 Analog Devices Inc.
+ */
+
+#ifndef _ADXL372_H_
+#define _ADXL372_H_
+
+#define ADXL372_REVID  0x03
+
+int adxl372_probe(struct device *dev, struct regmap *regmap,
+                 int irq, const char *name);
+bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg);
+
+#endif /* _ADXL372_H_ */
diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c
new file mode 100644 (file)
index 0000000..e1affe4
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ADXL372 3-Axis Digital Accelerometer I2C driver
+ *
+ * Copyright 2018 Analog Devices Inc.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include "adxl372.h"
+
+static const struct regmap_config adxl372_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .readable_noinc_reg = adxl372_readable_noinc_reg,
+};
+
+static int adxl372_i2c_probe(struct i2c_client *client,
+                            const struct i2c_device_id *id)
+{
+       struct regmap *regmap;
+       unsigned int regval;
+       int ret;
+
+       regmap = devm_regmap_init_i2c(client, &adxl372_regmap_config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       ret = regmap_read(regmap, ADXL372_REVID, &regval);
+       if (ret < 0)
+               return ret;
+
+       /* Starting with the 3rd revision an I2C chip bug was fixed */
+       if (regval < 3)
+               dev_warn(&client->dev,
+               "I2C might not work properly with other devices on the bus");
+
+       return adxl372_probe(&client->dev, regmap, client->irq, id->name);
+}
+
+static const struct i2c_device_id adxl372_i2c_id[] = {
+       { "adxl372", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id);
+
+static struct i2c_driver adxl372_i2c_driver = {
+       .driver = {
+               .name = "adxl372_i2c",
+       },
+       .probe = adxl372_i2c_probe,
+       .id_table = adxl372_i2c_id,
+};
+
+module_i2c_driver(adxl372_i2c_driver);
+
+MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer I2C driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c
new file mode 100644 (file)
index 0000000..e14e655
--- /dev/null
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ADXL372 3-Axis Digital Accelerometer SPI driver
+ *
+ * Copyright 2018 Analog Devices Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "adxl372.h"
+
+static const struct regmap_config adxl372_spi_regmap_config = {
+       .reg_bits = 7,
+       .pad_bits = 1,
+       .val_bits = 8,
+       .read_flag_mask = BIT(0),
+       .readable_noinc_reg = adxl372_readable_noinc_reg,
+};
+
+static int adxl372_spi_probe(struct spi_device *spi)
+{
+       const struct spi_device_id *id = spi_get_device_id(spi);
+       struct regmap *regmap;
+
+       regmap = devm_regmap_init_spi(spi, &adxl372_spi_regmap_config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       return adxl372_probe(&spi->dev, regmap, spi->irq, id->name);
+}
+
+static const struct spi_device_id adxl372_spi_id[] = {
+       { "adxl372", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(spi, adxl372_spi_id);
+
+static struct spi_driver adxl372_spi_driver = {
+       .driver = {
+               .name = "adxl372_spi",
+       },
+       .probe = adxl372_spi_probe,
+       .id_table = adxl372_spi_id,
+};
+
+module_spi_driver(adxl372_spi_driver);
+
+MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer SPI driver");
+MODULE_LICENSE("GPL");
index 4a754921fb6f9de7d488a2c7dc59bba0d3d11ddc..a52fea8749a9050a553842067a5c2032392ee8df 100644 (file)
@@ -501,6 +501,16 @@ config MCP3422
          This driver can also be built as a module. If so, the module will be
          called mcp3422.
 
+config MCP3911
+       tristate "Microchip Technology MCP3911 driver"
+       depends on SPI
+       help
+         Say yes here to build support for Microchip Technology's MCP3911
+         analog to digital converter.
+
+         This driver can also be built as a module. If so, the module will be
+         called mcp3911.
+
 config MEDIATEK_MT6577_AUXADC
         tristate "MediaTek AUXADC driver"
         depends on ARCH_MEDIATEK || COMPILE_TEST
@@ -596,6 +606,26 @@ config QCOM_SPMI_VADC
          To compile this driver as a module, choose M here: the module will
          be called qcom-spmi-vadc.
 
+config QCOM_SPMI_ADC5
+       tristate "Qualcomm Technologies Inc. SPMI PMIC5 ADC"
+       depends on SPMI
+       select REGMAP_SPMI
+       select QCOM_VADC_COMMON
+       help
+         This is the IIO Voltage PMIC5 ADC driver for Qualcomm Technologies Inc.
+
+         The driver supports multiple channels read. The ADC is a 16-bit
+         sigma-delta ADC. The hardware supports calibrated results for
+         conversion requests and clients include reading voltage phone
+         power, on board system thermistors connected to the PMIC ADC,
+         PMIC die temperature, charger temperature, battery current, USB voltage
+         input, voltage signals connected to supported PMIC GPIO inputs. The
+         hardware supports internal pull-up for thermistors and can choose between
+         a 100k, 30k and 400k pull up using the ADC channels.
+
+         To compile this driver as a module, choose M here: the module will
+         be called qcom-spmi-adc5.
+
 config RCAR_GYRO_ADC
        tristate "Renesas R-Car GyroADC driver"
        depends on ARCH_RCAR_GEN2 || COMPILE_TEST
index 03db7b578f9c077c4a5790f79f8ba48beb8d56dd..a6e6a0b659e2ab3eb921080c1a7f436c9b93453a 100644 (file)
@@ -47,12 +47,14 @@ obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MAX9611) += max9611.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_MCP3422) += mcp3422.o
+obj-$(CONFIG_MCP3911) += mcp3911.o
 obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
 obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
 obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
+obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o
 obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
 obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
 obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
index 2b20c6c8ec7f631bd0b0f7d19da49d0a86aa4f0e..e0220825fde053e77cd475c961aef690a53cac1b 100644 (file)
@@ -385,6 +385,6 @@ static struct spi_driver ad7298_driver = {
 };
 module_spi_driver(ad7298_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7298 ADC");
 MODULE_LICENSE("GPL v2");
index fbaae47746a83d82cb29135007a7aa8d33b2e7c6..0549686b9ef840917744f857b0030d653f42c54c 100644 (file)
@@ -328,6 +328,6 @@ static struct spi_driver ad7476_driver = {
 };
 module_spi_driver(ad7476_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7476 and similar 1-channel ADCs");
 MODULE_LICENSE("GPL v2");
index d4bbe5b533189730437aa5a8a4c8593288fc10da..4ac3ae62f56f98943b6c719179066e98c716319b 100644 (file)
@@ -822,6 +822,6 @@ static struct spi_driver ad7793_driver = {
 };
 module_spi_driver(ad7793_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs");
 MODULE_LICENSE("GPL v2");
index 205c0f1761aa208abaefb4c39161a451a55c9491..9d4c2467d362b0067d03b53bcc508269f75d2609 100644 (file)
@@ -362,6 +362,6 @@ static struct spi_driver ad7887_driver = {
 };
 module_spi_driver(ad7887_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7887 ADC");
 MODULE_LICENSE("GPL v2");
index ffb7e089969c26a4ab2fd3edca7f742162ad4231..d62dbb62be458cd9652384fb1a2052f5bcde1519 100644 (file)
@@ -363,7 +363,7 @@ static struct spi_driver ad7923_driver = {
 };
 module_spi_driver(ad7923_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_AUTHOR("Patrick Vasseur <patrick.vasseur@c-s.fr>");
 MODULE_DESCRIPTION("Analog Devices AD7904/AD7914/AD7923/AD7924 ADC");
 MODULE_LICENSE("GPL v2");
index e1da67d5ee2204b6ad1e97281653cb3e89ffbc86..7a5b5d00a87ddf40adc4bef2533c927a8e9cec1e 100644 (file)
@@ -892,6 +892,6 @@ static struct i2c_driver ad799x_driver = {
 };
 module_i2c_driver(ad799x_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD799x ADC");
 MODULE_LICENSE("GPL v2");
index 44b516863c9d4d220f3323ca580d98fbb6f8e772..75d2f73582a3d7581e533afd361cdb7af7df46d0 100644 (file)
@@ -248,12 +248,14 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *idev = pf->indio_dev;
        struct at91_adc_state *st = iio_priv(idev);
+       struct iio_chan_spec const *chan;
        int i, j = 0;
 
        for (i = 0; i < idev->masklength; i++) {
                if (!test_bit(i, idev->active_scan_mask))
                        continue;
-               st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, i));
+               chan = idev->channels + i;
+               st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, chan->channel));
                j++;
        }
 
@@ -279,6 +281,8 @@ static void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
                iio_trigger_poll(idev->trig);
        } else {
                st->last_value = at91_adc_readl(st, AT91_ADC_CHAN(st, st->chnb));
+               /* Needed to ACK the DRDY interruption */
+               at91_adc_readl(st, AT91_ADC_LCDR);
                st->done = true;
                wake_up_interruptible(&st->wq_data_avail);
        }
index 4ebda8ab54fe7ae7caae11de4f32789d6b46714d..2f2b563c116223ae824f9f58b6c86ef5eff628c9 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for an envelope detector using a DAC and a comparator
  *
  * Copyright (C) 2016 Axentia Technologies AB
  *
  * Author: Peter Rosin <peda@axentia.se>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 /*
index ea264fa9e567a4f5b2e1f3458e361693712e27b5..929c617db3645eca203ad098e92cd177f52b2c30 100644 (file)
@@ -209,12 +209,14 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
                ret = of_property_read_u32(child, "reg", &reg);
                if (ret) {
                        dev_err(dev, "Failed to get reg property\n");
+                       of_node_put(child);
                        return ret;
                }
 
                if (reg >= MX25_NUM_CFGS) {
                        dev_err(dev,
                                "reg value is greater than the number of available configuration registers\n");
+                       of_node_put(child);
                        return -EINVAL;
                }
 
@@ -228,6 +230,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
                        if (IS_ERR(priv->vref[refp])) {
                                dev_err(dev, "Error, trying to use external voltage reference without a vref-%s regulator.",
                                        mx25_gcq_refp_names[refp]);
+                               of_node_put(child);
                                return PTR_ERR(priv->vref[refp]);
                        }
                        priv->channel_vref_mv[reg] =
@@ -240,6 +243,7 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
                        break;
                default:
                        dev_err(dev, "Invalid positive reference %d\n", refp);
+                       of_node_put(child);
                        return -EINVAL;
                }
 
@@ -254,10 +258,12 @@ static int mx25_gcq_setup_cfgs(struct platform_device *pdev,
 
                if ((refp & MX25_ADCQ_CFG_REFP_MASK) != refp) {
                        dev_err(dev, "Invalid fsl,adc-refp property value\n");
+                       of_node_put(child);
                        return -EINVAL;
                }
                if ((refn & MX25_ADCQ_CFG_REFN_MASK) != refn) {
                        dev_err(dev, "Invalid fsl,adc-refn property value\n");
+                       of_node_put(child);
                        return -EINVAL;
                }
 
index 0538ff8c4ac1d2f1e242898daf644d3b69345c4d..643a4e66eb80b2e1d0d11148b534536f8ac3f546 100644 (file)
@@ -289,7 +289,7 @@ static int max9611_read_csa_voltage(struct max9611_dev *max9611,
                        return ret;
 
                if (*adc_raw > 0) {
-                       *csa_gain = gain_selectors[i];
+                       *csa_gain = (enum max9611_csa_gain)gain_selectors[i];
                        return 0;
                }
        }
diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
new file mode 100644 (file)
index 0000000..dd52f08
--- /dev/null
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Microchip MCP3911, Two-channel Analog Front End
+ *
+ * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
+ * Copyright (C) 2018 Kent Gustavsson <kent@minoris.se>
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#define MCP3911_REG_CHANNEL0           0x00
+#define MCP3911_REG_CHANNEL1           0x03
+#define MCP3911_REG_MOD                        0x06
+#define MCP3911_REG_PHASE              0x07
+#define MCP3911_REG_GAIN               0x09
+
+#define MCP3911_REG_STATUSCOM          0x0a
+#define MCP3911_STATUSCOM_CH1_24WIDTH  BIT(4)
+#define MCP3911_STATUSCOM_CH0_24WIDTH  BIT(3)
+#define MCP3911_STATUSCOM_EN_OFFCAL    BIT(2)
+#define MCP3911_STATUSCOM_EN_GAINCAL   BIT(1)
+
+#define MCP3911_REG_CONFIG             0x0c
+#define MCP3911_CONFIG_CLKEXT          BIT(1)
+#define MCP3911_CONFIG_VREFEXT         BIT(2)
+
+#define MCP3911_REG_OFFCAL_CH0         0x0e
+#define MCP3911_REG_GAINCAL_CH0                0x11
+#define MCP3911_REG_OFFCAL_CH1         0x14
+#define MCP3911_REG_GAINCAL_CH1                0x17
+#define MCP3911_REG_VREFCAL            0x1a
+
+#define MCP3911_CHANNEL(x)             (MCP3911_REG_CHANNEL0 + x * 3)
+#define MCP3911_OFFCAL(x)              (MCP3911_REG_OFFCAL_CH0 + x * 6)
+
+/* Internal voltage reference in uV */
+#define MCP3911_INT_VREF_UV            1200000
+
+#define MCP3911_REG_READ(reg, id)      ((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff)
+#define MCP3911_REG_WRITE(reg, id)     ((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
+
+#define MCP3911_NUM_CHANNELS           2
+
+struct mcp3911 {
+       struct spi_device *spi;
+       struct mutex lock;
+       struct regulator *vref;
+       struct clk *clki;
+       u32 dev_addr;
+};
+
+static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len)
+{
+       int ret;
+
+       reg = MCP3911_REG_READ(reg, adc->dev_addr);
+       ret = spi_write_then_read(adc->spi, &reg, 1, val, len);
+       if (ret < 0)
+               return ret;
+
+       be32_to_cpus(val);
+       *val >>= ((4 - len) * 8);
+       dev_dbg(&adc->spi->dev, "reading 0x%x from register 0x%x\n", *val,
+               reg >> 1);
+       return ret;
+}
+
+static int mcp3911_write(struct mcp3911 *adc, u8 reg, u32 val, u8 len)
+{
+       dev_dbg(&adc->spi->dev, "writing 0x%x to register 0x%x\n", val, reg);
+
+       val <<= (3 - len) * 8;
+       cpu_to_be32s(&val);
+       val |= MCP3911_REG_WRITE(reg, adc->dev_addr);
+
+       return spi_write(adc->spi, &val, len + 1);
+}
+
+static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask,
+               u32 val, u8 len)
+{
+       u32 tmp;
+       int ret;
+
+       ret = mcp3911_read(adc, reg, &tmp, len);
+       if (ret)
+               return ret;
+
+       val &= mask;
+       val |= tmp & ~mask;
+       return mcp3911_write(adc, reg, val, len);
+}
+
+static int mcp3911_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *channel, int *val,
+                           int *val2, long mask)
+{
+       struct mcp3911 *adc = iio_priv(indio_dev);
+       int ret = -EINVAL;
+
+       mutex_lock(&adc->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = mcp3911_read(adc,
+                                  MCP3911_CHANNEL(channel->channel), val, 3);
+               if (ret)
+                       goto out;
+
+               ret = IIO_VAL_INT;
+               break;
+
+       case IIO_CHAN_INFO_OFFSET:
+               ret = mcp3911_read(adc,
+                                  MCP3911_OFFCAL(channel->channel), val, 3);
+               if (ret)
+                       goto out;
+
+               ret = IIO_VAL_INT;
+               break;
+
+       case IIO_CHAN_INFO_SCALE:
+               if (adc->vref) {
+                       ret = regulator_get_voltage(adc->vref);
+                       if (ret < 0) {
+                               dev_err(indio_dev->dev.parent,
+                                       "failed to get vref voltage: %d\n",
+                                      ret);
+                               goto out;
+                       }
+
+                       *val = ret / 1000;
+               } else {
+                       *val = MCP3911_INT_VREF_UV;
+               }
+
+               *val2 = 24;
+               ret = IIO_VAL_FRACTIONAL_LOG2;
+               break;
+       }
+
+out:
+       mutex_unlock(&adc->lock);
+       return ret;
+}
+
+static int mcp3911_write_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *channel, int val,
+                           int val2, long mask)
+{
+       struct mcp3911 *adc = iio_priv(indio_dev);
+       int ret = -EINVAL;
+
+       mutex_lock(&adc->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_OFFSET:
+               if (val2 != 0) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               /* Write offset */
+               ret = mcp3911_write(adc, MCP3911_OFFCAL(channel->channel), val,
+                                   3);
+               if (ret)
+                       goto out;
+
+               /* Enable offset*/
+               ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM,
+                               MCP3911_STATUSCOM_EN_OFFCAL,
+                               MCP3911_STATUSCOM_EN_OFFCAL, 2);
+               break;
+       }
+
+out:
+       mutex_unlock(&adc->lock);
+       return ret;
+}
+
+#define MCP3911_CHAN(idx) {                                    \
+               .type = IIO_VOLTAGE,                            \
+               .indexed = 1,                                   \
+               .channel = idx,                                 \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
+                       BIT(IIO_CHAN_INFO_OFFSET) |             \
+                       BIT(IIO_CHAN_INFO_SCALE),               \
+}
+
+static const struct iio_chan_spec mcp3911_channels[] = {
+       MCP3911_CHAN(0),
+       MCP3911_CHAN(1),
+};
+
+static const struct iio_info mcp3911_info = {
+       .read_raw = mcp3911_read_raw,
+       .write_raw = mcp3911_write_raw,
+};
+
+static int mcp3911_config(struct mcp3911 *adc, struct device_node *of_node)
+{
+       u32 configreg;
+       int ret;
+
+       of_property_read_u32(of_node, "device-addr", &adc->dev_addr);
+       if (adc->dev_addr > 3) {
+               dev_err(&adc->spi->dev,
+                       "invalid device address (%i). Must be in range 0-3.\n",
+                       adc->dev_addr);
+               return -EINVAL;
+       }
+       dev_dbg(&adc->spi->dev, "use device address %i\n", adc->dev_addr);
+
+       ret = mcp3911_read(adc, MCP3911_REG_CONFIG, &configreg, 2);
+       if (ret)
+               return ret;
+
+       if (adc->vref) {
+               dev_dbg(&adc->spi->dev, "use external voltage reference\n");
+               configreg |= MCP3911_CONFIG_VREFEXT;
+       } else {
+               dev_dbg(&adc->spi->dev,
+                       "use internal voltage reference (1.2V)\n");
+               configreg &= ~MCP3911_CONFIG_VREFEXT;
+       }
+
+       if (adc->clki) {
+               dev_dbg(&adc->spi->dev, "use external clock as clocksource\n");
+               configreg |= MCP3911_CONFIG_CLKEXT;
+       } else {
+               dev_dbg(&adc->spi->dev,
+                       "use crystal oscillator as clocksource\n");
+               configreg &= ~MCP3911_CONFIG_CLKEXT;
+       }
+
+       return  mcp3911_write(adc, MCP3911_REG_CONFIG, configreg, 2);
+}
+
+static int mcp3911_probe(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev;
+       struct mcp3911 *adc;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       adc = iio_priv(indio_dev);
+       adc->spi = spi;
+
+       adc->vref = devm_regulator_get_optional(&adc->spi->dev, "vref");
+       if (IS_ERR(adc->vref)) {
+               if (PTR_ERR(adc->vref) == -ENODEV) {
+                       adc->vref = NULL;
+               } else {
+                       dev_err(&adc->spi->dev,
+                               "failed to get regulator (%ld)\n",
+                               PTR_ERR(adc->vref));
+                       return PTR_ERR(adc->vref);
+               }
+
+       } else {
+               ret = regulator_enable(adc->vref);
+               if (ret)
+                       return ret;
+       }
+
+       adc->clki = devm_clk_get(&adc->spi->dev, NULL);
+       if (IS_ERR(adc->clki)) {
+               if (PTR_ERR(adc->clki) == -ENOENT) {
+                       adc->clki = NULL;
+               } else {
+                       dev_err(&adc->spi->dev,
+                               "failed to get adc clk (%ld)\n",
+                               PTR_ERR(adc->clki));
+                       ret = PTR_ERR(adc->clki);
+                       goto reg_disable;
+               }
+       } else {
+               ret = clk_prepare_enable(adc->clki);
+               if (ret < 0) {
+                       dev_err(&adc->spi->dev,
+                               "Failed to enable clki: %d\n", ret);
+                       goto reg_disable;
+               }
+       }
+
+       ret = mcp3911_config(adc, spi->dev.of_node);
+       if (ret)
+               goto clk_disable;
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->dev.of_node = spi->dev.of_node;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->info = &mcp3911_info;
+       spi_set_drvdata(spi, indio_dev);
+
+       indio_dev->channels = mcp3911_channels;
+       indio_dev->num_channels = ARRAY_SIZE(mcp3911_channels);
+
+       mutex_init(&adc->lock);
+
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto clk_disable;
+
+       return ret;
+
+clk_disable:
+       clk_disable_unprepare(adc->clki);
+reg_disable:
+       if (adc->vref)
+               regulator_disable(adc->vref);
+
+       return ret;
+}
+
+static int mcp3911_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct mcp3911 *adc = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       clk_disable_unprepare(adc->clki);
+       if (adc->vref)
+               regulator_disable(adc->vref);
+
+       return 0;
+}
+
+static const struct of_device_id mcp3911_dt_ids[] = {
+       { .compatible = "microchip,mcp3911" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mcp3911_dt_ids);
+
+static const struct spi_device_id mcp3911_id[] = {
+       { "mcp3911", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(spi, mcp3911_id);
+
+static struct spi_driver mcp3911_driver = {
+       .driver = {
+               .name = "mcp3911",
+               .of_match_table = mcp3911_dt_ids,
+       },
+       .probe = mcp3911_probe,
+       .remove = mcp3911_remove,
+       .id_table = mcp3911_id,
+};
+module_spi_driver(mcp3911_driver);
+
+MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
+MODULE_AUTHOR("Kent Gustavsson <kent@minoris.se>");
+MODULE_DESCRIPTION("Microchip Technology MCP3911");
+MODULE_LICENSE("GPL v2");
index da2d16dfa63e3b4eacaca90d8e07c521a85284ea..028ccd218f82a3b0d32b47763d1a2830b3635fd5 100644 (file)
        #define MESON_SAR_ADC_DELTA_10_TS_REVE1                 BIT(26)
        #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK   GENMASK(25, 16)
        #define MESON_SAR_ADC_DELTA_10_TS_REVE0                 BIT(15)
-       #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT               11
        #define MESON_SAR_ADC_DELTA_10_TS_C_MASK                GENMASK(14, 11)
        #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN                BIT(10)
        #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK   GENMASK(9, 0)
        .type = IIO_VOLTAGE,                                            \
        .indexed = 1,                                                   \
        .channel = _chan,                                               \
+       .address = _chan,                                               \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |                  \
                                BIT(IIO_CHAN_INFO_AVERAGE_RAW),         \
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
@@ -235,7 +235,7 @@ struct meson_sar_adc_data {
 struct meson_sar_adc_priv {
        struct regmap                           *regmap;
        struct regulator                        *vref;
-       const struct meson_sar_adc_data         *data;
+       const struct meson_sar_adc_param        *param;
        struct clk                              *clkin;
        struct clk                              *core_clk;
        struct clk                              *adc_sel_clk;
@@ -280,7 +280,7 @@ static int meson_sar_adc_calib_val(struct iio_dev *indio_dev, int val)
        /* use val_calib = scale * val_raw + offset calibration function */
        tmp = div_s64((s64)val * priv->calibscale, MILLION) + priv->calibbias;
 
-       return clamp(tmp, 0, (1 << priv->data->param->resolution) - 1);
+       return clamp(tmp, 0, (1 << priv->param->resolution) - 1);
 }
 
 static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev)
@@ -324,15 +324,15 @@ static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
 
        regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
        fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK, regval);
-       if (fifo_chan != chan->channel) {
+       if (fifo_chan != chan->address) {
                dev_err(&indio_dev->dev,
-                       "ADC FIFO entry belongs to channel %d instead of %d\n",
-                       fifo_chan, chan->channel);
+                       "ADC FIFO entry belongs to channel %d instead of %lu\n",
+                       fifo_chan, chan->address);
                return -EINVAL;
        }
 
        fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK, regval);
-       fifo_val &= GENMASK(priv->data->param->resolution - 1, 0);
+       fifo_val &= GENMASK(priv->param->resolution - 1, 0);
        *val = meson_sar_adc_calib_val(indio_dev, fifo_val);
 
        return 0;
@@ -344,16 +344,16 @@ static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev,
                                        enum meson_sar_adc_num_samples samples)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
-       int val, channel = chan->channel;
+       int val, address = chan->address;
 
-       val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel);
+       val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(address);
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
-                          MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel),
+                          MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(address),
                           val);
 
-       val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel);
+       val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(address);
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
-                          MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val);
+                          MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(address), val);
 }
 
 static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
@@ -373,23 +373,23 @@ static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
 
        /* map channel index 0 to the channel which we want to read */
        regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0),
-                           chan->channel);
+                           chan->address);
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
                           MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval);
 
        regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
-                           chan->channel);
+                           chan->address);
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
                           MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
                           regval);
 
        regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
-                           chan->channel);
+                           chan->address);
        regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
                           MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
                           regval);
 
-       if (chan->channel == 6)
+       if (chan->address == 6)
                regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
                                   MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0);
 }
@@ -451,7 +451,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
 
        mutex_lock(&indio_dev->mlock);
 
-       if (priv->data->param->has_bl30_integration) {
+       if (priv->param->has_bl30_integration) {
                /* prevent BL30 from using the SAR ADC while we are using it */
                regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
                                MESON_SAR_ADC_DELAY_KERNEL_BUSY,
@@ -479,7 +479,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
 
-       if (priv->data->param->has_bl30_integration)
+       if (priv->param->has_bl30_integration)
                /* allow BL30 to use the SAR ADC again */
                regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
                                MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
@@ -527,8 +527,8 @@ static int meson_sar_adc_get_sample(struct iio_dev *indio_dev,
 
        if (ret) {
                dev_warn(indio_dev->dev.parent,
-                        "failed to read sample for channel %d: %d\n",
-                        chan->channel, ret);
+                        "failed to read sample for channel %lu: %d\n",
+                        chan->address, ret);
                return ret;
        }
 
@@ -563,7 +563,7 @@ static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev,
                }
 
                *val = ret / 1000;
-               *val2 = priv->data->param->resolution;
+               *val2 = priv->param->resolution;
                return IIO_VAL_FRACTIONAL_LOG2;
 
        case IIO_CHAN_INFO_CALIBBIAS:
@@ -636,7 +636,7 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
         */
        meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT);
 
-       if (priv->data->param->has_bl30_integration) {
+       if (priv->param->has_bl30_integration) {
                /*
                 * leave sampling delay and the input clocks as configured by
                 * BL30 to make sure BL30 gets the values it expects when
@@ -716,7 +716,7 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
                return ret;
        }
 
-       ret = clk_set_rate(priv->adc_clk, priv->data->param->clock_rate);
+       ret = clk_set_rate(priv->adc_clk, priv->param->clock_rate);
        if (ret) {
                dev_err(indio_dev->dev.parent,
                        "failed to set adc clock rate\n");
@@ -729,7 +729,7 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
 static void meson_sar_adc_set_bandgap(struct iio_dev *indio_dev, bool on_off)
 {
        struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
-       const struct meson_sar_adc_param *param = priv->data->param;
+       const struct meson_sar_adc_param *param = priv->param;
        u32 enable_mask;
 
        if (param->bandgap_reg == MESON_SAR_ADC_REG11)
@@ -849,13 +849,13 @@ static int meson_sar_adc_calib(struct iio_dev *indio_dev)
        int ret, nominal0, nominal1, value0, value1;
 
        /* use points 25% and 75% for calibration */
-       nominal0 = (1 << priv->data->param->resolution) / 4;
-       nominal1 = (1 << priv->data->param->resolution) * 3 / 4;
+       nominal0 = (1 << priv->param->resolution) / 4;
+       nominal1 = (1 << priv->param->resolution) * 3 / 4;
 
        meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_DIV4);
        usleep_range(10, 20);
        ret = meson_sar_adc_get_sample(indio_dev,
-                                      &meson_sar_adc_iio_channels[7],
+                                      &indio_dev->channels[7],
                                       MEAN_AVERAGING, EIGHT_SAMPLES, &value0);
        if (ret < 0)
                goto out;
@@ -863,7 +863,7 @@ static int meson_sar_adc_calib(struct iio_dev *indio_dev)
        meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_MUL3_DIV4);
        usleep_range(10, 20);
        ret = meson_sar_adc_get_sample(indio_dev,
-                                      &meson_sar_adc_iio_channels[7],
+                                      &indio_dev->channels[7],
                                       MEAN_AVERAGING, EIGHT_SAMPLES, &value1);
        if (ret < 0)
                goto out;
@@ -979,11 +979,11 @@ MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match);
 
 static int meson_sar_adc_probe(struct platform_device *pdev)
 {
+       const struct meson_sar_adc_data *match_data;
        struct meson_sar_adc_priv *priv;
        struct iio_dev *indio_dev;
        struct resource *res;
        void __iomem *base;
-       const struct of_device_id *match;
        int irq, ret;
 
        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
@@ -995,15 +995,15 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
        priv = iio_priv(indio_dev);
        init_completion(&priv->done);
 
-       match = of_match_device(meson_sar_adc_of_match, &pdev->dev);
-       if (!match) {
-               dev_err(&pdev->dev, "failed to match device\n");
+       match_data = of_device_get_match_data(&pdev->dev);
+       if (!match_data) {
+               dev_err(&pdev->dev, "failed to get match data\n");
                return -ENODEV;
        }
 
-       priv->data = match->data;
+       priv->param = match_data->param;
 
-       indio_dev->name = priv->data->name;
+       indio_dev->name = match_data->name;
        indio_dev->dev.parent = &pdev->dev;
        indio_dev->dev.of_node = pdev->dev.of_node;
        indio_dev->modes = INDIO_DIRECT_MODE;
@@ -1027,7 +1027,7 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
                return ret;
 
        priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
-                                            priv->data->param->regmap_config);
+                                            priv->param->regmap_config);
        if (IS_ERR(priv->regmap))
                return PTR_ERR(priv->regmap);
 
index b093ecddf1a8ae4fc53410ed57cbd59a2472d9b8..c30c002f1fef78d35a9fca18dee6a8cce3277e3f 100644 (file)
@@ -708,8 +708,8 @@ static int pm8xxx_of_xlate(struct iio_dev *indio_dev,
         * mux.
         */
        if (iiospec->args_count != 2) {
-               dev_err(&indio_dev->dev, "wrong number of arguments for %s need 2 got %d\n",
-                       iiospec->np->name,
+               dev_err(&indio_dev->dev, "wrong number of arguments for %pOFn need 2 got %d\n",
+                       iiospec->np,
                        iiospec->args_count);
                return -EINVAL;
        }
diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
new file mode 100644 (file)
index 0000000..f9af6b0
--- /dev/null
@@ -0,0 +1,793 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/log2.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include "qcom-vadc-common.h"
+
+#define ADC5_USR_REVISION1                     0x0
+#define ADC5_USR_STATUS1                       0x8
+#define ADC5_USR_STATUS1_REQ_STS               BIT(1)
+#define ADC5_USR_STATUS1_EOC                   BIT(0)
+#define ADC5_USR_STATUS1_REQ_STS_EOC_MASK      0x3
+
+#define ADC5_USR_STATUS2                       0x9
+#define ADC5_USR_STATUS2_CONV_SEQ_MASK         0x70
+#define ADC5_USR_STATUS2_CONV_SEQ_MASK_SHIFT   0x5
+
+#define ADC5_USR_IBAT_MEAS                     0xf
+#define ADC5_USR_IBAT_MEAS_SUPPORTED           BIT(0)
+
+#define ADC5_USR_DIG_PARAM                     0x42
+#define ADC5_USR_DIG_PARAM_CAL_VAL             BIT(6)
+#define ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT       6
+#define ADC5_USR_DIG_PARAM_CAL_SEL             0x30
+#define ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT       4
+#define ADC5_USR_DIG_PARAM_DEC_RATIO_SEL       0xc
+#define ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT 2
+
+#define ADC5_USR_FAST_AVG_CTL                  0x43
+#define ADC5_USR_FAST_AVG_CTL_EN               BIT(7)
+#define ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK     0x7
+
+#define ADC5_USR_CH_SEL_CTL                    0x44
+
+#define ADC5_USR_DELAY_CTL                     0x45
+#define ADC5_USR_HW_SETTLE_DELAY_MASK          0xf
+
+#define ADC5_USR_EN_CTL1                       0x46
+#define ADC5_USR_EN_CTL1_ADC_EN                        BIT(7)
+
+#define ADC5_USR_CONV_REQ                      0x47
+#define ADC5_USR_CONV_REQ_REQ                  BIT(7)
+
+#define ADC5_USR_DATA0                         0x50
+
+#define ADC5_USR_DATA1                         0x51
+
+#define ADC5_USR_IBAT_DATA0                    0x52
+
+#define ADC5_USR_IBAT_DATA1                    0x53
+
+/*
+ * Conversion time varies based on the decimation, clock rate, fast average
+ * samples and measurements queued across different VADC peripherals.
+ * Set the timeout to a max of 100ms.
+ */
+#define ADC5_CONV_TIME_MIN_US                  263
+#define ADC5_CONV_TIME_MAX_US                  264
+#define ADC5_CONV_TIME_RETRY                   400
+#define ADC5_CONV_TIMEOUT                      msecs_to_jiffies(100)
+
+/* Digital version >= 5.3 supports hw_settle_2 */
+#define ADC5_HW_SETTLE_DIFF_MINOR              3
+#define ADC5_HW_SETTLE_DIFF_MAJOR              5
+
+enum adc5_cal_method {
+       ADC5_NO_CAL = 0,
+       ADC5_RATIOMETRIC_CAL,
+       ADC5_ABSOLUTE_CAL
+};
+
+enum adc5_cal_val {
+       ADC5_TIMER_CAL = 0,
+       ADC5_NEW_CAL
+};
+
+/**
+ * struct adc5_channel_prop - ADC channel property.
+ * @channel: channel number, refer to the channel list.
+ * @cal_method: calibration method.
+ * @cal_val: calibration value
+ * @decimation: sampling rate supported for the channel.
+ * @prescale: channel scaling performed on the input signal.
+ * @hw_settle_time: the time between AMUX being configured and the
+ *     start of conversion.
+ * @avg_samples: ability to provide single result from the ADC
+ *     that is an average of multiple measurements.
+ * @scale_fn_type: Represents the scaling function to convert voltage
+ *     physical units desired by the client for the channel.
+ * @datasheet_name: Channel name used in device tree.
+ */
+struct adc5_channel_prop {
+       unsigned int            channel;
+       enum adc5_cal_method    cal_method;
+       enum adc5_cal_val       cal_val;
+       unsigned int            decimation;
+       unsigned int            prescale;
+       unsigned int            hw_settle_time;
+       unsigned int            avg_samples;
+       enum vadc_scale_fn_type scale_fn_type;
+       const char              *datasheet_name;
+};
+
+/**
+ * struct adc5_chip - ADC private structure.
+ * @regmap: SPMI ADC5 peripheral register map field.
+ * @dev: SPMI ADC5 device.
+ * @base: base address for the ADC peripheral.
+ * @nchannels: number of ADC channels.
+ * @chan_props: array of ADC channel properties.
+ * @iio_chans: array of IIO channels specification.
+ * @poll_eoc: use polling instead of interrupt.
+ * @complete: ADC result notification after interrupt is received.
+ * @lock: ADC lock for access to the peripheral.
+ * @data: software configuration data.
+ */
+struct adc5_chip {
+       struct regmap           *regmap;
+       struct device           *dev;
+       u16                     base;
+       unsigned int            nchannels;
+       struct adc5_channel_prop        *chan_props;
+       struct iio_chan_spec    *iio_chans;
+       bool                    poll_eoc;
+       struct completion       complete;
+       struct mutex            lock;
+       const struct adc5_data  *data;
+};
+
+static const struct vadc_prescale_ratio adc5_prescale_ratios[] = {
+       {.num =  1, .den =  1},
+       {.num =  1, .den =  3},
+       {.num =  1, .den =  4},
+       {.num =  1, .den =  6},
+       {.num =  1, .den = 20},
+       {.num =  1, .den =  8},
+       {.num = 10, .den = 81},
+       {.num =  1, .den = 10},
+       {.num =  1, .den = 16}
+};
+
+static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len)
+{
+       return regmap_bulk_read(adc->regmap, adc->base + offset, data, len);
+}
+
+static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len)
+{
+       return regmap_bulk_write(adc->regmap, adc->base + offset, data, len);
+}
+
+static int adc5_prescaling_from_dt(u32 num, u32 den)
+{
+       unsigned int pre;
+
+       for (pre = 0; pre < ARRAY_SIZE(adc5_prescale_ratios); pre++)
+               if (adc5_prescale_ratios[pre].num == num &&
+                   adc5_prescale_ratios[pre].den == den)
+                       break;
+
+       if (pre == ARRAY_SIZE(adc5_prescale_ratios))
+               return -EINVAL;
+
+       return pre;
+}
+
+static int adc5_hw_settle_time_from_dt(u32 value,
+                                       const unsigned int *hw_settle)
+{
+       unsigned int i;
+
+       for (i = 0; i < VADC_HW_SETTLE_SAMPLES_MAX; i++) {
+               if (value == hw_settle[i])
+                       return i;
+       }
+
+       return -EINVAL;
+}
+
+static int adc5_avg_samples_from_dt(u32 value)
+{
+       if (!is_power_of_2(value) || value > ADC5_AVG_SAMPLES_MAX)
+               return -EINVAL;
+
+       return __ffs(value);
+}
+
+static int adc5_decimation_from_dt(u32 value,
+                                       const unsigned int *decimation)
+{
+       unsigned int i;
+
+       for (i = 0; i < ADC5_DECIMATION_SAMPLES_MAX; i++) {
+               if (value == decimation[i])
+                       return i;
+       }
+
+       return -EINVAL;
+}
+
+static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data)
+{
+       int ret;
+       u8 rslt_lsb, rslt_msb;
+
+       ret = adc5_read(adc, ADC5_USR_DATA0, &rslt_lsb, sizeof(rslt_lsb));
+       if (ret)
+               return ret;
+
+       ret = adc5_read(adc, ADC5_USR_DATA1, &rslt_msb, sizeof(rslt_lsb));
+       if (ret)
+               return ret;
+
+       *data = (rslt_msb << 8) | rslt_lsb;
+
+       if (*data == ADC5_USR_DATA_CHECK) {
+               pr_err("Invalid data:0x%x\n", *data);
+               return -EINVAL;
+       }
+
+       pr_debug("voltage raw code:0x%x\n", *data);
+
+       return 0;
+}
+
+static int adc5_poll_wait_eoc(struct adc5_chip *adc)
+{
+       unsigned int count, retry = ADC5_CONV_TIME_RETRY;
+       u8 status1;
+       int ret;
+
+       for (count = 0; count < retry; count++) {
+               ret = adc5_read(adc, ADC5_USR_STATUS1, &status1,
+                                                       sizeof(status1));
+               if (ret)
+                       return ret;
+
+               status1 &= ADC5_USR_STATUS1_REQ_STS_EOC_MASK;
+               if (status1 == ADC5_USR_STATUS1_EOC)
+                       return 0;
+
+               usleep_range(ADC5_CONV_TIME_MIN_US, ADC5_CONV_TIME_MAX_US);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static void adc5_update_dig_param(struct adc5_chip *adc,
+                       struct adc5_channel_prop *prop, u8 *data)
+{
+       /* Update calibration value */
+       *data &= ~ADC5_USR_DIG_PARAM_CAL_VAL;
+       *data |= (prop->cal_val << ADC5_USR_DIG_PARAM_CAL_VAL_SHIFT);
+
+       /* Update calibration select */
+       *data &= ~ADC5_USR_DIG_PARAM_CAL_SEL;
+       *data |= (prop->cal_method << ADC5_USR_DIG_PARAM_CAL_SEL_SHIFT);
+
+       /* Update decimation ratio select */
+       *data &= ~ADC5_USR_DIG_PARAM_DEC_RATIO_SEL;
+       *data |= (prop->decimation << ADC5_USR_DIG_PARAM_DEC_RATIO_SEL_SHIFT);
+}
+
+static int adc5_configure(struct adc5_chip *adc,
+                       struct adc5_channel_prop *prop)
+{
+       int ret;
+       u8 buf[6];
+
+       /* Read registers 0x42 through 0x46 */
+       ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
+       if (ret < 0)
+               return ret;
+
+       /* Digital param selection */
+       adc5_update_dig_param(adc, prop, &buf[0]);
+
+       /* Update fast average sample value */
+       buf[1] &= (u8) ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
+       buf[1] |= prop->avg_samples;
+
+       /* Select ADC channel */
+       buf[2] = prop->channel;
+
+       /* Select HW settle delay for channel */
+       buf[3] &= (u8) ~ADC5_USR_HW_SETTLE_DELAY_MASK;
+       buf[3] |= prop->hw_settle_time;
+
+       /* Select ADC enable */
+       buf[4] |= ADC5_USR_EN_CTL1_ADC_EN;
+
+       /* Select CONV request */
+       buf[5] |= ADC5_USR_CONV_REQ_REQ;
+
+       if (!adc->poll_eoc)
+               reinit_completion(&adc->complete);
+
+       return adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
+}
+
+static int adc5_do_conversion(struct adc5_chip *adc,
+                       struct adc5_channel_prop *prop,
+                       struct iio_chan_spec const *chan,
+                       u16 *data_volt, u16 *data_cur)
+{
+       int ret;
+
+       mutex_lock(&adc->lock);
+
+       ret = adc5_configure(adc, prop);
+       if (ret) {
+               pr_err("ADC configure failed with %d\n", ret);
+               goto unlock;
+       }
+
+       if (adc->poll_eoc) {
+               ret = adc5_poll_wait_eoc(adc);
+               if (ret < 0) {
+                       pr_err("EOC bit not set\n");
+                       goto unlock;
+               }
+       } else {
+               ret = wait_for_completion_timeout(&adc->complete,
+                                                       ADC5_CONV_TIMEOUT);
+               if (!ret) {
+                       pr_debug("Did not get completion timeout.\n");
+                       ret = adc5_poll_wait_eoc(adc);
+                       if (ret < 0) {
+                               pr_err("EOC bit not set\n");
+                               goto unlock;
+                       }
+               }
+       }
+
+       ret = adc5_read_voltage_data(adc, data_volt);
+unlock:
+       mutex_unlock(&adc->lock);
+
+       return ret;
+}
+
+static irqreturn_t adc5_isr(int irq, void *dev_id)
+{
+       struct adc5_chip *adc = dev_id;
+
+       complete(&adc->complete);
+
+       return IRQ_HANDLED;
+}
+
+static int adc5_of_xlate(struct iio_dev *indio_dev,
+                               const struct of_phandle_args *iiospec)
+{
+       struct adc5_chip *adc = iio_priv(indio_dev);
+       int i;
+
+       for (i = 0; i < adc->nchannels; i++)
+               if (adc->chan_props[i].channel == iiospec->args[0])
+                       return i;
+
+       return -EINVAL;
+}
+
+static int adc5_read_raw(struct iio_dev *indio_dev,
+                        struct iio_chan_spec const *chan, int *val, int *val2,
+                        long mask)
+{
+       struct adc5_chip *adc = iio_priv(indio_dev);
+       struct adc5_channel_prop *prop;
+       u16 adc_code_volt, adc_code_cur;
+       int ret;
+
+       prop = &adc->chan_props[chan->address];
+
+       switch (mask) {
+       case IIO_CHAN_INFO_PROCESSED:
+               ret = adc5_do_conversion(adc, prop, chan,
+                               &adc_code_volt, &adc_code_cur);
+               if (ret)
+                       return ret;
+
+               ret = qcom_adc5_hw_scale(prop->scale_fn_type,
+                       &adc5_prescale_ratios[prop->prescale],
+                       adc->data,
+                       adc_code_volt, val);
+               if (ret)
+                       return ret;
+
+               return IIO_VAL_INT;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct iio_info adc5_info = {
+       .read_raw = adc5_read_raw,
+       .of_xlate = adc5_of_xlate,
+};
+
+struct adc5_channels {
+       const char *datasheet_name;
+       unsigned int prescale_index;
+       enum iio_chan_type type;
+       long info_mask;
+       enum vadc_scale_fn_type scale_fn_type;
+};
+
+#define ADC5_CHAN(_dname, _type, _mask, _pre, _scale)                  \
+       {                                                               \
+               .datasheet_name = _dname,                               \
+               .prescale_index = _pre,                                 \
+               .type = _type,                                          \
+               .info_mask = _mask,                                     \
+               .scale_fn_type = _scale,                                \
+       },                                                              \
+
+#define ADC5_CHAN_TEMP(_dname, _pre, _scale)                           \
+       ADC5_CHAN(_dname, IIO_TEMP,                                     \
+               BIT(IIO_CHAN_INFO_PROCESSED),                           \
+               _pre, _scale)                                           \
+
+#define ADC5_CHAN_VOLT(_dname, _pre, _scale)                           \
+       ADC5_CHAN(_dname, IIO_VOLTAGE,                                  \
+                 BIT(IIO_CHAN_INFO_PROCESSED),                         \
+                 _pre, _scale)                                         \
+
+static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
+       [ADC5_REF_GND]          = ADC5_CHAN_VOLT("ref_gnd", 1,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_1P25VREF]         = ADC5_CHAN_VOLT("vref_1p25", 1,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_VPH_PWR]          = ADC5_CHAN_VOLT("vph_pwr", 3,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_VBAT_SNS]         = ADC5_CHAN_VOLT("vbat_sns", 3,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_DIE_TEMP]         = ADC5_CHAN_TEMP("die_temp", 1,
+                                       SCALE_HW_CALIB_PMIC_THERM)
+       [ADC5_USB_IN_I]         = ADC5_CHAN_VOLT("usb_in_i_uv", 1,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_USB_IN_V_16]      = ADC5_CHAN_VOLT("usb_in_v_div_16", 16,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_CHG_TEMP]         = ADC5_CHAN_TEMP("chg_temp", 1,
+                                       SCALE_HW_CALIB_PM5_CHG_TEMP)
+       /* Charger prescales SBUx and MID_CHG to fit within 1.8V upper unit */
+       [ADC5_SBUx]             = ADC5_CHAN_VOLT("chg_sbux", 3,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_MID_CHG_DIV6]     = ADC5_CHAN_VOLT("chg_mid_chg", 6,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm", 1,
+                                       SCALE_HW_CALIB_XOTHERM)
+       [ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM2]        = ADC5_CHAN_TEMP("amux_thm2", 1,
+                                       SCALE_HW_CALIB_PM5_SMB_TEMP)
+};
+
+static const struct adc5_channels adc5_chans_rev2[ADC5_MAX_CHANNEL] = {
+       [ADC5_REF_GND]          = ADC5_CHAN_VOLT("ref_gnd", 1,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_1P25VREF]         = ADC5_CHAN_VOLT("vref_1p25", 1,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_VPH_PWR]          = ADC5_CHAN_VOLT("vph_pwr", 3,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_VBAT_SNS]         = ADC5_CHAN_VOLT("vbat_sns", 3,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_VCOIN]            = ADC5_CHAN_VOLT("vcoin", 3,
+                                       SCALE_HW_CALIB_DEFAULT)
+       [ADC5_DIE_TEMP]         = ADC5_CHAN_TEMP("die_temp", 1,
+                                       SCALE_HW_CALIB_PMIC_THERM)
+       [ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+       [ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm_100k_pu", 1,
+                                       SCALE_HW_CALIB_THERM_100K_PULLUP)
+};
+
+static int adc5_get_dt_channel_data(struct adc5_chip *adc,
+                                   struct adc5_channel_prop *prop,
+                                   struct device_node *node,
+                                   const struct adc5_data *data)
+{
+       const char *name = node->name, *channel_name;
+       u32 chan, value, varr[2];
+       int ret;
+       struct device *dev = adc->dev;
+
+       ret = of_property_read_u32(node, "reg", &chan);
+       if (ret) {
+               dev_err(dev, "invalid channel number %s\n", name);
+               return ret;
+       }
+
+       if (chan > ADC5_PARALLEL_ISENSE_VBAT_IDATA ||
+           !data->adc_chans[chan].datasheet_name) {
+               dev_err(dev, "%s invalid channel number %d\n", name, chan);
+               return -EINVAL;
+       }
+
+       /* the channel has DT description */
+       prop->channel = chan;
+
+       channel_name = of_get_property(node,
+                               "label", NULL) ? : node->name;
+       if (!channel_name) {
+               pr_err("Invalid channel name\n");
+               return -EINVAL;
+       }
+       prop->datasheet_name = channel_name;
+
+       ret = of_property_read_u32(node, "qcom,decimation", &value);
+       if (!ret) {
+               ret = adc5_decimation_from_dt(value, data->decimation);
+               if (ret < 0) {
+                       dev_err(dev, "%02x invalid decimation %d\n",
+                               chan, value);
+                       return ret;
+               }
+               prop->decimation = ret;
+       } else {
+               prop->decimation = ADC5_DECIMATION_DEFAULT;
+       }
+
+       ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2);
+       if (!ret) {
+               ret = adc5_prescaling_from_dt(varr[0], varr[1]);
+               if (ret < 0) {
+                       dev_err(dev, "%02x invalid pre-scaling <%d %d>\n",
+                               chan, varr[0], varr[1]);
+                       return ret;
+               }
+               prop->prescale = ret;
+       }
+
+       ret = of_property_read_u32(node, "qcom,hw-settle-time", &value);
+       if (!ret) {
+               u8 dig_version[2];
+
+               ret = adc5_read(adc, ADC5_USR_REVISION1, dig_version,
+                                                       sizeof(dig_version));
+               if (ret < 0) {
+                       dev_err(dev, "Invalid dig version read %d\n", ret);
+                       return ret;
+               }
+
+               pr_debug("dig_ver:minor:%d, major:%d\n", dig_version[0],
+                                               dig_version[1]);
+               /* Digital controller >= 5.3 have hw_settle_2 option */
+               if (dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
+                       dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR)
+                       ret = adc5_hw_settle_time_from_dt(value,
+                                                       data->hw_settle_2);
+               else
+                       ret = adc5_hw_settle_time_from_dt(value,
+                                                       data->hw_settle_1);
+
+               if (ret < 0) {
+                       dev_err(dev, "%02x invalid hw-settle-time %d us\n",
+                               chan, value);
+                       return ret;
+               }
+               prop->hw_settle_time = ret;
+       } else {
+               prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME;
+       }
+
+       ret = of_property_read_u32(node, "qcom,avg-samples", &value);
+       if (!ret) {
+               ret = adc5_avg_samples_from_dt(value);
+               if (ret < 0) {
+                       dev_err(dev, "%02x invalid avg-samples %d\n",
+                               chan, value);
+                       return ret;
+               }
+               prop->avg_samples = ret;
+       } else {
+               prop->avg_samples = VADC_DEF_AVG_SAMPLES;
+       }
+
+       if (of_property_read_bool(node, "qcom,ratiometric"))
+               prop->cal_method = ADC5_RATIOMETRIC_CAL;
+       else
+               prop->cal_method = ADC5_ABSOLUTE_CAL;
+
+       /*
+        * Default to using timer calibration. Using a fresh calibration value
+        * for every conversion will increase the overall time for a request.
+        */
+       prop->cal_val = ADC5_TIMER_CAL;
+
+       dev_dbg(dev, "%02x name %s\n", chan, name);
+
+       return 0;
+}
+
+static const struct adc5_data adc5_data_pmic = {
+       .full_scale_code_volt = 0x70e4,
+       .full_scale_code_cur = 0x2710,
+       .adc_chans = adc5_chans_pmic,
+       .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
+                               {250, 420, 840},
+       .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+                               {15, 100, 200, 300, 400, 500, 600, 700,
+                               800, 900, 1, 2, 4, 6, 8, 10},
+       .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+                               {15, 100, 200, 300, 400, 500, 600, 700,
+                               1, 2, 4, 8, 16, 32, 64, 128},
+};
+
+static const struct adc5_data adc5_data_pmic_rev2 = {
+       .full_scale_code_volt = 0x4000,
+       .full_scale_code_cur = 0x1800,
+       .adc_chans = adc5_chans_rev2,
+       .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
+                               {256, 512, 1024},
+       .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+                               {0, 100, 200, 300, 400, 500, 600, 700,
+                               800, 900, 1, 2, 4, 6, 8, 10},
+       .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+                               {15, 100, 200, 300, 400, 500, 600, 700,
+                               1, 2, 4, 8, 16, 32, 64, 128},
+};
+
+static const struct of_device_id adc5_match_table[] = {
+       {
+               .compatible = "qcom,spmi-adc5",
+               .data = &adc5_data_pmic,
+       },
+       {
+               .compatible = "qcom,spmi-adc-rev2",
+               .data = &adc5_data_pmic_rev2,
+       },
+       { }
+};
+
+static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node)
+{
+       const struct adc5_channels *adc_chan;
+       struct iio_chan_spec *iio_chan;
+       struct adc5_channel_prop prop, *chan_props;
+       struct device_node *child;
+       unsigned int index = 0;
+       const struct of_device_id *id;
+       const struct adc5_data *data;
+       int ret;
+
+       adc->nchannels = of_get_available_child_count(node);
+       if (!adc->nchannels)
+               return -EINVAL;
+
+       adc->iio_chans = devm_kcalloc(adc->dev, adc->nchannels,
+                                      sizeof(*adc->iio_chans), GFP_KERNEL);
+       if (!adc->iio_chans)
+               return -ENOMEM;
+
+       adc->chan_props = devm_kcalloc(adc->dev, adc->nchannels,
+                                       sizeof(*adc->chan_props), GFP_KERNEL);
+       if (!adc->chan_props)
+               return -ENOMEM;
+
+       chan_props = adc->chan_props;
+       iio_chan = adc->iio_chans;
+       id = of_match_node(adc5_match_table, node);
+       if (id)
+               data = id->data;
+       else
+               data = &adc5_data_pmic;
+       adc->data = data;
+
+       for_each_available_child_of_node(node, child) {
+               ret = adc5_get_dt_channel_data(adc, &prop, child, data);
+               if (ret) {
+                       of_node_put(child);
+                       return ret;
+               }
+
+               prop.scale_fn_type =
+                       data->adc_chans[prop.channel].scale_fn_type;
+               *chan_props = prop;
+               adc_chan = &data->adc_chans[prop.channel];
+
+               iio_chan->channel = prop.channel;
+               iio_chan->datasheet_name = prop.datasheet_name;
+               iio_chan->extend_name = prop.datasheet_name;
+               iio_chan->info_mask_separate = adc_chan->info_mask;
+               iio_chan->type = adc_chan->type;
+               iio_chan->address = index;
+               iio_chan++;
+               chan_props++;
+               index++;
+       }
+
+       return 0;
+}
+
+static int adc5_probe(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       struct iio_dev *indio_dev;
+       struct adc5_chip *adc;
+       struct regmap *regmap;
+       int ret, irq_eoc;
+       u32 reg;
+
+       regmap = dev_get_regmap(dev->parent, NULL);
+       if (!regmap)
+               return -ENODEV;
+
+       ret = of_property_read_u32(node, "reg", &reg);
+       if (ret < 0)
+               return ret;
+
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       adc = iio_priv(indio_dev);
+       adc->regmap = regmap;
+       adc->dev = dev;
+       adc->base = reg;
+       init_completion(&adc->complete);
+       mutex_init(&adc->lock);
+
+       ret = adc5_get_dt_data(adc, node);
+       if (ret) {
+               pr_err("adc get dt data failed\n");
+               return ret;
+       }
+
+       irq_eoc = platform_get_irq(pdev, 0);
+       if (irq_eoc < 0) {
+               if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL)
+                       return irq_eoc;
+               adc->poll_eoc = true;
+       } else {
+               ret = devm_request_irq(dev, irq_eoc, adc5_isr, 0,
+                                      "pm-adc5", adc);
+               if (ret)
+                       return ret;
+       }
+
+       indio_dev->dev.parent = dev;
+       indio_dev->dev.of_node = node;
+       indio_dev->name = pdev->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->info = &adc5_info;
+       indio_dev->channels = adc->iio_chans;
+       indio_dev->num_channels = adc->nchannels;
+
+       return devm_iio_device_register(dev, indio_dev);
+}
+
+static struct platform_driver adc5_driver = {
+       .driver = {
+               .name = "qcom-spmi-adc5.c",
+               .of_match_table = adc5_match_table,
+       },
+       .probe = adc5_probe,
+};
+module_platform_driver(adc5_driver);
+
+MODULE_ALIAS("platform:qcom-spmi-adc5");
+MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 ADC driver");
+MODULE_LICENSE("GPL v2");
index fe3d7826783c0fcd0bae1831f356ba0d5acc86a4..dcd7fb5b9fb24ab21190d2769cb1238db1fdbc13 100644 (file)
@@ -47,8 +47,79 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = {
        {44,    125}
 };
 
+/*
+ * Voltage to temperature table for 100k pull up for NTCG104EF104 with
+ * 1.875V reference.
+ */
+static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
+       { 1831, -40000 },
+       { 1814, -35000 },
+       { 1791, -30000 },
+       { 1761, -25000 },
+       { 1723, -20000 },
+       { 1675, -15000 },
+       { 1616, -10000 },
+       { 1545, -5000 },
+       { 1463, 0 },
+       { 1370, 5000 },
+       { 1268, 10000 },
+       { 1160, 15000 },
+       { 1049, 20000 },
+       { 937,  25000 },
+       { 828,  30000 },
+       { 726,  35000 },
+       { 630,  40000 },
+       { 544,  45000 },
+       { 467,  50000 },
+       { 399,  55000 },
+       { 340,  60000 },
+       { 290,  65000 },
+       { 247,  70000 },
+       { 209,  75000 },
+       { 179,  80000 },
+       { 153,  85000 },
+       { 130,  90000 },
+       { 112,  95000 },
+       { 96,   100000 },
+       { 82,   105000 },
+       { 71,   110000 },
+       { 62,   115000 },
+       { 53,   120000 },
+       { 46,   125000 },
+};
+
+static int qcom_vadc_scale_hw_calib_volt(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_uv);
+static int qcom_vadc_scale_hw_calib_therm(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec);
+static int qcom_vadc_scale_hw_smb_temp(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec);
+static int qcom_vadc_scale_hw_chg5_temp(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec);
+static int qcom_vadc_scale_hw_calib_die_temp(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec);
+
+static struct qcom_adc5_scale_type scale_adc5_fn[] = {
+       [SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
+       [SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
+       [SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
+       [SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp},
+       [SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
+       [SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
+};
+
 static int qcom_vadc_map_voltage_temp(const struct vadc_map_pt *pts,
-                                     u32 tablesize, s32 input, s64 *output)
+                                     u32 tablesize, s32 input, int *output)
 {
        bool descending = 1;
        u32 i = 0;
@@ -128,7 +199,7 @@ static int qcom_vadc_scale_therm(const struct vadc_linear_graph *calib_graph,
                                 bool absolute, u16 adc_code,
                                 int *result_mdec)
 {
-       s64 voltage = 0, result = 0;
+       s64 voltage = 0;
        int ret;
 
        qcom_vadc_scale_calib(calib_graph, adc_code, absolute, &voltage);
@@ -138,12 +209,11 @@ static int qcom_vadc_scale_therm(const struct vadc_linear_graph *calib_graph,
 
        ret = qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb,
                                         ARRAY_SIZE(adcmap_100k_104ef_104fb),
-                                        voltage, &result);
+                                        voltage, result_mdec);
        if (ret)
                return ret;
 
-       result *= 1000;
-       *result_mdec = result;
+       *result_mdec *= 1000;
 
        return 0;
 }
@@ -191,6 +261,99 @@ static int qcom_vadc_scale_chg_temp(const struct vadc_linear_graph *calib_graph,
        return 0;
 }
 
+static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               unsigned int factor)
+{
+       s64 voltage, temp, adc_vdd_ref_mv = 1875;
+
+       /*
+        * The normal data range is between 0V to 1.875V. On cases where
+        * we read low voltage values, the ADC code can go beyond the
+        * range and the scale result is incorrect so we clamp the values
+        * for the cases where the code represents a value below 0V
+        */
+       if (adc_code > VADC5_MAX_CODE)
+               adc_code = 0;
+
+       /* (ADC code * vref_vadc (1.875V)) / full_scale_code */
+       voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
+       voltage = div64_s64(voltage, data->full_scale_code_volt);
+       if (voltage > 0) {
+               voltage *= prescale->den;
+               temp = prescale->num * factor;
+               voltage = div64_s64(voltage, temp);
+       } else {
+               voltage = 0;
+       }
+
+       return (int) voltage;
+}
+
+static int qcom_vadc_scale_hw_calib_volt(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_uv)
+{
+       *result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
+                               prescale, data, 1);
+
+       return 0;
+}
+
+static int qcom_vadc_scale_hw_calib_therm(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec)
+{
+       int voltage;
+
+       voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
+                               prescale, data, 1000);
+
+       /* Map voltage to temperature from look-up table */
+       return qcom_vadc_map_voltage_temp(adcmap_100k_104ef_104fb_1875_vref,
+                                ARRAY_SIZE(adcmap_100k_104ef_104fb_1875_vref),
+                                voltage, result_mdec);
+}
+
+static int qcom_vadc_scale_hw_calib_die_temp(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec)
+{
+       *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
+                               prescale, data, 2);
+       *result_mdec -= KELVINMIL_CELSIUSMIL;
+
+       return 0;
+}
+
+static int qcom_vadc_scale_hw_smb_temp(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec)
+{
+       *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code * 100,
+                               prescale, data, PMIC5_SMB_TEMP_SCALE_FACTOR);
+       *result_mdec = PMIC5_SMB_TEMP_CONSTANT - *result_mdec;
+
+       return 0;
+}
+
+static int qcom_vadc_scale_hw_chg5_temp(
+                               const struct vadc_prescale_ratio *prescale,
+                               const struct adc5_data *data,
+                               u16 adc_code, int *result_mdec)
+{
+       *result_mdec = qcom_vadc_scale_code_voltage_factor(adc_code,
+                               prescale, data, 4);
+       *result_mdec = PMIC5_CHG_TEMP_SCALE_FACTOR - *result_mdec;
+
+       return 0;
+}
+
 int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
                    const struct vadc_linear_graph *calib_graph,
                    const struct vadc_prescale_ratio *prescale,
@@ -221,6 +384,22 @@ int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
 }
 EXPORT_SYMBOL(qcom_vadc_scale);
 
+int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
+                   const struct vadc_prescale_ratio *prescale,
+                   const struct adc5_data *data,
+                   u16 adc_code, int *result)
+{
+       if (!(scaletype >= SCALE_HW_CALIB_DEFAULT &&
+               scaletype < SCALE_HW_CALIB_INVALID)) {
+               pr_err("Invalid scale type %d\n", scaletype);
+               return -EINVAL;
+       }
+
+       return scale_adc5_fn[scaletype].scale_fn(prescale, data,
+                                       adc_code, result);
+}
+EXPORT_SYMBOL(qcom_adc5_hw_scale);
+
 int qcom_vadc_decimation_from_dt(u32 value)
 {
        if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||
index 1d5354ff5c7297d5999fc4094e502a2b792592d4..bbb1fa02b382f56499b7dd8aaf4a71f38efb11e4 100644 (file)
 
 #define VADC_DECIMATION_MIN                    512
 #define VADC_DECIMATION_MAX                    4096
+#define ADC5_DEF_VBAT_PRESCALING               1 /* 1:3 */
+#define ADC5_DECIMATION_SHORT                  250
+#define ADC5_DECIMATION_MEDIUM                 420
+#define ADC5_DECIMATION_LONG                   840
+/* Default decimation - 1024 for rev2, 840 for pmic5 */
+#define ADC5_DECIMATION_DEFAULT                        2
+#define ADC5_DECIMATION_SAMPLES_MAX            3
 
 #define VADC_HW_SETTLE_DELAY_MAX               10000
+#define VADC_HW_SETTLE_SAMPLES_MAX             16
 #define VADC_AVG_SAMPLES_MAX                   512
+#define ADC5_AVG_SAMPLES_MAX                   16
 
 #define KELVINMIL_CELSIUSMIL                   273150
+#define PMIC5_CHG_TEMP_SCALE_FACTOR            377500
+#define PMIC5_SMB_TEMP_CONSTANT                        419400
+#define PMIC5_SMB_TEMP_SCALE_FACTOR            356
 
 #define PMI_CHG_SCALE_1                                -138890
 #define PMI_CHG_SCALE_2                                391750000000LL
 
+#define VADC5_MAX_CODE                         0x7fff
+#define ADC5_FULL_SCALE_CODE                   0x70e4
+#define ADC5_USR_DATA_CHECK                    0x8000
+
 /**
  * struct vadc_map_pt - Map the graph representation for ADC channel
  * @x: Represent the ADC digitized code.
@@ -89,6 +105,18 @@ struct vadc_prescale_ratio {
  * SCALE_PMIC_THERM: Returns result in milli degree's Centigrade.
  * SCALE_XOTHERM: Returns XO thermistor voltage in millidegC.
  * SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp
+ * SCALE_HW_CALIB_DEFAULT: Default scaling to convert raw adc code to
+ *     voltage (uV) with hardware applied offset/slope values to adc code.
+ * SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using
+ *     lookup table. The hardware applies offset/slope to adc code.
+ * SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using
+ *     100k pullup. The hardware applies offset/slope to adc code.
+ * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
+ *     The hardware applies offset/slope to adc code.
+ * SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
+ *     charger temperature.
+ * SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
+ *     SMB1390 temperature.
  */
 enum vadc_scale_fn_type {
        SCALE_DEFAULT = 0,
@@ -96,6 +124,22 @@ enum vadc_scale_fn_type {
        SCALE_PMIC_THERM,
        SCALE_XOTHERM,
        SCALE_PMI_CHG_TEMP,
+       SCALE_HW_CALIB_DEFAULT,
+       SCALE_HW_CALIB_THERM_100K_PULLUP,
+       SCALE_HW_CALIB_XOTHERM,
+       SCALE_HW_CALIB_PMIC_THERM,
+       SCALE_HW_CALIB_PM5_CHG_TEMP,
+       SCALE_HW_CALIB_PM5_SMB_TEMP,
+       SCALE_HW_CALIB_INVALID,
+};
+
+struct adc5_data {
+       const u32       full_scale_code_volt;
+       const u32       full_scale_code_cur;
+       const struct adc5_channels *adc_chans;
+       unsigned int    *decimation;
+       unsigned int    *hw_settle_1;
+       unsigned int    *hw_settle_2;
 };
 
 int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
@@ -104,6 +148,16 @@ int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
                    bool absolute,
                    u16 adc_code, int *result_mdec);
 
+struct qcom_adc5_scale_type {
+       int (*scale_fn)(const struct vadc_prescale_ratio *prescale,
+               const struct adc5_data *data, u16 adc_code, int *result);
+};
+
+int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
+                   const struct vadc_prescale_ratio *prescale,
+                   const struct adc5_data *data,
+                   u16 adc_code, int *result_mdec);
+
 int qcom_vadc_decimation_from_dt(u32 value);
 
 #endif /* QCOM_VADC_COMMON_H */
index dcb50172186f49ab62722997cc34a55bdb667a06..4e982b51bcda7bc4dc1a1cdad5e7b29507e7aac9 100644 (file)
@@ -343,8 +343,8 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev)
        for_each_child_of_node(np, child) {
                of_id = of_match_node(rcar_gyroadc_child_match, child);
                if (!of_id) {
-                       dev_err(dev, "Ignoring unsupported ADC \"%s\".",
-                               child->name);
+                       dev_err(dev, "Ignoring unsupported ADC \"%pOFn\".",
+                               child);
                        continue;
                }
 
@@ -381,16 +381,16 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev)
                        ret = of_property_read_u32(child, "reg", &reg);
                        if (ret) {
                                dev_err(dev,
-                                       "Failed to get child reg property of ADC \"%s\".\n",
-                                       child->name);
+                                       "Failed to get child reg property of ADC \"%pOFn\".\n",
+                                       child);
                                return ret;
                        }
 
                        /* Channel number is too high. */
                        if (reg >= num_channels) {
                                dev_err(dev,
-                                       "Only %i channels supported with %s, but reg = <%i>.\n",
-                                       num_channels, child->name, reg);
+                                       "Only %i channels supported with %pOFn, but reg = <%i>.\n",
+                                       num_channels, child, reg);
                                return ret;
                        }
                }
index 2b60efea0c39fdf27497ee4a5432337bf4126e99..7940b23dcad901baa00784ee48497e0f1dd99ec7 100644 (file)
@@ -5,10 +5,12 @@
 #include <linux/iio/iio.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <linux/slab.h>
 
 /* PMIC global registers definition */
 #define SC27XX_MODULE_EN               0xc08
@@ -87,16 +89,73 @@ struct sc27xx_adc_linear_graph {
  * should use the small-scale graph, and if more than 1.2v, we should use the
  * big-scale graph.
  */
-static const struct sc27xx_adc_linear_graph big_scale_graph = {
+static struct sc27xx_adc_linear_graph big_scale_graph = {
        4200, 3310,
        3600, 2832,
 };
 
-static const struct sc27xx_adc_linear_graph small_scale_graph = {
+static struct sc27xx_adc_linear_graph small_scale_graph = {
        1000, 3413,
        100, 341,
 };
 
+static const struct sc27xx_adc_linear_graph big_scale_graph_calib = {
+       4200, 856,
+       3600, 733,
+};
+
+static const struct sc27xx_adc_linear_graph small_scale_graph_calib = {
+       1000, 833,
+       100, 80,
+};
+
+static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc)
+{
+       return ((calib_data & 0xff) + calib_adc - 128) * 4;
+}
+
+static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data,
+                                       bool big_scale)
+{
+       const struct sc27xx_adc_linear_graph *calib_graph;
+       struct sc27xx_adc_linear_graph *graph;
+       struct nvmem_cell *cell;
+       const char *cell_name;
+       u32 calib_data = 0;
+       void *buf;
+       size_t len;
+
+       if (big_scale) {
+               calib_graph = &big_scale_graph_calib;
+               graph = &big_scale_graph;
+               cell_name = "big_scale_calib";
+       } else {
+               calib_graph = &small_scale_graph_calib;
+               graph = &small_scale_graph;
+               cell_name = "small_scale_calib";
+       }
+
+       cell = nvmem_cell_get(data->dev, cell_name);
+       if (IS_ERR(cell))
+               return PTR_ERR(cell);
+
+       buf = nvmem_cell_read(cell, &len);
+       nvmem_cell_put(cell);
+
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
+
+       memcpy(&calib_data, buf, min(len, sizeof(u32)));
+
+       /* Only need to calibrate the adc values in the linear graph. */
+       graph->adc0 = sc27xx_adc_get_calib_data(calib_data, calib_graph->adc0);
+       graph->adc1 = sc27xx_adc_get_calib_data(calib_data >> 8,
+                                               calib_graph->adc1);
+
+       kfree(buf);
+       return 0;
+}
+
 static int sc27xx_adc_get_ratio(int channel, int scale)
 {
        switch (channel) {
@@ -209,7 +268,7 @@ static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data,
        *div_denominator = ratio & SC27XX_RATIO_DENOMINATOR_MASK;
 }
 
-static int sc27xx_adc_to_volt(const struct sc27xx_adc_linear_graph *graph,
+static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph,
                              int raw_adc)
 {
        int tmp;
@@ -273,6 +332,17 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev,
        int ret, tmp;
 
        switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               mutex_lock(&indio_dev->mlock);
+               ret = sc27xx_adc_read(data, chan->channel, scale, &tmp);
+               mutex_unlock(&indio_dev->mlock);
+
+               if (ret)
+                       return ret;
+
+               *val = tmp;
+               return IIO_VAL_INT;
+
        case IIO_CHAN_INFO_PROCESSED:
                mutex_lock(&indio_dev->mlock);
                ret = sc27xx_adc_read_processed(data, chan->channel, scale,
@@ -315,48 +385,47 @@ static const struct iio_info sc27xx_info = {
        .write_raw = &sc27xx_adc_write_raw,
 };
 
-#define SC27XX_ADC_CHANNEL(index) {                            \
+#define SC27XX_ADC_CHANNEL(index, mask) {                      \
        .type = IIO_VOLTAGE,                                    \
        .channel = index,                                       \
-       .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |    \
-                             BIT(IIO_CHAN_INFO_SCALE),         \
+       .info_mask_separate = mask | BIT(IIO_CHAN_INFO_SCALE),  \
        .datasheet_name = "CH##index",                          \
        .indexed = 1,                                           \
 }
 
 static const struct iio_chan_spec sc27xx_channels[] = {
-       SC27XX_ADC_CHANNEL(0),
-       SC27XX_ADC_CHANNEL(1),
-       SC27XX_ADC_CHANNEL(2),
-       SC27XX_ADC_CHANNEL(3),
-       SC27XX_ADC_CHANNEL(4),
-       SC27XX_ADC_CHANNEL(5),
-       SC27XX_ADC_CHANNEL(6),
-       SC27XX_ADC_CHANNEL(7),
-       SC27XX_ADC_CHANNEL(8),
-       SC27XX_ADC_CHANNEL(9),
-       SC27XX_ADC_CHANNEL(10),
-       SC27XX_ADC_CHANNEL(11),
-       SC27XX_ADC_CHANNEL(12),
-       SC27XX_ADC_CHANNEL(13),
-       SC27XX_ADC_CHANNEL(14),
-       SC27XX_ADC_CHANNEL(15),
-       SC27XX_ADC_CHANNEL(16),
-       SC27XX_ADC_CHANNEL(17),
-       SC27XX_ADC_CHANNEL(18),
-       SC27XX_ADC_CHANNEL(19),
-       SC27XX_ADC_CHANNEL(20),
-       SC27XX_ADC_CHANNEL(21),
-       SC27XX_ADC_CHANNEL(22),
-       SC27XX_ADC_CHANNEL(23),
-       SC27XX_ADC_CHANNEL(24),
-       SC27XX_ADC_CHANNEL(25),
-       SC27XX_ADC_CHANNEL(26),
-       SC27XX_ADC_CHANNEL(27),
-       SC27XX_ADC_CHANNEL(28),
-       SC27XX_ADC_CHANNEL(29),
-       SC27XX_ADC_CHANNEL(30),
-       SC27XX_ADC_CHANNEL(31),
+       SC27XX_ADC_CHANNEL(0, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(1, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(2, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(3, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(4, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(5, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(6, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(7, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(8, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(9, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(10, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(11, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(12, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(13, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(14, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(15, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(16, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(17, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(18, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(19, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(20, BIT(IIO_CHAN_INFO_RAW)),
+       SC27XX_ADC_CHANNEL(21, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(22, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(23, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(24, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(25, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(26, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(27, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(28, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(29, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(30, BIT(IIO_CHAN_INFO_PROCESSED)),
+       SC27XX_ADC_CHANNEL(31, BIT(IIO_CHAN_INFO_PROCESSED)),
 };
 
 static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
@@ -380,6 +449,15 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
        if (ret)
                goto disable_clk;
 
+       /* ADC channel scales' calibration from nvmem device */
+       ret = sc27xx_adc_scale_calibration(data, true);
+       if (ret)
+               goto disable_clk;
+
+       ret = sc27xx_adc_scale_calibration(data, false);
+       if (ret)
+               goto disable_clk;
+
        return 0;
 
 disable_clk:
index a5bd5944bc66083d1a866e54e873b7ed46bdd52f..0ad63592cc3c91ddfe8deca1e7ecfde6bb3a2968 100644 (file)
@@ -51,7 +51,7 @@
 
 struct ti_ads7950_state {
        struct spi_device       *spi;
-       struct spi_transfer     ring_xfer[TI_ADS7950_MAX_CHAN + 2];
+       struct spi_transfer     ring_xfer;
        struct spi_transfer     scan_single_xfer[3];
        struct spi_message      ring_msg;
        struct spi_message      scan_single_msg;
@@ -65,11 +65,11 @@ struct ti_ads7950_state {
         * DMA (thus cache coherency maintenance) requires the
         * transfer buffers to live in their own cache lines.
         */
-       __be16  rx_buf[TI_ADS7950_MAX_CHAN + TI_ADS7950_TIMESTAMP_SIZE]
+       u16 rx_buf[TI_ADS7950_MAX_CHAN + 2 + TI_ADS7950_TIMESTAMP_SIZE]
                                                        ____cacheline_aligned;
-       __be16  tx_buf[TI_ADS7950_MAX_CHAN];
-       __be16                  single_tx;
-       __be16                  single_rx;
+       u16 tx_buf[TI_ADS7950_MAX_CHAN + 2];
+       u16 single_tx;
+       u16 single_rx;
 
 };
 
@@ -108,7 +108,7 @@ enum ti_ads7950_id {
                .realbits = bits,                               \
                .storagebits = 16,                              \
                .shift = 12 - (bits),                           \
-               .endianness = IIO_BE,                           \
+               .endianness = IIO_CPU,                          \
        },                                                      \
 }
 
@@ -249,23 +249,14 @@ static int ti_ads7950_update_scan_mode(struct iio_dev *indio_dev,
        len = 0;
        for_each_set_bit(i, active_scan_mask, indio_dev->num_channels) {
                cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(i) | st->settings;
-               st->tx_buf[len++] = cpu_to_be16(cmd);
+               st->tx_buf[len++] = cmd;
        }
 
        /* Data for the 1st channel is not returned until the 3rd transfer */
-       len += 2;
-       for (i = 0; i < len; i++) {
-               if ((i + 2) < len)
-                       st->ring_xfer[i].tx_buf = &st->tx_buf[i];
-               if (i >= 2)
-                       st->ring_xfer[i].rx_buf = &st->rx_buf[i - 2];
-               st->ring_xfer[i].len = 2;
-               st->ring_xfer[i].cs_change = 1;
-       }
-       /* make sure last transfer's cs_change is not set */
-       st->ring_xfer[len - 1].cs_change = 0;
+       st->tx_buf[len++] = 0;
+       st->tx_buf[len++] = 0;
 
-       spi_message_init_with_transfers(&st->ring_msg, st->ring_xfer, len);
+       st->ring_xfer.len = len * 2;
 
        return 0;
 }
@@ -281,7 +272,7 @@ static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p)
        if (ret < 0)
                goto out;
 
-       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+       iio_push_to_buffers_with_timestamp(indio_dev, &st->rx_buf[2],
                                           iio_get_time_ns(indio_dev));
 
 out:
@@ -298,13 +289,13 @@ static int ti_ads7950_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
        mutex_lock(&indio_dev->mlock);
 
        cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(ch) | st->settings;
-       st->single_tx = cpu_to_be16(cmd);
+       st->single_tx = cmd;
 
        ret = spi_sync(st->spi, &st->scan_single_msg);
        if (ret)
                goto out;
 
-       ret = be16_to_cpu(st->single_rx);
+       ret = st->single_rx;
 
 out:
        mutex_unlock(&indio_dev->mlock);
@@ -378,6 +369,14 @@ static int ti_ads7950_probe(struct spi_device *spi)
        const struct ti_ads7950_chip_info *info;
        int ret;
 
+       spi->bits_per_word = 16;
+       spi->mode |= SPI_CS_WORD;
+       ret = spi_setup(spi);
+       if (ret < 0) {
+               dev_err(&spi->dev, "Error in spi setup\n");
+               return ret;
+       }
+
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (!indio_dev)
                return -ENOMEM;
@@ -398,6 +397,16 @@ static int ti_ads7950_probe(struct spi_device *spi)
        indio_dev->num_channels = info->num_channels;
        indio_dev->info = &ti_ads7950_info;
 
+       /* build spi ring message */
+       spi_message_init(&st->ring_msg);
+
+       st->ring_xfer.tx_buf = &st->tx_buf[0];
+       st->ring_xfer.rx_buf = &st->rx_buf[0];
+       /* len will be set later */
+       st->ring_xfer.cs_change = true;
+
+       spi_message_add_tail(&st->ring_xfer, &st->ring_msg);
+
        /*
         * Setup default message. The sample is read at the end of the first
         * transfer, then it takes one full cycle to convert the sample and one
index 0138337aedd10d52660a42fdcc333dfe9ac169dd..4b76b61ba4bee2e2c15e919e11349d020059ea81 100644 (file)
@@ -209,6 +209,6 @@ static struct spi_driver ad8366_driver = {
 
 module_spi_driver(ad8366_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD8366 VGA");
 MODULE_LICENSE("GPL v2");
index e049323f209ae83ba8a8fd35deec4e9934cc146e..0ae89b87e2d6451fbe177e0978b2179ab4c4487b 100644 (file)
@@ -4,10 +4,10 @@
 
 #define BME680_REG_CHIP_I2C_ID                 0xD0
 #define BME680_REG_CHIP_SPI_ID                 0x50
-#define BME680_CHIP_ID_VAL                     0x61
+#define   BME680_CHIP_ID_VAL                   0x61
 #define BME680_REG_SOFT_RESET_I2C              0xE0
 #define BME680_REG_SOFT_RESET_SPI              0x60
-#define BME680_CMD_SOFTRESET                   0xB6
+#define   BME680_CMD_SOFTRESET                 0xB6
 #define BME680_REG_STATUS                      0x73
 #define   BME680_SPI_MEM_PAGE_BIT              BIT(4)
 #define     BME680_SPI_MEM_PAGE_1_VAL          1
@@ -18,6 +18,7 @@
 #define BME680_REG_GAS_MSB                     0x2A
 #define BME680_REG_GAS_R_LSB                   0x2B
 #define   BME680_GAS_STAB_BIT                  BIT(4)
+#define   BME680_GAS_RANGE_MASK                        GENMASK(3, 0)
 
 #define BME680_REG_CTRL_HUMIDITY               0x72
 #define   BME680_OSRS_HUMIDITY_MASK            GENMASK(2, 0)
@@ -26,9 +27,8 @@
 #define   BME680_OSRS_TEMP_MASK                        GENMASK(7, 5)
 #define   BME680_OSRS_PRESS_MASK               GENMASK(4, 2)
 #define   BME680_MODE_MASK                     GENMASK(1, 0)
-
-#define BME680_MODE_FORCED                     1
-#define BME680_MODE_SLEEP                      0
+#define     BME680_MODE_FORCED                 1
+#define     BME680_MODE_SLEEP                  0
 
 #define BME680_REG_CONFIG                      0x75
 #define   BME680_FILTER_MASK                   GENMASK(4, 2)
 
 #define BME680_MAX_OVERFLOW_VAL                        0x40000000
 #define BME680_HUM_REG_SHIFT_VAL               4
-#define BME680_BIT_H1_DATA_MSK                 0x0F
+#define BME680_BIT_H1_DATA_MASK                        GENMASK(3, 0)
 
 #define BME680_REG_RES_HEAT_RANGE              0x02
-#define BME680_RHRANGE_MSK                     0x30
+#define   BME680_RHRANGE_MASK                  GENMASK(5, 4)
 #define BME680_REG_RES_HEAT_VAL                        0x00
 #define BME680_REG_RANGE_SW_ERR                        0x04
-#define BME680_RSERROR_MSK                     0xF0
+#define   BME680_RSERROR_MASK                  GENMASK(7, 4)
 #define BME680_REG_RES_HEAT_0                  0x5A
 #define BME680_REG_GAS_WAIT_0                  0x64
-#define BME680_GAS_RANGE_MASK                  0x0F
 #define BME680_ADC_GAS_RES_SHIFT               6
 #define BME680_AMB_TEMP                                25
 
 #define BME680_REG_CTRL_GAS_1                  0x71
 #define   BME680_RUN_GAS_MASK                  BIT(4)
 #define   BME680_NB_CONV_MASK                  GENMASK(3, 0)
-#define     BME680_RUN_GAS_EN_BIT              BIT(4)
-#define     BME680_NB_CONV_0_VAL               0
 
 #define BME680_REG_MEAS_STAT_0                 0x1D
 #define   BME680_GAS_MEAS_BIT                  BIT(6)
index 7d9bb62baa3fd3e8620f377143ecaca9dae69ae4..70c1fe4366f4c6a17100b469452f8903281e665e 100644 (file)
@@ -91,8 +91,6 @@ static const struct iio_chan_spec bme680_channels[] = {
        },
 };
 
-static const int bme680_oversampling_avail[] = { 1, 2, 4, 8, 16 };
-
 static int bme680_read_calib(struct bme680_data *data,
                             struct bme680_calib *calib)
 {
@@ -102,16 +100,14 @@ static int bme680_read_calib(struct bme680_data *data,
        __le16 buf;
 
        /* Temperature related coefficients */
-       ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_T1_LSB_REG\n");
                return ret;
        }
        calib->par_t1 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_T2_LSB_REG\n");
                return ret;
@@ -126,16 +122,14 @@ static int bme680_read_calib(struct bme680_data *data,
        calib->par_t3 = tmp;
 
        /* Pressure related coefficients */
-       ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P1_LSB_REG\n");
                return ret;
        }
        calib->par_p1 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P2_LSB_REG\n");
                return ret;
@@ -149,16 +143,14 @@ static int bme680_read_calib(struct bme680_data *data,
        }
        calib->par_p3 = tmp;
 
-       ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P4_LSB_REG\n");
                return ret;
        }
        calib->par_p4 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P5_LSB_REG\n");
                return ret;
@@ -179,16 +171,14 @@ static int bme680_read_calib(struct bme680_data *data,
        }
        calib->par_p7 = tmp;
 
-       ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P8_LSB_REG\n");
                return ret;
        }
        calib->par_p8 = le16_to_cpu(buf);
 
-       ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG, (u8 *) &buf, 2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_P9_LSB_REG\n");
                return ret;
@@ -208,30 +198,26 @@ static int bme680_read_calib(struct bme680_data *data,
                dev_err(dev, "failed to read BME680_H1_MSB_REG\n");
                return ret;
        }
-
        ret = regmap_read(data->regmap, BME680_H1_LSB_REG, &tmp_lsb);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_H1_LSB_REG\n");
                return ret;
        }
-
        calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
-                               (tmp_lsb & BME680_BIT_H1_DATA_MSK);
+                       (tmp_lsb & BME680_BIT_H1_DATA_MASK);
 
        ret = regmap_read(data->regmap, BME680_H2_MSB_REG, &tmp_msb);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_H2_MSB_REG\n");
                return ret;
        }
-
        ret = regmap_read(data->regmap, BME680_H2_LSB_REG, &tmp_lsb);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_H2_LSB_REG\n");
                return ret;
        }
-
        calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
-                               (tmp_lsb >> BME680_HUM_REG_SHIFT_VAL);
+                       (tmp_lsb >> BME680_HUM_REG_SHIFT_VAL);
 
        ret = regmap_read(data->regmap, BME680_H3_REG, &tmp);
        if (ret < 0) {
@@ -276,8 +262,8 @@ static int bme680_read_calib(struct bme680_data *data,
        }
        calib->par_gh1 = tmp;
 
-       ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG,
-                              (u8 *) &buf, 2);
+       ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG, (u8 *) &buf,
+                              2);
        if (ret < 0) {
                dev_err(dev, "failed to read BME680_GH2_LSB_REG\n");
                return ret;
@@ -297,7 +283,7 @@ static int bme680_read_calib(struct bme680_data *data,
                dev_err(dev, "failed to read resistance heat range\n");
                return ret;
        }
-       calib->res_heat_range = (tmp & BME680_RHRANGE_MSK) / 16;
+       calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK, tmp);
 
        ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_VAL, &tmp);
        if (ret < 0) {
@@ -311,7 +297,7 @@ static int bme680_read_calib(struct bme680_data *data,
                dev_err(dev, "failed to read range software error\n");
                return ret;
        }
-       calib->range_sw_err = (tmp & BME680_RSERROR_MSK) / 16;
+       calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK, tmp);
 
        return 0;
 }
@@ -408,10 +394,7 @@ static u32 bme680_compensate_humid(struct bme680_data *data,
        var6 = (var4 * var5) >> 1;
        calc_hum = (((var3 + var6) >> 10) * 1000) >> 12;
 
-       if (calc_hum > 100000) /* Cap at 100%rH */
-               calc_hum = 100000;
-       else if (calc_hum < 0)
-               calc_hum = 0;
+       calc_hum = clamp(calc_hum, 0, 100000); /* clamp between 0-100 %rH */
 
        return calc_hum;
 }
@@ -518,12 +501,20 @@ static int bme680_set_mode(struct bme680_data *data, bool mode)
        return ret;
 }
 
+static u8 bme680_oversampling_to_reg(u8 val)
+{
+       return ilog2(val) + 1;
+}
+
 static int bme680_chip_config(struct bme680_data *data)
 {
        struct device *dev = regmap_get_device(data->regmap);
        int ret;
-       u8 osrs = FIELD_PREP(BME680_OSRS_HUMIDITY_MASK,
-                            data->oversampling_humid + 1);
+       u8 osrs;
+
+       osrs = FIELD_PREP(
+               BME680_OSRS_HUMIDITY_MASK,
+               bme680_oversampling_to_reg(data->oversampling_humid));
        /*
         * Highly recommended to set oversampling of humidity before
         * temperature/pressure oversampling.
@@ -544,12 +535,12 @@ static int bme680_chip_config(struct bme680_data *data)
                return ret;
        }
 
-       osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK, data->oversampling_temp + 1) |
-              FIELD_PREP(BME680_OSRS_PRESS_MASK, data->oversampling_press + 1);
-
+       osrs = FIELD_PREP(BME680_OSRS_TEMP_MASK,
+                         bme680_oversampling_to_reg(data->oversampling_temp)) |
+              FIELD_PREP(BME680_OSRS_PRESS_MASK,
+                         bme680_oversampling_to_reg(data->oversampling_press));
        ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
-                               BME680_OSRS_TEMP_MASK |
-                               BME680_OSRS_PRESS_MASK,
+                               BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK,
                                osrs);
        if (ret < 0)
                dev_err(dev, "failed to write ctrl_meas register\n");
@@ -577,14 +568,15 @@ static int bme680_gas_config(struct bme680_data *data)
        /* set target heating duration */
        ret = regmap_write(data->regmap, BME680_REG_GAS_WAIT_0, heatr_dur);
        if (ret < 0) {
-               dev_err(dev, "failted to write gas_wait_0 register\n");
+               dev_err(dev, "failed to write gas_wait_0 register\n");
                return ret;
        }
 
-       /* Selecting the runGas and NB conversion settings for the sensor */
+       /* Enable the gas sensor and select heater profile set-point 0 */
        ret = regmap_update_bits(data->regmap, BME680_REG_CTRL_GAS_1,
                                 BME680_RUN_GAS_MASK | BME680_NB_CONV_MASK,
-                                BME680_RUN_GAS_EN_BIT | BME680_NB_CONV_0_VAL);
+                                FIELD_PREP(BME680_RUN_GAS_MASK, 1) |
+                                FIELD_PREP(BME680_NB_CONV_MASK, 0));
        if (ret < 0)
                dev_err(dev, "failed to write ctrl_gas_1 register\n");
 
@@ -782,13 +774,13 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
                switch (chan->type) {
                case IIO_TEMP:
-                       *val = 1 << data->oversampling_temp;
+                       *val = data->oversampling_temp;
                        return IIO_VAL_INT;
                case IIO_PRESSURE:
-                       *val = 1 << data->oversampling_press;
+                       *val = data->oversampling_press;
                        return IIO_VAL_INT;
                case IIO_HUMIDITYRELATIVE:
-                       *val = 1 << data->oversampling_humid;
+                       *val = data->oversampling_humid;
                        return IIO_VAL_INT;
                default:
                        return -EINVAL;
@@ -798,52 +790,9 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
        }
 }
 
-static int bme680_write_oversampling_ratio_temp(struct bme680_data *data,
-                                               int val)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
-               if (bme680_oversampling_avail[i] == val) {
-                       data->oversampling_temp = ilog2(val);
-
-                       return bme680_chip_config(data);
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int bme680_write_oversampling_ratio_press(struct bme680_data *data,
-                                                int val)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
-               if (bme680_oversampling_avail[i] == val) {
-                       data->oversampling_press = ilog2(val);
-
-                       return bme680_chip_config(data);
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int bme680_write_oversampling_ratio_humid(struct bme680_data *data,
-                                                int val)
+static bool bme680_is_valid_oversampling(int rate)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(bme680_oversampling_avail); i++) {
-               if (bme680_oversampling_avail[i] == val) {
-                       data->oversampling_humid = ilog2(val);
-
-                       return bme680_chip_config(data);
-               }
-       }
-
-       return -EINVAL;
+       return (rate > 0 && rate <= 16 && is_power_of_2(rate));
 }
 
 static int bme680_write_raw(struct iio_dev *indio_dev,
@@ -852,18 +801,31 @@ static int bme680_write_raw(struct iio_dev *indio_dev,
 {
        struct bme680_data *data = iio_priv(indio_dev);
 
+       if (val2 != 0)
+               return -EINVAL;
+
        switch (mask) {
        case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+       {
+               if (!bme680_is_valid_oversampling(val))
+                       return -EINVAL;
+
                switch (chan->type) {
                case IIO_TEMP:
-                       return bme680_write_oversampling_ratio_temp(data, val);
+                       data->oversampling_temp = val;
+                       break;
                case IIO_PRESSURE:
-                       return bme680_write_oversampling_ratio_press(data, val);
+                       data->oversampling_press = val;
+                       break;
                case IIO_HUMIDITYRELATIVE:
-                       return bme680_write_oversampling_ratio_humid(data, val);
+                       data->oversampling_humid = val;
+                       break;
                default:
                        return -EINVAL;
                }
+
+               return bme680_chip_config(data);
+       }
        default:
                return -EINVAL;
        }
@@ -925,9 +887,9 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
        indio_dev->modes = INDIO_DIRECT_MODE;
 
        /* default values for the sensor */
-       data->oversampling_humid = ilog2(2); /* 2X oversampling rate */
-       data->oversampling_press = ilog2(4); /* 4X oversampling rate */
-       data->oversampling_temp = ilog2(8);  /* 8X oversampling rate */
+       data->oversampling_humid = 2; /* 2X oversampling rate */
+       data->oversampling_press = 4; /* 4X oversampling rate */
+       data->oversampling_temp = 8;  /* 8X oversampling rate */
        data->heater_temp = 320; /* degree Celsius */
        data->heater_dur = 150;  /* milliseconds */
 
index 80beb64e9e0c66d843fd1acb6d721d6c7c163994..bb2057fd1b6f54e2fd69f679196e313d4cb2166d 100644 (file)
@@ -120,6 +120,16 @@ config AD5624R_SPI
          Say yes here to build support for Analog Devices AD5624R, AD5644R and
          AD5664R converters (DAC). This driver uses the common SPI interface.
 
+config LTC1660
+       tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver"
+       depends on SPI
+       help
+         Say yes here to build support for Linear Technology
+         LTC1660 and LTC1665 Digital to Analog Converters.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ltc1660.
+
 config LTC2632
        tristate "Linear Technology LTC2632-12/10/8 DAC spi driver"
        depends on SPI
index a1b37cf9944165fcaef0db42d85149aaab88a233..2ac93cc4a38937d849c9580ae5fef85cc7a36d53 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_CIO_DAC) += cio-dac.o
 obj-$(CONFIG_DPOT_DAC) += dpot-dac.o
 obj-$(CONFIG_DS4424) += ds4424.o
 obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o
+obj-$(CONFIG_LTC1660) += ltc1660.o
 obj-$(CONFIG_LTC2632) += ltc2632.o
 obj-$(CONFIG_M62332) += m62332.o
 obj-$(CONFIG_MAX517) += max517.o
index bf4fc40ec84d93bb5b39edd0f6c510605b8580cd..2f98cb2a3b9645ff08d522a5c7b260db3f986359 100644 (file)
@@ -808,6 +808,40 @@ static int ad5064_set_config(struct ad5064_state *st, unsigned int val)
        return ad5064_write(st, cmd, 0, val, 0);
 }
 
+static int ad5064_request_vref(struct ad5064_state *st, struct device *dev)
+{
+       unsigned int i;
+       int ret;
+
+       for (i = 0; i < ad5064_num_vref(st); ++i)
+               st->vref_reg[i].supply = ad5064_vref_name(st, i);
+
+       if (!st->chip_info->internal_vref)
+               return devm_regulator_bulk_get(dev, ad5064_num_vref(st),
+                                              st->vref_reg);
+
+       /*
+        * This assumes that when the regulator has an internal VREF
+        * there is only one external VREF connection, which is
+        * currently the case for all supported devices.
+        */
+       st->vref_reg[0].consumer = devm_regulator_get_optional(dev, "vref");
+       if (!IS_ERR(st->vref_reg[0].consumer))
+               return 0;
+
+       ret = PTR_ERR(st->vref_reg[0].consumer);
+       if (ret != -ENODEV)
+               return ret;
+
+       /* If no external regulator was supplied use the internal VREF */
+       st->use_internal_vref = true;
+       ret = ad5064_set_config(st, AD5064_CONFIG_INT_VREF_ENABLE);
+       if (ret)
+               dev_err(dev, "Failed to enable internal vref: %d\n", ret);
+
+       return ret;
+}
+
 static int ad5064_probe(struct device *dev, enum ad5064_type type,
                        const char *name, ad5064_write_func write)
 {
@@ -828,22 +862,11 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
        st->dev = dev;
        st->write = write;
 
-       for (i = 0; i < ad5064_num_vref(st); ++i)
-               st->vref_reg[i].supply = ad5064_vref_name(st, i);
+       ret = ad5064_request_vref(st, dev);
+       if (ret)
+               return ret;
 
-       ret = devm_regulator_bulk_get(dev, ad5064_num_vref(st),
-               st->vref_reg);
-       if (ret) {
-               if (!st->chip_info->internal_vref)
-                       return ret;
-               st->use_internal_vref = true;
-               ret = ad5064_set_config(st, AD5064_CONFIG_INT_VREF_ENABLE);
-               if (ret) {
-                       dev_err(dev, "Failed to enable internal vref: %d\n",
-                               ret);
-                       return ret;
-               }
-       } else {
+       if (!st->use_internal_vref) {
                ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
                if (ret)
                        return ret;
index fd26a4272fc5bc98284d1491e25cd86f16d8f80d..c3426708b6b559c543ac916ead8be58858bdc639 100644 (file)
@@ -628,6 +628,6 @@ static void __exit ad5446_exit(void)
 }
 module_exit(ad5446_exit);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
 MODULE_LICENSE("GPL v2");
index d9037ea59168ef1664b4e6841082b5b4b98b3e01..0ae23a268017ea4c511a6d6db9719ae50a42f56f 100644 (file)
@@ -369,6 +369,6 @@ static struct spi_driver ad5504_driver = {
 };
 module_spi_driver(ad5504_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
 MODULE_LICENSE("GPL v2");
index 2ddbfc3fdbae7430330466c9dc386ae8d3e26603..0e134b13967a5b85d68e023544178cbac434e6d8 100644 (file)
@@ -470,6 +470,6 @@ int ad5686_remove(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(ad5686_remove);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
 MODULE_LICENSE("GPL v2");
index bd36333257af8bf334bedbda9012bb4f8c9a6dfb..ef41f12bf2620c7e9e163d4c272e62dfa4d90b78 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/property.h>
 #include <linux/spi/spi.h>
+#include <linux/gpio/consumer.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -108,6 +109,7 @@ struct ad5758_range {
 struct ad5758_state {
        struct spi_device *spi;
        struct mutex lock;
+       struct gpio_desc *gpio_reset;
        struct ad5758_range out_range;
        unsigned int dc_dc_mode;
        unsigned int dc_dc_ilim;
@@ -474,6 +476,21 @@ static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable)
                                             AD5758_CAL_MEM_UNREFRESHED_MSK);
 }
 
+static int ad5758_reset(struct ad5758_state *st)
+{
+       if (st->gpio_reset) {
+               gpiod_set_value(st->gpio_reset, 0);
+               usleep_range(100, 1000);
+               gpiod_set_value(st->gpio_reset, 1);
+               usleep_range(100, 1000);
+
+               return 0;
+       } else {
+               /* Perform a software reset */
+               return ad5758_soft_reset(st);
+       }
+}
+
 static int ad5758_reg_access(struct iio_dev *indio_dev,
                             unsigned int reg,
                             unsigned int writeval,
@@ -768,13 +785,18 @@ static int ad5758_init(struct ad5758_state *st)
 {
        int regval, ret;
 
+       st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
+                                                GPIOD_OUT_HIGH);
+       if (IS_ERR(st->gpio_reset))
+               return PTR_ERR(st->gpio_reset);
+
        /* Disable CRC checks */
        ret = ad5758_crc_disable(st);
        if (ret < 0)
                return ret;
 
-       /* Perform a software reset */
-       ret = ad5758_soft_reset(st);
+       /* Perform a reset */
+       ret = ad5758_reset(st);
        if (ret < 0)
                return ret;
 
index 7569bf6868c277cf6141b3ad44674ad6bf472eb3..84ce5e6ecf3f8eb938fec8be09149aed3d12b21c 100644 (file)
@@ -467,6 +467,6 @@ static struct spi_driver ad5791_driver = {
 };
 module_spi_driver(ad5791_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
 MODULE_LICENSE("GPL v2");
index aaa2103d7c2b7229709609af7f71c1ad7fa8cc8e..a791d0a09d3b5c47b46c1589018d37b33ff655a1 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * IIO DAC emulation driver using a digital potentiometer
  *
  * Copyright (C) 2016 Axentia Technologies AB
  *
  * Author: Peter Rosin <peda@axentia.se>
- *
- * 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.
  */
 
 /*
diff --git a/drivers/iio/dac/ltc1660.c b/drivers/iio/dac/ltc1660.c
new file mode 100644 (file)
index 0000000..1086683
--- /dev/null
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Linear Technology LTC1665/LTC1660, 8 channels DAC
+ *
+ * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
+ */
+#include <linux/bitops.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#define LTC1660_REG_WAKE       0x0
+#define LTC1660_REG_DAC_A      0x1
+#define LTC1660_REG_DAC_B      0x2
+#define LTC1660_REG_DAC_C      0x3
+#define LTC1660_REG_DAC_D      0x4
+#define LTC1660_REG_DAC_E      0x5
+#define LTC1660_REG_DAC_F      0x6
+#define LTC1660_REG_DAC_G      0x7
+#define LTC1660_REG_DAC_H      0x8
+#define LTC1660_REG_SLEEP      0xe
+
+#define LTC1660_NUM_CHANNELS   8
+
+static const struct regmap_config ltc1660_regmap_config = {
+       .reg_bits = 4,
+       .val_bits = 12,
+};
+
+enum ltc1660_supported_device_ids {
+       ID_LTC1660,
+       ID_LTC1665,
+};
+
+struct ltc1660_priv {
+       struct spi_device *spi;
+       struct regmap *regmap;
+       struct regulator *vref_reg;
+       unsigned int value[LTC1660_NUM_CHANNELS];
+       unsigned int vref_mv;
+};
+
+static int ltc1660_read_raw(struct iio_dev *indio_dev,
+               struct iio_chan_spec const *chan,
+               int *val,
+               int *val2,
+               long mask)
+{
+       struct ltc1660_priv *priv = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               *val = priv->value[chan->channel];
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = regulator_get_voltage(priv->vref_reg);
+               if (*val < 0) {
+                       dev_err(&priv->spi->dev, "failed to read vref regulator: %d\n",
+                                       *val);
+                       return *val;
+               }
+
+               /* Convert to mV */
+               *val /= 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ltc1660_write_raw(struct iio_dev *indio_dev,
+               struct iio_chan_spec const *chan,
+               int val,
+               int val2,
+               long mask)
+{
+       struct ltc1660_priv *priv = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val2 != 0)
+                       return -EINVAL;
+
+               if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
+                       return -EINVAL;
+
+               ret = regmap_write(priv->regmap, chan->channel,
+                                       (val << chan->scan_type.shift));
+               if (!ret)
+                       priv->value[chan->channel] = val;
+
+               return ret;
+       default:
+               return -EINVAL;
+       }
+}
+
+#define LTC1660_CHAN(chan, bits) {                     \
+       .type = IIO_VOLTAGE,                            \
+       .indexed = 1,                                   \
+       .output = 1,                                    \
+       .channel = chan,                                \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
+       .scan_type = {                                  \
+               .sign = 'u',                            \
+               .realbits = (bits),                     \
+               .storagebits = 16,                      \
+               .shift = 12 - (bits),                   \
+       },                                              \
+}
+
+#define  LTC1660_OCTAL_CHANNELS(bits) {                        \
+               LTC1660_CHAN(LTC1660_REG_DAC_A, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_B, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_C, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_D, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_E, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_F, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_G, bits),  \
+               LTC1660_CHAN(LTC1660_REG_DAC_H, bits),  \
+}
+
+static const struct iio_chan_spec ltc1660_channels[][LTC1660_NUM_CHANNELS] = {
+       [ID_LTC1660] = LTC1660_OCTAL_CHANNELS(10),
+       [ID_LTC1665] = LTC1660_OCTAL_CHANNELS(8),
+};
+
+static const struct iio_info ltc1660_info = {
+       .read_raw = &ltc1660_read_raw,
+       .write_raw = &ltc1660_write_raw,
+};
+
+static int __maybe_unused ltc1660_suspend(struct device *dev)
+{
+       struct ltc1660_priv *priv = iio_priv(spi_get_drvdata(
+                                               to_spi_device(dev)));
+       return regmap_write(priv->regmap, LTC1660_REG_SLEEP, 0x00);
+}
+
+static int __maybe_unused ltc1660_resume(struct device *dev)
+{
+       struct ltc1660_priv *priv = iio_priv(spi_get_drvdata(
+                                               to_spi_device(dev)));
+       return regmap_write(priv->regmap, LTC1660_REG_WAKE, 0x00);
+}
+static SIMPLE_DEV_PM_OPS(ltc1660_pm_ops, ltc1660_suspend, ltc1660_resume);
+
+static int ltc1660_probe(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev;
+       struct ltc1660_priv *priv;
+       const struct spi_device_id *id = spi_get_device_id(spi);
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
+       if (indio_dev == NULL)
+               return -ENOMEM;
+
+       priv = iio_priv(indio_dev);
+       priv->regmap = devm_regmap_init_spi(spi, &ltc1660_regmap_config);
+       if (IS_ERR(priv->regmap)) {
+               dev_err(&spi->dev, "failed to register spi regmap %ld\n",
+                       PTR_ERR(priv->regmap));
+               return PTR_ERR(priv->regmap);
+       }
+
+       priv->vref_reg = devm_regulator_get(&spi->dev, "vref");
+       if (IS_ERR(priv->vref_reg)) {
+               dev_err(&spi->dev, "vref regulator not specified\n");
+               return PTR_ERR(priv->vref_reg);
+       }
+
+       ret = regulator_enable(priv->vref_reg);
+       if (ret) {
+               dev_err(&spi->dev, "failed to enable vref regulator: %d\n",
+                               ret);
+               return ret;
+       }
+
+       priv->spi = spi;
+       spi_set_drvdata(spi, indio_dev);
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->info = &ltc1660_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = ltc1660_channels[id->driver_data];
+       indio_dev->num_channels = LTC1660_NUM_CHANNELS;
+       indio_dev->name = id->name;
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&spi->dev, "failed to register iio device: %d\n",
+                               ret);
+               goto error_disable_reg;
+       }
+
+       return 0;
+
+error_disable_reg:
+       regulator_disable(priv->vref_reg);
+
+       return ret;
+}
+
+static int ltc1660_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ltc1660_priv *priv = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       regulator_disable(priv->vref_reg);
+
+       return 0;
+}
+
+static const struct of_device_id ltc1660_dt_ids[] = {
+       { .compatible = "lltc,ltc1660", .data = (void *)ID_LTC1660 },
+       { .compatible = "lltc,ltc1665", .data = (void *)ID_LTC1665 },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ltc1660_dt_ids);
+
+static const struct spi_device_id ltc1660_id[] = {
+       {"ltc1660", ID_LTC1660},
+       {"ltc1665", ID_LTC1665},
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(spi, ltc1660_id);
+
+static struct spi_driver ltc1660_driver = {
+       .driver = {
+               .name = "ltc1660",
+               .of_match_table = ltc1660_dt_ids,
+               .pm = &ltc1660_pm_ops,
+       },
+       .probe  = ltc1660_probe,
+       .remove = ltc1660_remove,
+       .id_table = ltc1660_id,
+};
+module_spi_driver(ltc1660_driver);
+
+MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
+MODULE_DESCRIPTION("Linear Technology LTC1660/LTC1665 DAC");
+MODULE_LICENSE("GPL v2");
index 1d853247a20598feda1913990a680bd06e5533c9..451d10e323cff1ff6d3a033e21b4129ad6ffe3c7 100644 (file)
@@ -113,15 +113,14 @@ static int max517_write_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int max517_suspend(struct device *dev)
+static int __maybe_unused max517_suspend(struct device *dev)
 {
        u8 outbuf = COMMAND_PD;
 
        return i2c_master_send(to_i2c_client(dev), &outbuf, 1);
 }
 
-static int max517_resume(struct device *dev)
+static int __maybe_unused max517_resume(struct device *dev)
 {
        u8 outbuf = 0;
 
@@ -129,10 +128,6 @@ static int max517_resume(struct device *dev)
 }
 
 static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume);
-#define MAX517_PM_OPS (&max517_pm_ops)
-#else
-#define MAX517_PM_OPS NULL
-#endif
 
 static const struct iio_info max517_info = {
        .read_raw = max517_read_raw,
@@ -229,7 +224,7 @@ MODULE_DEVICE_TABLE(i2c, max517_id);
 static struct i2c_driver max517_driver = {
        .driver = {
                .name   = MAX517_DRV_NAME,
-               .pm             = MAX517_PM_OPS,
+               .pm     = &max517_pm_ops,
        },
        .probe          = max517_probe,
        .remove         = max517_remove,
index d0ecc1fdd8fcd1d5d31108664f8157765e5db6c8..f0cf6903dcd2a92b2886661264418d74eec043b2 100644 (file)
@@ -270,8 +270,7 @@ static int max5821_write_raw(struct iio_dev *indio_dev,
        }
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int max5821_suspend(struct device *dev)
+static int __maybe_unused max5821_suspend(struct device *dev)
 {
        u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE,
                         MAX5821_EXTENDED_DAC_A |
@@ -281,7 +280,7 @@ static int max5821_suspend(struct device *dev)
        return i2c_master_send(to_i2c_client(dev), outbuf, 2);
 }
 
-static int max5821_resume(struct device *dev)
+static int __maybe_unused max5821_resume(struct device *dev)
 {
        u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE,
                         MAX5821_EXTENDED_DAC_A |
@@ -292,10 +291,6 @@ static int max5821_resume(struct device *dev)
 }
 
 static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume);
-#define MAX5821_PM_OPS (&max5821_pm_ops)
-#else
-#define MAX5821_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP */
 
 static const struct iio_info max5821_info = {
        .read_raw = max5821_read_raw,
@@ -392,7 +387,7 @@ static struct i2c_driver max5821_driver = {
        .driver = {
                .name   = "max5821",
                .of_match_table = max5821_of_match,
-               .pm     = MAX5821_PM_OPS,
+               .pm     = &max5821_pm_ops,
        },
        .probe          = max5821_probe,
        .remove         = max5821_remove,
index 8b5aad4c32d90effd27cb6a19f3373d5c9060879..6d71fd905e29d69b0a5b1afa99c5451037333153 100644 (file)
@@ -45,7 +45,7 @@ struct mcp4725_data {
        struct regulator *vref_reg;
 };
 
-static int mcp4725_suspend(struct device *dev)
+static int __maybe_unused mcp4725_suspend(struct device *dev)
 {
        struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
                to_i2c_client(dev)));
@@ -58,7 +58,7 @@ static int mcp4725_suspend(struct device *dev)
        return i2c_master_send(data->client, outbuf, 2);
 }
 
-static int mcp4725_resume(struct device *dev)
+static int __maybe_unused mcp4725_resume(struct device *dev)
 {
        struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
                to_i2c_client(dev)));
@@ -71,13 +71,7 @@ static int mcp4725_resume(struct device *dev)
 
        return i2c_master_send(data->client, outbuf, 2);
 }
-
-#ifdef CONFIG_PM_SLEEP
 static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
-#define MCP4725_PM_OPS (&mcp4725_pm_ops)
-#else
-#define MCP4725_PM_OPS NULL
-#endif
 
 static ssize_t mcp4725_store_eeprom(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t len)
@@ -547,7 +541,7 @@ static struct i2c_driver mcp4725_driver = {
        .driver = {
                .name   = MCP4725_DRV_NAME,
                .of_match_table = of_match_ptr(mcp4725_of_match),
-               .pm     = MCP4725_PM_OPS,
+               .pm     = &mcp4725_pm_ops,
        },
        .probe          = mcp4725_probe,
        .remove         = mcp4725_remove,
index bf9aa3fc0534e6786c5f5fe605cfd43b9a383690..b5190d1dae8e33a15e148ff78471fb09dd4b90d1 100644 (file)
@@ -94,17 +94,22 @@ static int mcp4922_write_raw(struct iio_dev *indio_dev,
                long mask)
 {
        struct mcp4922_state *state = iio_priv(indio_dev);
+       int ret;
 
        if (val2 != 0)
                return -EINVAL;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
-               if (val > GENMASK(chan->scan_type.realbits-1, 0))
+               if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
                        return -EINVAL;
                val <<= chan->scan_type.shift;
-               state->value[chan->channel] = val;
-               return mcp4922_spi_write(state, chan->channel, val);
+
+               ret = mcp4922_spi_write(state, chan->channel, val);
+               if (!ret)
+                       state->value[chan->channel] = val;
+               return ret;
+
        default:
                return -EINVAL;
        }
index e39d1e901353bc06ef0d06fb6c38f1844990d20d..f6dcd8bce2b018a8e97d41099daac48faf0e783a 100644 (file)
@@ -421,6 +421,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id);
 static struct i2c_driver dac5571_driver = {
        .driver = {
                   .name = "ti-dac5571",
+                  .of_match_table = of_match_ptr(dac5571_of_id),
        },
        .probe    = dac5571_probe,
        .remove   = dac5571_remove,
index f4a508107f0de9b70180d7d4bf3e7f59e46bb64a..f3f94fbdd20aba7aec96250b1c72b3b575399210 100644 (file)
@@ -1078,6 +1078,6 @@ static struct spi_driver ad9523_driver = {
 };
 module_spi_driver(ad9523_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD9523 CLOCKDIST/PLL");
 MODULE_LICENSE("GPL v2");
index 6d768431d90e926f33e3c524e7af014e2b7ce26d..f4748ff243f74a209fad810d5765ad7da271942f 100644 (file)
@@ -388,7 +388,7 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
        if (!pdata)
                return NULL;
 
-       strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1);
+       snprintf(&pdata->name[0], SPI_NAME_SIZE - 1, "%pOFn", np);
 
        tmp = 10000;
        of_property_read_u32(np, "adi,channel-spacing", &tmp);
index 15ccadc74891f73dca409acb0806cb4136646da9..3e29562ce374ffec9f213555f1360bed9b03d46a 100644 (file)
@@ -282,9 +282,11 @@ static int max30102_read_measurement(struct max30102_data *data,
        switch (measurements) {
        case 3:
                MAX30102_COPY_DATA(2);
-       case 2: /* fall-through */
+               /* fall through */
+       case 2:
                MAX30102_COPY_DATA(1);
-       case 1: /* fall-through */
+               /* fall through */
+       case 1:
                MAX30102_COPY_DATA(0);
                break;
        default:
index d80ef468508a19763ccbe0a70be5397158440c77..1e428c196a825c22f40318ca5d00cf776ff8359f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/iio/iio.h>
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include "inv_mpu_iio.h"
 
 /*
@@ -926,6 +927,39 @@ error_power_off:
        return result;
 }
 
+static int inv_mpu_core_enable_regulator(struct inv_mpu6050_state *st)
+{
+       int result;
+
+       result = regulator_enable(st->vddio_supply);
+       if (result) {
+               dev_err(regmap_get_device(st->map),
+                       "Failed to enable regulator: %d\n", result);
+       } else {
+               /* Give the device a little bit of time to start up. */
+               usleep_range(35000, 70000);
+       }
+
+       return result;
+}
+
+static int inv_mpu_core_disable_regulator(struct inv_mpu6050_state *st)
+{
+       int result;
+
+       result = regulator_disable(st->vddio_supply);
+       if (result)
+               dev_err(regmap_get_device(st->map),
+                       "Failed to disable regulator: %d\n", result);
+
+       return result;
+}
+
+static void inv_mpu_core_disable_regulator_action(void *_data)
+{
+       inv_mpu_core_disable_regulator(_data);
+}
+
 int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
                int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type)
 {
@@ -992,6 +1026,28 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
                return -EINVAL;
        }
 
+       st->vddio_supply = devm_regulator_get(dev, "vddio");
+       if (IS_ERR(st->vddio_supply)) {
+               if (PTR_ERR(st->vddio_supply) != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get vddio regulator %d\n",
+                               (int)PTR_ERR(st->vddio_supply));
+
+               return PTR_ERR(st->vddio_supply);
+       }
+
+       result = inv_mpu_core_enable_regulator(st);
+       if (result)
+               return result;
+
+       result = devm_add_action(dev, inv_mpu_core_disable_regulator_action,
+                                st);
+       if (result) {
+               inv_mpu_core_disable_regulator_action(st);
+               dev_err(dev, "Failed to setup regulator cleanup action %d\n",
+                       result);
+               return result;
+       }
+
        /* power is turned on inside check chip type*/
        result = inv_check_and_setup_chip(st);
        if (result)
@@ -1051,7 +1107,12 @@ static int inv_mpu_resume(struct device *dev)
        int result;
 
        mutex_lock(&st->lock);
+       result = inv_mpu_core_enable_regulator(st);
+       if (result)
+               goto out_unlock;
+
        result = inv_mpu6050_set_power_itg(st, true);
+out_unlock:
        mutex_unlock(&st->lock);
 
        return result;
@@ -1064,6 +1125,7 @@ static int inv_mpu_suspend(struct device *dev)
 
        mutex_lock(&st->lock);
        result = inv_mpu6050_set_power_itg(st, false);
+       inv_mpu_core_disable_regulator(st);
        mutex_unlock(&st->lock);
 
        return result;
index e69a59659dbcf9036c24abe96b8a4ef314a89143..6bcc11fc1b886c7d847525e5f3139bb0c38699b4 100644 (file)
@@ -129,6 +129,7 @@ struct inv_mpu6050_hw {
  *  @chip_period:      chip internal period estimation (~1kHz).
  *  @it_timestamp:     timestamp from previous interrupt.
  *  @data_timestamp:   timestamp for next data sample.
+ *  @vddio_supply      voltage regulator for the chip.
  */
 struct inv_mpu6050_state {
        struct mutex lock;
@@ -149,6 +150,7 @@ struct inv_mpu6050_state {
        s64 chip_period;
        s64 it_timestamp;
        s64 data_timestamp;
+       struct regulator *vddio_supply;
 };
 
 /*register and associated bit definition*/
index ccc817e17eb859cfab79419b1c48c06dc889882b..094fd006b63d36f24abb747418f3d71231117757 100644 (file)
@@ -9,7 +9,7 @@ config IIO_ST_LSM6DSX
        help
          Say yes here to build support for STMicroelectronics LSM6DSx imu
          sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
-         ism330dlc
+         ism330dlc, lsm6dso
 
          To compile this driver as a module, choose M here: the module
          will be called st_lsm6dsx.
index edcd838037cd80799e8253e3bfe953443036c49f..ef73519a0fb6fa4a309bd2d10da1822cd560baeb 100644 (file)
@@ -19,6 +19,7 @@
 #define ST_LSM6DSL_DEV_NAME    "lsm6dsl"
 #define ST_LSM6DSM_DEV_NAME    "lsm6dsm"
 #define ST_ISM330DLC_DEV_NAME  "ism330dlc"
+#define ST_LSM6DSO_DEV_NAME    "lsm6dso"
 
 enum st_lsm6dsx_hw_id {
        ST_LSM6DS3_ID,
@@ -26,14 +27,20 @@ enum st_lsm6dsx_hw_id {
        ST_LSM6DSL_ID,
        ST_LSM6DSM_ID,
        ST_ISM330DLC_ID,
+       ST_LSM6DSO_ID,
        ST_LSM6DSX_MAX_ID,
 };
 
-#define ST_LSM6DSX_BUFF_SIZE           400
+#define ST_LSM6DSX_BUFF_SIZE           512
 #define ST_LSM6DSX_CHAN_SIZE           2
 #define ST_LSM6DSX_SAMPLE_SIZE         6
+#define ST_LSM6DSX_TAG_SIZE            1
+#define ST_LSM6DSX_TAGGED_SAMPLE_SIZE  (ST_LSM6DSX_SAMPLE_SIZE + \
+                                        ST_LSM6DSX_TAG_SIZE)
 #define ST_LSM6DSX_MAX_WORD_LEN                ((32 / ST_LSM6DSX_SAMPLE_SIZE) * \
                                         ST_LSM6DSX_SAMPLE_SIZE)
+#define ST_LSM6DSX_MAX_TAGGED_WORD_LEN ((32 / ST_LSM6DSX_TAGGED_SAMPLE_SIZE) \
+                                        * ST_LSM6DSX_TAGGED_SAMPLE_SIZE)
 #define ST_LSM6DSX_SHIFT_VAL(val, mask)        (((val) << __ffs(mask)) & (mask))
 
 struct st_lsm6dsx_reg {
@@ -41,13 +48,17 @@ struct st_lsm6dsx_reg {
        u8 mask;
 };
 
+struct st_lsm6dsx_hw;
+
 /**
  * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings
+ * @read_fifo: Read FIFO callback.
  * @fifo_th: FIFO threshold register info (addr + mask).
  * @fifo_diff: FIFO diff status register info (addr + mask).
  * @th_wl: FIFO threshold word length.
  */
 struct st_lsm6dsx_fifo_ops {
+       int (*read_fifo)(struct st_lsm6dsx_hw *hw);
        struct {
                u8 addr;
                u16 mask;
@@ -79,6 +90,7 @@ struct st_lsm6dsx_hw_ts_settings {
  * @max_fifo_size: Sensor max fifo length in FIFO words.
  * @id: List of hw id supported by the driver configuration.
  * @decimator: List of decimator register info (addr + mask).
+ * @batch: List of FIFO batching register info (addr + mask).
  * @fifo_ops: Sensor hw FIFO parameters.
  * @ts_settings: Hw timer related settings.
  */
@@ -87,6 +99,7 @@ struct st_lsm6dsx_settings {
        u16 max_fifo_size;
        enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID];
        struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
+       struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
        struct st_lsm6dsx_fifo_ops fifo_ops;
        struct st_lsm6dsx_hw_ts_settings ts_settings;
 };
@@ -175,5 +188,8 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
 int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
 int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
                             enum st_lsm6dsx_fifo_mode fifo_mode);
+int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw);
+int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw);
+int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val);
 
 #endif /* ST_LSM6DSX_H */
index 631360b14ca71c398e67a9425dff363de1eb255a..b5263fc522ca662e431f34a8b11786bd5d598ef2 100644 (file)
  * buffer contains the data of all the enabled FIFO data sets
  * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the
  * value of the decimation factor and ODR set for each FIFO data set.
+ *
+ * LSM6DSO: The FIFO buffer can be configured to store data from gyroscope and
+ * accelerometer. Each sample is queued with a tag (1B) indicating data source
+ * (gyroscope, accelerometer, hw timer).
+ *
  * FIFO supported modes:
  *  - BYPASS: FIFO disabled
  *  - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index
@@ -46,6 +51,7 @@
 #define ST_LSM6DSX_FIFO_ODR_MASK               GENMASK(6, 3)
 #define ST_LSM6DSX_FIFO_EMPTY_MASK             BIT(12)
 #define ST_LSM6DSX_REG_FIFO_OUTL_ADDR          0x3e
+#define ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR       0x78
 #define ST_LSM6DSX_REG_TS_RESET_ADDR           0x42
 
 #define ST_LSM6DSX_MAX_FIFO_ODR_VAL            0x08
@@ -58,6 +64,12 @@ struct st_lsm6dsx_decimator_entry {
        u8 val;
 };
 
+enum st_lsm6dsx_fifo_tag {
+       ST_LSM6DSX_GYRO_TAG = 0x01,
+       ST_LSM6DSX_ACC_TAG = 0x02,
+       ST_LSM6DSX_TS_TAG = 0x04,
+};
+
 static const
 struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
        {  0, 0x0 },
@@ -177,12 +189,34 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor,
                                   bool enable)
 {
        struct st_lsm6dsx_hw *hw = sensor->hw;
+       const struct st_lsm6dsx_reg *batch_reg;
        u8 data;
 
-       data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0;
-       return regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
-                                ST_LSM6DSX_FIFO_ODR_MASK,
-                                FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK, data));
+       batch_reg = &hw->settings->batch[sensor->id];
+       if (batch_reg->addr) {
+               int val;
+
+               if (enable) {
+                       int err;
+
+                       err = st_lsm6dsx_check_odr(sensor, sensor->odr,
+                                                  &data);
+                       if (err < 0)
+                               return err;
+               } else {
+                       data = 0;
+               }
+               val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask);
+               return regmap_update_bits(hw->regmap, batch_reg->addr,
+                                         batch_reg->mask, val);
+       } else {
+               data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0;
+               return regmap_update_bits(hw->regmap,
+                                         ST_LSM6DSX_REG_FIFO_MODE_ADDR,
+                                         ST_LSM6DSX_FIFO_ODR_MASK,
+                                         FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK,
+                                                    data));
+       }
 }
 
 int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
@@ -250,21 +284,21 @@ static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw)
 }
 
 /*
- * Set max bulk read to ST_LSM6DSX_MAX_WORD_LEN in order to avoid
- * a kmalloc for each bus access
+ * Set max bulk read to ST_LSM6DSX_MAX_WORD_LEN/ST_LSM6DSX_MAX_TAGGED_WORD_LEN
+ * in order to avoid a kmalloc for each bus access
  */
-static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 *data,
-                                       unsigned int data_len)
+static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
+                                       u8 *data, unsigned int data_len,
+                                       unsigned int max_word_len)
 {
        unsigned int word_len, read_len = 0;
        int err;
 
        while (read_len < data_len) {
                word_len = min_t(unsigned int, data_len - read_len,
-                                ST_LSM6DSX_MAX_WORD_LEN);
-               err = regmap_bulk_read(hw->regmap,
-                                      ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
-                                      data + read_len, word_len);
+                                max_word_len);
+               err = regmap_bulk_read(hw->regmap, addr, data + read_len,
+                                      word_len);
                if (err < 0)
                        return err;
                read_len += word_len;
@@ -282,7 +316,7 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 *data,
  *
  * Return: Number of bytes read from the FIFO
  */
-static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
+int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
 {
        u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
        u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
@@ -314,7 +348,9 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
        gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
 
        for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
-               err = st_lsm6dsx_read_block(hw, hw->buff, pattern_len);
+               err = st_lsm6dsx_read_block(hw, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
+                                           hw->buff, pattern_len,
+                                           ST_LSM6DSX_MAX_WORD_LEN);
                if (err < 0) {
                        dev_err(hw->dev,
                                "failed to read pattern from fifo (err=%d)\n",
@@ -400,13 +436,111 @@ static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
        return read_len;
 }
 
+/**
+ * st_lsm6dsx_read_tagged_fifo() - LSM6DSO read FIFO routine
+ * @hw: Pointer to instance of struct st_lsm6dsx_hw.
+ *
+ * Read samples from the hw FIFO and push them to IIO buffers.
+ *
+ * Return: Number of bytes read from the FIFO
+ */
+int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
+{
+       u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
+       u16 fifo_len, fifo_diff_mask;
+       struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
+       u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag;
+       bool reset_ts = false;
+       int i, err, read_len;
+       __le16 fifo_status;
+       s64 ts = 0;
+
+       err = regmap_bulk_read(hw->regmap,
+                              hw->settings->fifo_ops.fifo_diff.addr,
+                              &fifo_status, sizeof(fifo_status));
+       if (err < 0) {
+               dev_err(hw->dev, "failed to read fifo status (err=%d)\n",
+                       err);
+               return err;
+       }
+
+       fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
+       fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) *
+                  ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
+       if (!fifo_len)
+               return 0;
+
+       acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
+       gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
+
+       for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
+               err = st_lsm6dsx_read_block(hw,
+                                           ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
+                                           hw->buff, pattern_len,
+                                           ST_LSM6DSX_MAX_TAGGED_WORD_LEN);
+               if (err < 0) {
+                       dev_err(hw->dev,
+                               "failed to read pattern from fifo (err=%d)\n",
+                               err);
+                       return err;
+               }
+
+               for (i = 0; i < pattern_len;
+                    i += ST_LSM6DSX_TAGGED_SAMPLE_SIZE) {
+                       memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE],
+                              ST_LSM6DSX_SAMPLE_SIZE);
+
+                       tag = hw->buff[i] >> 3;
+                       switch (tag) {
+                       case ST_LSM6DSX_TS_TAG:
+                               /*
+                                * hw timestamp is 4B long and it is stored
+                                * in FIFO according to this schema:
+                                * B0 = ts[7:0], B1 = ts[15:8], B2 = ts[23:16],
+                                * B3 = ts[31:24]
+                                */
+                               ts = le32_to_cpu(*((__le32 *)iio_buff));
+                               /*
+                                * check if hw timestamp engine is going to
+                                * reset (the sensor generates an interrupt
+                                * to signal the hw timestamp will reset in
+                                * 1.638s)
+                                */
+                               if (!reset_ts && ts >= 0xffff0000)
+                                       reset_ts = true;
+                               ts *= ST_LSM6DSX_TS_SENSITIVITY;
+                               break;
+                       case ST_LSM6DSX_GYRO_TAG:
+                               iio_push_to_buffers_with_timestamp(
+                                       hw->iio_devs[ST_LSM6DSX_ID_GYRO],
+                                       iio_buff, gyro_sensor->ts_ref + ts);
+                               break;
+                       case ST_LSM6DSX_ACC_TAG:
+                               iio_push_to_buffers_with_timestamp(
+                                       hw->iio_devs[ST_LSM6DSX_ID_ACC],
+                                       iio_buff, acc_sensor->ts_ref + ts);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+
+       if (unlikely(reset_ts)) {
+               err = st_lsm6dsx_reset_hw_ts(hw);
+               if (err < 0)
+                       return err;
+       }
+       return read_len;
+}
+
 int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
 {
        int err;
 
        mutex_lock(&hw->fifo_lock);
 
-       st_lsm6dsx_read_fifo(hw);
+       hw->settings->fifo_ops.read_fifo(hw);
        err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS);
 
        mutex_unlock(&hw->fifo_lock);
@@ -478,7 +612,7 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
        int count;
 
        mutex_lock(&hw->fifo_lock);
-       count = st_lsm6dsx_read_fifo(hw);
+       count = hw->settings->fifo_ops.read_fifo(hw);
        mutex_unlock(&hw->fifo_lock);
 
        return !count ? IRQ_NONE : IRQ_HANDLED;
index aebbe0ddd8d8c3ddf2900cf9487d1736ec123ae2..2ad3c610e4b63777cfc7e83f278d88ca231e0e2f 100644 (file)
  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
  *   - FIFO size: 4KB
  *
+ * - LSM6DSO
+ *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
+ *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
+ *   - FIFO size: 3KB
+ *
  * Copyright 2016 STMicroelectronics Inc.
  *
  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
@@ -171,6 +177,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                        },
                },
                .fifo_ops = {
+                       .read_fifo = st_lsm6dsx_read_fifo,
                        .fifo_th = {
                                .addr = 0x06,
                                .mask = GENMASK(11, 0),
@@ -217,6 +224,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                        },
                },
                .fifo_ops = {
+                       .read_fifo = st_lsm6dsx_read_fifo,
                        .fifo_th = {
                                .addr = 0x06,
                                .mask = GENMASK(11, 0),
@@ -265,6 +273,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                        },
                },
                .fifo_ops = {
+                       .read_fifo = st_lsm6dsx_read_fifo,
                        .fifo_th = {
                                .addr = 0x06,
                                .mask = GENMASK(10, 0),
@@ -294,6 +303,45 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
                        },
                },
        },
+       {
+               .wai = 0x6c,
+               .max_fifo_size = 512,
+               .id = {
+                       [0] = ST_LSM6DSO_ID,
+               },
+               .batch = {
+                       [ST_LSM6DSX_ID_ACC] = {
+                               .addr = 0x09,
+                               .mask = GENMASK(3, 0),
+                       },
+                       [ST_LSM6DSX_ID_GYRO] = {
+                               .addr = 0x09,
+                               .mask = GENMASK(7, 4),
+                       },
+               },
+               .fifo_ops = {
+                       .read_fifo = st_lsm6dsx_read_tagged_fifo,
+                       .fifo_th = {
+                               .addr = 0x07,
+                               .mask = GENMASK(8, 0),
+                       },
+                       .fifo_diff = {
+                               .addr = 0x3a,
+                               .mask = GENMASK(8, 0),
+                       },
+                       .th_wl = 1,
+               },
+               .ts_settings = {
+                       .timer_en = {
+                               .addr = 0x19,
+                               .mask = BIT(5),
+                       },
+                       .decimator = {
+                               .addr = 0x0a,
+                               .mask = GENMASK(7, 6),
+                       },
+               },
+       },
 };
 
 #define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx)             \
@@ -395,8 +443,7 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
        return 0;
 }
 
-static int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr,
-                               u8 *val)
+int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
 {
        int i;
 
index 377c4e9997daf891d3e6d74cbd9f3296f0a5d71d..448b7bc1e57818c744b4f791fa0137a04184bed7 100644 (file)
@@ -61,6 +61,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
                .compatible = "st,ism330dlc",
                .data = (void *)ST_ISM330DLC_ID,
        },
+       {
+               .compatible = "st,lsm6dso",
+               .data = (void *)ST_LSM6DSO_ID,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
@@ -71,6 +75,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
        { ST_LSM6DSL_DEV_NAME, ST_LSM6DSL_ID },
        { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
        { ST_ISM330DLC_DEV_NAME, ST_ISM330DLC_ID },
+       { ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID },
        {},
 };
 MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
index fec5c6ce7eb7a247fba044fb297ba7a29210f0ec..b1df8a6973e6f4d019abae7b669347220e97d4e1 100644 (file)
@@ -61,6 +61,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
                .compatible = "st,ism330dlc",
                .data = (void *)ST_ISM330DLC_ID,
        },
+       {
+               .compatible = "st,lsm6dso",
+               .data = (void *)ST_LSM6DSO_ID,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
@@ -71,6 +75,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
        { ST_LSM6DSL_DEV_NAME, ST_LSM6DSL_ID },
        { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
        { ST_ISM330DLC_DEV_NAME, ST_ISM330DLC_ID },
+       { ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID },
        {},
 };
 MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
index a814828e69f5c3c47de3c3a95a8131d042dbbec5..28347df78cff6830f2a027f89545559e53f811ff 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ROHM BH1710/BH1715/BH1721/BH1750/BH1751 ambient light sensor driver
  *
  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Data sheets:
  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1710fvc-e.pdf
  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1715fvc-e.pdf
@@ -281,8 +278,7 @@ static int bh1750_remove(struct i2c_client *client)
        return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int bh1750_suspend(struct device *dev)
+static int __maybe_unused bh1750_suspend(struct device *dev)
 {
        int ret;
        struct bh1750_data *data =
@@ -300,10 +296,6 @@ static int bh1750_suspend(struct device *dev)
 }
 
 static SIMPLE_DEV_PM_OPS(bh1750_pm_ops, bh1750_suspend, NULL);
-#define BH1750_PM_OPS (&bh1750_pm_ops)
-#else
-#define BH1750_PM_OPS NULL
-#endif
 
 static const struct i2c_device_id bh1750_id[] = {
        { "bh1710", BH1710 },
@@ -315,10 +307,21 @@ static const struct i2c_device_id bh1750_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, bh1750_id);
 
+static const struct of_device_id bh1750_of_match[] = {
+       { .compatible = "rohm,bh1710", },
+       { .compatible = "rohm,bh1715", },
+       { .compatible = "rohm,bh1721", },
+       { .compatible = "rohm,bh1750", },
+       { .compatible = "rohm,bh1751", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, bh1750_of_match);
+
 static struct i2c_driver bh1750_driver = {
        .driver = {
                .name = "bh1750",
-               .pm = BH1750_PM_OPS,
+               .of_match_table = bh1750_of_match,
+               .pm = &bh1750_pm_ops,
        },
        .probe = bh1750_probe,
        .remove = bh1750_remove,
index 4067dff2ff6aca49ab5cfea1f869702f431f6396..d3fb460cfbdce575f3bb0f2be5d1057130567637 100644 (file)
@@ -99,7 +99,6 @@ static const int max44000_alspga_shift[] = {0, 2, 4, 7};
  * Handling this internally is also required for buffer support because the
  * channel's scan_type can't be modified dynamically.
  */
-static const int max44000_alstim_shift[] = {0, 2, 4, 6};
 #define MAX44000_ALSTIM_SHIFT(alstim) (2 * (alstim))
 
 /* Available integration times with pretty manual alignment: */
index df5b2a0da96c4a9c311ddd6da57f990f6d1f821f..83cece921843c64594f67d60e41d79cea9b4ac89 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/platform_data/tsl2772.h>
+#include <linux/regulator/consumer.h>
 
 /* Cal defs */
 #define PROX_STAT_CAL                  0
 #define TSL2772_ALS_GAIN_TRIM_MIN      250
 #define TSL2772_ALS_GAIN_TRIM_MAX      4000
 
+#define TSL2772_MAX_PROX_LEDS          2
+
+#define TSL2772_BOOT_MIN_SLEEP_TIME    10000
+#define TSL2772_BOOT_MAX_SLEEP_TIME    28000
+
 /* Device family members */
 enum {
        tsl2571,
@@ -118,7 +124,8 @@ enum {
        tsl2672,
        tmd2672,
        tsl2772,
-       tmd2772
+       tmd2772,
+       apds9930,
 };
 
 enum {
@@ -141,11 +148,21 @@ struct tsl2772_chip_info {
        const struct iio_info *info;
 };
 
+static const int tsl2772_led_currents[][2] = {
+       { 100000, TSL2772_100_mA },
+       {  50000, TSL2772_50_mA },
+       {  25000, TSL2772_25_mA },
+       {  13000, TSL2772_13_mA },
+       {      0, 0 }
+};
+
 struct tsl2772_chip {
        kernel_ulong_t id;
        struct mutex prox_mutex;
        struct mutex als_mutex;
        struct i2c_client *client;
+       struct regulator *vdd_supply;
+       struct regulator *vddio_supply;
        u16 prox_data;
        struct tsl2772_als_info als_cur_info;
        struct tsl2772_settings settings;
@@ -197,6 +214,12 @@ static const struct tsl2772_lux tmd2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
        {     0,      0 },
 };
 
+static const struct tsl2772_lux apds9930_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
+       { 52000,  96824 },
+       { 38792,  67132 },
+       {     0,      0 },
+};
+
 static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = {
        [tsl2571] = tsl2x71_lux_table,
        [tsl2671] = tsl2x71_lux_table,
@@ -208,6 +231,7 @@ static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = {
        [tmd2672] = tmd2x72_lux_table,
        [tsl2772] = tsl2x72_lux_table,
        [tmd2772] = tmd2x72_lux_table,
+       [apds9930] = apds9930_lux_table,
 };
 
 static const struct tsl2772_settings tsl2772_default_settings = {
@@ -258,6 +282,7 @@ static const int tsl2772_int_time_avail[][6] = {
        [tmd2672] = { 0, 2730, 0, 2730, 0, 699000 },
        [tsl2772] = { 0, 2730, 0, 2730, 0, 699000 },
        [tmd2772] = { 0, 2730, 0, 2730, 0, 699000 },
+       [apds9930] = { 0, 2730, 0, 2730, 0, 699000 },
 };
 
 static int tsl2772_int_calibscale_avail[] = { 1, 8, 16, 120 };
@@ -283,7 +308,8 @@ static const u8 device_channel_config[] = {
        [tsl2672] = PRX2,
        [tmd2672] = PRX2,
        [tsl2772] = ALSPRX2,
-       [tmd2772] = ALSPRX2
+       [tmd2772] = ALSPRX2,
+       [apds9930] = ALSPRX2,
 };
 
 static int tsl2772_read_status(struct tsl2772_chip *chip)
@@ -497,6 +523,7 @@ static int tsl2772_get_prox(struct iio_dev *indio_dev)
        case tmd2672:
        case tsl2772:
        case tmd2772:
+       case apds9930:
                if (!(ret & TSL2772_STA_PRX_VALID)) {
                        ret = -EINVAL;
                        goto prox_poll_err;
@@ -515,6 +542,75 @@ prox_poll_err:
        return ret;
 }
 
+static int tsl2772_read_prox_led_current(struct tsl2772_chip *chip)
+{
+       struct device_node *of_node = chip->client->dev.of_node;
+       int ret, tmp, i;
+
+       ret = of_property_read_u32(of_node, "led-max-microamp", &tmp);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; tsl2772_led_currents[i][0] != 0; i++) {
+               if (tmp == tsl2772_led_currents[i][0]) {
+                       chip->settings.prox_power = tsl2772_led_currents[i][1];
+                       return 0;
+               }
+       }
+
+       dev_err(&chip->client->dev, "Invalid value %d for led-max-microamp\n",
+               tmp);
+
+       return -EINVAL;
+
+}
+
+static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip)
+{
+       struct device_node *of_node = chip->client->dev.of_node;
+       int i, ret, num_leds, prox_diode_mask;
+       u32 leds[TSL2772_MAX_PROX_LEDS];
+
+       ret = of_property_count_u32_elems(of_node, "amstaos,proximity-diodes");
+       if (ret < 0)
+               return ret;
+
+       num_leds = ret;
+       if (num_leds > TSL2772_MAX_PROX_LEDS)
+               num_leds = TSL2772_MAX_PROX_LEDS;
+
+       ret = of_property_read_u32_array(of_node, "amstaos,proximity-diodes",
+                                        leds, num_leds);
+       if (ret < 0) {
+               dev_err(&chip->client->dev,
+                       "Invalid value for amstaos,proximity-diodes: %d.\n",
+                       ret);
+               return ret;
+       }
+
+       prox_diode_mask = 0;
+       for (i = 0; i < num_leds; i++) {
+               if (leds[i] == 0)
+                       prox_diode_mask |= TSL2772_DIODE0;
+               else if (leds[i] == 1)
+                       prox_diode_mask |= TSL2772_DIODE1;
+               else {
+                       dev_err(&chip->client->dev,
+                               "Invalid value %d in amstaos,proximity-diodes.\n",
+                               leds[i]);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static void tsl2772_parse_dt(struct tsl2772_chip *chip)
+{
+       tsl2772_read_prox_led_current(chip);
+       tsl2772_read_prox_diodes(chip);
+}
+
 /**
  * tsl2772_defaults() - Populates the device nominal operating parameters
  *                      with those provided by a 'platform' data struct or
@@ -541,6 +637,8 @@ static void tsl2772_defaults(struct tsl2772_chip *chip)
                memcpy(chip->tsl2772_device_lux,
                       tsl2772_default_lux_table_group[chip->id],
                       TSL2772_DEFAULT_TABLE_BYTES);
+
+       tsl2772_parse_dt(chip);
 }
 
 /**
@@ -595,6 +693,52 @@ static int tsl2772_als_calibrate(struct iio_dev *indio_dev)
        return ret;
 }
 
+static void tsl2772_disable_regulators_action(void *_data)
+{
+       struct tsl2772_chip *chip = _data;
+
+       regulator_disable(chip->vdd_supply);
+       regulator_disable(chip->vddio_supply);
+}
+
+static int tsl2772_enable_regulator(struct tsl2772_chip *chip,
+                                   struct regulator *regulator)
+{
+       int ret;
+
+       ret = regulator_enable(regulator);
+       if (ret < 0) {
+               dev_err(&chip->client->dev, "Failed to enable regulator: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct regulator *tsl2772_get_regulator(struct tsl2772_chip *chip,
+                                              char *name)
+{
+       struct regulator *regulator;
+       int ret;
+
+       regulator = devm_regulator_get(&chip->client->dev, name);
+       if (IS_ERR(regulator)) {
+               if (PTR_ERR(regulator) != -EPROBE_DEFER)
+                       dev_err(&chip->client->dev,
+                               "Failed to get %s regulator %d\n",
+                               name, (int)PTR_ERR(regulator));
+
+               return regulator;
+       }
+
+       ret = tsl2772_enable_regulator(chip, regulator);
+       if (ret < 0)
+               return ERR_PTR(ret);
+
+       return regulator;
+}
+
 static int tsl2772_chip_on(struct iio_dev *indio_dev)
 {
        struct tsl2772_chip *chip = iio_priv(indio_dev);
@@ -1260,6 +1404,7 @@ static int tsl2772_device_id_verif(int id, int target)
        case tmd2672:
        case tsl2772:
        case tmd2772:
+       case apds9930:
                return (id & 0xf0) == SWORDFISH_ID;
        }
 
@@ -1652,6 +1797,27 @@ static int tsl2772_probe(struct i2c_client *clientp,
        chip->client = clientp;
        i2c_set_clientdata(clientp, indio_dev);
 
+       chip->vddio_supply = tsl2772_get_regulator(chip, "vddio");
+       if (IS_ERR(chip->vddio_supply))
+               return PTR_ERR(chip->vddio_supply);
+
+       chip->vdd_supply = tsl2772_get_regulator(chip, "vdd");
+       if (IS_ERR(chip->vdd_supply)) {
+               regulator_disable(chip->vddio_supply);
+               return PTR_ERR(chip->vdd_supply);
+       }
+
+       ret = devm_add_action(&clientp->dev, tsl2772_disable_regulators_action,
+                             chip);
+       if (ret < 0) {
+               tsl2772_disable_regulators_action(chip);
+               dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n",
+                       ret);
+               return ret;
+       }
+
+       usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
+
        ret = i2c_smbus_read_byte_data(chip->client,
                                       TSL2772_CMD_REG | TSL2772_CHIPID);
        if (ret < 0)
@@ -1725,13 +1891,33 @@ static int tsl2772_probe(struct i2c_client *clientp,
 static int tsl2772_suspend(struct device *dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct tsl2772_chip *chip = iio_priv(indio_dev);
+       int ret;
+
+       ret = tsl2772_chip_off(indio_dev);
+       regulator_disable(chip->vdd_supply);
+       regulator_disable(chip->vddio_supply);
 
-       return tsl2772_chip_off(indio_dev);
+       return ret;
 }
 
 static int tsl2772_resume(struct device *dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct tsl2772_chip *chip = iio_priv(indio_dev);
+       int ret;
+
+       ret = tsl2772_enable_regulator(chip, chip->vddio_supply);
+       if (ret < 0)
+               return ret;
+
+       ret = tsl2772_enable_regulator(chip, chip->vdd_supply);
+       if (ret < 0) {
+               regulator_disable(chip->vddio_supply);
+               return ret;
+       }
+
+       usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
 
        return tsl2772_chip_on(indio_dev);
 }
@@ -1758,6 +1944,7 @@ static const struct i2c_device_id tsl2772_idtable[] = {
        { "tmd2672", tmd2672 },
        { "tsl2772", tsl2772 },
        { "tmd2772", tmd2772 },
+       { "apds9930", apds9930},
        {}
 };
 
@@ -1774,6 +1961,7 @@ static const struct of_device_id tsl2772_of_match[] = {
        { .compatible = "amstaos,tmd2672" },
        { .compatible = "amstaos,tsl2772" },
        { .compatible = "amstaos,tmd2772" },
+       { .compatible = "avago,apds9930" },
        {}
 };
 MODULE_DEVICE_TABLE(of, tsl2772_of_match);
index 76a5d7484d8d2ceb313c7f9ffec1c05921591f68..a75224cf99df24b50c8f823332b35f171fb0d280 100644 (file)
@@ -31,7 +31,7 @@ enum hmc5843_ids {
 };
 
 /**
- * struct hcm5843_data - device specific data
+ * struct hmc5843_data - device specific data
  * @dev:               actual device
  * @lock:              update and read regmap data
  * @regmap:            hardware access register maps
index e1f44cecdef4c50b984878229f7afb3389c9a7ca..0422ef57914cd0617a1bee41196da466deaff87b 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * IIO multiplexer driver
  *
  * Copyright (C) 2017 Axentia Technologies AB
  *
  * Author: Peter Rosin <peda@axentia.se>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/err.h>
index ffe2761333a2da1f71437fe255691f8fda12eb94..6d2f13fa56623cffbcc495ca7b5802b3b1ec40f6 100644 (file)
@@ -137,7 +137,6 @@ static int max5481_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        struct max5481_data *data;
        const struct spi_device_id *id = spi_get_device_id(spi);
-       const struct of_device_id *match;
        int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
@@ -149,10 +148,8 @@ static int max5481_probe(struct spi_device *spi)
 
        data->spi = spi;
 
-       match = of_match_device(of_match_ptr(max5481_match), &spi->dev);
-       if (match)
-               data->cfg = of_device_get_match_data(&spi->dev);
-       else
+       data->cfg = of_device_get_match_data(&spi->dev);
+       if (!data->cfg)
                data->cfg = &max5481_cfg[id->driver_data];
 
        indio_dev->name = id->name;
index 320a7c9297772992371d065faaddd41de9de1bbe..62151b2a2b12db798155344995b7e9657fc25c9f 100644 (file)
@@ -147,7 +147,6 @@ static int mcp4018_probe(struct i2c_client *client)
        struct device *dev = &client->dev;
        struct mcp4018_data *data;
        struct iio_dev *indio_dev;
-       const struct of_device_id *match;
 
        if (!i2c_check_functionality(client->adapter,
                                     I2C_FUNC_SMBUS_BYTE)) {
@@ -162,10 +161,8 @@ static int mcp4018_probe(struct i2c_client *client)
        i2c_set_clientdata(client, indio_dev);
        data->client = client;
 
-       match = of_match_device(of_match_ptr(mcp4018_of_match), dev);
-       if (match)
-               data->cfg = of_device_get_match_data(dev);
-       else
+       data->cfg = of_device_get_match_data(dev);
+       if (!data->cfg)
                data->cfg = &mcp4018_cfg[i2c_match_id(mcp4018_id, client)->driver_data];
 
        indio_dev->dev.parent = dev;
@@ -190,4 +187,4 @@ module_i2c_driver(mcp4018_driver);
 
 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
 MODULE_DESCRIPTION("MCP4018 digital potentiometer");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index df894af6cccbd59b479390ae2a7b65c51f69eddf..d71a22d71a308110d4ad178a0571ed0bf1b93331 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Industrial I/O driver for Microchip digital potentiometers
  * Copyright (c) 2015  Axentia Technologies AB
  * mcp4652     2       257             5, 10, 50, 100          01011xx
  * mcp4661     2       257             5, 10, 50, 100          0101xxx
  * mcp4662     2       257             5, 10, 50, 100          01011xx
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
  */
 
 #include <linux/module.h>
@@ -360,7 +357,6 @@ static int mcp4531_probe(struct i2c_client *client)
        struct device *dev = &client->dev;
        struct mcp4531_data *data;
        struct iio_dev *indio_dev;
-       const struct of_device_id *match;
 
        if (!i2c_check_functionality(client->adapter,
                                     I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -375,10 +371,8 @@ static int mcp4531_probe(struct i2c_client *client)
        i2c_set_clientdata(client, indio_dev);
        data->client = client;
 
-       match = of_match_device(of_match_ptr(mcp4531_of_match), dev);
-       if (match)
-               data->cfg = of_device_get_match_data(dev);
-       else
+       data->cfg = of_device_get_match_data(dev);
+       if (!data->cfg)
                data->cfg = &mcp4531_cfg[i2c_match_id(mcp4531_id, client)->driver_data];
 
        indio_dev->dev.parent = dev;
@@ -403,4 +397,4 @@ module_i2c_driver(mcp4531_driver);
 
 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
 MODULE_DESCRIPTION("MCP4531 digital potentiometer");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index ead9e9f8589487a60fac2dc90a602f9e8a0a410f..bc06271fa38bc95f8b1f14e2fdb27041e24c6560 100644 (file)
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * MS5611 pressure and temperature sensor driver
  *
  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #ifndef _MS5611_H
index f950cfde5db99ce4e8a7e16367c8fbeadb7b481c..2f598ad91621fd70c715d140da665dad977365d9 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * MS5611 pressure and temperature sensor driver
  *
  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Data sheet:
  *  http://www.meas-spec.com/downloads/MS5611-01BA03.pdf
  *  http://www.meas-spec.com/downloads/MS5607-02BA03.pdf
index 55fb5fc0b6eac1d9adbf54e2e45382048cb135f5..8089c59adce5b09b1b05a6242b694c8069961a89 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * MS5611 pressure and temperature sensor driver (I2C bus)
  *
  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * 7-bit I2C slave addresses:
  *
  * 0x77 (CSB pin low)
@@ -117,9 +114,7 @@ static int ms5611_i2c_remove(struct i2c_client *client)
 #if defined(CONFIG_OF)
 static const struct of_device_id ms5611_i2c_matches[] = {
        { .compatible = "meas,ms5611" },
-       { .compatible = "ms5611" },
        { .compatible = "meas,ms5607" },
-       { .compatible = "ms5607" },
        { }
 };
 MODULE_DEVICE_TABLE(of, ms5611_i2c_matches);
index 932e05001e1a91fa1a7a211f75491005f197bc93..b463eaa799ab4df73166a473c195f2cd86edb11a 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * MS5611 pressure and temperature sensor driver (SPI bus)
  *
  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  */
 
 #include <linux/delay.h>
@@ -119,9 +116,7 @@ static int ms5611_spi_remove(struct spi_device *spi)
 #if defined(CONFIG_OF)
 static const struct of_device_id ms5611_spi_matches[] = {
        { .compatible = "meas,ms5611" },
-       { .compatible = "ms5611" },
        { .compatible = "meas,ms5607" },
-       { .compatible = "ms5607" },
        { }
 };
 MODULE_DEVICE_TABLE(of, ms5611_spi_matches);
index 388ef70c11d24090dcd081498894f33cc926713a..b99367a89f8102bc008af17c2f081aebaaa8d8fe 100644 (file)
@@ -92,4 +92,15 @@ config SRF08
          To compile this driver as a module, choose M here: the
          module will be called srf08.
 
+config VL53L0X_I2C
+       tristate "STMicroelectronics VL53L0X ToF ranger sensor (I2C)"
+       depends on I2C
+       help
+         Say Y here to build a driver for STMicroelectronics VL53L0X
+         ToF ranger sensors with i2c interface.
+         This driver can be used to measure the distance of objects.
+
+         To compile this driver as a module, choose M here: the
+         module will be called vl53l0x-i2c.
+
 endmenu
index cac3d7d3325e35f0271f46c279a153c4526af372..6d031f903c4c24281bc7c81767b44d3513de788e 100644 (file)
@@ -11,3 +11,5 @@ obj-$(CONFIG_RFD77402)                += rfd77402.o
 obj-$(CONFIG_SRF04)            += srf04.o
 obj-$(CONFIG_SRF08)            += srf08.o
 obj-$(CONFIG_SX9500)           += sx9500.o
+obj-$(CONFIG_VL53L0X_I2C)      += vl53l0x-i2c.o
+
index e5e94540f404dd2c0d72efc90abbfd85aa0c5a72..5ae549075b27c50d512cbf5ef75b9630c87ef9c3 100644 (file)
@@ -232,7 +232,6 @@ static u32 isl29501_register_write(struct isl29501_private *isl29501,
                                   u32 value)
 {
        const struct isl29501_register_desc *reg = &isl29501_registers[name];
-       u8 msb, lsb;
        int ret;
 
        if (!reg->msb && value > U8_MAX)
@@ -241,22 +240,15 @@ static u32 isl29501_register_write(struct isl29501_private *isl29501,
        if (value > U16_MAX)
                return -ERANGE;
 
-       if (!reg->msb) {
-               lsb = value & 0xFF;
-       } else {
-               msb = (value >> 8) & 0xFF;
-               lsb = value & 0xFF;
-       }
-
        mutex_lock(&isl29501->lock);
        if (reg->msb) {
                ret = i2c_smbus_write_byte_data(isl29501->client,
-                                               reg->msb, msb);
+                                               reg->msb, value >> 8);
                if (ret < 0)
                        goto err;
        }
 
-       ret = i2c_smbus_write_byte_data(isl29501->client, reg->lsb, lsb);
+       ret = i2c_smbus_write_byte_data(isl29501->client, reg->lsb, value);
 
 err:
        mutex_unlock(&isl29501->lock);
diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c
new file mode 100644 (file)
index 0000000..b48216c
--- /dev/null
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for ST VL53L0X FlightSense ToF Ranging Sensor on a i2c bus.
+ *
+ * Copyright (C) 2016 STMicroelectronics Imaging Division.
+ * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com>
+ *
+ * Datasheet available at
+ * <https://www.st.com/resource/en/datasheet/vl53l0x.pdf>
+ *
+ * Default 7-bit i2c slave address 0x29.
+ *
+ * TODO: FIFO buffer, continuous mode, interrupts, range selection,
+ * sensor ID check.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+
+#define VL_REG_SYSRANGE_START                          0x00
+
+#define VL_REG_SYSRANGE_MODE_MASK                      GENMASK(3, 0)
+#define VL_REG_SYSRANGE_MODE_SINGLESHOT                        0x00
+#define VL_REG_SYSRANGE_MODE_START_STOP                        BIT(0)
+#define VL_REG_SYSRANGE_MODE_BACKTOBACK                        BIT(1)
+#define VL_REG_SYSRANGE_MODE_TIMED                     BIT(2)
+#define VL_REG_SYSRANGE_MODE_HISTOGRAM                 BIT(3)
+
+#define VL_REG_RESULT_INT_STATUS                       0x13
+#define VL_REG_RESULT_RANGE_STATUS                     0x14
+#define VL_REG_RESULT_RANGE_STATUS_COMPLETE            BIT(0)
+
+struct vl53l0x_data {
+       struct i2c_client *client;
+};
+
+static int vl53l0x_read_proximity(struct vl53l0x_data *data,
+                                 const struct iio_chan_spec *chan,
+                                 int *val)
+{
+       struct i2c_client *client = data->client;
+       u16 tries = 20;
+       u8 buffer[12];
+       int ret;
+
+       ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
+       if (ret < 0)
+               return ret;
+
+       do {
+               ret = i2c_smbus_read_byte_data(client,
+                                              VL_REG_RESULT_RANGE_STATUS);
+               if (ret < 0)
+                       return ret;
+
+               if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
+                       break;
+
+               usleep_range(1000, 5000);
+       } while (--tries);
+       if (!tries)
+               return -ETIMEDOUT;
+
+       ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS,
+                                           12, buffer);
+       if (ret < 0)
+               return ret;
+       else if (ret != 12)
+               return -EREMOTEIO;
+
+       /* Values should be between 30~1200 in millimeters. */
+       *val = (buffer[10] << 8) + buffer[11];
+
+       return 0;
+}
+
+static const struct iio_chan_spec vl53l0x_channels[] = {
+       {
+               .type = IIO_DISTANCE,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                                     BIT(IIO_CHAN_INFO_SCALE),
+       },
+};
+
+static int vl53l0x_read_raw(struct iio_dev *indio_dev,
+                           const struct iio_chan_spec *chan,
+                           int *val, int *val2, long mask)
+{
+       struct vl53l0x_data *data = iio_priv(indio_dev);
+       int ret;
+
+       if (chan->type != IIO_DISTANCE)
+               return -EINVAL;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = vl53l0x_read_proximity(data, chan, val);
+               if (ret < 0)
+                       return ret;
+
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = 1000;
+
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info vl53l0x_info = {
+       .read_raw = vl53l0x_read_raw,
+};
+
+static int vl53l0x_probe(struct i2c_client *client)
+{
+       struct vl53l0x_data *data;
+       struct iio_dev *indio_dev;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       data->client = client;
+       i2c_set_clientdata(client, indio_dev);
+
+       if (!i2c_check_functionality(client->adapter,
+                                    I2C_FUNC_SMBUS_READ_I2C_BLOCK |
+                                    I2C_FUNC_SMBUS_BYTE_DATA))
+               return -EOPNOTSUPP;
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->name = "vl53l0x";
+       indio_dev->info = &vl53l0x_info;
+       indio_dev->channels = vl53l0x_channels;
+       indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct of_device_id st_vl53l0x_dt_match[] = {
+       { .compatible = "st,vl53l0x", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, st_vl53l0x_dt_match);
+
+static struct i2c_driver vl53l0x_driver = {
+       .driver = {
+               .name = "vl53l0x-i2c",
+               .of_match_table = st_vl53l0x_dt_match,
+       },
+       .probe_new = vl53l0x_probe,
+};
+module_i2c_driver(vl53l0x_driver);
+
+MODULE_AUTHOR("Song Qiang <songqiang1304521@gmail.com>");
+MODULE_DESCRIPTION("ST vl53l0x ToF ranging sensor driver");
+MODULE_LICENSE("GPL v2");
index 3f0dc9a1a51406c5622a06cfc2b9cd01a96e0c85..45c4897295d6dfc319384622974acd8f3de6dfda 100644 (file)
@@ -222,7 +222,7 @@ static void __exit iio_sysfs_trig_exit(void)
 }
 module_exit(iio_sysfs_trig_exit);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:iio-trig-sysfs");
index f9f69f7111a91e99c1552e16533afac7d0d5f275..44bd5b9166bbfd2b6022ae22f20a88eae0058225 100644 (file)
@@ -11,7 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/bug.h>
 #include <linux/clk.h>
 #include <linux/component.h>
index 676c029494e44cc4a8eaf9af26e47d5e9ba40e02..0e780848f59b6b41bb96859c3539c83e0939d322 100644 (file)
@@ -13,7 +13,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/bug.h>
 #include <linux/clk.h>
 #include <linux/component.h>
index e8ae2e54151cc2d913f1d5159610e9813d2a8799..0a0b8e1f4236f701640a5c0e7c9056c0c3c88d01 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
 #include <linux/jiffies.h>
@@ -38,7 +38,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
-#include <linux/memblock.h>
 #include <linux/sched/signal.h>
 
 #include <asm/byteorder.h>
@@ -493,7 +492,7 @@ int __init smu_init (void)
                goto fail_np;
        }
 
-       smu = alloc_bootmem(sizeof(struct smu_device));
+       smu = memblock_alloc(sizeof(struct smu_device), SMP_CACHE_BYTES);
 
        spin_lock_init(&smu->lock);
        INIT_LIST_HEAD(&smu->cmd_list);
@@ -569,7 +568,7 @@ fail_msg_node:
 fail_db_node:
        of_node_put(smu->db_node);
 fail_bootmem:
-       free_bootmem(__pa(smu), sizeof(struct smu_device));
+       memblock_free(__pa(smu), sizeof(struct smu_device));
        smu = NULL;
 fail_np:
        of_node_put(np);
index 841c005d8ebb2f720047a984ff25c0d974a37dff..3eeb12e93e986fd009818182a6a813645c14b5d9 100644 (file)
@@ -105,12 +105,12 @@ config STI_MBOX
 
 config TI_MESSAGE_MANAGER
        tristate "Texas Instruments Message Manager Driver"
-       depends on ARCH_KEYSTONE
+       depends on ARCH_KEYSTONE || ARCH_K3
        help
          An implementation of Message Manager slave driver for Keystone
-         architecture SoCs from Texas Instruments. Message Manager is a
-         communication entity found on few of Texas Instrument's keystone
-         architecture SoCs. These may be used for communication between
+         and K3 architecture SoCs from Texas Instruments. Message Manager
+         is a communication entity found on few of Texas Instrument's keystone
+         and K3 architecture SoCs. These may be used for communication between
          multiple processors within the SoC. Select this driver if your
          platform has support for the hardware block.
 
index 8ab077ff58f4a8a58cebf7a8d3aa1a93417b088e..d7a8ed7d809789f6d55f28aa7935d026193b0db7 100644 (file)
@@ -375,7 +375,7 @@ static u32 flexrm_estimate_header_desc_count(u32 nhcnt)
        return hcnt;
 }
 
-static void flexrm_flip_header_toogle(void *desc_ptr)
+static void flexrm_flip_header_toggle(void *desc_ptr)
 {
        u64 desc = flexrm_read_desc(desc_ptr);
 
@@ -709,7 +709,7 @@ static void *flexrm_spu_write_descs(struct brcm_message *msg, u32 nhcnt,
        wmb();
 
        /* Flip toggle bit in header */
-       flexrm_flip_header_toogle(orig_desc_ptr);
+       flexrm_flip_header_toggle(orig_desc_ptr);
 
        return desc_ptr;
 }
@@ -838,7 +838,7 @@ static void *flexrm_sba_write_descs(struct brcm_message *msg, u32 nhcnt,
        wmb();
 
        /* Flip toggle bit in header */
-       flexrm_flip_header_toogle(orig_desc_ptr);
+       flexrm_flip_header_toggle(orig_desc_ptr);
 
        return desc_ptr;
 }
index aec46d5d3506181a7dc34bee920d80645c2c95f0..f7cc29c00302a493ee4136fe41273775b706c35a 100644 (file)
@@ -363,6 +363,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
        WARN_ON(cmdq->suspended);
 
        task = kzalloc(sizeof(*task), GFP_ATOMIC);
+       if (!task)
+               return -ENOMEM;
+
        task->cmdq = cmdq;
        INIT_LIST_HEAD(&task->list_entry);
        task->pa_base = pkt->pa_base;
index 333ed4a9d4b8fc62d14fdc9abc8db0242a80026c..aed23ac9550dff8ef24761a18776ca650d082c7a 100644 (file)
@@ -126,6 +126,7 @@ static const struct of_device_id qcom_apcs_ipc_of_match[] = {
        { .compatible = "qcom,msm8916-apcs-kpss-global", .data = (void *)8 },
        { .compatible = "qcom,msm8996-apcs-hmss-global", .data = (void *)16 },
        { .compatible = "qcom,msm8998-apcs-hmss-global", .data = (void *)8 },
+       { .compatible = "qcom,qcs404-apcs-apps-global", .data = (void *)8 },
        { .compatible = "qcom,sdm845-apss-shared", .data = (void *)12 },
        {}
 };
index 5bceafbf66993f266de4df2ddf574c9c19bfdca9..713d701b656892d2f9fe5d7008f30808d21936c8 100644 (file)
@@ -560,8 +560,8 @@ static struct mbox_chan *ti_msgmgr_of_xlate(struct mbox_controller *mbox,
        }
 
 err:
-       dev_err(inst->dev, "Queue ID %d, Proxy ID %d is wrong on %s\n",
-               req_qid, req_pid, p->np->name);
+       dev_err(inst->dev, "Queue ID %d, Proxy ID %d is wrong on %pOFn\n",
+               req_qid, req_pid, p->np);
        return ERR_PTR(-ENOENT);
 }
 
index 594b462ddf0efab902599b1c0441075dab1f1c8c..985d35ec6b298491eb80bd7c3b246faba58d0dd7 100644 (file)
@@ -3,7 +3,8 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-media-objs     := media-device.o media-devnode.o media-entity.o
+media-objs     := media-device.o media-devnode.o media-entity.o \
+                  media-request.o
 
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
index 29a2ab9e77c5dffd8fadc034450f83bdbe9e2aad..ad8677d8c89679bb6b0eda8357a136dfb920fbf3 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o
+cec-objs := cec-core.o cec-adap.o cec-api.o
 
 ifeq ($(CONFIG_CEC_NOTIFIER),y)
   cec-objs += cec-notifier.o
index 030b2602faf0c322ad0483cd5f0f29e565b06497..31d1f4ab915ea7e07f8843d1feb99217409a1af4 100644 (file)
@@ -62,6 +62,19 @@ static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr
        return adap->log_addrs.primary_device_type[i < 0 ? 0 : i];
 }
 
+u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
+                          unsigned int *offset)
+{
+       unsigned int loc = cec_get_edid_spa_location(edid, size);
+
+       if (offset)
+               *offset = loc;
+       if (loc == 0)
+               return CEC_PHYS_ADDR_INVALID;
+       return (edid[loc] << 8) | edid[loc + 1];
+}
+EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
+
 /*
  * Queue a new event for this filehandle. If ts == 0, then set it
  * to the current time.
@@ -341,7 +354,7 @@ static void cec_data_completed(struct cec_data *data)
  *
  * This function is called with adap->lock held.
  */
-static void cec_data_cancel(struct cec_data *data)
+static void cec_data_cancel(struct cec_data *data, u8 tx_status)
 {
        /*
         * It's either the current transmit, or it is a pending
@@ -356,13 +369,11 @@ static void cec_data_cancel(struct cec_data *data)
        }
 
        if (data->msg.tx_status & CEC_TX_STATUS_OK) {
-               /* Mark the canceled RX as a timeout */
                data->msg.rx_ts = ktime_get_ns();
-               data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
+               data->msg.rx_status = CEC_RX_STATUS_ABORTED;
        } else {
-               /* Mark the canceled TX as an error */
                data->msg.tx_ts = ktime_get_ns();
-               data->msg.tx_status |= CEC_TX_STATUS_ERROR |
+               data->msg.tx_status |= tx_status |
                                       CEC_TX_STATUS_MAX_RETRIES;
                data->msg.tx_error_cnt++;
                data->attempts = 0;
@@ -390,15 +401,15 @@ static void cec_flush(struct cec_adapter *adap)
        while (!list_empty(&adap->transmit_queue)) {
                data = list_first_entry(&adap->transmit_queue,
                                        struct cec_data, list);
-               cec_data_cancel(data);
+               cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
        }
        if (adap->transmitting)
-               cec_data_cancel(adap->transmitting);
+               cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED);
 
        /* Cancel the pending timeout work. */
        list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
                if (cancel_delayed_work(&data->work))
-                       cec_data_cancel(data);
+                       cec_data_cancel(data, CEC_TX_STATUS_OK);
                /*
                 * If cancel_delayed_work returned false, then
                 * the cec_wait_timeout function is running,
@@ -474,12 +485,13 @@ int cec_thread_func(void *_adap)
                         * so much traffic on the bus that the adapter was
                         * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
                         */
-                       dprintk(1, "%s: message %*ph timed out\n", __func__,
+                       pr_warn("cec-%s: message %*ph timed out\n", adap->name,
                                adap->transmitting->msg.len,
                                adap->transmitting->msg.msg);
                        adap->tx_timeouts++;
                        /* Just give up on this. */
-                       cec_data_cancel(adap->transmitting);
+                       cec_data_cancel(adap->transmitting,
+                                       CEC_TX_STATUS_TIMEOUT);
                        goto unlock;
                }
 
@@ -514,9 +526,11 @@ int cec_thread_func(void *_adap)
                if (data->attempts) {
                        /* should be >= 3 data bit periods for a retry */
                        signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY;
-               } else if (data->new_initiator) {
+               } else if (adap->last_initiator !=
+                          cec_msg_initiator(&data->msg)) {
                        /* should be >= 5 data bit periods for new initiator */
                        signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
+                       adap->last_initiator = cec_msg_initiator(&data->msg);
                } else {
                        /*
                         * should be >= 7 data bit periods for sending another
@@ -530,7 +544,7 @@ int cec_thread_func(void *_adap)
                /* Tell the adapter to transmit, cancel on error */
                if (adap->ops->adap_transmit(adap, data->attempts,
                                             signal_free_time, &data->msg))
-                       cec_data_cancel(data);
+                       cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
 
 unlock:
                mutex_unlock(&adap->lock);
@@ -701,9 +715,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
                        struct cec_fh *fh, bool block)
 {
        struct cec_data *data;
-       u8 last_initiator = 0xff;
-       unsigned int timeout;
-       int res = 0;
 
        msg->rx_ts = 0;
        msg->tx_ts = 0;
@@ -813,23 +824,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
        data->adap = adap;
        data->blocking = block;
 
-       /*
-        * Determine if this message follows a message from the same
-        * initiator. Needed to determine the free signal time later on.
-        */
-       if (msg->len > 1) {
-               if (!(list_empty(&adap->transmit_queue))) {
-                       const struct cec_data *last;
-
-                       last = list_last_entry(&adap->transmit_queue,
-                                              const struct cec_data, list);
-                       last_initiator = cec_msg_initiator(&last->msg);
-               } else if (adap->transmitting) {
-                       last_initiator =
-                               cec_msg_initiator(&adap->transmitting->msg);
-               }
-       }
-       data->new_initiator = last_initiator != cec_msg_initiator(msg);
        init_completion(&data->c);
        INIT_DELAYED_WORK(&data->work, cec_wait_timeout);
 
@@ -845,48 +839,23 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
        if (!block)
                return 0;
 
-       /*
-        * If we don't get a completion before this time something is really
-        * wrong and we time out.
-        */
-       timeout = CEC_XFER_TIMEOUT_MS;
-       /* Add the requested timeout if we have to wait for a reply as well */
-       if (msg->timeout)
-               timeout += msg->timeout;
-
        /*
         * Release the lock and wait, retake the lock afterwards.
         */
        mutex_unlock(&adap->lock);
-       res = wait_for_completion_killable_timeout(&data->c,
-                                                  msecs_to_jiffies(timeout));
+       wait_for_completion_killable(&data->c);
+       if (!data->completed)
+               cancel_delayed_work_sync(&data->work);
        mutex_lock(&adap->lock);
 
-       if (data->completed) {
-               /* The transmit completed (possibly with an error) */
-               *msg = data->msg;
-               kfree(data);
-               return 0;
-       }
-       /*
-        * The wait for completion timed out or was interrupted, so mark this
-        * as non-blocking and disconnect from the filehandle since it is
-        * still 'in flight'. When it finally completes it will just drop the
-        * result silently.
-        */
-       data->blocking = false;
-       if (data->fh)
-               list_del(&data->xfer_list);
-       data->fh = NULL;
+       /* Cancel the transmit if it was interrupted */
+       if (!data->completed)
+               cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
 
-       if (res == 0) { /* timed out */
-               /* Check if the reply or the transmit failed */
-               if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK))
-                       msg->rx_status = CEC_RX_STATUS_TIMEOUT;
-               else
-                       msg->tx_status = CEC_TX_STATUS_MAX_RETRIES;
-       }
-       return res > 0 ? 0 : res;
+       /* The transmit completed (possibly with an error) */
+       *msg = data->msg;
+       kfree(data);
+       return 0;
 }
 
 /* Helper function to be used by drivers and this framework. */
@@ -1044,6 +1013,8 @@ void cec_received_msg_ts(struct cec_adapter *adap,
        mutex_lock(&adap->lock);
        dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
 
+       adap->last_initiator = 0xff;
+
        /* Check if this message was for us (directed or broadcast). */
        if (!cec_msg_is_broadcast(msg))
                valid_la = cec_has_log_addr(adap, msg_dest);
@@ -1506,6 +1477,8 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
        }
 
        mutex_lock(&adap->devnode.lock);
+       adap->last_initiator = 0xff;
+
        if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
            adap->ops->adap_enable(adap, true)) {
                mutex_unlock(&adap->devnode.lock);
index b6536bbad530c6b2bed6af16a9a4b1a41b32726a..391b6fd483e14b0237ca45aee2e519816c61ea25 100644 (file)
@@ -77,9 +77,9 @@ static long cec_adap_g_caps(struct cec_adapter *adap,
 {
        struct cec_caps caps = {};
 
-       strlcpy(caps.driver, adap->devnode.dev.parent->driver->name,
+       strscpy(caps.driver, adap->devnode.dev.parent->driver->name,
                sizeof(caps.driver));
-       strlcpy(caps.name, adap->name, sizeof(caps.name));
+       strscpy(caps.name, adap->name, sizeof(caps.name));
        caps.available_log_addrs = adap->available_log_addrs;
        caps.capabilities = adap->capabilities;
        caps.version = LINUX_VERSION_CODE;
@@ -101,6 +101,23 @@ static long cec_adap_g_phys_addr(struct cec_adapter *adap,
        return 0;
 }
 
+static int cec_validate_phys_addr(u16 phys_addr)
+{
+       int i;
+
+       if (phys_addr == CEC_PHYS_ADDR_INVALID)
+               return 0;
+       for (i = 0; i < 16; i += 4)
+               if (phys_addr & (0xf << i))
+                       break;
+       if (i == 16)
+               return 0;
+       for (i += 4; i < 16; i += 4)
+               if ((phys_addr & (0xf << i)) == 0)
+                       return -EINVAL;
+       return 0;
+}
+
 static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
                                 bool block, __u16 __user *parg)
 {
@@ -112,7 +129,7 @@ static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
        if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
                return -EFAULT;
 
-       err = cec_phys_addr_validate(phys_addr, NULL, NULL);
+       err = cec_validate_phys_addr(phys_addr);
        if (err)
                return err;
        mutex_lock(&adap->lock);
@@ -665,6 +682,7 @@ const struct file_operations cec_devnode_fops = {
        .owner = THIS_MODULE,
        .open = cec_open,
        .unlocked_ioctl = cec_ioctl,
+       .compat_ioctl = cec_ioctl,
        .release = cec_release,
        .poll = cec_poll,
        .llseek = no_llseek,
index b278ab90b38715023ea286c79f35cdfa47c94532..e4edc930d4ed35c63b8515991f8c463d806fe6dd 100644 (file)
@@ -264,7 +264,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
        adap = kzalloc(sizeof(*adap), GFP_KERNEL);
        if (!adap)
                return ERR_PTR(-ENOMEM);
-       strlcpy(adap->name, name, sizeof(adap->name));
+       strscpy(adap->name, name, sizeof(adap->name));
        adap->phys_addr = CEC_PHYS_ADDR_INVALID;
        adap->cec_pin_is_high = true;
        adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
@@ -307,12 +307,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
                return ERR_PTR(-ENOMEM);
        }
 
-       snprintf(adap->device_name, sizeof(adap->device_name),
-                "RC for %s", name);
        snprintf(adap->input_phys, sizeof(adap->input_phys),
-                "%s/input0", name);
+                "%s/input0", adap->name);
 
-       adap->rc->device_name = adap->device_name;
+       adap->rc->device_name = adap->name;
        adap->rc->input_phys = adap->input_phys;
        adap->rc->input_id.bustype = BUS_CEC;
        adap->rc->input_id.vendor = 0;
diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c
deleted file mode 100644 (file)
index ec72ac1..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions
- *
- * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <media/cec.h>
-
-/*
- * This EDID is expected to be a CEA-861 compliant, which means that there are
- * at least two blocks and one or more of the extensions blocks are CEA-861
- * blocks.
- *
- * The returned location is guaranteed to be < size - 1.
- */
-static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size)
-{
-       unsigned int blocks = size / 128;
-       unsigned int block;
-       u8 d;
-
-       /* Sanity check: at least 2 blocks and a multiple of the block size */
-       if (blocks < 2 || size % 128)
-               return 0;
-
-       /*
-        * If there are fewer extension blocks than the size, then update
-        * 'blocks'. It is allowed to have more extension blocks than the size,
-        * since some hardware can only read e.g. 256 bytes of the EDID, even
-        * though more blocks are present. The first CEA-861 extension block
-        * should normally be in block 1 anyway.
-        */
-       if (edid[0x7e] + 1 < blocks)
-               blocks = edid[0x7e] + 1;
-
-       for (block = 1; block < blocks; block++) {
-               unsigned int offset = block * 128;
-
-               /* Skip any non-CEA-861 extension blocks */
-               if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
-                       continue;
-
-               /* search Vendor Specific Data Block (tag 3) */
-               d = edid[offset + 2] & 0x7f;
-               /* Check if there are Data Blocks */
-               if (d <= 4)
-                       continue;
-               if (d > 4) {
-                       unsigned int i = offset + 4;
-                       unsigned int end = offset + d;
-
-                       /* Note: 'end' is always < 'size' */
-                       do {
-                               u8 tag = edid[i] >> 5;
-                               u8 len = edid[i] & 0x1f;
-
-                               if (tag == 3 && len >= 5 && i + len <= end &&
-                                   edid[i + 1] == 0x03 &&
-                                   edid[i + 2] == 0x0c &&
-                                   edid[i + 3] == 0x00)
-                                       return i + 4;
-                               i += len + 1;
-                       } while (i < end);
-               }
-       }
-       return 0;
-}
-
-u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
-                          unsigned int *offset)
-{
-       unsigned int loc = cec_get_edid_spa_location(edid, size);
-
-       if (offset)
-               *offset = loc;
-       if (loc == 0)
-               return CEC_PHYS_ADDR_INVALID;
-       return (edid[loc] << 8) | edid[loc + 1];
-}
-EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
-
-void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr)
-{
-       unsigned int loc = cec_get_edid_spa_location(edid, size);
-       u8 sum = 0;
-       unsigned int i;
-
-       if (loc == 0)
-               return;
-       edid[loc] = phys_addr >> 8;
-       edid[loc + 1] = phys_addr & 0xff;
-       loc &= ~0x7f;
-
-       /* update the checksum */
-       for (i = loc; i < loc + 127; i++)
-               sum += edid[i];
-       edid[i] = 256 - sum;
-}
-EXPORT_SYMBOL_GPL(cec_set_edid_phys_addr);
-
-u16 cec_phys_addr_for_input(u16 phys_addr, u8 input)
-{
-       /* Check if input is sane */
-       if (WARN_ON(input == 0 || input > 0xf))
-               return CEC_PHYS_ADDR_INVALID;
-
-       if (phys_addr == 0)
-               return input << 12;
-
-       if ((phys_addr & 0x0fff) == 0)
-               return phys_addr | (input << 8);
-
-       if ((phys_addr & 0x00ff) == 0)
-               return phys_addr | (input << 4);
-
-       if ((phys_addr & 0x000f) == 0)
-               return phys_addr | input;
-
-       /*
-        * All nibbles are used so no valid physical addresses can be assigned
-        * to the input.
-        */
-       return CEC_PHYS_ADDR_INVALID;
-}
-EXPORT_SYMBOL_GPL(cec_phys_addr_for_input);
-
-int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
-{
-       int i;
-
-       if (parent)
-               *parent = phys_addr;
-       if (port)
-               *port = 0;
-       if (phys_addr == CEC_PHYS_ADDR_INVALID)
-               return 0;
-       for (i = 0; i < 16; i += 4)
-               if (phys_addr & (0xf << i))
-                       break;
-       if (i == 16)
-               return 0;
-       if (parent)
-               *parent = phys_addr & (0xfff0 << i);
-       if (port)
-               *port = (phys_addr >> i) & 0xf;
-       for (i += 4; i < 16; i += 4)
-               if ((phys_addr & (0xf << i)) == 0)
-                       return -EINVAL;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(cec_phys_addr_validate);
index 6e311424f0dc5030ab33571bdb9a4d4958093cdd..635db8e70ead57e24915f9d64fcfa1ccad48ec0e 100644 (file)
@@ -935,6 +935,17 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
                        /* Start bit, switch to receive state */
                        pin->ts = ts;
                        pin->state = CEC_ST_RX_START_BIT_LOW;
+                       /*
+                        * If a transmit is pending, then that transmit should
+                        * use a signal free time of no more than
+                        * CEC_SIGNAL_FREE_TIME_NEW_INITIATOR since it will
+                        * have a new initiator due to the receive that is now
+                        * starting.
+                        */
+                       if (pin->tx_msg.len && pin->tx_signal_free_time >
+                           CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
+                               pin->tx_signal_free_time =
+                                       CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
                        break;
                }
                if (ktime_to_ns(pin->ts) == 0)
@@ -1157,6 +1168,15 @@ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
 {
        struct cec_pin *pin = adap->pin;
 
+       /*
+        * If a receive is in progress, then this transmit should use
+        * a signal free time of max CEC_SIGNAL_FREE_TIME_NEW_INITIATOR
+        * since when it starts transmitting it will have a new initiator.
+        */
+       if (pin->state != CEC_ST_IDLE &&
+           signal_free_time > CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
+               signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
+
        pin->tx_signal_free_time = signal_free_time;
        pin->tx_extra_bytes = 0;
        pin->tx_msg = *msg;
index 6675b605eb6f6b1a4b6d39ac7337ebd6c3550caa..1f1eaa807811b569d3a65566c3860a6d7d5845c7 100644 (file)
@@ -226,12 +226,12 @@ int flexcop_i2c_init(struct flexcop_device *fc)
        fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
        fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
 
-       strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
-                       sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
-       strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
-                       sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
-       strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
-                       sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
+       strscpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
+               sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+       strscpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
+               sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+       strscpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
+               sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
 
        i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
        i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
index 81dce9a81bd30aa2fbbe83147da8de44630782c5..1dcc39b87bb7bc2dfde80442b10bd77dfaa5b20e 100644 (file)
@@ -569,7 +569,7 @@ static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
                qctrl->step = step;
                qctrl->default_value = def;
                qctrl->reserved[0] = qctrl->reserved[1] = 0;
-               strlcpy(qctrl->name, name, sizeof(qctrl->name));
+               strscpy(qctrl->name, name, sizeof(qctrl->name));
                return 0;
 
        default:
index d4987fd05d05f5b089e18b482fddf3deca2ac2ad..c790ae264464f33727c91e759ba9727df1665157 100644 (file)
@@ -606,7 +606,7 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
        vfd->tvnorms = 0;
        for (i = 0; i < dev->ext_vv_data->num_stds; i++)
                vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
-       strlcpy(vfd->name, name, sizeof(vfd->name));
+       strscpy(vfd->name, name, sizeof(vfd->name));
        video_set_drvdata(vfd, dev);
 
        err = video_register_device(vfd, type, -1);
index 0dfa0c09d646fdcd147437f871b49a995803af87..f90aa8109663195b319c8b930b73f1baf9283ce1 100644 (file)
@@ -451,8 +451,8 @@ static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *
        struct video_device *vdev = video_devdata(file);
        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-       strcpy((char *)cap->driver, "saa7146 v4l2");
-       strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
+       strscpy((char *)cap->driver, "saa7146 v4l2", sizeof(cap->driver));
+       strscpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
        sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
        cap->device_caps =
                V4L2_CAP_VIDEO_CAPTURE |
@@ -525,8 +525,8 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtd
 {
        if (f->index >= ARRAY_SIZE(formats))
                return -EINVAL;
-       strlcpy((char *)f->description, formats[f->index].name,
-                       sizeof(f->description));
+       strscpy((char *)f->description, formats[f->index].name,
+               sizeof(f->description));
        f->pixelformat = formats[f->index].pixelformat;
        return 0;
 }
index 3b02cb570a6ead3e1ac406684703853a4183b059..add9d63619145bf5a9a0c6ef719dedf7a0432643 100644 (file)
@@ -450,7 +450,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
        entry = kmalloc(sizeof(*entry), GFP_KERNEL);
        if (entry) {
                entry->mode = default_mode;
-               strlcpy(entry->devpath, devpath, sizeof(entry->devpath));
+               strscpy(entry->devpath, devpath, sizeof(entry->devpath));
                list_add(&entry->entry, &g_smscore_registry);
        } else
                pr_err("failed to create smscore_registry.\n");
@@ -735,7 +735,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
        dev->postload_handler = params->postload_handler;
 
        dev->device_flags = params->flags;
-       strlcpy(dev->devpath, params->devpath, sizeof(dev->devpath));
+       strscpy(dev->devpath, params->devpath, sizeof(dev->devpath));
 
        smscore_registry_settype(dev->devpath, params->device_type);
 
index 56db0a9444218b7ef0565d5d422295b8a196c920..79bd627f84b8e959e84c8ecc004952170358316f 100644 (file)
@@ -26,10 +26,10 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
        const s32 *samples = (const void *)buf;
 
        for (i = 0; i < len >> 2; i++) {
-               DEFINE_IR_RAW_EVENT(ev);
-
-               ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
-               ev.pulse = (samples[i] > 0) ? false : true;
+               struct ir_raw_event ev = {
+                       .duration = abs(samples[i]) * 1000, /* Convert to ns */
+                       .pulse = (samples[i] > 0) ? false : true
+               };
 
                ir_raw_event_store(coredev->ir.dev, &ev);
        }
@@ -55,7 +55,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
        snprintf(coredev->ir.name, sizeof(coredev->ir.name),
                 "SMS IR (%s)", sms_get_board(board_id)->name);
 
-       strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
+       strscpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
        strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
 
        dev->device_name = coredev->ir.name;
index 3a3dc23c560c86862d0215d19269db855da64fe0..a4341205c197d9fdf90a1f80de12f4843a688167 100644 (file)
@@ -602,14 +602,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 },
        [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 },
        [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 },
-       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 },
+       [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 },
        [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 },
@@ -658,14 +658,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 },
        [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 },
        [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 },
-       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 },
+       [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 },
        [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 },
@@ -714,14 +714,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 },
        [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 },
        [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 },
-       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 },
+       [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 },
        [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 },
@@ -770,14 +770,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2599, 901, 909 },
        [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 991, 0, 2966 },
        [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2989, 3120, 1180 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1913, 3011, 3009 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1836, 3099, 1105 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2627, 413, 2966 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2576, 943, 951 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1026, 0, 2942 },
-       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][1] = { 2989, 3120, 1180 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][2] = { 1913, 3011, 3009 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][3] = { 1836, 3099, 1105 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][4] = { 2627, 413, 2966 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][5] = { 2576, 943, 951 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][6] = { 1026, 0, 2942 },
+       [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2879, 3022, 874 },
        [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1688, 2903, 2901 },
@@ -826,14 +826,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][5] = { 3001, 800, 799 },
        [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3071 },
        [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 776 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][2] = { 1068, 3033, 3033 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][3] = { 1068, 3033, 776 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][4] = { 2977, 851, 3048 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][5] = { 2977, 851, 851 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3048 },
-       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 776 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][2] = { 1068, 3033, 3033 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][3] = { 1068, 3033, 776 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][4] = { 2977, 851, 3048 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][5] = { 2977, 851, 851 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3048 },
+       [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 423 },
        [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][2] = { 749, 2926, 2926 },
@@ -882,14 +882,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 },
-       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 },
+       [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 },
@@ -922,62 +922,62 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1812, 886, 886 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1812 },
        [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 1063 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 1828, 3033, 3033 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 1828, 3033, 1063 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 2633, 851, 2979 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 2633, 851, 851 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 2979 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 },
-       [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 1063 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][2] = { 1828, 3033, 3033 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][3] = { 1828, 3033, 1063 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][4] = { 2633, 851, 2979 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][5] = { 2633, 851, 851 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 2979 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 },
+       [V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 },
@@ -994,14 +994,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][5] = { 2517, 1159, 900 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][6] = { 1042, 870, 2917 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][1] = { 2976, 3018, 1315 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][2] = { 2024, 2942, 3011 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][3] = { 1930, 2926, 1256 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][4] = { 2563, 1227, 2916 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][5] = { 2494, 1183, 943 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][6] = { 1073, 916, 2894 },
-       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][1] = { 2976, 3018, 1315 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][2] = { 2024, 2942, 3011 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][3] = { 1930, 2926, 1256 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][4] = { 2563, 1227, 2916 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][5] = { 2494, 1183, 943 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][6] = { 1073, 916, 2894 },
+       [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][1] = { 2864, 2910, 1024 },
        [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][2] = { 1811, 2826, 2903 },
@@ -1050,14 +1050,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
        [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][5] = { 2880, 998, 902 },
        [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][6] = { 816, 823, 2940 },
        [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][1] = { 3029, 3028, 1255 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][2] = { 1406, 2988, 3011 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][3] = { 1398, 2983, 1190 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][4] = { 2860, 1050, 2939 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][5] = { 2857, 1033, 945 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][6] = { 866, 873, 2916 },
-       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][1] = { 3029, 3028, 1255 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][2] = { 1406, 2988, 3011 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][3] = { 1398, 2983, 1190 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][4] = { 2860, 1050, 2939 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][5] = { 2857, 1033, 945 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][6] = { 866, 873, 2916 },
+       [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
        [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
        [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][1] = { 2923, 2921, 957 },
        [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][2] = { 1125, 2877, 2902 },
@@ -1128,7 +1128,7 @@ static const double rec709_to_240m[3][3] = {
        { 0.0016327, 0.0044133, 0.9939540 },
 };
 
-static const double rec709_to_adobergb[3][3] = {
+static const double rec709_to_oprgb[3][3] = {
        { 0.7151627, 0.2848373, -0.0000000 },
        { 0.0000000, 1.0000000, 0.0000000 },
        { -0.0000000, 0.0411705, 0.9588295 },
@@ -1195,7 +1195,7 @@ static double transfer_rec709_to_rgb(double v)
        return (v < 0.081) ? v / 4.5 : pow((v + 0.099) / 1.099, 1.0 / 0.45);
 }
 
-static double transfer_rgb_to_adobergb(double v)
+static double transfer_rgb_to_oprgb(double v)
 {
        return pow(v, 1.0 / 2.19921875);
 }
@@ -1251,8 +1251,8 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
        case V4L2_COLORSPACE_470_SYSTEM_M:
                mult_matrix(r, g, b, rec709_to_ntsc1953);
                break;
-       case V4L2_COLORSPACE_ADOBERGB:
-               mult_matrix(r, g, b, rec709_to_adobergb);
+       case V4L2_COLORSPACE_OPRGB:
+               mult_matrix(r, g, b, rec709_to_oprgb);
                break;
        case V4L2_COLORSPACE_BT2020:
                mult_matrix(r, g, b, rec709_to_bt2020);
@@ -1284,10 +1284,10 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
                *g = transfer_rgb_to_srgb(*g);
                *b = transfer_rgb_to_srgb(*b);
                break;
-       case V4L2_XFER_FUNC_ADOBERGB:
-               *r = transfer_rgb_to_adobergb(*r);
-               *g = transfer_rgb_to_adobergb(*g);
-               *b = transfer_rgb_to_adobergb(*b);
+       case V4L2_XFER_FUNC_OPRGB:
+               *r = transfer_rgb_to_oprgb(*r);
+               *g = transfer_rgb_to_oprgb(*g);
+               *b = transfer_rgb_to_oprgb(*b);
                break;
        case V4L2_XFER_FUNC_DCI_P3:
                *r = transfer_rgb_to_dcip3(*r);
@@ -1321,7 +1321,7 @@ int main(int argc, char **argv)
                V4L2_COLORSPACE_470_SYSTEM_BG,
                0,
                V4L2_COLORSPACE_SRGB,
-               V4L2_COLORSPACE_ADOBERGB,
+               V4L2_COLORSPACE_OPRGB,
                V4L2_COLORSPACE_BT2020,
                0,
                V4L2_COLORSPACE_DCI_P3,
@@ -1336,7 +1336,7 @@ int main(int argc, char **argv)
                "V4L2_COLORSPACE_470_SYSTEM_BG",
                "",
                "V4L2_COLORSPACE_SRGB",
-               "V4L2_COLORSPACE_ADOBERGB",
+               "V4L2_COLORSPACE_OPRGB",
                "V4L2_COLORSPACE_BT2020",
                "",
                "V4L2_COLORSPACE_DCI_P3",
@@ -1345,7 +1345,7 @@ int main(int argc, char **argv)
                "",
                "V4L2_XFER_FUNC_709",
                "V4L2_XFER_FUNC_SRGB",
-               "V4L2_XFER_FUNC_ADOBERGB",
+               "V4L2_XFER_FUNC_OPRGB",
                "V4L2_XFER_FUNC_SMPTE240M",
                "V4L2_XFER_FUNC_NONE",
                "V4L2_XFER_FUNC_DCI_P3",
index abd4c788dffdea26b73acb0bb5191ff78c1a3c5d..fa483b95bc5a996a4a8bb3fe737a32c791cab5bd 100644 (file)
@@ -202,6 +202,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
        case V4L2_PIX_FMT_SGBRG12:
        case V4L2_PIX_FMT_SGRBG12:
        case V4L2_PIX_FMT_SRGGB12:
+       case V4L2_PIX_FMT_SBGGR16:
+       case V4L2_PIX_FMT_SGBRG16:
+       case V4L2_PIX_FMT_SGRBG16:
+       case V4L2_PIX_FMT_SRGGB16:
                tpg->interleaved = true;
                tpg->vdownsampling[1] = 1;
                tpg->hdownsampling[1] = 1;
@@ -235,6 +239,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
        case V4L2_PIX_FMT_Y12:
        case V4L2_PIX_FMT_Y16:
        case V4L2_PIX_FMT_Y16_BE:
+       case V4L2_PIX_FMT_Z16:
                tpg->color_enc = TGP_COLOR_ENC_LUMA;
                break;
        case V4L2_PIX_FMT_YUV444:
@@ -351,6 +356,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
        case V4L2_PIX_FMT_Y12:
        case V4L2_PIX_FMT_Y16:
        case V4L2_PIX_FMT_Y16_BE:
+       case V4L2_PIX_FMT_Z16:
                tpg->twopixelsize[0] = 2 * 2;
                break;
        case V4L2_PIX_FMT_RGB24:
@@ -392,6 +398,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
        case V4L2_PIX_FMT_SGRBG12:
        case V4L2_PIX_FMT_SGBRG12:
        case V4L2_PIX_FMT_SBGGR12:
+       case V4L2_PIX_FMT_SRGGB16:
+       case V4L2_PIX_FMT_SGRBG16:
+       case V4L2_PIX_FMT_SGBRG16:
+       case V4L2_PIX_FMT_SBGGR16:
                tpg->twopixelsize[0] = 4;
                tpg->twopixelsize[1] = 4;
                break;
@@ -1062,6 +1072,7 @@ static void gen_twopix(struct tpg_data *tpg,
                buf[0][offset+1] = r_y_h >> 4;
                break;
        case V4L2_PIX_FMT_Y16:
+       case V4L2_PIX_FMT_Z16:
                /*
                 * Ideally both bytes should be set to r_y_h, but then you won't
                 * be able to detect endian problems. So keep it 0 except for
@@ -1355,6 +1366,22 @@ static void gen_twopix(struct tpg_data *tpg,
                buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
                buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
                break;
+       case V4L2_PIX_FMT_SBGGR16:
+               buf[0][offset] = buf[0][offset + 1] = odd ? g_u_s : b_v;
+               buf[1][offset] = buf[1][offset + 1] = odd ? r_y_h : g_u_s;
+               break;
+       case V4L2_PIX_FMT_SGBRG16:
+               buf[0][offset] = buf[0][offset + 1] = odd ? b_v : g_u_s;
+               buf[1][offset] = buf[1][offset + 1] = odd ? g_u_s : r_y_h;
+               break;
+       case V4L2_PIX_FMT_SGRBG16:
+               buf[0][offset] = buf[0][offset + 1] = odd ? r_y_h : g_u_s;
+               buf[1][offset] = buf[1][offset + 1] = odd ? g_u_s : b_v;
+               break;
+       case V4L2_PIX_FMT_SRGGB16:
+               buf[0][offset] = buf[0][offset + 1] = odd ? g_u_s : r_y_h;
+               buf[1][offset] = buf[1][offset + 1] = odd ? b_v : g_u_s;
+               break;
        }
 }
 
@@ -1373,6 +1400,10 @@ unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
        case V4L2_PIX_FMT_SGBRG12:
        case V4L2_PIX_FMT_SGRBG12:
        case V4L2_PIX_FMT_SRGGB12:
+       case V4L2_PIX_FMT_SBGGR16:
+       case V4L2_PIX_FMT_SGBRG16:
+       case V4L2_PIX_FMT_SGRBG16:
+       case V4L2_PIX_FMT_SRGGB16:
                return buf_line & 1;
        default:
                return 0;
@@ -1770,7 +1801,7 @@ typedef struct { u16 __; u8 _; } __packed x24;
                                pos[7] = (chr & (0x01 << 0) ? fg : bg); \
                        } \
        \
-                       pos += (tpg->hflip ? -8 : 8) / hdiv;    \
+                       pos += (tpg->hflip ? -8 : 8) / (int)hdiv;       \
                }       \
        }       \
 } while (0)
@@ -2038,8 +2069,12 @@ void tpg_log_status(struct tpg_data *tpg)
                        tpg->compose.left, tpg->compose.top);
        pr_info("tpg colorspace: %d\n", tpg->colorspace);
        pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
-       pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
-       pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc);
+       if (tpg->color_enc == TGP_COLOR_ENC_HSV)
+               pr_info("tpg HSV encoding: %d/%d\n",
+                       tpg->hsv_enc, tpg->real_hsv_enc);
+       else if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
+               pr_info("tpg Y'CbCr encoding: %d/%d\n",
+                       tpg->ycbcr_enc, tpg->real_ycbcr_enc);
        pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
        pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
 }
index 5653e8eebe2b1cd564332100be923012c0d9b1bc..975ff5669f729ffa7b264fa48ece8c131f24ba30 100644 (file)
@@ -356,6 +356,8 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
                        vb->planes[plane].length = plane_sizes[plane];
                        vb->planes[plane].min_length = plane_sizes[plane];
                }
+               call_void_bufop(q, init_buffer, vb);
+
                q->bufs[vb->index] = vb;
 
                /* Allocate video buffer memory for the MMAP type */
@@ -497,8 +499,9 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
                        pr_info("     buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
                                vb->cnt_buf_init, vb->cnt_buf_cleanup,
                                vb->cnt_buf_prepare, vb->cnt_buf_finish);
-                       pr_info("     buf_queue: %u buf_done: %u\n",
-                               vb->cnt_buf_queue, vb->cnt_buf_done);
+                       pr_info("     buf_queue: %u buf_done: %u buf_request_complete: %u\n",
+                               vb->cnt_buf_queue, vb->cnt_buf_done,
+                               vb->cnt_buf_request_complete);
                        pr_info("     alloc: %u put: %u prepare: %u finish: %u mmap: %u\n",
                                vb->cnt_mem_alloc, vb->cnt_mem_put,
                                vb->cnt_mem_prepare, vb->cnt_mem_finish,
@@ -661,6 +664,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 {
        unsigned int num_buffers, allocated_buffers, num_planes = 0;
        unsigned plane_sizes[VB2_MAX_PLANES] = { };
+       unsigned int i;
        int ret;
 
        if (q->streaming) {
@@ -682,7 +686,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
                }
 
                /*
-                * Call queue_cancel to clean up any buffers in the PREPARED or
+                * Call queue_cancel to clean up any buffers in the
                 * QUEUED state which is possible if buffers were prepared or
                 * queued without ever calling STREAMON.
                 */
@@ -718,6 +722,14 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
        if (ret)
                return ret;
 
+       /* Check that driver has set sane values */
+       if (WARN_ON(!num_planes))
+               return -EINVAL;
+
+       for (i = 0; i < num_planes; i++)
+               if (WARN_ON(!plane_sizes[i]))
+                       return -EINVAL;
+
        /* Finally, allocate buffers and video memory */
        allocated_buffers =
                __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
@@ -921,6 +933,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
                /* sync buffers */
                for (plane = 0; plane < vb->num_planes; ++plane)
                        call_void_memop(vb, finish, vb->planes[plane].mem_priv);
+               vb->synced = false;
        }
 
        spin_lock_irqsave(&q->done_lock, flags);
@@ -933,6 +946,14 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
                vb->state = state;
        }
        atomic_dec(&q->owned_by_drv_count);
+
+       if (vb->req_obj.req) {
+               /* This is not supported at the moment */
+               WARN_ON(state == VB2_BUF_STATE_REQUEUEING);
+               media_request_object_unbind(&vb->req_obj);
+               media_request_object_put(&vb->req_obj);
+       }
+
        spin_unlock_irqrestore(&q->done_lock, flags);
 
        trace_vb2_buf_done(q, vb);
@@ -967,20 +988,19 @@ EXPORT_SYMBOL_GPL(vb2_discard_done);
 /*
  * __prepare_mmap() - prepare an MMAP buffer
  */
-static int __prepare_mmap(struct vb2_buffer *vb, const void *pb)
+static int __prepare_mmap(struct vb2_buffer *vb)
 {
        int ret = 0;
 
-       if (pb)
-               ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
-                                vb, pb, vb->planes);
+       ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+                        vb, vb->planes);
        return ret ? ret : call_vb_qop(vb, buf_prepare, vb);
 }
 
 /*
  * __prepare_userptr() - prepare a USERPTR buffer
  */
-static int __prepare_userptr(struct vb2_buffer *vb, const void *pb)
+static int __prepare_userptr(struct vb2_buffer *vb)
 {
        struct vb2_plane planes[VB2_MAX_PLANES];
        struct vb2_queue *q = vb->vb2_queue;
@@ -991,12 +1011,10 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb)
 
        memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
        /* Copy relevant information provided by the userspace */
-       if (pb) {
-               ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
-                                vb, pb, planes);
-               if (ret)
-                       return ret;
-       }
+       ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+                        vb, planes);
+       if (ret)
+               return ret;
 
        for (plane = 0; plane < vb->num_planes; ++plane) {
                /* Skip the plane if already verified */
@@ -1096,7 +1114,7 @@ err:
 /*
  * __prepare_dmabuf() - prepare a DMABUF buffer
  */
-static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
+static int __prepare_dmabuf(struct vb2_buffer *vb)
 {
        struct vb2_plane planes[VB2_MAX_PLANES];
        struct vb2_queue *q = vb->vb2_queue;
@@ -1107,12 +1125,10 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
 
        memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
        /* Copy relevant information provided by the userspace */
-       if (pb) {
-               ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
-                                vb, pb, planes);
-               if (ret)
-                       return ret;
-       }
+       ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
+                        vb, planes);
+       if (ret)
+               return ret;
 
        for (plane = 0; plane < vb->num_planes; ++plane) {
                struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
@@ -1241,9 +1257,10 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
        call_void_vb_qop(vb, buf_queue, vb);
 }
 
-static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
+static int __buf_prepare(struct vb2_buffer *vb)
 {
        struct vb2_queue *q = vb->vb2_queue;
+       enum vb2_buffer_state orig_state = vb->state;
        unsigned int plane;
        int ret;
 
@@ -1252,26 +1269,31 @@ static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
                return -EIO;
        }
 
+       if (vb->prepared)
+               return 0;
+       WARN_ON(vb->synced);
+
        vb->state = VB2_BUF_STATE_PREPARING;
 
        switch (q->memory) {
        case VB2_MEMORY_MMAP:
-               ret = __prepare_mmap(vb, pb);
+               ret = __prepare_mmap(vb);
                break;
        case VB2_MEMORY_USERPTR:
-               ret = __prepare_userptr(vb, pb);
+               ret = __prepare_userptr(vb);
                break;
        case VB2_MEMORY_DMABUF:
-               ret = __prepare_dmabuf(vb, pb);
+               ret = __prepare_dmabuf(vb);
                break;
        default:
                WARN(1, "Invalid queue type\n");
                ret = -EINVAL;
+               break;
        }
 
        if (ret) {
                dprintk(1, "buffer preparation failed: %d\n", ret);
-               vb->state = VB2_BUF_STATE_DEQUEUED;
+               vb->state = orig_state;
                return ret;
        }
 
@@ -1279,11 +1301,98 @@ static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
        for (plane = 0; plane < vb->num_planes; ++plane)
                call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
 
-       vb->state = VB2_BUF_STATE_PREPARED;
+       vb->synced = true;
+       vb->prepared = true;
+       vb->state = orig_state;
 
        return 0;
 }
 
+static int vb2_req_prepare(struct media_request_object *obj)
+{
+       struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+       int ret;
+
+       if (WARN_ON(vb->state != VB2_BUF_STATE_IN_REQUEST))
+               return -EINVAL;
+
+       mutex_lock(vb->vb2_queue->lock);
+       ret = __buf_prepare(vb);
+       mutex_unlock(vb->vb2_queue->lock);
+       return ret;
+}
+
+static void __vb2_dqbuf(struct vb2_buffer *vb);
+
+static void vb2_req_unprepare(struct media_request_object *obj)
+{
+       struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+       mutex_lock(vb->vb2_queue->lock);
+       __vb2_dqbuf(vb);
+       vb->state = VB2_BUF_STATE_IN_REQUEST;
+       mutex_unlock(vb->vb2_queue->lock);
+       WARN_ON(!vb->req_obj.req);
+}
+
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
+                 struct media_request *req);
+
+static void vb2_req_queue(struct media_request_object *obj)
+{
+       struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+       mutex_lock(vb->vb2_queue->lock);
+       vb2_core_qbuf(vb->vb2_queue, vb->index, NULL, NULL);
+       mutex_unlock(vb->vb2_queue->lock);
+}
+
+static void vb2_req_unbind(struct media_request_object *obj)
+{
+       struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+       if (vb->state == VB2_BUF_STATE_IN_REQUEST)
+               call_void_bufop(vb->vb2_queue, init_buffer, vb);
+}
+
+static void vb2_req_release(struct media_request_object *obj)
+{
+       struct vb2_buffer *vb = container_of(obj, struct vb2_buffer, req_obj);
+
+       if (vb->state == VB2_BUF_STATE_IN_REQUEST)
+               vb->state = VB2_BUF_STATE_DEQUEUED;
+}
+
+static const struct media_request_object_ops vb2_core_req_ops = {
+       .prepare = vb2_req_prepare,
+       .unprepare = vb2_req_unprepare,
+       .queue = vb2_req_queue,
+       .unbind = vb2_req_unbind,
+       .release = vb2_req_release,
+};
+
+bool vb2_request_object_is_buffer(struct media_request_object *obj)
+{
+       return obj->ops == &vb2_core_req_ops;
+}
+EXPORT_SYMBOL_GPL(vb2_request_object_is_buffer);
+
+unsigned int vb2_request_buffer_cnt(struct media_request *req)
+{
+       struct media_request_object *obj;
+       unsigned long flags;
+       unsigned int buffer_cnt = 0;
+
+       spin_lock_irqsave(&req->lock, flags);
+       list_for_each_entry(obj, &req->objects, list)
+               if (vb2_request_object_is_buffer(obj))
+                       buffer_cnt++;
+       spin_unlock_irqrestore(&req->lock, flags);
+
+       return buffer_cnt;
+}
+EXPORT_SYMBOL_GPL(vb2_request_buffer_cnt);
+
 int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
 {
        struct vb2_buffer *vb;
@@ -1295,8 +1404,12 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
                        vb->state);
                return -EINVAL;
        }
+       if (vb->prepared) {
+               dprintk(1, "buffer already prepared\n");
+               return -EINVAL;
+       }
 
-       ret = __buf_prepare(vb, pb);
+       ret = __buf_prepare(vb);
        if (ret)
                return ret;
 
@@ -1305,7 +1418,7 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
 
        dprintk(2, "prepare of buffer %d succeeded\n", vb->index);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
 
@@ -1372,7 +1485,8 @@ static int vb2_start_streaming(struct vb2_queue *q)
        return ret;
 }
 
-int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
+                 struct media_request *req)
 {
        struct vb2_buffer *vb;
        int ret;
@@ -1384,13 +1498,57 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
 
        vb = q->bufs[index];
 
-       switch (vb->state) {
-       case VB2_BUF_STATE_DEQUEUED:
-               ret = __buf_prepare(vb, pb);
+       if ((req && q->uses_qbuf) ||
+           (!req && vb->state != VB2_BUF_STATE_IN_REQUEST &&
+            q->uses_requests)) {
+               dprintk(1, "queue in wrong mode (qbuf vs requests)\n");
+               return -EBUSY;
+       }
+
+       if (req) {
+               int ret;
+
+               q->uses_requests = 1;
+               if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+                       dprintk(1, "buffer %d not in dequeued state\n",
+                               vb->index);
+                       return -EINVAL;
+               }
+
+               media_request_object_init(&vb->req_obj);
+
+               /* Make sure the request is in a safe state for updating. */
+               ret = media_request_lock_for_update(req);
                if (ret)
                        return ret;
-               break;
-       case VB2_BUF_STATE_PREPARED:
+               ret = media_request_object_bind(req, &vb2_core_req_ops,
+                                               q, true, &vb->req_obj);
+               media_request_unlock_for_update(req);
+               if (ret)
+                       return ret;
+
+               vb->state = VB2_BUF_STATE_IN_REQUEST;
+               /* Fill buffer information for the userspace */
+               if (pb) {
+                       call_void_bufop(q, copy_timestamp, vb, pb);
+                       call_void_bufop(q, fill_user_buffer, vb, pb);
+               }
+
+               dprintk(2, "qbuf of buffer %d succeeded\n", vb->index);
+               return 0;
+       }
+
+       if (vb->state != VB2_BUF_STATE_IN_REQUEST)
+               q->uses_qbuf = 1;
+
+       switch (vb->state) {
+       case VB2_BUF_STATE_DEQUEUED:
+       case VB2_BUF_STATE_IN_REQUEST:
+               if (!vb->prepared) {
+                       ret = __buf_prepare(vb);
+                       if (ret)
+                               return ret;
+               }
                break;
        case VB2_BUF_STATE_PREPARING:
                dprintk(1, "buffer still being prepared\n");
@@ -1591,6 +1749,11 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
                        call_void_memop(vb, unmap_dmabuf, vb->planes[i].mem_priv);
                        vb->planes[i].dbuf_mapped = 0;
                }
+       if (vb->req_obj.req) {
+               media_request_object_unbind(&vb->req_obj);
+               media_request_object_put(&vb->req_obj);
+       }
+       call_void_bufop(q, init_buffer, vb);
 }
 
 int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
@@ -1616,6 +1779,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
        }
 
        call_void_vb_qop(vb, buf_finish, vb);
+       vb->prepared = false;
 
        if (pindex)
                *pindex = vb->index;
@@ -1679,6 +1843,8 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
        q->start_streaming_called = 0;
        q->queued_count = 0;
        q->error = 0;
+       q->uses_requests = 0;
+       q->uses_qbuf = 0;
 
        /*
         * Remove all buffers from videobuf's list...
@@ -1703,19 +1869,38 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
         */
        for (i = 0; i < q->num_buffers; ++i) {
                struct vb2_buffer *vb = q->bufs[i];
+               struct media_request *req = vb->req_obj.req;
+
+               /*
+                * If a request is associated with this buffer, then
+                * call buf_request_cancel() to give the driver to complete()
+                * related request objects. Otherwise those objects would
+                * never complete.
+                */
+               if (req) {
+                       enum media_request_state state;
+                       unsigned long flags;
+
+                       spin_lock_irqsave(&req->lock, flags);
+                       state = req->state;
+                       spin_unlock_irqrestore(&req->lock, flags);
 
-               if (vb->state == VB2_BUF_STATE_PREPARED ||
-                   vb->state == VB2_BUF_STATE_QUEUED) {
+                       if (state == MEDIA_REQUEST_STATE_QUEUED)
+                               call_void_vb_qop(vb, buf_request_complete, vb);
+               }
+
+               if (vb->synced) {
                        unsigned int plane;
 
                        for (plane = 0; plane < vb->num_planes; ++plane)
                                call_void_memop(vb, finish,
                                                vb->planes[plane].mem_priv);
+                       vb->synced = false;
                }
 
-               if (vb->state != VB2_BUF_STATE_DEQUEUED) {
-                       vb->state = VB2_BUF_STATE_PREPARED;
+               if (vb->prepared) {
                        call_void_vb_qop(vb, buf_finish, vb);
+                       vb->prepared = false;
                }
                __vb2_dqbuf(vb);
        }
@@ -2272,7 +2457,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
                 * Queue all buffers.
                 */
                for (i = 0; i < q->num_buffers; i++) {
-                       ret = vb2_core_qbuf(q, i, NULL);
+                       ret = vb2_core_qbuf(q, i, NULL, NULL);
                        if (ret)
                                goto err_reqbufs;
                        fileio->bufs[i].queued = 1;
@@ -2451,7 +2636,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
 
                if (copy_timestamp)
                        b->timestamp = ktime_get_ns();
-               ret = vb2_core_qbuf(q, index, NULL);
+               ret = vb2_core_qbuf(q, index, NULL, NULL);
                dprintk(5, "vb2_dbuf result: %d\n", ret);
                if (ret)
                        return ret;
@@ -2554,7 +2739,7 @@ static int vb2_thread(void *data)
                if (copy_timestamp)
                        vb->timestamp = ktime_get_ns();
                if (!threadio->stop)
-                       ret = vb2_core_qbuf(q, vb->index, NULL);
+                       ret = vb2_core_qbuf(q, vb->index, NULL, NULL);
                call_void_qop(q, wait_prepare, q);
                if (ret || threadio->stop)
                        break;
index 886a2d8d5c6c424790ecc13874e9ba4949c1161a..a17033ab2c2290e5dca5c9ea80849f9de918e290 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kthread.h>
 
 #include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-common.h>
@@ -40,10 +41,12 @@ module_param(debug, int, 0644);
                        pr_info("vb2-v4l2: %s: " fmt, __func__, ## arg); \
        } while (0)
 
-/* Flags that are set by the vb2 core */
+/* Flags that are set by us */
 #define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
                                 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
                                 V4L2_BUF_FLAG_PREPARED | \
+                                V4L2_BUF_FLAG_IN_REQUEST | \
+                                V4L2_BUF_FLAG_REQUEST_FD | \
                                 V4L2_BUF_FLAG_TIMESTAMP_MASK)
 /* Output buffer flags that should be passed on to the driver */
 #define V4L2_BUFFER_OUT_FLAGS  (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
@@ -118,6 +121,16 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        return 0;
 }
 
+/*
+ * __init_v4l2_vb2_buffer() - initialize the v4l2_vb2_buffer struct
+ */
+static void __init_v4l2_vb2_buffer(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+       vbuf->request_fd = -1;
+}
+
 static void __copy_timestamp(struct vb2_buffer *vb, const void *pb)
 {
        const struct v4l2_buffer *b = pb;
@@ -154,9 +167,181 @@ static void vb2_warn_zero_bytesused(struct vb2_buffer *vb)
                pr_warn("use the actual size instead.\n");
 }
 
-static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
-                                   const char *opname)
+static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
 {
+       struct vb2_queue *q = vb->vb2_queue;
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct vb2_plane *planes = vbuf->planes;
+       unsigned int plane;
+       int ret;
+
+       ret = __verify_length(vb, b);
+       if (ret < 0) {
+               dprintk(1, "plane parameters verification failed: %d\n", ret);
+               return ret;
+       }
+       if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) {
+               /*
+                * If the format's field is ALTERNATE, then the buffer's field
+                * should be either TOP or BOTTOM, not ALTERNATE since that
+                * makes no sense. The driver has to know whether the
+                * buffer represents a top or a bottom field in order to
+                * program any DMA correctly. Using ALTERNATE is wrong, since
+                * that just says that it is either a top or a bottom field,
+                * but not which of the two it is.
+                */
+               dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n");
+               return -EINVAL;
+       }
+       vbuf->sequence = 0;
+       vbuf->request_fd = -1;
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+               switch (b->memory) {
+               case VB2_MEMORY_USERPTR:
+                       for (plane = 0; plane < vb->num_planes; ++plane) {
+                               planes[plane].m.userptr =
+                                       b->m.planes[plane].m.userptr;
+                               planes[plane].length =
+                                       b->m.planes[plane].length;
+                       }
+                       break;
+               case VB2_MEMORY_DMABUF:
+                       for (plane = 0; plane < vb->num_planes; ++plane) {
+                               planes[plane].m.fd =
+                                       b->m.planes[plane].m.fd;
+                               planes[plane].length =
+                                       b->m.planes[plane].length;
+                       }
+                       break;
+               default:
+                       for (plane = 0; plane < vb->num_planes; ++plane) {
+                               planes[plane].m.offset =
+                                       vb->planes[plane].m.offset;
+                               planes[plane].length =
+                                       vb->planes[plane].length;
+                       }
+                       break;
+               }
+
+               /* Fill in driver-provided information for OUTPUT types */
+               if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+                       /*
+                        * Will have to go up to b->length when API starts
+                        * accepting variable number of planes.
+                        *
+                        * If bytesused == 0 for the output buffer, then fall
+                        * back to the full buffer size. In that case
+                        * userspace clearly never bothered to set it and
+                        * it's a safe assumption that they really meant to
+                        * use the full plane sizes.
+                        *
+                        * Some drivers, e.g. old codec drivers, use bytesused == 0
+                        * as a way to indicate that streaming is finished.
+                        * In that case, the driver should use the
+                        * allow_zero_bytesused flag to keep old userspace
+                        * applications working.
+                        */
+                       for (plane = 0; plane < vb->num_planes; ++plane) {
+                               struct vb2_plane *pdst = &planes[plane];
+                               struct v4l2_plane *psrc = &b->m.planes[plane];
+
+                               if (psrc->bytesused == 0)
+                                       vb2_warn_zero_bytesused(vb);
+
+                               if (vb->vb2_queue->allow_zero_bytesused)
+                                       pdst->bytesused = psrc->bytesused;
+                               else
+                                       pdst->bytesused = psrc->bytesused ?
+                                               psrc->bytesused : pdst->length;
+                               pdst->data_offset = psrc->data_offset;
+                       }
+               }
+       } else {
+               /*
+                * Single-planar buffers do not use planes array,
+                * so fill in relevant v4l2_buffer struct fields instead.
+                * In videobuf we use our internal V4l2_planes struct for
+                * single-planar buffers as well, for simplicity.
+                *
+                * If bytesused == 0 for the output buffer, then fall back
+                * to the full buffer size as that's a sensible default.
+                *
+                * Some drivers, e.g. old codec drivers, use bytesused == 0 as
+                * a way to indicate that streaming is finished. In that case,
+                * the driver should use the allow_zero_bytesused flag to keep
+                * old userspace applications working.
+                */
+               switch (b->memory) {
+               case VB2_MEMORY_USERPTR:
+                       planes[0].m.userptr = b->m.userptr;
+                       planes[0].length = b->length;
+                       break;
+               case VB2_MEMORY_DMABUF:
+                       planes[0].m.fd = b->m.fd;
+                       planes[0].length = b->length;
+                       break;
+               default:
+                       planes[0].m.offset = vb->planes[0].m.offset;
+                       planes[0].length = vb->planes[0].length;
+                       break;
+               }
+
+               planes[0].data_offset = 0;
+               if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+                       if (b->bytesused == 0)
+                               vb2_warn_zero_bytesused(vb);
+
+                       if (vb->vb2_queue->allow_zero_bytesused)
+                               planes[0].bytesused = b->bytesused;
+                       else
+                               planes[0].bytesused = b->bytesused ?
+                                       b->bytesused : planes[0].length;
+               } else
+                       planes[0].bytesused = 0;
+
+       }
+
+       /* Zero flags that we handle */
+       vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
+       if (!vb->vb2_queue->copy_timestamp || !V4L2_TYPE_IS_OUTPUT(b->type)) {
+               /*
+                * Non-COPY timestamps and non-OUTPUT queues will get
+                * their timestamp and timestamp source flags from the
+                * queue.
+                */
+               vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       }
+
+       if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+               /*
+                * For output buffers mask out the timecode flag:
+                * this will be handled later in vb2_qbuf().
+                * The 'field' is valid metadata for this output buffer
+                * and so that needs to be copied here.
+                */
+               vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE;
+               vbuf->field = b->field;
+       } else {
+               /* Zero any output buffer flags as this is a capture buffer */
+               vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
+               /* Zero last flag, this is a signal from driver to userspace */
+               vbuf->flags &= ~V4L2_BUF_FLAG_LAST;
+       }
+
+       return 0;
+}
+
+static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
+                                   struct v4l2_buffer *b,
+                                   const char *opname,
+                                   struct media_request **p_req)
+{
+       struct media_request *req;
+       struct vb2_v4l2_buffer *vbuf;
+       struct vb2_buffer *vb;
+       int ret;
+
        if (b->type != q->type) {
                dprintk(1, "%s: invalid buffer type\n", opname);
                return -EINVAL;
@@ -178,7 +363,82 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
                return -EINVAL;
        }
 
-       return __verify_planes_array(q->bufs[b->index], b);
+       vb = q->bufs[b->index];
+       vbuf = to_vb2_v4l2_buffer(vb);
+       ret = __verify_planes_array(vb, b);
+       if (ret)
+               return ret;
+
+       if (!vb->prepared) {
+               /* Copy relevant information provided by the userspace */
+               memset(vbuf->planes, 0,
+                      sizeof(vbuf->planes[0]) * vb->num_planes);
+               ret = vb2_fill_vb2_v4l2_buffer(vb, b);
+               if (ret)
+                       return ret;
+       }
+
+       if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) {
+               if (q->uses_requests) {
+                       dprintk(1, "%s: queue uses requests\n", opname);
+                       return -EBUSY;
+               }
+               return 0;
+       } else if (!q->supports_requests) {
+               dprintk(1, "%s: queue does not support requests\n", opname);
+               return -EACCES;
+       } else if (q->uses_qbuf) {
+               dprintk(1, "%s: queue does not use requests\n", opname);
+               return -EBUSY;
+       }
+
+       /*
+        * For proper locking when queueing a request you need to be able
+        * to lock access to the vb2 queue, so check that there is a lock
+        * that we can use. In addition p_req must be non-NULL.
+        */
+       if (WARN_ON(!q->lock || !p_req))
+               return -EINVAL;
+
+       /*
+        * Make sure this op is implemented by the driver. It's easy to forget
+        * this callback, but is it important when canceling a buffer in a
+        * queued request.
+        */
+       if (WARN_ON(!q->ops->buf_request_complete))
+               return -EINVAL;
+
+       if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+               dprintk(1, "%s: buffer is not in dequeued state\n", opname);
+               return -EINVAL;
+       }
+
+       if (b->request_fd < 0) {
+               dprintk(1, "%s: request_fd < 0\n", opname);
+               return -EINVAL;
+       }
+
+       req = media_request_get_by_fd(mdev, b->request_fd);
+       if (IS_ERR(req)) {
+               dprintk(1, "%s: invalid request_fd\n", opname);
+               return PTR_ERR(req);
+       }
+
+       /*
+        * Early sanity check. This is checked again when the buffer
+        * is bound to the request in vb2_core_qbuf().
+        */
+       if (req->state != MEDIA_REQUEST_STATE_IDLE &&
+           req->state != MEDIA_REQUEST_STATE_UPDATING) {
+               dprintk(1, "%s: request is not idle\n", opname);
+               media_request_put(req);
+               return -EBUSY;
+       }
+
+       *p_req = req;
+       vbuf->request_fd = b->request_fd;
+
+       return 0;
 }
 
 /*
@@ -204,7 +464,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
        b->timecode = vbuf->timecode;
        b->sequence = vbuf->sequence;
        b->reserved2 = 0;
-       b->reserved = 0;
+       b->request_fd = 0;
 
        if (q->is_multiplanar) {
                /*
@@ -261,15 +521,15 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
        case VB2_BUF_STATE_ACTIVE:
                b->flags |= V4L2_BUF_FLAG_QUEUED;
                break;
+       case VB2_BUF_STATE_IN_REQUEST:
+               b->flags |= V4L2_BUF_FLAG_IN_REQUEST;
+               break;
        case VB2_BUF_STATE_ERROR:
                b->flags |= V4L2_BUF_FLAG_ERROR;
                /* fall through */
        case VB2_BUF_STATE_DONE:
                b->flags |= V4L2_BUF_FLAG_DONE;
                break;
-       case VB2_BUF_STATE_PREPARED:
-               b->flags |= V4L2_BUF_FLAG_PREPARED;
-               break;
        case VB2_BUF_STATE_PREPARING:
        case VB2_BUF_STATE_DEQUEUED:
        case VB2_BUF_STATE_REQUEUEING:
@@ -277,8 +537,17 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
                break;
        }
 
+       if ((vb->state == VB2_BUF_STATE_DEQUEUED ||
+            vb->state == VB2_BUF_STATE_IN_REQUEST) &&
+           vb->synced && vb->prepared)
+               b->flags |= V4L2_BUF_FLAG_PREPARED;
+
        if (vb2_buffer_in_use(q, vb))
                b->flags |= V4L2_BUF_FLAG_MAPPED;
+       if (vbuf->request_fd >= 0) {
+               b->flags |= V4L2_BUF_FLAG_REQUEST_FD;
+               b->request_fd = vbuf->request_fd;
+       }
 
        if (!q->is_output &&
                b->flags & V4L2_BUF_FLAG_DONE &&
@@ -291,158 +560,28 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
  * v4l2_buffer by the userspace. It also verifies that struct
  * v4l2_buffer has a valid number of planes.
  */
-static int __fill_vb2_buffer(struct vb2_buffer *vb,
-               const void *pb, struct vb2_plane *planes)
+static int __fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes)
 {
-       struct vb2_queue *q = vb->vb2_queue;
-       const struct v4l2_buffer *b = pb;
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        unsigned int plane;
-       int ret;
-
-       ret = __verify_length(vb, b);
-       if (ret < 0) {
-               dprintk(1, "plane parameters verification failed: %d\n", ret);
-               return ret;
-       }
-       if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) {
-               /*
-                * If the format's field is ALTERNATE, then the buffer's field
-                * should be either TOP or BOTTOM, not ALTERNATE since that
-                * makes no sense. The driver has to know whether the
-                * buffer represents a top or a bottom field in order to
-                * program any DMA correctly. Using ALTERNATE is wrong, since
-                * that just says that it is either a top or a bottom field,
-                * but not which of the two it is.
-                */
-               dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n");
-               return -EINVAL;
-       }
-       vb->timestamp = 0;
-       vbuf->sequence = 0;
 
-       if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
-               if (b->memory == VB2_MEMORY_USERPTR) {
-                       for (plane = 0; plane < vb->num_planes; ++plane) {
-                               planes[plane].m.userptr =
-                                       b->m.planes[plane].m.userptr;
-                               planes[plane].length =
-                                       b->m.planes[plane].length;
-                       }
-               }
-               if (b->memory == VB2_MEMORY_DMABUF) {
-                       for (plane = 0; plane < vb->num_planes; ++plane) {
-                               planes[plane].m.fd =
-                                       b->m.planes[plane].m.fd;
-                               planes[plane].length =
-                                       b->m.planes[plane].length;
-                       }
-               }
-
-               /* Fill in driver-provided information for OUTPUT types */
-               if (V4L2_TYPE_IS_OUTPUT(b->type)) {
-                       /*
-                        * Will have to go up to b->length when API starts
-                        * accepting variable number of planes.
-                        *
-                        * If bytesused == 0 for the output buffer, then fall
-                        * back to the full buffer size. In that case
-                        * userspace clearly never bothered to set it and
-                        * it's a safe assumption that they really meant to
-                        * use the full plane sizes.
-                        *
-                        * Some drivers, e.g. old codec drivers, use bytesused == 0
-                        * as a way to indicate that streaming is finished.
-                        * In that case, the driver should use the
-                        * allow_zero_bytesused flag to keep old userspace
-                        * applications working.
-                        */
-                       for (plane = 0; plane < vb->num_planes; ++plane) {
-                               struct vb2_plane *pdst = &planes[plane];
-                               struct v4l2_plane *psrc = &b->m.planes[plane];
-
-                               if (psrc->bytesused == 0)
-                                       vb2_warn_zero_bytesused(vb);
-
-                               if (vb->vb2_queue->allow_zero_bytesused)
-                                       pdst->bytesused = psrc->bytesused;
-                               else
-                                       pdst->bytesused = psrc->bytesused ?
-                                               psrc->bytesused : pdst->length;
-                               pdst->data_offset = psrc->data_offset;
-                       }
-               }
-       } else {
-               /*
-                * Single-planar buffers do not use planes array,
-                * so fill in relevant v4l2_buffer struct fields instead.
-                * In videobuf we use our internal V4l2_planes struct for
-                * single-planar buffers as well, for simplicity.
-                *
-                * If bytesused == 0 for the output buffer, then fall back
-                * to the full buffer size as that's a sensible default.
-                *
-                * Some drivers, e.g. old codec drivers, use bytesused == 0 as
-                * a way to indicate that streaming is finished. In that case,
-                * the driver should use the allow_zero_bytesused flag to keep
-                * old userspace applications working.
-                */
-               if (b->memory == VB2_MEMORY_USERPTR) {
-                       planes[0].m.userptr = b->m.userptr;
-                       planes[0].length = b->length;
-               }
+       if (!vb->vb2_queue->is_output || !vb->vb2_queue->copy_timestamp)
+               vb->timestamp = 0;
 
-               if (b->memory == VB2_MEMORY_DMABUF) {
-                       planes[0].m.fd = b->m.fd;
-                       planes[0].length = b->length;
+       for (plane = 0; plane < vb->num_planes; ++plane) {
+               if (vb->vb2_queue->memory != VB2_MEMORY_MMAP) {
+                       planes[plane].m = vbuf->planes[plane].m;
+                       planes[plane].length = vbuf->planes[plane].length;
                }
-
-               if (V4L2_TYPE_IS_OUTPUT(b->type)) {
-                       if (b->bytesused == 0)
-                               vb2_warn_zero_bytesused(vb);
-
-                       if (vb->vb2_queue->allow_zero_bytesused)
-                               planes[0].bytesused = b->bytesused;
-                       else
-                               planes[0].bytesused = b->bytesused ?
-                                       b->bytesused : planes[0].length;
-               } else
-                       planes[0].bytesused = 0;
-
-       }
-
-       /* Zero flags that the vb2 core handles */
-       vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
-       if (!vb->vb2_queue->copy_timestamp || !V4L2_TYPE_IS_OUTPUT(b->type)) {
-               /*
-                * Non-COPY timestamps and non-OUTPUT queues will get
-                * their timestamp and timestamp source flags from the
-                * queue.
-                */
-               vbuf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+               planes[plane].bytesused = vbuf->planes[plane].bytesused;
+               planes[plane].data_offset = vbuf->planes[plane].data_offset;
        }
-
-       if (V4L2_TYPE_IS_OUTPUT(b->type)) {
-               /*
-                * For output buffers mask out the timecode flag:
-                * this will be handled later in vb2_qbuf().
-                * The 'field' is valid metadata for this output buffer
-                * and so that needs to be copied here.
-                */
-               vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE;
-               vbuf->field = b->field;
-       } else {
-               /* Zero any output buffer flags as this is a capture buffer */
-               vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
-               /* Zero last flag, this is a signal from driver to userspace */
-               vbuf->flags &= ~V4L2_BUF_FLAG_LAST;
-       }
-
        return 0;
 }
 
 static const struct vb2_buf_ops v4l2_buf_ops = {
        .verify_planes_array    = __verify_planes_array_core,
+       .init_buffer            = __init_v4l2_vb2_buffer,
        .fill_user_buffer       = __fill_v4l2_buffer,
        .fill_vb2_buffer        = __fill_vb2_buffer,
        .copy_timestamp         = __copy_timestamp,
@@ -483,15 +622,30 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
 }
 EXPORT_SYMBOL(vb2_querybuf);
 
+static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
+{
+       *caps = 0;
+       if (q->io_modes & VB2_MMAP)
+               *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP;
+       if (q->io_modes & VB2_USERPTR)
+               *caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR;
+       if (q->io_modes & VB2_DMABUF)
+               *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF;
+       if (q->supports_requests)
+               *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
+}
+
 int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 {
        int ret = vb2_verify_memory_type(q, req->memory, req->type);
 
+       fill_buf_caps(q, &req->capabilities);
        return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count);
 }
 EXPORT_SYMBOL_GPL(vb2_reqbufs);
 
-int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
+int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
+                   struct v4l2_buffer *b)
 {
        int ret;
 
@@ -500,7 +654,10 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
                return -EBUSY;
        }
 
-       ret = vb2_queue_or_prepare_buf(q, b, "prepare_buf");
+       if (b->flags & V4L2_BUF_FLAG_REQUEST_FD)
+               return -EINVAL;
+
+       ret = vb2_queue_or_prepare_buf(q, mdev, b, "prepare_buf", NULL);
 
        return ret ? ret : vb2_core_prepare_buf(q, b->index, b);
 }
@@ -514,6 +671,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
        int ret = vb2_verify_memory_type(q, create->memory, f->type);
        unsigned i;
 
+       fill_buf_caps(q, &create->capabilities);
        create->index = q->num_buffers;
        if (create->count == 0)
                return ret != -EBUSY ? ret : 0;
@@ -560,8 +718,10 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
 }
 EXPORT_SYMBOL_GPL(vb2_create_bufs);
 
-int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
+int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev,
+            struct v4l2_buffer *b)
 {
+       struct media_request *req = NULL;
        int ret;
 
        if (vb2_fileio_is_active(q)) {
@@ -569,8 +729,13 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
                return -EBUSY;
        }
 
-       ret = vb2_queue_or_prepare_buf(q, b, "qbuf");
-       return ret ? ret : vb2_core_qbuf(q, b->index, b);
+       ret = vb2_queue_or_prepare_buf(q, mdev, b, "qbuf", &req);
+       if (ret)
+               return ret;
+       ret = vb2_core_qbuf(q, b->index, b, req);
+       if (req)
+               media_request_put(req);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(vb2_qbuf);
 
@@ -714,6 +879,7 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv,
        struct video_device *vdev = video_devdata(file);
        int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type);
 
+       fill_buf_caps(vdev->queue, &p->capabilities);
        if (res)
                return res;
        if (vb2_queue_is_busy(vdev, file))
@@ -735,6 +901,7 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv,
                        p->format.type);
 
        p->index = vdev->queue->num_buffers;
+       fill_buf_caps(vdev->queue, &p->capabilities);
        /*
         * If count == 0, then just check if memory and type are valid.
         * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0.
@@ -760,7 +927,7 @@ int vb2_ioctl_prepare_buf(struct file *file, void *priv,
 
        if (vb2_queue_is_busy(vdev, file))
                return -EBUSY;
-       return vb2_prepare_buf(vdev->queue, p);
+       return vb2_prepare_buf(vdev->queue, vdev->v4l2_dev->mdev, p);
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_prepare_buf);
 
@@ -779,7 +946,7 @@ int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 
        if (vb2_queue_is_busy(vdev, file))
                return -EBUSY;
-       return vb2_qbuf(vdev->queue, p);
+       return vb2_qbuf(vdev->queue, vdev->v4l2_dev->mdev, p);
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_qbuf);
 
@@ -961,6 +1128,57 @@ void vb2_ops_wait_finish(struct vb2_queue *vq)
 }
 EXPORT_SYMBOL_GPL(vb2_ops_wait_finish);
 
+/*
+ * Note that this function is called during validation time and
+ * thus the req_queue_mutex is held to ensure no request objects
+ * can be added or deleted while validating. So there is no need
+ * to protect the objects list.
+ */
+int vb2_request_validate(struct media_request *req)
+{
+       struct media_request_object *obj;
+       int ret = 0;
+
+       if (!vb2_request_buffer_cnt(req))
+               return -ENOENT;
+
+       list_for_each_entry(obj, &req->objects, list) {
+               if (!obj->ops->prepare)
+                       continue;
+
+               ret = obj->ops->prepare(obj);
+               if (ret)
+                       break;
+       }
+
+       if (ret) {
+               list_for_each_entry_continue_reverse(obj, &req->objects, list)
+                       if (obj->ops->unprepare)
+                               obj->ops->unprepare(obj);
+               return ret;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_request_validate);
+
+void vb2_request_queue(struct media_request *req)
+{
+       struct media_request_object *obj, *obj_safe;
+
+       /*
+        * Queue all objects. Note that buffer objects are at the end of the
+        * objects list, after all other object types. Once buffer objects
+        * are queued, the driver might delete them immediately (if the driver
+        * processes the buffer at once), so we have to use
+        * list_for_each_entry_safe() to handle the case where the object we
+        * queue is deleted.
+        */
+       list_for_each_entry_safe(obj, obj_safe, &req->objects, list)
+               if (obj->ops->queue)
+                       obj->ops->queue(obj);
+}
+EXPORT_SYMBOL_GPL(vb2_request_queue);
+
 MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
 MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
 MODULE_LICENSE("GPL");
index d548f98c7a67d48052c2a77f2c00e9ebb23f3eb1..1544e8cef564ecfda35867b9e2340b1ee2b9a375 100644 (file)
@@ -1265,6 +1265,7 @@ static const struct file_operations dvb_demux_fops = {
        .owner = THIS_MODULE,
        .read = dvb_demux_read,
        .unlocked_ioctl = dvb_demux_ioctl,
+       .compat_ioctl = dvb_demux_ioctl,
        .open = dvb_demux_open,
        .release = dvb_demux_release,
        .poll = dvb_demux_poll,
index c4e7ebfe4d2955c9d9eb8b0cd55e1302269d7f4b..961207cf09eb489317630b3edcd470fec189a1b5 100644 (file)
@@ -2422,7 +2422,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
                struct dvb_frontend_info *info = parg;
                memset(info, 0, sizeof(*info));
 
-               strcpy(info->name, fe->ops.info.name);
+               strscpy(info->name, fe->ops.info.name, sizeof(info->name));
                info->symbol_rate_min = fe->ops.info.symbol_rate_min;
                info->symbol_rate_max = fe->ops.info.symbol_rate_max;
                info->symbol_rate_tolerance = fe->ops.info.symbol_rate_tolerance;
index b811adf88afa3424d14b6584969928d2b5cdae54..6974f1731529437b5ed481f46a38ac237b5926c0 100644 (file)
@@ -146,8 +146,7 @@ static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb)
        dprintk(3, "[%s]\n", ctx->name);
 }
 
-static int _fill_vb2_buffer(struct vb2_buffer *vb,
-                           const void *pb, struct vb2_plane *planes)
+static int _fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes)
 {
        struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 
@@ -194,7 +193,7 @@ int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
        spin_lock_init(&ctx->slock);
        INIT_LIST_HEAD(&ctx->dvb_q);
 
-       strlcpy(ctx->name, name, DVB_VB2_NAME_MAX);
+       strscpy(ctx->name, name, DVB_VB2_NAME_MAX);
        ctx->nonblocking = nonblocking;
        ctx->state = DVB_VB2_STATE_INIT;
 
@@ -385,7 +384,7 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
 {
        int ret;
 
-       ret = vb2_core_qbuf(&ctx->vb_q, b->index, b);
+       ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL);
        if (ret) {
                dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
                        b->index, ret);
index 3c87785703310fb97f342b1e42279b33f466b80f..b7171bf094fbb0d92a1006551be1115da4d87a99 100644 (file)
@@ -621,7 +621,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
        unsigned demux_pad = 0;
        unsigned dvr_pad = 0;
        unsigned ntuner = 0, ndemod = 0;
-       int ret;
+       int ret, pad_source, pad_sink;
        static const char *connector_name = "Television";
 
        if (!mdev)
@@ -681,7 +681,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
                if (ret)
                        return ret;
 
-               if (!ntuner)
+               if (!ntuner) {
                        ret = media_create_pad_links(mdev,
                                                     MEDIA_ENT_F_CONN_RF,
                                                     conn, 0,
@@ -689,22 +689,31 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
                                                     demod, 0,
                                                     MEDIA_LNK_FL_ENABLED,
                                                     false);
-               else
+               } else {
+                       pad_sink = media_get_pad_index(tuner, true,
+                                                      PAD_SIGNAL_ANALOG);
+                       if (pad_sink < 0)
+                               return -EINVAL;
                        ret = media_create_pad_links(mdev,
                                                     MEDIA_ENT_F_CONN_RF,
                                                     conn, 0,
                                                     MEDIA_ENT_F_TUNER,
-                                                    tuner, TUNER_PAD_RF_INPUT,
+                                                    tuner, pad_sink,
                                                     MEDIA_LNK_FL_ENABLED,
                                                     false);
+               }
                if (ret)
                        return ret;
        }
 
        if (ntuner && ndemod) {
+               pad_source = media_get_pad_index(tuner, true,
+                                                PAD_SIGNAL_ANALOG);
+               if (pad_source)
+                       return -EINVAL;
                ret = media_create_pad_links(mdev,
                                             MEDIA_ENT_F_TUNER,
-                                            tuner, TUNER_PAD_OUTPUT,
+                                            tuner, pad_source,
                                             MEDIA_ENT_F_DTV_DEMOD,
                                             demod, 0, MEDIA_LNK_FL_ENABLED,
                                             false);
@@ -967,9 +976,9 @@ struct i2c_client *dvb_module_probe(const char *module_name,
                return NULL;
 
        if (name)
-               strlcpy(board_info->type, name, I2C_NAME_SIZE);
+               strscpy(board_info->type, name, I2C_NAME_SIZE);
        else
-               strlcpy(board_info->type, module_name, I2C_NAME_SIZE);
+               strscpy(board_info->type, module_name, I2C_NAME_SIZE);
 
        board_info->addr = addr;
        board_info->platform_data = platform_data;
index 048285134cdf0aadde4e6df6ae635dd3a069d7ff..847da72d1256f8084c7156171f22512f36f8d812 100644 (file)
@@ -791,6 +791,16 @@ config DVB_LNBH25
          An SEC control chip.
          Say Y when you want to support this chip.
 
+config DVB_LNBH29
+       tristate "LNBH29 SEC controller"
+       depends on DVB_CORE && I2C
+       default m if !MEDIA_SUBDRV_AUTOSELECT
+       help
+         LNB power supply and control voltage
+         regulator chip with step-up converter
+         and I2C interface for STMicroelectronics LNBH29.
+         Say Y when you want to support this chip.
+
 config DVB_LNBP21
        tristate "LNBP21/LNBH24 SEC controllers"
        depends on DVB_CORE && I2C
index 779dfd027b2434d2fb89081e2e7526089239b27d..e9179162658ccbe2276f4e926dc28e9259c07256 100644 (file)
@@ -58,6 +58,7 @@ obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o
 obj-$(CONFIG_DVB_LG2160) += lg2160.o
 obj-$(CONFIG_DVB_CX24123) += cx24123.o
 obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
+obj-$(CONFIG_DVB_LNBH29) += lnbh29.o
 obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
 obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
 obj-$(CONFIG_DVB_ISL6405) += isl6405.o
index f285096a48f08d361e7bc587ca8f471e3a43b009..b2dd20ffd00251f1bd33c8a2b80be839b3869a23 100644 (file)
@@ -718,10 +718,12 @@ static int au8522_probe(struct i2c_client *client,
        v4l2_i2c_subdev_init(sd, client, &au8522_ops);
 #if defined(CONFIG_MEDIA_CONTROLLER)
 
-       state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
-       state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
-       state->pads[DEMOD_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[AU8522_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       state->pads[AU8522_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
+       state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[AU8522_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
+       state->pads[AU8522_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[AU8522_PAD_AUDIO_OUT].sig_type = PAD_SIGNAL_AUDIO;
        sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
 
        ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads),
index 2043c174475377b9542ebcf1acdffc9d88642923..68299d2705f7a69821bf414ad1662385e57797b4 100644 (file)
 #define AU8522_DIGITAL_MODE 1
 #define AU8522_SUSPEND_MODE 2
 
+enum au8522_pads {
+       AU8522_PAD_IF_INPUT,
+       AU8522_PAD_VID_OUT,
+       AU8522_PAD_AUDIO_OUT,
+       AU8522_NUM_PADS
+};
+
 struct au8522_state {
        struct i2c_client *c;
        struct i2c_adapter *i2c;
@@ -71,7 +78,7 @@ struct au8522_state {
        struct v4l2_ctrl_handler hdl;
 
 #ifdef CONFIG_MEDIA_CONTROLLER
-       struct media_pad pads[DEMOD_NUM_PADS];
+       struct media_pad pads[AU8522_NUM_PADS];
 #endif
 };
 
index e49215020a9372bb092e7acd6eb8b895c7dbee61..83dfae78579d1f5935518bef9122b2b588bbf125 100644 (file)
@@ -1087,7 +1087,7 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
        if (config->dont_use_pll)
                cx24123_repeater_mode(state, 1, 0);
 
-       strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
+       strscpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
                sizeof(state->tuner_i2c_adapter.name));
        state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
        state->tuner_i2c_adapter.algo_data = NULL;
index 4a0ce3037fd638af56da56c0c652786e1775199b..5264e873850e9d86a45a369d27f7e5c6f33d4af2 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * cxd2099.c: Driver for the Sony CXD2099AR Common Interface Controller
  *
@@ -701,4 +702,4 @@ module_i2c_driver(cxd2099_driver);
 
 MODULE_DESCRIPTION("Sony CXD2099AR Common Interface controller driver");
 MODULE_AUTHOR("Ralph Metzler");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index ec1910dec3f3fbd7e8c43e97ce40b16dd41df01b..0c101bdef01da78f252d50aa0aba6ff6e39556c4 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * cxd2099.h: Driver for the Sony CXD2099AR Common Interface Controller
  *
index 3e0d8cbd76da36e680f40661edd9a57de344a60b..0f0acf98d22679e3f2c0f85723653864d881341a 100644 (file)
@@ -540,7 +540,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config,
        pdata.attach_in_use = true;
 
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);
+       strscpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);
        board_info.addr = config->i2c_address;
        board_info.platform_data = &pdata;
        client = i2c_new_device(adapter, &board_info);
index 70119c79ac2b41900daabc678c28795cea081867..dc80a8442e7af1ef29a6017a837332b3f3313116 100644 (file)
@@ -424,7 +424,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
                                struct i2c_algorithm *algo, const char *name,
                                struct dibx000_i2c_master *mst)
 {
-       strlcpy(i2c_adap->name, name, sizeof(i2c_adap->name));
+       strscpy(i2c_adap->name, name, sizeof(i2c_adap->name));
        i2c_adap->algo = algo;
        i2c_adap->algo_data = NULL;
        i2c_set_adapdata(i2c_adap, mst);
index 9628d4067fe19c8ea64bd0f616ddd410c9e47e41..551b7d65fa668f9deee713ad9d379fef2fce7809 100644 (file)
@@ -3555,8 +3555,8 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                if (!ext_attr->has_smatx)
                        return -EIO;
                switch (uio_cfg->mode) {
-               case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
-               case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
+               case DRX_UIO_MODE_FIRMWARE_SMA: /* fall through */
+               case DRX_UIO_MODE_FIRMWARE_SAW: /* fall through */
                case DRX_UIO_MODE_READWRITE:
                        ext_attr->uio_sma_tx_mode = uio_cfg->mode;
                        break;
@@ -3579,7 +3579,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                if (!ext_attr->has_smarx)
                        return -EIO;
                switch (uio_cfg->mode) {
-               case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
+               case DRX_UIO_MODE_FIRMWARE0:    /* fall through */
                case DRX_UIO_MODE_READWRITE:
                        ext_attr->uio_sma_rx_mode = uio_cfg->mode;
                        break;
@@ -3603,7 +3603,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                if (!ext_attr->has_gpio)
                        return -EIO;
                switch (uio_cfg->mode) {
-               case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
+               case DRX_UIO_MODE_FIRMWARE0:    /* fall through */
                case DRX_UIO_MODE_READWRITE:
                        ext_attr->uio_gpio_mode = uio_cfg->mode;
                        break;
@@ -3639,7 +3639,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
                        }
                        ext_attr->uio_irqn_mode = uio_cfg->mode;
                        break;
-               case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
+               case DRX_UIO_MODE_FIRMWARE0:    /* fall through */
                default:
                        return -EINVAL;
                        break;
index 10d584ce538d71bf84729a3b2527edc27418de12..96807e1348868a0ca4a9bc4ac08d006619a19b51 100644 (file)
@@ -929,7 +929,7 @@ struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config,
        struct i2c_board_info board_info = {};
        struct lgdt330x_config config = *_config;
 
-       strlcpy(board_info.type, "lgdt330x", sizeof(board_info.type));
+       strscpy(board_info.type, "lgdt330x", sizeof(board_info.type));
        board_info.addr = demod_address;
        board_info.platform_data = &config;
        client = i2c_new_device(i2c, &board_info);
diff --git a/drivers/media/dvb-frontends/lnbh29.c b/drivers/media/dvb-frontends/lnbh29.c
new file mode 100644 (file)
index 0000000..410bae0
--- /dev/null
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Driver for LNB supply and control IC STMicroelectronics LNBH29
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include <media/dvb_frontend.h>
+#include "lnbh29.h"
+
+/**
+ * struct lnbh29_priv - LNBH29 driver private data
+ * @i2c:         Pointer to the I2C adapter structure
+ * @i2c_address: I2C address of LNBH29 chip
+ * @config:      Registers configuration
+ *               offset 0: 1st register address, always 0x01 (DATA)
+ *               offset 1: DATA register value
+ */
+struct lnbh29_priv {
+       struct i2c_adapter *i2c;
+       u8 i2c_address;
+       u8 config[2];
+};
+
+#define LNBH29_STATUS_OLF     BIT(0)
+#define LNBH29_STATUS_OTF     BIT(1)
+#define LNBH29_STATUS_VMON    BIT(2)
+#define LNBH29_STATUS_PNG     BIT(3)
+#define LNBH29_STATUS_PDO     BIT(4)
+#define LNBH29_VSEL_MASK      GENMASK(2, 0)
+#define LNBH29_VSEL_0         0x00
+/* Min: 13.188V, Typ: 13.667V, Max:14V */
+#define LNBH29_VSEL_13        0x03
+/* Min: 18.158V, Typ: 18.817V, Max:19.475V */
+#define LNBH29_VSEL_18        0x07
+
+static int lnbh29_read_vmon(struct lnbh29_priv *priv)
+{
+       u8 addr = 0x00;
+       u8 status[2];
+       int ret;
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->i2c_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &addr
+               }, {
+                       .addr = priv->i2c_address,
+                       .flags = I2C_M_RD,
+                       .len = sizeof(status),
+                       .buf = status
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret >= 0 && ret != 2)
+               ret = -EIO;
+       if (ret < 0) {
+               dev_dbg(&priv->i2c->dev, "LNBH29 I2C transfer failed (%d)\n",
+                       ret);
+               return ret;
+       }
+
+       if (status[0] & (LNBH29_STATUS_OLF | LNBH29_STATUS_VMON)) {
+               dev_err(&priv->i2c->dev,
+                       "LNBH29 voltage in failure state, status reg 0x%x\n",
+                       status[0]);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int lnbh29_set_voltage(struct dvb_frontend *fe,
+                             enum fe_sec_voltage voltage)
+{
+       struct lnbh29_priv *priv = fe->sec_priv;
+       u8 data_reg;
+       int ret;
+       struct i2c_msg msg = {
+               .addr = priv->i2c_address,
+               .flags = 0,
+               .len = sizeof(priv->config),
+               .buf = priv->config
+       };
+
+       switch (voltage) {
+       case SEC_VOLTAGE_OFF:
+               data_reg = LNBH29_VSEL_0;
+               break;
+       case SEC_VOLTAGE_13:
+               data_reg = LNBH29_VSEL_13;
+               break;
+       case SEC_VOLTAGE_18:
+               data_reg = LNBH29_VSEL_18;
+               break;
+       default:
+               return -EINVAL;
+       }
+       priv->config[1] &= ~LNBH29_VSEL_MASK;
+       priv->config[1] |= data_reg;
+
+       ret = i2c_transfer(priv->i2c, &msg, 1);
+       if (ret >= 0 && ret != 1)
+               ret = -EIO;
+       if (ret < 0) {
+               dev_err(&priv->i2c->dev, "LNBH29 I2C transfer error (%d)\n",
+                       ret);
+               return ret;
+       }
+
+       /* Soft-start time (Vout 0V to 18V) is Typ. 6ms. */
+       usleep_range(6000, 20000);
+
+       if (voltage == SEC_VOLTAGE_OFF)
+               return 0;
+
+       return lnbh29_read_vmon(priv);
+}
+
+static void lnbh29_release(struct dvb_frontend *fe)
+{
+       lnbh29_set_voltage(fe, SEC_VOLTAGE_OFF);
+       kfree(fe->sec_priv);
+       fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe,
+                                  struct lnbh29_config *cfg,
+                                  struct i2c_adapter *i2c)
+{
+       struct lnbh29_priv *priv;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return NULL;
+
+       priv->i2c_address = (cfg->i2c_address >> 1);
+       priv->i2c = i2c;
+       priv->config[0] = 0x01;
+       priv->config[1] = cfg->data_config;
+       fe->sec_priv = priv;
+
+       if (lnbh29_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+               dev_err(&i2c->dev, "no LNBH29 found at I2C addr 0x%02x\n",
+                       priv->i2c_address);
+               kfree(priv);
+               fe->sec_priv = NULL;
+               return NULL;
+       }
+
+       fe->ops.release_sec = lnbh29_release;
+       fe->ops.set_voltage = lnbh29_set_voltage;
+
+       dev_info(&i2c->dev, "LNBH29 attached at I2C addr 0x%02x\n",
+                priv->i2c_address);
+
+       return fe;
+}
+EXPORT_SYMBOL(lnbh29_attach);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("STMicroelectronics LNBH29 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/dvb-frontends/lnbh29.h b/drivers/media/dvb-frontends/lnbh29.h
new file mode 100644 (file)
index 0000000..6179921
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Driver for LNB supply and control IC STMicroelectronics LNBH29
+ *
+ * Copyright (c) 2018 Socionext Inc.
+ */
+
+#ifndef LNBH29_H
+#define LNBH29_H
+
+#include <linux/i2c.h>
+#include <linux/dvb/frontend.h>
+
+/* Using very low E.S.R. capacitors or ceramic caps */
+#define LNBH29_DATA_COMP    BIT(3)
+
+struct lnbh29_config {
+       u8 i2c_address;
+       u8 data_config;
+};
+
+#if IS_REACHABLE(CONFIG_DVB_LNBH29)
+struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe,
+                                  struct lnbh29_config *cfg,
+                                  struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe,
+                                                struct lnbh29_config *cfg,
+                                                struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
index dffd2d4bf1c8b96b0735707d449f46a6bb125033..123f2a33738b07f7da057fcd237409e62e8a24cd 100644 (file)
@@ -1284,7 +1284,7 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
        pdata.attach_in_use = true;
 
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
+       strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
        board_info.addr = cfg->i2c_addr;
        board_info.platform_data = &pdata;
        client = i2c_new_device(i2c, &board_info);
index aad07adda37dff25c605e3f1aeb1011c83b17843..03e74a729168c31e51fddf40c42d3826ba75ca05 100644 (file)
@@ -815,17 +815,20 @@ struct dvb_frontend *mt312_attach(const struct mt312_config *config,
 
        switch (state->id) {
        case ID_VP310:
-               strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
+               strscpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S",
+                       sizeof(state->frontend.ops.info.name));
                state->xtal = MT312_PLL_CLK;
                state->freq_mult = 9;
                break;
        case ID_MT312:
-               strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
+               strscpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S",
+                       sizeof(state->frontend.ops.info.name));
                state->xtal = MT312_PLL_CLK;
                state->freq_mult = 6;
                break;
        case ID_ZL10313:
-               strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
+               strscpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S",
+                       sizeof(state->frontend.ops.info.name));
                state->xtal = MT312_PLL_CLK_10_111;
                state->freq_mult = 9;
                break;
index 295f37d5f10e595a8e75a2787e1e14072e74ff1e..6191315f5970957c7f47896b03c82b96967fd7b0 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for the MaxLinear MxL5xx family of tuners/demods
  *
@@ -17,7 +18,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #include <linux/kernel.h>
@@ -739,6 +739,7 @@ static int get_frontend(struct dvb_frontend *fe,
                default:
                        break;
                }
+               /* Fall through */
        case SYS_DVBS:
                switch ((enum MXL_HYDRA_MODULATION_E)
                        reg_data[DMD_MODULATION_SCHEME_ADDR]) {
@@ -1893,4 +1894,4 @@ EXPORT_SYMBOL_GPL(mxl5xx_attach);
 
 MODULE_DESCRIPTION("MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver");
 MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index ad4c218468006d20234e87f512f36a9c3c9d3fc1..706a2f5d8f9737e20a99c2b98cd4aa6de4ff4827 100644 (file)
@@ -1,3 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Driver for the MaxLinear MxL5xx family of tuners/demods
+ *
+ * Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Marcus Metzler <mocm@metzlerbros.de>
+ *                         developed for Digital Devices GmbH
+ *
+ * based on code:
+ * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
+ * which was released under GPL V2
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
 #ifndef _MXL5XX_H_
 #define _MXL5XX_H_
 
index fd9e61e0188f95983d91f9cfa1a48378e2ac0686..1442af8dc17625a7f476b40b5c719460a9b87095 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Defines for the Maxlinear MX58x family of tuners/demods
  *
index 5001dafe1ba80032096fc7521af5f9a0827db9a6..86d5317eba7a09fc5c801401e80a8e87d47e2fd2 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
  *
index d448d9d4879c6bcc35786b724e46d91c6f2cc7ea..d6673f4fb47bad0e1b3a0b2a8d1cda9912a5de8b 100644 (file)
@@ -439,8 +439,8 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
 
        dev_dbg(&pdev->dev, "\n");
 
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, dev->vdev.name, sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, dev->vdev.name, sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
                        V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
@@ -976,7 +976,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
        dev_dbg(&pdev->dev, "index=%d type=%d\n", v->index, v->type);
 
        if (v->index == 0) {
-               strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
+               strscpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
                v->type = V4L2_TUNER_ADC;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow =   300000;
@@ -986,7 +986,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
                   V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, g_tuner)) {
                ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_tuner, v);
        } else if (v->index == 1) {
-               strlcpy(v->name, "RF: <unknown>", sizeof(v->name));
+               strscpy(v->name, "RF: <unknown>", sizeof(v->name));
                v->type = V4L2_TUNER_RF;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow =    50000000;
@@ -1133,7 +1133,7 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
        if (f->index >= dev->num_formats)
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       strscpy(f->description, formats[f->index].name, sizeof(f->description));
        f->pixelformat = formats[f->index].pixelformat;
 
        return 0;
@@ -1394,7 +1394,8 @@ static int rtl2832_sdr_probe(struct platform_device *pdev)
        case RTL2832_SDR_TUNER_E4000:
                v4l2_ctrl_handler_init(&dev->hdl, 9);
                if (subdev)
-                       v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler, NULL);
+                       v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler,
+                                             NULL, true);
                break;
        case RTL2832_SDR_TUNER_R820T:
        case RTL2832_SDR_TUNER_R828D:
@@ -1423,7 +1424,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev)
                v4l2_ctrl_handler_init(&dev->hdl, 2);
                if (subdev)
                        v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler,
-                                             NULL);
+                                             NULL, true);
                break;
        default:
                v4l2_ctrl_handler_init(&dev->hdl, 0);
index a65cdf8e8cd9a22950543d4749eb17c38d3cfac9..c63b56f7fc1419867b304c33ad63c5f69f7dd4e8 100644 (file)
@@ -912,7 +912,7 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
        state->frontend.demodulator_priv = state;
 
        /* create tuner i2c adapter */
-       strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
+       strscpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
                sizeof(state->tuner_i2c_adapter.name));
        state->tuner_i2c_adapter.algo      = &s5h1420_tuner_i2c_algo;
        state->tuner_i2c_adapter.algo_data = NULL;
index 4c86073f1a8d2921cd6d78a3e4697844eee385bb..fc2440d8af365edebc8b029e43e695f7844d2c0d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for the ST STV0910 DVB-S/S2 demodulator.
  *
@@ -1839,4 +1840,4 @@ EXPORT_SYMBOL_GPL(stv0910_attach);
 
 MODULE_DESCRIPTION("ST STV0910 multistandard frontend driver");
 MODULE_AUTHOR("Ralph and Marcus Metzler, Manfred Voelkel");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index f37171b7a2de02e09b587bb5b833d87e46d06545..24ecc6902235460c99018f39e54e9ddf456db949 100644 (file)
@@ -1,3 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Driver for the ST STV0910 DVB-S/S2 demodulator.
+ *
+ * Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
+ *                         Marcus Metzler <mocm@metzlerbros.de>
+ *                         developed for Digital Devices GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
 #ifndef _STV0910_H_
 #define _STV0910_H_
 
index f0eb915090bda6da26aa41a3be1568ed817ca89a..448c89b8cd7cca3fee422945c7f8751a58bf4b99 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * @DVB-S/DVB-S2 STMicroelectronics STV0900 register definitions
  * Author Manfred Voelkel, August 2013
index 0cf460111acbebe5b4f3b2999101dd62d573166d..d5035dac4574a0b1bbfdecf9136cd947e12deaf7 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for the ST STV6111 tuner
  *
@@ -11,7 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #include <linux/kernel.h>
@@ -687,4 +687,4 @@ EXPORT_SYMBOL_GPL(stv6111_attach);
 
 MODULE_DESCRIPTION("ST STV6111 satellite tuner driver");
 MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 5bc1228dc9bd9a8ab66e37642ee8ec9829382aff..49e821ac9954b54cd932a1915fce94368672537f 100644 (file)
@@ -1,3 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Driver for the ST STV6111 tuner
+ *
+ * Copyright (C) 2014 Digital Devices GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
 #ifndef _STV6111_H_
 #define _STV6111_H_
 
index 2ad81a438d6a509fd65fe50579dd051d40764fad..849d63dbc279b86602bfc35700b4b6dbfa1aed52 100644 (file)
@@ -781,7 +781,7 @@ static int tc90522_probe(struct i2c_client *client,
        adap->owner = THIS_MODULE;
        adap->algo = &tc90522_tuner_i2c_algo;
        adap->dev.parent = &client->dev;
-       strlcpy(adap->name, "tc90522_sub", sizeof(adap->name));
+       strscpy(adap->name, "tc90522_sub", sizeof(adap->name));
        i2c_set_adapdata(adap, state);
        ret = i2c_add_adapter(adap);
        if (ret < 0)
index 3e3e408786332f7554cfddaed447d5a61268210b..e5cd2cd414f4ea83f7dd9913727b3a12adaca2db 100644 (file)
@@ -525,7 +525,7 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
        pdata.attach_in_use = true;
 
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "ts2020", I2C_NAME_SIZE);
+       strscpy(board_info.type, "ts2020", I2C_NAME_SIZE);
        board_info.addr = config->tuner_address;
        board_info.platform_data = &pdata;
        client = i2c_new_device(i2c, &board_info);
index 84a2b25a574a3c6ad43fe780126020410f5a0da5..212f9328cea89ab9415c403f0a0a2319fa18c2aa 100644 (file)
@@ -499,7 +499,8 @@ static int zd1301_demod_probe(struct platform_device *pdev)
                goto err_kfree;
 
        /* Create I2C adapter */
-       strlcpy(dev->adapter.name, "ZyDAS ZD1301 demod", sizeof(dev->adapter.name));
+       strscpy(dev->adapter.name, "ZyDAS ZD1301 demod",
+               sizeof(dev->adapter.name));
        dev->adapter.algo = &zd1301_demod_i2c_algorithm;
        dev->adapter.algo_data = NULL;
        dev->adapter.dev.parent = pdev->dev.parent;
index 6293bd920fa613aae8f7f629688a71283ca299d2..333e4a1da13bd5f673305f082c58f22325817c23 100644 (file)
@@ -288,8 +288,9 @@ struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
        state->id = state->id & 0x0f;
        switch (state->id) {
        case ID_ZL10039:
-               strcpy(fe->ops.tuner_ops.info.name,
-                       "Zarlink ZL10039 DVB-S tuner");
+               strscpy(fe->ops.tuner_ops.info.name,
+                       "Zarlink ZL10039 DVB-S tuner",
+                       sizeof(fe->ops.tuner_ops.info.name));
                break;
        default:
                dprintk("Chip ID=%x does not match a known type\n", state->id);
index 69087ae6c1d00d347cdfc2e05c518845e7b434d5..683957885ac43650d534e6ab1633f37edc0f8fd0 100644 (file)
@@ -247,7 +247,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
                dev_err(fdtv->device, "no frontend for model type %d\n",
                        fdtv->type);
        }
-       strcpy(fi->name, name);
+       strscpy(fi->name, name, sizeof(fi->name));
 
        fdtv->fe.dvb = &fdtv->adapter;
        fdtv->fe.sec_priv = fdtv;
index 82af97430e5b36c6bb81f05703dd8c3c9c6fc547..704af210e2708081700c5360d284680c7991dab9 100644 (file)
@@ -614,6 +614,28 @@ config VIDEO_IMX274
          This is a V4L2 sensor driver for the Sony IMX274
          CMOS image sensor.
 
+config VIDEO_IMX319
+       tristate "Sony IMX319 sensor support"
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       depends on MEDIA_CAMERA_SUPPORT
+       help
+         This is a Video4Linux2 sensor driver for the Sony
+         IMX319 camera.
+
+         To compile this driver as a module, choose M here: the
+         module will be called imx319.
+
+config VIDEO_IMX355
+       tristate "Sony IMX355 sensor support"
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       depends on MEDIA_CAMERA_SUPPORT
+       help
+         This is a Video4Linux2 sensor driver for the Sony
+         IMX355 camera.
+
+         To compile this driver as a module, choose M here: the
+         module will be called imx355.
+
 config VIDEO_OV2640
        tristate "OmniVision OV2640 sensor support"
        depends on VIDEO_V4L2 && I2C
@@ -747,6 +769,7 @@ config VIDEO_OV772X
        tristate "OmniVision OV772x sensor support"
        depends on I2C && VIDEO_V4L2
        depends on MEDIA_CAMERA_SUPPORT
+       select REGMAP_SCCB
        ---help---
          This is a Video4Linux2 sensor driver for the OmniVision
          OV772x camera.
@@ -786,6 +809,7 @@ config VIDEO_OV7740
 config VIDEO_OV9650
        tristate "OmniVision OV9650/OV9652 sensor support"
        depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       select REGMAP_SCCB
        ---help---
          This is a V4L2 sensor driver for the Omnivision
          OV9650 and OV9652 camera sensors.
index a94eb03d10d4e12d278207a1484686b6131df8f6..260d4d9ec2a1c60222eee4cc5227ad76bd17331b 100644 (file)
@@ -108,5 +108,7 @@ obj-$(CONFIG_VIDEO_OV2659)  += ov2659.o
 obj-$(CONFIG_VIDEO_TC358743)   += tc358743.o
 obj-$(CONFIG_VIDEO_IMX258)     += imx258.o
 obj-$(CONFIG_VIDEO_IMX274)     += imx274.o
+obj-$(CONFIG_VIDEO_IMX319)     += imx319.o
+obj-$(CONFIG_VIDEO_IMX355)     += imx355.o
 
 obj-$(CONFIG_SDR_MAX2175) += max2175.o
index 034ebf7540070074f67dace1ff05b269252090d6..907323f0ca3b63b6b616a3264dab9b8b0f782d52 100644 (file)
@@ -317,7 +317,7 @@ static int ad5820_probe(struct i2c_client *client,
        v4l2_i2c_subdev_init(&coil->subdev, client, &ad5820_ops);
        coil->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
        coil->subdev.internal_ops = &ad5820_internal_ops;
-       strcpy(coil->subdev.name, "ad5820 focus");
+       strscpy(coil->subdev.name, "ad5820 focus", sizeof(coil->subdev.name));
 
        ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
        if (ret < 0)
index de10367d550b40ccf196c726f47d8e827a472e21..99697baad2ea09d27f9b497def2d2226bfa2fb34 100644 (file)
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * adv7180.c Analog Devices ADV7180 video decoder driver
  * Copyright (c) 2009 Intel Corporation
  * Copyright (C) 2013 Cogent Embedded, Inc.
  * Copyright (C) 2013 Renesas Solutions Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
@@ -761,7 +752,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
        struct adv7180_state *state = to_state(sd);
 
        if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
-               cfg->type = V4L2_MBUS_CSI2;
+               cfg->type = V4L2_MBUS_CSI2_DPHY;
                cfg->flags = V4L2_MBUS_CSI2_1_LANE |
                                V4L2_MBUS_CSI2_CHANNEL_0 |
                                V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
index edd25e895e5dec3cecb7de0b3afead0e85dcd54d..71714634efb08bd434daa5ab12ae3b46a101b3ca 100644 (file)
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver
  * with standard definition processor (SDP)
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
  */
 
 #include <linux/delay.h>
@@ -286,7 +282,7 @@ static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int enable)
                        goto unlock;
        }
 
-       ret = adv748x_txb_power(state, enable);
+       ret = adv748x_tx_power(&state->txb, enable);
        if (ret)
                goto unlock;
 
index 6ca88daa0ecd79dad07c16bf7686c78089f15e13..6854d898fdd1f1920755ebc05ef620e8f5ebfbb0 100644 (file)
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Driver for Analog Devices ADV748X HDMI receiver with AFE
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  *
- * 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.
- *
  * Authors:
  *     Koji Matsuoka <koji.matsuoka.xm@renesas.com>
  *     Niklas Söderlund <niklas.soderlund@ragnatech.se>
@@ -285,40 +281,23 @@ static const struct adv748x_reg_value adv748x_power_down_txb_1lane[] = {
 
        {ADV748X_PAGE_TXB, 0x31, 0x82}, /* ADI Required Write */
        {ADV748X_PAGE_TXB, 0x1e, 0x00}, /* ADI Required Write */
-       {ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 4-lane MIPI */
+       {ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 1-lane MIPI */
        {ADV748X_PAGE_TXB, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */
        {ADV748X_PAGE_TXB, 0xc1, 0x3b}, /* ADI Required Write */
 
        {ADV748X_PAGE_EOR, 0xff, 0xff}  /* End of register table */
 };
 
-int adv748x_txa_power(struct adv748x_state *state, bool on)
+int adv748x_tx_power(struct adv748x_csi2 *tx, bool on)
 {
+       struct adv748x_state *state = tx->state;
+       const struct adv748x_reg_value *reglist;
        int val;
 
-       val = txa_read(state, ADV748X_CSI_FS_AS_LS);
-       if (val < 0)
-               return val;
-
-       /*
-        * This test against BIT(6) is not documented by the datasheet, but was
-        * specified in the downstream driver.
-        * Track with a WARN_ONCE to determine if it is ever set by HW.
-        */
-       WARN_ONCE((on && val & ADV748X_CSI_FS_AS_LS_UNKNOWN),
-                       "Enabling with unknown bit set");
+       if (!is_tx_enabled(tx))
+               return 0;
 
-       if (on)
-               return adv748x_write_regs(state, adv748x_power_up_txa_4lane);
-
-       return adv748x_write_regs(state, adv748x_power_down_txa_4lane);
-}
-
-int adv748x_txb_power(struct adv748x_state *state, bool on)
-{
-       int val;
-
-       val = txb_read(state, ADV748X_CSI_FS_AS_LS);
+       val = tx_read(tx, ADV748X_CSI_FS_AS_LS);
        if (val < 0)
                return val;
 
@@ -331,9 +310,13 @@ int adv748x_txb_power(struct adv748x_state *state, bool on)
                        "Enabling with unknown bit set");
 
        if (on)
-               return adv748x_write_regs(state, adv748x_power_up_txb_1lane);
+               reglist = is_txa(tx) ? adv748x_power_up_txa_4lane :
+                                      adv748x_power_up_txb_1lane;
+       else
+               reglist = is_txa(tx) ? adv748x_power_down_txa_4lane :
+                                      adv748x_power_down_txb_1lane;
 
-       return adv748x_write_regs(state, adv748x_power_down_txb_1lane);
+       return adv748x_write_regs(state, reglist);
 }
 
 /* -----------------------------------------------------------------------------
@@ -399,8 +382,6 @@ static const struct adv748x_reg_value adv748x_init_txa_4lane[] = {
 
        {ADV748X_PAGE_IO, 0x0c, 0xe0},  /* Enable LLC_DLL & Double LLC Timing */
        {ADV748X_PAGE_IO, 0x0e, 0xdd},  /* LLC/PIX/SPI PINS TRISTATED AUD */
-       /* Outputs Enabled */
-       {ADV748X_PAGE_IO, 0x10, 0xa0},  /* Enable 4-lane CSI Tx & Pixel Port */
 
        {ADV748X_PAGE_TXA, 0x00, 0x84}, /* Enable 4-lane MIPI */
        {ADV748X_PAGE_TXA, 0x00, 0xa4}, /* Set Auto DPHY Timing */
@@ -454,10 +435,6 @@ static const struct adv748x_reg_value adv748x_init_txb_1lane[] = {
        {ADV748X_PAGE_SDP, 0x31, 0x12}, /* ADI Required Write */
        {ADV748X_PAGE_SDP, 0xe6, 0x4f},  /* V bit end pos manually in NTSC */
 
-       /* Enable 1-Lane MIPI Tx, */
-       /* enable pixel output and route SD through Pixel port */
-       {ADV748X_PAGE_IO, 0x10, 0x70},
-
        {ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 1-lane MIPI */
        {ADV748X_PAGE_TXB, 0x00, 0xa1}, /* Set Auto DPHY Timing */
        {ADV748X_PAGE_TXB, 0xd2, 0x40}, /* ADI Required Write */
@@ -482,6 +459,7 @@ static const struct adv748x_reg_value adv748x_init_txb_1lane[] = {
 static int adv748x_reset(struct adv748x_state *state)
 {
        int ret;
+       u8 regval = 0;
 
        ret = adv748x_write_regs(state, adv748x_sw_reset);
        if (ret < 0)
@@ -496,22 +474,24 @@ static int adv748x_reset(struct adv748x_state *state)
        if (ret)
                return ret;
 
-       adv748x_txa_power(state, 0);
+       adv748x_tx_power(&state->txa, 0);
 
        /* Init and power down TXB */
        ret = adv748x_write_regs(state, adv748x_init_txb_1lane);
        if (ret)
                return ret;
 
-       adv748x_txb_power(state, 0);
+       adv748x_tx_power(&state->txb, 0);
 
        /* Disable chip powerdown & Enable HDMI Rx block */
        io_write(state, ADV748X_IO_PD, ADV748X_IO_PD_RX_EN);
 
-       /* Enable 4-lane CSI Tx & Pixel Port */
-       io_write(state, ADV748X_IO_10, ADV748X_IO_10_CSI4_EN |
-                                      ADV748X_IO_10_CSI1_EN |
-                                      ADV748X_IO_10_PIX_OUT_EN);
+       /* Conditionally enable TXa and TXb. */
+       if (is_tx_enabled(&state->txa))
+               regval |= ADV748X_IO_10_CSI4_EN;
+       if (is_tx_enabled(&state->txb))
+               regval |= ADV748X_IO_10_CSI1_EN;
+       io_write(state, ADV748X_IO_10, regval);
 
        /* Use vid_std and v_freq as freerun resolution for CP */
        cp_clrset(state, ADV748X_CP_CLMP_POS, ADV748X_CP_CLMP_POS_DIS_AUTO,
@@ -569,7 +549,8 @@ static int adv748x_parse_dt(struct adv748x_state *state)
 {
        struct device_node *ep_np = NULL;
        struct of_endpoint ep;
-       bool found = false;
+       bool out_found = false;
+       bool in_found = false;
 
        for_each_endpoint_of_node(state->dev->of_node, ep_np) {
                of_graph_parse_endpoint(ep_np, &ep);
@@ -592,10 +573,17 @@ static int adv748x_parse_dt(struct adv748x_state *state)
                of_node_get(ep_np);
                state->endpoints[ep.port] = ep_np;
 
-               found = true;
+               /*
+                * At least one input endpoint and one output endpoint shall
+                * be defined.
+                */
+               if (ep.port < ADV748X_PORT_TXA)
+                       in_found = true;
+               else
+                       out_found = true;
        }
 
-       return found ? 0 : -ENODEV;
+       return in_found && out_found ? 0 : -ENODEV;
 }
 
 static void adv748x_dt_cleanup(struct adv748x_state *state)
@@ -627,6 +615,17 @@ static int adv748x_probe(struct i2c_client *client,
        state->i2c_clients[ADV748X_PAGE_IO] = client;
        i2c_set_clientdata(client, state);
 
+       /*
+        * We can not use container_of to get back to the state with two TXs;
+        * Initialize the TXs's fields unconditionally on the endpoint
+        * presence to access them later.
+        */
+       state->txa.state = state->txb.state = state;
+       state->txa.page = ADV748X_PAGE_TXA;
+       state->txb.page = ADV748X_PAGE_TXB;
+       state->txa.port = ADV748X_PORT_TXA;
+       state->txb.port = ADV748X_PORT_TXB;
+
        /* Discover and process ports declared by the Device tree endpoints */
        ret = adv748x_parse_dt(state);
        if (ret) {
@@ -755,4 +754,4 @@ module_i2c_driver(adv748x_driver);
 
 MODULE_AUTHOR("Kieran Bingham <kieran.bingham@ideasonboard.com>");
 MODULE_DESCRIPTION("ADV748X video decoder");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
index 469be87a3761feb5b775e4cf26aeac2600987f83..6ce21542ed48581150c96e045f777657166e5ce2 100644 (file)
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Driver for Analog Devices ADV748X CSI-2 Transmitter
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
  */
 
 #include <linux/module.h>
 
 #include "adv748x.h"
 
-static bool is_txa(struct adv748x_csi2 *tx)
-{
-       return tx == &tx->state->txa;
-}
-
 static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx,
                                            unsigned int vc)
 {
@@ -87,15 +78,15 @@ static int adv748x_csi2_registered(struct v4l2_subdev *sd)
         *
         * Link HDMI->TXA, and AFE->TXB directly.
         */
-       if (is_txa(tx)) {
+       if (is_txa(tx) && is_hdmi_enabled(state))
                return adv748x_csi2_register_link(tx, sd->v4l2_dev,
                                                  &state->hdmi.sd,
                                                  ADV748X_HDMI_SOURCE);
-       } else {
+       if (!is_txa(tx) && is_afe_enabled(state))
                return adv748x_csi2_register_link(tx, sd->v4l2_dev,
                                                  &state->afe.sd,
                                                  ADV748X_AFE_SOURCE);
-       }
+       return 0;
 }
 
 static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
@@ -266,19 +257,10 @@ static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
 
 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
 {
-       struct device_node *ep;
        int ret;
 
-       /* We can not use container_of to get back to the state with two TXs */
-       tx->state = state;
-       tx->page = is_txa(tx) ? ADV748X_PAGE_TXA : ADV748X_PAGE_TXB;
-
-       ep = state->endpoints[is_txa(tx) ? ADV748X_PORT_TXA : ADV748X_PORT_TXB];
-       if (!ep) {
-               adv_err(state, "No endpoint found for %s\n",
-                               is_txa(tx) ? "txa" : "txb");
-               return -ENODEV;
-       }
+       if (!is_tx_enabled(tx))
+               return 0;
 
        /* Initialise the virtual channel */
        adv748x_csi2_set_virtual_channel(tx, 0);
@@ -288,7 +270,7 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
                            is_txa(tx) ? "txa" : "txb");
 
        /* Ensure that matching is based upon the endpoint fwnodes */
-       tx->sd.fwnode = of_fwnode_handle(ep);
+       tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]);
 
        /* Register internal ops for incremental subdev registration */
        tx->sd.internal_ops = &adv748x_csi2_internal_ops;
@@ -321,6 +303,9 @@ err_free_media:
 
 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
 {
+       if (!is_tx_enabled(tx))
+               return;
+
        v4l2_async_unregister_subdev(&tx->sd);
        media_entity_cleanup(&tx->sd.entity);
        v4l2_ctrl_handler_free(&tx->ctrl_hdl);
index aecc2a84dfecbec8ccb575090abcef64472a1f6a..35d027941482a8927676961e64df36d2a7254eba 100644 (file)
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Driver for Analog Devices ADV748X HDMI receiver and Component Processor (CP)
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
  */
 
 #include <linux/module.h>
@@ -362,7 +358,7 @@ static int adv748x_hdmi_s_stream(struct v4l2_subdev *sd, int enable)
 
        mutex_lock(&state->mutex);
 
-       ret = adv748x_txa_power(state, enable);
+       ret = adv748x_tx_power(&state->txa, enable);
        if (ret)
                goto done;
 
index 65f83741277e1365cdf723a1221df693562da55e..39c2fdc3b41667d8ff23f082ed7d81c7bdc4cfe0 100644 (file)
@@ -1,13 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Driver for Analog Devices ADV748X video decoder and HDMI receiver
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  *
- * 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.
- *
  * Authors:
  *     Koji Matsuoka <koji.matsuoka.xm@renesas.com>
  *     Niklas Söderlund <niklas.soderlund@ragnatech.se>
@@ -82,6 +78,7 @@ struct adv748x_csi2 {
        struct adv748x_state *state;
        struct v4l2_mbus_framefmt format;
        unsigned int page;
+       unsigned int port;
 
        struct media_pad pads[ADV748X_CSI2_NR_PADS];
        struct v4l2_ctrl_handler ctrl_hdl;
@@ -91,6 +88,18 @@ struct adv748x_csi2 {
 
 #define notifier_to_csi2(n) container_of(n, struct adv748x_csi2, notifier)
 #define adv748x_sd_to_csi2(sd) container_of(sd, struct adv748x_csi2, sd)
+#define is_tx_enabled(_tx) ((_tx)->state->endpoints[(_tx)->port] != NULL)
+#define is_txa(_tx) ((_tx) == &(_tx)->state->txa)
+#define is_afe_enabled(_state)                                 \
+       ((_state)->endpoints[ADV748X_PORT_AIN0] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN1] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN2] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN3] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN4] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN5] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN6] != NULL ||      \
+        (_state)->endpoints[ADV748X_PORT_AIN7] != NULL)
+#define is_hdmi_enabled(_state) ((_state)->endpoints[ADV748X_PORT_HDMI] != NULL)
 
 enum adv748x_hdmi_pads {
        ADV748X_HDMI_SINK,
@@ -376,9 +385,6 @@ int adv748x_write_block(struct adv748x_state *state, int client_page,
 #define cp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_CP, r, v)
 #define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~m) | v)
 
-#define txa_read(s, r) adv748x_read(s, ADV748X_PAGE_TXA, r)
-#define txb_read(s, r) adv748x_read(s, ADV748X_PAGE_TXB, r)
-
 #define tx_read(t, r) adv748x_read(t->state, t->page, r)
 #define tx_write(t, r, v) adv748x_write(t->state, t->page, r, v)
 
@@ -398,8 +404,7 @@ void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state,
 int adv748x_register_subdevs(struct adv748x_state *state,
                             struct v4l2_device *v4l2_dev);
 
-int adv748x_txa_power(struct adv748x_state *state, bool on);
-int adv748x_txb_power(struct adv748x_state *state, bool on);
+int adv748x_tx_power(struct adv748x_csi2 *tx, bool on);
 
 int adv748x_afe_init(struct adv748x_afe *afe);
 void adv748x_afe_cleanup(struct adv748x_afe *afe);
index 55c2ea0720d9e13dc846d5665602d21cbd5c9fdd..f3899cc84e27f8db4c89c63e8ab1f2593dd8432a 100644 (file)
@@ -1355,10 +1355,10 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd,
        state->xfer_func = format->format.xfer_func;
 
        switch (format->format.colorspace) {
-       case V4L2_COLORSPACE_ADOBERGB:
+       case V4L2_COLORSPACE_OPRGB:
                c = HDMI_COLORIMETRY_EXTENDED;
-               ec = y ? HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601 :
-                        HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
+               ec = y ? HDMI_EXTENDED_COLORIMETRY_OPYCC_601 :
+                        HDMI_EXTENDED_COLORIMETRY_OPRGB;
                break;
        case V4L2_COLORSPACE_SMPTE170M:
                c = y ? HDMI_COLORIMETRY_ITU_601 : HDMI_COLORIMETRY_NONE;
index 668be2bca57aa53ace00b92960aaa3dc3a5a1554..9eb7c70a7712580a6741723c9447d7439bc87b7d 100644 (file)
@@ -2284,8 +2284,10 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
                state->aspect_ratio.numerator = 16;
                state->aspect_ratio.denominator = 9;
 
-               if (!state->edid.present)
+               if (!state->edid.present) {
                        state->edid.blocks = 0;
+                       cec_phys_addr_invalidate(state->cec_adap);
+               }
 
                v4l2_dbg(2, debug, sd, "%s: clear EDID pad %d, edid.present = 0x%x\n",
                                __func__, edid->pad, state->edid.present);
@@ -2295,8 +2297,8 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
                edid->blocks = 2;
                return -E2BIG;
        }
-       pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc);
-       err = cec_phys_addr_validate(pa, &pa, NULL);
+       pa = v4l2_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc);
+       err = v4l2_phys_addr_validate(pa, &pa, NULL);
        if (err)
                return err;
 
@@ -2474,7 +2476,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd)
                "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
                "xvYCC Bt.601", "xvYCC Bt.709",
                "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
-               "sYCC", "Adobe YCC 601", "AdobeRGB", "invalid", "invalid",
+               "sYCC", "opYCC 601", "opRGB", "invalid", "invalid",
                "invalid", "invalid", "invalid"
        };
        static const char * const rgb_quantization_range_txt[] = {
@@ -3093,7 +3095,7 @@ MODULE_DEVICE_TABLE(of, adv76xx_of_id);
 
 static int adv76xx_parse_dt(struct adv76xx_state *state)
 {
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct device_node *endpoint;
        struct device_node *np;
        unsigned int flags;
index 4f8fbdd00e35eb01d5f3ec3d4fb92820249e5f18..4721d49dcf0fef4bc4048e73d49bac558e3ed13e 100644 (file)
@@ -786,11 +786,13 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
        /* Disable I2C access to internal EDID ram from HDMI DDC ports */
        rep_write_and_or(sd, 0x77, 0xf3, 0x00);
 
-       if (!state->hdmi_edid.present)
+       if (!state->hdmi_edid.present) {
+               cec_phys_addr_invalidate(state->cec_adap);
                return 0;
+       }
 
-       pa = cec_get_edid_phys_addr(edid, 256, &spa_loc);
-       err = cec_phys_addr_validate(pa, &pa, NULL);
+       pa = v4l2_get_edid_phys_addr(edid, 256, &spa_loc);
+       err = v4l2_phys_addr_validate(pa, &pa, NULL);
        if (err)
                return err;
 
@@ -1525,6 +1527,7 @@ static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
        v4l2_find_dv_timings_cap(timings, adv7842_get_dv_timings_cap(sd),
                        is_digital_input(sd) ? 250000 : 1000000,
                        adv7842_check_dv_timings, NULL);
+       timings->bt.flags |= V4L2_DV_FL_CAN_DETECT_REDUCED_FPS;
 }
 
 static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
@@ -1596,6 +1599,14 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
                        bt->il_vbackporch = 0;
                }
                adv7842_fill_optional_dv_timings_fields(sd, timings);
+               if ((timings->bt.flags & V4L2_DV_FL_CAN_REDUCE_FPS) &&
+                   freq < bt->pixelclock) {
+                       u32 reduced_freq = ((u32)bt->pixelclock / 1001) * 1000;
+                       u32 delta_freq = abs(freq - reduced_freq);
+
+                       if (delta_freq < ((u32)bt->pixelclock - reduced_freq) / 2)
+                               timings->bt.flags |= V4L2_DV_FL_REDUCED_FPS;
+               }
        } else {
                /* find format
                 * Since LCVS values are inaccurate [REF_03, p. 339-340],
index 16682c8477d14d378b761bf58e1b1be89912c1ff..30f9db1351b91a26fb2369695eebddf4a4d014c3 100644 (file)
@@ -136,7 +136,6 @@ static int ak881x_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
                sel->r.left = 0;
                sel->r.top = 0;
                sel->r.width = 720;
index fd70fe2130a15c5aaea13d3e64defb60472c2b8a..ef4bdbae45315523dc86d9a5003470c72a9012b7 100644 (file)
@@ -149,7 +149,7 @@ static int cs53l32a_probe(struct i2c_client *client,
                return -EIO;
 
        if (!id)
-               strlcpy(client->name, "cs53l32a", sizeof(client->name));
+               strscpy(client->name, "cs53l32a", sizeof(client->name));
 
        v4l_info(client, "chip found @ 0x%x (%s)\n",
                        client->addr << 1, client->adapter->name);
index ad7f66c7aac87f1ca36658e9a535e6d59e453983..69cdc09981af669de3cd921bd08a2b85bdaecdf1 100644 (file)
@@ -701,10 +701,8 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
                if (v > IR_MAX_DURATION)
                        v = IR_MAX_DURATION;
 
-               init_ir_raw_event(&p->ir_core_data);
-               p->ir_core_data.pulse = u;
-               p->ir_core_data.duration = v;
-               p->ir_core_data.timeout = w;
+               p->ir_core_data = (struct ir_raw_event)
+                       { .pulse = u, .duration = v, .timeout = w };
 
                v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns  %s  %s\n",
                         v, u ? "mark" : "space", w ? "(timed out)" : "");
index 91fae01d052bf5568cd646d6bf521062182a43ca..26d83693a6816fe0ad8d8aa8289f9f427a427046 100644 (file)
@@ -169,8 +169,9 @@ static int dw9714_probe(struct i2c_client *client)
        return 0;
 
 err_cleanup:
-       dw9714_subdev_cleanup(dw9714_dev);
-       dev_err(&client->dev, "Probe failed: %d\n", rval);
+       v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
+       media_entity_cleanup(&dw9714_dev->sd.entity);
+
        return rval;
 }
 
index 8ba3920b6e2f470e2a3b514fa2e1ea2ccd3e7ff6..b38a4e6d270da7ba6f23d22aec2b5b2d2bf622a7 100644 (file)
@@ -218,7 +218,8 @@ static int dw9807_probe(struct i2c_client *client)
        return 0;
 
 err_cleanup:
-       dw9807_subdev_cleanup(dw9807_dev);
+       v4l2_ctrl_handler_free(&dw9807_dev->ctrls_vcm);
+       media_entity_cleanup(&dw9807_dev->sd.entity);
 
        return rval;
 }
@@ -229,7 +230,6 @@ static int dw9807_remove(struct i2c_client *client)
        struct dw9807_device *dw9807_dev = sd_to_dw9807_vcm(sd);
 
        pm_runtime_disable(&client->dev);
-       pm_runtime_set_suspended(&client->dev);
 
        dw9807_subdev_cleanup(dw9807_dev);
 
index f8c70f1a34feb09f2fddfba53471e8f9bd0b8409..11c69281692ebe8078a15d815435061b83112afb 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * imx274.c - IMX274 CMOS Image Sensor driver
  *
@@ -6,18 +7,6 @@
  * Leon Luo <leonl@leopardimaging.com>
  * Edwin Zou <edwinz@leopardimaging.com>
  * Luca Ceresoli <luca@lucaceresoli.net>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/clk.h>
@@ -76,7 +65,7 @@
  */
 #define IMX274_MIN_EXPOSURE_TIME               (4 * 260 / 72)
 
-#define IMX274_DEFAULT_MODE                    IMX274_BINNING_OFF
+#define IMX274_DEFAULT_BINNING                 IMX274_BINNING_OFF
 #define IMX274_MAX_WIDTH                       (3840)
 #define IMX274_MAX_HEIGHT                      (2160)
 #define IMX274_MAX_FRAME_RATE                  (120)
@@ -178,7 +167,7 @@ enum imx274_binning {
  * @nocpiop: Number of clocks per internal offset period (see "Integration Time
  *           in Each Readout Drive Mode (CSI-2)" in the datasheet)
  */
-struct imx274_frmfmt {
+struct imx274_mode {
        const struct reg_8 *init_regs;
        unsigned int bin_ratio;
        int min_frame_len;
@@ -349,20 +338,14 @@ static const struct reg_8 imx274_mode5_1280x720_raw10[] = {
  */
 static const struct reg_8 imx274_start_1[] = {
        {IMX274_STANDBY_REG, 0x12},
-       {IMX274_TABLE_END, 0x00}
-};
 
-/*
- * imx274 second step register configuration for
- * starting stream
- */
-static const struct reg_8 imx274_start_2[] = {
-       {0x3120, 0xF0}, /* clock settings */
-       {0x3121, 0x00}, /* clock settings */
-       {0x3122, 0x02}, /* clock settings */
-       {0x3129, 0x9C}, /* clock settings */
-       {0x312A, 0x02}, /* clock settings */
-       {0x312D, 0x02}, /* clock settings */
+       /* PLRD: clock settings */
+       {0x3120, 0xF0},
+       {0x3121, 0x00},
+       {0x3122, 0x02},
+       {0x3129, 0x9C},
+       {0x312A, 0x02},
+       {0x312D, 0x02},
 
        {0x310B, 0x00},
 
@@ -407,20 +390,20 @@ static const struct reg_8 imx274_start_2[] = {
 };
 
 /*
- * imx274 third step register configuration for
+ * imx274 second step register configuration for
  * starting stream
  */
-static const struct reg_8 imx274_start_3[] = {
+static const struct reg_8 imx274_start_2[] = {
        {IMX274_STANDBY_REG, 0x00},
        {0x303E, 0x02}, /* SYS_MODE = 2 */
        {IMX274_TABLE_END, 0x00}
 };
 
 /*
- * imx274 forth step register configuration for
+ * imx274 third step register configuration for
  * starting stream
  */
-static const struct reg_8 imx274_start_4[] = {
+static const struct reg_8 imx274_start_3[] = {
        {0x30F4, 0x00},
        {0x3018, 0xA2}, /* XHS VHS OUTUPT */
        {IMX274_TABLE_END, 0x00}
@@ -459,7 +442,7 @@ static const struct reg_8 imx274_tp_regs[] = {
 };
 
 /* nocpiop happens to be the same number for the implemented modes */
-static const struct imx274_frmfmt imx274_formats[] = {
+static const struct imx274_mode imx274_modes[] = {
        {
                /* mode 1, 4K */
                .bin_ratio = 1,
@@ -532,7 +515,7 @@ struct stimx274 {
        struct regmap *regmap;
        struct gpio_desc *reset_gpio;
        struct mutex lock; /* mutex lock for operations */
-       const struct imx274_frmfmt *mode;
+       const struct imx274_mode *mode;
 };
 
 #define IMX274_ROUND(dim, step, flags)                 \
@@ -665,6 +648,41 @@ static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val)
        return err;
 }
 
+/**
+ * Read a multibyte register.
+ *
+ * Uses a bulk read where possible.
+ *
+ * @priv: Pointer to device structure
+ * @addr: Address of the LSB register.  Other registers must be
+ *        consecutive, least-to-most significant.
+ * @val: Pointer to store the register value (cpu endianness)
+ * @nbytes: Number of bytes to read (range: [1..3]).
+ *          Other bytes are zet to 0.
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_read_mbreg(struct stimx274 *priv, u16 addr, u32 *val,
+                            size_t nbytes)
+{
+       __le32 val_le = 0;
+       int err;
+
+       err = regmap_bulk_read(priv->regmap, addr, &val_le, nbytes);
+       if (err) {
+               dev_err(&priv->client->dev,
+                       "%s : i2c bulk read failed, %x (%zu bytes)\n",
+                       __func__, addr, nbytes);
+       } else {
+               *val = le32_to_cpu(val_le);
+               dev_dbg(&priv->client->dev,
+                       "%s : addr 0x%x, val=0x%x (%zu bytes)\n",
+                       __func__, addr, *val, nbytes);
+       }
+
+       return err;
+}
+
 /**
  * Write a multibyte register.
  *
@@ -674,7 +692,7 @@ static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val)
  * @addr: Address of the LSB register.  Other registers must be
  *        consecutive, least-to-most significant.
  * @val: Value to be written to the register (cpu endianness)
- * @nbytes: Number of bits to write (range: [1..3])
+ * @nbytes: Number of bytes to write (range: [1..3])
  */
 static int imx274_write_mbreg(struct stimx274 *priv, u16 addr, u32 val,
                              size_t nbytes)
@@ -708,10 +726,6 @@ static int imx274_mode_regs(struct stimx274 *priv)
        if (err)
                return err;
 
-       err = imx274_write_table(priv, imx274_start_2);
-       if (err)
-               return err;
-
        err = imx274_write_table(priv, priv->mode->init_regs);
 
        return err;
@@ -733,7 +747,7 @@ static int imx274_start_stream(struct stimx274 *priv)
         * give it 1 extra ms for margin
         */
        msleep_range(11);
-       err = imx274_write_table(priv, imx274_start_3);
+       err = imx274_write_table(priv, imx274_start_2);
        if (err)
                return err;
 
@@ -743,7 +757,7 @@ static int imx274_start_stream(struct stimx274 *priv)
         * give it 1 extra ms for margin
         */
        msleep_range(8);
-       err = imx274_write_table(priv, imx274_start_4);
+       err = imx274_write_table(priv, imx274_start_3);
        if (err)
                return err;
 
@@ -881,7 +895,7 @@ static int __imx274_change_compose(struct stimx274 *imx274,
        const struct v4l2_rect *cur_crop;
        struct v4l2_mbus_framefmt *tgt_fmt;
        unsigned int i;
-       const struct imx274_frmfmt *best_mode = &imx274_formats[0];
+       const struct imx274_mode *best_mode = &imx274_modes[0];
        int best_goodness = INT_MIN;
 
        if (which == V4L2_SUBDEV_FORMAT_TRY) {
@@ -892,8 +906,8 @@ static int __imx274_change_compose(struct stimx274 *imx274,
                tgt_fmt = &imx274->format;
        }
 
-       for (i = 0; i < ARRAY_SIZE(imx274_formats); i++) {
-               unsigned int ratio = imx274_formats[i].bin_ratio;
+       for (i = 0; i < ARRAY_SIZE(imx274_modes); i++) {
+               unsigned int ratio = imx274_modes[i].bin_ratio;
 
                int goodness = imx274_binning_goodness(
                        imx274,
@@ -903,7 +917,7 @@ static int __imx274_change_compose(struct stimx274 *imx274,
 
                if (goodness >= best_goodness) {
                        best_goodness = goodness;
-                       best_mode = &imx274_formats[i];
+                       best_mode = &imx274_modes[i];
                }
        }
 
@@ -1323,7 +1337,7 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
 
        dev_dbg(&imx274->client->dev, "%s : %s, mode index = %td\n", __func__,
                on ? "Stream Start" : "Stream Stop",
-               imx274->mode - &imx274_formats[0]);
+               imx274->mode - &imx274_modes[0]);
 
        mutex_lock(&imx274->lock);
 
@@ -1387,37 +1401,17 @@ fail:
 static int imx274_get_frame_length(struct stimx274 *priv, u32 *val)
 {
        int err;
-       u16 svr;
+       u32 svr;
        u32 vmax;
-       u8 reg_val[3];
-
-       /* svr */
-       err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, &reg_val[0]);
-       if (err)
-               goto fail;
 
-       err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, &reg_val[1]);
+       err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2);
        if (err)
                goto fail;
 
-       svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
-
-       /* vmax */
-       err = imx274_read_reg(priv, IMX274_VMAX_REG_3, &reg_val[0]);
+       err = imx274_read_mbreg(priv, IMX274_VMAX_REG_3, &vmax, 3);
        if (err)
                goto fail;
 
-       err = imx274_read_reg(priv, IMX274_VMAX_REG_2, &reg_val[1]);
-       if (err)
-               goto fail;
-
-       err = imx274_read_reg(priv, IMX274_VMAX_REG_1, &reg_val[2]);
-       if (err)
-               goto fail;
-
-       vmax = ((reg_val[2] & IMX274_MASK_LSB_3_BITS) << IMX274_SHIFT_16_BITS)
-               + (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
-
        *val = vmax * (svr + 1);
 
        return 0;
@@ -1598,8 +1592,7 @@ fail:
 static int imx274_set_exposure(struct stimx274 *priv, int val)
 {
        int err;
-       u16 hmax;
-       u8 reg_val[2];
+       u32 hmax;
        u32 coarse_time; /* exposure time in unit of line (HMAX)*/
 
        dev_dbg(&priv->client->dev,
@@ -1607,14 +1600,10 @@ static int imx274_set_exposure(struct stimx274 *priv, int val)
 
        /* step 1: convert input exposure_time (val) into number of 1[HMAX] */
 
-       /* obtain HMAX value */
-       err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, &reg_val[0]);
-       if (err)
-               goto fail;
-       err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, &reg_val[1]);
+       err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2);
        if (err)
                goto fail;
-       hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+
        if (hmax == 0) {
                err = -EINVAL;
                goto fail;
@@ -1749,9 +1738,8 @@ static int imx274_set_frame_interval(struct stimx274 *priv,
 {
        int err;
        u32 frame_length, req_frame_rate;
-       u16 svr;
-       u16 hmax;
-       u8 reg_val[2];
+       u32 svr;
+       u32 hmax;
 
        dev_dbg(&priv->client->dev, "%s: input frame interval = %d / %d",
                __func__, frame_interval.numerator,
@@ -1779,25 +1767,17 @@ static int imx274_set_frame_interval(struct stimx274 *priv,
         * frame_length (i.e. VMAX) = (frame_interval) x 72M /(SVR+1) / HMAX
         */
 
-       /* SVR */
-       err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, &reg_val[0]);
-       if (err)
-               goto fail;
-       err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, &reg_val[1]);
+       err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2);
        if (err)
                goto fail;
-       svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+
        dev_dbg(&priv->client->dev,
                "%s : register SVR = %d\n", __func__, svr);
 
-       /* HMAX */
-       err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, &reg_val[0]);
-       if (err)
-               goto fail;
-       err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, &reg_val[1]);
+       err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2);
        if (err)
                goto fail;
-       hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+
        dev_dbg(&priv->client->dev,
                "%s : register HMAX = %d\n", __func__, hmax);
 
@@ -1871,7 +1851,7 @@ static int imx274_probe(struct i2c_client *client,
        mutex_init(&imx274->lock);
 
        /* initialize format */
-       imx274->mode = &imx274_formats[IMX274_DEFAULT_MODE];
+       imx274->mode = &imx274_modes[IMX274_DEFAULT_BINNING];
        imx274->crop.width = IMX274_MAX_WIDTH;
        imx274->crop.height = IMX274_MAX_HEIGHT;
        imx274->format.width = imx274->crop.width / imx274->mode->bin_ratio;
@@ -1895,7 +1875,6 @@ static int imx274_probe(struct i2c_client *client,
        imx274->client = client;
        sd = &imx274->sd;
        v4l2_i2c_subdev_init(sd, client, &imx274_subdev_ops);
-       strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
 
        /* initialize subdev media pad */
diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c
new file mode 100644 (file)
index 0000000..0d3e278
--- /dev/null
@@ -0,0 +1,2560 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include <asm/unaligned.h>
+#include <linux/acpi.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+
+#define IMX319_REG_MODE_SELECT         0x0100
+#define IMX319_MODE_STANDBY            0x00
+#define IMX319_MODE_STREAMING          0x01
+
+/* Chip ID */
+#define IMX319_REG_CHIP_ID             0x0016
+#define IMX319_CHIP_ID                 0x0319
+
+/* V_TIMING internal */
+#define IMX319_REG_FLL                 0x0340
+#define IMX319_FLL_MAX                 0xffff
+
+/* Exposure control */
+#define IMX319_REG_EXPOSURE            0x0202
+#define IMX319_EXPOSURE_MIN            1
+#define IMX319_EXPOSURE_STEP           1
+#define IMX319_EXPOSURE_DEFAULT                0x04f6
+
+/*
+ *  the digital control register for all color control looks like:
+ *  +-----------------+------------------+
+ *  |      [7:0]      |       [15:8]     |
+ *  +-----------------+------------------+
+ *  |    0x020f      |       0x020e     |
+ *  --------------------------------------
+ *  it is used to calculate the digital gain times value(integral + fractional)
+ *  the [15:8] bits is the fractional part and [7:0] bits is the integral
+ *  calculation equation is:
+ *      gain value (unit: times) = REG[15:8] + REG[7:0]/0x100
+ *  Only value in 0x0100 ~ 0x0FFF range is allowed.
+ *  Analog gain use 10 bits in the registers and allowed range is 0 ~ 960
+ */
+/* Analog gain control */
+#define IMX319_REG_ANALOG_GAIN         0x0204
+#define IMX319_ANA_GAIN_MIN            0
+#define IMX319_ANA_GAIN_MAX            960
+#define IMX319_ANA_GAIN_STEP           1
+#define IMX319_ANA_GAIN_DEFAULT                0
+
+/* Digital gain control */
+#define IMX319_REG_DPGA_USE_GLOBAL_GAIN        0x3ff9
+#define IMX319_REG_DIG_GAIN_GLOBAL     0x020e
+#define IMX319_DGTL_GAIN_MIN           256
+#define IMX319_DGTL_GAIN_MAX           4095
+#define IMX319_DGTL_GAIN_STEP          1
+#define IMX319_DGTL_GAIN_DEFAULT       256
+
+/* Test Pattern Control */
+#define IMX319_REG_TEST_PATTERN                0x0600
+#define IMX319_TEST_PATTERN_DISABLED           0
+#define IMX319_TEST_PATTERN_SOLID_COLOR                1
+#define IMX319_TEST_PATTERN_COLOR_BARS         2
+#define IMX319_TEST_PATTERN_GRAY_COLOR_BARS    3
+#define IMX319_TEST_PATTERN_PN9                        4
+
+/* Flip Control */
+#define IMX319_REG_ORIENTATION         0x0101
+
+/* default link frequency and external clock */
+#define IMX319_LINK_FREQ_DEFAULT       482400000
+#define IMX319_EXT_CLK                 19200000
+#define IMX319_LINK_FREQ_INDEX         0
+
+struct imx319_reg {
+       u16 address;
+       u8 val;
+};
+
+struct imx319_reg_list {
+       u32 num_of_regs;
+       const struct imx319_reg *regs;
+};
+
+/* Mode : resolution and related config&values */
+struct imx319_mode {
+       /* Frame width */
+       u32 width;
+       /* Frame height */
+       u32 height;
+
+       /* V-timing */
+       u32 fll_def;
+       u32 fll_min;
+
+       /* H-timing */
+       u32 llp;
+
+       /* index of link frequency */
+       u32 link_freq_index;
+
+       /* Default register values */
+       struct imx319_reg_list reg_list;
+};
+
+struct imx319_hwcfg {
+       u32 ext_clk;                    /* sensor external clk */
+       s64 *link_freqs;                /* CSI-2 link frequencies */
+       unsigned int nr_of_link_freqs;
+};
+
+struct imx319 {
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+
+       struct v4l2_ctrl_handler ctrl_handler;
+       /* V4L2 Controls */
+       struct v4l2_ctrl *link_freq;
+       struct v4l2_ctrl *pixel_rate;
+       struct v4l2_ctrl *vblank;
+       struct v4l2_ctrl *hblank;
+       struct v4l2_ctrl *exposure;
+       struct v4l2_ctrl *vflip;
+       struct v4l2_ctrl *hflip;
+
+       /* Current mode */
+       const struct imx319_mode *cur_mode;
+
+       struct imx319_hwcfg *hwcfg;
+       s64 link_def_freq;      /* CSI-2 link default frequency */
+
+       /*
+        * Mutex for serialized access:
+        * Protect sensor set pad format and start/stop streaming safely.
+        * Protect access to sensor v4l2 controls.
+        */
+       struct mutex mutex;
+
+       /* Streaming on/off */
+       bool streaming;
+};
+
+static const struct imx319_reg imx319_global_regs[] = {
+       { 0x0136, 0x13 },
+       { 0x0137, 0x33 },
+       { 0x3c7e, 0x05 },
+       { 0x3c7f, 0x07 },
+       { 0x4d39, 0x0b },
+       { 0x4d41, 0x33 },
+       { 0x4d43, 0x0c },
+       { 0x4d49, 0x89 },
+       { 0x4e05, 0x0b },
+       { 0x4e0d, 0x33 },
+       { 0x4e0f, 0x0c },
+       { 0x4e15, 0x89 },
+       { 0x4e49, 0x2a },
+       { 0x4e51, 0x33 },
+       { 0x4e53, 0x0c },
+       { 0x4e59, 0x89 },
+       { 0x5601, 0x4f },
+       { 0x560b, 0x45 },
+       { 0x562f, 0x0a },
+       { 0x5643, 0x0a },
+       { 0x5645, 0x0c },
+       { 0x56ef, 0x51 },
+       { 0x586f, 0x33 },
+       { 0x5873, 0x89 },
+       { 0x5905, 0x33 },
+       { 0x5907, 0x89 },
+       { 0x590d, 0x33 },
+       { 0x590f, 0x89 },
+       { 0x5915, 0x33 },
+       { 0x5917, 0x89 },
+       { 0x5969, 0x1c },
+       { 0x596b, 0x72 },
+       { 0x5971, 0x33 },
+       { 0x5973, 0x89 },
+       { 0x5975, 0x33 },
+       { 0x5977, 0x89 },
+       { 0x5979, 0x1c },
+       { 0x597b, 0x72 },
+       { 0x5985, 0x33 },
+       { 0x5987, 0x89 },
+       { 0x5999, 0x1c },
+       { 0x599b, 0x72 },
+       { 0x59a5, 0x33 },
+       { 0x59a7, 0x89 },
+       { 0x7485, 0x08 },
+       { 0x7487, 0x0c },
+       { 0x7489, 0xc7 },
+       { 0x748b, 0x8b },
+       { 0x9004, 0x09 },
+       { 0x9200, 0x6a },
+       { 0x9201, 0x22 },
+       { 0x9202, 0x6a },
+       { 0x9203, 0x23 },
+       { 0x9204, 0x5f },
+       { 0x9205, 0x23 },
+       { 0x9206, 0x5f },
+       { 0x9207, 0x24 },
+       { 0x9208, 0x5f },
+       { 0x9209, 0x26 },
+       { 0x920a, 0x5f },
+       { 0x920b, 0x27 },
+       { 0x920c, 0x5f },
+       { 0x920d, 0x29 },
+       { 0x920e, 0x5f },
+       { 0x920f, 0x2a },
+       { 0x9210, 0x5f },
+       { 0x9211, 0x2c },
+       { 0xbc22, 0x1a },
+       { 0xf01f, 0x04 },
+       { 0xf021, 0x03 },
+       { 0xf023, 0x02 },
+       { 0xf03d, 0x05 },
+       { 0xf03f, 0x03 },
+       { 0xf041, 0x02 },
+       { 0xf0af, 0x04 },
+       { 0xf0b1, 0x03 },
+       { 0xf0b3, 0x02 },
+       { 0xf0cd, 0x05 },
+       { 0xf0cf, 0x03 },
+       { 0xf0d1, 0x02 },
+       { 0xf13f, 0x04 },
+       { 0xf141, 0x03 },
+       { 0xf143, 0x02 },
+       { 0xf15d, 0x05 },
+       { 0xf15f, 0x03 },
+       { 0xf161, 0x02 },
+       { 0xf1cf, 0x04 },
+       { 0xf1d1, 0x03 },
+       { 0xf1d3, 0x02 },
+       { 0xf1ed, 0x05 },
+       { 0xf1ef, 0x03 },
+       { 0xf1f1, 0x02 },
+       { 0xf287, 0x04 },
+       { 0xf289, 0x03 },
+       { 0xf28b, 0x02 },
+       { 0xf2a5, 0x05 },
+       { 0xf2a7, 0x03 },
+       { 0xf2a9, 0x02 },
+       { 0xf2b7, 0x04 },
+       { 0xf2b9, 0x03 },
+       { 0xf2bb, 0x02 },
+       { 0xf2d5, 0x05 },
+       { 0xf2d7, 0x03 },
+       { 0xf2d9, 0x02 },
+};
+
+static const struct imx319_reg_list imx319_global_setting = {
+       .num_of_regs = ARRAY_SIZE(imx319_global_regs),
+       .regs = imx319_global_regs,
+};
+
+static const struct imx319_reg mode_3264x2448_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0f },
+       { 0x0343, 0x80 },
+       { 0x0340, 0x0c },
+       { 0x0341, 0xaa },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x01 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x00 },
+       { 0x0409, 0x08 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x08 },
+       { 0x040c, 0x0c },
+       { 0x040d, 0xc0 },
+       { 0x040e, 0x09 },
+       { 0x040f, 0x90 },
+       { 0x034c, 0x0c },
+       { 0x034d, 0xc0 },
+       { 0x034e, 0x09 },
+       { 0x034f, 0x90 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0x48 },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x01 },
+       { 0x3f79, 0x18 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x00 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x0a },
+       { 0x0203, 0x7a },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_3280x2464_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0f },
+       { 0x0343, 0x80 },
+       { 0x0340, 0x0c },
+       { 0x0341, 0xaa },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x01 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x00 },
+       { 0x0409, 0x00 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x00 },
+       { 0x040c, 0x0c },
+       { 0x040d, 0xd0 },
+       { 0x040e, 0x09 },
+       { 0x040f, 0xa0 },
+       { 0x034c, 0x0c },
+       { 0x034d, 0xd0 },
+       { 0x034e, 0x09 },
+       { 0x034f, 0xa0 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0x48 },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x01 },
+       { 0x3f79, 0x18 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x00 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x0a },
+       { 0x0203, 0x7a },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_1936x1096_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0f },
+       { 0x0343, 0x80 },
+       { 0x0340, 0x0c },
+       { 0x0341, 0xaa },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0xac },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x06 },
+       { 0x034b, 0xf3 },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x01 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x02 },
+       { 0x0409, 0xa0 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x00 },
+       { 0x040c, 0x07 },
+       { 0x040d, 0x90 },
+       { 0x040e, 0x04 },
+       { 0x040f, 0x48 },
+       { 0x034c, 0x07 },
+       { 0x034d, 0x90 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0x48 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0x48 },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x01 },
+       { 0x3f79, 0x18 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x00 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x05 },
+       { 0x0203, 0x34 },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_1920x1080_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0f },
+       { 0x0343, 0x80 },
+       { 0x0340, 0x0c },
+       { 0x0341, 0xaa },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0xb4 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x06 },
+       { 0x034b, 0xeb },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x01 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x02 },
+       { 0x0409, 0xa8 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x00 },
+       { 0x040c, 0x07 },
+       { 0x040d, 0x80 },
+       { 0x040e, 0x04 },
+       { 0x040f, 0x38 },
+       { 0x034c, 0x07 },
+       { 0x034d, 0x80 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0x38 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0x48 },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x01 },
+       { 0x3f79, 0x18 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x00 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x05 },
+       { 0x0203, 0x34 },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_1640x1232_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x08 },
+       { 0x0343, 0x20 },
+       { 0x0340, 0x18 },
+       { 0x0341, 0x2a },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x02 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x00 },
+       { 0x0409, 0x00 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x00 },
+       { 0x040c, 0x06 },
+       { 0x040d, 0x68 },
+       { 0x040e, 0x04 },
+       { 0x040f, 0xd0 },
+       { 0x034c, 0x06 },
+       { 0x034d, 0x68 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0xd0 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0xba },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x00 },
+       { 0x3f79, 0x34 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x04 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x04 },
+       { 0x0203, 0xf6 },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_1640x922_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x08 },
+       { 0x0343, 0x20 },
+       { 0x0340, 0x18 },
+       { 0x0341, 0x2a },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x01 },
+       { 0x0347, 0x30 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x08 },
+       { 0x034b, 0x6f },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x02 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x00 },
+       { 0x0409, 0x00 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x02 },
+       { 0x040c, 0x06 },
+       { 0x040d, 0x68 },
+       { 0x040e, 0x03 },
+       { 0x040f, 0x9a },
+       { 0x034c, 0x06 },
+       { 0x034d, 0x68 },
+       { 0x034e, 0x03 },
+       { 0x034f, 0x9a },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0xba },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x00 },
+       { 0x3f79, 0x34 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x04 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x04 },
+       { 0x0203, 0xf6 },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_1296x736_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x08 },
+       { 0x0343, 0x20 },
+       { 0x0340, 0x18 },
+       { 0x0341, 0x2a },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x01 },
+       { 0x0347, 0xf0 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x07 },
+       { 0x034b, 0xaf },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x02 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x00 },
+       { 0x0409, 0xac },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x00 },
+       { 0x040c, 0x05 },
+       { 0x040d, 0x10 },
+       { 0x040e, 0x02 },
+       { 0x040f, 0xe0 },
+       { 0x034c, 0x05 },
+       { 0x034d, 0x10 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0xe0 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0xba },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x00 },
+       { 0x3f79, 0x34 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x04 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x04 },
+       { 0x0203, 0xf6 },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const struct imx319_reg mode_1280x720_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x08 },
+       { 0x0343, 0x20 },
+       { 0x0340, 0x18 },
+       { 0x0341, 0x2a },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x07 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0221, 0x11 },
+       { 0x0381, 0x01 },
+       { 0x0383, 0x01 },
+       { 0x0385, 0x01 },
+       { 0x0387, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x0a },
+       { 0x3140, 0x02 },
+       { 0x3141, 0x00 },
+       { 0x3f0d, 0x0a },
+       { 0x3f14, 0x01 },
+       { 0x3f3c, 0x02 },
+       { 0x3f4d, 0x01 },
+       { 0x3f4c, 0x01 },
+       { 0x4254, 0x7f },
+       { 0x0401, 0x00 },
+       { 0x0404, 0x00 },
+       { 0x0405, 0x10 },
+       { 0x0408, 0x00 },
+       { 0x0409, 0xb4 },
+       { 0x040a, 0x00 },
+       { 0x040b, 0x00 },
+       { 0x040c, 0x05 },
+       { 0x040d, 0x00 },
+       { 0x040e, 0x02 },
+       { 0x040f, 0xd0 },
+       { 0x034c, 0x05 },
+       { 0x034d, 0x00 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0xd0 },
+       { 0x3261, 0x00 },
+       { 0x3264, 0x00 },
+       { 0x3265, 0x10 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x04 },
+       { 0x0305, 0x04 },
+       { 0x0306, 0x01 },
+       { 0x0307, 0x92 },
+       { 0x0309, 0x0a },
+       { 0x030b, 0x02 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0xfa },
+       { 0x0310, 0x00 },
+       { 0x0820, 0x0f },
+       { 0x0821, 0x13 },
+       { 0x0822, 0x33 },
+       { 0x0823, 0x33 },
+       { 0x3e20, 0x01 },
+       { 0x3e37, 0x00 },
+       { 0x3e3b, 0x01 },
+       { 0x38a3, 0x01 },
+       { 0x38a8, 0x00 },
+       { 0x38a9, 0x00 },
+       { 0x38aa, 0x00 },
+       { 0x38ab, 0x00 },
+       { 0x3234, 0x00 },
+       { 0x3fc1, 0x00 },
+       { 0x3235, 0x00 },
+       { 0x3802, 0x00 },
+       { 0x3143, 0x04 },
+       { 0x360a, 0x00 },
+       { 0x0b00, 0x00 },
+       { 0x0106, 0x00 },
+       { 0x0b05, 0x01 },
+       { 0x0b06, 0x01 },
+       { 0x3230, 0x00 },
+       { 0x3602, 0x01 },
+       { 0x3607, 0x01 },
+       { 0x3c00, 0x00 },
+       { 0x3c01, 0xba },
+       { 0x3c02, 0xc8 },
+       { 0x3c03, 0xaa },
+       { 0x3c04, 0x91 },
+       { 0x3c05, 0x54 },
+       { 0x3c06, 0x26 },
+       { 0x3c07, 0x20 },
+       { 0x3c08, 0x51 },
+       { 0x3d80, 0x00 },
+       { 0x3f50, 0x00 },
+       { 0x3f56, 0x00 },
+       { 0x3f57, 0x30 },
+       { 0x3f78, 0x00 },
+       { 0x3f79, 0x34 },
+       { 0x3f7c, 0x00 },
+       { 0x3f7d, 0x00 },
+       { 0x3fba, 0x00 },
+       { 0x3fbb, 0x00 },
+       { 0xa081, 0x04 },
+       { 0xe014, 0x00 },
+       { 0x0202, 0x04 },
+       { 0x0203, 0xf6 },
+       { 0x0224, 0x01 },
+       { 0x0225, 0xf4 },
+       { 0x0204, 0x00 },
+       { 0x0205, 0x00 },
+       { 0x0216, 0x00 },
+       { 0x0217, 0x00 },
+       { 0x020e, 0x01 },
+       { 0x020f, 0x00 },
+       { 0x0210, 0x01 },
+       { 0x0211, 0x00 },
+       { 0x0212, 0x01 },
+       { 0x0213, 0x00 },
+       { 0x0214, 0x01 },
+       { 0x0215, 0x00 },
+       { 0x0218, 0x01 },
+       { 0x0219, 0x00 },
+       { 0x3614, 0x00 },
+       { 0x3616, 0x0d },
+       { 0x3617, 0x56 },
+       { 0xb612, 0x20 },
+       { 0xb613, 0x20 },
+       { 0xb614, 0x20 },
+       { 0xb615, 0x20 },
+       { 0xb616, 0x0a },
+       { 0xb617, 0x0a },
+       { 0xb618, 0x20 },
+       { 0xb619, 0x20 },
+       { 0xb61a, 0x20 },
+       { 0xb61b, 0x20 },
+       { 0xb61c, 0x0a },
+       { 0xb61d, 0x0a },
+       { 0xb666, 0x30 },
+       { 0xb667, 0x30 },
+       { 0xb668, 0x30 },
+       { 0xb669, 0x30 },
+       { 0xb66a, 0x14 },
+       { 0xb66b, 0x14 },
+       { 0xb66c, 0x20 },
+       { 0xb66d, 0x20 },
+       { 0xb66e, 0x20 },
+       { 0xb66f, 0x20 },
+       { 0xb670, 0x10 },
+       { 0xb671, 0x10 },
+       { 0x3237, 0x00 },
+       { 0x3900, 0x00 },
+       { 0x3901, 0x00 },
+       { 0x3902, 0x00 },
+       { 0x3904, 0x00 },
+       { 0x3905, 0x00 },
+       { 0x3906, 0x00 },
+       { 0x3907, 0x00 },
+       { 0x3908, 0x00 },
+       { 0x3909, 0x00 },
+       { 0x3912, 0x00 },
+       { 0x3930, 0x00 },
+       { 0x3931, 0x00 },
+       { 0x3933, 0x00 },
+       { 0x3934, 0x00 },
+       { 0x3935, 0x00 },
+       { 0x3936, 0x00 },
+       { 0x3937, 0x00 },
+       { 0x30ac, 0x00 },
+};
+
+static const char * const imx319_test_pattern_menu[] = {
+       "Disabled",
+       "100% color bars",
+       "Solid color",
+       "Fade to gray color bars",
+       "PN9"
+};
+
+/* supported link frequencies */
+static const s64 link_freq_menu_items[] = {
+       IMX319_LINK_FREQ_DEFAULT,
+};
+
+/* Mode configs */
+static const struct imx319_mode supported_modes[] = {
+       {
+               .width = 3280,
+               .height = 2464,
+               .fll_def = 3242,
+               .fll_min = 3242,
+               .llp = 3968,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
+                       .regs = mode_3280x2464_regs,
+               },
+       },
+       {
+               .width = 3264,
+               .height = 2448,
+               .fll_def = 3242,
+               .fll_min = 3242,
+               .llp = 3968,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
+                       .regs = mode_3264x2448_regs,
+               },
+       },
+       {
+               .width = 1936,
+               .height = 1096,
+               .fll_def = 3242,
+               .fll_min = 3242,
+               .llp = 3968,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
+                       .regs = mode_1936x1096_regs,
+               },
+       },
+       {
+               .width = 1920,
+               .height = 1080,
+               .fll_def = 3242,
+               .fll_min = 3242,
+               .llp = 3968,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
+                       .regs = mode_1920x1080_regs,
+               },
+       },
+       {
+               .width = 1640,
+               .height = 1232,
+               .fll_def = 5146,
+               .fll_min = 5146,
+               .llp = 2500,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
+                       .regs = mode_1640x1232_regs,
+               },
+       },
+       {
+               .width = 1640,
+               .height = 922,
+               .fll_def = 5146,
+               .fll_min = 5146,
+               .llp = 2500,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
+                       .regs = mode_1640x922_regs,
+               },
+       },
+       {
+               .width = 1296,
+               .height = 736,
+               .fll_def = 5146,
+               .fll_min = 5146,
+               .llp = 2500,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
+                       .regs = mode_1296x736_regs,
+               },
+       },
+       {
+               .width = 1280,
+               .height = 720,
+               .fll_def = 5146,
+               .fll_min = 5146,
+               .llp = 2500,
+               .link_freq_index = IMX319_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
+                       .regs = mode_1280x720_regs,
+               },
+       },
+};
+
+static inline struct imx319 *to_imx319(struct v4l2_subdev *_sd)
+{
+       return container_of(_sd, struct imx319, sd);
+}
+
+/* Get bayer order based on flip setting. */
+static u32 imx319_get_format_code(struct imx319 *imx319)
+{
+       /*
+        * Only one bayer order is supported.
+        * It depends on the flip settings.
+        */
+       u32 code;
+       static const u32 codes[2][2] = {
+               { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
+               { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
+       };
+
+       lockdep_assert_held(&imx319->mutex);
+       code = codes[imx319->vflip->val][imx319->hflip->val];
+
+       return code;
+}
+
+/* Read registers up to 4 at a time */
+static int imx319_read_reg(struct imx319 *imx319, u16 reg, u32 len, u32 *val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       struct i2c_msg msgs[2];
+       u8 addr_buf[2];
+       u8 data_buf[4] = { 0 };
+       int ret;
+
+       if (len > 4)
+               return -EINVAL;
+
+       put_unaligned_be16(reg, addr_buf);
+       /* Write register address */
+       msgs[0].addr = client->addr;
+       msgs[0].flags = 0;
+       msgs[0].len = ARRAY_SIZE(addr_buf);
+       msgs[0].buf = addr_buf;
+
+       /* Read data from register */
+       msgs[1].addr = client->addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = len;
+       msgs[1].buf = &data_buf[4 - len];
+
+       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+       if (ret != ARRAY_SIZE(msgs))
+               return -EIO;
+
+       *val = get_unaligned_be32(data_buf);
+
+       return 0;
+}
+
+/* Write registers up to 4 at a time */
+static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       u8 buf[6];
+
+       if (len > 4)
+               return -EINVAL;
+
+       put_unaligned_be16(reg, buf);
+       put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
+       if (i2c_master_send(client, buf, len + 2) != len + 2)
+               return -EIO;
+
+       return 0;
+}
+
+/* Write a list of registers */
+static int imx319_write_regs(struct imx319 *imx319,
+                            const struct imx319_reg *regs, u32 len)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       int ret;
+       u32 i;
+
+       for (i = 0; i < len; i++) {
+               ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
+               if (ret) {
+                       dev_err_ratelimited(&client->dev,
+                                           "write reg 0x%4.4x return err %d",
+                                           regs[i].address, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/* Open sub-device */
+static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       struct imx319 *imx319 = to_imx319(sd);
+       struct v4l2_mbus_framefmt *try_fmt =
+               v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
+       mutex_lock(&imx319->mutex);
+
+       /* Initialize try_fmt */
+       try_fmt->width = imx319->cur_mode->width;
+       try_fmt->height = imx319->cur_mode->height;
+       try_fmt->code = imx319_get_format_code(imx319);
+       try_fmt->field = V4L2_FIELD_NONE;
+
+       mutex_unlock(&imx319->mutex);
+
+       return 0;
+}
+
+static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct imx319 *imx319 = container_of(ctrl->handler,
+                                            struct imx319, ctrl_handler);
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       s64 max;
+       int ret;
+
+       /* Propagate change of current control to all related controls */
+       switch (ctrl->id) {
+       case V4L2_CID_VBLANK:
+               /* Update max exposure while meeting expected vblanking */
+               max = imx319->cur_mode->height + ctrl->val - 18;
+               __v4l2_ctrl_modify_range(imx319->exposure,
+                                        imx319->exposure->minimum,
+                                        max, imx319->exposure->step, max);
+               break;
+       }
+
+       /*
+        * Applying V4L2 control value only happens
+        * when power is up for streaming
+        */
+       if (!pm_runtime_get_if_in_use(&client->dev))
+               return 0;
+
+       switch (ctrl->id) {
+       case V4L2_CID_ANALOGUE_GAIN:
+               /* Analog gain = 1024/(1024 - ctrl->val) times */
+               ret = imx319_write_reg(imx319, IMX319_REG_ANALOG_GAIN, 2,
+                                      ctrl->val);
+               break;
+       case V4L2_CID_DIGITAL_GAIN:
+               ret = imx319_write_reg(imx319, IMX319_REG_DIG_GAIN_GLOBAL, 2,
+                                      ctrl->val);
+               break;
+       case V4L2_CID_EXPOSURE:
+               ret = imx319_write_reg(imx319, IMX319_REG_EXPOSURE, 2,
+                                      ctrl->val);
+               break;
+       case V4L2_CID_VBLANK:
+               /* Update FLL that meets expected vertical blanking */
+               ret = imx319_write_reg(imx319, IMX319_REG_FLL, 2,
+                                      imx319->cur_mode->height + ctrl->val);
+               break;
+       case V4L2_CID_TEST_PATTERN:
+               ret = imx319_write_reg(imx319, IMX319_REG_TEST_PATTERN,
+                                      2, ctrl->val);
+               break;
+       case V4L2_CID_HFLIP:
+       case V4L2_CID_VFLIP:
+               ret = imx319_write_reg(imx319, IMX319_REG_ORIENTATION, 1,
+                                      imx319->hflip->val |
+                                      imx319->vflip->val << 1);
+               break;
+       default:
+               ret = -EINVAL;
+               dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
+                        ctrl->id, ctrl->val);
+               break;
+       }
+
+       pm_runtime_put(&client->dev);
+
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops imx319_ctrl_ops = {
+       .s_ctrl = imx319_set_ctrl,
+};
+
+static int imx319_enum_mbus_code(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct imx319 *imx319 = to_imx319(sd);
+
+       if (code->index > 0)
+               return -EINVAL;
+
+       mutex_lock(&imx319->mutex);
+       code->code = imx319_get_format_code(imx319);
+       mutex_unlock(&imx319->mutex);
+
+       return 0;
+}
+
+static int imx319_enum_frame_size(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_pad_config *cfg,
+                                 struct v4l2_subdev_frame_size_enum *fse)
+{
+       struct imx319 *imx319 = to_imx319(sd);
+
+       if (fse->index >= ARRAY_SIZE(supported_modes))
+               return -EINVAL;
+
+       mutex_lock(&imx319->mutex);
+       if (fse->code != imx319_get_format_code(imx319)) {
+               mutex_unlock(&imx319->mutex);
+               return -EINVAL;
+       }
+       mutex_unlock(&imx319->mutex);
+
+       fse->min_width = supported_modes[fse->index].width;
+       fse->max_width = fse->min_width;
+       fse->min_height = supported_modes[fse->index].height;
+       fse->max_height = fse->min_height;
+
+       return 0;
+}
+
+static void imx319_update_pad_format(struct imx319 *imx319,
+                                    const struct imx319_mode *mode,
+                                    struct v4l2_subdev_format *fmt)
+{
+       fmt->format.width = mode->width;
+       fmt->format.height = mode->height;
+       fmt->format.code = imx319_get_format_code(imx319);
+       fmt->format.field = V4L2_FIELD_NONE;
+}
+
+static int imx319_do_get_pad_format(struct imx319 *imx319,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_subdev_format *fmt)
+{
+       struct v4l2_mbus_framefmt *framefmt;
+       struct v4l2_subdev *sd = &imx319->sd;
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+               fmt->format = *framefmt;
+       } else {
+               imx319_update_pad_format(imx319, imx319->cur_mode, fmt);
+       }
+
+       return 0;
+}
+
+static int imx319_get_pad_format(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_format *fmt)
+{
+       struct imx319 *imx319 = to_imx319(sd);
+       int ret;
+
+       mutex_lock(&imx319->mutex);
+       ret = imx319_do_get_pad_format(imx319, cfg, fmt);
+       mutex_unlock(&imx319->mutex);
+
+       return ret;
+}
+
+static int
+imx319_set_pad_format(struct v4l2_subdev *sd,
+                     struct v4l2_subdev_pad_config *cfg,
+                     struct v4l2_subdev_format *fmt)
+{
+       struct imx319 *imx319 = to_imx319(sd);
+       const struct imx319_mode *mode;
+       struct v4l2_mbus_framefmt *framefmt;
+       s32 vblank_def;
+       s32 vblank_min;
+       s64 h_blank;
+       u64 pixel_rate;
+       u32 height;
+
+       mutex_lock(&imx319->mutex);
+
+       /*
+        * Only one bayer order is supported.
+        * It depends on the flip settings.
+        */
+       fmt->format.code = imx319_get_format_code(imx319);
+
+       mode = v4l2_find_nearest_size(supported_modes,
+                                     ARRAY_SIZE(supported_modes),
+                                     width, height,
+                                     fmt->format.width, fmt->format.height);
+       imx319_update_pad_format(imx319, mode, fmt);
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+               *framefmt = fmt->format;
+       } else {
+               imx319->cur_mode = mode;
+               pixel_rate = imx319->link_def_freq * 2 * 4;
+               do_div(pixel_rate, 10);
+               __v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
+               /* Update limits and set FPS to default */
+               height = imx319->cur_mode->height;
+               vblank_def = imx319->cur_mode->fll_def - height;
+               vblank_min = imx319->cur_mode->fll_min - height;
+               height = IMX319_FLL_MAX - height;
+               __v4l2_ctrl_modify_range(imx319->vblank, vblank_min, height, 1,
+                                        vblank_def);
+               __v4l2_ctrl_s_ctrl(imx319->vblank, vblank_def);
+               h_blank = mode->llp - imx319->cur_mode->width;
+               /*
+                * Currently hblank is not changeable.
+                * So FPS control is done only by vblank.
+                */
+               __v4l2_ctrl_modify_range(imx319->hblank, h_blank,
+                                        h_blank, 1, h_blank);
+       }
+
+       mutex_unlock(&imx319->mutex);
+
+       return 0;
+}
+
+/* Start streaming */
+static int imx319_start_streaming(struct imx319 *imx319)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       const struct imx319_reg_list *reg_list;
+       int ret;
+
+       /* Global Setting */
+       reg_list = &imx319_global_setting;
+       ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
+       if (ret) {
+               dev_err(&client->dev, "failed to set global settings");
+               return ret;
+       }
+
+       /* Apply default values of current mode */
+       reg_list = &imx319->cur_mode->reg_list;
+       ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
+       if (ret) {
+               dev_err(&client->dev, "failed to set mode");
+               return ret;
+       }
+
+       /* set digital gain control to all color mode */
+       ret = imx319_write_reg(imx319, IMX319_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
+       if (ret)
+               return ret;
+
+       /* Apply customized values from user */
+       ret =  __v4l2_ctrl_handler_setup(imx319->sd.ctrl_handler);
+       if (ret)
+               return ret;
+
+       return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
+                               1, IMX319_MODE_STREAMING);
+}
+
+/* Stop streaming */
+static int imx319_stop_streaming(struct imx319 *imx319)
+{
+       return imx319_write_reg(imx319, IMX319_REG_MODE_SELECT,
+                               1, IMX319_MODE_STANDBY);
+}
+
+static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct imx319 *imx319 = to_imx319(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret = 0;
+
+       mutex_lock(&imx319->mutex);
+       if (imx319->streaming == enable) {
+               mutex_unlock(&imx319->mutex);
+               return 0;
+       }
+
+       if (enable) {
+               ret = pm_runtime_get_sync(&client->dev);
+               if (ret < 0) {
+                       pm_runtime_put_noidle(&client->dev);
+                       goto err_unlock;
+               }
+
+               /*
+                * Apply default & customized values
+                * and then start streaming.
+                */
+               ret = imx319_start_streaming(imx319);
+               if (ret)
+                       goto err_rpm_put;
+       } else {
+               imx319_stop_streaming(imx319);
+               pm_runtime_put(&client->dev);
+       }
+
+       imx319->streaming = enable;
+
+       /* vflip and hflip cannot change during streaming */
+       __v4l2_ctrl_grab(imx319->vflip, enable);
+       __v4l2_ctrl_grab(imx319->hflip, enable);
+
+       mutex_unlock(&imx319->mutex);
+
+       return ret;
+
+err_rpm_put:
+       pm_runtime_put(&client->dev);
+err_unlock:
+       mutex_unlock(&imx319->mutex);
+
+       return ret;
+}
+
+static int __maybe_unused imx319_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct imx319 *imx319 = to_imx319(sd);
+
+       if (imx319->streaming)
+               imx319_stop_streaming(imx319);
+
+       return 0;
+}
+
+static int __maybe_unused imx319_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct imx319 *imx319 = to_imx319(sd);
+       int ret;
+
+       if (imx319->streaming) {
+               ret = imx319_start_streaming(imx319);
+               if (ret)
+                       goto error;
+       }
+
+       return 0;
+
+error:
+       imx319_stop_streaming(imx319);
+       imx319->streaming = 0;
+       return ret;
+}
+
+/* Verify chip ID */
+static int imx319_identify_module(struct imx319 *imx319)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       int ret;
+       u32 val;
+
+       ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
+       if (ret)
+               return ret;
+
+       if (val != IMX319_CHIP_ID) {
+               dev_err(&client->dev, "chip id mismatch: %x!=%x",
+                       IMX319_CHIP_ID, val);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
+       .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+       .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops imx319_video_ops = {
+       .s_stream = imx319_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops imx319_pad_ops = {
+       .enum_mbus_code = imx319_enum_mbus_code,
+       .get_fmt = imx319_get_pad_format,
+       .set_fmt = imx319_set_pad_format,
+       .enum_frame_size = imx319_enum_frame_size,
+};
+
+static const struct v4l2_subdev_ops imx319_subdev_ops = {
+       .core = &imx319_subdev_core_ops,
+       .video = &imx319_video_ops,
+       .pad = &imx319_pad_ops,
+};
+
+static const struct media_entity_operations imx319_subdev_entity_ops = {
+       .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
+       .open = imx319_open,
+};
+
+/* Initialize control handlers */
+static int imx319_init_controls(struct imx319 *imx319)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+       struct v4l2_ctrl_handler *ctrl_hdlr;
+       s64 exposure_max;
+       s64 vblank_def;
+       s64 vblank_min;
+       s64 hblank;
+       u64 pixel_rate;
+       const struct imx319_mode *mode;
+       u32 max;
+       int ret;
+
+       ctrl_hdlr = &imx319->ctrl_handler;
+       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
+       if (ret)
+               return ret;
+
+       ctrl_hdlr->lock = &imx319->mutex;
+       max = ARRAY_SIZE(link_freq_menu_items) - 1;
+       imx319->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx319_ctrl_ops,
+                                                  V4L2_CID_LINK_FREQ, max, 0,
+                                                  link_freq_menu_items);
+       if (imx319->link_freq)
+               imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
+       pixel_rate = imx319->link_def_freq * 2 * 4;
+       do_div(pixel_rate, 10);
+       /* By default, PIXEL_RATE is read only */
+       imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
+                                              V4L2_CID_PIXEL_RATE, pixel_rate,
+                                              pixel_rate, 1, pixel_rate);
+
+       /* Initial vblank/hblank/exposure parameters based on current mode */
+       mode = imx319->cur_mode;
+       vblank_def = mode->fll_def - mode->height;
+       vblank_min = mode->fll_min - mode->height;
+       imx319->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
+                                          V4L2_CID_VBLANK, vblank_min,
+                                          IMX319_FLL_MAX - mode->height,
+                                          1, vblank_def);
+
+       hblank = mode->llp - mode->width;
+       imx319->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
+                                          V4L2_CID_HBLANK, hblank, hblank,
+                                          1, hblank);
+       if (imx319->hblank)
+               imx319->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       /* fll >= exposure time + adjust parameter (default value is 18) */
+       exposure_max = mode->fll_def - 18;
+       imx319->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
+                                            V4L2_CID_EXPOSURE,
+                                            IMX319_EXPOSURE_MIN, exposure_max,
+                                            IMX319_EXPOSURE_STEP,
+                                            IMX319_EXPOSURE_DEFAULT);
+
+       imx319->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
+                                         V4L2_CID_HFLIP, 0, 1, 1, 0);
+       imx319->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
+                                         V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+       v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+                         IMX319_ANA_GAIN_MIN, IMX319_ANA_GAIN_MAX,
+                         IMX319_ANA_GAIN_STEP, IMX319_ANA_GAIN_DEFAULT);
+
+       /* Digital gain */
+       v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+                         IMX319_DGTL_GAIN_MIN, IMX319_DGTL_GAIN_MAX,
+                         IMX319_DGTL_GAIN_STEP, IMX319_DGTL_GAIN_DEFAULT);
+
+       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx319_ctrl_ops,
+                                    V4L2_CID_TEST_PATTERN,
+                                    ARRAY_SIZE(imx319_test_pattern_menu) - 1,
+                                    0, 0, imx319_test_pattern_menu);
+       if (ctrl_hdlr->error) {
+               ret = ctrl_hdlr->error;
+               dev_err(&client->dev, "control init failed: %d", ret);
+               goto error;
+       }
+
+       imx319->sd.ctrl_handler = ctrl_hdlr;
+
+       return 0;
+
+error:
+       v4l2_ctrl_handler_free(ctrl_hdlr);
+
+       return ret;
+}
+
+static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
+{
+       struct imx319_hwcfg *cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = {
+               .bus_type = V4L2_MBUS_CSI2_DPHY
+       };
+       struct fwnode_handle *ep;
+       struct fwnode_handle *fwnode = dev_fwnode(dev);
+       unsigned int i;
+       int ret;
+
+       if (!fwnode)
+               return NULL;
+
+       ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+       if (!ep)
+               return NULL;
+
+       ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+       if (ret)
+               goto out_err;
+
+       cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
+       if (!cfg)
+               goto out_err;
+
+       ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+                                      &cfg->ext_clk);
+       if (ret) {
+               dev_err(dev, "can't get clock frequency");
+               goto out_err;
+       }
+
+       dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
+       if (cfg->ext_clk != IMX319_EXT_CLK) {
+               dev_err(dev, "external clock %d is not supported",
+                       cfg->ext_clk);
+               goto out_err;
+       }
+
+       dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
+       if (!bus_cfg.nr_of_link_frequencies) {
+               dev_warn(dev, "no link frequencies defined");
+               goto out_err;
+       }
+
+       cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
+       cfg->link_freqs = devm_kcalloc(dev,
+                                      bus_cfg.nr_of_link_frequencies + 1,
+                                      sizeof(*cfg->link_freqs), GFP_KERNEL);
+       if (!cfg->link_freqs)
+               goto out_err;
+
+       for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
+               cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
+               dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
+       }
+
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+       fwnode_handle_put(ep);
+       return cfg;
+
+out_err:
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+       fwnode_handle_put(ep);
+       return NULL;
+}
+
+static int imx319_probe(struct i2c_client *client)
+{
+       struct imx319 *imx319;
+       int ret;
+       u32 i;
+
+       imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
+       if (!imx319)
+               return -ENOMEM;
+
+       mutex_init(&imx319->mutex);
+
+       /* Initialize subdev */
+       v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
+
+       /* Check module identity */
+       ret = imx319_identify_module(imx319);
+       if (ret) {
+               dev_err(&client->dev, "failed to find sensor: %d", ret);
+               goto error_probe;
+       }
+
+       imx319->hwcfg = imx319_get_hwcfg(&client->dev);
+       if (!imx319->hwcfg) {
+               dev_err(&client->dev, "failed to get hwcfg");
+               ret = -ENODEV;
+               goto error_probe;
+       }
+
+       imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
+       for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
+               if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
+                       dev_dbg(&client->dev, "link freq index %d matched", i);
+                       break;
+               }
+       }
+
+       if (i == imx319->hwcfg->nr_of_link_freqs) {
+               dev_err(&client->dev, "no link frequency supported");
+               ret = -EINVAL;
+               goto error_probe;
+       }
+
+       /* Set default mode to max resolution */
+       imx319->cur_mode = &supported_modes[0];
+
+       ret = imx319_init_controls(imx319);
+       if (ret) {
+               dev_err(&client->dev, "failed to init controls: %d", ret);
+               goto error_probe;
+       }
+
+       /* Initialize subdev */
+       imx319->sd.internal_ops = &imx319_internal_ops;
+       imx319->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+               V4L2_SUBDEV_FL_HAS_EVENTS;
+       imx319->sd.entity.ops = &imx319_subdev_entity_ops;
+       imx319->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+       /* Initialize source pad */
+       imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
+       if (ret) {
+               dev_err(&client->dev, "failed to init entity pads: %d", ret);
+               goto error_handler_free;
+       }
+
+       ret = v4l2_async_register_subdev_sensor_common(&imx319->sd);
+       if (ret < 0)
+               goto error_media_entity;
+
+       /*
+        * Device is already turned on by i2c-core with ACPI domain PM.
+        * Enable runtime PM and turn off the device.
+        */
+       pm_runtime_set_active(&client->dev);
+       pm_runtime_enable(&client->dev);
+       pm_runtime_idle(&client->dev);
+
+       return 0;
+
+error_media_entity:
+       media_entity_cleanup(&imx319->sd.entity);
+
+error_handler_free:
+       v4l2_ctrl_handler_free(imx319->sd.ctrl_handler);
+
+error_probe:
+       mutex_destroy(&imx319->mutex);
+
+       return ret;
+}
+
+static int imx319_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct imx319 *imx319 = to_imx319(sd);
+
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+
+       pm_runtime_disable(&client->dev);
+       pm_runtime_set_suspended(&client->dev);
+
+       mutex_destroy(&imx319->mutex);
+
+       return 0;
+}
+
+static const struct dev_pm_ops imx319_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume)
+};
+
+static const struct acpi_device_id imx319_acpi_ids[] = {
+       { "SONY319A" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids);
+
+static struct i2c_driver imx319_i2c_driver = {
+       .driver = {
+               .name = "imx319",
+               .pm = &imx319_pm_ops,
+               .acpi_match_table = ACPI_PTR(imx319_acpi_ids),
+       },
+       .probe_new = imx319_probe,
+       .remove = imx319_remove,
+};
+module_i2c_driver(imx319_i2c_driver);
+
+MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
+MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
+MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
+MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
+MODULE_DESCRIPTION("Sony imx319 sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
new file mode 100644 (file)
index 0000000..20c8eea
--- /dev/null
@@ -0,0 +1,1860 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include <asm/unaligned.h>
+#include <linux/acpi.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+
+#define IMX355_REG_MODE_SELECT         0x0100
+#define IMX355_MODE_STANDBY            0x00
+#define IMX355_MODE_STREAMING          0x01
+
+/* Chip ID */
+#define IMX355_REG_CHIP_ID             0x0016
+#define IMX355_CHIP_ID                 0x0355
+
+/* V_TIMING internal */
+#define IMX355_REG_FLL                 0x0340
+#define IMX355_FLL_MAX                 0xffff
+
+/* Exposure control */
+#define IMX355_REG_EXPOSURE            0x0202
+#define IMX355_EXPOSURE_MIN            1
+#define IMX355_EXPOSURE_STEP           1
+#define IMX355_EXPOSURE_DEFAULT                0x0282
+
+/* Analog gain control */
+#define IMX355_REG_ANALOG_GAIN         0x0204
+#define IMX355_ANA_GAIN_MIN            0
+#define IMX355_ANA_GAIN_MAX            960
+#define IMX355_ANA_GAIN_STEP           1
+#define IMX355_ANA_GAIN_DEFAULT                0
+
+/* Digital gain control */
+#define IMX355_REG_DPGA_USE_GLOBAL_GAIN        0x3070
+#define IMX355_REG_DIG_GAIN_GLOBAL     0x020e
+#define IMX355_DGTL_GAIN_MIN           256
+#define IMX355_DGTL_GAIN_MAX           4095
+#define IMX355_DGTL_GAIN_STEP          1
+#define IMX355_DGTL_GAIN_DEFAULT       256
+
+/* Test Pattern Control */
+#define IMX355_REG_TEST_PATTERN                0x0600
+#define IMX355_TEST_PATTERN_DISABLED           0
+#define IMX355_TEST_PATTERN_SOLID_COLOR                1
+#define IMX355_TEST_PATTERN_COLOR_BARS         2
+#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS    3
+#define IMX355_TEST_PATTERN_PN9                        4
+
+/* Flip Control */
+#define IMX355_REG_ORIENTATION         0x0101
+
+/* default link frequency and external clock */
+#define IMX355_LINK_FREQ_DEFAULT       360000000
+#define IMX355_EXT_CLK                 19200000
+#define IMX355_LINK_FREQ_INDEX         0
+
+struct imx355_reg {
+       u16 address;
+       u8 val;
+};
+
+struct imx355_reg_list {
+       u32 num_of_regs;
+       const struct imx355_reg *regs;
+};
+
+/* Mode : resolution and related config&values */
+struct imx355_mode {
+       /* Frame width */
+       u32 width;
+       /* Frame height */
+       u32 height;
+
+       /* V-timing */
+       u32 fll_def;
+       u32 fll_min;
+
+       /* H-timing */
+       u32 llp;
+
+       /* index of link frequency */
+       u32 link_freq_index;
+
+       /* Default register values */
+       struct imx355_reg_list reg_list;
+};
+
+struct imx355_hwcfg {
+       u32 ext_clk;                    /* sensor external clk */
+       s64 *link_freqs;                /* CSI-2 link frequencies */
+       unsigned int nr_of_link_freqs;
+};
+
+struct imx355 {
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+
+       struct v4l2_ctrl_handler ctrl_handler;
+       /* V4L2 Controls */
+       struct v4l2_ctrl *link_freq;
+       struct v4l2_ctrl *pixel_rate;
+       struct v4l2_ctrl *vblank;
+       struct v4l2_ctrl *hblank;
+       struct v4l2_ctrl *exposure;
+       struct v4l2_ctrl *vflip;
+       struct v4l2_ctrl *hflip;
+
+       /* Current mode */
+       const struct imx355_mode *cur_mode;
+
+       struct imx355_hwcfg *hwcfg;
+       s64 link_def_freq;      /* CSI-2 link default frequency */
+
+       /*
+        * Mutex for serialized access:
+        * Protect sensor set pad format and start/stop streaming safely.
+        * Protect access to sensor v4l2 controls.
+        */
+       struct mutex mutex;
+
+       /* Streaming on/off */
+       bool streaming;
+};
+
+static const struct imx355_reg imx355_global_regs[] = {
+       { 0x0136, 0x13 },
+       { 0x0137, 0x33 },
+       { 0x304e, 0x03 },
+       { 0x4348, 0x16 },
+       { 0x4350, 0x19 },
+       { 0x4408, 0x0a },
+       { 0x440c, 0x0b },
+       { 0x4411, 0x5f },
+       { 0x4412, 0x2c },
+       { 0x4623, 0x00 },
+       { 0x462c, 0x0f },
+       { 0x462d, 0x00 },
+       { 0x462e, 0x00 },
+       { 0x4684, 0x54 },
+       { 0x480a, 0x07 },
+       { 0x4908, 0x07 },
+       { 0x4909, 0x07 },
+       { 0x490d, 0x0a },
+       { 0x491e, 0x0f },
+       { 0x4921, 0x06 },
+       { 0x4923, 0x28 },
+       { 0x4924, 0x28 },
+       { 0x4925, 0x29 },
+       { 0x4926, 0x29 },
+       { 0x4927, 0x1f },
+       { 0x4928, 0x20 },
+       { 0x4929, 0x20 },
+       { 0x492a, 0x20 },
+       { 0x492c, 0x05 },
+       { 0x492d, 0x06 },
+       { 0x492e, 0x06 },
+       { 0x492f, 0x06 },
+       { 0x4930, 0x03 },
+       { 0x4931, 0x04 },
+       { 0x4932, 0x04 },
+       { 0x4933, 0x05 },
+       { 0x595e, 0x01 },
+       { 0x5963, 0x01 },
+       { 0x3030, 0x01 },
+       { 0x3031, 0x01 },
+       { 0x3045, 0x01 },
+       { 0x4010, 0x00 },
+       { 0x4011, 0x00 },
+       { 0x4012, 0x00 },
+       { 0x4013, 0x01 },
+       { 0x68a8, 0xfe },
+       { 0x68a9, 0xff },
+       { 0x6888, 0x00 },
+       { 0x6889, 0x00 },
+       { 0x68b0, 0x00 },
+       { 0x3058, 0x00 },
+       { 0x305a, 0x00 },
+};
+
+static const struct imx355_reg_list imx355_global_setting = {
+       .num_of_regs = ARRAY_SIZE(imx355_global_regs),
+       .regs = imx355_global_regs,
+};
+
+static const struct imx355_reg mode_3268x2448_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x0a },
+       { 0x0341, 0x37 },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x08 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x08 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcb },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x97 },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x0c },
+       { 0x034d, 0xc4 },
+       { 0x034e, 0x09 },
+       { 0x034f, 0x90 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_3264x2448_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x0a },
+       { 0x0341, 0x37 },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x08 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x08 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xc7 },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x97 },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x0c },
+       { 0x034d, 0xc0 },
+       { 0x034e, 0x09 },
+       { 0x034f, 0x90 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_3280x2464_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x0a },
+       { 0x0341, 0x37 },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x0c },
+       { 0x034d, 0xd0 },
+       { 0x034e, 0x09 },
+       { 0x034f, 0xa0 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1940x1096_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x02 },
+       { 0x0345, 0xa0 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0xac },
+       { 0x0348, 0x0a },
+       { 0x0349, 0x33 },
+       { 0x034a, 0x06 },
+       { 0x034b, 0xf3 },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x07 },
+       { 0x034d, 0x94 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0x48 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1936x1096_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x02 },
+       { 0x0345, 0xa0 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0xac },
+       { 0x0348, 0x0a },
+       { 0x0349, 0x2f },
+       { 0x034a, 0x06 },
+       { 0x034b, 0xf3 },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x07 },
+       { 0x034d, 0x90 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0x48 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1924x1080_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x02 },
+       { 0x0345, 0xa8 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0xb4 },
+       { 0x0348, 0x0a },
+       { 0x0349, 0x2b },
+       { 0x034a, 0x06 },
+       { 0x034b, 0xeb },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x07 },
+       { 0x034d, 0x84 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0x38 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1920x1080_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x02 },
+       { 0x0345, 0xa8 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0xb4 },
+       { 0x0348, 0x0a },
+       { 0x0349, 0x27 },
+       { 0x034a, 0x06 },
+       { 0x034b, 0xeb },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x00 },
+       { 0x0901, 0x11 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x07 },
+       { 0x034d, 0x80 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0x38 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1640x1232_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x07 },
+       { 0x0343, 0x2c },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x06 },
+       { 0x034d, 0x68 },
+       { 0x034e, 0x04 },
+       { 0x034f, 0xd0 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1640x922_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x07 },
+       { 0x0343, 0x2c },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x01 },
+       { 0x0347, 0x30 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x08 },
+       { 0x034b, 0x63 },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x06 },
+       { 0x034d, 0x68 },
+       { 0x034e, 0x03 },
+       { 0x034f, 0x9a },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1300x736_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x07 },
+       { 0x0343, 0x2c },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x01 },
+       { 0x0345, 0x58 },
+       { 0x0346, 0x01 },
+       { 0x0347, 0xf0 },
+       { 0x0348, 0x0b },
+       { 0x0349, 0x7f },
+       { 0x034a, 0x07 },
+       { 0x034b, 0xaf },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x05 },
+       { 0x034d, 0x14 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0xe0 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1296x736_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x07 },
+       { 0x0343, 0x2c },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x01 },
+       { 0x0345, 0x58 },
+       { 0x0346, 0x01 },
+       { 0x0347, 0xf0 },
+       { 0x0348, 0x0b },
+       { 0x0349, 0x77 },
+       { 0x034a, 0x07 },
+       { 0x034b, 0xaf },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x05 },
+       { 0x034d, 0x10 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0xe0 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1284x720_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x07 },
+       { 0x0343, 0x2c },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x01 },
+       { 0x0345, 0x68 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0b },
+       { 0x0349, 0x6f },
+       { 0x034a, 0x07 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x05 },
+       { 0x034d, 0x04 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0xd0 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_1280x720_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x07 },
+       { 0x0343, 0x2c },
+       { 0x0340, 0x05 },
+       { 0x0341, 0x1a },
+       { 0x0344, 0x01 },
+       { 0x0345, 0x68 },
+       { 0x0346, 0x02 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0b },
+       { 0x0349, 0x67 },
+       { 0x034a, 0x07 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x22 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x05 },
+       { 0x034d, 0x00 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0xd0 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x00 },
+       { 0x0701, 0x10 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const struct imx355_reg mode_820x616_regs[] = {
+       { 0x0112, 0x0a },
+       { 0x0113, 0x0a },
+       { 0x0114, 0x03 },
+       { 0x0342, 0x0e },
+       { 0x0343, 0x58 },
+       { 0x0340, 0x02 },
+       { 0x0341, 0x8c },
+       { 0x0344, 0x00 },
+       { 0x0345, 0x00 },
+       { 0x0346, 0x00 },
+       { 0x0347, 0x00 },
+       { 0x0348, 0x0c },
+       { 0x0349, 0xcf },
+       { 0x034a, 0x09 },
+       { 0x034b, 0x9f },
+       { 0x0220, 0x00 },
+       { 0x0222, 0x01 },
+       { 0x0900, 0x01 },
+       { 0x0901, 0x44 },
+       { 0x0902, 0x00 },
+       { 0x034c, 0x03 },
+       { 0x034d, 0x34 },
+       { 0x034e, 0x02 },
+       { 0x034f, 0x68 },
+       { 0x0301, 0x05 },
+       { 0x0303, 0x01 },
+       { 0x0305, 0x02 },
+       { 0x0306, 0x00 },
+       { 0x0307, 0x78 },
+       { 0x030b, 0x01 },
+       { 0x030d, 0x02 },
+       { 0x030e, 0x00 },
+       { 0x030f, 0x4b },
+       { 0x0310, 0x00 },
+       { 0x0700, 0x02 },
+       { 0x0701, 0x78 },
+       { 0x0820, 0x0b },
+       { 0x0821, 0x40 },
+       { 0x3088, 0x04 },
+       { 0x6813, 0x02 },
+       { 0x6835, 0x07 },
+       { 0x6836, 0x01 },
+       { 0x6837, 0x04 },
+       { 0x684d, 0x07 },
+       { 0x684e, 0x01 },
+       { 0x684f, 0x04 },
+};
+
+static const char * const imx355_test_pattern_menu[] = {
+       "Disabled",
+       "100% color bars",
+       "Solid color",
+       "Fade to gray color bars",
+       "PN9"
+};
+
+/* supported link frequencies */
+static const s64 link_freq_menu_items[] = {
+       IMX355_LINK_FREQ_DEFAULT,
+};
+
+/* Mode configs */
+static const struct imx355_mode supported_modes[] = {
+       {
+               .width = 3280,
+               .height = 2464,
+               .fll_def = 2615,
+               .fll_min = 2615,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
+                       .regs = mode_3280x2464_regs,
+               },
+       },
+       {
+               .width = 3268,
+               .height = 2448,
+               .fll_def = 2615,
+               .fll_min = 2615,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
+                       .regs = mode_3268x2448_regs,
+               },
+       },
+       {
+               .width = 3264,
+               .height = 2448,
+               .fll_def = 2615,
+               .fll_min = 2615,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
+                       .regs = mode_3264x2448_regs,
+               },
+       },
+       {
+               .width = 1940,
+               .height = 1096,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
+                       .regs = mode_1940x1096_regs,
+               },
+       },
+       {
+               .width = 1936,
+               .height = 1096,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
+                       .regs = mode_1936x1096_regs,
+               },
+       },
+       {
+               .width = 1924,
+               .height = 1080,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
+                       .regs = mode_1924x1080_regs,
+               },
+       },
+       {
+               .width = 1920,
+               .height = 1080,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
+                       .regs = mode_1920x1080_regs,
+               },
+       },
+       {
+               .width = 1640,
+               .height = 1232,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 1836,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
+                       .regs = mode_1640x1232_regs,
+               },
+       },
+       {
+               .width = 1640,
+               .height = 922,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 1836,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
+                       .regs = mode_1640x922_regs,
+               },
+       },
+       {
+               .width = 1300,
+               .height = 736,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 1836,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
+                       .regs = mode_1300x736_regs,
+               },
+       },
+       {
+               .width = 1296,
+               .height = 736,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 1836,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
+                       .regs = mode_1296x736_regs,
+               },
+       },
+       {
+               .width = 1284,
+               .height = 720,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 1836,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
+                       .regs = mode_1284x720_regs,
+               },
+       },
+       {
+               .width = 1280,
+               .height = 720,
+               .fll_def = 1306,
+               .fll_min = 1306,
+               .llp = 1836,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
+                       .regs = mode_1280x720_regs,
+               },
+       },
+       {
+               .width = 820,
+               .height = 616,
+               .fll_def = 652,
+               .fll_min = 652,
+               .llp = 3672,
+               .link_freq_index = IMX355_LINK_FREQ_INDEX,
+               .reg_list = {
+                       .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
+                       .regs = mode_820x616_regs,
+               },
+       },
+};
+
+static inline struct imx355 *to_imx355(struct v4l2_subdev *_sd)
+{
+       return container_of(_sd, struct imx355, sd);
+}
+
+/* Get bayer order based on flip setting. */
+static u32 imx355_get_format_code(struct imx355 *imx355)
+{
+       /*
+        * Only one bayer order is supported.
+        * It depends on the flip settings.
+        */
+       u32 code;
+       static const u32 codes[2][2] = {
+               { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
+               { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
+       };
+
+       lockdep_assert_held(&imx355->mutex);
+       code = codes[imx355->vflip->val][imx355->hflip->val];
+
+       return code;
+}
+
+/* Read registers up to 4 at a time */
+static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       struct i2c_msg msgs[2];
+       u8 addr_buf[2];
+       u8 data_buf[4] = { 0 };
+       int ret;
+
+       if (len > 4)
+               return -EINVAL;
+
+       put_unaligned_be16(reg, addr_buf);
+       /* Write register address */
+       msgs[0].addr = client->addr;
+       msgs[0].flags = 0;
+       msgs[0].len = ARRAY_SIZE(addr_buf);
+       msgs[0].buf = addr_buf;
+
+       /* Read data from register */
+       msgs[1].addr = client->addr;
+       msgs[1].flags = I2C_M_RD;
+       msgs[1].len = len;
+       msgs[1].buf = &data_buf[4 - len];
+
+       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+       if (ret != ARRAY_SIZE(msgs))
+               return -EIO;
+
+       *val = get_unaligned_be32(data_buf);
+
+       return 0;
+}
+
+/* Write registers up to 4 at a time */
+static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       u8 buf[6];
+
+       if (len > 4)
+               return -EINVAL;
+
+       put_unaligned_be16(reg, buf);
+       put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
+       if (i2c_master_send(client, buf, len + 2) != len + 2)
+               return -EIO;
+
+       return 0;
+}
+
+/* Write a list of registers */
+static int imx355_write_regs(struct imx355 *imx355,
+                            const struct imx355_reg *regs, u32 len)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       int ret;
+       u32 i;
+
+       for (i = 0; i < len; i++) {
+               ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
+               if (ret) {
+                       dev_err_ratelimited(&client->dev,
+                                           "write reg 0x%4.4x return err %d",
+                                           regs[i].address, ret);
+
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/* Open sub-device */
+static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       struct imx355 *imx355 = to_imx355(sd);
+       struct v4l2_mbus_framefmt *try_fmt =
+               v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
+       mutex_lock(&imx355->mutex);
+
+       /* Initialize try_fmt */
+       try_fmt->width = imx355->cur_mode->width;
+       try_fmt->height = imx355->cur_mode->height;
+       try_fmt->code = imx355_get_format_code(imx355);
+       try_fmt->field = V4L2_FIELD_NONE;
+
+       mutex_unlock(&imx355->mutex);
+
+       return 0;
+}
+
+static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct imx355 *imx355 = container_of(ctrl->handler,
+                                            struct imx355, ctrl_handler);
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       s64 max;
+       int ret;
+
+       /* Propagate change of current control to all related controls */
+       switch (ctrl->id) {
+       case V4L2_CID_VBLANK:
+               /* Update max exposure while meeting expected vblanking */
+               max = imx355->cur_mode->height + ctrl->val - 10;
+               __v4l2_ctrl_modify_range(imx355->exposure,
+                                        imx355->exposure->minimum,
+                                        max, imx355->exposure->step, max);
+               break;
+       }
+
+       /*
+        * Applying V4L2 control value only happens
+        * when power is up for streaming
+        */
+       if (!pm_runtime_get_if_in_use(&client->dev))
+               return 0;
+
+       switch (ctrl->id) {
+       case V4L2_CID_ANALOGUE_GAIN:
+               /* Analog gain = 1024/(1024 - ctrl->val) times */
+               ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
+                                      ctrl->val);
+               break;
+       case V4L2_CID_DIGITAL_GAIN:
+               ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
+                                      ctrl->val);
+               break;
+       case V4L2_CID_EXPOSURE:
+               ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
+                                      ctrl->val);
+               break;
+       case V4L2_CID_VBLANK:
+               /* Update FLL that meets expected vertical blanking */
+               ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
+                                      imx355->cur_mode->height + ctrl->val);
+               break;
+       case V4L2_CID_TEST_PATTERN:
+               ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
+                                      2, ctrl->val);
+               break;
+       case V4L2_CID_HFLIP:
+       case V4L2_CID_VFLIP:
+               ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
+                                      imx355->hflip->val |
+                                      imx355->vflip->val << 1);
+               break;
+       default:
+               ret = -EINVAL;
+               dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
+                        ctrl->id, ctrl->val);
+               break;
+       }
+
+       pm_runtime_put(&client->dev);
+
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops imx355_ctrl_ops = {
+       .s_ctrl = imx355_set_ctrl,
+};
+
+static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct imx355 *imx355 = to_imx355(sd);
+
+       if (code->index > 0)
+               return -EINVAL;
+
+       mutex_lock(&imx355->mutex);
+       code->code = imx355_get_format_code(imx355);
+       mutex_unlock(&imx355->mutex);
+
+       return 0;
+}
+
+static int imx355_enum_frame_size(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_pad_config *cfg,
+                                 struct v4l2_subdev_frame_size_enum *fse)
+{
+       struct imx355 *imx355 = to_imx355(sd);
+
+       if (fse->index >= ARRAY_SIZE(supported_modes))
+               return -EINVAL;
+
+       mutex_lock(&imx355->mutex);
+       if (fse->code != imx355_get_format_code(imx355)) {
+               mutex_unlock(&imx355->mutex);
+               return -EINVAL;
+       }
+       mutex_unlock(&imx355->mutex);
+
+       fse->min_width = supported_modes[fse->index].width;
+       fse->max_width = fse->min_width;
+       fse->min_height = supported_modes[fse->index].height;
+       fse->max_height = fse->min_height;
+
+       return 0;
+}
+
+static void imx355_update_pad_format(struct imx355 *imx355,
+                                    const struct imx355_mode *mode,
+                                    struct v4l2_subdev_format *fmt)
+{
+       fmt->format.width = mode->width;
+       fmt->format.height = mode->height;
+       fmt->format.code = imx355_get_format_code(imx355);
+       fmt->format.field = V4L2_FIELD_NONE;
+}
+
+static int imx355_do_get_pad_format(struct imx355 *imx355,
+                                   struct v4l2_subdev_pad_config *cfg,
+                                   struct v4l2_subdev_format *fmt)
+{
+       struct v4l2_mbus_framefmt *framefmt;
+       struct v4l2_subdev *sd = &imx355->sd;
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+               fmt->format = *framefmt;
+       } else {
+               imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
+       }
+
+       return 0;
+}
+
+static int imx355_get_pad_format(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_format *fmt)
+{
+       struct imx355 *imx355 = to_imx355(sd);
+       int ret;
+
+       mutex_lock(&imx355->mutex);
+       ret = imx355_do_get_pad_format(imx355, cfg, fmt);
+       mutex_unlock(&imx355->mutex);
+
+       return ret;
+}
+
+static int
+imx355_set_pad_format(struct v4l2_subdev *sd,
+                     struct v4l2_subdev_pad_config *cfg,
+                     struct v4l2_subdev_format *fmt)
+{
+       struct imx355 *imx355 = to_imx355(sd);
+       const struct imx355_mode *mode;
+       struct v4l2_mbus_framefmt *framefmt;
+       s32 vblank_def;
+       s32 vblank_min;
+       s64 h_blank;
+       u64 pixel_rate;
+       u32 height;
+
+       mutex_lock(&imx355->mutex);
+
+       /*
+        * Only one bayer order is supported.
+        * It depends on the flip settings.
+        */
+       fmt->format.code = imx355_get_format_code(imx355);
+
+       mode = v4l2_find_nearest_size(supported_modes,
+                                     ARRAY_SIZE(supported_modes),
+                                     width, height,
+                                     fmt->format.width, fmt->format.height);
+       imx355_update_pad_format(imx355, mode, fmt);
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+               *framefmt = fmt->format;
+       } else {
+               imx355->cur_mode = mode;
+               pixel_rate = imx355->link_def_freq * 2 * 4;
+               do_div(pixel_rate, 10);
+               __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
+               /* Update limits and set FPS to default */
+               height = imx355->cur_mode->height;
+               vblank_def = imx355->cur_mode->fll_def - height;
+               vblank_min = imx355->cur_mode->fll_min - height;
+               height = IMX355_FLL_MAX - height;
+               __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
+                                        vblank_def);
+               __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
+               h_blank = mode->llp - imx355->cur_mode->width;
+               /*
+                * Currently hblank is not changeable.
+                * So FPS control is done only by vblank.
+                */
+               __v4l2_ctrl_modify_range(imx355->hblank, h_blank,
+                                        h_blank, 1, h_blank);
+       }
+
+       mutex_unlock(&imx355->mutex);
+
+       return 0;
+}
+
+/* Start streaming */
+static int imx355_start_streaming(struct imx355 *imx355)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       const struct imx355_reg_list *reg_list;
+       int ret;
+
+       /* Global Setting */
+       reg_list = &imx355_global_setting;
+       ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
+       if (ret) {
+               dev_err(&client->dev, "failed to set global settings");
+               return ret;
+       }
+
+       /* Apply default values of current mode */
+       reg_list = &imx355->cur_mode->reg_list;
+       ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
+       if (ret) {
+               dev_err(&client->dev, "failed to set mode");
+               return ret;
+       }
+
+       /* set digital gain control to all color mode */
+       ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
+       if (ret)
+               return ret;
+
+       /* Apply customized values from user */
+       ret =  __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
+       if (ret)
+               return ret;
+
+       return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
+                               1, IMX355_MODE_STREAMING);
+}
+
+/* Stop streaming */
+static int imx355_stop_streaming(struct imx355 *imx355)
+{
+       return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
+                               1, IMX355_MODE_STANDBY);
+}
+
+static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct imx355 *imx355 = to_imx355(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret = 0;
+
+       mutex_lock(&imx355->mutex);
+       if (imx355->streaming == enable) {
+               mutex_unlock(&imx355->mutex);
+               return 0;
+       }
+
+       if (enable) {
+               ret = pm_runtime_get_sync(&client->dev);
+               if (ret < 0) {
+                       pm_runtime_put_noidle(&client->dev);
+                       goto err_unlock;
+               }
+
+               /*
+                * Apply default & customized values
+                * and then start streaming.
+                */
+               ret = imx355_start_streaming(imx355);
+               if (ret)
+                       goto err_rpm_put;
+       } else {
+               imx355_stop_streaming(imx355);
+               pm_runtime_put(&client->dev);
+       }
+
+       imx355->streaming = enable;
+
+       /* vflip and hflip cannot change during streaming */
+       __v4l2_ctrl_grab(imx355->vflip, enable);
+       __v4l2_ctrl_grab(imx355->hflip, enable);
+
+       mutex_unlock(&imx355->mutex);
+
+       return ret;
+
+err_rpm_put:
+       pm_runtime_put(&client->dev);
+err_unlock:
+       mutex_unlock(&imx355->mutex);
+
+       return ret;
+}
+
+static int __maybe_unused imx355_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct imx355 *imx355 = to_imx355(sd);
+
+       if (imx355->streaming)
+               imx355_stop_streaming(imx355);
+
+       return 0;
+}
+
+static int __maybe_unused imx355_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct imx355 *imx355 = to_imx355(sd);
+       int ret;
+
+       if (imx355->streaming) {
+               ret = imx355_start_streaming(imx355);
+               if (ret)
+                       goto error;
+       }
+
+       return 0;
+
+error:
+       imx355_stop_streaming(imx355);
+       imx355->streaming = 0;
+       return ret;
+}
+
+/* Verify chip ID */
+static int imx355_identify_module(struct imx355 *imx355)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       int ret;
+       u32 val;
+
+       ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
+       if (ret)
+               return ret;
+
+       if (val != IMX355_CHIP_ID) {
+               dev_err(&client->dev, "chip id mismatch: %x!=%x",
+                       IMX355_CHIP_ID, val);
+               return -EIO;
+       }
+       return 0;
+}
+
+static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = {
+       .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+       .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops imx355_video_ops = {
+       .s_stream = imx355_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
+       .enum_mbus_code = imx355_enum_mbus_code,
+       .get_fmt = imx355_get_pad_format,
+       .set_fmt = imx355_set_pad_format,
+       .enum_frame_size = imx355_enum_frame_size,
+};
+
+static const struct v4l2_subdev_ops imx355_subdev_ops = {
+       .core = &imx355_subdev_core_ops,
+       .video = &imx355_video_ops,
+       .pad = &imx355_pad_ops,
+};
+
+static const struct media_entity_operations imx355_subdev_entity_ops = {
+       .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
+       .open = imx355_open,
+};
+
+/* Initialize control handlers */
+static int imx355_init_controls(struct imx355 *imx355)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
+       struct v4l2_ctrl_handler *ctrl_hdlr;
+       s64 exposure_max;
+       s64 vblank_def;
+       s64 vblank_min;
+       s64 hblank;
+       u64 pixel_rate;
+       const struct imx355_mode *mode;
+       u32 max;
+       int ret;
+
+       ctrl_hdlr = &imx355->ctrl_handler;
+       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
+       if (ret)
+               return ret;
+
+       ctrl_hdlr->lock = &imx355->mutex;
+       max = ARRAY_SIZE(link_freq_menu_items) - 1;
+       imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
+                                                  V4L2_CID_LINK_FREQ, max, 0,
+                                                  link_freq_menu_items);
+       if (imx355->link_freq)
+               imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
+       pixel_rate = imx355->link_def_freq * 2 * 4;
+       do_div(pixel_rate, 10);
+       /* By default, PIXEL_RATE is read only */
+       imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
+                                              V4L2_CID_PIXEL_RATE, pixel_rate,
+                                              pixel_rate, 1, pixel_rate);
+
+       /* Initialize vblank/hblank/exposure parameters based on current mode */
+       mode = imx355->cur_mode;
+       vblank_def = mode->fll_def - mode->height;
+       vblank_min = mode->fll_min - mode->height;
+       imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
+                                          V4L2_CID_VBLANK, vblank_min,
+                                          IMX355_FLL_MAX - mode->height,
+                                          1, vblank_def);
+
+       hblank = mode->llp - mode->width;
+       imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
+                                          V4L2_CID_HBLANK, hblank, hblank,
+                                          1, hblank);
+       if (imx355->hblank)
+               imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       /* fll >= exposure time + adjust parameter (default value is 10) */
+       exposure_max = mode->fll_def - 10;
+       imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
+                                            V4L2_CID_EXPOSURE,
+                                            IMX355_EXPOSURE_MIN, exposure_max,
+                                            IMX355_EXPOSURE_STEP,
+                                            IMX355_EXPOSURE_DEFAULT);
+
+       imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
+                                         V4L2_CID_HFLIP, 0, 1, 1, 0);
+       imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
+                                         V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+       v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+                         IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX,
+                         IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT);
+
+       /* Digital gain */
+       v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+                         IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX,
+                         IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT);
+
+       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops,
+                                    V4L2_CID_TEST_PATTERN,
+                                    ARRAY_SIZE(imx355_test_pattern_menu) - 1,
+                                    0, 0, imx355_test_pattern_menu);
+       if (ctrl_hdlr->error) {
+               ret = ctrl_hdlr->error;
+               dev_err(&client->dev, "control init failed: %d", ret);
+               goto error;
+       }
+
+       imx355->sd.ctrl_handler = ctrl_hdlr;
+
+       return 0;
+
+error:
+       v4l2_ctrl_handler_free(ctrl_hdlr);
+
+       return ret;
+}
+
+static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
+{
+       struct imx355_hwcfg *cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = {
+               .bus_type = V4L2_MBUS_CSI2_DPHY
+       };
+       struct fwnode_handle *ep;
+       struct fwnode_handle *fwnode = dev_fwnode(dev);
+       unsigned int i;
+       int ret;
+
+       if (!fwnode)
+               return NULL;
+
+       ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+       if (!ep)
+               return NULL;
+
+       ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+       if (ret)
+               goto out_err;
+
+       cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
+       if (!cfg)
+               goto out_err;
+
+       ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+                                      &cfg->ext_clk);
+       if (ret) {
+               dev_err(dev, "can't get clock frequency");
+               goto out_err;
+       }
+
+       dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
+       if (cfg->ext_clk != IMX355_EXT_CLK) {
+               dev_err(dev, "external clock %d is not supported",
+                       cfg->ext_clk);
+               goto out_err;
+       }
+
+       dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
+       if (!bus_cfg.nr_of_link_frequencies) {
+               dev_warn(dev, "no link frequencies defined");
+               goto out_err;
+       }
+
+       cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
+       cfg->link_freqs = devm_kcalloc(dev,
+                                      bus_cfg.nr_of_link_frequencies + 1,
+                                      sizeof(*cfg->link_freqs), GFP_KERNEL);
+       if (!cfg->link_freqs)
+               goto out_err;
+
+       for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
+               cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
+               dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
+       }
+
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+       fwnode_handle_put(ep);
+       return cfg;
+
+out_err:
+       v4l2_fwnode_endpoint_free(&bus_cfg);
+       fwnode_handle_put(ep);
+       return NULL;
+}
+
+static int imx355_probe(struct i2c_client *client)
+{
+       struct imx355 *imx355;
+       int ret;
+       u32 i;
+
+       imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
+       if (!imx355)
+               return -ENOMEM;
+
+       mutex_init(&imx355->mutex);
+
+       /* Initialize subdev */
+       v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
+
+       /* Check module identity */
+       ret = imx355_identify_module(imx355);
+       if (ret) {
+               dev_err(&client->dev, "failed to find sensor: %d", ret);
+               goto error_probe;
+       }
+
+       imx355->hwcfg = imx355_get_hwcfg(&client->dev);
+       if (!imx355->hwcfg) {
+               dev_err(&client->dev, "failed to get hwcfg");
+               ret = -ENODEV;
+               goto error_probe;
+       }
+
+       imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
+       for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
+               if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
+                       dev_dbg(&client->dev, "link freq index %d matched", i);
+                       break;
+               }
+       }
+
+       if (i == imx355->hwcfg->nr_of_link_freqs) {
+               dev_err(&client->dev, "no link frequency supported");
+               ret = -EINVAL;
+               goto error_probe;
+       }
+
+       /* Set default mode to max resolution */
+       imx355->cur_mode = &supported_modes[0];
+
+       ret = imx355_init_controls(imx355);
+       if (ret) {
+               dev_err(&client->dev, "failed to init controls: %d", ret);
+               goto error_probe;
+       }
+
+       /* Initialize subdev */
+       imx355->sd.internal_ops = &imx355_internal_ops;
+       imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+               V4L2_SUBDEV_FL_HAS_EVENTS;
+       imx355->sd.entity.ops = &imx355_subdev_entity_ops;
+       imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+       /* Initialize source pad */
+       imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
+       if (ret) {
+               dev_err(&client->dev, "failed to init entity pads: %d", ret);
+               goto error_handler_free;
+       }
+
+       ret = v4l2_async_register_subdev_sensor_common(&imx355->sd);
+       if (ret < 0)
+               goto error_media_entity;
+
+       /*
+        * Device is already turned on by i2c-core with ACPI domain PM.
+        * Enable runtime PM and turn off the device.
+        */
+       pm_runtime_set_active(&client->dev);
+       pm_runtime_enable(&client->dev);
+       pm_runtime_idle(&client->dev);
+
+       return 0;
+
+error_media_entity:
+       media_entity_cleanup(&imx355->sd.entity);
+
+error_handler_free:
+       v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
+
+error_probe:
+       mutex_destroy(&imx355->mutex);
+
+       return ret;
+}
+
+static int imx355_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct imx355 *imx355 = to_imx355(sd);
+
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+
+       pm_runtime_disable(&client->dev);
+       pm_runtime_set_suspended(&client->dev);
+
+       mutex_destroy(&imx355->mutex);
+
+       return 0;
+}
+
+static const struct dev_pm_ops imx355_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume)
+};
+
+static const struct acpi_device_id imx355_acpi_ids[] = {
+       { "SONY355A" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
+
+static struct i2c_driver imx355_i2c_driver = {
+       .driver = {
+               .name = "imx355",
+               .pm = &imx355_pm_ops,
+               .acpi_match_table = ACPI_PTR(imx355_acpi_ids),
+       },
+       .probe_new = imx355_probe,
+       .remove = imx355_remove,
+};
+module_i2c_driver(imx355_i2c_driver);
+
+MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
+MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
+MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
+MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
+MODULE_DESCRIPTION("Sony imx355 sensor driver");
+MODULE_LICENSE("GPL v2");
index 49c6644cbba777eaa2b03c182d9e1f660abb6ce5..f122f03bd6b79adeb6efbeb88656d785f1db29d1 100644 (file)
@@ -362,7 +362,8 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
 
        v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops);
        flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-       strcpy(flash->subdev_led[led_no].name, led_name);
+       strscpy(flash->subdev_led[led_no].name, led_name,
+               sizeof(flash->subdev_led[led_no].name));
        rval = lm3560_init_controls(flash, led_no);
        if (rval)
                goto err_out;
index 7e9967af36ecd36a74dff0bc012bc2a2bed8fb72..12ef2653987b8c37a22338a0003d95828d4fa1e5 100644 (file)
@@ -278,7 +278,8 @@ static int lm3646_subdev_init(struct lm3646_flash *flash)
 
        v4l2_i2c_subdev_init(&flash->subdev_led, client, &lm3646_ops);
        flash->subdev_led.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-       strcpy(flash->subdev_led.name, LM3646_NAME);
+       strscpy(flash->subdev_led.name, LM3646_NAME,
+               sizeof(flash->subdev_led.name));
        rval = lm3646_init_controls(flash);
        if (rval)
                goto err_out;
index 12e79f9e32d53c090a001bc1036398a209cb9de1..b8b2bf4cbfb253f4a1bd1d131cadcca325b55090 100644 (file)
@@ -987,7 +987,8 @@ static int m5mols_probe(struct i2c_client *client,
 
        sd = &info->sd;
        v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
-       strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
+       /* Static name; NEVER use in new drivers! */
+       strscpy(sd->name, MODULE_NAME, sizeof(sd->name));
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
        sd->internal_ops = &m5mols_subdev_internal_ops;
index 008a082cb8ad73f2d433f268013694c5f7f86740..7b226fadcdb86ca2c7d559cbcc2c2c62d7d463cf 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Maxim Integrated MAX2175 RF to Bits tuner driver
  *
@@ -6,15 +7,6 @@
  *
  * Copyright (C) 2016 Maxim Integrated Products
  * Copyright (C) 2017 Renesas Electronics Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
  */
 
 #include <linux/clk.h>
@@ -1165,7 +1157,7 @@ static int max2175_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
        if (vt->index > 0)
                return -EINVAL;
 
-       strlcpy(vt->name, "RF", sizeof(vt->name));
+       strscpy(vt->name, "RF", sizeof(vt->name));
        vt->type = V4L2_TUNER_RF;
        vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
        vt->rangelow = ctx->bands_rf->rangelow;
index eb43373ce7e2f2e9f6d6e9a71fd21308885abde2..1ece587c153d7335951afb64cf71e5bab5b0dfd7 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * Maxim Integrated MAX2175 RF to Bits tuner driver
  *
  * This driver & most of the hard coded values are based on the reference
@@ -6,15 +7,6 @@
  *
  * Copyright (C) 2016 Maxim Integrated Products
  * Copyright (C) 2017 Renesas Electronics Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
  */
 
 #ifndef __MAX2175_H__
index 3db966db83eb50c6888549c062fefd05ae591da9..c63be01059b24a28db26d1cfb3d0752701757019 100644 (file)
@@ -688,7 +688,7 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
 #endif
 
        if (!id)
-               strlcpy(client->name, "msp3400", sizeof(client->name));
+               strscpy(client->name, "msp3400", sizeof(client->name));
 
        if (msp_reset(client) == -1) {
                dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3400 not found\n");
@@ -703,8 +703,10 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
        v4l2_i2c_subdev_init(sd, client, &msp_ops);
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       state->pads[IF_AUD_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       state->pads[IF_AUD_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[MSP3400_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       state->pads[MSP3400_PAD_IF_INPUT].sig_type = PAD_SIGNAL_AUDIO;
+       state->pads[MSP3400_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[MSP3400_PAD_OUT].sig_type = PAD_SIGNAL_AUDIO;
 
        sd->entity.function = MEDIA_ENT_F_IF_AUD_DECODER;
 
index b6c7698bce5a1fe983d97e88e6176b9806be001b..2bb9d5ff1bbde5936ccf9a277c39aa20ae0c01e6 100644 (file)
@@ -52,6 +52,12 @@ extern int msp_standard;
 extern bool msp_dolby;
 extern int msp_stereo_thresh;
 
+enum msp3400_pads {
+       MSP3400_PAD_IF_INPUT,
+       MSP3400_PAD_OUT,
+       MSP3400_NUM_PADS
+};
+
 struct msp_state {
        struct v4l2_subdev sd;
        struct v4l2_ctrl_handler hdl;
@@ -106,7 +112,7 @@ struct msp_state {
        unsigned int         watch_stereo:1;
 
 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
-       struct media_pad pads[IF_AUD_DEC_PAD_NUM_PADS];
+       struct media_pad pads[MSP3400_NUM_PADS];
 #endif
 };
 
index efda1aa95ca023d0fde2cb6ac7585444170f9659..1395986a07bb80faa85c938ece6bf917c303e0a3 100644 (file)
@@ -445,7 +445,6 @@ static int mt9m111_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
                sel->r.left = MT9M111_MIN_DARK_COLS;
                sel->r.top = MT9M111_MIN_DARK_ROWS;
                sel->r.width = MT9M111_MAX_WIDTH;
index af8cca9842154cd70082b06025b74c6325dfbeee..ef353a244e33ff2802d4c90ddda963ed512f25ff 100644 (file)
@@ -888,12 +888,6 @@ static int mt9t112_get_selection(struct v4l2_subdev *sd,
                sel->r.width = MAX_WIDTH;
                sel->r.height = MAX_HEIGHT;
                return 0;
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.left = 0;
-               sel->r.top = 0;
-               sel->r.width = VGA_WIDTH;
-               sel->r.height = VGA_HEIGHT;
-               return 0;
        case V4L2_SEL_TGT_CROP:
                sel->r = priv->frame;
                return 0;
index f74730d24d8fe38bf049fb3020fa5493c2f64a49..67f69ad6ecf44d04d2359f4739dbbd41721fd91e 100644 (file)
@@ -989,7 +989,7 @@ static struct mt9v032_platform_data *
 mt9v032_get_pdata(struct i2c_client *client)
 {
        struct mt9v032_platform_data *pdata = NULL;
-       struct v4l2_fwnode_endpoint endpoint;
+       struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
        struct device_node *np;
        struct property *prop;
 
index 88c498ad45dfb01aa089090609307ed3ce29673c..11479e65a9ae15c30a4e2b2d761774109c6f79b0 100644 (file)
@@ -720,7 +720,8 @@ static int noon010_probe(struct i2c_client *client,
        mutex_init(&info->lock);
        sd = &info->sd;
        v4l2_i2c_subdev_init(sd, client, &noon010_ops);
-       strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
+       /* Static name; NEVER use in new drivers! */
+       strscpy(sd->name, MODULE_NAME, sizeof(sd->name));
 
        sd->internal_ops = &noon010_subdev_internal_ops;
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index a66f6201f53c71e73306ff3d1942d47ba08d6fef..c8bbc1f522619504e8053f825183fa71865bb5bb 100644 (file)
@@ -1230,7 +1230,7 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
         * Applying V4L2 control value only happens
         * when power is up for streaming
         */
-       if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+       if (!pm_runtime_get_if_in_use(&client->dev))
                return 0;
 
        ret = 0;
@@ -1735,10 +1735,9 @@ static int ov13858_probe(struct i2c_client *client,
         * Device is already turned on by i2c-core with ACPI domain PM.
         * Enable runtime PM and turn off the device.
         */
-       pm_runtime_get_noresume(&client->dev);
        pm_runtime_set_active(&client->dev);
        pm_runtime_enable(&client->dev);
-       pm_runtime_put(&client->dev);
+       pm_runtime_idle(&client->dev);
 
        return 0;
 
@@ -1761,14 +1760,7 @@ static int ov13858_remove(struct i2c_client *client)
        media_entity_cleanup(&sd->entity);
        ov13858_free_controls(ov13858);
 
-       /*
-        * Disable runtime PM but keep the device turned on.
-        * i2c-core with ACPI domain PM will turn off the device.
-        */
-       pm_runtime_get_sync(&client->dev);
        pm_runtime_disable(&client->dev);
-       pm_runtime_set_suspended(&client->dev);
-       pm_runtime_put_noidle(&client->dev);
 
        return 0;
 }
index beb722065152e57fabec16cfbe9d8c790843cdf1..20a8853ba1e29a815386698c10756a5250c1e098 100644 (file)
@@ -1010,7 +1010,6 @@ static int ov2640_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
        case V4L2_SEL_TGT_CROP:
                sel->r.left = 0;
                sel->r.top = 0;
index 4715edc8ca33e2ef2d73fbf8a6eb32ba5099ae5b..799acce803fe5ee4d504a01a55fc20bae36b19a1 100644 (file)
@@ -1347,8 +1347,9 @@ static struct ov2659_platform_data *
 ov2659_get_pdata(struct i2c_client *client)
 {
        struct ov2659_platform_data *pdata;
-       struct v4l2_fwnode_endpoint *bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct device_node *endpoint;
+       int ret;
 
        if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
                return client->dev.platform_data;
@@ -1357,8 +1358,9 @@ ov2659_get_pdata(struct i2c_client *client)
        if (!endpoint)
                return NULL;
 
-       bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint));
-       if (IS_ERR(bus_cfg)) {
+       ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint),
+                                              &bus_cfg);
+       if (ret) {
                pdata = NULL;
                goto done;
        }
@@ -1367,17 +1369,17 @@ ov2659_get_pdata(struct i2c_client *client)
        if (!pdata)
                goto done;
 
-       if (!bus_cfg->nr_of_link_frequencies) {
+       if (!bus_cfg.nr_of_link_frequencies) {
                dev_err(&client->dev,
                        "link-frequencies property not found or too many\n");
                pdata = NULL;
                goto done;
        }
 
-       pdata->link_frequency = bus_cfg->link_frequencies[0];
+       pdata->link_frequency = bus_cfg.link_frequencies[0];
 
 done:
-       v4l2_fwnode_endpoint_free(bus_cfg);
+       v4l2_fwnode_endpoint_free(&bus_cfg);
        of_node_put(endpoint);
        return pdata;
 }
index f753a1c333ef9b7f10963fca1f1f7b7817900997..0e34e15b67b336791a4098f8cf5d5a726dcd91f2 100644 (file)
@@ -926,7 +926,7 @@ static int ov2680_mode_init(struct ov2680_dev *sensor)
        return 0;
 }
 
-static int ov2680_v4l2_init(struct ov2680_dev *sensor)
+static int ov2680_v4l2_register(struct ov2680_dev *sensor)
 {
        const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
        struct ov2680_ctrls *ctrls = &sensor->ctrls;
@@ -1088,26 +1088,20 @@ static int ov2680_probe(struct i2c_client *client)
 
        mutex_init(&sensor->lock);
 
-       ret = ov2680_v4l2_init(sensor);
+       ret = ov2680_check_id(sensor);
        if (ret < 0)
                goto lock_destroy;
 
-       ret = ov2680_check_id(sensor);
+       ret = ov2680_v4l2_register(sensor);
        if (ret < 0)
-               goto error_cleanup;
+               goto lock_destroy;
 
        dev_info(dev, "ov2680 init correctly\n");
 
        return 0;
 
-error_cleanup:
-       dev_err(dev, "ov2680 init fail: %d\n", ret);
-
-       media_entity_cleanup(&sensor->sd.entity);
-       v4l2_async_unregister_subdev(&sensor->sd);
-       v4l2_ctrl_handler_free(&sensor->ctrls.handler);
-
 lock_destroy:
+       dev_err(dev, "ov2680 init fail: %d\n", ret);
        mutex_destroy(&sensor->lock);
 
        return ret;
index 385c1886a9470a1ad4153b61493501803be5ee5c..98a1f2e312b58249069de19f7b3c78dc4bf4e85d 100644 (file)
@@ -549,7 +549,7 @@ static int ov2685_set_ctrl(struct v4l2_ctrl *ctrl)
                break;
        }
 
-       if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+       if (!pm_runtime_get_if_in_use(&client->dev))
                return 0;
 
        switch (ctrl->id) {
index 071f4bc240ca72a1162b354170bdcf956a4d4f89..eaefdb58653b700bb639adc6b26a44e0f5fd514c 100644 (file)
@@ -223,8 +223,10 @@ struct ov5640_dev {
        int power_count;
 
        struct v4l2_mbus_framefmt fmt;
+       bool pending_fmt_change;
 
        const struct ov5640_mode_info *current_mode;
+       const struct ov5640_mode_info *last_mode;
        enum ov5640_frame_rate current_fr;
        struct v4l2_fract frame_interval;
 
@@ -255,7 +257,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
  * should be identified and removed to speed register load time
  * over i2c.
  */
-
+/* YUV422 UYVY VGA@30fps */
 static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
        {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
        {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
@@ -286,10 +288,10 @@ static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
        {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
        {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
        {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
-       {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+       {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
        {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
        {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
-       {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+       {0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0},
        {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
        {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
        {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
@@ -606,7 +608,7 @@ static const struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
        {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
        {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
        {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
-       {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
+       {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
        {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
        {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
 };
@@ -908,6 +910,26 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg,
 }
 
 /* download ov5640 settings to sensor through i2c */
+static int ov5640_set_timings(struct ov5640_dev *sensor,
+                             const struct ov5640_mode_info *mode)
+{
+       int ret;
+
+       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
+       if (ret < 0)
+               return ret;
+
+       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
+       if (ret < 0)
+               return ret;
+
+       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
+       if (ret < 0)
+               return ret;
+
+       return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
+}
+
 static int ov5640_load_regs(struct ov5640_dev *sensor,
                            const struct ov5640_mode_info *mode)
 {
@@ -935,7 +957,13 @@ static int ov5640_load_regs(struct ov5640_dev *sensor,
                        usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
        }
 
-       return ret;
+       return ov5640_set_timings(sensor, mode);
+}
+
+static int ov5640_set_autoexposure(struct ov5640_dev *sensor, bool on)
+{
+       return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
+                             BIT(0), on ? 0 : BIT(0));
 }
 
 /* read exposure, in number of line periods */
@@ -994,6 +1022,18 @@ static int ov5640_get_gain(struct ov5640_dev *sensor)
        return gain & 0x3ff;
 }
 
+static int ov5640_set_gain(struct ov5640_dev *sensor, int gain)
+{
+       return ov5640_write_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN,
+                                 (u16)gain & 0x3ff);
+}
+
+static int ov5640_set_autogain(struct ov5640_dev *sensor, bool on)
+{
+       return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
+                             BIT(1), on ? 0 : BIT(1));
+}
+
 static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
 {
        int ret;
@@ -1102,12 +1142,25 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
 {
        int ret;
 
-       ret = ov5640_mod_reg(sensor, OV5640_REG_MIPI_CTRL00, BIT(5),
-                            on ? 0 : BIT(5));
-       if (ret)
-               return ret;
-       ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00,
-                              on ? 0x00 : 0x70);
+       /*
+        * Enable/disable the MIPI interface
+        *
+        * 0x300e = on ? 0x45 : 0x40
+        *
+        * FIXME: the sensor manual (version 2.03) reports
+        * [7:5] = 000  : 1 data lane mode
+        * [7:5] = 001  : 2 data lanes mode
+        * But this settings do not work, while the following ones
+        * have been validated for 2 data lanes mode.
+        *
+        * [7:5] = 010  : 2 data lanes mode
+        * [4] = 0      : Power up MIPI HS Tx
+        * [3] = 0      : Power up MIPI LS Rx
+        * [2] = 1/0    : MIPI interface enable/disable
+        * [1:0] = 01/00: FIXME: 'debug'
+        */
+       ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00,
+                              on ? 0x45 : 0x40);
        if (ret)
                return ret;
 
@@ -1331,7 +1384,7 @@ static int ov5640_set_ae_target(struct ov5640_dev *sensor, int target)
        return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1F, fast_low);
 }
 
-static int ov5640_binning_on(struct ov5640_dev *sensor)
+static int ov5640_get_binning(struct ov5640_dev *sensor)
 {
        u8 temp;
        int ret;
@@ -1339,8 +1392,8 @@ static int ov5640_binning_on(struct ov5640_dev *sensor)
        ret = ov5640_read_reg(sensor, OV5640_REG_TIMING_TC_REG21, &temp);
        if (ret)
                return ret;
-       temp &= 0xfe;
-       return temp ? 1 : 0;
+
+       return temp & BIT(0);
 }
 
 static int ov5640_set_binning(struct ov5640_dev *sensor, bool enable)
@@ -1385,30 +1438,6 @@ static int ov5640_set_virtual_channel(struct ov5640_dev *sensor)
        return ov5640_write_reg(sensor, OV5640_REG_DEBUG_MODE, temp);
 }
 
-static int ov5640_set_timings(struct ov5640_dev *sensor,
-                             const struct ov5640_mode_info *mode)
-{
-       int ret;
-
-       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
-       if (ret < 0)
-               return ret;
-
-       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
-       if (ret < 0)
-               return ret;
-
-       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
-       if (ret < 0)
-               return ret;
-
-       ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
 static const struct ov5640_mode_info *
 ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
                 int width, int height, bool nearest)
@@ -1450,7 +1479,7 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
        if (ret < 0)
                return ret;
        prev_shutter = ret;
-       ret = ov5640_binning_on(sensor);
+       ret = ov5640_get_binning(sensor);
        if (ret < 0)
                return ret;
        if (ret && mode->id != OV5640_MODE_720P_1280_720 &&
@@ -1571,7 +1600,7 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
        }
 
        /* set capture gain */
-       ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.gain, cap_gain16);
+       ret = ov5640_set_gain(sensor, cap_gain16);
        if (ret)
                return ret;
 
@@ -1584,7 +1613,7 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
        }
 
        /* set exposure */
-       return __v4l2_ctrl_s_ctrl(sensor->ctrls.exposure, cap_shutter);
+       return ov5640_set_exposure(sensor, cap_shutter);
 }
 
 /*
@@ -1592,53 +1621,45 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
  * change mode directly
  */
 static int ov5640_set_mode_direct(struct ov5640_dev *sensor,
-                                 const struct ov5640_mode_info *mode,
-                                 s32 exposure)
+                                 const struct ov5640_mode_info *mode)
 {
-       int ret;
-
        if (!mode->reg_data)
                return -EINVAL;
 
        /* Write capture setting */
-       ret = ov5640_load_regs(sensor, mode);
-       if (ret < 0)
-               return ret;
-
-       /* turn auto gain/exposure back on for direct mode */
-       ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.auto_gain, 1);
-       if (ret)
-               return ret;
-
-       return __v4l2_ctrl_s_ctrl(sensor->ctrls.auto_exp, exposure);
+       return ov5640_load_regs(sensor, mode);
 }
 
-static int ov5640_set_mode(struct ov5640_dev *sensor,
-                          const struct ov5640_mode_info *orig_mode)
+static int ov5640_set_mode(struct ov5640_dev *sensor)
 {
        const struct ov5640_mode_info *mode = sensor->current_mode;
+       const struct ov5640_mode_info *orig_mode = sensor->last_mode;
        enum ov5640_downsize_mode dn_mode, orig_dn_mode;
-       s32 exposure;
+       bool auto_gain = sensor->ctrls.auto_gain->val == 1;
+       bool auto_exp =  sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO;
        int ret;
 
        dn_mode = mode->dn_mode;
        orig_dn_mode = orig_mode->dn_mode;
 
        /* auto gain and exposure must be turned off when changing modes */
-       ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.auto_gain, 0);
-       if (ret)
-               return ret;
+       if (auto_gain) {
+               ret = ov5640_set_autogain(sensor, false);
+               if (ret)
+                       return ret;
+       }
 
-       exposure = sensor->ctrls.auto_exp->val;
-       ret = ov5640_set_exposure(sensor, V4L2_EXPOSURE_MANUAL);
-       if (ret)
-               return ret;
+       if (auto_exp) {
+               ret = ov5640_set_autoexposure(sensor, false);
+               if (ret)
+                       goto restore_auto_gain;
+       }
 
        if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
            (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
                /*
                 * change between subsampling and scaling
-                * go through exposure calucation
+                * go through exposure calculation
                 */
                ret = ov5640_set_mode_exposure_calc(sensor, mode);
        } else {
@@ -1646,15 +1667,16 @@ static int ov5640_set_mode(struct ov5640_dev *sensor,
                 * change inside subsampling or scaling
                 * download firmware directly
                 */
-               ret = ov5640_set_mode_direct(sensor, mode, exposure);
+               ret = ov5640_set_mode_direct(sensor, mode);
        }
-
        if (ret < 0)
-               return ret;
+               goto restore_auto_exp_gain;
 
-       ret = ov5640_set_timings(sensor, mode);
-       if (ret < 0)
-               return ret;
+       /* restore auto gain and exposure */
+       if (auto_gain)
+               ov5640_set_autogain(sensor, true);
+       if (auto_exp)
+               ov5640_set_autoexposure(sensor, true);
 
        ret = ov5640_set_binning(sensor, dn_mode != SCALING);
        if (ret < 0)
@@ -1673,8 +1695,18 @@ static int ov5640_set_mode(struct ov5640_dev *sensor,
                return ret;
 
        sensor->pending_mode_change = false;
+       sensor->last_mode = mode;
 
        return 0;
+
+restore_auto_exp_gain:
+       if (auto_exp)
+               ov5640_set_autoexposure(sensor, true);
+restore_auto_gain:
+       if (auto_gain)
+               ov5640_set_autogain(sensor, true);
+
+       return ret;
 }
 
 static int ov5640_set_framefmt(struct ov5640_dev *sensor,
@@ -1689,6 +1721,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
        ret = ov5640_load_regs(sensor, &ov5640_mode_init_data);
        if (ret < 0)
                return ret;
+       sensor->last_mode = &ov5640_mode_init_data;
 
        ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x3f,
                             (ilog2(OV5640_SCLK2X_ROOT_DIVIDER_DEFAULT) << 2) |
@@ -1697,7 +1730,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
                return ret;
 
        /* now restore the last capture mode */
-       ret = ov5640_set_mode(sensor, &ov5640_mode_init_data);
+       ret = ov5640_set_mode(sensor);
        if (ret < 0)
                return ret;
 
@@ -1786,23 +1819,69 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
                if (ret)
                        goto power_off;
 
-               if (sensor->ep.bus_type == V4L2_MBUS_CSI2) {
-                       /*
-                        * start streaming briefly followed by stream off in
-                        * order to coax the clock lane into LP-11 state.
-                        */
-                       ret = ov5640_set_stream_mipi(sensor, true);
-                       if (ret)
-                               goto power_off;
-                       usleep_range(1000, 2000);
-                       ret = ov5640_set_stream_mipi(sensor, false);
-                       if (ret)
-                               goto power_off;
+               /* We're done here for DVP bus, while CSI-2 needs setup. */
+               if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
+                       return 0;
+
+               /*
+                * Power up MIPI HS Tx and LS Rx; 2 data lanes mode
+                *
+                * 0x300e = 0x40
+                * [7:5] = 010  : 2 data lanes mode (see FIXME note in
+                *                "ov5640_set_stream_mipi()")
+                * [4] = 0      : Power up MIPI HS Tx
+                * [3] = 0      : Power up MIPI LS Rx
+                * [2] = 0      : MIPI interface disabled
+                */
+               ret = ov5640_write_reg(sensor,
+                                      OV5640_REG_IO_MIPI_CTRL00, 0x40);
+               if (ret)
+                       goto power_off;
+
+               /*
+                * Gate clock and set LP11 in 'no packets mode' (idle)
+                *
+                * 0x4800 = 0x24
+                * [5] = 1      : Gate clock when 'no packets'
+                * [2] = 1      : MIPI bus in LP11 when 'no packets'
+                */
+               ret = ov5640_write_reg(sensor,
+                                      OV5640_REG_MIPI_CTRL00, 0x24);
+               if (ret)
+                       goto power_off;
+
+               /*
+                * Set data lanes and clock in LP11 when 'sleeping'
+                *
+                * 0x3019 = 0x70
+                * [6] = 1      : MIPI data lane 2 in LP11 when 'sleeping'
+                * [5] = 1      : MIPI data lane 1 in LP11 when 'sleeping'
+                * [4] = 1      : MIPI clock lane in LP11 when 'sleeping'
+                */
+               ret = ov5640_write_reg(sensor,
+                                      OV5640_REG_PAD_OUTPUT00, 0x70);
+               if (ret)
+                       goto power_off;
+
+               /* Give lanes some time to coax into LP11 state. */
+               usleep_range(500, 1000);
+
+       } else {
+               if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
+                       /* Reset MIPI bus settings to their default values. */
+                       ov5640_write_reg(sensor,
+                                        OV5640_REG_IO_MIPI_CTRL00, 0x58);
+                       ov5640_write_reg(sensor,
+                                        OV5640_REG_MIPI_CTRL00, 0x04);
+                       ov5640_write_reg(sensor,
+                                        OV5640_REG_PAD_OUTPUT00, 0x00);
                }
 
-               return 0;
+               ov5640_set_power_off(sensor);
        }
 
+       return 0;
+
 power_off:
        ov5640_set_power_off(sensor);
        return ret;
@@ -1968,9 +2047,12 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
 
        if (new_mode != sensor->current_mode) {
                sensor->current_mode = new_mode;
-               sensor->fmt = *mbus_fmt;
                sensor->pending_mode_change = true;
        }
+       if (mbus_fmt->code != sensor->fmt.code) {
+               sensor->fmt = *mbus_fmt;
+               sensor->pending_fmt_change = true;
+       }
 out:
        mutex_unlock(&sensor->lock);
        return ret;
@@ -2137,20 +2219,20 @@ static int ov5640_set_ctrl_white_balance(struct ov5640_dev *sensor, int awb)
        return ret;
 }
 
-static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor, int exp)
+static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor,
+                                   enum v4l2_exposure_auto_type auto_exposure)
 {
        struct ov5640_ctrls *ctrls = &sensor->ctrls;
-       bool auto_exposure = (exp == V4L2_EXPOSURE_AUTO);
+       bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
        int ret = 0;
 
        if (ctrls->auto_exp->is_new) {
-               ret = ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
-                                    BIT(0), auto_exposure ? 0 : BIT(0));
+               ret = ov5640_set_autoexposure(sensor, auto_exp);
                if (ret)
                        return ret;
        }
 
-       if (!auto_exposure && ctrls->exposure->is_new) {
+       if (!auto_exp && ctrls->exposure->is_new) {
                u16 max_exp;
 
                ret = ov5640_read_reg16(sensor, OV5640_REG_AEC_PK_VTS,
@@ -2170,25 +2252,19 @@ static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor, int exp)
        return ret;
 }
 
-static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, int auto_gain)
+static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, bool auto_gain)
 {
        struct ov5640_ctrls *ctrls = &sensor->ctrls;
        int ret = 0;
 
        if (ctrls->auto_gain->is_new) {
-               ret = ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
-                                    BIT(1),
-                                    ctrls->auto_gain->val ? 0 : BIT(1));
+               ret = ov5640_set_autogain(sensor, auto_gain);
                if (ret)
                        return ret;
        }
 
-       if (!auto_gain && ctrls->gain->is_new) {
-               u16 gain = (u16)ctrls->gain->val;
-
-               ret = ov5640_write_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN,
-                                        gain & 0x3ff);
-       }
+       if (!auto_gain && ctrls->gain->is_new)
+               ret = ov5640_set_gain(sensor, ctrls->gain->val);
 
        return ret;
 }
@@ -2261,16 +2337,12 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 
        switch (ctrl->id) {
        case V4L2_CID_AUTOGAIN:
-               if (!ctrl->val)
-                       return 0;
                val = ov5640_get_gain(sensor);
                if (val < 0)
                        return val;
                sensor->ctrls.gain->val = val;
                break;
        case V4L2_CID_EXPOSURE_AUTO:
-               if (ctrl->val == V4L2_EXPOSURE_MANUAL)
-                       return 0;
                val = ov5640_get_exposure(sensor);
                if (val < 0)
                        return val;
@@ -2501,8 +2573,6 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
        if (frame_rate < 0)
                frame_rate = OV5640_15_FPS;
 
-       sensor->current_fr = frame_rate;
-       sensor->frame_interval = fi->interval;
        mode = ov5640_find_mode(sensor, frame_rate, mode->hact,
                                mode->vact, true);
        if (!mode) {
@@ -2510,7 +2580,10 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
                goto out;
        }
 
-       if (mode != sensor->current_mode) {
+       if (mode != sensor->current_mode ||
+           frame_rate != sensor->current_fr) {
+               sensor->current_fr = frame_rate;
+               sensor->frame_interval = fi->interval;
                sensor->current_mode = mode;
                sensor->pending_mode_change = true;
        }
@@ -2541,16 +2614,19 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
 
        if (sensor->streaming == !enable) {
                if (enable && sensor->pending_mode_change) {
-                       ret = ov5640_set_mode(sensor, sensor->current_mode);
+                       ret = ov5640_set_mode(sensor);
                        if (ret)
                                goto out;
+               }
 
+               if (enable && sensor->pending_fmt_change) {
                        ret = ov5640_set_framefmt(sensor, &sensor->fmt);
                        if (ret)
                                goto out;
+                       sensor->pending_fmt_change = false;
                }
 
-               if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
+               if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
                        ret = ov5640_set_stream_mipi(sensor, enable);
                else
                        ret = ov5640_set_stream_dvp(sensor, enable);
@@ -2642,9 +2718,14 @@ static int ov5640_probe(struct i2c_client *client,
                return -ENOMEM;
 
        sensor->i2c_client = client;
+
+       /*
+        * default init sequence initialize sensor to
+        * YUV422 UYVY VGA@30fps
+        */
        fmt = &sensor->fmt;
-       fmt->code = ov5640_formats[0].code;
-       fmt->colorspace = ov5640_formats[0].colorspace;
+       fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       fmt->colorspace = V4L2_COLORSPACE_SRGB;
        fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
        fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
        fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
@@ -2656,7 +2737,7 @@ static int ov5640_probe(struct i2c_client *client,
        sensor->current_fr = OV5640_30_FPS;
        sensor->current_mode =
                &ov5640_mode_data[OV5640_30_FPS][OV5640_MODE_VGA_640_480];
-       sensor->pending_mode_change = true;
+       sensor->last_mode = sensor->current_mode;
 
        sensor->ae_target = 52;
 
index 1722cdab0daf2ae1b4a7c444ddb29cc48be5d3f0..5eba8dd7222bc5f405f5433e8f81aff6ea204000 100644 (file)
@@ -1127,7 +1127,7 @@ static int ov5645_probe(struct i2c_client *client,
                return ret;
        }
 
-       if (ov5645->ep.bus_type != V4L2_MBUS_CSI2) {
+       if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(dev, "invalid bus type, must be CSI2\n");
                return -EINVAL;
        }
index da39c49de503c260b3cc78bed1c7a13c57472bf0..4589631798c968a41116169ccdd9e6cd9b26b800 100644 (file)
@@ -532,7 +532,7 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
 
 static int ov5647_parse_dt(struct device_node *np)
 {
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct device_node *ep;
 
        int ret;
index 7b7c74d7737075c3e2dd5402342afd08edf40cc7..041fcbb4eebdf8cd4e6c44ee95042956e6da7074 100644 (file)
@@ -2016,7 +2016,7 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
        }
 
        /* V4L2 controls values will be applied only when power is already up */
-       if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+       if (!pm_runtime_get_if_in_use(&client->dev))
                return 0;
 
        switch (ctrl->id) {
@@ -2504,10 +2504,9 @@ static int ov5670_probe(struct i2c_client *client)
         * Device is already turned on by i2c-core with ACPI domain PM.
         * Enable runtime PM and turn off the device.
         */
-       pm_runtime_get_noresume(&client->dev);
        pm_runtime_set_active(&client->dev);
        pm_runtime_enable(&client->dev);
-       pm_runtime_put(&client->dev);
+       pm_runtime_idle(&client->dev);
 
        return 0;
 
@@ -2536,14 +2535,7 @@ static int ov5670_remove(struct i2c_client *client)
        v4l2_ctrl_handler_free(sd->ctrl_handler);
        mutex_destroy(&ov5670->mutex);
 
-       /*
-        * Disable runtime PM but keep the device turned on.
-        * i2c-core with ACPI domain PM will turn off the device.
-        */
-       pm_runtime_get_sync(&client->dev);
        pm_runtime_disable(&client->dev);
-       pm_runtime_set_suspended(&client->dev);
-       pm_runtime_put_noidle(&client->dev);
 
        return 0;
 }
index 9a80decd93d3c0ed5e011734dc8ea5c4211085a2..5d107c53364d64249374431d7c1a236ead06e4b4 100644 (file)
@@ -1110,7 +1110,7 @@ static int ov5695_set_ctrl(struct v4l2_ctrl *ctrl)
                break;
        }
 
-       if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+       if (!pm_runtime_get_if_in_use(&client->dev))
                return 0;
 
        switch (ctrl->id) {
index 17a34b4a819d32187589cbd045853ec3999995aa..5d1b218bb7f0832804b334f0061e92ee91f1854d 100644 (file)
@@ -449,7 +449,6 @@ static int ov6650_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
                sel->r.left = DEF_HSTRT << 1;
                sel->r.top = DEF_VSTRT << 1;
                sel->r.width = W_CIF;
index d3ebb7529fca9e6b181e0365ce4efed903426cae..0c10203f822b128569811fb2dfe698ace925ff6b 100644 (file)
@@ -1279,9 +1279,9 @@ static int ov7251_probe(struct i2c_client *client)
                return ret;
        }
 
-       if (ov7251->ep.bus_type != V4L2_MBUS_CSI2) {
+       if (ov7251->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(dev, "invalid bus type (%u), must be CSI2 (%u)\n",
-                       ov7251->ep.bus_type, V4L2_MBUS_CSI2);
+                       ov7251->ep.bus_type, V4L2_MBUS_CSI2_DPHY);
                return -EINVAL;
        }
 
index 31bf577b0bd3024b900cfdfc9dbe4b7860b5113c..bc68a3a5b4ec41fe64b6ba462e18f7eaf62614af 100644 (file)
@@ -1728,7 +1728,7 @@ static int ov7670_parse_dt(struct device *dev,
                           struct ov7670_info *info)
 {
        struct fwnode_handle *fwnode = dev_fwnode(dev);
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct fwnode_handle *ep;
        int ret;
 
@@ -1808,17 +1808,24 @@ static int ov7670_probe(struct i2c_client *client,
                        info->pclk_hb_disable = true;
        }
 
-       info->clk = devm_clk_get(&client->dev, "xclk");
-       if (IS_ERR(info->clk))
-               return PTR_ERR(info->clk);
-       ret = clk_prepare_enable(info->clk);
-       if (ret)
-               return ret;
+       info->clk = devm_clk_get(&client->dev, "xclk"); /* optional */
+       if (IS_ERR(info->clk)) {
+               ret = PTR_ERR(info->clk);
+               if (ret == -ENOENT)
+                       info->clk = NULL;
+               else
+                       return ret;
+       }
+       if (info->clk) {
+               ret = clk_prepare_enable(info->clk);
+               if (ret)
+                       return ret;
 
-       info->clock_speed = clk_get_rate(info->clk) / 1000000;
-       if (info->clock_speed < 10 || info->clock_speed > 48) {
-               ret = -EINVAL;
-               goto clk_disable;
+               info->clock_speed = clk_get_rate(info->clk) / 1000000;
+               if (info->clock_speed < 10 || info->clock_speed > 48) {
+                       ret = -EINVAL;
+                       goto clk_disable;
+               }
        }
 
        ret = ov7670_init_gpio(client, info);
index 7158c31d8403be27483c6e1afa011ba8dc1912b2..fefff7fd7d686c98dd60680e9df6543f4696e9fa 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
@@ -414,6 +415,7 @@ struct ov772x_priv {
        struct v4l2_subdev                subdev;
        struct v4l2_ctrl_handler          hdl;
        struct clk                       *clk;
+       struct regmap                    *regmap;
        struct ov772x_camera_info        *info;
        struct gpio_desc                 *pwdn_gpio;
        struct gpio_desc                 *rstb_gpio;
@@ -549,51 +551,18 @@ static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd)
        return container_of(sd, struct ov772x_priv, subdev);
 }
 
-static int ov772x_read(struct i2c_client *client, u8 addr)
-{
-       int ret;
-       u8 val;
-
-       ret = i2c_master_send(client, &addr, 1);
-       if (ret < 0)
-               return ret;
-       ret = i2c_master_recv(client, &val, 1);
-       if (ret < 0)
-               return ret;
-
-       return val;
-}
-
-static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
-{
-       return i2c_smbus_write_byte_data(client, addr, value);
-}
-
-static int ov772x_mask_set(struct i2c_client *client, u8  command, u8  mask,
-                          u8  set)
-{
-       s32 val = ov772x_read(client, command);
-
-       if (val < 0)
-               return val;
-
-       val &= ~mask;
-       val |= set & mask;
-
-       return ov772x_write(client, command, val);
-}
-
-static int ov772x_reset(struct i2c_client *client)
+static int ov772x_reset(struct ov772x_priv *priv)
 {
        int ret;
 
-       ret = ov772x_write(client, COM7, SCCB_RESET);
+       ret = regmap_write(priv->regmap, COM7, SCCB_RESET);
        if (ret < 0)
                return ret;
 
        usleep_range(1000, 5000);
 
-       return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
+       return regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
+                                 SOFT_SLEEP_MODE);
 }
 
 /*
@@ -611,8 +580,8 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
        if (priv->streaming == enable)
                goto done;
 
-       ret = ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE,
-                             enable ? 0 : SOFT_SLEEP_MODE);
+       ret = regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
+                                enable ? 0 : SOFT_SLEEP_MODE);
        if (ret)
                goto done;
 
@@ -657,7 +626,6 @@ static int ov772x_set_frame_rate(struct ov772x_priv *priv,
                                 const struct ov772x_color_format *cfmt,
                                 const struct ov772x_win_size *win)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
        unsigned long fin = clk_get_rate(priv->clk);
        unsigned int best_diff;
        unsigned int fsize;
@@ -723,11 +691,11 @@ static int ov772x_set_frame_rate(struct ov772x_priv *priv,
                }
        }
 
-       ret = ov772x_write(client, COM4, com4 | COM4_RESERVED);
+       ret = regmap_write(priv->regmap, COM4, com4 | COM4_RESERVED);
        if (ret < 0)
                return ret;
 
-       ret = ov772x_write(client, CLKRC, clkrc | CLKRC_RESERVED);
+       ret = regmap_write(priv->regmap, CLKRC, clkrc | CLKRC_RESERVED);
        if (ret < 0)
                return ret;
 
@@ -788,8 +756,7 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct ov772x_priv *priv = container_of(ctrl->handler,
                                                struct ov772x_priv, hdl);
-       struct v4l2_subdev *sd = &priv->subdev;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct regmap *regmap = priv->regmap;
        int ret = 0;
        u8 val;
 
@@ -808,27 +775,27 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
                val = ctrl->val ? VFLIP_IMG : 0x00;
                if (priv->info && (priv->info->flags & OV772X_FLAG_VFLIP))
                        val ^= VFLIP_IMG;
-               return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
+               return regmap_update_bits(regmap, COM3, VFLIP_IMG, val);
        case V4L2_CID_HFLIP:
                val = ctrl->val ? HFLIP_IMG : 0x00;
                if (priv->info && (priv->info->flags & OV772X_FLAG_HFLIP))
                        val ^= HFLIP_IMG;
-               return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
+               return regmap_update_bits(regmap, COM3, HFLIP_IMG, val);
        case V4L2_CID_BAND_STOP_FILTER:
                if (!ctrl->val) {
                        /* Switch the filter off, it is on now */
-                       ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
+                       ret = regmap_update_bits(regmap, BDBASE, 0xff, 0xff);
                        if (!ret)
-                               ret = ov772x_mask_set(client, COM8,
-                                                     BNDF_ON_OFF, 0);
+                               ret = regmap_update_bits(regmap, COM8,
+                                                        BNDF_ON_OFF, 0);
                } else {
                        /* Switch the filter on, set AEC low limit */
                        val = 256 - ctrl->val;
-                       ret = ov772x_mask_set(client, COM8,
-                                             BNDF_ON_OFF, BNDF_ON_OFF);
+                       ret = regmap_update_bits(regmap, COM8,
+                                                BNDF_ON_OFF, BNDF_ON_OFF);
                        if (!ret)
-                               ret = ov772x_mask_set(client, BDBASE,
-                                                     0xff, val);
+                               ret = regmap_update_bits(regmap, BDBASE,
+                                                        0xff, val);
                }
 
                return ret;
@@ -841,18 +808,19 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
 static int ov772x_g_register(struct v4l2_subdev *sd,
                             struct v4l2_dbg_register *reg)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov772x_priv *priv = to_ov772x(sd);
        int ret;
+       unsigned int val;
 
        reg->size = 1;
        if (reg->reg > 0xff)
                return -EINVAL;
 
-       ret = ov772x_read(client, reg->reg);
+       ret = regmap_read(priv->regmap, reg->reg, &val);
        if (ret < 0)
                return ret;
 
-       reg->val = (__u64)ret;
+       reg->val = (__u64)val;
 
        return 0;
 }
@@ -860,13 +828,13 @@ static int ov772x_g_register(struct v4l2_subdev *sd,
 static int ov772x_s_register(struct v4l2_subdev *sd,
                             const struct v4l2_dbg_register *reg)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov772x_priv *priv = to_ov772x(sd);
 
        if (reg->reg > 0xff ||
            reg->val > 0xff)
                return -EINVAL;
 
-       return ov772x_write(client, reg->reg, reg->val);
+       return regmap_write(priv->regmap, reg->reg, reg->val);
 }
 #endif
 
@@ -896,6 +864,7 @@ static int ov772x_power_on(struct ov772x_priv *priv)
                                             GPIOD_OUT_LOW);
        if (IS_ERR(priv->rstb_gpio)) {
                dev_info(&client->dev, "Unable to get GPIO \"reset\"");
+               clk_disable_unprepare(priv->clk);
                return PTR_ERR(priv->rstb_gpio);
        }
 
@@ -1004,7 +973,7 @@ static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf,
 
 static int ov772x_edgectrl(struct ov772x_priv *priv)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
+       struct regmap *regmap = priv->regmap;
        int ret;
 
        if (!priv->info)
@@ -1018,19 +987,19 @@ static int ov772x_edgectrl(struct ov772x_priv *priv)
                 * Remove it when manual mode.
                 */
 
-               ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
+               ret = regmap_update_bits(regmap, DSPAUTO, EDGE_ACTRL, 0x00);
                if (ret < 0)
                        return ret;
 
-               ret = ov772x_mask_set(client,
-                                     EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
-                                     priv->info->edgectrl.threshold);
+               ret = regmap_update_bits(regmap, EDGE_TRSHLD,
+                                        OV772X_EDGE_THRESHOLD_MASK,
+                                        priv->info->edgectrl.threshold);
                if (ret < 0)
                        return ret;
 
-               ret = ov772x_mask_set(client,
-                                     EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
-                                     priv->info->edgectrl.strength);
+               ret = regmap_update_bits(regmap, EDGE_STRNGT,
+                                        OV772X_EDGE_STRENGTH_MASK,
+                                        priv->info->edgectrl.strength);
                if (ret < 0)
                        return ret;
 
@@ -1040,15 +1009,15 @@ static int ov772x_edgectrl(struct ov772x_priv *priv)
                 *
                 * Set upper and lower limit.
                 */
-               ret = ov772x_mask_set(client,
-                                     EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
-                                     priv->info->edgectrl.upper);
+               ret = regmap_update_bits(regmap, EDGE_UPPER,
+                                        OV772X_EDGE_UPPER_MASK,
+                                        priv->info->edgectrl.upper);
                if (ret < 0)
                        return ret;
 
-               ret = ov772x_mask_set(client,
-                                     EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
-                                     priv->info->edgectrl.lower);
+               ret = regmap_update_bits(regmap, EDGE_LOWER,
+                                        OV772X_EDGE_LOWER_MASK,
+                                        priv->info->edgectrl.lower);
                if (ret < 0)
                        return ret;
        }
@@ -1060,12 +1029,11 @@ static int ov772x_set_params(struct ov772x_priv *priv,
                             const struct ov772x_color_format *cfmt,
                             const struct ov772x_win_size *win)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
        int ret;
        u8  val;
 
        /* Reset hardware. */
-       ov772x_reset(client);
+       ov772x_reset(priv);
 
        /* Edge Ctrl. */
        ret = ov772x_edgectrl(priv);
@@ -1073,32 +1041,32 @@ static int ov772x_set_params(struct ov772x_priv *priv,
                return ret;
 
        /* Format and window size. */
-       ret = ov772x_write(client, HSTART, win->rect.left >> 2);
+       ret = regmap_write(priv->regmap, HSTART, win->rect.left >> 2);
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
+       ret = regmap_write(priv->regmap, HSIZE, win->rect.width >> 2);
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, VSTART, win->rect.top >> 1);
+       ret = regmap_write(priv->regmap, VSTART, win->rect.top >> 1);
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
+       ret = regmap_write(priv->regmap, VSIZE, win->rect.height >> 1);
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
+       ret = regmap_write(priv->regmap, HOUTSIZE, win->rect.width >> 2);
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
+       ret = regmap_write(priv->regmap, VOUTSIZE, win->rect.height >> 1);
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, HREF,
+       ret = regmap_write(priv->regmap, HREF,
                           ((win->rect.top & 1) << HREF_VSTART_SHIFT) |
                           ((win->rect.left & 3) << HREF_HSTART_SHIFT) |
                           ((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
                           ((win->rect.width & 3) << HREF_HSIZE_SHIFT));
        if (ret < 0)
                goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, EXHCH,
+       ret = regmap_write(priv->regmap, EXHCH,
                           ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
                           ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
        if (ret < 0)
@@ -1107,15 +1075,14 @@ static int ov772x_set_params(struct ov772x_priv *priv,
        /* Set DSP_CTRL3. */
        val = cfmt->dsp3;
        if (val) {
-               ret = ov772x_mask_set(client,
-                                     DSP_CTRL3, UV_MASK, val);
+               ret = regmap_update_bits(priv->regmap, DSP_CTRL3, UV_MASK, val);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
        }
 
        /* DSP_CTRL4: AEC reference point and DSP output format. */
        if (cfmt->dsp4) {
-               ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4);
+               ret = regmap_write(priv->regmap, DSP_CTRL4, cfmt->dsp4);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
        }
@@ -1131,13 +1098,12 @@ static int ov772x_set_params(struct ov772x_priv *priv,
        if (priv->hflip_ctrl->val)
                val ^= HFLIP_IMG;
 
-       ret = ov772x_mask_set(client,
-                             COM3, SWAP_MASK | IMG_MASK, val);
+       ret = regmap_update_bits(priv->regmap, COM3, SWAP_MASK | IMG_MASK, val);
        if (ret < 0)
                goto ov772x_set_fmt_error;
 
        /* COM7: Sensor resolution and output format control. */
-       ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7);
+       ret = regmap_write(priv->regmap, COM7, win->com7_bit | cfmt->com7);
        if (ret < 0)
                goto ov772x_set_fmt_error;
 
@@ -1150,10 +1116,11 @@ static int ov772x_set_params(struct ov772x_priv *priv,
        if (priv->band_filter_ctrl->val) {
                unsigned short band_filter = priv->band_filter_ctrl->val;
 
-               ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, BNDF_ON_OFF);
+               ret = regmap_update_bits(priv->regmap, COM8,
+                                        BNDF_ON_OFF, BNDF_ON_OFF);
                if (!ret)
-                       ret = ov772x_mask_set(client, BDBASE,
-                                             0xff, 256 - band_filter);
+                       ret = regmap_update_bits(priv->regmap, BDBASE,
+                                                0xff, 256 - band_filter);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
        }
@@ -1162,7 +1129,7 @@ static int ov772x_set_params(struct ov772x_priv *priv,
 
 ov772x_set_fmt_error:
 
-       ov772x_reset(client);
+       ov772x_reset(priv);
 
        return ret;
 }
@@ -1180,7 +1147,6 @@ static int ov772x_get_selection(struct v4l2_subdev *sd,
        sel->r.top = 0;
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
        case V4L2_SEL_TGT_CROP:
                sel->r.width = priv->win->rect.width;
                sel->r.height = priv->win->rect.height;
@@ -1276,12 +1242,12 @@ static int ov772x_video_probe(struct ov772x_priv *priv)
                return ret;
 
        /* Check and show product ID and manufacturer ID. */
-       pid = ov772x_read(client, PID);
-       if (pid < 0)
-               return pid;
-       ver = ov772x_read(client, VER);
-       if (ver < 0)
-               return ver;
+       ret = regmap_read(priv->regmap, PID, &pid);
+       if (ret < 0)
+               return ret;
+       ret = regmap_read(priv->regmap, VER, &ver);
+       if (ret < 0)
+               return ret;
 
        switch (VERSION(pid, ver)) {
        case OV7720:
@@ -1297,12 +1263,12 @@ static int ov772x_video_probe(struct ov772x_priv *priv)
                goto done;
        }
 
-       midh = ov772x_read(client, MIDH);
-       if (midh < 0)
-               return midh;
-       midl = ov772x_read(client, MIDL);
-       if (midl < 0)
-               return midl;
+       ret = regmap_read(priv->regmap, MIDH, &midh);
+       if (ret < 0)
+               return ret;
+       ret = regmap_read(priv->regmap, MIDL, &midl);
+       if (ret < 0)
+               return ret;
 
        dev_info(&client->dev,
                 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
@@ -1386,8 +1352,12 @@ static int ov772x_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct ov772x_priv      *priv;
-       struct i2c_adapter      *adapter = client->adapter;
        int                     ret;
+       static const struct regmap_config ov772x_regmap_config = {
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = DSPAUTO,
+       };
 
        if (!client->dev.of_node && !client->dev.platform_data) {
                dev_err(&client->dev,
@@ -1395,16 +1365,16 @@ static int ov772x_probe(struct i2c_client *client,
                return -EINVAL;
        }
 
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-               dev_err(&adapter->dev,
-                       "I2C-Adapter doesn't support SMBUS_BYTE_DATA\n");
-               return -EIO;
-       }
-
        priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
+       priv->regmap = devm_regmap_init_sccb(client, &ov772x_regmap_config);
+       if (IS_ERR(priv->regmap)) {
+               dev_err(&client->dev, "Failed to allocate register map\n");
+               return PTR_ERR(priv->regmap);
+       }
+
        priv->info = client->dev.platform_data;
        mutex_init(&priv->lock);
 
index 605f3e25ad82b2cdd1d11978d508043a99798a53..6e9c233cfbe352589ae2b042fca4d540023ec2a9 100644 (file)
@@ -510,7 +510,7 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
        int ret;
        u8 val = 0;
 
-       if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+       if (!pm_runtime_get_if_in_use(&client->dev))
                return 0;
 
        switch (ctrl->id) {
index 5bea31cd41aa1e63b3e024e0ce9d55624d633b7e..f0587c0c0a7246547a5eb104c73df35dd21dff3b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/media.h>
 #include <linux/module.h>
 #include <linux/ratelimit.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/videodev2.h>
@@ -259,7 +260,7 @@ struct ov965x {
        /* Protects the struct fields below */
        struct mutex lock;
 
-       struct i2c_client *client;
+       struct regmap *regmap;
 
        /* Exposure row interval in us */
        unsigned int exp_row_interval;
@@ -424,51 +425,42 @@ static inline struct ov965x *to_ov965x(struct v4l2_subdev *sd)
        return container_of(sd, struct ov965x, sd);
 }
 
-static int ov965x_read(struct i2c_client *client, u8 addr, u8 *val)
+static int ov965x_read(struct ov965x *ov965x, u8 addr, u8 *val)
 {
-       u8 buf = addr;
-       struct i2c_msg msg = {
-               .addr = client->addr,
-               .flags = 0,
-               .len = 1,
-               .buf = &buf
-       };
        int ret;
+       unsigned int buf;
 
-       ret = i2c_transfer(client->adapter, &msg, 1);
-       if (ret == 1) {
-               msg.flags = I2C_M_RD;
-               ret = i2c_transfer(client->adapter, &msg, 1);
-
-               if (ret == 1)
-                       *val = buf;
-       }
+       ret = regmap_read(ov965x->regmap, addr, &buf);
+       if (!ret)
+               *val = buf;
+       else
+               *val = -1;
 
-       v4l2_dbg(2, debug, client, "%s: 0x%02x @ 0x%02x. (%d)\n",
+       v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02x. (%d)\n",
                 __func__, *val, addr, ret);
 
-       return ret == 1 ? 0 : ret;
+       return ret;
 }
 
-static int ov965x_write(struct i2c_client *client, u8 addr, u8 val)
+static int ov965x_write(struct ov965x *ov965x, u8 addr, u8 val)
 {
-       u8 buf[2] = { addr, val };
+       int ret;
 
-       int ret = i2c_master_send(client, buf, 2);
+       ret = regmap_write(ov965x->regmap, addr, val);
 
-       v4l2_dbg(2, debug, client, "%s: 0x%02x @ 0x%02X (%d)\n",
+       v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02X (%d)\n",
                 __func__, val, addr, ret);
 
-       return ret == 2 ? 0 : ret;
+       return ret;
 }
 
-static int ov965x_write_array(struct i2c_client *client,
+static int ov965x_write_array(struct ov965x *ov965x,
                              const struct i2c_rv *regs)
 {
        int i, ret = 0;
 
        for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
-               ret = ov965x_write(client, regs[i].addr, regs[i].value);
+               ret = ov965x_write(ov965x, regs[i].addr, regs[i].value);
 
        return ret;
 }
@@ -486,7 +478,7 @@ static int ov965x_set_default_gamma_curve(struct ov965x *ov965x)
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(gamma_curve); i++) {
-               int ret = ov965x_write(ov965x->client, addr, gamma_curve[i]);
+               int ret = ov965x_write(ov965x, addr, gamma_curve[i]);
 
                if (ret < 0)
                        return ret;
@@ -506,7 +498,7 @@ static int ov965x_set_color_matrix(struct ov965x *ov965x)
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(mtx); i++) {
-               int ret = ov965x_write(ov965x->client, addr, mtx[i]);
+               int ret = ov965x_write(ov965x, addr, mtx[i]);
 
                if (ret < 0)
                        return ret;
@@ -542,16 +534,15 @@ static int __ov965x_set_power(struct ov965x *ov965x, int on)
 static int ov965x_s_power(struct v4l2_subdev *sd, int on)
 {
        struct ov965x *ov965x = to_ov965x(sd);
-       struct i2c_client *client = ov965x->client;
        int ret = 0;
 
-       v4l2_dbg(1, debug, client, "%s: on: %d\n", __func__, on);
+       v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
 
        mutex_lock(&ov965x->lock);
        if (ov965x->power == !on) {
                ret = __ov965x_set_power(ov965x, on);
                if (!ret && on) {
-                       ret = ov965x_write_array(client,
+                       ret = ov965x_write_array(ov965x,
                                                 ov965x_init_regs);
                        ov965x->apply_frame_fmt = 1;
                        ov965x->ctrls.update = 1;
@@ -609,13 +600,13 @@ static int ov965x_set_banding_filter(struct ov965x *ov965x, int value)
        int ret;
        u8 reg;
 
-       ret = ov965x_read(ov965x->client, REG_COM8, &reg);
+       ret = ov965x_read(ov965x, REG_COM8, &reg);
        if (!ret) {
                if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED)
                        reg &= ~COM8_BFILT;
                else
                        reg |= COM8_BFILT;
-               ret = ov965x_write(ov965x->client, REG_COM8, reg);
+               ret = ov965x_write(ov965x, REG_COM8, reg);
        }
        if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED)
                return 0;
@@ -631,7 +622,7 @@ static int ov965x_set_banding_filter(struct ov965x *ov965x, int value)
               ov965x->fiv->interval.numerator;
        mbd = ((mbd / (light_freq * 2)) + 500) / 1000UL;
 
-       return ov965x_write(ov965x->client, REG_MBD, mbd);
+       return ov965x_write(ov965x, REG_MBD, mbd);
 }
 
 static int ov965x_set_white_balance(struct ov965x *ov965x, int awb)
@@ -639,17 +630,17 @@ static int ov965x_set_white_balance(struct ov965x *ov965x, int awb)
        int ret;
        u8 reg;
 
-       ret = ov965x_read(ov965x->client, REG_COM8, &reg);
+       ret = ov965x_read(ov965x, REG_COM8, &reg);
        if (!ret) {
                reg = awb ? reg | REG_COM8 : reg & ~REG_COM8;
-               ret = ov965x_write(ov965x->client, REG_COM8, reg);
+               ret = ov965x_write(ov965x, REG_COM8, reg);
        }
        if (!ret && !awb) {
-               ret = ov965x_write(ov965x->client, REG_BLUE,
+               ret = ov965x_write(ov965x, REG_BLUE,
                                   ov965x->ctrls.blue_balance->val);
                if (ret < 0)
                        return ret;
-               ret = ov965x_write(ov965x->client, REG_RED,
+               ret = ov965x_write(ov965x, REG_RED,
                                   ov965x->ctrls.red_balance->val);
        }
        return ret;
@@ -677,14 +668,13 @@ static int ov965x_set_brightness(struct ov965x *ov965x, int val)
                return -EINVAL;
 
        for (i = 0; i < NUM_BR_REGS && !ret; i++)
-               ret = ov965x_write(ov965x->client, regs[0][i],
+               ret = ov965x_write(ov965x, regs[0][i],
                                   regs[val][i]);
        return ret;
 }
 
 static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
 {
-       struct i2c_client *client = ov965x->client;
        struct ov965x_ctrls *ctrls = &ov965x->ctrls;
        int ret = 0;
        u8 reg;
@@ -693,14 +683,14 @@ static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
         * gain value in REG_VREF, REG_GAIN is not overwritten.
         */
        if (ctrls->auto_gain->is_new) {
-               ret = ov965x_read(client, REG_COM8, &reg);
+               ret = ov965x_read(ov965x, REG_COM8, &reg);
                if (ret < 0)
                        return ret;
                if (ctrls->auto_gain->val)
                        reg |= COM8_AGC;
                else
                        reg &= ~COM8_AGC;
-               ret = ov965x_write(client, REG_COM8, reg);
+               ret = ov965x_write(ov965x, REG_COM8, reg);
                if (ret < 0)
                        return ret;
        }
@@ -719,15 +709,15 @@ static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
                rgain = (gain - ((1 << m) * 16)) / (1 << m);
                rgain |= (((1 << m) - 1) << 4);
 
-               ret = ov965x_write(client, REG_GAIN, rgain & 0xff);
+               ret = ov965x_write(ov965x, REG_GAIN, rgain & 0xff);
                if (ret < 0)
                        return ret;
-               ret = ov965x_read(client, REG_VREF, &reg);
+               ret = ov965x_read(ov965x, REG_VREF, &reg);
                if (ret < 0)
                        return ret;
                reg &= ~VREF_GAIN_MASK;
                reg |= (((rgain >> 8) & 0x3) << 6);
-               ret = ov965x_write(client, REG_VREF, reg);
+               ret = ov965x_write(ov965x, REG_VREF, reg);
                if (ret < 0)
                        return ret;
                /* Return updated control's value to userspace */
@@ -742,10 +732,10 @@ static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value)
        u8 com14, edge;
        int ret;
 
-       ret = ov965x_read(ov965x->client, REG_COM14, &com14);
+       ret = ov965x_read(ov965x, REG_COM14, &com14);
        if (ret < 0)
                return ret;
-       ret = ov965x_read(ov965x->client, REG_EDGE, &edge);
+       ret = ov965x_read(ov965x, REG_EDGE, &edge);
        if (ret < 0)
                return ret;
        com14 = value ? com14 | COM14_EDGE_EN : com14 & ~COM14_EDGE_EN;
@@ -756,33 +746,32 @@ static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value)
        } else {
                com14 &= ~COM14_EEF_X2;
        }
-       ret = ov965x_write(ov965x->client, REG_COM14, com14);
+       ret = ov965x_write(ov965x, REG_COM14, com14);
        if (ret < 0)
                return ret;
 
        edge &= ~EDGE_FACTOR_MASK;
        edge |= ((u8)value & 0x0f);
 
-       return ov965x_write(ov965x->client, REG_EDGE, edge);
+       return ov965x_write(ov965x, REG_EDGE, edge);
 }
 
 static int ov965x_set_exposure(struct ov965x *ov965x, int exp)
 {
-       struct i2c_client *client = ov965x->client;
        struct ov965x_ctrls *ctrls = &ov965x->ctrls;
        bool auto_exposure = (exp == V4L2_EXPOSURE_AUTO);
        int ret;
        u8 reg;
 
        if (ctrls->auto_exp->is_new) {
-               ret = ov965x_read(client, REG_COM8, &reg);
+               ret = ov965x_read(ov965x, REG_COM8, &reg);
                if (ret < 0)
                        return ret;
                if (auto_exposure)
                        reg |= (COM8_AEC | COM8_AGC);
                else
                        reg &= ~(COM8_AEC | COM8_AGC);
-               ret = ov965x_write(client, REG_COM8, reg);
+               ret = ov965x_write(ov965x, REG_COM8, reg);
                if (ret < 0)
                        return ret;
        }
@@ -794,12 +783,12 @@ static int ov965x_set_exposure(struct ov965x *ov965x, int exp)
                 * Manual exposure value
                 * [b15:b0] - AECHM (b15:b10), AECH (b9:b2), COM1 (b1:b0)
                 */
-               ret = ov965x_write(client, REG_COM1, exposure & 0x3);
+               ret = ov965x_write(ov965x, REG_COM1, exposure & 0x3);
                if (!ret)
-                       ret = ov965x_write(client, REG_AECH,
+                       ret = ov965x_write(ov965x, REG_AECH,
                                           (exposure >> 2) & 0xff);
                if (!ret)
-                       ret = ov965x_write(client, REG_AECHM,
+                       ret = ov965x_write(ov965x, REG_AECHM,
                                           (exposure >> 10) & 0x3f);
                /* Update the value to minimize rounding errors */
                ctrls->exposure->val = ((exposure * ov965x->exp_row_interval)
@@ -822,7 +811,7 @@ static int ov965x_set_flip(struct ov965x *ov965x)
        if (ov965x->ctrls.vflip->val)
                mvfp |= MVFP_FLIP;
 
-       return ov965x_write(ov965x->client, REG_MVFP, mvfp);
+       return ov965x_write(ov965x, REG_MVFP, mvfp);
 }
 
 #define NUM_SAT_LEVELS 5
@@ -846,7 +835,7 @@ static int ov965x_set_saturation(struct ov965x *ov965x, int val)
                return -EINVAL;
 
        for (i = 0; i < NUM_SAT_REGS && !ret; i++)
-               ret = ov965x_write(ov965x->client, addr + i, regs[val][i]);
+               ret = ov965x_write(ov965x, addr + i, regs[val][i]);
 
        return ret;
 }
@@ -856,16 +845,15 @@ static int ov965x_set_test_pattern(struct ov965x *ov965x, int value)
        int ret;
        u8 reg;
 
-       ret = ov965x_read(ov965x->client, REG_COM23, &reg);
+       ret = ov965x_read(ov965x, REG_COM23, &reg);
        if (ret < 0)
                return ret;
        reg = value ? reg | COM23_TEST_MODE : reg & ~COM23_TEST_MODE;
-       return ov965x_write(ov965x->client, REG_COM23, reg);
+       return ov965x_write(ov965x, REG_COM23, reg);
 }
 
 static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
 {
-       struct i2c_client *client = ov965x->client;
        unsigned int exposure, gain, m;
        u8 reg0, reg1, reg2;
        int ret;
@@ -877,10 +865,10 @@ static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
        case V4L2_CID_AUTOGAIN:
                if (!ctrl->val)
                        return 0;
-               ret = ov965x_read(client, REG_GAIN, &reg0);
+               ret = ov965x_read(ov965x, REG_GAIN, &reg0);
                if (ret < 0)
                        return ret;
-               ret = ov965x_read(client, REG_VREF, &reg1);
+               ret = ov965x_read(ov965x, REG_VREF, &reg1);
                if (ret < 0)
                        return ret;
                gain = ((reg1 >> 6) << 8) | reg0;
@@ -891,13 +879,13 @@ static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
        case V4L2_CID_EXPOSURE_AUTO:
                if (ctrl->val == V4L2_EXPOSURE_MANUAL)
                        return 0;
-               ret = ov965x_read(client, REG_COM1, &reg0);
+               ret = ov965x_read(ov965x, REG_COM1, &reg0);
                if (ret < 0)
                        return ret;
-               ret = ov965x_read(client, REG_AECH, &reg1);
+               ret = ov965x_read(ov965x, REG_AECH, &reg1);
                if (ret < 0)
                        return ret;
-               ret = ov965x_read(client, REG_AECHM, &reg2);
+               ret = ov965x_read(ov965x, REG_AECHM, &reg2);
                if (ret < 0)
                        return ret;
                exposure = ((reg2 & 0x3f) << 10) | (reg1 << 2) |
@@ -1279,32 +1267,31 @@ static int ov965x_set_frame_size(struct ov965x *ov965x)
        int i, ret = 0;
 
        for (i = 0; ret == 0 && i < NUM_FMT_REGS; i++)
-               ret = ov965x_write(ov965x->client, frame_size_reg_addr[i],
+               ret = ov965x_write(ov965x, frame_size_reg_addr[i],
                                   ov965x->frame_size->regs[i]);
        return ret;
 }
 
 static int __ov965x_set_params(struct ov965x *ov965x)
 {
-       struct i2c_client *client = ov965x->client;
        struct ov965x_ctrls *ctrls = &ov965x->ctrls;
        int ret = 0;
        u8 reg;
 
        if (ov965x->apply_frame_fmt) {
                reg = DEF_CLKRC + ov965x->fiv->clkrc_div;
-               ret = ov965x_write(client, REG_CLKRC, reg);
+               ret = ov965x_write(ov965x, REG_CLKRC, reg);
                if (ret < 0)
                        return ret;
                ret = ov965x_set_frame_size(ov965x);
                if (ret < 0)
                        return ret;
-               ret = ov965x_read(client, REG_TSLB, &reg);
+               ret = ov965x_read(ov965x, REG_TSLB, &reg);
                if (ret < 0)
                        return ret;
                reg &= ~TSLB_YUYV_MASK;
                reg |= ov965x->tslb_reg;
-               ret = ov965x_write(client, REG_TSLB, reg);
+               ret = ov965x_write(ov965x, REG_TSLB, reg);
                if (ret < 0)
                        return ret;
        }
@@ -1318,10 +1305,10 @@ static int __ov965x_set_params(struct ov965x *ov965x)
         * Select manual banding filter, the filter will
         * be enabled further if required.
         */
-       ret = ov965x_read(client, REG_COM11, &reg);
+       ret = ov965x_read(ov965x, REG_COM11, &reg);
        if (!ret)
                reg |= COM11_BANDING;
-       ret = ov965x_write(client, REG_COM11, reg);
+       ret = ov965x_write(ov965x, REG_COM11, reg);
        if (ret < 0)
                return ret;
        /*
@@ -1333,12 +1320,11 @@ static int __ov965x_set_params(struct ov965x *ov965x)
 
 static int ov965x_s_stream(struct v4l2_subdev *sd, int on)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct ov965x *ov965x = to_ov965x(sd);
        struct ov965x_ctrls *ctrls = &ov965x->ctrls;
        int ret = 0;
 
-       v4l2_dbg(1, debug, client, "%s: on: %d\n", __func__, on);
+       v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
 
        mutex_lock(&ov965x->lock);
        if (ov965x->streaming == !on) {
@@ -1358,7 +1344,7 @@ static int ov965x_s_stream(struct v4l2_subdev *sd, int on)
                                ctrls->update = 0;
                }
                if (!ret)
-                       ret = ov965x_write(client, REG_COM2,
+                       ret = ov965x_write(ov965x, REG_COM2,
                                           on ? 0x01 : 0x11);
        }
        if (!ret)
@@ -1421,6 +1407,7 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x,
 {
        int ret, i;
        int gpios[NUM_GPIOS];
+       struct device *dev = regmap_get_device(ov965x->regmap);
 
        gpios[GPIO_PWDN] = pdata->gpio_pwdn;
        gpios[GPIO_RST]  = pdata->gpio_reset;
@@ -1430,7 +1417,7 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x,
 
                if (!gpio_is_valid(gpio))
                        continue;
-               ret = devm_gpio_request_one(&ov965x->client->dev, gpio,
+               ret = devm_gpio_request_one(dev, gpio,
                                            GPIOF_OUT_INIT_HIGH, "OV965X");
                if (ret < 0)
                        return ret;
@@ -1446,7 +1433,7 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x,
 
 static int ov965x_configure_gpios(struct ov965x *ov965x)
 {
-       struct device *dev = &ov965x->client->dev;
+       struct device *dev = regmap_get_device(ov965x->regmap);
 
        ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown",
                                                        GPIOD_OUT_HIGH);
@@ -1467,7 +1454,6 @@ static int ov965x_configure_gpios(struct ov965x *ov965x)
 
 static int ov965x_detect_sensor(struct v4l2_subdev *sd)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct ov965x *ov965x = to_ov965x(sd);
        u8 pid, ver;
        int ret;
@@ -1480,9 +1466,9 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd)
        msleep(25);
 
        /* Check sensor revision */
-       ret = ov965x_read(client, REG_PID, &pid);
+       ret = ov965x_read(ov965x, REG_PID, &pid);
        if (!ret)
-               ret = ov965x_read(client, REG_VER, &ver);
+               ret = ov965x_read(ov965x, REG_VER, &ver);
 
        __ov965x_set_power(ov965x, 0);
 
@@ -1509,12 +1495,21 @@ static int ov965x_probe(struct i2c_client *client,
        struct v4l2_subdev *sd;
        struct ov965x *ov965x;
        int ret;
+       static const struct regmap_config ov965x_regmap_config = {
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xab,
+       };
 
        ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL);
        if (!ov965x)
                return -ENOMEM;
 
-       ov965x->client = client;
+       ov965x->regmap = devm_regmap_init_sccb(client, &ov965x_regmap_config);
+       if (IS_ERR(ov965x->regmap)) {
+               dev_err(&client->dev, "Failed to allocate register map\n");
+               return PTR_ERR(ov965x->regmap);
+       }
 
        if (pdata) {
                if (pdata->mclk_frequency == 0) {
@@ -1527,7 +1522,7 @@ static int ov965x_probe(struct i2c_client *client,
                if (ret < 0)
                        return ret;
        } else if (dev_fwnode(&client->dev)) {
-               ov965x->clk = devm_clk_get(&ov965x->client->dev, NULL);
+               ov965x->clk = devm_clk_get(&client->dev, NULL);
                if (IS_ERR(ov965x->clk))
                        return PTR_ERR(ov965x->clk);
                ov965x->mclk_frequency = clk_get_rate(ov965x->clk);
@@ -1546,7 +1541,7 @@ static int ov965x_probe(struct i2c_client *client,
 
        sd = &ov965x->sd;
        v4l2_i2c_subdev_init(sd, client, &ov965x_subdev_ops);
-       strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
+       strscpy(sd->name, DRIVER_NAME, sizeof(sd->name));
 
        sd->internal_ops = &ov965x_sd_internal_ops;
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
index 6ad998ad1b167f931f42727aa620efbf2b6e782f..4cc51e00187440a1fe97a83cd013cfd615f50a2b 100644 (file)
@@ -589,7 +589,6 @@ static int rj54n1_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
                sel->r.left = RJ54N1_COLUMN_SKIP;
                sel->r.top = RJ54N1_ROW_SKIP;
                sel->r.width = RJ54N1_MAX_WIDTH;
index ce196b60f9170d219de213187aaef1cd26057c12..c461847ddae81d2b908576f57730b1a44ff9b090 100644 (file)
@@ -1603,7 +1603,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
        const struct s5c73m3_platform_data *pdata = dev->platform_data;
        struct device_node *node = dev->of_node;
        struct device_node *node_ep;
-       struct v4l2_fwnode_endpoint ep;
+       struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
        int ret;
 
        if (!node) {
@@ -1644,7 +1644,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
        if (ret)
                return ret;
 
-       if (ep.bus_type != V4L2_MBUS_CSI2) {
+       if (ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(dev, "unsupported bus type\n");
                return -EINVAL;
        }
@@ -1683,7 +1683,7 @@ static int s5c73m3_probe(struct i2c_client *client,
        v4l2_subdev_init(sd, &s5c73m3_subdev_ops);
        sd->owner = client->dev.driver->owner;
        v4l2_set_subdevdata(sd, state);
-       strlcpy(sd->name, "S5C73M3", sizeof(sd->name));
+       strscpy(sd->name, "S5C73M3", sizeof(sd->name));
 
        sd->internal_ops = &s5c73m3_internal_ops;
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1698,7 +1698,8 @@ static int s5c73m3_probe(struct i2c_client *client,
                return ret;
 
        v4l2_i2c_subdev_init(oif_sd, client, &oif_subdev_ops);
-       strcpy(oif_sd->name, "S5C73M3-OIF");
+       /* Static name; NEVER use in new drivers! */
+       strscpy(oif_sd->name, "S5C73M3-OIF", sizeof(oif_sd->name));
 
        oif_sd->internal_ops = &oif_internal_ops;
        oif_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index 6ebcf254989a5237869b5d94b065a06fadc04d14..79aa2740edc471beb8d741695000e1ded03a2a16 100644 (file)
@@ -954,7 +954,8 @@ static int s5k4ecgx_probe(struct i2c_client *client,
        sd = &priv->sd;
        /* Registering subdev */
        v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops);
-       strlcpy(sd->name, S5K4ECGX_DRIVER_NAME, sizeof(sd->name));
+       /* Static name; NEVER use in new drivers! */
+       strscpy(sd->name, S5K4ECGX_DRIVER_NAME, sizeof(sd->name));
 
        sd->internal_ops = &s5k4ecgx_subdev_internal_ops;
        /* Support v4l2 sub-device user space API */
index 5007c9659342dbbd2b2e96c00453bf77163ee0ab..727db7c0670ae692dd8d7b07cabdadc994e8e4ff 100644 (file)
@@ -766,7 +766,7 @@ static int s5k5baf_hw_set_video_bus(struct s5k5baf *state)
 {
        u16 en_pkts;
 
-       if (state->bus_type == V4L2_MBUS_CSI2)
+       if (state->bus_type == V4L2_MBUS_CSI2_DPHY)
                en_pkts = EN_PACKETS_CSI2;
        else
                en_pkts = 0;
@@ -1841,7 +1841,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
 {
        struct device_node *node = dev->of_node;
        struct device_node *node_ep;
-       struct v4l2_fwnode_endpoint ep;
+       struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
        int ret;
 
        if (!node) {
@@ -1875,7 +1875,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
        state->bus_type = ep.bus_type;
 
        switch (state->bus_type) {
-       case V4L2_MBUS_CSI2:
+       case V4L2_MBUS_CSI2_DPHY:
                state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
                break;
        case V4L2_MBUS_PARALLEL:
index 13c10b5e2b451ccedaae039e1d92a9ecc56d9155..ab26f549d716de3a930a9d7db82f4ac3a715db3c 100644 (file)
@@ -688,7 +688,7 @@ static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa,
         * but there is nothing indicating how to switch between both
         * in the datasheet. For now default BT.601 interface is assumed.
         */
-       if (bus_type == V4L2_MBUS_CSI2)
+       if (bus_type == V4L2_MBUS_CSI2_DPHY)
                cfg = nlanes;
        else if (bus_type != V4L2_MBUS_PARALLEL)
                return -EINVAL;
@@ -1576,7 +1576,8 @@ static int s5k6aa_probe(struct i2c_client *client,
 
        sd = &s5k6aa->sd;
        v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
-       strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
+       /* Static name; NEVER use in new drivers! */
+       strscpy(sd->name, DRIVER_NAME, sizeof(sd->name));
 
        sd->internal_ops = &s5k6aa_subdev_internal_ops;
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index b07114b5efb27b9207ddd9395924cb83700e32a1..6bc278aa31fce4a9b98f66d8213629517e25bb42 100644 (file)
@@ -59,10 +59,16 @@ enum saa711x_model {
        SAA7118,
 };
 
+enum saa711x_pads {
+       SAA711X_PAD_IF_INPUT,
+       SAA711X_PAD_VID_OUT,
+       SAA711X_NUM_PADS
+};
+
 struct saa711x_state {
        struct v4l2_subdev sd;
 #ifdef CONFIG_MEDIA_CONTROLLER
-       struct media_pad pads[DEMOD_NUM_PADS];
+       struct media_pad pads[SAA711X_NUM_PADS];
 #endif
        struct v4l2_ctrl_handler hdl;
 
@@ -1765,7 +1771,7 @@ static int saa711x_detect_chip(struct i2c_client *client,
                 * the lower nibble is a gm7113c.
                 */
 
-               strlcpy(name, "gm7113c", CHIP_VER_SIZE);
+               strscpy(name, "gm7113c", CHIP_VER_SIZE);
 
                if (!autodetect && strcmp(name, id->name))
                        return -EINVAL;
@@ -1779,7 +1785,7 @@ static int saa711x_detect_chip(struct i2c_client *client,
 
        /* Check if it is a CJC7113 */
        if (!memcmp(name, "1111111111111111", CHIP_VER_SIZE)) {
-               strlcpy(name, "cjc7113", CHIP_VER_SIZE);
+               strscpy(name, "cjc7113", CHIP_VER_SIZE);
 
                if (!autodetect && strcmp(name, id->name))
                        return -EINVAL;
@@ -1825,7 +1831,7 @@ static int saa711x_probe(struct i2c_client *client,
        if (ident < 0)
                return ident;
 
-       strlcpy(client->name, name, sizeof(client->name));
+       strscpy(client->name, name, sizeof(client->name));
 
        state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
        if (state == NULL)
@@ -1834,13 +1840,15 @@ static int saa711x_probe(struct i2c_client *client,
        v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
-       state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[SAA711X_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       state->pads[SAA711X_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
+       state->pads[SAA711X_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[SAA711X_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
 
        sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
 
-       ret = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, state->pads);
+       ret = media_entity_pads_init(&sd->entity, SAA711X_NUM_PADS,
+                                    state->pads);
        if (ret < 0)
                return ret;
 #endif
index e58a150cec5ca3be0e63bc177ca4083f3d51d207..a67865b810c0991060ad8becf8bd98a7f86dc04d 100644 (file)
@@ -761,10 +761,10 @@ static int saa7127_probe(struct i2c_client *client,
                        saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2,
                                        read_result);
                        state->ident = SAA7129;
-                       strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
+                       strscpy(client->name, "saa7129", I2C_NAME_SIZE);
                } else {
                        state->ident = SAA7127;
-                       strlcpy(client->name, "saa7127", I2C_NAME_SIZE);
+                       strscpy(client->name, "saa7127", I2C_NAME_SIZE);
                }
        }
 
index 1236683da8f75556c52aa738178822f0bf0c2e1c..58a45c353e2702d23e9b3673413886512f4eb2b2 100644 (file)
@@ -624,7 +624,7 @@ static int smiapp_init_late_controls(struct smiapp_sensor *sensor)
 {
        unsigned long *valid_link_freqs = &sensor->valid_link_freqs[
                sensor->csi_format->compressed - sensor->compressed_min_bpp];
-       unsigned int max, i;
+       unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) {
                int max_value = (1 << sensor->csi_format->width) - 1;
@@ -635,8 +635,6 @@ static int smiapp_init_late_controls(struct smiapp_sensor *sensor)
                                0, max_value, 1, max_value);
        }
 
-       for (max = 0; sensor->hwcfg->op_sys_clock[max + 1]; max++);
-
        sensor->link_freq = v4l2_ctrl_new_int_menu(
                &sensor->src->ctrl_handler, &smiapp_ctrl_ops,
                V4L2_CID_LINK_FREQ, __fls(*valid_link_freqs),
@@ -2617,9 +2615,7 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor,
        ssd->npads = num_pads;
        ssd->source_pad = num_pads - 1;
 
-       snprintf(ssd->sd.name,
-                sizeof(ssd->sd.name), "%s %s %d-%4.4x", sensor->minfo.name,
-                name, i2c_adapter_id(client->adapter), client->addr);
+       v4l2_i2c_subdev_set_name(&ssd->sd, client, sensor->minfo.name, name);
 
        smiapp_get_native_size(ssd, &ssd->sink_fmt);
 
@@ -2761,7 +2757,7 @@ static int __maybe_unused smiapp_resume(struct device *dev)
 static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
 {
        struct smiapp_hwconfig *hwcfg;
-       struct v4l2_fwnode_endpoint *bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct fwnode_handle *ep;
        struct fwnode_handle *fwnode = dev_fwnode(dev);
        u32 rotation;
@@ -2775,27 +2771,33 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
        if (!ep)
                return NULL;
 
-       bus_cfg = v4l2_fwnode_endpoint_alloc_parse(ep);
-       if (IS_ERR(bus_cfg))
+       bus_cfg.bus_type = V4L2_MBUS_CSI2_DPHY;
+       rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+       if (rval == -ENXIO) {
+               bus_cfg = (struct v4l2_fwnode_endpoint)
+                       { .bus_type = V4L2_MBUS_CCP2 };
+               rval = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+       }
+       if (rval)
                goto out_err;
 
        hwcfg = devm_kzalloc(dev, sizeof(*hwcfg), GFP_KERNEL);
        if (!hwcfg)
                goto out_err;
 
-       switch (bus_cfg->bus_type) {
-       case V4L2_MBUS_CSI2:
+       switch (bus_cfg.bus_type) {
+       case V4L2_MBUS_CSI2_DPHY:
                hwcfg->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2;
-               hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes;
+               hwcfg->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
                break;
        case V4L2_MBUS_CCP2:
-               hwcfg->csi_signalling_mode = (bus_cfg->bus.mipi_csi1.strobe) ?
+               hwcfg->csi_signalling_mode = (bus_cfg.bus.mipi_csi1.strobe) ?
                SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE :
                SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK;
                hwcfg->lanes = 1;
                break;
        default:
-               dev_err(dev, "unsupported bus %u\n", bus_cfg->bus_type);
+               dev_err(dev, "unsupported bus %u\n", bus_cfg.bus_type);
                goto out_err;
        }
 
@@ -2827,28 +2829,28 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
        dev_dbg(dev, "nvm %d, clk %d, mode %d\n",
                hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode);
 
-       if (!bus_cfg->nr_of_link_frequencies) {
+       if (!bus_cfg.nr_of_link_frequencies) {
                dev_warn(dev, "no link frequencies defined\n");
                goto out_err;
        }
 
        hwcfg->op_sys_clock = devm_kcalloc(
-               dev, bus_cfg->nr_of_link_frequencies + 1 /* guardian */,
+               dev, bus_cfg.nr_of_link_frequencies + 1 /* guardian */,
                sizeof(*hwcfg->op_sys_clock), GFP_KERNEL);
        if (!hwcfg->op_sys_clock)
                goto out_err;
 
-       for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) {
-               hwcfg->op_sys_clock[i] = bus_cfg->link_frequencies[i];
+       for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
+               hwcfg->op_sys_clock[i] = bus_cfg.link_frequencies[i];
                dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]);
        }
 
-       v4l2_fwnode_endpoint_free(bus_cfg);
+       v4l2_fwnode_endpoint_free(&bus_cfg);
        fwnode_handle_put(ep);
        return hwcfg;
 
 out_err:
-       v4l2_fwnode_endpoint_free(bus_cfg);
+       v4l2_fwnode_endpoint_free(&bus_cfg);
        fwnode_handle_put(ep);
        return NULL;
 }
@@ -3064,9 +3066,9 @@ static int smiapp_probe(struct i2c_client *client,
        if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
                sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
 
-       smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2);
-       smiapp_create_subdev(sensor, sensor->binner, "binner", 2);
-       smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1);
+       smiapp_create_subdev(sensor, sensor->scaler, " scaler", 2);
+       smiapp_create_subdev(sensor, sensor->binner, " binner", 2);
+       smiapp_create_subdev(sensor, sensor->pixel_array, " pixel_array", 1);
 
        dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
 
index 8c7770f62997220ffe9a74ad5238d895937537ee..09ae483b96efcca6671e235b99d40636febd9bcd 100644 (file)
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_SOC_CAMERA_MT9M001)       += mt9m001.o
-obj-$(CONFIG_SOC_CAMERA_MT9T112)       += mt9t112.o
-obj-$(CONFIG_SOC_CAMERA_MT9V022)       += mt9v022.o
-obj-$(CONFIG_SOC_CAMERA_OV5642)                += ov5642.o
-obj-$(CONFIG_SOC_CAMERA_OV772X)                += ov772x.o
-obj-$(CONFIG_SOC_CAMERA_OV9640)                += ov9640.o
-obj-$(CONFIG_SOC_CAMERA_OV9740)                += ov9740.o
-obj-$(CONFIG_SOC_CAMERA_RJ54N1)                += rj54n1cb0c.o
-obj-$(CONFIG_SOC_CAMERA_TW9910)                += tw9910.o
+obj-$(CONFIG_SOC_CAMERA_MT9M001)       += soc_mt9m001.o
+obj-$(CONFIG_SOC_CAMERA_MT9T112)       += soc_mt9t112.o
+obj-$(CONFIG_SOC_CAMERA_MT9V022)       += soc_mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_OV5642)                += soc_ov5642.o
+obj-$(CONFIG_SOC_CAMERA_OV772X)                += soc_ov772x.o
+obj-$(CONFIG_SOC_CAMERA_OV9640)                += soc_ov9640.o
+obj-$(CONFIG_SOC_CAMERA_OV9740)                += soc_ov9740.o
+obj-$(CONFIG_SOC_CAMERA_RJ54N1)                += soc_rj54n1cb0c.o
+obj-$(CONFIG_SOC_CAMERA_TW9910)                += soc_tw9910.o
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
deleted file mode 100644 (file)
index 1bfb0d5..0000000
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/module.h>
-
-#include <media/soc_camera.h>
-#include <media/drv-intf/soc_mediabus.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * mt9m001 i2c address 0x5d
- * The platform has to define struct i2c_board_info objects and link to them
- * from struct soc_camera_host_desc
- */
-
-/* mt9m001 selected register addresses */
-#define MT9M001_CHIP_VERSION           0x00
-#define MT9M001_ROW_START              0x01
-#define MT9M001_COLUMN_START           0x02
-#define MT9M001_WINDOW_HEIGHT          0x03
-#define MT9M001_WINDOW_WIDTH           0x04
-#define MT9M001_HORIZONTAL_BLANKING    0x05
-#define MT9M001_VERTICAL_BLANKING      0x06
-#define MT9M001_OUTPUT_CONTROL         0x07
-#define MT9M001_SHUTTER_WIDTH          0x09
-#define MT9M001_FRAME_RESTART          0x0b
-#define MT9M001_SHUTTER_DELAY          0x0c
-#define MT9M001_RESET                  0x0d
-#define MT9M001_READ_OPTIONS1          0x1e
-#define MT9M001_READ_OPTIONS2          0x20
-#define MT9M001_GLOBAL_GAIN            0x35
-#define MT9M001_CHIP_ENABLE            0xF1
-
-#define MT9M001_MAX_WIDTH              1280
-#define MT9M001_MAX_HEIGHT             1024
-#define MT9M001_MIN_WIDTH              48
-#define MT9M001_MIN_HEIGHT             32
-#define MT9M001_COLUMN_SKIP            20
-#define MT9M001_ROW_SKIP               12
-
-/* MT9M001 has only one fixed colorspace per pixelcode */
-struct mt9m001_datafmt {
-       u32     code;
-       enum v4l2_colorspace            colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9m001_datafmt *mt9m001_find_datafmt(
-       u32 code, const struct mt9m001_datafmt *fmt,
-       int n)
-{
-       int i;
-       for (i = 0; i < n; i++)
-               if (fmt[i].code == code)
-                       return fmt + i;
-
-       return NULL;
-}
-
-static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
-       /*
-        * Order important: first natively supported,
-        * second supported with a GPIO extender
-        */
-       {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
-};
-
-static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
-       /* Order important - see above */
-       {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
-       {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
-};
-
-struct mt9m001 {
-       struct v4l2_subdev subdev;
-       struct v4l2_ctrl_handler hdl;
-       struct {
-               /* exposure/auto-exposure cluster */
-               struct v4l2_ctrl *autoexposure;
-               struct v4l2_ctrl *exposure;
-       };
-       struct v4l2_rect rect;  /* Sensor window */
-       struct v4l2_clk *clk;
-       const struct mt9m001_datafmt *fmt;
-       const struct mt9m001_datafmt *fmts;
-       int num_fmts;
-       unsigned int total_h;
-       unsigned short y_skip_top;      /* Lines to skip at the top */
-};
-
-static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
-{
-       return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u8 reg)
-{
-       return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int reg_write(struct i2c_client *client, const u8 reg,
-                    const u16 data)
-{
-       return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int reg_set(struct i2c_client *client, const u8 reg,
-                  const u16 data)
-{
-       int ret;
-
-       ret = reg_read(client, reg);
-       if (ret < 0)
-               return ret;
-       return reg_write(client, reg, ret | data);
-}
-
-static int reg_clear(struct i2c_client *client, const u8 reg,
-                    const u16 data)
-{
-       int ret;
-
-       ret = reg_read(client, reg);
-       if (ret < 0)
-               return ret;
-       return reg_write(client, reg, ret & ~data);
-}
-
-static int mt9m001_init(struct i2c_client *client)
-{
-       int ret;
-
-       dev_dbg(&client->dev, "%s\n", __func__);
-
-       /*
-        * We don't know, whether platform provides reset, issue a soft reset
-        * too. This returns all registers to their default values.
-        */
-       ret = reg_write(client, MT9M001_RESET, 1);
-       if (!ret)
-               ret = reg_write(client, MT9M001_RESET, 0);
-
-       /* Disable chip, synchronous option update */
-       if (!ret)
-               ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
-
-       return ret;
-}
-
-static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       /* Switch to master "normal" mode or stop sensor readout */
-       if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
-               return -EIO;
-       return 0;
-}
-
-static int mt9m001_set_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct v4l2_rect rect = sel->r;
-       const u16 hblank = 9, vblank = 25;
-       int ret;
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       if (mt9m001->fmts == mt9m001_colour_fmts)
-               /*
-                * Bayer format - even number of rows for simplicity,
-                * but let the user play with the top row.
-                */
-               rect.height = ALIGN(rect.height, 2);
-
-       /* Datasheet requirement: see register description */
-       rect.width = ALIGN(rect.width, 2);
-       rect.left = ALIGN(rect.left, 2);
-
-       soc_camera_limit_side(&rect.left, &rect.width,
-                    MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
-
-       soc_camera_limit_side(&rect.top, &rect.height,
-                    MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
-
-       mt9m001->total_h = rect.height + mt9m001->y_skip_top + vblank;
-
-       /* Blanking and start values - default... */
-       ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
-       if (!ret)
-               ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
-
-       /*
-        * The caller provides a supported format, as verified per
-        * call to .set_fmt(FORMAT_TRY).
-        */
-       if (!ret)
-               ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
-       if (!ret)
-               ret = reg_write(client, MT9M001_ROW_START, rect.top);
-       if (!ret)
-               ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
-       if (!ret)
-               ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
-                               rect.height + mt9m001->y_skip_top - 1);
-       if (!ret && v4l2_ctrl_g_ctrl(mt9m001->autoexposure) == V4L2_EXPOSURE_AUTO)
-               ret = reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h);
-
-       if (!ret)
-               mt9m001->rect = rect;
-
-       return ret;
-}
-
-static int mt9m001_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.left = MT9M001_COLUMN_SKIP;
-               sel->r.top = MT9M001_ROW_SKIP;
-               sel->r.width = MT9M001_MAX_WIDTH;
-               sel->r.height = MT9M001_MAX_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = mt9m001->rect;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int mt9m001_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct v4l2_mbus_framefmt *mf = &format->format;
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->width       = mt9m001->rect.width;
-       mf->height      = mt9m001->rect.height;
-       mf->code        = mt9m001->fmt->code;
-       mf->colorspace  = mt9m001->fmt->colorspace;
-       mf->field       = V4L2_FIELD_NONE;
-
-       return 0;
-}
-
-static int mt9m001_s_fmt(struct v4l2_subdev *sd,
-                        const struct mt9m001_datafmt *fmt,
-                        struct v4l2_mbus_framefmt *mf)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct v4l2_subdev_selection sel = {
-               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-               .target = V4L2_SEL_TGT_CROP,
-               .r.left = mt9m001->rect.left,
-               .r.top = mt9m001->rect.top,
-               .r.width = mf->width,
-               .r.height = mf->height,
-       };
-       int ret;
-
-       /* No support for scaling so far, just crop. TODO: use skipping */
-       ret = mt9m001_set_selection(sd, NULL, &sel);
-       if (!ret) {
-               mf->width       = mt9m001->rect.width;
-               mf->height      = mt9m001->rect.height;
-               mt9m001->fmt    = fmt;
-               mf->colorspace  = fmt->colorspace;
-       }
-
-       return ret;
-}
-
-static int mt9m001_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       const struct mt9m001_datafmt *fmt;
-
-       if (format->pad)
-               return -EINVAL;
-
-       v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
-               MT9M001_MAX_WIDTH, 1,
-               &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
-               MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
-
-       if (mt9m001->fmts == mt9m001_colour_fmts)
-               mf->height = ALIGN(mf->height - 1, 2);
-
-       fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
-                                  mt9m001->num_fmts);
-       if (!fmt) {
-               fmt = mt9m001->fmt;
-               mf->code = fmt->code;
-       }
-
-       mf->colorspace  = fmt->colorspace;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               return mt9m001_s_fmt(sd, fmt, mf);
-       cfg->try_fmt = *mf;
-       return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9m001_g_register(struct v4l2_subdev *sd,
-                             struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg > 0xff)
-               return -EINVAL;
-
-       reg->size = 2;
-       reg->val = reg_read(client, reg->reg);
-
-       if (reg->val > 0xffff)
-               return -EIO;
-
-       return 0;
-}
-
-static int mt9m001_s_register(struct v4l2_subdev *sd,
-                             const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg > 0xff)
-               return -EINVAL;
-
-       if (reg_write(client, reg->reg, reg->val) < 0)
-               return -EIO;
-
-       return 0;
-}
-#endif
-
-static int mt9m001_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-
-       return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on);
-}
-
-static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct mt9m001 *mt9m001 = container_of(ctrl->handler,
-                                              struct mt9m001, hdl);
-       s32 min, max;
-
-       switch (ctrl->id) {
-       case V4L2_CID_EXPOSURE_AUTO:
-               min = mt9m001->exposure->minimum;
-               max = mt9m001->exposure->maximum;
-               mt9m001->exposure->val =
-                       (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min;
-               break;
-       }
-       return 0;
-}
-
-static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct mt9m001 *mt9m001 = container_of(ctrl->handler,
-                                              struct mt9m001, hdl);
-       struct v4l2_subdev *sd = &mt9m001->subdev;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct v4l2_ctrl *exp = mt9m001->exposure;
-       int data;
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               if (ctrl->val)
-                       data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
-               else
-                       data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
-               if (data < 0)
-                       return -EIO;
-               return 0;
-
-       case V4L2_CID_GAIN:
-               /* See Datasheet Table 7, Gain settings. */
-               if (ctrl->val <= ctrl->default_value) {
-                       /* Pack it into 0..1 step 0.125, register values 0..8 */
-                       unsigned long range = ctrl->default_value - ctrl->minimum;
-                       data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range;
-
-                       dev_dbg(&client->dev, "Setting gain %d\n", data);
-                       data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
-                       if (data < 0)
-                               return -EIO;
-               } else {
-                       /* Pack it into 1.125..15 variable step, register values 9..67 */
-                       /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
-                       unsigned long range = ctrl->maximum - ctrl->default_value - 1;
-                       unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) *
-                                              111 + range / 2) / range + 9;
-
-                       if (gain <= 32)
-                               data = gain;
-                       else if (gain <= 64)
-                               data = ((gain - 32) * 16 + 16) / 32 + 80;
-                       else
-                               data = ((gain - 64) * 7 + 28) / 56 + 96;
-
-                       dev_dbg(&client->dev, "Setting gain from %d to %d\n",
-                                reg_read(client, MT9M001_GLOBAL_GAIN), data);
-                       data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
-                       if (data < 0)
-                               return -EIO;
-               }
-               return 0;
-
-       case V4L2_CID_EXPOSURE_AUTO:
-               if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
-                       unsigned long range = exp->maximum - exp->minimum;
-                       unsigned long shutter = ((exp->val - (s32)exp->minimum) * 1048 +
-                                                range / 2) / range + 1;
-
-                       dev_dbg(&client->dev,
-                               "Setting shutter width from %d to %lu\n",
-                               reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
-                       if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
-                               return -EIO;
-               } else {
-                       const u16 vblank = 25;
-
-                       mt9m001->total_h = mt9m001->rect.height +
-                               mt9m001->y_skip_top + vblank;
-                       if (reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h) < 0)
-                               return -EIO;
-               }
-               return 0;
-       }
-       return -EINVAL;
-}
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9m001_video_probe(struct soc_camera_subdev_desc *ssdd,
-                              struct i2c_client *client)
-{
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       s32 data;
-       unsigned long flags;
-       int ret;
-
-       ret = mt9m001_s_power(&mt9m001->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /* Enable the chip */
-       data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
-       dev_dbg(&client->dev, "write: %d\n", data);
-
-       /* Read out the chip version register */
-       data = reg_read(client, MT9M001_CHIP_VERSION);
-
-       /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
-       switch (data) {
-       case 0x8411:
-       case 0x8421:
-               mt9m001->fmts = mt9m001_colour_fmts;
-               break;
-       case 0x8431:
-               mt9m001->fmts = mt9m001_monochrome_fmts;
-               break;
-       default:
-               dev_err(&client->dev,
-                       "No MT9M001 chip detected, register read %x\n", data);
-               ret = -ENODEV;
-               goto done;
-       }
-
-       mt9m001->num_fmts = 0;
-
-       /*
-        * This is a 10bit sensor, so by default we only allow 10bit.
-        * The platform may support different bus widths due to
-        * different routing of the data lines.
-        */
-       if (ssdd->query_bus_param)
-               flags = ssdd->query_bus_param(ssdd);
-       else
-               flags = SOCAM_DATAWIDTH_10;
-
-       if (flags & SOCAM_DATAWIDTH_10)
-               mt9m001->num_fmts++;
-       else
-               mt9m001->fmts++;
-
-       if (flags & SOCAM_DATAWIDTH_8)
-               mt9m001->num_fmts++;
-
-       mt9m001->fmt = &mt9m001->fmts[0];
-
-       dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
-                data == 0x8431 ? "C12STM" : "C12ST");
-
-       ret = mt9m001_init(client);
-       if (ret < 0) {
-               dev_err(&client->dev, "Failed to initialise the camera\n");
-               goto done;
-       }
-
-       /* mt9m001_init() has reset the chip, returning registers to defaults */
-       ret = v4l2_ctrl_handler_setup(&mt9m001->hdl);
-
-done:
-       mt9m001_s_power(&mt9m001->subdev, 0);
-       return ret;
-}
-
-static void mt9m001_video_remove(struct soc_camera_subdev_desc *ssdd)
-{
-       if (ssdd->free_bus)
-               ssdd->free_bus(ssdd);
-}
-
-static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-
-       *lines = mt9m001->y_skip_top;
-
-       return 0;
-}
-
-static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
-       .g_volatile_ctrl = mt9m001_g_volatile_ctrl,
-       .s_ctrl = mt9m001_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = mt9m001_g_register,
-       .s_register     = mt9m001_s_register,
-#endif
-       .s_power        = mt9m001_s_power,
-};
-
-static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-
-       if (code->pad || code->index >= mt9m001->num_fmts)
-               return -EINVAL;
-
-       code->code = mt9m001->fmts[code->index].code;
-       return 0;
-}
-
-static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       /* MT9M001 has all capture_format parameters fixed */
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
-                               const struct v4l2_mbus_config *cfg)
-{
-       const struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample;
-
-       if (ssdd->set_bus_param)
-               return ssdd->set_bus_param(ssdd, 1 << (bps - 1));
-
-       /*
-        * Without board specific bus width settings we only support the
-        * sensors native bus width
-        */
-       return bps == 10 ? 0 : -EINVAL;
-}
-
-static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
-       .s_stream       = mt9m001_s_stream,
-       .g_mbus_config  = mt9m001_g_mbus_config,
-       .s_mbus_config  = mt9m001_s_mbus_config,
-};
-
-static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
-       .g_skip_top_lines       = mt9m001_g_skip_top_lines,
-};
-
-static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = {
-       .enum_mbus_code = mt9m001_enum_mbus_code,
-       .get_selection  = mt9m001_get_selection,
-       .set_selection  = mt9m001_set_selection,
-       .get_fmt        = mt9m001_get_fmt,
-       .set_fmt        = mt9m001_set_fmt,
-};
-
-static const struct v4l2_subdev_ops mt9m001_subdev_ops = {
-       .core   = &mt9m001_subdev_core_ops,
-       .video  = &mt9m001_subdev_video_ops,
-       .sensor = &mt9m001_subdev_sensor_ops,
-       .pad    = &mt9m001_subdev_pad_ops,
-};
-
-static int mt9m001_probe(struct i2c_client *client,
-                        const struct i2c_device_id *did)
-{
-       struct mt9m001 *mt9m001;
-       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       int ret;
-
-       if (!ssdd) {
-               dev_err(&client->dev, "MT9M001 driver needs platform data\n");
-               return -EINVAL;
-       }
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
-               dev_warn(&adapter->dev,
-                        "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
-               return -EIO;
-       }
-
-       mt9m001 = devm_kzalloc(&client->dev, sizeof(struct mt9m001), GFP_KERNEL);
-       if (!mt9m001)
-               return -ENOMEM;
-
-       v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
-       v4l2_ctrl_handler_init(&mt9m001->hdl, 4);
-       v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
-                       V4L2_CID_VFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
-                       V4L2_CID_GAIN, 0, 127, 1, 64);
-       mt9m001->exposure = v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
-                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
-       /*
-        * Simulated autoexposure. If enabled, we calculate shutter width
-        * ourselves in the driver based on vertical blanking and frame width
-        */
-       mt9m001->autoexposure = v4l2_ctrl_new_std_menu(&mt9m001->hdl,
-                       &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
-                       V4L2_EXPOSURE_AUTO);
-       mt9m001->subdev.ctrl_handler = &mt9m001->hdl;
-       if (mt9m001->hdl.error)
-               return mt9m001->hdl.error;
-
-       v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure,
-                                       V4L2_EXPOSURE_MANUAL, true);
-
-       /* Second stage probe - when a capture adapter is there */
-       mt9m001->y_skip_top     = 0;
-       mt9m001->rect.left      = MT9M001_COLUMN_SKIP;
-       mt9m001->rect.top       = MT9M001_ROW_SKIP;
-       mt9m001->rect.width     = MT9M001_MAX_WIDTH;
-       mt9m001->rect.height    = MT9M001_MAX_HEIGHT;
-
-       mt9m001->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(mt9m001->clk)) {
-               ret = PTR_ERR(mt9m001->clk);
-               goto eclkget;
-       }
-
-       ret = mt9m001_video_probe(ssdd, client);
-       if (ret) {
-               v4l2_clk_put(mt9m001->clk);
-eclkget:
-               v4l2_ctrl_handler_free(&mt9m001->hdl);
-       }
-
-       return ret;
-}
-
-static int mt9m001_remove(struct i2c_client *client)
-{
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       v4l2_clk_put(mt9m001->clk);
-       v4l2_device_unregister_subdev(&mt9m001->subdev);
-       v4l2_ctrl_handler_free(&mt9m001->hdl);
-       mt9m001_video_remove(ssdd);
-
-       return 0;
-}
-
-static const struct i2c_device_id mt9m001_id[] = {
-       { "mt9m001", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9m001_id);
-
-static struct i2c_driver mt9m001_i2c_driver = {
-       .driver = {
-               .name = "mt9m001",
-       },
-       .probe          = mt9m001_probe,
-       .remove         = mt9m001_remove,
-       .id_table       = mt9m001_id,
-};
-
-module_i2c_driver(mt9m001_i2c_driver);
-
-MODULE_DESCRIPTION("Micron MT9M001 Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
deleted file mode 100644 (file)
index b53c36d..0000000
+++ /dev/null
@@ -1,1163 +0,0 @@
-/*
- * mt9t112 Camera Driver
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov772x driver, mt9m111 driver,
- *
- * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
- * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/i2c/mt9t112.h>
-#include <media/soc_camera.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-image-sizes.h>
-
-/* you can check PLL/clock info */
-/* #define EXT_CLOCK 24000000 */
-
-/************************************************************************
-                       macro
-************************************************************************/
-/*
- * frame size
- */
-#define MAX_WIDTH   2048
-#define MAX_HEIGHT  1536
-
-/*
- * macro of read/write
- */
-#define ECHECKER(ret, x)               \
-       do {                            \
-               (ret) = (x);            \
-               if ((ret) < 0)          \
-                       return (ret);   \
-       } while (0)
-
-#define mt9t112_reg_write(ret, client, a, b) \
-       ECHECKER(ret, __mt9t112_reg_write(client, a, b))
-#define mt9t112_mcu_write(ret, client, a, b) \
-       ECHECKER(ret, __mt9t112_mcu_write(client, a, b))
-
-#define mt9t112_reg_mask_set(ret, client, a, b, c) \
-       ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c))
-#define mt9t112_mcu_mask_set(ret, client, a, b, c) \
-       ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c))
-
-#define mt9t112_reg_read(ret, client, a) \
-       ECHECKER(ret, __mt9t112_reg_read(client, a))
-
-/*
- * Logical address
- */
-#define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff))
-#define VAR(id, offset)  _VAR(id, offset, 0x0000)
-#define VAR8(id, offset) _VAR(id, offset, 0x8000)
-
-/************************************************************************
-                       struct
-************************************************************************/
-struct mt9t112_format {
-       u32 code;
-       enum v4l2_colorspace colorspace;
-       u16 fmt;
-       u16 order;
-};
-
-struct mt9t112_priv {
-       struct v4l2_subdev               subdev;
-       struct mt9t112_platform_data    *info;
-       struct i2c_client               *client;
-       struct v4l2_rect                 frame;
-       struct v4l2_clk                 *clk;
-       const struct mt9t112_format     *format;
-       int                              num_formats;
-       u32                              flags;
-/* for flags */
-#define INIT_DONE      (1 << 0)
-#define PCLK_RISING    (1 << 1)
-};
-
-/************************************************************************
-                       supported format
-************************************************************************/
-
-static const struct mt9t112_format mt9t112_cfmts[] = {
-       {
-               .code           = MEDIA_BUS_FMT_UYVY8_2X8,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .fmt            = 1,
-               .order          = 0,
-       }, {
-               .code           = MEDIA_BUS_FMT_VYUY8_2X8,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .fmt            = 1,
-               .order          = 1,
-       }, {
-               .code           = MEDIA_BUS_FMT_YUYV8_2X8,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .fmt            = 1,
-               .order          = 2,
-       }, {
-               .code           = MEDIA_BUS_FMT_YVYU8_2X8,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .fmt            = 1,
-               .order          = 3,
-       }, {
-               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .fmt            = 8,
-               .order          = 2,
-       }, {
-               .code           = MEDIA_BUS_FMT_RGB565_2X8_LE,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .fmt            = 4,
-               .order          = 2,
-       },
-};
-
-/************************************************************************
-                       general function
-************************************************************************/
-static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
-{
-       return container_of(i2c_get_clientdata(client),
-                           struct mt9t112_priv,
-                           subdev);
-}
-
-static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
-{
-       struct i2c_msg msg[2];
-       u8 buf[2];
-       int ret;
-
-       command = swab16(command);
-
-       msg[0].addr  = client->addr;
-       msg[0].flags = 0;
-       msg[0].len   = 2;
-       msg[0].buf   = (u8 *)&command;
-
-       msg[1].addr  = client->addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].len   = 2;
-       msg[1].buf   = buf;
-
-       /*
-        * if return value of this function is < 0,
-        * it mean error.
-        * else, under 16bit is valid data.
-        */
-       ret = i2c_transfer(client->adapter, msg, 2);
-       if (ret < 0)
-               return ret;
-
-       memcpy(&ret, buf, 2);
-       return swab16(ret);
-}
-
-static int __mt9t112_reg_write(const struct i2c_client *client,
-                              u16 command, u16 data)
-{
-       struct i2c_msg msg;
-       u8 buf[4];
-       int ret;
-
-       command = swab16(command);
-       data = swab16(data);
-
-       memcpy(buf + 0, &command, 2);
-       memcpy(buf + 2, &data,    2);
-
-       msg.addr  = client->addr;
-       msg.flags = 0;
-       msg.len   = 4;
-       msg.buf   = buf;
-
-       /*
-        * i2c_transfer return message length,
-        * but this function should return 0 if correct case
-        */
-       ret = i2c_transfer(client->adapter, &msg, 1);
-       if (ret >= 0)
-               ret = 0;
-
-       return ret;
-}
-
-static int __mt9t112_reg_mask_set(const struct i2c_client *client,
-                                 u16  command,
-                                 u16  mask,
-                                 u16  set)
-{
-       int val = __mt9t112_reg_read(client, command);
-       if (val < 0)
-               return val;
-
-       val &= ~mask;
-       val |= set & mask;
-
-       return __mt9t112_reg_write(client, command, val);
-}
-
-/* mcu access */
-static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command)
-{
-       int ret;
-
-       ret = __mt9t112_reg_write(client, 0x098E, command);
-       if (ret < 0)
-               return ret;
-
-       return __mt9t112_reg_read(client, 0x0990);
-}
-
-static int __mt9t112_mcu_write(const struct i2c_client *client,
-                              u16 command, u16 data)
-{
-       int ret;
-
-       ret = __mt9t112_reg_write(client, 0x098E, command);
-       if (ret < 0)
-               return ret;
-
-       return __mt9t112_reg_write(client, 0x0990, data);
-}
-
-static int __mt9t112_mcu_mask_set(const struct i2c_client *client,
-                                 u16  command,
-                                 u16  mask,
-                                 u16  set)
-{
-       int val = __mt9t112_mcu_read(client, command);
-       if (val < 0)
-               return val;
-
-       val &= ~mask;
-       val |= set & mask;
-
-       return __mt9t112_mcu_write(client, command, val);
-}
-
-static int mt9t112_reset(const struct i2c_client *client)
-{
-       int ret;
-
-       mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001);
-       msleep(1);
-       mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000);
-
-       return ret;
-}
-
-#ifndef EXT_CLOCK
-#define CLOCK_INFO(a, b)
-#else
-#define CLOCK_INFO(a, b) mt9t112_clock_info(a, b)
-static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
-{
-       int m, n, p1, p2, p3, p4, p5, p6, p7;
-       u32 vco, clk;
-       char *enable;
-
-       ext /= 1000; /* kbyte order */
-
-       mt9t112_reg_read(n, client, 0x0012);
-       p1 = n & 0x000f;
-       n = n >> 4;
-       p2 = n & 0x000f;
-       n = n >> 4;
-       p3 = n & 0x000f;
-
-       mt9t112_reg_read(n, client, 0x002a);
-       p4 = n & 0x000f;
-       n = n >> 4;
-       p5 = n & 0x000f;
-       n = n >> 4;
-       p6 = n & 0x000f;
-
-       mt9t112_reg_read(n, client, 0x002c);
-       p7 = n & 0x000f;
-
-       mt9t112_reg_read(n, client, 0x0010);
-       m = n & 0x00ff;
-       n = (n >> 8) & 0x003f;
-
-       enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
-       dev_dbg(&client->dev, "EXTCLK          : %10u K %s\n", ext, enable);
-
-       vco = 2 * m * ext / (n+1);
-       enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
-       dev_dbg(&client->dev, "VCO             : %10u K %s\n", vco, enable);
-
-       clk = vco / (p1+1) / (p2+1);
-       enable = (96000 < clk) ? "X" : "";
-       dev_dbg(&client->dev, "PIXCLK          : %10u K %s\n", clk, enable);
-
-       clk = vco / (p3+1);
-       enable = (768000 < clk) ? "X" : "";
-       dev_dbg(&client->dev, "MIPICLK         : %10u K %s\n", clk, enable);
-
-       clk = vco / (p6+1);
-       enable = (96000 < clk) ? "X" : "";
-       dev_dbg(&client->dev, "MCU CLK         : %10u K %s\n", clk, enable);
-
-       clk = vco / (p5+1);
-       enable = (54000 < clk) ? "X" : "";
-       dev_dbg(&client->dev, "SOC CLK         : %10u K %s\n", clk, enable);
-
-       clk = vco / (p4+1);
-       enable = (70000 < clk) ? "X" : "";
-       dev_dbg(&client->dev, "Sensor CLK      : %10u K %s\n", clk, enable);
-
-       clk = vco / (p7+1);
-       dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
-
-       clk = ext / (n+1);
-       enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
-       dev_dbg(&client->dev, "PFD             : %10u K %s\n", clk, enable);
-
-       return 0;
-}
-#endif
-
-static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
-{
-       soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
-       soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
-}
-
-static int mt9t112_set_a_frame_size(const struct i2c_client *client,
-                                  u16 width,
-                                  u16 height)
-{
-       int ret;
-       u16 wstart = (MAX_WIDTH - width) / 2;
-       u16 hstart = (MAX_HEIGHT - height) / 2;
-
-       /* (Context A) Image Width/Height */
-       mt9t112_mcu_write(ret, client, VAR(26, 0), width);
-       mt9t112_mcu_write(ret, client, VAR(26, 2), height);
-
-       /* (Context A) Output Width/Height */
-       mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width);
-       mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height);
-
-       /* (Context A) Start Row/Column */
-       mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart);
-       mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart);
-
-       /* (Context A) End Row/Column */
-       mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart);
-       mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width  + wstart);
-
-       mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
-       return ret;
-}
-
-static int mt9t112_set_pll_dividers(const struct i2c_client *client,
-                                   u8 m, u8 n,
-                                   u8 p1, u8 p2, u8 p3,
-                                   u8 p4, u8 p5, u8 p6,
-                                   u8 p7)
-{
-       int ret;
-       u16 val;
-
-       /* N/M */
-       val = (n << 8) |
-             (m << 0);
-       mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val);
-
-       /* P1/P2/P3 */
-       val = ((p3 & 0x0F) << 8) |
-             ((p2 & 0x0F) << 4) |
-             ((p1 & 0x0F) << 0);
-       mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val);
-
-       /* P4/P5/P6 */
-       val = (0x7         << 12) |
-             ((p6 & 0x0F) <<  8) |
-             ((p5 & 0x0F) <<  4) |
-             ((p4 & 0x0F) <<  0);
-       mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val);
-
-       /* P7 */
-       val = (0x1         << 12) |
-             ((p7 & 0x0F) <<  0);
-       mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val);
-
-       return ret;
-}
-
-static int mt9t112_init_pll(const struct i2c_client *client)
-{
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       int data, i, ret;
-
-       mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
-
-       /* PLL control: BYPASS PLL = 8517 */
-       mt9t112_reg_write(ret, client, 0x0014, 0x2145);
-
-       /* Replace these registers when new timing parameters are generated */
-       mt9t112_set_pll_dividers(client,
-                                priv->info->divider.m,
-                                priv->info->divider.n,
-                                priv->info->divider.p1,
-                                priv->info->divider.p2,
-                                priv->info->divider.p3,
-                                priv->info->divider.p4,
-                                priv->info->divider.p5,
-                                priv->info->divider.p6,
-                                priv->info->divider.p7);
-
-       /*
-        * TEST_BYPASS  on
-        * PLL_ENABLE   on
-        * SEL_LOCK_DET on
-        * TEST_BYPASS  off
-        */
-       mt9t112_reg_write(ret, client, 0x0014, 0x2525);
-       mt9t112_reg_write(ret, client, 0x0014, 0x2527);
-       mt9t112_reg_write(ret, client, 0x0014, 0x3427);
-       mt9t112_reg_write(ret, client, 0x0014, 0x3027);
-
-       mdelay(10);
-
-       /*
-        * PLL_BYPASS off
-        * Reference clock count
-        * I2C Master Clock Divider
-        */
-       mt9t112_reg_write(ret, client, 0x0014, 0x3046);
-       mt9t112_reg_write(ret, client, 0x0016, 0x0400); /* JPEG initialization workaround */
-       mt9t112_reg_write(ret, client, 0x0022, 0x0190);
-       mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
-
-       /* External sensor clock is PLL bypass */
-       mt9t112_reg_write(ret, client, 0x002E, 0x0500);
-
-       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002);
-       mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004);
-
-       /* MCU disabled */
-       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004);
-
-       /* out of standby */
-       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
-
-       mdelay(50);
-
-       /*
-        * Standby Workaround
-        * Disable Secondary I2C Pads
-        */
-       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
-       mdelay(1);
-       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
-       mdelay(1);
-       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
-       mdelay(1);
-       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
-       mdelay(1);
-       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
-       mdelay(1);
-       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
-       mdelay(1);
-
-       /* poll to verify out of standby. Must Poll this bit */
-       for (i = 0; i < 100; i++) {
-               mt9t112_reg_read(data, client, 0x0018);
-               if (!(0x4000 & data))
-                       break;
-
-               mdelay(10);
-       }
-
-       return ret;
-}
-
-static int mt9t112_init_setting(const struct i2c_client *client)
-{
-
-       int ret;
-
-       /* Adaptive Output Clock (A) */
-       mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000);
-
-       /* Read Mode (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024);
-
-       /* Fine Correction (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC);
-
-       /* Fine IT Min (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1);
-
-       /* Fine IT Max Margin (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF);
-
-       /* Base Frame Lines (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D);
-
-       /* Min Line Length (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a);
-
-       /* Line Length (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0);
-
-       /* Adaptive Output Clock (B) */
-       mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000);
-
-       /* Row Start (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004);
-
-       /* Column Start (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004);
-
-       /* Row End (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B);
-
-       /* Column End (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B);
-
-       /* Fine Correction (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C);
-
-       /* Fine IT Min (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1);
-
-       /* Fine IT Max Margin (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF);
-
-       /* Base Frame Lines (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668);
-
-       /* Min Line Length (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0);
-
-       /* Line Length (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0);
-
-       /*
-        * Flicker Dectection registers
-        * This section should be replaced whenever new Timing file is generated
-        * All the following registers need to be replaced
-        * Following registers are generated from Register Wizard but user can
-        * modify them. For detail see auto flicker detection tuning
-        */
-
-       /* FD_FDPERIOD_SELECT */
-       mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01);
-
-       /* PRI_B_CONFIG_FD_ALGO_RUN */
-       mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003);
-
-       /* PRI_A_CONFIG_FD_ALGO_RUN */
-       mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003);
-
-       /*
-        * AFD range detection tuning registers
-        */
-
-       /* search_f1_50 */
-       mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25);
-
-       /* search_f2_50 */
-       mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28);
-
-       /* search_f1_60 */
-       mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C);
-
-       /* search_f2_60 */
-       mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F);
-
-       /* period_50Hz (A) */
-       mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA);
-
-       /* secret register by aptina */
-       /* period_50Hz (A MSB) */
-       mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00);
-
-       /* period_60Hz (A) */
-       mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B);
-
-       /* secret register by aptina */
-       /* period_60Hz (A MSB) */
-       mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00);
-
-       /* period_50Hz (B) */
-       mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82);
-
-       /* secret register by aptina */
-       /* period_50Hz (B) MSB */
-       mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00);
-
-       /* period_60Hz (B) */
-       mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D);
-
-       /* secret register by aptina */
-       /* period_60Hz (B) MSB */
-       mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00);
-
-       /* FD Mode */
-       mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10);
-
-       /* Stat_min */
-       mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02);
-
-       /* Stat_max */
-       mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03);
-
-       /* Min_amplitude */
-       mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A);
-
-       /* RX FIFO Watermark (A) */
-       mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014);
-
-       /* RX FIFO Watermark (B) */
-       mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014);
-
-       /* MCLK: 16MHz
-        * PCLK: 73MHz
-        * CorePixCLK: 36.5 MHz
-        */
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133);
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110);
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130);
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108);
-
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27);
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30);
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32);
-       mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35);
-
-       return ret;
-}
-
-static int mt9t112_auto_focus_setting(const struct i2c_client *client)
-{
-       int ret;
-
-       mt9t112_mcu_write(ret, client, VAR(12, 13),     0x000F);
-       mt9t112_mcu_write(ret, client, VAR(12, 23),     0x0F0F);
-       mt9t112_mcu_write(ret, client, VAR8(1, 0),      0x06);
-
-       mt9t112_reg_write(ret, client, 0x0614, 0x0000);
-
-       mt9t112_mcu_write(ret, client, VAR8(1, 0),      0x05);
-       mt9t112_mcu_write(ret, client, VAR8(12, 2),     0x02);
-       mt9t112_mcu_write(ret, client, VAR(12, 3),      0x0002);
-       mt9t112_mcu_write(ret, client, VAR(17, 3),      0x8001);
-       mt9t112_mcu_write(ret, client, VAR(17, 11),     0x0025);
-       mt9t112_mcu_write(ret, client, VAR(17, 13),     0x0193);
-       mt9t112_mcu_write(ret, client, VAR8(17, 33),    0x18);
-       mt9t112_mcu_write(ret, client, VAR8(1, 0),      0x05);
-
-       return ret;
-}
-
-static int mt9t112_auto_focus_trigger(const struct i2c_client *client)
-{
-       int ret;
-
-       mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01);
-
-       return ret;
-}
-
-static int mt9t112_init_camera(const struct i2c_client *client)
-{
-       int ret;
-
-       ECHECKER(ret, mt9t112_reset(client));
-
-       ECHECKER(ret, mt9t112_init_pll(client));
-
-       ECHECKER(ret, mt9t112_init_setting(client));
-
-       ECHECKER(ret, mt9t112_auto_focus_setting(client));
-
-       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
-
-       /* Analog setting B */
-       mt9t112_reg_write(ret, client, 0x3084, 0x2409);
-       mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
-       mt9t112_reg_write(ret, client, 0x3094, 0x4949);
-       mt9t112_reg_write(ret, client, 0x3096, 0x4950);
-
-       /*
-        * Disable adaptive clock
-        * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
-        * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
-        */
-       mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E);
-       mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E);
-
-       /* Configure STatus in Status_before_length Format and enable header */
-       /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
-       mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4);
-
-       /* Enable JPEG in context B */
-       /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
-       mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01);
-
-       /* Disable Dac_TXLO */
-       mt9t112_reg_write(ret, client, 0x316C, 0x350F);
-
-       /* Set max slew rates */
-       mt9t112_reg_write(ret, client, 0x1E, 0x777);
-
-       return ret;
-}
-
-/************************************************************************
-                       v4l2_subdev_core_ops
-************************************************************************/
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9t112_g_register(struct v4l2_subdev *sd,
-                             struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int                ret;
-
-       reg->size = 2;
-       mt9t112_reg_read(ret, client, reg->reg);
-
-       reg->val = (__u64)ret;
-
-       return 0;
-}
-
-static int mt9t112_s_register(struct v4l2_subdev *sd,
-                             const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
-
-       mt9t112_reg_write(ret, client, reg->reg, reg->val);
-
-       return ret;
-}
-#endif
-
-static int mt9t112_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-
-       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
-}
-
-static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = mt9t112_g_register,
-       .s_register     = mt9t112_s_register,
-#endif
-       .s_power        = mt9t112_s_power,
-};
-
-
-/************************************************************************
-                       v4l2_subdev_video_ops
-************************************************************************/
-static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       int ret = 0;
-
-       if (!enable) {
-               /* FIXME
-                *
-                * If user selected large output size,
-                * and used it long time,
-                * mt9t112 camera will be very warm.
-                *
-                * But current driver can not stop mt9t112 camera.
-                * So, set small size here to solve this problem.
-                */
-               mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
-               return ret;
-       }
-
-       if (!(priv->flags & INIT_DONE)) {
-               u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000;
-
-               ECHECKER(ret, mt9t112_init_camera(client));
-
-               /* Invert PCLK (Data sampled on falling edge of pixclk) */
-               mt9t112_reg_write(ret, client, 0x3C20, param);
-
-               mdelay(5);
-
-               priv->flags |= INIT_DONE;
-       }
-
-       mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
-       mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
-       mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
-
-       mt9t112_set_a_frame_size(client,
-                                priv->frame.width,
-                                priv->frame.height);
-
-       ECHECKER(ret, mt9t112_auto_focus_trigger(client));
-
-       dev_dbg(&client->dev, "format : %d\n", priv->format->code);
-       dev_dbg(&client->dev, "size   : %d x %d\n",
-               priv->frame.width,
-               priv->frame.height);
-
-       CLOCK_INFO(client, EXT_CLOCK);
-
-       return ret;
-}
-
-static int mt9t112_set_params(struct mt9t112_priv *priv,
-                             const struct v4l2_rect *rect,
-                             u32 code)
-{
-       int i;
-
-       /*
-        * get color format
-        */
-       for (i = 0; i < priv->num_formats; i++)
-               if (mt9t112_cfmts[i].code == code)
-                       break;
-
-       if (i == priv->num_formats)
-               return -EINVAL;
-
-       priv->frame  = *rect;
-
-       /*
-        * frame size check
-        */
-       mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
-                           &priv->frame.left, &priv->frame.top);
-
-       priv->format = mt9t112_cfmts + i;
-
-       return 0;
-}
-
-static int mt9t112_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               sel->r.left = 0;
-               sel->r.top = 0;
-               sel->r.width = MAX_WIDTH;
-               sel->r.height = MAX_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.left = 0;
-               sel->r.top = 0;
-               sel->r.width = VGA_WIDTH;
-               sel->r.height = VGA_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = priv->frame;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int mt9t112_set_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       const struct v4l2_rect *rect = &sel->r;
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       return mt9t112_set_params(priv, rect, priv->format->code);
-}
-
-static int mt9t112_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->width       = priv->frame.width;
-       mf->height      = priv->frame.height;
-       mf->colorspace  = priv->format->colorspace;
-       mf->code        = priv->format->code;
-       mf->field       = V4L2_FIELD_NONE;
-
-       return 0;
-}
-
-static int mt9t112_s_fmt(struct v4l2_subdev *sd,
-                        struct v4l2_mbus_framefmt *mf)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       struct v4l2_rect rect = {
-               .width = mf->width,
-               .height = mf->height,
-               .left = priv->frame.left,
-               .top = priv->frame.top,
-       };
-       int ret;
-
-       ret = mt9t112_set_params(priv, &rect, mf->code);
-
-       if (!ret)
-               mf->colorspace = priv->format->colorspace;
-
-       return ret;
-}
-
-static int mt9t112_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       unsigned int top, left;
-       int i;
-
-       if (format->pad)
-               return -EINVAL;
-
-       for (i = 0; i < priv->num_formats; i++)
-               if (mt9t112_cfmts[i].code == mf->code)
-                       break;
-
-       if (i == priv->num_formats) {
-               mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
-               mf->colorspace = V4L2_COLORSPACE_JPEG;
-       } else {
-               mf->colorspace  = mt9t112_cfmts[i].colorspace;
-       }
-
-       mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
-
-       mf->field = V4L2_FIELD_NONE;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               return mt9t112_s_fmt(sd, mf);
-       cfg->try_fmt = *mf;
-       return 0;
-}
-
-static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-
-       if (code->pad || code->index >= priv->num_formats)
-               return -EINVAL;
-
-       code->code = mt9t112_cfmts[code->index].code;
-
-       return 0;
-}
-
-static int mt9t112_g_mbus_config(struct v4l2_subdev *sd,
-                                struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH |
-               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
-                                const struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct mt9t112_priv *priv = to_mt9t112(client);
-
-       if (soc_camera_apply_board_flags(ssdd, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING)
-               priv->flags |= PCLK_RISING;
-
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
-       .s_stream       = mt9t112_s_stream,
-       .g_mbus_config  = mt9t112_g_mbus_config,
-       .s_mbus_config  = mt9t112_s_mbus_config,
-};
-
-static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = {
-       .enum_mbus_code = mt9t112_enum_mbus_code,
-       .get_selection  = mt9t112_get_selection,
-       .set_selection  = mt9t112_set_selection,
-       .get_fmt        = mt9t112_get_fmt,
-       .set_fmt        = mt9t112_set_fmt,
-};
-
-/************************************************************************
-                       i2c driver
-************************************************************************/
-static const struct v4l2_subdev_ops mt9t112_subdev_ops = {
-       .core   = &mt9t112_subdev_core_ops,
-       .video  = &mt9t112_subdev_video_ops,
-       .pad    = &mt9t112_subdev_pad_ops,
-};
-
-static int mt9t112_camera_probe(struct i2c_client *client)
-{
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       const char          *devname;
-       int                  chipid;
-       int                  ret;
-
-       ret = mt9t112_s_power(&priv->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * check and show chip ID
-        */
-       mt9t112_reg_read(chipid, client, 0x0000);
-
-       switch (chipid) {
-       case 0x2680:
-               devname = "mt9t111";
-               priv->num_formats = 1;
-               break;
-       case 0x2682:
-               devname = "mt9t112";
-               priv->num_formats = ARRAY_SIZE(mt9t112_cfmts);
-               break;
-       default:
-               dev_err(&client->dev, "Product ID error %04x\n", chipid);
-               ret = -ENODEV;
-               goto done;
-       }
-
-       dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
-
-done:
-       mt9t112_s_power(&priv->subdev, 0);
-       return ret;
-}
-
-static int mt9t112_probe(struct i2c_client *client,
-                        const struct i2c_device_id *did)
-{
-       struct mt9t112_priv *priv;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct v4l2_rect rect = {
-               .width = VGA_WIDTH,
-               .height = VGA_HEIGHT,
-               .left = (MAX_WIDTH - VGA_WIDTH) / 2,
-               .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
-       };
-       int ret;
-
-       if (!ssdd || !ssdd->drv_priv) {
-               dev_err(&client->dev, "mt9t112: missing platform data!\n");
-               return -EINVAL;
-       }
-
-       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->info = ssdd->drv_priv;
-
-       v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
-
-       priv->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(priv->clk))
-               return PTR_ERR(priv->clk);
-
-       ret = mt9t112_camera_probe(client);
-
-       /* Cannot fail: using the default supported pixel code */
-       if (!ret)
-               mt9t112_set_params(priv, &rect, MEDIA_BUS_FMT_UYVY8_2X8);
-       else
-               v4l2_clk_put(priv->clk);
-
-       return ret;
-}
-
-static int mt9t112_remove(struct i2c_client *client)
-{
-       struct mt9t112_priv *priv = to_mt9t112(client);
-
-       v4l2_clk_put(priv->clk);
-       return 0;
-}
-
-static const struct i2c_device_id mt9t112_id[] = {
-       { "mt9t112", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9t112_id);
-
-static struct i2c_driver mt9t112_i2c_driver = {
-       .driver = {
-               .name = "mt9t112",
-       },
-       .probe    = mt9t112_probe,
-       .remove   = mt9t112_remove,
-       .id_table = mt9t112_id,
-};
-
-module_i2c_driver(mt9t112_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
deleted file mode 100644 (file)
index 762f069..0000000
+++ /dev/null
@@ -1,1013 +0,0 @@
-/*
- * Driver for MT9V022 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/log2.h>
-#include <linux/module.h>
-
-#include <media/i2c/mt9v022.h>
-#include <media/soc_camera.h>
-#include <media/drv-intf/soc_mediabus.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
- * The platform has to define struct i2c_board_info objects and link to them
- * from struct soc_camera_host_desc
- */
-
-static char *sensor_type;
-module_param(sensor_type, charp, S_IRUGO);
-MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
-
-/* mt9v022 selected register addresses */
-#define MT9V022_CHIP_VERSION           0x00
-#define MT9V022_COLUMN_START           0x01
-#define MT9V022_ROW_START              0x02
-#define MT9V022_WINDOW_HEIGHT          0x03
-#define MT9V022_WINDOW_WIDTH           0x04
-#define MT9V022_HORIZONTAL_BLANKING    0x05
-#define MT9V022_VERTICAL_BLANKING      0x06
-#define MT9V022_CHIP_CONTROL           0x07
-#define MT9V022_SHUTTER_WIDTH1         0x08
-#define MT9V022_SHUTTER_WIDTH2         0x09
-#define MT9V022_SHUTTER_WIDTH_CTRL     0x0a
-#define MT9V022_TOTAL_SHUTTER_WIDTH    0x0b
-#define MT9V022_RESET                  0x0c
-#define MT9V022_READ_MODE              0x0d
-#define MT9V022_MONITOR_MODE           0x0e
-#define MT9V022_PIXEL_OPERATION_MODE   0x0f
-#define MT9V022_LED_OUT_CONTROL                0x1b
-#define MT9V022_ADC_MODE_CONTROL       0x1c
-#define MT9V022_REG32                  0x20
-#define MT9V022_ANALOG_GAIN            0x35
-#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
-#define MT9V022_PIXCLK_FV_LV           0x74
-#define MT9V022_DIGITAL_TEST_PATTERN   0x7f
-#define MT9V022_AEC_AGC_ENABLE         0xAF
-#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH        0xBD
-
-/* mt9v024 partial list register addresses changes with respect to mt9v022 */
-#define MT9V024_PIXCLK_FV_LV           0x72
-#define MT9V024_MAX_TOTAL_SHUTTER_WIDTH        0xAD
-
-/* Progressive scan, master, defaults */
-#define MT9V022_CHIP_CONTROL_DEFAULT   0x188
-
-#define MT9V022_MAX_WIDTH              752
-#define MT9V022_MAX_HEIGHT             480
-#define MT9V022_MIN_WIDTH              48
-#define MT9V022_MIN_HEIGHT             32
-#define MT9V022_COLUMN_SKIP            1
-#define MT9V022_ROW_SKIP               4
-
-#define MT9V022_HORIZONTAL_BLANKING_MIN        43
-#define MT9V022_HORIZONTAL_BLANKING_MAX        1023
-#define MT9V022_HORIZONTAL_BLANKING_DEF        94
-#define MT9V022_VERTICAL_BLANKING_MIN  2
-#define MT9V022_VERTICAL_BLANKING_MAX  3000
-#define MT9V022_VERTICAL_BLANKING_DEF  45
-
-#define is_mt9v022_rev3(id)    (id == 0x1313)
-#define is_mt9v024(id)         (id == 0x1324)
-
-/* MT9V022 has only one fixed colorspace per pixelcode */
-struct mt9v022_datafmt {
-       u32     code;
-       enum v4l2_colorspace            colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct mt9v022_datafmt *mt9v022_find_datafmt(
-       u32 code, const struct mt9v022_datafmt *fmt,
-       int n)
-{
-       int i;
-       for (i = 0; i < n; i++)
-               if (fmt[i].code == code)
-                       return fmt + i;
-
-       return NULL;
-}
-
-static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
-       /*
-        * Order important: first natively supported,
-        * second supported with a GPIO extender
-        */
-       {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
-};
-
-static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
-       /* Order important - see above */
-       {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
-       {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
-};
-
-/* only registers with different addresses on different mt9v02x sensors */
-struct mt9v02x_register {
-       u8      max_total_shutter_width;
-       u8      pixclk_fv_lv;
-};
-
-static const struct mt9v02x_register mt9v022_register = {
-       .max_total_shutter_width        = MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
-       .pixclk_fv_lv                   = MT9V022_PIXCLK_FV_LV,
-};
-
-static const struct mt9v02x_register mt9v024_register = {
-       .max_total_shutter_width        = MT9V024_MAX_TOTAL_SHUTTER_WIDTH,
-       .pixclk_fv_lv                   = MT9V024_PIXCLK_FV_LV,
-};
-
-enum mt9v022_model {
-       MT9V022IX7ATM,
-       MT9V022IX7ATC,
-};
-
-struct mt9v022 {
-       struct v4l2_subdev subdev;
-       struct v4l2_ctrl_handler hdl;
-       struct {
-               /* exposure/auto-exposure cluster */
-               struct v4l2_ctrl *autoexposure;
-               struct v4l2_ctrl *exposure;
-       };
-       struct {
-               /* gain/auto-gain cluster */
-               struct v4l2_ctrl *autogain;
-               struct v4l2_ctrl *gain;
-       };
-       struct v4l2_ctrl *hblank;
-       struct v4l2_ctrl *vblank;
-       struct v4l2_rect rect;  /* Sensor window */
-       struct v4l2_clk *clk;
-       const struct mt9v022_datafmt *fmt;
-       const struct mt9v022_datafmt *fmts;
-       const struct mt9v02x_register *reg;
-       int num_fmts;
-       enum mt9v022_model model;
-       u16 chip_control;
-       u16 chip_version;
-       unsigned short y_skip_top;      /* Lines to skip at the top */
-};
-
-static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
-{
-       return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u8 reg)
-{
-       return i2c_smbus_read_word_swapped(client, reg);
-}
-
-static int reg_write(struct i2c_client *client, const u8 reg,
-                    const u16 data)
-{
-       return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int reg_set(struct i2c_client *client, const u8 reg,
-                  const u16 data)
-{
-       int ret;
-
-       ret = reg_read(client, reg);
-       if (ret < 0)
-               return ret;
-       return reg_write(client, reg, ret | data);
-}
-
-static int reg_clear(struct i2c_client *client, const u8 reg,
-                    const u16 data)
-{
-       int ret;
-
-       ret = reg_read(client, reg);
-       if (ret < 0)
-               return ret;
-       return reg_write(client, reg, ret & ~data);
-}
-
-static int mt9v022_init(struct i2c_client *client)
-{
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       int ret;
-
-       /*
-        * Almost the default mode: master, parallel, simultaneous, and an
-        * undocumented bit 0x200, which is present in table 7, but not in 8,
-        * plus snapshot mode to disable scan for now
-        */
-       mt9v022->chip_control |= 0x10;
-       ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
-       if (!ret)
-               ret = reg_write(client, MT9V022_READ_MODE, 0x300);
-
-       /* All defaults */
-       if (!ret)
-               /* AEC, AGC on */
-               ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
-       if (!ret)
-               ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
-       if (!ret)
-               ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
-       if (!ret)
-               ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480);
-       if (!ret)
-               /* default - auto */
-               ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
-       if (!ret)
-               ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
-       if (!ret)
-               return v4l2_ctrl_handler_setup(&mt9v022->hdl);
-
-       return ret;
-}
-
-static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-       if (enable) {
-               /* Switch to master "normal" mode */
-               mt9v022->chip_control &= ~0x10;
-               if (is_mt9v022_rev3(mt9v022->chip_version) ||
-                   is_mt9v024(mt9v022->chip_version)) {
-                       /*
-                        * Unset snapshot mode specific settings: clear bit 9
-                        * and bit 2 in reg. 0x20 when in normal mode.
-                        */
-                       if (reg_clear(client, MT9V022_REG32, 0x204))
-                               return -EIO;
-               }
-       } else {
-               /* Switch to snapshot mode */
-               mt9v022->chip_control |= 0x10;
-               if (is_mt9v022_rev3(mt9v022->chip_version) ||
-                   is_mt9v024(mt9v022->chip_version)) {
-                       /*
-                        * Required settings for snapshot mode: set bit 9
-                        * (RST enable) and bit 2 (CR enable) in reg. 0x20
-                        * See TechNote TN0960 or TN-09-225.
-                        */
-                       if (reg_set(client, MT9V022_REG32, 0x204))
-                               return -EIO;
-               }
-       }
-
-       if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
-               return -EIO;
-       return 0;
-}
-
-static int mt9v022_set_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct v4l2_rect rect = sel->r;
-       int min_row, min_blank;
-       int ret;
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       /* Bayer format - even size lengths */
-       if (mt9v022->fmts == mt9v022_colour_fmts) {
-               rect.width      = ALIGN(rect.width, 2);
-               rect.height     = ALIGN(rect.height, 2);
-               /* Let the user play with the starting pixel */
-       }
-
-       soc_camera_limit_side(&rect.left, &rect.width,
-                    MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
-
-       soc_camera_limit_side(&rect.top, &rect.height,
-                    MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
-
-       /* Like in example app. Contradicts the datasheet though */
-       ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
-       if (ret >= 0) {
-               if (ret & 1) /* Autoexposure */
-                       ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
-                                       rect.height + mt9v022->y_skip_top + 43);
-               /*
-                * If autoexposure is off, there is no need to set
-                * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off
-                * only if the user has set exposure manually, using the
-                * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL.
-                * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH
-                * already contains the correct value.
-                */
-       }
-       /* Setup frame format: defaults apart from width and height */
-       if (!ret)
-               ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
-       if (!ret)
-               ret = reg_write(client, MT9V022_ROW_START, rect.top);
-       /*
-        * mt9v022: min total row time is 660 columns, min blanking is 43
-        * mt9v024: min total row time is 690 columns, min blanking is 61
-        */
-       if (is_mt9v024(mt9v022->chip_version)) {
-               min_row = 690;
-               min_blank = 61;
-       } else {
-               min_row = 660;
-               min_blank = 43;
-       }
-       if (!ret)
-               ret = v4l2_ctrl_s_ctrl(mt9v022->hblank,
-                               rect.width > min_row - min_blank ?
-                               min_blank : min_row - rect.width);
-       if (!ret)
-               ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45);
-       if (!ret)
-               ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
-       if (!ret)
-               ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
-                               rect.height + mt9v022->y_skip_top);
-
-       if (ret < 0)
-               return ret;
-
-       dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height);
-
-       mt9v022->rect = rect;
-
-       return 0;
-}
-
-static int mt9v022_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.left = MT9V022_COLUMN_SKIP;
-               sel->r.top = MT9V022_ROW_SKIP;
-               sel->r.width = MT9V022_MAX_WIDTH;
-               sel->r.height = MT9V022_MAX_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = mt9v022->rect;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int mt9v022_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->width       = mt9v022->rect.width;
-       mf->height      = mt9v022->rect.height;
-       mf->code        = mt9v022->fmt->code;
-       mf->colorspace  = mt9v022->fmt->colorspace;
-       mf->field       = V4L2_FIELD_NONE;
-
-       return 0;
-}
-
-static int mt9v022_s_fmt(struct v4l2_subdev *sd,
-                        const struct mt9v022_datafmt *fmt,
-                        struct v4l2_mbus_framefmt *mf)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct v4l2_subdev_selection sel = {
-               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-               .target = V4L2_SEL_TGT_CROP,
-               .r.left = mt9v022->rect.left,
-               .r.top = mt9v022->rect.top,
-               .r.width = mf->width,
-               .r.height = mf->height,
-       };
-       int ret;
-
-       /*
-        * The caller provides a supported format, as verified per call to
-        * .set_fmt(FORMAT_TRY), datawidth is from our supported format list
-        */
-       switch (mf->code) {
-       case MEDIA_BUS_FMT_Y8_1X8:
-       case MEDIA_BUS_FMT_Y10_1X10:
-               if (mt9v022->model != MT9V022IX7ATM)
-                       return -EINVAL;
-               break;
-       case MEDIA_BUS_FMT_SBGGR8_1X8:
-       case MEDIA_BUS_FMT_SBGGR10_1X10:
-               if (mt9v022->model != MT9V022IX7ATC)
-                       return -EINVAL;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* No support for scaling on this camera, just crop. */
-       ret = mt9v022_set_selection(sd, NULL, &sel);
-       if (!ret) {
-               mf->width       = mt9v022->rect.width;
-               mf->height      = mt9v022->rect.height;
-               mt9v022->fmt    = fmt;
-               mf->colorspace  = fmt->colorspace;
-       }
-
-       return ret;
-}
-
-static int mt9v022_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       const struct mt9v022_datafmt *fmt;
-       int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
-               mf->code == MEDIA_BUS_FMT_SBGGR10_1X10;
-
-       if (format->pad)
-               return -EINVAL;
-
-       v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
-               MT9V022_MAX_WIDTH, align,
-               &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
-               MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
-
-       fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
-                                  mt9v022->num_fmts);
-       if (!fmt) {
-               fmt = mt9v022->fmt;
-               mf->code = fmt->code;
-       }
-
-       mf->colorspace  = fmt->colorspace;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               return mt9v022_s_fmt(sd, fmt, mf);
-       cfg->try_fmt = *mf;
-       return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9v022_g_register(struct v4l2_subdev *sd,
-                             struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg > 0xff)
-               return -EINVAL;
-
-       reg->size = 2;
-       reg->val = reg_read(client, reg->reg);
-
-       if (reg->val > 0xffff)
-               return -EIO;
-
-       return 0;
-}
-
-static int mt9v022_s_register(struct v4l2_subdev *sd,
-                             const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg > 0xff)
-               return -EINVAL;
-
-       if (reg_write(client, reg->reg, reg->val) < 0)
-               return -EIO;
-
-       return 0;
-}
-#endif
-
-static int mt9v022_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-       return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
-}
-
-static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct mt9v022 *mt9v022 = container_of(ctrl->handler,
-                                              struct mt9v022, hdl);
-       struct v4l2_subdev *sd = &mt9v022->subdev;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct v4l2_ctrl *gain = mt9v022->gain;
-       struct v4l2_ctrl *exp = mt9v022->exposure;
-       unsigned long range;
-       int data;
-
-       switch (ctrl->id) {
-       case V4L2_CID_AUTOGAIN:
-               data = reg_read(client, MT9V022_ANALOG_GAIN);
-               if (data < 0)
-                       return -EIO;
-
-               range = gain->maximum - gain->minimum;
-               gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
-               return 0;
-       case V4L2_CID_EXPOSURE_AUTO:
-               data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
-               if (data < 0)
-                       return -EIO;
-
-               range = exp->maximum - exp->minimum;
-               exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
-               return 0;
-       case V4L2_CID_HBLANK:
-               data = reg_read(client, MT9V022_HORIZONTAL_BLANKING);
-               if (data < 0)
-                       return -EIO;
-               ctrl->val = data;
-               return 0;
-       case V4L2_CID_VBLANK:
-               data = reg_read(client, MT9V022_VERTICAL_BLANKING);
-               if (data < 0)
-                       return -EIO;
-               ctrl->val = data;
-               return 0;
-       }
-       return -EINVAL;
-}
-
-static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct mt9v022 *mt9v022 = container_of(ctrl->handler,
-                                              struct mt9v022, hdl);
-       struct v4l2_subdev *sd = &mt9v022->subdev;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int data;
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               if (ctrl->val)
-                       data = reg_set(client, MT9V022_READ_MODE, 0x10);
-               else
-                       data = reg_clear(client, MT9V022_READ_MODE, 0x10);
-               if (data < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_HFLIP:
-               if (ctrl->val)
-                       data = reg_set(client, MT9V022_READ_MODE, 0x20);
-               else
-                       data = reg_clear(client, MT9V022_READ_MODE, 0x20);
-               if (data < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_AUTOGAIN:
-               if (ctrl->val) {
-                       if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
-                               return -EIO;
-               } else {
-                       struct v4l2_ctrl *gain = mt9v022->gain;
-                       /* mt9v022 has minimum == default */
-                       unsigned long range = gain->maximum - gain->minimum;
-                       /* Valid values 16 to 64, 32 to 64 must be even. */
-                       unsigned long gain_val = ((gain->val - (s32)gain->minimum) *
-                                             48 + range / 2) / range + 16;
-
-                       if (gain_val >= 32)
-                               gain_val &= ~1;
-
-                       /*
-                        * The user wants to set gain manually, hope, she
-                        * knows, what she's doing... Switch AGC off.
-                        */
-                       if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
-                               return -EIO;
-
-                       dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
-                               reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
-                       if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
-                               return -EIO;
-               }
-               return 0;
-       case V4L2_CID_EXPOSURE_AUTO:
-               if (ctrl->val == V4L2_EXPOSURE_AUTO) {
-                       data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
-               } else {
-                       struct v4l2_ctrl *exp = mt9v022->exposure;
-                       unsigned long range = exp->maximum - exp->minimum;
-                       unsigned long shutter = ((exp->val - (s32)exp->minimum) *
-                                       479 + range / 2) / range + 1;
-
-                       /*
-                        * The user wants to set shutter width manually, hope,
-                        * she knows, what she's doing... Switch AEC off.
-                        */
-                       data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
-                       if (data < 0)
-                               return -EIO;
-                       dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
-                                       reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
-                                       shutter);
-                       if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
-                                               shutter) < 0)
-                               return -EIO;
-               }
-               return 0;
-       case V4L2_CID_HBLANK:
-               if (reg_write(client, MT9V022_HORIZONTAL_BLANKING,
-                               ctrl->val) < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_VBLANK:
-               if (reg_write(client, MT9V022_VERTICAL_BLANKING,
-                               ctrl->val) < 0)
-                       return -EIO;
-               return 0;
-       }
-       return -EINVAL;
-}
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9v022_video_probe(struct i2c_client *client)
-{
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       s32 data;
-       int ret;
-       unsigned long flags;
-
-       ret = mt9v022_s_power(&mt9v022->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /* Read out the chip version register */
-       data = reg_read(client, MT9V022_CHIP_VERSION);
-
-       /* must be 0x1311, 0x1313 or 0x1324 */
-       if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
-               ret = -ENODEV;
-               dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
-                        data);
-               goto ei2c;
-       }
-
-       mt9v022->chip_version = data;
-
-       mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
-                       &mt9v022_register;
-
-       /* Soft reset */
-       ret = reg_write(client, MT9V022_RESET, 1);
-       if (ret < 0)
-               goto ei2c;
-       /* 15 clock cycles */
-       udelay(200);
-       if (reg_read(client, MT9V022_RESET)) {
-               dev_err(&client->dev, "Resetting MT9V022 failed!\n");
-               if (ret > 0)
-                       ret = -EIO;
-               goto ei2c;
-       }
-
-       /* Set monochrome or colour sensor type */
-       if (sensor_type && (!strcmp("colour", sensor_type) ||
-                           !strcmp("color", sensor_type))) {
-               ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
-               mt9v022->model = MT9V022IX7ATC;
-               mt9v022->fmts = mt9v022_colour_fmts;
-       } else {
-               ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
-               mt9v022->model = MT9V022IX7ATM;
-               mt9v022->fmts = mt9v022_monochrome_fmts;
-       }
-
-       if (ret < 0)
-               goto ei2c;
-
-       mt9v022->num_fmts = 0;
-
-       /*
-        * This is a 10bit sensor, so by default we only allow 10bit.
-        * The platform may support different bus widths due to
-        * different routing of the data lines.
-        */
-       if (ssdd->query_bus_param)
-               flags = ssdd->query_bus_param(ssdd);
-       else
-               flags = SOCAM_DATAWIDTH_10;
-
-       if (flags & SOCAM_DATAWIDTH_10)
-               mt9v022->num_fmts++;
-       else
-               mt9v022->fmts++;
-
-       if (flags & SOCAM_DATAWIDTH_8)
-               mt9v022->num_fmts++;
-
-       mt9v022->fmt = &mt9v022->fmts[0];
-
-       dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
-                data, mt9v022->model == MT9V022IX7ATM ?
-                "monochrome" : "colour");
-
-       ret = mt9v022_init(client);
-       if (ret < 0)
-               dev_err(&client->dev, "Failed to initialise the camera\n");
-
-ei2c:
-       mt9v022_s_power(&mt9v022->subdev, 0);
-       return ret;
-}
-
-static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-       *lines = mt9v022->y_skip_top;
-
-       return 0;
-}
-
-static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
-       .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
-       .s_ctrl = mt9v022_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = mt9v022_g_register,
-       .s_register     = mt9v022_s_register,
-#endif
-       .s_power        = mt9v022_s_power,
-};
-
-static int mt9v022_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-       if (code->pad || code->index >= mt9v022->num_fmts)
-               return -EINVAL;
-
-       code->code = mt9v022->fmts[code->index].code;
-       return 0;
-}
-
-static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
-               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
-               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
-                                const struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg);
-       unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
-       int ret;
-       u16 pixclk = 0;
-
-       if (ssdd->set_bus_param) {
-               ret = ssdd->set_bus_param(ssdd, 1 << (bps - 1));
-               if (ret)
-                       return ret;
-       } else if (bps != 10) {
-               /*
-                * Without board specific bus width settings we only support the
-                * sensors native bus width
-                */
-               return -EINVAL;
-       }
-
-       if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
-               pixclk |= 0x10;
-
-       if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
-               pixclk |= 0x1;
-
-       if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
-               pixclk |= 0x2;
-
-       ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk);
-       if (ret < 0)
-               return ret;
-
-       if (!(flags & V4L2_MBUS_MASTER))
-               mt9v022->chip_control &= ~0x8;
-
-       ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
-       if (ret < 0)
-               return ret;
-
-       dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
-               pixclk, mt9v022->chip_control);
-
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
-       .s_stream       = mt9v022_s_stream,
-       .g_mbus_config  = mt9v022_g_mbus_config,
-       .s_mbus_config  = mt9v022_s_mbus_config,
-};
-
-static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
-       .g_skip_top_lines       = mt9v022_g_skip_top_lines,
-};
-
-static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = {
-       .enum_mbus_code = mt9v022_enum_mbus_code,
-       .get_selection  = mt9v022_get_selection,
-       .set_selection  = mt9v022_set_selection,
-       .get_fmt        = mt9v022_get_fmt,
-       .set_fmt        = mt9v022_set_fmt,
-};
-
-static const struct v4l2_subdev_ops mt9v022_subdev_ops = {
-       .core   = &mt9v022_subdev_core_ops,
-       .video  = &mt9v022_subdev_video_ops,
-       .sensor = &mt9v022_subdev_sensor_ops,
-       .pad    = &mt9v022_subdev_pad_ops,
-};
-
-static int mt9v022_probe(struct i2c_client *client,
-                        const struct i2c_device_id *did)
-{
-       struct mt9v022 *mt9v022;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct mt9v022_platform_data *pdata;
-       int ret;
-
-       if (!ssdd) {
-               dev_err(&client->dev, "MT9V022 driver needs platform data\n");
-               return -EINVAL;
-       }
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
-               dev_warn(&adapter->dev,
-                        "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
-               return -EIO;
-       }
-
-       mt9v022 = devm_kzalloc(&client->dev, sizeof(struct mt9v022), GFP_KERNEL);
-       if (!mt9v022)
-               return -ENOMEM;
-
-       pdata = ssdd->drv_priv;
-       v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
-       v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
-       v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_VFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_HFLIP, 0, 1, 1, 0);
-       mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
-       mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_GAIN, 0, 127, 1, 64);
-
-       /*
-        * Simulated autoexposure. If enabled, we calculate shutter width
-        * ourselves in the driver based on vertical blanking and frame width
-        */
-       mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
-                       &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
-                       V4L2_EXPOSURE_AUTO);
-       mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
-
-       mt9v022->hblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_HBLANK, MT9V022_HORIZONTAL_BLANKING_MIN,
-                       MT9V022_HORIZONTAL_BLANKING_MAX, 1,
-                       MT9V022_HORIZONTAL_BLANKING_DEF);
-
-       mt9v022->vblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
-                       V4L2_CID_VBLANK, MT9V022_VERTICAL_BLANKING_MIN,
-                       MT9V022_VERTICAL_BLANKING_MAX, 1,
-                       MT9V022_VERTICAL_BLANKING_DEF);
-
-       mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
-       if (mt9v022->hdl.error) {
-               int err = mt9v022->hdl.error;
-
-               dev_err(&client->dev, "control initialisation err %d\n", err);
-               return err;
-       }
-       v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
-                               V4L2_EXPOSURE_MANUAL, true);
-       v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
-
-       mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
-
-       /*
-        * On some platforms the first read out line is corrupted.
-        * Workaround it by skipping if indicated by platform data.
-        */
-       mt9v022->y_skip_top     = pdata ? pdata->y_skip_top : 0;
-       mt9v022->rect.left      = MT9V022_COLUMN_SKIP;
-       mt9v022->rect.top       = MT9V022_ROW_SKIP;
-       mt9v022->rect.width     = MT9V022_MAX_WIDTH;
-       mt9v022->rect.height    = MT9V022_MAX_HEIGHT;
-
-       mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(mt9v022->clk)) {
-               ret = PTR_ERR(mt9v022->clk);
-               goto eclkget;
-       }
-
-       ret = mt9v022_video_probe(client);
-       if (ret) {
-               v4l2_clk_put(mt9v022->clk);
-eclkget:
-               v4l2_ctrl_handler_free(&mt9v022->hdl);
-       }
-
-       return ret;
-}
-
-static int mt9v022_remove(struct i2c_client *client)
-{
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       v4l2_clk_put(mt9v022->clk);
-       v4l2_device_unregister_subdev(&mt9v022->subdev);
-       if (ssdd->free_bus)
-               ssdd->free_bus(ssdd);
-       v4l2_ctrl_handler_free(&mt9v022->hdl);
-
-       return 0;
-}
-static const struct i2c_device_id mt9v022_id[] = {
-       { "mt9v022", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, mt9v022_id);
-
-static struct i2c_driver mt9v022_i2c_driver = {
-       .driver = {
-               .name = "mt9v022",
-       },
-       .probe          = mt9v022_probe,
-       .remove         = mt9v022_remove,
-       .id_table       = mt9v022_id,
-};
-
-module_i2c_driver(mt9v022_i2c_driver);
-
-MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
deleted file mode 100644 (file)
index 39f420d..0000000
+++ /dev/null
@@ -1,1088 +0,0 @@
-/*
- * Driver for OV5642 CMOS Image Sensor from Omnivision
- *
- * Copyright (C) 2011, Bastian Hecht <hechtb@gmail.com>
- *
- * Based on Sony IMX074 Camera Driver
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * Based on Omnivision OV7670 Camera Driver
- * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-#include <linux/v4l2-mediabus.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-subdev.h>
-
-/* OV5642 registers */
-#define REG_CHIP_ID_HIGH               0x300a
-#define REG_CHIP_ID_LOW                        0x300b
-
-#define REG_WINDOW_START_X_HIGH                0x3800
-#define REG_WINDOW_START_X_LOW         0x3801
-#define REG_WINDOW_START_Y_HIGH                0x3802
-#define REG_WINDOW_START_Y_LOW         0x3803
-#define REG_WINDOW_WIDTH_HIGH          0x3804
-#define REG_WINDOW_WIDTH_LOW           0x3805
-#define REG_WINDOW_HEIGHT_HIGH         0x3806
-#define REG_WINDOW_HEIGHT_LOW          0x3807
-#define REG_OUT_WIDTH_HIGH             0x3808
-#define REG_OUT_WIDTH_LOW              0x3809
-#define REG_OUT_HEIGHT_HIGH            0x380a
-#define REG_OUT_HEIGHT_LOW             0x380b
-#define REG_OUT_TOTAL_WIDTH_HIGH       0x380c
-#define REG_OUT_TOTAL_WIDTH_LOW                0x380d
-#define REG_OUT_TOTAL_HEIGHT_HIGH      0x380e
-#define REG_OUT_TOTAL_HEIGHT_LOW       0x380f
-#define REG_OUTPUT_FORMAT              0x4300
-#define REG_ISP_CTRL_01                        0x5001
-#define REG_AVG_WINDOW_END_X_HIGH      0x5682
-#define REG_AVG_WINDOW_END_X_LOW       0x5683
-#define REG_AVG_WINDOW_END_Y_HIGH      0x5686
-#define REG_AVG_WINDOW_END_Y_LOW       0x5687
-
-/* active pixel array size */
-#define OV5642_SENSOR_SIZE_X   2592
-#define OV5642_SENSOR_SIZE_Y   1944
-
-/*
- * About OV5642 resolution, cropping and binning:
- * This sensor supports it all, at least in the feature description.
- * Unfortunately, no combination of appropriate registers settings could make
- * the chip work the intended way. As it works with predefined register lists,
- * some undocumented registers are presumably changed there to achieve their
- * goals.
- * This driver currently only works for resolutions up to 720 lines with a
- * 1:1 scale. Hopefully these restrictions will be removed in the future.
- */
-#define OV5642_MAX_WIDTH       OV5642_SENSOR_SIZE_X
-#define OV5642_MAX_HEIGHT      720
-
-/* default sizes */
-#define OV5642_DEFAULT_WIDTH   1280
-#define OV5642_DEFAULT_HEIGHT  OV5642_MAX_HEIGHT
-
-/* minimum extra blanking */
-#define BLANKING_EXTRA_WIDTH           500
-#define BLANKING_EXTRA_HEIGHT          20
-
-/*
- * the sensor's autoexposure is buggy when setting total_height low.
- * It tries to expose longer than 1 frame period without taking care of it
- * and this leads to weird output. So we set 1000 lines as minimum.
- */
-#define BLANKING_MIN_HEIGHT            1000
-
-struct regval_list {
-       u16 reg_num;
-       u8 value;
-};
-
-static struct regval_list ov5642_default_regs_init[] = {
-       { 0x3103, 0x93 },
-       { 0x3008, 0x82 },
-       { 0x3017, 0x7f },
-       { 0x3018, 0xfc },
-       { 0x3810, 0xc2 },
-       { 0x3615, 0xf0 },
-       { 0x3000, 0x0  },
-       { 0x3001, 0x0  },
-       { 0x3002, 0x0  },
-       { 0x3003, 0x0  },
-       { 0x3004, 0xff },
-       { 0x3030, 0x2b },
-       { 0x3011, 0x8  },
-       { 0x3010, 0x10 },
-       { 0x3604, 0x60 },
-       { 0x3622, 0x60 },
-       { 0x3621, 0x9  },
-       { 0x3709, 0x0  },
-       { 0x4000, 0x21 },
-       { 0x401d, 0x22 },
-       { 0x3600, 0x54 },
-       { 0x3605, 0x4  },
-       { 0x3606, 0x3f },
-       { 0x3c01, 0x80 },
-       { 0x300d, 0x22 },
-       { 0x3623, 0x22 },
-       { 0x5000, 0x4f },
-       { 0x5020, 0x4  },
-       { 0x5181, 0x79 },
-       { 0x5182, 0x0  },
-       { 0x5185, 0x22 },
-       { 0x5197, 0x1  },
-       { 0x5500, 0xa  },
-       { 0x5504, 0x0  },
-       { 0x5505, 0x7f },
-       { 0x5080, 0x8  },
-       { 0x300e, 0x18 },
-       { 0x4610, 0x0  },
-       { 0x471d, 0x5  },
-       { 0x4708, 0x6  },
-       { 0x370c, 0xa0 },
-       { 0x5687, 0x94 },
-       { 0x501f, 0x0  },
-       { 0x5000, 0x4f },
-       { 0x5001, 0xcf },
-       { 0x4300, 0x30 },
-       { 0x4300, 0x30 },
-       { 0x460b, 0x35 },
-       { 0x471d, 0x0  },
-       { 0x3002, 0xc  },
-       { 0x3002, 0x0  },
-       { 0x4713, 0x3  },
-       { 0x471c, 0x50 },
-       { 0x4721, 0x2  },
-       { 0x4402, 0x90 },
-       { 0x460c, 0x22 },
-       { 0x3815, 0x44 },
-       { 0x3503, 0x7  },
-       { 0x3501, 0x73 },
-       { 0x3502, 0x80 },
-       { 0x350b, 0x0  },
-       { 0x3818, 0xc8 },
-       { 0x3824, 0x11 },
-       { 0x3a00, 0x78 },
-       { 0x3a1a, 0x4  },
-       { 0x3a13, 0x30 },
-       { 0x3a18, 0x0  },
-       { 0x3a19, 0x7c },
-       { 0x3a08, 0x12 },
-       { 0x3a09, 0xc0 },
-       { 0x3a0a, 0xf  },
-       { 0x3a0b, 0xa0 },
-       { 0x350c, 0x7  },
-       { 0x350d, 0xd0 },
-       { 0x3a0d, 0x8  },
-       { 0x3a0e, 0x6  },
-       { 0x3500, 0x0  },
-       { 0x3501, 0x0  },
-       { 0x3502, 0x0  },
-       { 0x350a, 0x0  },
-       { 0x350b, 0x0  },
-       { 0x3503, 0x0  },
-       { 0x3a0f, 0x3c },
-       { 0x3a10, 0x32 },
-       { 0x3a1b, 0x3c },
-       { 0x3a1e, 0x32 },
-       { 0x3a11, 0x80 },
-       { 0x3a1f, 0x20 },
-       { 0x3030, 0x2b },
-       { 0x3a02, 0x0  },
-       { 0x3a03, 0x7d },
-       { 0x3a04, 0x0  },
-       { 0x3a14, 0x0  },
-       { 0x3a15, 0x7d },
-       { 0x3a16, 0x0  },
-       { 0x3a00, 0x78 },
-       { 0x3a08, 0x9  },
-       { 0x3a09, 0x60 },
-       { 0x3a0a, 0x7  },
-       { 0x3a0b, 0xd0 },
-       { 0x3a0d, 0x10 },
-       { 0x3a0e, 0xd  },
-       { 0x4407, 0x4  },
-       { 0x5193, 0x70 },
-       { 0x589b, 0x0  },
-       { 0x589a, 0xc0 },
-       { 0x401e, 0x20 },
-       { 0x4001, 0x42 },
-       { 0x401c, 0x6  },
-       { 0x3825, 0xac },
-       { 0x3827, 0xc  },
-       { 0x528a, 0x1  },
-       { 0x528b, 0x4  },
-       { 0x528c, 0x8  },
-       { 0x528d, 0x10 },
-       { 0x528e, 0x20 },
-       { 0x528f, 0x28 },
-       { 0x5290, 0x30 },
-       { 0x5292, 0x0  },
-       { 0x5293, 0x1  },
-       { 0x5294, 0x0  },
-       { 0x5295, 0x4  },
-       { 0x5296, 0x0  },
-       { 0x5297, 0x8  },
-       { 0x5298, 0x0  },
-       { 0x5299, 0x10 },
-       { 0x529a, 0x0  },
-       { 0x529b, 0x20 },
-       { 0x529c, 0x0  },
-       { 0x529d, 0x28 },
-       { 0x529e, 0x0  },
-       { 0x529f, 0x30 },
-       { 0x5282, 0x0  },
-       { 0x5300, 0x0  },
-       { 0x5301, 0x20 },
-       { 0x5302, 0x0  },
-       { 0x5303, 0x7c },
-       { 0x530c, 0x0  },
-       { 0x530d, 0xc  },
-       { 0x530e, 0x20 },
-       { 0x530f, 0x80 },
-       { 0x5310, 0x20 },
-       { 0x5311, 0x80 },
-       { 0x5308, 0x20 },
-       { 0x5309, 0x40 },
-       { 0x5304, 0x0  },
-       { 0x5305, 0x30 },
-       { 0x5306, 0x0  },
-       { 0x5307, 0x80 },
-       { 0x5314, 0x8  },
-       { 0x5315, 0x20 },
-       { 0x5319, 0x30 },
-       { 0x5316, 0x10 },
-       { 0x5317, 0x0  },
-       { 0x5318, 0x2  },
-       { 0x5380, 0x1  },
-       { 0x5381, 0x0  },
-       { 0x5382, 0x0  },
-       { 0x5383, 0x4e },
-       { 0x5384, 0x0  },
-       { 0x5385, 0xf  },
-       { 0x5386, 0x0  },
-       { 0x5387, 0x0  },
-       { 0x5388, 0x1  },
-       { 0x5389, 0x15 },
-       { 0x538a, 0x0  },
-       { 0x538b, 0x31 },
-       { 0x538c, 0x0  },
-       { 0x538d, 0x0  },
-       { 0x538e, 0x0  },
-       { 0x538f, 0xf  },
-       { 0x5390, 0x0  },
-       { 0x5391, 0xab },
-       { 0x5392, 0x0  },
-       { 0x5393, 0xa2 },
-       { 0x5394, 0x8  },
-       { 0x5480, 0x14 },
-       { 0x5481, 0x21 },
-       { 0x5482, 0x36 },
-       { 0x5483, 0x57 },
-       { 0x5484, 0x65 },
-       { 0x5485, 0x71 },
-       { 0x5486, 0x7d },
-       { 0x5487, 0x87 },
-       { 0x5488, 0x91 },
-       { 0x5489, 0x9a },
-       { 0x548a, 0xaa },
-       { 0x548b, 0xb8 },
-       { 0x548c, 0xcd },
-       { 0x548d, 0xdd },
-       { 0x548e, 0xea },
-       { 0x548f, 0x1d },
-       { 0x5490, 0x5  },
-       { 0x5491, 0x0  },
-       { 0x5492, 0x4  },
-       { 0x5493, 0x20 },
-       { 0x5494, 0x3  },
-       { 0x5495, 0x60 },
-       { 0x5496, 0x2  },
-       { 0x5497, 0xb8 },
-       { 0x5498, 0x2  },
-       { 0x5499, 0x86 },
-       { 0x549a, 0x2  },
-       { 0x549b, 0x5b },
-       { 0x549c, 0x2  },
-       { 0x549d, 0x3b },
-       { 0x549e, 0x2  },
-       { 0x549f, 0x1c },
-       { 0x54a0, 0x2  },
-       { 0x54a1, 0x4  },
-       { 0x54a2, 0x1  },
-       { 0x54a3, 0xed },
-       { 0x54a4, 0x1  },
-       { 0x54a5, 0xc5 },
-       { 0x54a6, 0x1  },
-       { 0x54a7, 0xa5 },
-       { 0x54a8, 0x1  },
-       { 0x54a9, 0x6c },
-       { 0x54aa, 0x1  },
-       { 0x54ab, 0x41 },
-       { 0x54ac, 0x1  },
-       { 0x54ad, 0x20 },
-       { 0x54ae, 0x0  },
-       { 0x54af, 0x16 },
-       { 0x54b0, 0x1  },
-       { 0x54b1, 0x20 },
-       { 0x54b2, 0x0  },
-       { 0x54b3, 0x10 },
-       { 0x54b4, 0x0  },
-       { 0x54b5, 0xf0 },
-       { 0x54b6, 0x0  },
-       { 0x54b7, 0xdf },
-       { 0x5402, 0x3f },
-       { 0x5403, 0x0  },
-       { 0x3406, 0x0  },
-       { 0x5180, 0xff },
-       { 0x5181, 0x52 },
-       { 0x5182, 0x11 },
-       { 0x5183, 0x14 },
-       { 0x5184, 0x25 },
-       { 0x5185, 0x24 },
-       { 0x5186, 0x6  },
-       { 0x5187, 0x8  },
-       { 0x5188, 0x8  },
-       { 0x5189, 0x7c },
-       { 0x518a, 0x60 },
-       { 0x518b, 0xb2 },
-       { 0x518c, 0xb2 },
-       { 0x518d, 0x44 },
-       { 0x518e, 0x3d },
-       { 0x518f, 0x58 },
-       { 0x5190, 0x46 },
-       { 0x5191, 0xf8 },
-       { 0x5192, 0x4  },
-       { 0x5193, 0x70 },
-       { 0x5194, 0xf0 },
-       { 0x5195, 0xf0 },
-       { 0x5196, 0x3  },
-       { 0x5197, 0x1  },
-       { 0x5198, 0x4  },
-       { 0x5199, 0x12 },
-       { 0x519a, 0x4  },
-       { 0x519b, 0x0  },
-       { 0x519c, 0x6  },
-       { 0x519d, 0x82 },
-       { 0x519e, 0x0  },
-       { 0x5025, 0x80 },
-       { 0x3a0f, 0x38 },
-       { 0x3a10, 0x30 },
-       { 0x3a1b, 0x3a },
-       { 0x3a1e, 0x2e },
-       { 0x3a11, 0x60 },
-       { 0x3a1f, 0x10 },
-       { 0x5688, 0xa6 },
-       { 0x5689, 0x6a },
-       { 0x568a, 0xea },
-       { 0x568b, 0xae },
-       { 0x568c, 0xa6 },
-       { 0x568d, 0x6a },
-       { 0x568e, 0x62 },
-       { 0x568f, 0x26 },
-       { 0x5583, 0x40 },
-       { 0x5584, 0x40 },
-       { 0x5580, 0x2  },
-       { 0x5000, 0xcf },
-       { 0x5800, 0x27 },
-       { 0x5801, 0x19 },
-       { 0x5802, 0x12 },
-       { 0x5803, 0xf  },
-       { 0x5804, 0x10 },
-       { 0x5805, 0x15 },
-       { 0x5806, 0x1e },
-       { 0x5807, 0x2f },
-       { 0x5808, 0x15 },
-       { 0x5809, 0xd  },
-       { 0x580a, 0xa  },
-       { 0x580b, 0x9  },
-       { 0x580c, 0xa  },
-       { 0x580d, 0xc  },
-       { 0x580e, 0x12 },
-       { 0x580f, 0x19 },
-       { 0x5810, 0xb  },
-       { 0x5811, 0x7  },
-       { 0x5812, 0x4  },
-       { 0x5813, 0x3  },
-       { 0x5814, 0x3  },
-       { 0x5815, 0x6  },
-       { 0x5816, 0xa  },
-       { 0x5817, 0xf  },
-       { 0x5818, 0xa  },
-       { 0x5819, 0x5  },
-       { 0x581a, 0x1  },
-       { 0x581b, 0x0  },
-       { 0x581c, 0x0  },
-       { 0x581d, 0x3  },
-       { 0x581e, 0x8  },
-       { 0x581f, 0xc  },
-       { 0x5820, 0xa  },
-       { 0x5821, 0x5  },
-       { 0x5822, 0x1  },
-       { 0x5823, 0x0  },
-       { 0x5824, 0x0  },
-       { 0x5825, 0x3  },
-       { 0x5826, 0x8  },
-       { 0x5827, 0xc  },
-       { 0x5828, 0xe  },
-       { 0x5829, 0x8  },
-       { 0x582a, 0x6  },
-       { 0x582b, 0x4  },
-       { 0x582c, 0x5  },
-       { 0x582d, 0x7  },
-       { 0x582e, 0xb  },
-       { 0x582f, 0x12 },
-       { 0x5830, 0x18 },
-       { 0x5831, 0x10 },
-       { 0x5832, 0xc  },
-       { 0x5833, 0xa  },
-       { 0x5834, 0xb  },
-       { 0x5835, 0xe  },
-       { 0x5836, 0x15 },
-       { 0x5837, 0x19 },
-       { 0x5838, 0x32 },
-       { 0x5839, 0x1f },
-       { 0x583a, 0x18 },
-       { 0x583b, 0x16 },
-       { 0x583c, 0x17 },
-       { 0x583d, 0x1e },
-       { 0x583e, 0x26 },
-       { 0x583f, 0x53 },
-       { 0x5840, 0x10 },
-       { 0x5841, 0xf  },
-       { 0x5842, 0xd  },
-       { 0x5843, 0xc  },
-       { 0x5844, 0xe  },
-       { 0x5845, 0x9  },
-       { 0x5846, 0x11 },
-       { 0x5847, 0x10 },
-       { 0x5848, 0x10 },
-       { 0x5849, 0x10 },
-       { 0x584a, 0x10 },
-       { 0x584b, 0xe  },
-       { 0x584c, 0x10 },
-       { 0x584d, 0x10 },
-       { 0x584e, 0x11 },
-       { 0x584f, 0x10 },
-       { 0x5850, 0xf  },
-       { 0x5851, 0xc  },
-       { 0x5852, 0xf  },
-       { 0x5853, 0x10 },
-       { 0x5854, 0x10 },
-       { 0x5855, 0xf  },
-       { 0x5856, 0xe  },
-       { 0x5857, 0xb  },
-       { 0x5858, 0x10 },
-       { 0x5859, 0xd  },
-       { 0x585a, 0xd  },
-       { 0x585b, 0xc  },
-       { 0x585c, 0xc  },
-       { 0x585d, 0xc  },
-       { 0x585e, 0xb  },
-       { 0x585f, 0xc  },
-       { 0x5860, 0xc  },
-       { 0x5861, 0xc  },
-       { 0x5862, 0xd  },
-       { 0x5863, 0x8  },
-       { 0x5864, 0x11 },
-       { 0x5865, 0x18 },
-       { 0x5866, 0x18 },
-       { 0x5867, 0x19 },
-       { 0x5868, 0x17 },
-       { 0x5869, 0x19 },
-       { 0x586a, 0x16 },
-       { 0x586b, 0x13 },
-       { 0x586c, 0x13 },
-       { 0x586d, 0x12 },
-       { 0x586e, 0x13 },
-       { 0x586f, 0x16 },
-       { 0x5870, 0x14 },
-       { 0x5871, 0x12 },
-       { 0x5872, 0x10 },
-       { 0x5873, 0x11 },
-       { 0x5874, 0x11 },
-       { 0x5875, 0x16 },
-       { 0x5876, 0x14 },
-       { 0x5877, 0x11 },
-       { 0x5878, 0x10 },
-       { 0x5879, 0xf  },
-       { 0x587a, 0x10 },
-       { 0x587b, 0x14 },
-       { 0x587c, 0x13 },
-       { 0x587d, 0x12 },
-       { 0x587e, 0x11 },
-       { 0x587f, 0x11 },
-       { 0x5880, 0x12 },
-       { 0x5881, 0x15 },
-       { 0x5882, 0x14 },
-       { 0x5883, 0x15 },
-       { 0x5884, 0x15 },
-       { 0x5885, 0x15 },
-       { 0x5886, 0x13 },
-       { 0x5887, 0x17 },
-       { 0x3710, 0x10 },
-       { 0x3632, 0x51 },
-       { 0x3702, 0x10 },
-       { 0x3703, 0xb2 },
-       { 0x3704, 0x18 },
-       { 0x370b, 0x40 },
-       { 0x370d, 0x3  },
-       { 0x3631, 0x1  },
-       { 0x3632, 0x52 },
-       { 0x3606, 0x24 },
-       { 0x3620, 0x96 },
-       { 0x5785, 0x7  },
-       { 0x3a13, 0x30 },
-       { 0x3600, 0x52 },
-       { 0x3604, 0x48 },
-       { 0x3606, 0x1b },
-       { 0x370d, 0xb  },
-       { 0x370f, 0xc0 },
-       { 0x3709, 0x1  },
-       { 0x3823, 0x0  },
-       { 0x5007, 0x0  },
-       { 0x5009, 0x0  },
-       { 0x5011, 0x0  },
-       { 0x5013, 0x0  },
-       { 0x519e, 0x0  },
-       { 0x5086, 0x0  },
-       { 0x5087, 0x0  },
-       { 0x5088, 0x0  },
-       { 0x5089, 0x0  },
-       { 0x302b, 0x0  },
-       { 0x3503, 0x7  },
-       { 0x3011, 0x8  },
-       { 0x350c, 0x2  },
-       { 0x350d, 0xe4 },
-       { 0x3621, 0xc9 },
-       { 0x370a, 0x81 },
-       { 0xffff, 0xff },
-};
-
-static struct regval_list ov5642_default_regs_finalise[] = {
-       { 0x3810, 0xc2 },
-       { 0x3818, 0xc9 },
-       { 0x381c, 0x10 },
-       { 0x381d, 0xa0 },
-       { 0x381e, 0x5  },
-       { 0x381f, 0xb0 },
-       { 0x3820, 0x0  },
-       { 0x3821, 0x0  },
-       { 0x3824, 0x11 },
-       { 0x3a08, 0x1b },
-       { 0x3a09, 0xc0 },
-       { 0x3a0a, 0x17 },
-       { 0x3a0b, 0x20 },
-       { 0x3a0d, 0x2  },
-       { 0x3a0e, 0x1  },
-       { 0x401c, 0x4  },
-       { 0x5682, 0x5  },
-       { 0x5683, 0x0  },
-       { 0x5686, 0x2  },
-       { 0x5687, 0xcc },
-       { 0x5001, 0x4f },
-       { 0x589b, 0x6  },
-       { 0x589a, 0xc5 },
-       { 0x3503, 0x0  },
-       { 0x460c, 0x20 },
-       { 0x460b, 0x37 },
-       { 0x471c, 0xd0 },
-       { 0x471d, 0x5  },
-       { 0x3815, 0x1  },
-       { 0x3818, 0xc1 },
-       { 0x501f, 0x0  },
-       { 0x5002, 0xe0 },
-       { 0x4300, 0x32 }, /* UYVY */
-       { 0x3002, 0x1c },
-       { 0x4800, 0x14 },
-       { 0x4801, 0xf  },
-       { 0x3007, 0x3b },
-       { 0x300e, 0x4  },
-       { 0x4803, 0x50 },
-       { 0x3815, 0x1  },
-       { 0x4713, 0x2  },
-       { 0x4842, 0x1  },
-       { 0x300f, 0xe  },
-       { 0x3003, 0x3  },
-       { 0x3003, 0x1  },
-       { 0xffff, 0xff },
-};
-
-struct ov5642_datafmt {
-       u32     code;
-       enum v4l2_colorspace            colorspace;
-};
-
-struct ov5642 {
-       struct v4l2_subdev              subdev;
-       const struct ov5642_datafmt     *fmt;
-       struct v4l2_rect                crop_rect;
-       struct v4l2_clk                 *clk;
-
-       /* blanking information */
-       int total_width;
-       int total_height;
-};
-
-static const struct ov5642_datafmt ov5642_colour_fmts[] = {
-       {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
-};
-
-static struct ov5642 *to_ov5642(const struct i2c_client *client)
-{
-       return container_of(i2c_get_clientdata(client), struct ov5642, subdev);
-}
-
-/* Find a data format by a pixel code in an array */
-static const struct ov5642_datafmt
-                       *ov5642_find_datafmt(u32 code)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(ov5642_colour_fmts); i++)
-               if (ov5642_colour_fmts[i].code == code)
-                       return ov5642_colour_fmts + i;
-
-       return NULL;
-}
-
-static int reg_read(struct i2c_client *client, u16 reg, u8 *val)
-{
-       int ret;
-       /* We have 16-bit i2c addresses - care for endianness */
-       unsigned char data[2] = { reg >> 8, reg & 0xff };
-
-       ret = i2c_master_send(client, data, 2);
-       if (ret < 2) {
-               dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
-                       __func__, reg);
-               return ret < 0 ? ret : -EIO;
-       }
-
-       ret = i2c_master_recv(client, val, 1);
-       if (ret < 1) {
-               dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
-                               __func__, reg);
-               return ret < 0 ? ret : -EIO;
-       }
-       return 0;
-}
-
-static int reg_write(struct i2c_client *client, u16 reg, u8 val)
-{
-       int ret;
-       unsigned char data[3] = { reg >> 8, reg & 0xff, val };
-
-       ret = i2c_master_send(client, data, 3);
-       if (ret < 3) {
-               dev_err(&client->dev, "%s: i2c write error, reg: %x\n",
-                       __func__, reg);
-               return ret < 0 ? ret : -EIO;
-       }
-
-       return 0;
-}
-
-/*
- * convenience function to write 16 bit register values that are split up
- * into two consecutive high and low parts
- */
-static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
-{
-       int ret;
-
-       ret = reg_write(client, reg, val16 >> 8);
-       if (ret)
-               return ret;
-       return reg_write(client, reg + 1, val16 & 0x00ff);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
-       u8 val;
-
-       if (reg->reg & ~0xffff)
-               return -EINVAL;
-
-       reg->size = 1;
-
-       ret = reg_read(client, reg->reg, &val);
-       if (!ret)
-               reg->val = (__u64)val;
-
-       return ret;
-}
-
-static int ov5642_set_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg & ~0xffff || reg->val & ~0xff)
-               return -EINVAL;
-
-       return reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov5642_write_array(struct i2c_client *client,
-                               struct regval_list *vals)
-{
-       while (vals->reg_num != 0xffff || vals->value != 0xff) {
-               int ret = reg_write(client, vals->reg_num, vals->value);
-               if (ret < 0)
-                       return ret;
-               vals++;
-       }
-       dev_dbg(&client->dev, "Register list loaded\n");
-       return 0;
-}
-
-static int ov5642_set_resolution(struct v4l2_subdev *sd)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov5642 *priv = to_ov5642(client);
-       int width = priv->crop_rect.width;
-       int height = priv->crop_rect.height;
-       int total_width = priv->total_width;
-       int total_height = priv->total_height;
-       int start_x = (OV5642_SENSOR_SIZE_X - width) / 2;
-       int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2;
-       int ret;
-
-       /*
-        * This should set the starting point for cropping.
-        * Doesn't work so far.
-        */
-       ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x);
-       if (!ret)
-               ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y);
-       if (!ret) {
-               priv->crop_rect.left = start_x;
-               priv->crop_rect.top = start_y;
-       }
-
-       if (!ret)
-               ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width);
-       if (!ret)
-               ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height);
-       if (ret)
-               return ret;
-       priv->crop_rect.width = width;
-       priv->crop_rect.height = height;
-
-       /* Set the output window size. Only 1:1 scale is supported so far. */
-       ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width);
-       if (!ret)
-               ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height);
-
-       /* Total width = output size + blanking */
-       if (!ret)
-               ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width);
-       if (!ret)
-               ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height);
-
-       /* Sets the window for AWB calculations */
-       if (!ret)
-               ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width);
-       if (!ret)
-               ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height);
-
-       return ret;
-}
-
-static int ov5642_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov5642 *priv = to_ov5642(client);
-       const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->width = priv->crop_rect.width;
-       mf->height = priv->crop_rect.height;
-
-       if (!fmt) {
-               if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-                       return -EINVAL;
-               mf->code        = ov5642_colour_fmts[0].code;
-               mf->colorspace  = ov5642_colour_fmts[0].colorspace;
-       }
-
-       mf->field       = V4L2_FIELD_NONE;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               priv->fmt = fmt;
-       else
-               cfg->try_fmt = *mf;
-       return 0;
-}
-
-static int ov5642_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov5642 *priv = to_ov5642(client);
-
-       const struct ov5642_datafmt *fmt = priv->fmt;
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->code        = fmt->code;
-       mf->colorspace  = fmt->colorspace;
-       mf->width       = priv->crop_rect.width;
-       mf->height      = priv->crop_rect.height;
-       mf->field       = V4L2_FIELD_NONE;
-
-       return 0;
-}
-
-static int ov5642_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index >= ARRAY_SIZE(ov5642_colour_fmts))
-               return -EINVAL;
-
-       code->code = ov5642_colour_fmts[code->index].code;
-       return 0;
-}
-
-static int ov5642_set_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov5642 *priv = to_ov5642(client);
-       struct v4l2_rect rect = sel->r;
-       int ret;
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1,
-                             &rect.height, 32, OV5642_MAX_HEIGHT, 1, 0);
-
-       priv->crop_rect.width   = rect.width;
-       priv->crop_rect.height  = rect.height;
-       priv->total_width       = rect.width + BLANKING_EXTRA_WIDTH;
-       priv->total_height      = max_t(int, rect.height +
-                                                       BLANKING_EXTRA_HEIGHT,
-                                                       BLANKING_MIN_HEIGHT);
-       priv->crop_rect.width           = rect.width;
-       priv->crop_rect.height          = rect.height;
-
-       ret = ov5642_write_array(client, ov5642_default_regs_init);
-       if (!ret)
-               ret = ov5642_set_resolution(sd);
-       if (!ret)
-               ret = ov5642_write_array(client, ov5642_default_regs_finalise);
-
-       return ret;
-}
-
-static int ov5642_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov5642 *priv = to_ov5642(client);
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.left = 0;
-               sel->r.top = 0;
-               sel->r.width = OV5642_MAX_WIDTH;
-               sel->r.height = OV5642_MAX_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = priv->crop_rect;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       cfg->type = V4L2_MBUS_CSI2;
-       cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
-                                       V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
-       return 0;
-}
-
-static int ov5642_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct ov5642 *priv = to_ov5642(client);
-       int ret;
-
-       if (!on)
-               return soc_camera_power_off(&client->dev, ssdd, priv->clk);
-
-       ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
-       if (ret < 0)
-               return ret;
-
-       ret = ov5642_write_array(client, ov5642_default_regs_init);
-       if (!ret)
-               ret = ov5642_set_resolution(sd);
-       if (!ret)
-               ret = ov5642_write_array(client, ov5642_default_regs_finalise);
-
-       return ret;
-}
-
-static const struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
-       .g_mbus_config  = ov5642_g_mbus_config,
-};
-
-static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = {
-       .enum_mbus_code = ov5642_enum_mbus_code,
-       .get_selection  = ov5642_get_selection,
-       .set_selection  = ov5642_set_selection,
-       .get_fmt        = ov5642_get_fmt,
-       .set_fmt        = ov5642_set_fmt,
-};
-
-static const struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
-       .s_power        = ov5642_s_power,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = ov5642_get_register,
-       .s_register     = ov5642_set_register,
-#endif
-};
-
-static const struct v4l2_subdev_ops ov5642_subdev_ops = {
-       .core   = &ov5642_subdev_core_ops,
-       .video  = &ov5642_subdev_video_ops,
-       .pad    = &ov5642_subdev_pad_ops,
-};
-
-static int ov5642_video_probe(struct i2c_client *client)
-{
-       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
-       int ret;
-       u8 id_high, id_low;
-       u16 id;
-
-       ret = ov5642_s_power(subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /* Read sensor Model ID */
-       ret = reg_read(client, REG_CHIP_ID_HIGH, &id_high);
-       if (ret < 0)
-               goto done;
-
-       id = id_high << 8;
-
-       ret = reg_read(client, REG_CHIP_ID_LOW, &id_low);
-       if (ret < 0)
-               goto done;
-
-       id |= id_low;
-
-       dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
-
-       if (id != 0x5642) {
-               ret = -ENODEV;
-               goto done;
-       }
-
-       ret = 0;
-
-done:
-       ov5642_s_power(subdev, 0);
-       return ret;
-}
-
-static int ov5642_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-{
-       struct ov5642 *priv;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       int ret;
-
-       if (!ssdd) {
-               dev_err(&client->dev, "OV5642: missing platform data!\n");
-               return -EINVAL;
-       }
-
-       priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
-
-       priv->fmt               = &ov5642_colour_fmts[0];
-
-       priv->crop_rect.width   = OV5642_DEFAULT_WIDTH;
-       priv->crop_rect.height  = OV5642_DEFAULT_HEIGHT;
-       priv->crop_rect.left    = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
-       priv->crop_rect.top     = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
-       priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
-       priv->total_height = BLANKING_MIN_HEIGHT;
-
-       priv->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(priv->clk))
-               return PTR_ERR(priv->clk);
-
-       ret = ov5642_video_probe(client);
-       if (ret < 0)
-               v4l2_clk_put(priv->clk);
-
-       return ret;
-}
-
-static int ov5642_remove(struct i2c_client *client)
-{
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct ov5642 *priv = to_ov5642(client);
-
-       v4l2_clk_put(priv->clk);
-       if (ssdd->free_bus)
-               ssdd->free_bus(ssdd);
-
-       return 0;
-}
-
-static const struct i2c_device_id ov5642_id[] = {
-       { "ov5642", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, ov5642_id);
-
-#if IS_ENABLED(CONFIG_OF)
-static const struct of_device_id ov5642_of_match[] = {
-       { .compatible = "ovti,ov5642" },
-       { },
-};
-MODULE_DEVICE_TABLE(of, ov5642_of_match);
-#endif
-
-static struct i2c_driver ov5642_i2c_driver = {
-       .driver = {
-               .name = "ov5642",
-               .of_match_table = of_match_ptr(ov5642_of_match),
-       },
-       .probe          = ov5642_probe,
-       .remove         = ov5642_remove,
-       .id_table       = ov5642_id,
-};
-
-module_i2c_driver(ov5642_i2c_driver);
-
-MODULE_DESCRIPTION("Omnivision OV5642 Camera driver");
-MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
deleted file mode 100644 (file)
index 14377af..0000000
+++ /dev/null
@@ -1,1124 +0,0 @@
-/*
- * ov772x Camera Driver
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov7670 and soc_camera_platform driver,
- *
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/i2c/ov772x.h>
-#include <media/soc_camera.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-image-sizes.h>
-
-/*
- * register offset
- */
-#define GAIN        0x00 /* AGC - Gain control gain setting */
-#define BLUE        0x01 /* AWB - Blue channel gain setting */
-#define RED         0x02 /* AWB - Red   channel gain setting */
-#define GREEN       0x03 /* AWB - Green channel gain setting */
-#define COM1        0x04 /* Common control 1 */
-#define BAVG        0x05 /* U/B Average Level */
-#define GAVG        0x06 /* Y/Gb Average Level */
-#define RAVG        0x07 /* V/R Average Level */
-#define AECH        0x08 /* Exposure Value - AEC MSBs */
-#define COM2        0x09 /* Common control 2 */
-#define PID         0x0A /* Product ID Number MSB */
-#define VER         0x0B /* Product ID Number LSB */
-#define COM3        0x0C /* Common control 3 */
-#define COM4        0x0D /* Common control 4 */
-#define COM5        0x0E /* Common control 5 */
-#define COM6        0x0F /* Common control 6 */
-#define AEC         0x10 /* Exposure Value */
-#define CLKRC       0x11 /* Internal clock */
-#define COM7        0x12 /* Common control 7 */
-#define COM8        0x13 /* Common control 8 */
-#define COM9        0x14 /* Common control 9 */
-#define COM10       0x15 /* Common control 10 */
-#define REG16       0x16 /* Register 16 */
-#define HSTART      0x17 /* Horizontal sensor size */
-#define HSIZE       0x18 /* Horizontal frame (HREF column) end high 8-bit */
-#define VSTART      0x19 /* Vertical frame (row) start high 8-bit */
-#define VSIZE       0x1A /* Vertical sensor size */
-#define PSHFT       0x1B /* Data format - pixel delay select */
-#define MIDH        0x1C /* Manufacturer ID byte - high */
-#define MIDL        0x1D /* Manufacturer ID byte - low  */
-#define LAEC        0x1F /* Fine AEC value */
-#define COM11       0x20 /* Common control 11 */
-#define BDBASE      0x22 /* Banding filter Minimum AEC value */
-#define DBSTEP      0x23 /* Banding filter Maximum Setp */
-#define AEW         0x24 /* AGC/AEC - Stable operating region (upper limit) */
-#define AEB         0x25 /* AGC/AEC - Stable operating region (lower limit) */
-#define VPT         0x26 /* AGC/AEC Fast mode operating region */
-#define REG28       0x28 /* Register 28 */
-#define HOUTSIZE    0x29 /* Horizontal data output size MSBs */
-#define EXHCH       0x2A /* Dummy pixel insert MSB */
-#define EXHCL       0x2B /* Dummy pixel insert LSB */
-#define VOUTSIZE    0x2C /* Vertical data output size MSBs */
-#define ADVFL       0x2D /* LSB of insert dummy lines in Vertical direction */
-#define ADVFH       0x2E /* MSG of insert dummy lines in Vertical direction */
-#define YAVE        0x2F /* Y/G Channel Average value */
-#define LUMHTH      0x30 /* Histogram AEC/AGC Luminance high level threshold */
-#define LUMLTH      0x31 /* Histogram AEC/AGC Luminance low  level threshold */
-#define HREF        0x32 /* Image start and size control */
-#define DM_LNL      0x33 /* Dummy line low  8 bits */
-#define DM_LNH      0x34 /* Dummy line high 8 bits */
-#define ADOFF_B     0x35 /* AD offset compensation value for B  channel */
-#define ADOFF_R     0x36 /* AD offset compensation value for R  channel */
-#define ADOFF_GB    0x37 /* AD offset compensation value for Gb channel */
-#define ADOFF_GR    0x38 /* AD offset compensation value for Gr channel */
-#define OFF_B       0x39 /* Analog process B  channel offset value */
-#define OFF_R       0x3A /* Analog process R  channel offset value */
-#define OFF_GB      0x3B /* Analog process Gb channel offset value */
-#define OFF_GR      0x3C /* Analog process Gr channel offset value */
-#define COM12       0x3D /* Common control 12 */
-#define COM13       0x3E /* Common control 13 */
-#define COM14       0x3F /* Common control 14 */
-#define COM15       0x40 /* Common control 15*/
-#define COM16       0x41 /* Common control 16 */
-#define TGT_B       0x42 /* BLC blue channel target value */
-#define TGT_R       0x43 /* BLC red  channel target value */
-#define TGT_GB      0x44 /* BLC Gb   channel target value */
-#define TGT_GR      0x45 /* BLC Gr   channel target value */
-/* for ov7720 */
-#define LCC0        0x46 /* Lens correction control 0 */
-#define LCC1        0x47 /* Lens correction option 1 - X coordinate */
-#define LCC2        0x48 /* Lens correction option 2 - Y coordinate */
-#define LCC3        0x49 /* Lens correction option 3 */
-#define LCC4        0x4A /* Lens correction option 4 - radius of the circular */
-#define LCC5        0x4B /* Lens correction option 5 */
-#define LCC6        0x4C /* Lens correction option 6 */
-/* for ov7725 */
-#define LC_CTR      0x46 /* Lens correction control */
-#define LC_XC       0x47 /* X coordinate of lens correction center relative */
-#define LC_YC       0x48 /* Y coordinate of lens correction center relative */
-#define LC_COEF     0x49 /* Lens correction coefficient */
-#define LC_RADI     0x4A /* Lens correction radius */
-#define LC_COEFB    0x4B /* Lens B channel compensation coefficient */
-#define LC_COEFR    0x4C /* Lens R channel compensation coefficient */
-
-#define FIXGAIN     0x4D /* Analog fix gain amplifer */
-#define AREF0       0x4E /* Sensor reference control */
-#define AREF1       0x4F /* Sensor reference current control */
-#define AREF2       0x50 /* Analog reference control */
-#define AREF3       0x51 /* ADC    reference control */
-#define AREF4       0x52 /* ADC    reference control */
-#define AREF5       0x53 /* ADC    reference control */
-#define AREF6       0x54 /* Analog reference control */
-#define AREF7       0x55 /* Analog reference control */
-#define UFIX        0x60 /* U channel fixed value output */
-#define VFIX        0x61 /* V channel fixed value output */
-#define AWBB_BLK    0x62 /* AWB option for advanced AWB */
-#define AWB_CTRL0   0x63 /* AWB control byte 0 */
-#define DSP_CTRL1   0x64 /* DSP control byte 1 */
-#define DSP_CTRL2   0x65 /* DSP control byte 2 */
-#define DSP_CTRL3   0x66 /* DSP control byte 3 */
-#define DSP_CTRL4   0x67 /* DSP control byte 4 */
-#define AWB_BIAS    0x68 /* AWB BLC level clip */
-#define AWB_CTRL1   0x69 /* AWB control  1 */
-#define AWB_CTRL2   0x6A /* AWB control  2 */
-#define AWB_CTRL3   0x6B /* AWB control  3 */
-#define AWB_CTRL4   0x6C /* AWB control  4 */
-#define AWB_CTRL5   0x6D /* AWB control  5 */
-#define AWB_CTRL6   0x6E /* AWB control  6 */
-#define AWB_CTRL7   0x6F /* AWB control  7 */
-#define AWB_CTRL8   0x70 /* AWB control  8 */
-#define AWB_CTRL9   0x71 /* AWB control  9 */
-#define AWB_CTRL10  0x72 /* AWB control 10 */
-#define AWB_CTRL11  0x73 /* AWB control 11 */
-#define AWB_CTRL12  0x74 /* AWB control 12 */
-#define AWB_CTRL13  0x75 /* AWB control 13 */
-#define AWB_CTRL14  0x76 /* AWB control 14 */
-#define AWB_CTRL15  0x77 /* AWB control 15 */
-#define AWB_CTRL16  0x78 /* AWB control 16 */
-#define AWB_CTRL17  0x79 /* AWB control 17 */
-#define AWB_CTRL18  0x7A /* AWB control 18 */
-#define AWB_CTRL19  0x7B /* AWB control 19 */
-#define AWB_CTRL20  0x7C /* AWB control 20 */
-#define AWB_CTRL21  0x7D /* AWB control 21 */
-#define GAM1        0x7E /* Gamma Curve  1st segment input end point */
-#define GAM2        0x7F /* Gamma Curve  2nd segment input end point */
-#define GAM3        0x80 /* Gamma Curve  3rd segment input end point */
-#define GAM4        0x81 /* Gamma Curve  4th segment input end point */
-#define GAM5        0x82 /* Gamma Curve  5th segment input end point */
-#define GAM6        0x83 /* Gamma Curve  6th segment input end point */
-#define GAM7        0x84 /* Gamma Curve  7th segment input end point */
-#define GAM8        0x85 /* Gamma Curve  8th segment input end point */
-#define GAM9        0x86 /* Gamma Curve  9th segment input end point */
-#define GAM10       0x87 /* Gamma Curve 10th segment input end point */
-#define GAM11       0x88 /* Gamma Curve 11th segment input end point */
-#define GAM12       0x89 /* Gamma Curve 12th segment input end point */
-#define GAM13       0x8A /* Gamma Curve 13th segment input end point */
-#define GAM14       0x8B /* Gamma Curve 14th segment input end point */
-#define GAM15       0x8C /* Gamma Curve 15th segment input end point */
-#define SLOP        0x8D /* Gamma curve highest segment slope */
-#define DNSTH       0x8E /* De-noise threshold */
-#define EDGE_STRNGT 0x8F /* Edge strength  control when manual mode */
-#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
-#define DNSOFF      0x91 /* Auto De-noise threshold control */
-#define EDGE_UPPER  0x92 /* Edge strength upper limit when Auto mode */
-#define EDGE_LOWER  0x93 /* Edge strength lower limit when Auto mode */
-#define MTX1        0x94 /* Matrix coefficient 1 */
-#define MTX2        0x95 /* Matrix coefficient 2 */
-#define MTX3        0x96 /* Matrix coefficient 3 */
-#define MTX4        0x97 /* Matrix coefficient 4 */
-#define MTX5        0x98 /* Matrix coefficient 5 */
-#define MTX6        0x99 /* Matrix coefficient 6 */
-#define MTX_CTRL    0x9A /* Matrix control */
-#define BRIGHT      0x9B /* Brightness control */
-#define CNTRST      0x9C /* Contrast contrast */
-#define CNTRST_CTRL 0x9D /* Contrast contrast center */
-#define UVAD_J0     0x9E /* Auto UV adjust contrast 0 */
-#define UVAD_J1     0x9F /* Auto UV adjust contrast 1 */
-#define SCAL0       0xA0 /* Scaling control 0 */
-#define SCAL1       0xA1 /* Scaling control 1 */
-#define SCAL2       0xA2 /* Scaling control 2 */
-#define FIFODLYM    0xA3 /* FIFO manual mode delay control */
-#define FIFODLYA    0xA4 /* FIFO auto   mode delay control */
-#define SDE         0xA6 /* Special digital effect control */
-#define USAT        0xA7 /* U component saturation control */
-#define VSAT        0xA8 /* V component saturation control */
-/* for ov7720 */
-#define HUE0        0xA9 /* Hue control 0 */
-#define HUE1        0xAA /* Hue control 1 */
-/* for ov7725 */
-#define HUECOS      0xA9 /* Cosine value */
-#define HUESIN      0xAA /* Sine value */
-
-#define SIGN        0xAB /* Sign bit for Hue and contrast */
-#define DSPAUTO     0xAC /* DSP auto function ON/OFF control */
-
-/*
- * register detail
- */
-
-/* COM2 */
-#define SOFT_SLEEP_MODE 0x10   /* Soft sleep mode */
-                               /* Output drive capability */
-#define OCAP_1x         0x00   /* 1x */
-#define OCAP_2x         0x01   /* 2x */
-#define OCAP_3x         0x02   /* 3x */
-#define OCAP_4x         0x03   /* 4x */
-
-/* COM3 */
-#define SWAP_MASK       (SWAP_RGB | SWAP_YUV | SWAP_ML)
-#define IMG_MASK        (VFLIP_IMG | HFLIP_IMG)
-
-#define VFLIP_IMG       0x80   /* Vertical flip image ON/OFF selection */
-#define HFLIP_IMG       0x40   /* Horizontal mirror image ON/OFF selection */
-#define SWAP_RGB        0x20   /* Swap B/R  output sequence in RGB mode */
-#define SWAP_YUV        0x10   /* Swap Y/UV output sequence in YUV mode */
-#define SWAP_ML         0x08   /* Swap output MSB/LSB */
-                               /* Tri-state option for output clock */
-#define NOTRI_CLOCK     0x04   /*   0: Tri-state    at this period */
-                               /*   1: No tri-state at this period */
-                               /* Tri-state option for output data */
-#define NOTRI_DATA      0x02   /*   0: Tri-state    at this period */
-                               /*   1: No tri-state at this period */
-#define SCOLOR_TEST     0x01   /* Sensor color bar test pattern */
-
-/* COM4 */
-                               /* PLL frequency control */
-#define PLL_BYPASS      0x00   /*  00: Bypass PLL */
-#define PLL_4x          0x40   /*  01: PLL 4x */
-#define PLL_6x          0x80   /*  10: PLL 6x */
-#define PLL_8x          0xc0   /*  11: PLL 8x */
-                               /* AEC evaluate window */
-#define AEC_FULL        0x00   /*  00: Full window */
-#define AEC_1p2         0x10   /*  01: 1/2  window */
-#define AEC_1p4         0x20   /*  10: 1/4  window */
-#define AEC_2p3         0x30   /*  11: Low 2/3 window */
-
-/* COM5 */
-#define AFR_ON_OFF      0x80   /* Auto frame rate control ON/OFF selection */
-#define AFR_SPPED       0x40   /* Auto frame rate control speed selection */
-                               /* Auto frame rate max rate control */
-#define AFR_NO_RATE     0x00   /*     No  reduction of frame rate */
-#define AFR_1p2         0x10   /*     Max reduction to 1/2 frame rate */
-#define AFR_1p4         0x20   /*     Max reduction to 1/4 frame rate */
-#define AFR_1p8         0x30   /* Max reduction to 1/8 frame rate */
-                               /* Auto frame rate active point control */
-#define AF_2x           0x00   /*     Add frame when AGC reaches  2x gain */
-#define AF_4x           0x04   /*     Add frame when AGC reaches  4x gain */
-#define AF_8x           0x08   /*     Add frame when AGC reaches  8x gain */
-#define AF_16x          0x0c   /* Add frame when AGC reaches 16x gain */
-                               /* AEC max step control */
-#define AEC_NO_LIMIT    0x01   /*   0 : AEC incease step has limit */
-                               /*   1 : No limit to AEC increase step */
-
-/* COM7 */
-                               /* SCCB Register Reset */
-#define SCCB_RESET      0x80   /*   0 : No change */
-                               /*   1 : Resets all registers to default */
-                               /* Resolution selection */
-#define SLCT_MASK       0x40   /*   Mask of VGA or QVGA */
-#define SLCT_VGA        0x00   /*   0 : VGA */
-#define SLCT_QVGA       0x40   /*   1 : QVGA */
-#define ITU656_ON_OFF   0x20   /* ITU656 protocol ON/OFF selection */
-#define SENSOR_RAW     0x10    /* Sensor RAW */
-                               /* RGB output format control */
-#define FMT_MASK        0x0c   /*      Mask of color format */
-#define FMT_GBR422      0x00   /*      00 : GBR 4:2:2 */
-#define FMT_RGB565      0x04   /*      01 : RGB 565 */
-#define FMT_RGB555      0x08   /*      10 : RGB 555 */
-#define FMT_RGB444      0x0c   /* 11 : RGB 444 */
-                               /* Output format control */
-#define OFMT_MASK       0x03    /*      Mask of output format */
-#define OFMT_YUV        0x00   /*      00 : YUV */
-#define OFMT_P_BRAW     0x01   /*      01 : Processed Bayer RAW */
-#define OFMT_RGB        0x02   /*      10 : RGB */
-#define OFMT_BRAW       0x03   /* 11 : Bayer RAW */
-
-/* COM8 */
-#define FAST_ALGO       0x80   /* Enable fast AGC/AEC algorithm */
-                               /* AEC Setp size limit */
-#define UNLMT_STEP      0x40   /*   0 : Step size is limited */
-                               /*   1 : Unlimited step size */
-#define BNDF_ON_OFF     0x20   /* Banding filter ON/OFF */
-#define AEC_BND         0x10   /* Enable AEC below banding value */
-#define AEC_ON_OFF      0x08   /* Fine AEC ON/OFF control */
-#define AGC_ON          0x04   /* AGC Enable */
-#define AWB_ON          0x02   /* AWB Enable */
-#define AEC_ON          0x01   /* AEC Enable */
-
-/* COM9 */
-#define BASE_AECAGC     0x80   /* Histogram or average based AEC/AGC */
-                               /* Automatic gain ceiling - maximum AGC value */
-#define GAIN_2x         0x00   /*    000 :   2x */
-#define GAIN_4x         0x10   /*    001 :   4x */
-#define GAIN_8x         0x20   /*    010 :   8x */
-#define GAIN_16x        0x30   /*    011 :  16x */
-#define GAIN_32x        0x40   /*    100 :  32x */
-#define GAIN_64x        0x50   /* 101 :  64x */
-#define GAIN_128x       0x60   /* 110 : 128x */
-#define DROP_VSYNC      0x04   /* Drop VSYNC output of corrupt frame */
-#define DROP_HREF       0x02   /* Drop HREF  output of corrupt frame */
-
-/* COM11 */
-#define SGLF_ON_OFF     0x02   /* Single frame ON/OFF selection */
-#define SGLF_TRIG       0x01   /* Single frame transfer trigger */
-
-/* HREF */
-#define HREF_VSTART_SHIFT      6       /* VSTART LSB */
-#define HREF_HSTART_SHIFT      4       /* HSTART 2 LSBs */
-#define HREF_VSIZE_SHIFT       2       /* VSIZE LSB */
-#define HREF_HSIZE_SHIFT       0       /* HSIZE 2 LSBs */
-
-/* EXHCH */
-#define EXHCH_VSIZE_SHIFT      2       /* VOUTSIZE LSB */
-#define EXHCH_HSIZE_SHIFT      0       /* HOUTSIZE 2 LSBs */
-
-/* DSP_CTRL1 */
-#define FIFO_ON         0x80   /* FIFO enable/disable selection */
-#define UV_ON_OFF       0x40   /* UV adjust function ON/OFF selection */
-#define YUV444_2_422    0x20   /* YUV444 to 422 UV channel option selection */
-#define CLR_MTRX_ON_OFF 0x10   /* Color matrix ON/OFF selection */
-#define INTPLT_ON_OFF   0x08   /* Interpolation ON/OFF selection */
-#define GMM_ON_OFF      0x04   /* Gamma function ON/OFF selection */
-#define AUTO_BLK_ON_OFF 0x02   /* Black defect auto correction ON/OFF */
-#define AUTO_WHT_ON_OFF 0x01   /* White define auto correction ON/OFF */
-
-/* DSP_CTRL3 */
-#define UV_MASK         0x80   /* UV output sequence option */
-#define UV_ON           0x80   /*   ON */
-#define UV_OFF          0x00   /*   OFF */
-#define CBAR_MASK       0x20   /* DSP Color bar mask */
-#define CBAR_ON         0x20   /*   ON */
-#define CBAR_OFF        0x00   /*   OFF */
-
-/* DSP_CTRL4 */
-#define DSP_OFMT_YUV   0x00
-#define DSP_OFMT_RGB   0x00
-#define DSP_OFMT_RAW8  0x02
-#define DSP_OFMT_RAW10 0x03
-
-/* DSPAUTO (DSP Auto Function ON/OFF Control) */
-#define AWB_ACTRL       0x80 /* AWB auto threshold control */
-#define DENOISE_ACTRL   0x40 /* De-noise auto threshold control */
-#define EDGE_ACTRL      0x20 /* Edge enhancement auto strength control */
-#define UV_ACTRL        0x10 /* UV adjust auto slope control */
-#define SCAL0_ACTRL     0x08 /* Auto scaling factor control */
-#define SCAL1_2_ACTRL   0x04 /* Auto scaling factor control */
-
-#define OV772X_MAX_WIDTH       VGA_WIDTH
-#define OV772X_MAX_HEIGHT      VGA_HEIGHT
-
-/*
- * ID
- */
-#define OV7720  0x7720
-#define OV7725  0x7721
-#define VERSION(pid, ver) ((pid<<8)|(ver&0xFF))
-
-/*
- * struct
- */
-
-struct ov772x_color_format {
-       u32 code;
-       enum v4l2_colorspace colorspace;
-       u8 dsp3;
-       u8 dsp4;
-       u8 com3;
-       u8 com7;
-};
-
-struct ov772x_win_size {
-       char                     *name;
-       unsigned char             com7_bit;
-       struct v4l2_rect          rect;
-};
-
-struct ov772x_priv {
-       struct v4l2_subdev                subdev;
-       struct v4l2_ctrl_handler          hdl;
-       struct v4l2_clk                  *clk;
-       struct ov772x_camera_info        *info;
-       const struct ov772x_color_format *cfmt;
-       const struct ov772x_win_size     *win;
-       unsigned short                    flag_vflip:1;
-       unsigned short                    flag_hflip:1;
-       /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
-       unsigned short                    band_filter;
-};
-
-/*
- * supported color format list
- */
-static const struct ov772x_color_format ov772x_cfmts[] = {
-       {
-               .code           = MEDIA_BUS_FMT_YUYV8_2X8,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = SWAP_YUV,
-               .com7           = OFMT_YUV,
-       },
-       {
-               .code           = MEDIA_BUS_FMT_YVYU8_2X8,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
-               .dsp3           = UV_ON,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = SWAP_YUV,
-               .com7           = OFMT_YUV,
-       },
-       {
-               .code           = MEDIA_BUS_FMT_UYVY8_2X8,
-               .colorspace     = V4L2_COLORSPACE_JPEG,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = 0x0,
-               .com7           = OFMT_YUV,
-       },
-       {
-               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = SWAP_RGB,
-               .com7           = FMT_RGB555 | OFMT_RGB,
-       },
-       {
-               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = 0x0,
-               .com7           = FMT_RGB555 | OFMT_RGB,
-       },
-       {
-               .code           = MEDIA_BUS_FMT_RGB565_2X8_LE,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = SWAP_RGB,
-               .com7           = FMT_RGB565 | OFMT_RGB,
-       },
-       {
-               .code           = MEDIA_BUS_FMT_RGB565_2X8_BE,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_YUV,
-               .com3           = 0x0,
-               .com7           = FMT_RGB565 | OFMT_RGB,
-       },
-       {
-               /* Setting DSP4 to DSP_OFMT_RAW8 still gives 10-bit output,
-                * regardless of the COM7 value. We can thus only support 10-bit
-                * Bayer until someone figures it out.
-                */
-               .code           = MEDIA_BUS_FMT_SBGGR10_1X10,
-               .colorspace     = V4L2_COLORSPACE_SRGB,
-               .dsp3           = 0x0,
-               .dsp4           = DSP_OFMT_RAW10,
-               .com3           = 0x0,
-               .com7           = SENSOR_RAW | OFMT_BRAW,
-       },
-};
-
-
-/*
- * window size list
- */
-
-static const struct ov772x_win_size ov772x_win_sizes[] = {
-       {
-               .name     = "VGA",
-               .com7_bit = SLCT_VGA,
-               .rect = {
-                       .left = 140,
-                       .top = 14,
-                       .width = VGA_WIDTH,
-                       .height = VGA_HEIGHT,
-               },
-       }, {
-               .name     = "QVGA",
-               .com7_bit = SLCT_QVGA,
-               .rect = {
-                       .left = 252,
-                       .top = 6,
-                       .width = QVGA_WIDTH,
-                       .height = QVGA_HEIGHT,
-               },
-       },
-};
-
-/*
- * general function
- */
-
-static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd)
-{
-       return container_of(sd, struct ov772x_priv, subdev);
-}
-
-static inline int ov772x_read(struct i2c_client *client, u8 addr)
-{
-       return i2c_smbus_read_byte_data(client, addr);
-}
-
-static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
-{
-       return i2c_smbus_write_byte_data(client, addr, value);
-}
-
-static int ov772x_mask_set(struct i2c_client *client, u8  command, u8  mask,
-                          u8  set)
-{
-       s32 val = ov772x_read(client, command);
-       if (val < 0)
-               return val;
-
-       val &= ~mask;
-       val |= set & mask;
-
-       return ov772x_write(client, command, val);
-}
-
-static int ov772x_reset(struct i2c_client *client)
-{
-       int ret;
-
-       ret = ov772x_write(client, COM7, SCCB_RESET);
-       if (ret < 0)
-               return ret;
-
-       msleep(1);
-
-       return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
-}
-
-/*
- * soc_camera_ops function
- */
-
-static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov772x_priv *priv = to_ov772x(sd);
-
-       if (!enable) {
-               ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
-               return 0;
-       }
-
-       ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
-
-       dev_dbg(&client->dev, "format %d, win %s\n",
-               priv->cfmt->code, priv->win->name);
-
-       return 0;
-}
-
-static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct ov772x_priv *priv = container_of(ctrl->handler,
-                                               struct ov772x_priv, hdl);
-       struct v4l2_subdev *sd = &priv->subdev;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret = 0;
-       u8 val;
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               val = ctrl->val ? VFLIP_IMG : 0x00;
-               priv->flag_vflip = ctrl->val;
-               if (priv->info->flags & OV772X_FLAG_VFLIP)
-                       val ^= VFLIP_IMG;
-               return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
-       case V4L2_CID_HFLIP:
-               val = ctrl->val ? HFLIP_IMG : 0x00;
-               priv->flag_hflip = ctrl->val;
-               if (priv->info->flags & OV772X_FLAG_HFLIP)
-                       val ^= HFLIP_IMG;
-               return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
-       case V4L2_CID_BAND_STOP_FILTER:
-               if (!ctrl->val) {
-                       /* Switch the filter off, it is on now */
-                       ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
-                       if (!ret)
-                               ret = ov772x_mask_set(client, COM8,
-                                                     BNDF_ON_OFF, 0);
-               } else {
-                       /* Switch the filter on, set AEC low limit */
-                       val = 256 - ctrl->val;
-                       ret = ov772x_mask_set(client, COM8,
-                                             BNDF_ON_OFF, BNDF_ON_OFF);
-                       if (!ret)
-                               ret = ov772x_mask_set(client, BDBASE,
-                                                     0xff, val);
-               }
-               if (!ret)
-                       priv->band_filter = ctrl->val;
-               return ret;
-       }
-
-       return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov772x_g_register(struct v4l2_subdev *sd,
-                            struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
-
-       reg->size = 1;
-       if (reg->reg > 0xff)
-               return -EINVAL;
-
-       ret = ov772x_read(client, reg->reg);
-       if (ret < 0)
-               return ret;
-
-       reg->val = (__u64)ret;
-
-       return 0;
-}
-
-static int ov772x_s_register(struct v4l2_subdev *sd,
-                            const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg > 0xff ||
-           reg->val > 0xff)
-               return -EINVAL;
-
-       return ov772x_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov772x_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct ov772x_priv *priv = to_ov772x(sd);
-
-       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
-}
-
-static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
-{
-       const struct ov772x_win_size *win = &ov772x_win_sizes[0];
-       u32 best_diff = UINT_MAX;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) {
-               u32 diff = abs(width - ov772x_win_sizes[i].rect.width)
-                        + abs(height - ov772x_win_sizes[i].rect.height);
-               if (diff < best_diff) {
-                       best_diff = diff;
-                       win = &ov772x_win_sizes[i];
-               }
-       }
-
-       return win;
-}
-
-static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf,
-                                const struct ov772x_color_format **cfmt,
-                                const struct ov772x_win_size **win)
-{
-       unsigned int i;
-
-       /* Select a format. */
-       *cfmt = &ov772x_cfmts[0];
-
-       for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
-               if (mf->code == ov772x_cfmts[i].code) {
-                       *cfmt = &ov772x_cfmts[i];
-                       break;
-               }
-       }
-
-       /* Select a window size. */
-       *win = ov772x_select_win(mf->width, mf->height);
-}
-
-static int ov772x_set_params(struct ov772x_priv *priv,
-                            const struct ov772x_color_format *cfmt,
-                            const struct ov772x_win_size *win)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
-       int ret;
-       u8  val;
-
-       /*
-        * reset hardware
-        */
-       ov772x_reset(client);
-
-       /*
-        * Edge Ctrl
-        */
-       if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
-
-               /*
-                * Manual Edge Control Mode
-                *
-                * Edge auto strength bit is set by default.
-                * Remove it when manual mode.
-                */
-
-               ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-
-               ret = ov772x_mask_set(client,
-                                     EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
-                                     priv->info->edgectrl.threshold);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-
-               ret = ov772x_mask_set(client,
-                                     EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
-                                     priv->info->edgectrl.strength);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-
-       } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
-               /*
-                * Auto Edge Control Mode
-                *
-                * set upper and lower limit
-                */
-               ret = ov772x_mask_set(client,
-                                     EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
-                                     priv->info->edgectrl.upper);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-
-               ret = ov772x_mask_set(client,
-                                     EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
-                                     priv->info->edgectrl.lower);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-       }
-
-       /* Format and window size */
-       ret = ov772x_write(client, HSTART, win->rect.left >> 2);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, VSTART, win->rect.top >> 1);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, HREF,
-                          ((win->rect.top & 1) << HREF_VSTART_SHIFT) |
-                          ((win->rect.left & 3) << HREF_HSTART_SHIFT) |
-                          ((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
-                          ((win->rect.width & 3) << HREF_HSIZE_SHIFT));
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-       ret = ov772x_write(client, EXHCH,
-                          ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
-                          ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-
-       /*
-        * set DSP_CTRL3
-        */
-       val = cfmt->dsp3;
-       if (val) {
-               ret = ov772x_mask_set(client,
-                                     DSP_CTRL3, UV_MASK, val);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-       }
-
-       /* DSP_CTRL4: AEC reference point and DSP output format. */
-       if (cfmt->dsp4) {
-               ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-       }
-
-       /*
-        * set COM3
-        */
-       val = cfmt->com3;
-       if (priv->info->flags & OV772X_FLAG_VFLIP)
-               val |= VFLIP_IMG;
-       if (priv->info->flags & OV772X_FLAG_HFLIP)
-               val |= HFLIP_IMG;
-       if (priv->flag_vflip)
-               val ^= VFLIP_IMG;
-       if (priv->flag_hflip)
-               val ^= HFLIP_IMG;
-
-       ret = ov772x_mask_set(client,
-                             COM3, SWAP_MASK | IMG_MASK, val);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-
-       /* COM7: Sensor resolution and output format control. */
-       ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7);
-       if (ret < 0)
-               goto ov772x_set_fmt_error;
-
-       /*
-        * set COM8
-        */
-       if (priv->band_filter) {
-               ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, BNDF_ON_OFF);
-               if (!ret)
-                       ret = ov772x_mask_set(client, BDBASE,
-                                             0xff, 256 - priv->band_filter);
-               if (ret < 0)
-                       goto ov772x_set_fmt_error;
-       }
-
-       return ret;
-
-ov772x_set_fmt_error:
-
-       ov772x_reset(client);
-
-       return ret;
-}
-
-static int ov772x_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       sel->r.left = 0;
-       sel->r.top = 0;
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.width = OV772X_MAX_WIDTH;
-               sel->r.height = OV772X_MAX_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP:
-               sel->r.width = VGA_WIDTH;
-               sel->r.height = VGA_HEIGHT;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int ov772x_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct ov772x_priv *priv = to_ov772x(sd);
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->width       = priv->win->rect.width;
-       mf->height      = priv->win->rect.height;
-       mf->code        = priv->cfmt->code;
-       mf->colorspace  = priv->cfmt->colorspace;
-       mf->field       = V4L2_FIELD_NONE;
-
-       return 0;
-}
-
-static int ov772x_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct ov772x_priv *priv = to_ov772x(sd);
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       const struct ov772x_color_format *cfmt;
-       const struct ov772x_win_size *win;
-       int ret;
-
-       if (format->pad)
-               return -EINVAL;
-
-       ov772x_select_params(mf, &cfmt, &win);
-
-       mf->code = cfmt->code;
-       mf->width = win->rect.width;
-       mf->height = win->rect.height;
-       mf->field = V4L2_FIELD_NONE;
-       mf->colorspace = cfmt->colorspace;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
-               cfg->try_fmt = *mf;
-               return 0;
-       }
-
-       ret = ov772x_set_params(priv, cfmt, win);
-       if (ret < 0)
-               return ret;
-
-       priv->win = win;
-       priv->cfmt = cfmt;
-       return 0;
-}
-
-static int ov772x_video_probe(struct ov772x_priv *priv)
-{
-       struct i2c_client  *client = v4l2_get_subdevdata(&priv->subdev);
-       u8                  pid, ver;
-       const char         *devname;
-       int                 ret;
-
-       ret = ov772x_s_power(&priv->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * check and show product ID and manufacturer ID
-        */
-       pid = ov772x_read(client, PID);
-       ver = ov772x_read(client, VER);
-
-       switch (VERSION(pid, ver)) {
-       case OV7720:
-               devname     = "ov7720";
-               break;
-       case OV7725:
-               devname     = "ov7725";
-               break;
-       default:
-               dev_err(&client->dev,
-                       "Product ID error %x:%x\n", pid, ver);
-               ret = -ENODEV;
-               goto done;
-       }
-
-       dev_info(&client->dev,
-                "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
-                devname,
-                pid,
-                ver,
-                ov772x_read(client, MIDH),
-                ov772x_read(client, MIDL));
-       ret = v4l2_ctrl_handler_setup(&priv->hdl);
-
-done:
-       ov772x_s_power(&priv->subdev, 0);
-       return ret;
-}
-
-static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
-       .s_ctrl = ov772x_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = ov772x_g_register,
-       .s_register     = ov772x_s_register,
-#endif
-       .s_power        = ov772x_s_power,
-};
-
-static int ov772x_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts))
-               return -EINVAL;
-
-       code->code = ov772x_cfmts[code->index].code;
-       return 0;
-}
-
-static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
-               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
-       .s_stream       = ov772x_s_stream,
-       .g_mbus_config  = ov772x_g_mbus_config,
-};
-
-static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = {
-       .enum_mbus_code = ov772x_enum_mbus_code,
-       .get_selection  = ov772x_get_selection,
-       .get_fmt        = ov772x_get_fmt,
-       .set_fmt        = ov772x_set_fmt,
-};
-
-static const struct v4l2_subdev_ops ov772x_subdev_ops = {
-       .core   = &ov772x_subdev_core_ops,
-       .video  = &ov772x_subdev_video_ops,
-       .pad    = &ov772x_subdev_pad_ops,
-};
-
-/*
- * i2c_driver function
- */
-
-static int ov772x_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-{
-       struct ov772x_priv      *priv;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
-       int                     ret;
-
-       if (!ssdd || !ssdd->drv_priv) {
-               dev_err(&client->dev, "OV772X: missing platform data!\n");
-               return -EINVAL;
-       }
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-                                             I2C_FUNC_PROTOCOL_MANGLING)) {
-               dev_err(&adapter->dev,
-                       "I2C-Adapter doesn't support SMBUS_BYTE_DATA or PROTOCOL_MANGLING\n");
-               return -EIO;
-       }
-       client->flags |= I2C_CLIENT_SCCB;
-
-       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->info = ssdd->drv_priv;
-
-       v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
-       v4l2_ctrl_handler_init(&priv->hdl, 3);
-       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
-                       V4L2_CID_VFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
-                       V4L2_CID_HFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
-                       V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
-       priv->subdev.ctrl_handler = &priv->hdl;
-       if (priv->hdl.error)
-               return priv->hdl.error;
-
-       priv->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(priv->clk)) {
-               ret = PTR_ERR(priv->clk);
-               goto eclkget;
-       }
-
-       ret = ov772x_video_probe(priv);
-       if (ret < 0) {
-               v4l2_clk_put(priv->clk);
-eclkget:
-               v4l2_ctrl_handler_free(&priv->hdl);
-       } else {
-               priv->cfmt = &ov772x_cfmts[0];
-               priv->win = &ov772x_win_sizes[0];
-       }
-
-       return ret;
-}
-
-static int ov772x_remove(struct i2c_client *client)
-{
-       struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
-
-       v4l2_clk_put(priv->clk);
-       v4l2_device_unregister_subdev(&priv->subdev);
-       v4l2_ctrl_handler_free(&priv->hdl);
-       return 0;
-}
-
-static const struct i2c_device_id ov772x_id[] = {
-       { "ov772x", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, ov772x_id);
-
-static struct i2c_driver ov772x_i2c_driver = {
-       .driver = {
-               .name = "ov772x",
-       },
-       .probe    = ov772x_probe,
-       .remove   = ov772x_remove,
-       .id_table = ov772x_id,
-};
-
-module_i2c_driver(ov772x_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for ov772x");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
deleted file mode 100644 (file)
index c639489..0000000
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * OmniVision OV96xx Camera Driver
- *
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
- *
- * Based on ov772x camera driver:
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov7670 and soc_camera_platform driver,
- *
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-
-#include "ov9640.h"
-
-#define to_ov9640_sensor(sd)   container_of(sd, struct ov9640_priv, subdev)
-
-/* default register setup */
-static const struct ov9640_reg ov9640_regs_dflt[] = {
-       { OV9640_COM5,  OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
-       { OV9640_COM6,  OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
-                       OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
-       { OV9640_PSHFT, OV9640_PSHFT_VAL(0x01) },
-       { OV9640_ACOM,  OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
-       { OV9640_TSLB,  OV9640_TSLB_YUYV_UYVY },
-       { OV9640_COM16, OV9640_COM16_RB_AVG },
-
-       /* Gamma curve P */
-       { 0x6c, 0x40 }, { 0x6d, 0x30 }, { 0x6e, 0x4b }, { 0x6f, 0x60 },
-       { 0x70, 0x70 }, { 0x71, 0x70 }, { 0x72, 0x70 }, { 0x73, 0x70 },
-       { 0x74, 0x60 }, { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 },
-       { 0x78, 0x3a }, { 0x79, 0x2e }, { 0x7a, 0x28 }, { 0x7b, 0x22 },
-
-       /* Gamma curve T */
-       { 0x7c, 0x04 }, { 0x7d, 0x07 }, { 0x7e, 0x10 }, { 0x7f, 0x28 },
-       { 0x80, 0x36 }, { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 },
-       { 0x84, 0x6c }, { 0x85, 0x78 }, { 0x86, 0x8c }, { 0x87, 0x9e },
-       { 0x88, 0xbb }, { 0x89, 0xd2 }, { 0x8a, 0xe6 },
-};
-
-/* Configurations
- * NOTE: for YUV, alter the following registers:
- *             COM12 |= OV9640_COM12_YUV_AVG
- *
- *      for RGB, alter the following registers:
- *             COM7  |= OV9640_COM7_RGB
- *             COM13 |= OV9640_COM13_RGB_AVG
- *             COM15 |= proper RGB color encoding mode
- */
-static const struct ov9640_reg ov9640_regs_qqcif[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
-       { OV9640_COM1,  OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
-       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
-       { OV9640_COM7,  OV9640_COM7_QCIF },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_qqvga[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
-       { OV9640_COM1,  OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
-       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
-       { OV9640_COM7,  OV9640_COM7_QVGA },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_qcif[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
-       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
-       { OV9640_COM7,  OV9640_COM7_QCIF },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_qvga[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
-       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
-       { OV9640_COM7,  OV9640_COM7_QVGA },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_cif[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
-       { OV9640_COM3,  OV9640_COM3_VP },
-       { OV9640_COM7,  OV9640_COM7_CIF },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_vga[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
-       { OV9640_COM3,  OV9640_COM3_VP },
-       { OV9640_COM7,  OV9640_COM7_VGA },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_sxga[] = {
-       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
-       { OV9640_COM3,  OV9640_COM3_VP },
-       { OV9640_COM7,  0 },
-       { OV9640_COM12, OV9640_COM12_RSVD },
-       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
-       { OV9640_COM15, OV9640_COM15_OR_10F0 },
-};
-
-static const struct ov9640_reg ov9640_regs_yuv[] = {
-       { OV9640_MTX1,  0x58 },
-       { OV9640_MTX2,  0x48 },
-       { OV9640_MTX3,  0x10 },
-       { OV9640_MTX4,  0x28 },
-       { OV9640_MTX5,  0x48 },
-       { OV9640_MTX6,  0x70 },
-       { OV9640_MTX7,  0x40 },
-       { OV9640_MTX8,  0x40 },
-       { OV9640_MTX9,  0x40 },
-       { OV9640_MTXS,  0x0f },
-};
-
-static const struct ov9640_reg ov9640_regs_rgb[] = {
-       { OV9640_MTX1,  0x71 },
-       { OV9640_MTX2,  0x3e },
-       { OV9640_MTX3,  0x0c },
-       { OV9640_MTX4,  0x33 },
-       { OV9640_MTX5,  0x72 },
-       { OV9640_MTX6,  0x00 },
-       { OV9640_MTX7,  0x2b },
-       { OV9640_MTX8,  0x66 },
-       { OV9640_MTX9,  0xd2 },
-       { OV9640_MTXS,  0x65 },
-};
-
-static u32 ov9640_codes[] = {
-       MEDIA_BUS_FMT_UYVY8_2X8,
-       MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
-       MEDIA_BUS_FMT_RGB565_2X8_LE,
-};
-
-/* read a register */
-static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
-{
-       int ret;
-       u8 data = reg;
-       struct i2c_msg msg = {
-               .addr   = client->addr,
-               .flags  = 0,
-               .len    = 1,
-               .buf    = &data,
-       };
-
-       ret = i2c_transfer(client->adapter, &msg, 1);
-       if (ret < 0)
-               goto err;
-
-       msg.flags = I2C_M_RD;
-       ret = i2c_transfer(client->adapter, &msg, 1);
-       if (ret < 0)
-               goto err;
-
-       *val = data;
-       return 0;
-
-err:
-       dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
-       return ret;
-}
-
-/* write a register */
-static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
-{
-       int ret;
-       u8 _val;
-       unsigned char data[2] = { reg, val };
-       struct i2c_msg msg = {
-               .addr   = client->addr,
-               .flags  = 0,
-               .len    = 2,
-               .buf    = data,
-       };
-
-       ret = i2c_transfer(client->adapter, &msg, 1);
-       if (ret < 0) {
-               dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
-               return ret;
-       }
-
-       /* we have to read the register back ... no idea why, maybe HW bug */
-       ret = ov9640_reg_read(client, reg, &_val);
-       if (ret)
-               dev_err(&client->dev,
-                       "Failed reading back register 0x%02x!\n", reg);
-
-       return 0;
-}
-
-
-/* Read a register, alter its bits, write it back */
-static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
-{
-       u8 val;
-       int ret;
-
-       ret = ov9640_reg_read(client, reg, &val);
-       if (ret) {
-               dev_err(&client->dev,
-                       "[Read]-Modify-Write of register %02x failed!\n", reg);
-               return ret;
-       }
-
-       val |= set;
-       val &= ~unset;
-
-       ret = ov9640_reg_write(client, reg, val);
-       if (ret)
-               dev_err(&client->dev,
-                       "Read-Modify-[Write] of register %02x failed!\n", reg);
-
-       return ret;
-}
-
-/* Soft reset the camera. This has nothing to do with the RESET pin! */
-static int ov9640_reset(struct i2c_client *client)
-{
-       int ret;
-
-       ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
-       if (ret)
-               dev_err(&client->dev,
-                       "An error occurred while entering soft reset!\n");
-
-       return ret;
-}
-
-/* Start/Stop streaming from the device */
-static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       return 0;
-}
-
-/* Set status of additional camera capabilities */
-static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct ov9640_priv *priv = container_of(ctrl->handler, struct ov9640_priv, hdl);
-       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               if (ctrl->val)
-                       return ov9640_reg_rmw(client, OV9640_MVFP,
-                                                       OV9640_MVFP_V, 0);
-               return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
-       case V4L2_CID_HFLIP:
-               if (ctrl->val)
-                       return ov9640_reg_rmw(client, OV9640_MVFP,
-                                                       OV9640_MVFP_H, 0);
-               return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
-       }
-       return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov9640_get_register(struct v4l2_subdev *sd,
-                               struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
-       u8 val;
-
-       if (reg->reg & ~0xff)
-               return -EINVAL;
-
-       reg->size = 1;
-
-       ret = ov9640_reg_read(client, reg->reg, &val);
-       if (ret)
-               return ret;
-
-       reg->val = (__u64)val;
-
-       return 0;
-}
-
-static int ov9640_set_register(struct v4l2_subdev *sd,
-                               const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg & ~0xff || reg->val & ~0xff)
-               return -EINVAL;
-
-       return ov9640_reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov9640_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
-       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
-}
-
-/* select nearest higher resolution for capture */
-static void ov9640_res_roundup(u32 *width, u32 *height)
-{
-       int i;
-       enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
-       static const int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
-       static const int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
-
-       for (i = 0; i < ARRAY_SIZE(res_x); i++) {
-               if (res_x[i] >= *width && res_y[i] >= *height) {
-                       *width = res_x[i];
-                       *height = res_y[i];
-                       return;
-               }
-       }
-
-       *width = res_x[SXGA];
-       *height = res_y[SXGA];
-}
-
-/* Prepare necessary register changes depending on color encoding */
-static void ov9640_alter_regs(u32 code,
-                             struct ov9640_reg_alt *alt)
-{
-       switch (code) {
-       default:
-       case MEDIA_BUS_FMT_UYVY8_2X8:
-               alt->com12      = OV9640_COM12_YUV_AVG;
-               alt->com13      = OV9640_COM13_Y_DELAY_EN |
-                                       OV9640_COM13_YUV_DLY(0x01);
-               break;
-       case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
-               alt->com7       = OV9640_COM7_RGB;
-               alt->com13      = OV9640_COM13_RGB_AVG;
-               alt->com15      = OV9640_COM15_RGB_555;
-               break;
-       case MEDIA_BUS_FMT_RGB565_2X8_LE:
-               alt->com7       = OV9640_COM7_RGB;
-               alt->com13      = OV9640_COM13_RGB_AVG;
-               alt->com15      = OV9640_COM15_RGB_565;
-               break;
-       }
-}
-
-/* Setup registers according to resolution and color encoding */
-static int ov9640_write_regs(struct i2c_client *client, u32 width,
-               u32 code, struct ov9640_reg_alt *alts)
-{
-       const struct ov9640_reg *ov9640_regs, *matrix_regs;
-       int                     ov9640_regs_len, matrix_regs_len;
-       int                     i, ret;
-       u8                      val;
-
-       /* select register configuration for given resolution */
-       switch (width) {
-       case W_QQCIF:
-               ov9640_regs     = ov9640_regs_qqcif;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqcif);
-               break;
-       case W_QQVGA:
-               ov9640_regs     = ov9640_regs_qqvga;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqvga);
-               break;
-       case W_QCIF:
-               ov9640_regs     = ov9640_regs_qcif;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qcif);
-               break;
-       case W_QVGA:
-               ov9640_regs     = ov9640_regs_qvga;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qvga);
-               break;
-       case W_CIF:
-               ov9640_regs     = ov9640_regs_cif;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_cif);
-               break;
-       case W_VGA:
-               ov9640_regs     = ov9640_regs_vga;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_vga);
-               break;
-       case W_SXGA:
-               ov9640_regs     = ov9640_regs_sxga;
-               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_sxga);
-               break;
-       default:
-               dev_err(&client->dev, "Failed to select resolution!\n");
-               return -EINVAL;
-       }
-
-       /* select color matrix configuration for given color encoding */
-       if (code == MEDIA_BUS_FMT_UYVY8_2X8) {
-               matrix_regs     = ov9640_regs_yuv;
-               matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv);
-       } else {
-               matrix_regs     = ov9640_regs_rgb;
-               matrix_regs_len = ARRAY_SIZE(ov9640_regs_rgb);
-       }
-
-       /* write register settings into the module */
-       for (i = 0; i < ov9640_regs_len; i++) {
-               val = ov9640_regs[i].val;
-
-               switch (ov9640_regs[i].reg) {
-               case OV9640_COM7:
-                       val |= alts->com7;
-                       break;
-               case OV9640_COM12:
-                       val |= alts->com12;
-                       break;
-               case OV9640_COM13:
-                       val |= alts->com13;
-                       break;
-               case OV9640_COM15:
-                       val |= alts->com15;
-                       break;
-               }
-
-               ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
-               if (ret)
-                       return ret;
-       }
-
-       /* write color matrix configuration into the module */
-       for (i = 0; i < matrix_regs_len; i++) {
-               ret = ov9640_reg_write(client, matrix_regs[i].reg,
-                                               matrix_regs[i].val);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-/* program default register values */
-static int ov9640_prog_dflt(struct i2c_client *client)
-{
-       int i, ret;
-
-       for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
-               ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
-                                               ov9640_regs_dflt[i].val);
-               if (ret)
-                       return ret;
-       }
-
-       /* wait for the changes to actually happen, 140ms are not enough yet */
-       mdelay(150);
-
-       return 0;
-}
-
-/* set the format we will capture in */
-static int ov9640_s_fmt(struct v4l2_subdev *sd,
-                       struct v4l2_mbus_framefmt *mf)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov9640_reg_alt alts = {0};
-       int ret;
-
-       ov9640_alter_regs(mf->code, &alts);
-
-       ov9640_reset(client);
-
-       ret = ov9640_prog_dflt(client);
-       if (ret)
-               return ret;
-
-       return ov9640_write_regs(client, mf->width, mf->code, &alts);
-}
-
-static int ov9640_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-
-       if (format->pad)
-               return -EINVAL;
-
-       ov9640_res_roundup(&mf->width, &mf->height);
-
-       mf->field = V4L2_FIELD_NONE;
-
-       switch (mf->code) {
-       case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
-       case MEDIA_BUS_FMT_RGB565_2X8_LE:
-               mf->colorspace = V4L2_COLORSPACE_SRGB;
-               break;
-       default:
-               mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
-               /* fall through */
-       case MEDIA_BUS_FMT_UYVY8_2X8:
-               mf->colorspace = V4L2_COLORSPACE_JPEG;
-               break;
-       }
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               return ov9640_s_fmt(sd, mf);
-
-       cfg->try_fmt = *mf;
-       return 0;
-}
-
-static int ov9640_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes))
-               return -EINVAL;
-
-       code->code = ov9640_codes[code->index];
-       return 0;
-}
-
-static int ov9640_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       sel->r.left = 0;
-       sel->r.top = 0;
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-       case V4L2_SEL_TGT_CROP:
-               sel->r.width = W_SXGA;
-               sel->r.height = H_SXGA;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int ov9640_video_probe(struct i2c_client *client)
-{
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
-       struct ov9640_priv *priv = to_ov9640_sensor(sd);
-       u8              pid, ver, midh, midl;
-       const char      *devname;
-       int             ret;
-
-       ret = ov9640_s_power(&priv->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * check and show product ID and manufacturer ID
-        */
-
-       ret = ov9640_reg_read(client, OV9640_PID, &pid);
-       if (!ret)
-               ret = ov9640_reg_read(client, OV9640_VER, &ver);
-       if (!ret)
-               ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
-       if (!ret)
-               ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
-       if (ret)
-               goto done;
-
-       switch (VERSION(pid, ver)) {
-       case OV9640_V2:
-               devname         = "ov9640";
-               priv->revision  = 2;
-               break;
-       case OV9640_V3:
-               devname         = "ov9640";
-               priv->revision  = 3;
-               break;
-       default:
-               dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
-               ret = -ENODEV;
-               goto done;
-       }
-
-       dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
-                devname, pid, ver, midh, midl);
-
-       ret = v4l2_ctrl_handler_setup(&priv->hdl);
-
-done:
-       ov9640_s_power(&priv->subdev, 0);
-       return ret;
-}
-
-static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
-       .s_ctrl = ov9640_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops ov9640_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register             = ov9640_get_register,
-       .s_register             = ov9640_set_register,
-#endif
-       .s_power                = ov9640_s_power,
-};
-
-/* Request bus settings on camera side */
-static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
-               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops ov9640_video_ops = {
-       .s_stream       = ov9640_s_stream,
-       .g_mbus_config  = ov9640_g_mbus_config,
-};
-
-static const struct v4l2_subdev_pad_ops ov9640_pad_ops = {
-       .enum_mbus_code = ov9640_enum_mbus_code,
-       .get_selection  = ov9640_get_selection,
-       .set_fmt        = ov9640_set_fmt,
-};
-
-static const struct v4l2_subdev_ops ov9640_subdev_ops = {
-       .core   = &ov9640_core_ops,
-       .video  = &ov9640_video_ops,
-       .pad    = &ov9640_pad_ops,
-};
-
-/*
- * i2c_driver function
- */
-static int ov9640_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-{
-       struct ov9640_priv *priv;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       int ret;
-
-       if (!ssdd) {
-               dev_err(&client->dev, "Missing platform_data for driver\n");
-               return -EINVAL;
-       }
-
-       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
-
-       v4l2_ctrl_handler_init(&priv->hdl, 2);
-       v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
-                       V4L2_CID_VFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
-                       V4L2_CID_HFLIP, 0, 1, 1, 0);
-       priv->subdev.ctrl_handler = &priv->hdl;
-       if (priv->hdl.error)
-               return priv->hdl.error;
-
-       priv->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(priv->clk)) {
-               ret = PTR_ERR(priv->clk);
-               goto eclkget;
-       }
-
-       ret = ov9640_video_probe(client);
-       if (ret) {
-               v4l2_clk_put(priv->clk);
-eclkget:
-               v4l2_ctrl_handler_free(&priv->hdl);
-       }
-
-       return ret;
-}
-
-static int ov9640_remove(struct i2c_client *client)
-{
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
-       struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
-       v4l2_clk_put(priv->clk);
-       v4l2_device_unregister_subdev(&priv->subdev);
-       v4l2_ctrl_handler_free(&priv->hdl);
-       return 0;
-}
-
-static const struct i2c_device_id ov9640_id[] = {
-       { "ov9640", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, ov9640_id);
-
-static struct i2c_driver ov9640_i2c_driver = {
-       .driver = {
-               .name = "ov9640",
-       },
-       .probe    = ov9640_probe,
-       .remove   = ov9640_remove,
-       .id_table = ov9640_id,
-};
-
-module_i2c_driver(ov9640_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
-MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
deleted file mode 100644 (file)
index 755de22..0000000
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * OmniVision OV9740 Camera Driver
- *
- * Copyright (C) 2011 NVIDIA Corporation
- *
- * Based on ov9640 camera driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-ctrls.h>
-
-#define to_ov9740(sd)          container_of(sd, struct ov9740_priv, subdev)
-
-/* General Status Registers */
-#define OV9740_MODEL_ID_HI             0x0000
-#define OV9740_MODEL_ID_LO             0x0001
-#define OV9740_REVISION_NUMBER         0x0002
-#define OV9740_MANUFACTURER_ID         0x0003
-#define OV9740_SMIA_VERSION            0x0004
-
-/* General Setup Registers */
-#define OV9740_MODE_SELECT             0x0100
-#define OV9740_IMAGE_ORT               0x0101
-#define OV9740_SOFTWARE_RESET          0x0103
-#define OV9740_GRP_PARAM_HOLD          0x0104
-#define OV9740_MSK_CORRUP_FM           0x0105
-
-/* Timing Setting */
-#define OV9740_FRM_LENGTH_LN_HI                0x0340 /* VTS */
-#define OV9740_FRM_LENGTH_LN_LO                0x0341 /* VTS */
-#define OV9740_LN_LENGTH_PCK_HI                0x0342 /* HTS */
-#define OV9740_LN_LENGTH_PCK_LO                0x0343 /* HTS */
-#define OV9740_X_ADDR_START_HI         0x0344
-#define OV9740_X_ADDR_START_LO         0x0345
-#define OV9740_Y_ADDR_START_HI         0x0346
-#define OV9740_Y_ADDR_START_LO         0x0347
-#define OV9740_X_ADDR_END_HI           0x0348
-#define OV9740_X_ADDR_END_LO           0x0349
-#define OV9740_Y_ADDR_END_HI           0x034a
-#define OV9740_Y_ADDR_END_LO           0x034b
-#define OV9740_X_OUTPUT_SIZE_HI                0x034c
-#define OV9740_X_OUTPUT_SIZE_LO                0x034d
-#define OV9740_Y_OUTPUT_SIZE_HI                0x034e
-#define OV9740_Y_OUTPUT_SIZE_LO                0x034f
-
-/* IO Control Registers */
-#define OV9740_IO_CREL00               0x3002
-#define OV9740_IO_CREL01               0x3004
-#define OV9740_IO_CREL02               0x3005
-#define OV9740_IO_OUTPUT_SEL01         0x3026
-#define OV9740_IO_OUTPUT_SEL02         0x3027
-
-/* AWB Registers */
-#define OV9740_AWB_MANUAL_CTRL         0x3406
-
-/* Analog Control Registers */
-#define OV9740_ANALOG_CTRL01           0x3601
-#define OV9740_ANALOG_CTRL02           0x3602
-#define OV9740_ANALOG_CTRL03           0x3603
-#define OV9740_ANALOG_CTRL04           0x3604
-#define OV9740_ANALOG_CTRL10           0x3610
-#define OV9740_ANALOG_CTRL12           0x3612
-#define OV9740_ANALOG_CTRL15           0x3615
-#define OV9740_ANALOG_CTRL20           0x3620
-#define OV9740_ANALOG_CTRL21           0x3621
-#define OV9740_ANALOG_CTRL22           0x3622
-#define OV9740_ANALOG_CTRL30           0x3630
-#define OV9740_ANALOG_CTRL31           0x3631
-#define OV9740_ANALOG_CTRL32           0x3632
-#define OV9740_ANALOG_CTRL33           0x3633
-
-/* Sensor Control */
-#define OV9740_SENSOR_CTRL03           0x3703
-#define OV9740_SENSOR_CTRL04           0x3704
-#define OV9740_SENSOR_CTRL05           0x3705
-#define OV9740_SENSOR_CTRL07           0x3707
-
-/* Timing Control */
-#define OV9740_TIMING_CTRL17           0x3817
-#define OV9740_TIMING_CTRL19           0x3819
-#define OV9740_TIMING_CTRL33           0x3833
-#define OV9740_TIMING_CTRL35           0x3835
-
-/* Banding Filter */
-#define OV9740_AEC_MAXEXPO_60_H                0x3a02
-#define OV9740_AEC_MAXEXPO_60_L                0x3a03
-#define OV9740_AEC_B50_STEP_HI         0x3a08
-#define OV9740_AEC_B50_STEP_LO         0x3a09
-#define OV9740_AEC_B60_STEP_HI         0x3a0a
-#define OV9740_AEC_B60_STEP_LO         0x3a0b
-#define OV9740_AEC_CTRL0D              0x3a0d
-#define OV9740_AEC_CTRL0E              0x3a0e
-#define OV9740_AEC_MAXEXPO_50_H                0x3a14
-#define OV9740_AEC_MAXEXPO_50_L                0x3a15
-
-/* AEC/AGC Control */
-#define OV9740_AEC_ENABLE              0x3503
-#define OV9740_GAIN_CEILING_01         0x3a18
-#define OV9740_GAIN_CEILING_02         0x3a19
-#define OV9740_AEC_HI_THRESHOLD                0x3a11
-#define OV9740_AEC_3A1A                        0x3a1a
-#define OV9740_AEC_CTRL1B_WPT2         0x3a1b
-#define OV9740_AEC_CTRL0F_WPT          0x3a0f
-#define OV9740_AEC_CTRL10_BPT          0x3a10
-#define OV9740_AEC_CTRL1E_BPT2         0x3a1e
-#define OV9740_AEC_LO_THRESHOLD                0x3a1f
-
-/* BLC Control */
-#define OV9740_BLC_AUTO_ENABLE         0x4002
-#define OV9740_BLC_MODE                        0x4005
-
-/* VFIFO */
-#define OV9740_VFIFO_READ_START_HI     0x4608
-#define OV9740_VFIFO_READ_START_LO     0x4609
-
-/* DVP Control */
-#define OV9740_DVP_VSYNC_CTRL02                0x4702
-#define OV9740_DVP_VSYNC_MODE          0x4704
-#define OV9740_DVP_VSYNC_CTRL06                0x4706
-
-/* PLL Setting */
-#define OV9740_PLL_MODE_CTRL01         0x3104
-#define OV9740_PRE_PLL_CLK_DIV         0x0305
-#define OV9740_PLL_MULTIPLIER          0x0307
-#define OV9740_VT_SYS_CLK_DIV          0x0303
-#define OV9740_VT_PIX_CLK_DIV          0x0301
-#define OV9740_PLL_CTRL3010            0x3010
-#define OV9740_VFIFO_CTRL00            0x460e
-
-/* ISP Control */
-#define OV9740_ISP_CTRL00              0x5000
-#define OV9740_ISP_CTRL01              0x5001
-#define OV9740_ISP_CTRL03              0x5003
-#define OV9740_ISP_CTRL05              0x5005
-#define OV9740_ISP_CTRL12              0x5012
-#define OV9740_ISP_CTRL19              0x5019
-#define OV9740_ISP_CTRL1A              0x501a
-#define OV9740_ISP_CTRL1E              0x501e
-#define OV9740_ISP_CTRL1F              0x501f
-#define OV9740_ISP_CTRL20              0x5020
-#define OV9740_ISP_CTRL21              0x5021
-
-/* AWB */
-#define OV9740_AWB_CTRL00              0x5180
-#define OV9740_AWB_CTRL01              0x5181
-#define OV9740_AWB_CTRL02              0x5182
-#define OV9740_AWB_CTRL03              0x5183
-#define OV9740_AWB_ADV_CTRL01          0x5184
-#define OV9740_AWB_ADV_CTRL02          0x5185
-#define OV9740_AWB_ADV_CTRL03          0x5186
-#define OV9740_AWB_ADV_CTRL04          0x5187
-#define OV9740_AWB_ADV_CTRL05          0x5188
-#define OV9740_AWB_ADV_CTRL06          0x5189
-#define OV9740_AWB_ADV_CTRL07          0x518a
-#define OV9740_AWB_ADV_CTRL08          0x518b
-#define OV9740_AWB_ADV_CTRL09          0x518c
-#define OV9740_AWB_ADV_CTRL10          0x518d
-#define OV9740_AWB_ADV_CTRL11          0x518e
-#define OV9740_AWB_CTRL0F              0x518f
-#define OV9740_AWB_CTRL10              0x5190
-#define OV9740_AWB_CTRL11              0x5191
-#define OV9740_AWB_CTRL12              0x5192
-#define OV9740_AWB_CTRL13              0x5193
-#define OV9740_AWB_CTRL14              0x5194
-
-/* MIPI Control */
-#define OV9740_MIPI_CTRL00             0x4800
-#define OV9740_MIPI_3837               0x3837
-#define OV9740_MIPI_CTRL01             0x4801
-#define OV9740_MIPI_CTRL03             0x4803
-#define OV9740_MIPI_CTRL05             0x4805
-#define OV9740_VFIFO_RD_CTRL           0x4601
-#define OV9740_MIPI_CTRL_3012          0x3012
-#define OV9740_SC_CMMM_MIPI_CTR                0x3014
-
-#define OV9740_MAX_WIDTH               1280
-#define OV9740_MAX_HEIGHT              720
-
-/* Misc. structures */
-struct ov9740_reg {
-       u16                             reg;
-       u8                              val;
-};
-
-struct ov9740_priv {
-       struct v4l2_subdev              subdev;
-       struct v4l2_ctrl_handler        hdl;
-       struct v4l2_clk                 *clk;
-
-       u16                             model;
-       u8                              revision;
-       u8                              manid;
-       u8                              smiaver;
-
-       bool                            flag_vflip;
-       bool                            flag_hflip;
-
-       /* For suspend/resume. */
-       struct v4l2_mbus_framefmt       current_mf;
-       bool                            current_enable;
-};
-
-static const struct ov9740_reg ov9740_defaults[] = {
-       /* Software Reset */
-       { OV9740_SOFTWARE_RESET,        0x01 },
-
-       /* Banding Filter */
-       { OV9740_AEC_B50_STEP_HI,       0x00 },
-       { OV9740_AEC_B50_STEP_LO,       0xe8 },
-       { OV9740_AEC_CTRL0E,            0x03 },
-       { OV9740_AEC_MAXEXPO_50_H,      0x15 },
-       { OV9740_AEC_MAXEXPO_50_L,      0xc6 },
-       { OV9740_AEC_B60_STEP_HI,       0x00 },
-       { OV9740_AEC_B60_STEP_LO,       0xc0 },
-       { OV9740_AEC_CTRL0D,            0x04 },
-       { OV9740_AEC_MAXEXPO_60_H,      0x18 },
-       { OV9740_AEC_MAXEXPO_60_L,      0x20 },
-
-       /* LC */
-       { 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 },
-       { 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc },
-
-       /* Un-documented OV9740 registers */
-       { 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 },
-       { 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c },
-       { 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580a, 0x0e }, { 0x580b, 0x16 },
-       { 0x580c, 0x06 }, { 0x580d, 0x02 }, { 0x580e, 0x00 }, { 0x580f, 0x00 },
-       { 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 },
-       { 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 },
-       { 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581a, 0x07 }, { 0x581b, 0x08 },
-       { 0x581c, 0x0b }, { 0x581d, 0x14 }, { 0x581e, 0x28 }, { 0x581f, 0x23 },
-       { 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a },
-       { 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f },
-       { 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582a, 0x8f }, { 0x582b, 0x9e },
-       { 0x582c, 0x8f }, { 0x582d, 0x9f }, { 0x582e, 0x4f }, { 0x582f, 0x87 },
-       { 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f },
-       { 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf },
-       { 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583a, 0x9f }, { 0x583b, 0x7f },
-       { 0x583c, 0x5f },
-
-       /* Y Gamma */
-       { 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e },
-       { 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 },
-       { 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548a, 0xa4 }, { 0x548b, 0xb1 },
-       { 0x548c, 0xc6 }, { 0x548d, 0xd8 }, { 0x548e, 0xe9 },
-
-       /* UV Gamma */
-       { 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 },
-       { 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 },
-       { 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549a, 0x02 }, { 0x549b, 0xeb },
-       { 0x549c, 0x02 }, { 0x549d, 0xa0 }, { 0x549e, 0x02 }, { 0x549f, 0x67 },
-       { 0x54a0, 0x02 }, { 0x54a1, 0x3b }, { 0x54a2, 0x02 }, { 0x54a3, 0x18 },
-       { 0x54a4, 0x01 }, { 0x54a5, 0xe7 }, { 0x54a6, 0x01 }, { 0x54a7, 0xc3 },
-       { 0x54a8, 0x01 }, { 0x54a9, 0x94 }, { 0x54aa, 0x01 }, { 0x54ab, 0x72 },
-       { 0x54ac, 0x01 }, { 0x54ad, 0x57 },
-
-       /* AWB */
-       { OV9740_AWB_CTRL00,            0xf0 },
-       { OV9740_AWB_CTRL01,            0x00 },
-       { OV9740_AWB_CTRL02,            0x41 },
-       { OV9740_AWB_CTRL03,            0x42 },
-       { OV9740_AWB_ADV_CTRL01,        0x8a },
-       { OV9740_AWB_ADV_CTRL02,        0x61 },
-       { OV9740_AWB_ADV_CTRL03,        0xce },
-       { OV9740_AWB_ADV_CTRL04,        0xa8 },
-       { OV9740_AWB_ADV_CTRL05,        0x17 },
-       { OV9740_AWB_ADV_CTRL06,        0x1f },
-       { OV9740_AWB_ADV_CTRL07,        0x27 },
-       { OV9740_AWB_ADV_CTRL08,        0x41 },
-       { OV9740_AWB_ADV_CTRL09,        0x34 },
-       { OV9740_AWB_ADV_CTRL10,        0xf0 },
-       { OV9740_AWB_ADV_CTRL11,        0x10 },
-       { OV9740_AWB_CTRL0F,            0xff },
-       { OV9740_AWB_CTRL10,            0x00 },
-       { OV9740_AWB_CTRL11,            0xff },
-       { OV9740_AWB_CTRL12,            0x00 },
-       { OV9740_AWB_CTRL13,            0xff },
-       { OV9740_AWB_CTRL14,            0x00 },
-
-       /* CIP */
-       { 0x530d, 0x12 },
-
-       /* CMX */
-       { 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 },
-       { 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 },
-       { 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538a, 0x00 }, { 0x538b, 0x20 },
-       { 0x538c, 0x00 }, { 0x538d, 0x00 }, { 0x538e, 0x00 }, { 0x538f, 0x16 },
-       { 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 },
-       { 0x5394, 0x18 },
-
-       /* 50/60 Detection */
-       { 0x3c0a, 0x9c }, { 0x3c0b, 0x3f },
-
-       /* Output Select */
-       { OV9740_IO_OUTPUT_SEL01,       0x00 },
-       { OV9740_IO_OUTPUT_SEL02,       0x00 },
-       { OV9740_IO_CREL00,             0x00 },
-       { OV9740_IO_CREL01,             0x00 },
-       { OV9740_IO_CREL02,             0x00 },
-
-       /* AWB Control */
-       { OV9740_AWB_MANUAL_CTRL,       0x00 },
-
-       /* Analog Control */
-       { OV9740_ANALOG_CTRL03,         0xaa },
-       { OV9740_ANALOG_CTRL32,         0x2f },
-       { OV9740_ANALOG_CTRL20,         0x66 },
-       { OV9740_ANALOG_CTRL21,         0xc0 },
-       { OV9740_ANALOG_CTRL31,         0x52 },
-       { OV9740_ANALOG_CTRL33,         0x50 },
-       { OV9740_ANALOG_CTRL30,         0xca },
-       { OV9740_ANALOG_CTRL04,         0x0c },
-       { OV9740_ANALOG_CTRL01,         0x40 },
-       { OV9740_ANALOG_CTRL02,         0x16 },
-       { OV9740_ANALOG_CTRL10,         0xa1 },
-       { OV9740_ANALOG_CTRL12,         0x24 },
-       { OV9740_ANALOG_CTRL22,         0x9f },
-       { OV9740_ANALOG_CTRL15,         0xf0 },
-
-       /* Sensor Control */
-       { OV9740_SENSOR_CTRL03,         0x42 },
-       { OV9740_SENSOR_CTRL04,         0x10 },
-       { OV9740_SENSOR_CTRL05,         0x45 },
-       { OV9740_SENSOR_CTRL07,         0x14 },
-
-       /* Timing Control */
-       { OV9740_TIMING_CTRL33,         0x04 },
-       { OV9740_TIMING_CTRL35,         0x02 },
-       { OV9740_TIMING_CTRL19,         0x6e },
-       { OV9740_TIMING_CTRL17,         0x94 },
-
-       /* AEC/AGC Control */
-       { OV9740_AEC_ENABLE,            0x10 },
-       { OV9740_GAIN_CEILING_01,       0x00 },
-       { OV9740_GAIN_CEILING_02,       0x7f },
-       { OV9740_AEC_HI_THRESHOLD,      0xa0 },
-       { OV9740_AEC_3A1A,              0x05 },
-       { OV9740_AEC_CTRL1B_WPT2,       0x50 },
-       { OV9740_AEC_CTRL0F_WPT,        0x50 },
-       { OV9740_AEC_CTRL10_BPT,        0x4c },
-       { OV9740_AEC_CTRL1E_BPT2,       0x4c },
-       { OV9740_AEC_LO_THRESHOLD,      0x26 },
-
-       /* BLC Control */
-       { OV9740_BLC_AUTO_ENABLE,       0x45 },
-       { OV9740_BLC_MODE,              0x18 },
-
-       /* DVP Control */
-       { OV9740_DVP_VSYNC_CTRL02,      0x04 },
-       { OV9740_DVP_VSYNC_MODE,        0x00 },
-       { OV9740_DVP_VSYNC_CTRL06,      0x08 },
-
-       /* PLL Setting */
-       { OV9740_PLL_MODE_CTRL01,       0x20 },
-       { OV9740_PRE_PLL_CLK_DIV,       0x03 },
-       { OV9740_PLL_MULTIPLIER,        0x4c },
-       { OV9740_VT_SYS_CLK_DIV,        0x01 },
-       { OV9740_VT_PIX_CLK_DIV,        0x08 },
-       { OV9740_PLL_CTRL3010,          0x01 },
-       { OV9740_VFIFO_CTRL00,          0x82 },
-
-       /* Timing Setting */
-       /* VTS */
-       { OV9740_FRM_LENGTH_LN_HI,      0x03 },
-       { OV9740_FRM_LENGTH_LN_LO,      0x07 },
-       /* HTS */
-       { OV9740_LN_LENGTH_PCK_HI,      0x06 },
-       { OV9740_LN_LENGTH_PCK_LO,      0x62 },
-
-       /* MIPI Control */
-       { OV9740_MIPI_CTRL00,           0x44 }, /* 0x64 for discontinuous clk */
-       { OV9740_MIPI_3837,             0x01 },
-       { OV9740_MIPI_CTRL01,           0x0f },
-       { OV9740_MIPI_CTRL03,           0x05 },
-       { OV9740_MIPI_CTRL05,           0x10 },
-       { OV9740_VFIFO_RD_CTRL,         0x16 },
-       { OV9740_MIPI_CTRL_3012,        0x70 },
-       { OV9740_SC_CMMM_MIPI_CTR,      0x01 },
-
-       /* YUYV order */
-       { OV9740_ISP_CTRL19,            0x02 },
-};
-
-static u32 ov9740_codes[] = {
-       MEDIA_BUS_FMT_YUYV8_2X8,
-};
-
-/* read a register */
-static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
-{
-       int ret;
-       struct i2c_msg msg[] = {
-               {
-                       .addr   = client->addr,
-                       .flags  = 0,
-                       .len    = 2,
-                       .buf    = (u8 *)&reg,
-               },
-               {
-                       .addr   = client->addr,
-                       .flags  = I2C_M_RD,
-                       .len    = 1,
-                       .buf    = val,
-               },
-       };
-
-       reg = swab16(reg);
-
-       ret = i2c_transfer(client->adapter, msg, 2);
-       if (ret < 0) {
-               dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg);
-               return ret;
-       }
-
-       return 0;
-}
-
-/* write a register */
-static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val)
-{
-       struct i2c_msg msg;
-       struct {
-               u16 reg;
-               u8 val;
-       } __packed buf;
-       int ret;
-
-       reg = swab16(reg);
-
-       buf.reg = reg;
-       buf.val = val;
-
-       msg.addr        = client->addr;
-       msg.flags       = 0;
-       msg.len         = 3;
-       msg.buf         = (u8 *)&buf;
-
-       ret = i2c_transfer(client->adapter, &msg, 1);
-       if (ret < 0) {
-               dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg);
-               return ret;
-       }
-
-       return 0;
-}
-
-
-/* Read a register, alter its bits, write it back */
-static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset)
-{
-       u8 val;
-       int ret;
-
-       ret = ov9740_reg_read(client, reg, &val);
-       if (ret < 0) {
-               dev_err(&client->dev,
-                       "[Read]-Modify-Write of register 0x%04x failed!\n",
-                       reg);
-               return ret;
-       }
-
-       val |= set;
-       val &= ~unset;
-
-       ret = ov9740_reg_write(client, reg, val);
-       if (ret < 0) {
-               dev_err(&client->dev,
-                       "Read-Modify-[Write] of register 0x%04x failed!\n",
-                       reg);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int ov9740_reg_write_array(struct i2c_client *client,
-                                 const struct ov9740_reg *regarray,
-                                 int regarraylen)
-{
-       int i;
-       int ret;
-
-       for (i = 0; i < regarraylen; i++) {
-               ret = ov9740_reg_write(client,
-                                      regarray[i].reg, regarray[i].val);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-
-/* Start/Stop streaming from the device */
-static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov9740_priv *priv = to_ov9740(sd);
-       int ret;
-
-       /* Program orientation register. */
-       if (priv->flag_vflip)
-               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0);
-       else
-               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2);
-       if (ret < 0)
-               return ret;
-
-       if (priv->flag_hflip)
-               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0);
-       else
-               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1);
-       if (ret < 0)
-               return ret;
-
-       if (enable) {
-               dev_dbg(&client->dev, "Enabling Streaming\n");
-               /* Start Streaming */
-               ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01);
-
-       } else {
-               dev_dbg(&client->dev, "Disabling Streaming\n");
-               /* Software Reset */
-               ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01);
-               if (!ret)
-                       /* Setting Streaming to Standby */
-                       ret = ov9740_reg_write(client, OV9740_MODE_SELECT,
-                                              0x00);
-       }
-
-       priv->current_enable = enable;
-
-       return ret;
-}
-
-/* select nearest higher resolution for capture */
-static void ov9740_res_roundup(u32 *width, u32 *height)
-{
-       /* Width must be a multiple of 4 pixels. */
-       *width = ALIGN(*width, 4);
-
-       /* Max resolution is 1280x720 (720p). */
-       if (*width > OV9740_MAX_WIDTH)
-               *width = OV9740_MAX_WIDTH;
-
-       if (*height > OV9740_MAX_HEIGHT)
-               *height = OV9740_MAX_HEIGHT;
-}
-
-/* Setup registers according to resolution and color encoding */
-static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
-{
-       u32 x_start;
-       u32 y_start;
-       u32 x_end;
-       u32 y_end;
-       bool scaling = false;
-       u32 scale_input_x;
-       u32 scale_input_y;
-       int ret;
-
-       if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
-               scaling = true;
-
-       /*
-        * Try to use as much of the sensor area as possible when supporting
-        * smaller resolutions.  Depending on the aspect ratio of the
-        * chosen resolution, we can either use the full width of the sensor,
-        * or the full height of the sensor (or both if the aspect ratio is
-        * the same as 1280x720.
-        */
-       if ((OV9740_MAX_WIDTH * height) > (OV9740_MAX_HEIGHT * width)) {
-               scale_input_x = (OV9740_MAX_HEIGHT * width) / height;
-               scale_input_y = OV9740_MAX_HEIGHT;
-       } else {
-               scale_input_x = OV9740_MAX_WIDTH;
-               scale_input_y = (OV9740_MAX_WIDTH * height) / width;
-       }
-
-       /* These describe the area of the sensor to use. */
-       x_start = (OV9740_MAX_WIDTH - scale_input_x) / 2;
-       y_start = (OV9740_MAX_HEIGHT - scale_input_y) / 2;
-       x_end = x_start + scale_input_x - 1;
-       y_end = y_start + scale_input_y - 1;
-
-       ret = ov9740_reg_write(client, OV9740_X_ADDR_START_HI, x_start >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_X_ADDR_START_LO, x_start & 0xff);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_HI, y_start >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_LO, y_start & 0xff);
-       if (ret)
-               goto done;
-
-       ret = ov9740_reg_write(client, OV9740_X_ADDR_END_HI, x_end >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_X_ADDR_END_LO, x_end & 0xff);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_HI, y_end >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_LO, y_end & 0xff);
-       if (ret)
-               goto done;
-
-       ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_HI, width >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_LO, width & 0xff);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_HI, height >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_LO, height & 0xff);
-       if (ret)
-               goto done;
-
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL1E, scale_input_x >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL1F, scale_input_x & 0xff);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL20, scale_input_y >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL21, scale_input_y & 0xff);
-       if (ret)
-               goto done;
-
-       ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_HI,
-                              (scale_input_x - width) >> 8);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_LO,
-                              (scale_input_x - width) & 0xff);
-       if (ret)
-               goto done;
-
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL00, 0xff);
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL01, 0xef |
-                                                         (scaling << 4));
-       if (ret)
-               goto done;
-       ret = ov9740_reg_write(client, OV9740_ISP_CTRL03, 0xff);
-
-done:
-       return ret;
-}
-
-/* set the format we will capture in */
-static int ov9740_s_fmt(struct v4l2_subdev *sd,
-                       struct v4l2_mbus_framefmt *mf)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov9740_priv *priv = to_ov9740(sd);
-       int ret;
-
-       ret = ov9740_reg_write_array(client, ov9740_defaults,
-                                    ARRAY_SIZE(ov9740_defaults));
-       if (ret < 0)
-               return ret;
-
-       ret = ov9740_set_res(client, mf->width, mf->height);
-       if (ret < 0)
-               return ret;
-
-       priv->current_mf = *mf;
-       return ret;
-}
-
-static int ov9740_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-
-       if (format->pad)
-               return -EINVAL;
-
-       ov9740_res_roundup(&mf->width, &mf->height);
-
-       mf->field = V4L2_FIELD_NONE;
-       mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
-       mf->colorspace = V4L2_COLORSPACE_SRGB;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               return ov9740_s_fmt(sd, mf);
-       cfg->try_fmt = *mf;
-       return 0;
-}
-
-static int ov9740_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index >= ARRAY_SIZE(ov9740_codes))
-               return -EINVAL;
-
-       code->code = ov9740_codes[code->index];
-
-       return 0;
-}
-
-static int ov9740_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-       case V4L2_SEL_TGT_CROP:
-               sel->r.left = 0;
-               sel->r.top = 0;
-               sel->r.width = OV9740_MAX_WIDTH;
-               sel->r.height = OV9740_MAX_HEIGHT;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-/* Set status of additional camera capabilities */
-static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct ov9740_priv *priv =
-               container_of(ctrl->handler, struct ov9740_priv, hdl);
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               priv->flag_vflip = ctrl->val;
-               break;
-       case V4L2_CID_HFLIP:
-               priv->flag_hflip = ctrl->val;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int ov9740_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct ov9740_priv *priv = to_ov9740(sd);
-       int ret;
-
-       if (on) {
-               ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
-               if (ret < 0)
-                       return ret;
-
-               if (priv->current_enable) {
-                       ov9740_s_fmt(sd, &priv->current_mf);
-                       ov9740_s_stream(sd, 1);
-               }
-       } else {
-               if (priv->current_enable) {
-                       ov9740_s_stream(sd, 0);
-                       priv->current_enable = true;
-               }
-
-               soc_camera_power_off(&client->dev, ssdd, priv->clk);
-       }
-
-       return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov9740_get_register(struct v4l2_subdev *sd,
-                              struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
-       u8 val;
-
-       if (reg->reg & ~0xffff)
-               return -EINVAL;
-
-       reg->size = 2;
-
-       ret = ov9740_reg_read(client, reg->reg, &val);
-       if (ret)
-               return ret;
-
-       reg->val = (__u64)val;
-
-       return ret;
-}
-
-static int ov9740_set_register(struct v4l2_subdev *sd,
-                              const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg & ~0xffff || reg->val & ~0xff)
-               return -EINVAL;
-
-       return ov9740_reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov9740_video_probe(struct i2c_client *client)
-{
-       struct v4l2_subdev *sd = i2c_get_clientdata(client);
-       struct ov9740_priv *priv = to_ov9740(sd);
-       u8 modelhi, modello;
-       int ret;
-
-       ret = ov9740_s_power(&priv->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * check and show product ID and manufacturer ID
-        */
-       ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
-       if (ret < 0)
-               goto done;
-
-       ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
-       if (ret < 0)
-               goto done;
-
-       priv->model = (modelhi << 8) | modello;
-
-       ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
-       if (ret < 0)
-               goto done;
-
-       ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
-       if (ret < 0)
-               goto done;
-
-       ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
-       if (ret < 0)
-               goto done;
-
-       if (priv->model != 0x9740) {
-               ret = -ENODEV;
-               goto done;
-       }
-
-       dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, Manufacturer 0x%02x, SMIA Version 0x%02x\n",
-                priv->model, priv->revision, priv->manid, priv->smiaver);
-
-       ret = v4l2_ctrl_handler_setup(&priv->hdl);
-
-done:
-       ov9740_s_power(&priv->subdev, 0);
-       return ret;
-}
-
-/* Request bus settings on camera side */
-static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
-               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops ov9740_video_ops = {
-       .s_stream       = ov9740_s_stream,
-       .g_mbus_config  = ov9740_g_mbus_config,
-};
-
-static const struct v4l2_subdev_core_ops ov9740_core_ops = {
-       .s_power                = ov9740_s_power,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register             = ov9740_get_register,
-       .s_register             = ov9740_set_register,
-#endif
-};
-
-static const struct v4l2_subdev_pad_ops ov9740_pad_ops = {
-       .enum_mbus_code = ov9740_enum_mbus_code,
-       .get_selection  = ov9740_get_selection,
-       .set_fmt        = ov9740_set_fmt,
-};
-
-static const struct v4l2_subdev_ops ov9740_subdev_ops = {
-       .core   = &ov9740_core_ops,
-       .video  = &ov9740_video_ops,
-       .pad    = &ov9740_pad_ops,
-};
-
-static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
-       .s_ctrl = ov9740_s_ctrl,
-};
-
-/*
- * i2c_driver function
- */
-static int ov9740_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-{
-       struct ov9740_priv *priv;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       int ret;
-
-       if (!ssdd) {
-               dev_err(&client->dev, "Missing platform_data for driver\n");
-               return -EINVAL;
-       }
-
-       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
-       v4l2_ctrl_handler_init(&priv->hdl, 13);
-       v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
-                       V4L2_CID_VFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
-                       V4L2_CID_HFLIP, 0, 1, 1, 0);
-       priv->subdev.ctrl_handler = &priv->hdl;
-       if (priv->hdl.error)
-               return priv->hdl.error;
-
-       priv->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(priv->clk)) {
-               ret = PTR_ERR(priv->clk);
-               goto eclkget;
-       }
-
-       ret = ov9740_video_probe(client);
-       if (ret < 0) {
-               v4l2_clk_put(priv->clk);
-eclkget:
-               v4l2_ctrl_handler_free(&priv->hdl);
-       }
-
-       return ret;
-}
-
-static int ov9740_remove(struct i2c_client *client)
-{
-       struct ov9740_priv *priv = i2c_get_clientdata(client);
-
-       v4l2_clk_put(priv->clk);
-       v4l2_device_unregister_subdev(&priv->subdev);
-       v4l2_ctrl_handler_free(&priv->hdl);
-       return 0;
-}
-
-static const struct i2c_device_id ov9740_id[] = {
-       { "ov9740", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, ov9740_id);
-
-static struct i2c_driver ov9740_i2c_driver = {
-       .driver = {
-               .name = "ov9740",
-       },
-       .probe    = ov9740_probe,
-       .remove   = ov9740_remove,
-       .id_table = ov9740_id,
-};
-
-module_i2c_driver(ov9740_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
-MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
deleted file mode 100644 (file)
index 02398d0..0000000
+++ /dev/null
@@ -1,1416 +0,0 @@
-/*
- * Driver for RJ54N1CB0C CMOS Image Sensor from Sharp
- *
- * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-#include <linux/module.h>
-
-#include <media/i2c/rj54n1cb0c.h>
-#include <media/soc_camera.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-subdev.h>
-#include <media/v4l2-ctrls.h>
-
-#define RJ54N1_DEV_CODE                        0x0400
-#define RJ54N1_DEV_CODE2               0x0401
-#define RJ54N1_OUT_SEL                 0x0403
-#define RJ54N1_XY_OUTPUT_SIZE_S_H      0x0404
-#define RJ54N1_X_OUTPUT_SIZE_S_L       0x0405
-#define RJ54N1_Y_OUTPUT_SIZE_S_L       0x0406
-#define RJ54N1_XY_OUTPUT_SIZE_P_H      0x0407
-#define RJ54N1_X_OUTPUT_SIZE_P_L       0x0408
-#define RJ54N1_Y_OUTPUT_SIZE_P_L       0x0409
-#define RJ54N1_LINE_LENGTH_PCK_S_H     0x040a
-#define RJ54N1_LINE_LENGTH_PCK_S_L     0x040b
-#define RJ54N1_LINE_LENGTH_PCK_P_H     0x040c
-#define RJ54N1_LINE_LENGTH_PCK_P_L     0x040d
-#define RJ54N1_RESIZE_N                        0x040e
-#define RJ54N1_RESIZE_N_STEP           0x040f
-#define RJ54N1_RESIZE_STEP             0x0410
-#define RJ54N1_RESIZE_HOLD_H           0x0411
-#define RJ54N1_RESIZE_HOLD_L           0x0412
-#define RJ54N1_H_OBEN_OFS              0x0413
-#define RJ54N1_V_OBEN_OFS              0x0414
-#define RJ54N1_RESIZE_CONTROL          0x0415
-#define RJ54N1_STILL_CONTROL           0x0417
-#define RJ54N1_INC_USE_SEL_H           0x0425
-#define RJ54N1_INC_USE_SEL_L           0x0426
-#define RJ54N1_MIRROR_STILL_MODE       0x0427
-#define RJ54N1_INIT_START              0x0428
-#define RJ54N1_SCALE_1_2_LEV           0x0429
-#define RJ54N1_SCALE_4_LEV             0x042a
-#define RJ54N1_Y_GAIN                  0x04d8
-#define RJ54N1_APT_GAIN_UP             0x04fa
-#define RJ54N1_RA_SEL_UL               0x0530
-#define RJ54N1_BYTE_SWAP               0x0531
-#define RJ54N1_OUT_SIGPO               0x053b
-#define RJ54N1_WB_SEL_WEIGHT_I         0x054e
-#define RJ54N1_BIT8_WB                 0x0569
-#define RJ54N1_HCAPS_WB                        0x056a
-#define RJ54N1_VCAPS_WB                        0x056b
-#define RJ54N1_HCAPE_WB                        0x056c
-#define RJ54N1_VCAPE_WB                        0x056d
-#define RJ54N1_EXPOSURE_CONTROL                0x058c
-#define RJ54N1_FRAME_LENGTH_S_H                0x0595
-#define RJ54N1_FRAME_LENGTH_S_L                0x0596
-#define RJ54N1_FRAME_LENGTH_P_H                0x0597
-#define RJ54N1_FRAME_LENGTH_P_L                0x0598
-#define RJ54N1_PEAK_H                  0x05b7
-#define RJ54N1_PEAK_50                 0x05b8
-#define RJ54N1_PEAK_60                 0x05b9
-#define RJ54N1_PEAK_DIFF               0x05ba
-#define RJ54N1_IOC                     0x05ef
-#define RJ54N1_TG_BYPASS               0x0700
-#define RJ54N1_PLL_L                   0x0701
-#define RJ54N1_PLL_N                   0x0702
-#define RJ54N1_PLL_EN                  0x0704
-#define RJ54N1_RATIO_TG                        0x0706
-#define RJ54N1_RATIO_T                 0x0707
-#define RJ54N1_RATIO_R                 0x0708
-#define RJ54N1_RAMP_TGCLK_EN           0x0709
-#define RJ54N1_OCLK_DSP                        0x0710
-#define RJ54N1_RATIO_OP                        0x0711
-#define RJ54N1_RATIO_O                 0x0712
-#define RJ54N1_OCLK_SEL_EN             0x0713
-#define RJ54N1_CLK_RST                 0x0717
-#define RJ54N1_RESET_STANDBY           0x0718
-#define RJ54N1_FWFLG                   0x07fe
-
-#define E_EXCLK                                (1 << 7)
-#define SOFT_STDBY                     (1 << 4)
-#define SEN_RSTX                       (1 << 2)
-#define TG_RSTX                                (1 << 1)
-#define DSP_RSTX                       (1 << 0)
-
-#define RESIZE_HOLD_SEL                        (1 << 2)
-#define RESIZE_GO                      (1 << 1)
-
-/*
- * When cropping, the camera automatically centers the cropped region, there
- * doesn't seem to be a way to specify an explicit location of the rectangle.
- */
-#define RJ54N1_COLUMN_SKIP             0
-#define RJ54N1_ROW_SKIP                        0
-#define RJ54N1_MAX_WIDTH               1600
-#define RJ54N1_MAX_HEIGHT              1200
-
-#define PLL_L                          2
-#define PLL_N                          0x31
-
-/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
-
-/* RJ54N1CB0C has only one fixed colorspace per pixelcode */
-struct rj54n1_datafmt {
-       u32     code;
-       enum v4l2_colorspace            colorspace;
-};
-
-/* Find a data format by a pixel code in an array */
-static const struct rj54n1_datafmt *rj54n1_find_datafmt(
-       u32 code, const struct rj54n1_datafmt *fmt,
-       int n)
-{
-       int i;
-       for (i = 0; i < n; i++)
-               if (fmt[i].code == code)
-                       return fmt + i;
-
-       return NULL;
-}
-
-static const struct rj54n1_datafmt rj54n1_colour_fmts[] = {
-       {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
-       {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG},
-       {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB},
-       {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
-};
-
-struct rj54n1_clock_div {
-       u8 ratio_tg;    /* can be 0 or an odd number */
-       u8 ratio_t;
-       u8 ratio_r;
-       u8 ratio_op;
-       u8 ratio_o;
-};
-
-struct rj54n1 {
-       struct v4l2_subdev subdev;
-       struct v4l2_ctrl_handler hdl;
-       struct v4l2_clk *clk;
-       struct rj54n1_clock_div clk_div;
-       const struct rj54n1_datafmt *fmt;
-       struct v4l2_rect rect;  /* Sensor window */
-       unsigned int tgclk_mhz;
-       bool auto_wb;
-       unsigned short width;   /* Output window */
-       unsigned short height;
-       unsigned short resize;  /* Sensor * 1024 / resize = Output */
-       unsigned short scale;
-       u8 bank;
-};
-
-struct rj54n1_reg_val {
-       u16 reg;
-       u8 val;
-};
-
-static const struct rj54n1_reg_val bank_4[] = {
-       {0x417, 0},
-       {0x42c, 0},
-       {0x42d, 0xf0},
-       {0x42e, 0},
-       {0x42f, 0x50},
-       {0x430, 0xf5},
-       {0x431, 0x16},
-       {0x432, 0x20},
-       {0x433, 0},
-       {0x434, 0xc8},
-       {0x43c, 8},
-       {0x43e, 0x90},
-       {0x445, 0x83},
-       {0x4ba, 0x58},
-       {0x4bb, 4},
-       {0x4bc, 0x20},
-       {0x4db, 4},
-       {0x4fe, 2},
-};
-
-static const struct rj54n1_reg_val bank_5[] = {
-       {0x514, 0},
-       {0x516, 0},
-       {0x518, 0},
-       {0x51a, 0},
-       {0x51d, 0xff},
-       {0x56f, 0x28},
-       {0x575, 0x40},
-       {0x5bc, 0x48},
-       {0x5c1, 6},
-       {0x5e5, 0x11},
-       {0x5e6, 0x43},
-       {0x5e7, 0x33},
-       {0x5e8, 0x21},
-       {0x5e9, 0x30},
-       {0x5ea, 0x0},
-       {0x5eb, 0xa5},
-       {0x5ec, 0xff},
-       {0x5fe, 2},
-};
-
-static const struct rj54n1_reg_val bank_7[] = {
-       {0x70a, 0},
-       {0x714, 0xff},
-       {0x715, 0xff},
-       {0x716, 0x1f},
-       {0x7FE, 2},
-};
-
-static const struct rj54n1_reg_val bank_8[] = {
-       {0x800, 0x00},
-       {0x801, 0x01},
-       {0x802, 0x61},
-       {0x805, 0x00},
-       {0x806, 0x00},
-       {0x807, 0x00},
-       {0x808, 0x00},
-       {0x809, 0x01},
-       {0x80A, 0x61},
-       {0x80B, 0x00},
-       {0x80C, 0x01},
-       {0x80D, 0x00},
-       {0x80E, 0x00},
-       {0x80F, 0x00},
-       {0x810, 0x00},
-       {0x811, 0x01},
-       {0x812, 0x61},
-       {0x813, 0x00},
-       {0x814, 0x11},
-       {0x815, 0x00},
-       {0x816, 0x41},
-       {0x817, 0x00},
-       {0x818, 0x51},
-       {0x819, 0x01},
-       {0x81A, 0x1F},
-       {0x81B, 0x00},
-       {0x81C, 0x01},
-       {0x81D, 0x00},
-       {0x81E, 0x11},
-       {0x81F, 0x00},
-       {0x820, 0x41},
-       {0x821, 0x00},
-       {0x822, 0x51},
-       {0x823, 0x00},
-       {0x824, 0x00},
-       {0x825, 0x00},
-       {0x826, 0x47},
-       {0x827, 0x01},
-       {0x828, 0x4F},
-       {0x829, 0x00},
-       {0x82A, 0x00},
-       {0x82B, 0x00},
-       {0x82C, 0x30},
-       {0x82D, 0x00},
-       {0x82E, 0x40},
-       {0x82F, 0x00},
-       {0x830, 0xB3},
-       {0x831, 0x00},
-       {0x832, 0xE3},
-       {0x833, 0x00},
-       {0x834, 0x00},
-       {0x835, 0x00},
-       {0x836, 0x00},
-       {0x837, 0x00},
-       {0x838, 0x00},
-       {0x839, 0x01},
-       {0x83A, 0x61},
-       {0x83B, 0x00},
-       {0x83C, 0x01},
-       {0x83D, 0x00},
-       {0x83E, 0x00},
-       {0x83F, 0x00},
-       {0x840, 0x00},
-       {0x841, 0x01},
-       {0x842, 0x61},
-       {0x843, 0x00},
-       {0x844, 0x1D},
-       {0x845, 0x00},
-       {0x846, 0x00},
-       {0x847, 0x00},
-       {0x848, 0x00},
-       {0x849, 0x01},
-       {0x84A, 0x1F},
-       {0x84B, 0x00},
-       {0x84C, 0x05},
-       {0x84D, 0x00},
-       {0x84E, 0x19},
-       {0x84F, 0x01},
-       {0x850, 0x21},
-       {0x851, 0x01},
-       {0x852, 0x5D},
-       {0x853, 0x00},
-       {0x854, 0x00},
-       {0x855, 0x00},
-       {0x856, 0x19},
-       {0x857, 0x01},
-       {0x858, 0x21},
-       {0x859, 0x00},
-       {0x85A, 0x00},
-       {0x85B, 0x00},
-       {0x85C, 0x00},
-       {0x85D, 0x00},
-       {0x85E, 0x00},
-       {0x85F, 0x00},
-       {0x860, 0xB3},
-       {0x861, 0x00},
-       {0x862, 0xE3},
-       {0x863, 0x00},
-       {0x864, 0x00},
-       {0x865, 0x00},
-       {0x866, 0x00},
-       {0x867, 0x00},
-       {0x868, 0x00},
-       {0x869, 0xE2},
-       {0x86A, 0x00},
-       {0x86B, 0x01},
-       {0x86C, 0x06},
-       {0x86D, 0x00},
-       {0x86E, 0x00},
-       {0x86F, 0x00},
-       {0x870, 0x60},
-       {0x871, 0x8C},
-       {0x872, 0x10},
-       {0x873, 0x00},
-       {0x874, 0xE0},
-       {0x875, 0x00},
-       {0x876, 0x27},
-       {0x877, 0x01},
-       {0x878, 0x00},
-       {0x879, 0x00},
-       {0x87A, 0x00},
-       {0x87B, 0x03},
-       {0x87C, 0x00},
-       {0x87D, 0x00},
-       {0x87E, 0x00},
-       {0x87F, 0x00},
-       {0x880, 0x00},
-       {0x881, 0x00},
-       {0x882, 0x00},
-       {0x883, 0x00},
-       {0x884, 0x00},
-       {0x885, 0x00},
-       {0x886, 0xF8},
-       {0x887, 0x00},
-       {0x888, 0x03},
-       {0x889, 0x00},
-       {0x88A, 0x64},
-       {0x88B, 0x00},
-       {0x88C, 0x03},
-       {0x88D, 0x00},
-       {0x88E, 0xB1},
-       {0x88F, 0x00},
-       {0x890, 0x03},
-       {0x891, 0x01},
-       {0x892, 0x1D},
-       {0x893, 0x00},
-       {0x894, 0x03},
-       {0x895, 0x01},
-       {0x896, 0x4B},
-       {0x897, 0x00},
-       {0x898, 0xE5},
-       {0x899, 0x00},
-       {0x89A, 0x01},
-       {0x89B, 0x00},
-       {0x89C, 0x01},
-       {0x89D, 0x04},
-       {0x89E, 0xC8},
-       {0x89F, 0x00},
-       {0x8A0, 0x01},
-       {0x8A1, 0x01},
-       {0x8A2, 0x61},
-       {0x8A3, 0x00},
-       {0x8A4, 0x01},
-       {0x8A5, 0x00},
-       {0x8A6, 0x00},
-       {0x8A7, 0x00},
-       {0x8A8, 0x00},
-       {0x8A9, 0x00},
-       {0x8AA, 0x7F},
-       {0x8AB, 0x03},
-       {0x8AC, 0x00},
-       {0x8AD, 0x00},
-       {0x8AE, 0x00},
-       {0x8AF, 0x00},
-       {0x8B0, 0x00},
-       {0x8B1, 0x00},
-       {0x8B6, 0x00},
-       {0x8B7, 0x01},
-       {0x8B8, 0x00},
-       {0x8B9, 0x00},
-       {0x8BA, 0x02},
-       {0x8BB, 0x00},
-       {0x8BC, 0xFF},
-       {0x8BD, 0x00},
-       {0x8FE, 2},
-};
-
-static const struct rj54n1_reg_val bank_10[] = {
-       {0x10bf, 0x69}
-};
-
-/* Clock dividers - these are default register values, divider = register + 1 */
-static const struct rj54n1_clock_div clk_div = {
-       .ratio_tg       = 3 /* default: 5 */,
-       .ratio_t        = 4 /* default: 1 */,
-       .ratio_r        = 4 /* default: 0 */,
-       .ratio_op       = 1 /* default: 5 */,
-       .ratio_o        = 9 /* default: 0 */,
-};
-
-static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
-{
-       return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
-}
-
-static int reg_read(struct i2c_client *client, const u16 reg)
-{
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       int ret;
-
-       /* set bank */
-       if (rj54n1->bank != reg >> 8) {
-               dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
-               ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
-               if (ret < 0)
-                       return ret;
-               rj54n1->bank = reg >> 8;
-       }
-       return i2c_smbus_read_byte_data(client, reg & 0xff);
-}
-
-static int reg_write(struct i2c_client *client, const u16 reg,
-                    const u8 data)
-{
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       int ret;
-
-       /* set bank */
-       if (rj54n1->bank != reg >> 8) {
-               dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
-               ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
-               if (ret < 0)
-                       return ret;
-               rj54n1->bank = reg >> 8;
-       }
-       dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
-       return i2c_smbus_write_byte_data(client, reg & 0xff, data);
-}
-
-static int reg_set(struct i2c_client *client, const u16 reg,
-                  const u8 data, const u8 mask)
-{
-       int ret;
-
-       ret = reg_read(client, reg);
-       if (ret < 0)
-               return ret;
-       return reg_write(client, reg, (ret & ~mask) | (data & mask));
-}
-
-static int reg_write_multiple(struct i2c_client *client,
-                             const struct rj54n1_reg_val *rv, const int n)
-{
-       int i, ret;
-
-       for (i = 0; i < n; i++) {
-               ret = reg_write(client, rv->reg, rv->val);
-               if (ret < 0)
-                       return ret;
-               rv++;
-       }
-
-       return 0;
-}
-
-static int rj54n1_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index >= ARRAY_SIZE(rj54n1_colour_fmts))
-               return -EINVAL;
-
-       code->code = rj54n1_colour_fmts[code->index].code;
-       return 0;
-}
-
-static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       /* Switch between preview and still shot modes */
-       return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
-}
-
-static int rj54n1_set_rect(struct i2c_client *client,
-                          u16 reg_x, u16 reg_y, u16 reg_xy,
-                          u32 width, u32 height)
-{
-       int ret;
-
-       ret = reg_write(client, reg_xy,
-                       ((width >> 4) & 0x70) |
-                       ((height >> 8) & 7));
-
-       if (!ret)
-               ret = reg_write(client, reg_x, width & 0xff);
-       if (!ret)
-               ret = reg_write(client, reg_y, height & 0xff);
-
-       return ret;
-}
-
-/*
- * Some commands, specifically certain initialisation sequences, require
- * a commit operation.
- */
-static int rj54n1_commit(struct i2c_client *client)
-{
-       int ret = reg_write(client, RJ54N1_INIT_START, 1);
-       msleep(10);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_INIT_START, 0);
-       return ret;
-}
-
-static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
-                              s32 *out_w, s32 *out_h);
-
-static int rj54n1_set_selection(struct v4l2_subdev *sd,
-                               struct v4l2_subdev_pad_config *cfg,
-                               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       const struct v4l2_rect *rect = &sel->r;
-       int dummy = 0, output_w, output_h,
-               input_w = rect->width, input_h = rect->height;
-       int ret;
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       /* arbitrary minimum width and height, edges unimportant */
-       soc_camera_limit_side(&dummy, &input_w,
-                    RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH);
-
-       soc_camera_limit_side(&dummy, &input_h,
-                    RJ54N1_ROW_SKIP, 8, RJ54N1_MAX_HEIGHT);
-
-       output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize;
-       output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize;
-
-       dev_dbg(&client->dev, "Scaling for %dx%d : %u = %dx%d\n",
-               input_w, input_h, rj54n1->resize, output_w, output_h);
-
-       ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
-       if (ret < 0)
-               return ret;
-
-       rj54n1->width           = output_w;
-       rj54n1->height          = output_h;
-       rj54n1->resize          = ret;
-       rj54n1->rect.width      = input_w;
-       rj54n1->rect.height     = input_h;
-
-       return 0;
-}
-
-static int rj54n1_get_selection(struct v4l2_subdev *sd,
-                               struct v4l2_subdev_pad_config *cfg,
-                               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.left = RJ54N1_COLUMN_SKIP;
-               sel->r.top = RJ54N1_ROW_SKIP;
-               sel->r.width = RJ54N1_MAX_WIDTH;
-               sel->r.height = RJ54N1_MAX_HEIGHT;
-               return 0;
-       case V4L2_SEL_TGT_CROP:
-               sel->r = rj54n1->rect;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static int rj54n1_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-
-       if (format->pad)
-               return -EINVAL;
-
-       mf->code        = rj54n1->fmt->code;
-       mf->colorspace  = rj54n1->fmt->colorspace;
-       mf->field       = V4L2_FIELD_NONE;
-       mf->width       = rj54n1->width;
-       mf->height      = rj54n1->height;
-
-       return 0;
-}
-
-/*
- * The actual geometry configuration routine. It scales the input window into
- * the output one, updates the window sizes and returns an error or the resize
- * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
- */
-static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
-                              s32 *out_w, s32 *out_h)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
-               output_w = *out_w, output_h = *out_h;
-       u16 inc_sel, wb_bit8, wb_left, wb_right, wb_top, wb_bottom;
-       unsigned int peak, peak_50, peak_60;
-       int ret;
-
-       /*
-        * We have a problem with crops, where the window is larger than 512x384
-        * and output window is larger than a half of the input one. In this
-        * case we have to either reduce the input window to equal or below
-        * 512x384 or the output window to equal or below 1/2 of the input.
-        */
-       if (output_w > max(512U, input_w / 2)) {
-               if (2 * output_w > RJ54N1_MAX_WIDTH) {
-                       input_w = RJ54N1_MAX_WIDTH;
-                       output_w = RJ54N1_MAX_WIDTH / 2;
-               } else {
-                       input_w = output_w * 2;
-               }
-
-               dev_dbg(&client->dev, "Adjusted output width: in %u, out %u\n",
-                       input_w, output_w);
-       }
-
-       if (output_h > max(384U, input_h / 2)) {
-               if (2 * output_h > RJ54N1_MAX_HEIGHT) {
-                       input_h = RJ54N1_MAX_HEIGHT;
-                       output_h = RJ54N1_MAX_HEIGHT / 2;
-               } else {
-                       input_h = output_h * 2;
-               }
-
-               dev_dbg(&client->dev, "Adjusted output height: in %u, out %u\n",
-                       input_h, output_h);
-       }
-
-       /* Idea: use the read mode for snapshots, handle separate geometries */
-       ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
-                             RJ54N1_Y_OUTPUT_SIZE_S_L,
-                             RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
-       if (!ret)
-               ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
-                             RJ54N1_Y_OUTPUT_SIZE_P_L,
-                             RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
-
-       if (ret < 0)
-               return ret;
-
-       if (output_w > input_w && output_h > input_h) {
-               input_w = output_w;
-               input_h = output_h;
-
-               resize = 1024;
-       } else {
-               unsigned int resize_x, resize_y;
-               resize_x = (input_w * 1024 + output_w / 2) / output_w;
-               resize_y = (input_h * 1024 + output_h / 2) / output_h;
-
-               /* We want max(resize_x, resize_y), check if it still fits */
-               if (resize_x > resize_y &&
-                   (output_h * resize_x + 512) / 1024 > RJ54N1_MAX_HEIGHT)
-                       resize = (RJ54N1_MAX_HEIGHT * 1024 + output_h / 2) /
-                               output_h;
-               else if (resize_y > resize_x &&
-                        (output_w * resize_y + 512) / 1024 > RJ54N1_MAX_WIDTH)
-                       resize = (RJ54N1_MAX_WIDTH * 1024 + output_w / 2) /
-                               output_w;
-               else
-                       resize = max(resize_x, resize_y);
-
-               /* Prohibited value ranges */
-               switch (resize) {
-               case 2040 ... 2047:
-                       resize = 2039;
-                       break;
-               case 4080 ... 4095:
-                       resize = 4079;
-                       break;
-               case 8160 ... 8191:
-                       resize = 8159;
-                       break;
-               case 16320 ... 16384:
-                       resize = 16319;
-               }
-       }
-
-       /* Set scaling */
-       ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
-
-       if (ret < 0)
-               return ret;
-
-       /*
-        * Configure a skipping bitmask. The sensor will select a skipping value
-        * among set bits automatically. This is very unclear in the datasheet
-        * too. I was told, in this register one enables all skipping values,
-        * that are required for a specific resize, and the camera selects
-        * automatically, which ones to use. But it is unclear how to identify,
-        * which cropping values are needed. Secondly, why don't we just set all
-        * bits and let the camera choose? Would it increase processing time and
-        * reduce the framerate? Using 0xfffc for INC_USE_SEL doesn't seem to
-        * improve the image quality or stability for larger frames (see comment
-        * above), but I didn't check the framerate.
-        */
-       skip = min(resize / 1024, 15U);
-
-       inc_sel = 1 << skip;
-
-       if (inc_sel <= 2)
-               inc_sel = 0xc;
-       else if (resize & 1023 && skip < 15)
-               inc_sel |= 1 << (skip + 1);
-
-       ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
-
-       if (!rj54n1->auto_wb) {
-               /* Auto white balance window */
-               wb_left   = output_w / 16;
-               wb_right  = (3 * output_w / 4 - 3) / 4;
-               wb_top    = output_h / 16;
-               wb_bottom = (3 * output_h / 4 - 3) / 4;
-               wb_bit8   = ((wb_left >> 2) & 0x40) | ((wb_top >> 4) & 0x10) |
-                       ((wb_right >> 6) & 4) | ((wb_bottom >> 8) & 1);
-
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_BIT8_WB, wb_bit8);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_HCAPS_WB, wb_left);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_VCAPS_WB, wb_top);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_HCAPE_WB, wb_right);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_VCAPE_WB, wb_bottom);
-       }
-
-       /* Antiflicker */
-       peak = 12 * RJ54N1_MAX_WIDTH * (1 << 14) * resize / rj54n1->tgclk_mhz /
-               10000;
-       peak_50 = peak / 6;
-       peak_60 = peak / 5;
-
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PEAK_H,
-                               ((peak_50 >> 4) & 0xf0) | (peak_60 >> 8));
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PEAK_50, peak_50);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PEAK_60, peak_60);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PEAK_DIFF, peak / 150);
-
-       /* Start resizing */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
-                               RESIZE_HOLD_SEL | RESIZE_GO | 1);
-
-       if (ret < 0)
-               return ret;
-
-       /* Constant taken from manufacturer's example */
-       msleep(230);
-
-       ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
-       if (ret < 0)
-               return ret;
-
-       *in_w = (output_w * resize + 512) / 1024;
-       *in_h = (output_h * resize + 512) / 1024;
-       *out_w = output_w;
-       *out_h = output_h;
-
-       dev_dbg(&client->dev, "Scaled for %dx%d : %u = %ux%u, skip %u\n",
-               *in_w, *in_h, resize, output_w, output_h, skip);
-
-       return resize;
-}
-
-static int rj54n1_set_clock(struct i2c_client *client)
-{
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       int ret;
-
-       /* Enable external clock */
-       ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
-       /* Leave stand-by. Note: use this when implementing suspend / resume */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
-
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PLL_L, PLL_L);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PLL_N, PLL_N);
-
-       /* TGCLK dividers */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RATIO_TG,
-                               rj54n1->clk_div.ratio_tg);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RATIO_T,
-                               rj54n1->clk_div.ratio_t);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RATIO_R,
-                               rj54n1->clk_div.ratio_r);
-
-       /* Enable TGCLK & RAMP */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
-
-       /* Disable clock output */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
-
-       /* Set divisors */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RATIO_OP,
-                               rj54n1->clk_div.ratio_op);
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RATIO_O,
-                               rj54n1->clk_div.ratio_o);
-
-       /* Enable OCLK */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
-
-       /* Use PLL for Timing Generator, write 2 to reserved bits */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
-
-       /* Take sensor out of reset */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESET_STANDBY,
-                               E_EXCLK | SEN_RSTX);
-       /* Enable PLL */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_PLL_EN, 1);
-
-       /* Wait for PLL to stabilise */
-       msleep(10);
-
-       /* Enable clock to frequency divider */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_CLK_RST, 1);
-
-       if (!ret)
-               ret = reg_read(client, RJ54N1_CLK_RST);
-       if (ret != 1) {
-               dev_err(&client->dev,
-                       "Resetting RJ54N1CB0C clock failed: %d!\n", ret);
-               return -EIO;
-       }
-
-       /* Start the PLL */
-       ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
-
-       /* Enable OCLK */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
-
-       return ret;
-}
-
-static int rj54n1_reg_init(struct i2c_client *client)
-{
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       int ret = rj54n1_set_clock(client);
-
-       if (!ret)
-               ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
-       if (!ret)
-               ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
-
-       /* Set binning divisors */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
-       if (!ret)
-               ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
-
-       /* Switch to fixed resize mode */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
-                               RESIZE_HOLD_SEL | 1);
-
-       /* Set gain */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
-
-       /*
-        * Mirror the image back: default is upside down and left-to-right...
-        * Set manual preview / still shot switching
-        */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_MIRROR_STILL_MODE, 0x27);
-
-       if (!ret)
-               ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
-
-       /* Auto exposure area */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_EXPOSURE_CONTROL, 0x80);
-       /* Check current auto WB config */
-       if (!ret)
-               ret = reg_read(client, RJ54N1_WB_SEL_WEIGHT_I);
-       if (ret >= 0) {
-               rj54n1->auto_wb = ret & 0x80;
-               ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
-       }
-       if (!ret)
-               ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
-
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESET_STANDBY,
-                               E_EXCLK | DSP_RSTX | SEN_RSTX);
-
-       /* Commit init */
-       if (!ret)
-               ret = rj54n1_commit(client);
-
-       /* Take DSP, TG, sensor out of reset */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_RESET_STANDBY,
-                               E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
-
-       /* Start register update? Same register as 0x?FE in many bank_* sets */
-       if (!ret)
-               ret = reg_write(client, RJ54N1_FWFLG, 2);
-
-       /* Constant taken from manufacturer's example */
-       msleep(700);
-
-       return ret;
-}
-
-static int rj54n1_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       const struct rj54n1_datafmt *fmt;
-       int output_w, output_h, max_w, max_h,
-               input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
-       int align = mf->code == MEDIA_BUS_FMT_SBGGR10_1X10 ||
-               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE ||
-               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE ||
-               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE ||
-               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE;
-       int ret;
-
-       if (format->pad)
-               return -EINVAL;
-
-       dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
-               __func__, mf->code, mf->width, mf->height);
-
-       fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
-                                 ARRAY_SIZE(rj54n1_colour_fmts));
-       if (!fmt) {
-               fmt = rj54n1->fmt;
-               mf->code = fmt->code;
-       }
-
-       mf->field       = V4L2_FIELD_NONE;
-       mf->colorspace  = fmt->colorspace;
-
-       v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align,
-                             &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0);
-
-       if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
-               cfg->try_fmt = *mf;
-               return 0;
-       }
-
-       /*
-        * Verify if the sensor has just been powered on. TODO: replace this
-        * with proper PM, when a suitable API is available.
-        */
-       ret = reg_read(client, RJ54N1_RESET_STANDBY);
-       if (ret < 0)
-               return ret;
-
-       if (!(ret & E_EXCLK)) {
-               ret = rj54n1_reg_init(client);
-               if (ret < 0)
-                       return ret;
-       }
-
-       /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
-       switch (mf->code) {
-       case MEDIA_BUS_FMT_YUYV8_2X8:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 0);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
-               break;
-       case MEDIA_BUS_FMT_YVYU8_2X8:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 0);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
-               break;
-       case MEDIA_BUS_FMT_RGB565_2X8_LE:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
-               break;
-       case MEDIA_BUS_FMT_RGB565_2X8_BE:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
-               break;
-       case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
-               break;
-       case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
-               break;
-       case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
-               break;
-       case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
-               if (!ret)
-                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
-               if (!ret)
-                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
-               break;
-       case MEDIA_BUS_FMT_SBGGR10_1X10:
-               ret = reg_write(client, RJ54N1_OUT_SEL, 5);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       /* Special case: a raw mode with 10 bits of data per clock tick */
-       if (!ret)
-               ret = reg_set(client, RJ54N1_OCLK_SEL_EN,
-                             (mf->code == MEDIA_BUS_FMT_SBGGR10_1X10) << 1, 2);
-
-       if (ret < 0)
-               return ret;
-
-       /* Supported scales 1:1 >= scale > 1:16 */
-       max_w = mf->width * (16 * 1024 - 1) / 1024;
-       if (input_w > max_w)
-               input_w = max_w;
-       max_h = mf->height * (16 * 1024 - 1) / 1024;
-       if (input_h > max_h)
-               input_h = max_h;
-
-       output_w = mf->width;
-       output_h = mf->height;
-
-       ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
-       if (ret < 0)
-               return ret;
-
-       fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
-                                 ARRAY_SIZE(rj54n1_colour_fmts));
-
-       rj54n1->fmt             = fmt;
-       rj54n1->resize          = ret;
-       rj54n1->rect.width      = input_w;
-       rj54n1->rect.height     = input_h;
-       rj54n1->width           = output_w;
-       rj54n1->height          = output_h;
-
-       mf->width               = output_w;
-       mf->height              = output_h;
-       mf->field               = V4L2_FIELD_NONE;
-       mf->colorspace          = fmt->colorspace;
-
-       return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int rj54n1_g_register(struct v4l2_subdev *sd,
-                            struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg < 0x400 || reg->reg > 0x1fff)
-               /* Registers > 0x0800 are only available from Sharp support */
-               return -EINVAL;
-
-       reg->size = 1;
-       reg->val = reg_read(client, reg->reg);
-
-       if (reg->val > 0xff)
-               return -EIO;
-
-       return 0;
-}
-
-static int rj54n1_s_register(struct v4l2_subdev *sd,
-                            const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg < 0x400 || reg->reg > 0x1fff)
-               /* Registers >= 0x0800 are only available from Sharp support */
-               return -EINVAL;
-
-       if (reg_write(client, reg->reg, reg->val) < 0)
-               return -EIO;
-
-       return 0;
-}
-#endif
-
-static int rj54n1_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-
-       return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on);
-}
-
-static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
-       struct v4l2_subdev *sd = &rj54n1->subdev;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int data;
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               if (ctrl->val)
-                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
-               else
-                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
-               if (data < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_HFLIP:
-               if (ctrl->val)
-                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
-               else
-                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
-               if (data < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_GAIN:
-               if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0)
-                       return -EIO;
-               return 0;
-       case V4L2_CID_AUTO_WHITE_BALANCE:
-               /* Auto WB area - whole image */
-               if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7,
-                           0x80) < 0)
-                       return -EIO;
-               rj54n1->auto_wb = ctrl->val;
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
-static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
-       .s_ctrl = rj54n1_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = rj54n1_g_register,
-       .s_register     = rj54n1_s_register,
-#endif
-       .s_power        = rj54n1_s_power,
-};
-
-static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags =
-               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
-               V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
-                               const struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
-       if (soc_camera_apply_board_flags(ssdd, cfg) &
-           V4L2_MBUS_PCLK_SAMPLE_RISING)
-               return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
-       else
-               return reg_write(client, RJ54N1_OUT_SIGPO, 0);
-}
-
-static const struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
-       .s_stream       = rj54n1_s_stream,
-       .g_mbus_config  = rj54n1_g_mbus_config,
-       .s_mbus_config  = rj54n1_s_mbus_config,
-};
-
-static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = {
-       .enum_mbus_code = rj54n1_enum_mbus_code,
-       .get_selection  = rj54n1_get_selection,
-       .set_selection  = rj54n1_set_selection,
-       .get_fmt        = rj54n1_get_fmt,
-       .set_fmt        = rj54n1_set_fmt,
-};
-
-static const struct v4l2_subdev_ops rj54n1_subdev_ops = {
-       .core   = &rj54n1_subdev_core_ops,
-       .video  = &rj54n1_subdev_video_ops,
-       .pad    = &rj54n1_subdev_pad_ops,
-};
-
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int rj54n1_video_probe(struct i2c_client *client,
-                             struct rj54n1_pdata *priv)
-{
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       int data1, data2;
-       int ret;
-
-       ret = rj54n1_s_power(&rj54n1->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /* Read out the chip version register */
-       data1 = reg_read(client, RJ54N1_DEV_CODE);
-       data2 = reg_read(client, RJ54N1_DEV_CODE2);
-
-       if (data1 != 0x51 || data2 != 0x10) {
-               ret = -ENODEV;
-               dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
-                        data1, data2);
-               goto done;
-       }
-
-       /* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */
-       ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7);
-       if (ret < 0)
-               goto done;
-
-       dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
-                data1, data2);
-
-       ret = v4l2_ctrl_handler_setup(&rj54n1->hdl);
-
-done:
-       rj54n1_s_power(&rj54n1->subdev, 0);
-       return ret;
-}
-
-static int rj54n1_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-{
-       struct rj54n1 *rj54n1;
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct rj54n1_pdata *rj54n1_priv;
-       int ret;
-
-       if (!ssdd || !ssdd->drv_priv) {
-               dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
-               return -EINVAL;
-       }
-
-       rj54n1_priv = ssdd->drv_priv;
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-               dev_warn(&adapter->dev,
-                        "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
-               return -EIO;
-       }
-
-       rj54n1 = devm_kzalloc(&client->dev, sizeof(struct rj54n1), GFP_KERNEL);
-       if (!rj54n1)
-               return -ENOMEM;
-
-       v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
-       v4l2_ctrl_handler_init(&rj54n1->hdl, 4);
-       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
-                       V4L2_CID_VFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
-                       V4L2_CID_HFLIP, 0, 1, 1, 0);
-       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
-                       V4L2_CID_GAIN, 0, 127, 1, 66);
-       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
-                       V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
-       rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
-       if (rj54n1->hdl.error)
-               return rj54n1->hdl.error;
-
-       rj54n1->clk_div         = clk_div;
-       rj54n1->rect.left       = RJ54N1_COLUMN_SKIP;
-       rj54n1->rect.top        = RJ54N1_ROW_SKIP;
-       rj54n1->rect.width      = RJ54N1_MAX_WIDTH;
-       rj54n1->rect.height     = RJ54N1_MAX_HEIGHT;
-       rj54n1->width           = RJ54N1_MAX_WIDTH;
-       rj54n1->height          = RJ54N1_MAX_HEIGHT;
-       rj54n1->fmt             = &rj54n1_colour_fmts[0];
-       rj54n1->resize          = 1024;
-       rj54n1->tgclk_mhz       = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
-               (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
-
-       rj54n1->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(rj54n1->clk)) {
-               ret = PTR_ERR(rj54n1->clk);
-               goto eclkget;
-       }
-
-       ret = rj54n1_video_probe(client, rj54n1_priv);
-       if (ret < 0) {
-               v4l2_clk_put(rj54n1->clk);
-eclkget:
-               v4l2_ctrl_handler_free(&rj54n1->hdl);
-       }
-
-       return ret;
-}
-
-static int rj54n1_remove(struct i2c_client *client)
-{
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       v4l2_clk_put(rj54n1->clk);
-       v4l2_device_unregister_subdev(&rj54n1->subdev);
-       if (ssdd->free_bus)
-               ssdd->free_bus(ssdd);
-       v4l2_ctrl_handler_free(&rj54n1->hdl);
-
-       return 0;
-}
-
-static const struct i2c_device_id rj54n1_id[] = {
-       { "rj54n1cb0c", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, rj54n1_id);
-
-static struct i2c_driver rj54n1_i2c_driver = {
-       .driver = {
-               .name = "rj54n1cb0c",
-       },
-       .probe          = rj54n1_probe,
-       .remove         = rj54n1_remove,
-       .id_table       = rj54n1_id,
-};
-
-module_i2c_driver(rj54n1_i2c_driver);
-
-MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
-MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_mt9m001.c b/drivers/media/i2c/soc_camera/soc_mt9m001.c
new file mode 100644 (file)
index 0000000..a1a85ff
--- /dev/null
@@ -0,0 +1,757 @@
+/*
+ * Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+
+#include <media/soc_camera.h>
+#include <media/drv-intf/soc_mediabus.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+
+/*
+ * mt9m001 i2c address 0x5d
+ * The platform has to define struct i2c_board_info objects and link to them
+ * from struct soc_camera_host_desc
+ */
+
+/* mt9m001 selected register addresses */
+#define MT9M001_CHIP_VERSION           0x00
+#define MT9M001_ROW_START              0x01
+#define MT9M001_COLUMN_START           0x02
+#define MT9M001_WINDOW_HEIGHT          0x03
+#define MT9M001_WINDOW_WIDTH           0x04
+#define MT9M001_HORIZONTAL_BLANKING    0x05
+#define MT9M001_VERTICAL_BLANKING      0x06
+#define MT9M001_OUTPUT_CONTROL         0x07
+#define MT9M001_SHUTTER_WIDTH          0x09
+#define MT9M001_FRAME_RESTART          0x0b
+#define MT9M001_SHUTTER_DELAY          0x0c
+#define MT9M001_RESET                  0x0d
+#define MT9M001_READ_OPTIONS1          0x1e
+#define MT9M001_READ_OPTIONS2          0x20
+#define MT9M001_GLOBAL_GAIN            0x35
+#define MT9M001_CHIP_ENABLE            0xF1
+
+#define MT9M001_MAX_WIDTH              1280
+#define MT9M001_MAX_HEIGHT             1024
+#define MT9M001_MIN_WIDTH              48
+#define MT9M001_MIN_HEIGHT             32
+#define MT9M001_COLUMN_SKIP            20
+#define MT9M001_ROW_SKIP               12
+
+/* MT9M001 has only one fixed colorspace per pixelcode */
+struct mt9m001_datafmt {
+       u32     code;
+       enum v4l2_colorspace            colorspace;
+};
+
+/* Find a data format by a pixel code in an array */
+static const struct mt9m001_datafmt *mt9m001_find_datafmt(
+       u32 code, const struct mt9m001_datafmt *fmt,
+       int n)
+{
+       int i;
+       for (i = 0; i < n; i++)
+               if (fmt[i].code == code)
+                       return fmt + i;
+
+       return NULL;
+}
+
+static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
+       /*
+        * Order important: first natively supported,
+        * second supported with a GPIO extender
+        */
+       {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+};
+
+static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
+       /* Order important - see above */
+       {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
+       {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
+};
+
+struct mt9m001 {
+       struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct {
+               /* exposure/auto-exposure cluster */
+               struct v4l2_ctrl *autoexposure;
+               struct v4l2_ctrl *exposure;
+       };
+       struct v4l2_rect rect;  /* Sensor window */
+       struct v4l2_clk *clk;
+       const struct mt9m001_datafmt *fmt;
+       const struct mt9m001_datafmt *fmts;
+       int num_fmts;
+       unsigned int total_h;
+       unsigned short y_skip_top;      /* Lines to skip at the top */
+};
+
+static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
+}
+
+static int reg_read(struct i2c_client *client, const u8 reg)
+{
+       return i2c_smbus_read_word_swapped(client, reg);
+}
+
+static int reg_write(struct i2c_client *client, const u8 reg,
+                    const u16 data)
+{
+       return i2c_smbus_write_word_swapped(client, reg, data);
+}
+
+static int reg_set(struct i2c_client *client, const u8 reg,
+                  const u16 data)
+{
+       int ret;
+
+       ret = reg_read(client, reg);
+       if (ret < 0)
+               return ret;
+       return reg_write(client, reg, ret | data);
+}
+
+static int reg_clear(struct i2c_client *client, const u8 reg,
+                    const u16 data)
+{
+       int ret;
+
+       ret = reg_read(client, reg);
+       if (ret < 0)
+               return ret;
+       return reg_write(client, reg, ret & ~data);
+}
+
+static int mt9m001_init(struct i2c_client *client)
+{
+       int ret;
+
+       dev_dbg(&client->dev, "%s\n", __func__);
+
+       /*
+        * We don't know, whether platform provides reset, issue a soft reset
+        * too. This returns all registers to their default values.
+        */
+       ret = reg_write(client, MT9M001_RESET, 1);
+       if (!ret)
+               ret = reg_write(client, MT9M001_RESET, 0);
+
+       /* Disable chip, synchronous option update */
+       if (!ret)
+               ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
+
+       return ret;
+}
+
+static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       /* Switch to master "normal" mode or stop sensor readout */
+       if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
+               return -EIO;
+       return 0;
+}
+
+static int mt9m001_set_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       struct v4l2_rect rect = sel->r;
+       const u16 hblank = 9, vblank = 25;
+       int ret;
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       if (mt9m001->fmts == mt9m001_colour_fmts)
+               /*
+                * Bayer format - even number of rows for simplicity,
+                * but let the user play with the top row.
+                */
+               rect.height = ALIGN(rect.height, 2);
+
+       /* Datasheet requirement: see register description */
+       rect.width = ALIGN(rect.width, 2);
+       rect.left = ALIGN(rect.left, 2);
+
+       soc_camera_limit_side(&rect.left, &rect.width,
+                    MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
+
+       soc_camera_limit_side(&rect.top, &rect.height,
+                    MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
+
+       mt9m001->total_h = rect.height + mt9m001->y_skip_top + vblank;
+
+       /* Blanking and start values - default... */
+       ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
+       if (!ret)
+               ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank);
+
+       /*
+        * The caller provides a supported format, as verified per
+        * call to .set_fmt(FORMAT_TRY).
+        */
+       if (!ret)
+               ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
+       if (!ret)
+               ret = reg_write(client, MT9M001_ROW_START, rect.top);
+       if (!ret)
+               ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
+       if (!ret)
+               ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
+                               rect.height + mt9m001->y_skip_top - 1);
+       if (!ret && v4l2_ctrl_g_ctrl(mt9m001->autoexposure) == V4L2_EXPOSURE_AUTO)
+               ret = reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h);
+
+       if (!ret)
+               mt9m001->rect = rect;
+
+       return ret;
+}
+
+static int mt9m001_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.left = MT9M001_COLUMN_SKIP;
+               sel->r.top = MT9M001_ROW_SKIP;
+               sel->r.width = MT9M001_MAX_WIDTH;
+               sel->r.height = MT9M001_MAX_HEIGHT;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = mt9m001->rect;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int mt9m001_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       struct v4l2_mbus_framefmt *mf = &format->format;
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->width       = mt9m001->rect.width;
+       mf->height      = mt9m001->rect.height;
+       mf->code        = mt9m001->fmt->code;
+       mf->colorspace  = mt9m001->fmt->colorspace;
+       mf->field       = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int mt9m001_s_fmt(struct v4l2_subdev *sd,
+                        const struct mt9m001_datafmt *fmt,
+                        struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       struct v4l2_subdev_selection sel = {
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+               .target = V4L2_SEL_TGT_CROP,
+               .r.left = mt9m001->rect.left,
+               .r.top = mt9m001->rect.top,
+               .r.width = mf->width,
+               .r.height = mf->height,
+       };
+       int ret;
+
+       /* No support for scaling so far, just crop. TODO: use skipping */
+       ret = mt9m001_set_selection(sd, NULL, &sel);
+       if (!ret) {
+               mf->width       = mt9m001->rect.width;
+               mf->height      = mt9m001->rect.height;
+               mt9m001->fmt    = fmt;
+               mf->colorspace  = fmt->colorspace;
+       }
+
+       return ret;
+}
+
+static int mt9m001_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       const struct mt9m001_datafmt *fmt;
+
+       if (format->pad)
+               return -EINVAL;
+
+       v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH,
+               MT9M001_MAX_WIDTH, 1,
+               &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
+               MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
+
+       if (mt9m001->fmts == mt9m001_colour_fmts)
+               mf->height = ALIGN(mf->height - 1, 2);
+
+       fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts,
+                                  mt9m001->num_fmts);
+       if (!fmt) {
+               fmt = mt9m001->fmt;
+               mf->code = fmt->code;
+       }
+
+       mf->colorspace  = fmt->colorspace;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return mt9m001_s_fmt(sd, fmt, mf);
+       cfg->try_fmt = *mf;
+       return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int mt9m001_g_register(struct v4l2_subdev *sd,
+                             struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       reg->size = 2;
+       reg->val = reg_read(client, reg->reg);
+
+       if (reg->val > 0xffff)
+               return -EIO;
+
+       return 0;
+}
+
+static int mt9m001_s_register(struct v4l2_subdev *sd,
+                             const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       if (reg_write(client, reg->reg, reg->val) < 0)
+               return -EIO;
+
+       return 0;
+}
+#endif
+
+static int mt9m001_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+       return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on);
+}
+
+static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct mt9m001 *mt9m001 = container_of(ctrl->handler,
+                                              struct mt9m001, hdl);
+       s32 min, max;
+
+       switch (ctrl->id) {
+       case V4L2_CID_EXPOSURE_AUTO:
+               min = mt9m001->exposure->minimum;
+               max = mt9m001->exposure->maximum;
+               mt9m001->exposure->val =
+                       (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min;
+               break;
+       }
+       return 0;
+}
+
+static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct mt9m001 *mt9m001 = container_of(ctrl->handler,
+                                              struct mt9m001, hdl);
+       struct v4l2_subdev *sd = &mt9m001->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct v4l2_ctrl *exp = mt9m001->exposure;
+       int data;
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               if (ctrl->val)
+                       data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
+               else
+                       data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
+               if (data < 0)
+                       return -EIO;
+               return 0;
+
+       case V4L2_CID_GAIN:
+               /* See Datasheet Table 7, Gain settings. */
+               if (ctrl->val <= ctrl->default_value) {
+                       /* Pack it into 0..1 step 0.125, register values 0..8 */
+                       unsigned long range = ctrl->default_value - ctrl->minimum;
+                       data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range;
+
+                       dev_dbg(&client->dev, "Setting gain %d\n", data);
+                       data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
+                       if (data < 0)
+                               return -EIO;
+               } else {
+                       /* Pack it into 1.125..15 variable step, register values 9..67 */
+                       /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
+                       unsigned long range = ctrl->maximum - ctrl->default_value - 1;
+                       unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) *
+                                              111 + range / 2) / range + 9;
+
+                       if (gain <= 32)
+                               data = gain;
+                       else if (gain <= 64)
+                               data = ((gain - 32) * 16 + 16) / 32 + 80;
+                       else
+                               data = ((gain - 64) * 7 + 28) / 56 + 96;
+
+                       dev_dbg(&client->dev, "Setting gain from %d to %d\n",
+                                reg_read(client, MT9M001_GLOBAL_GAIN), data);
+                       data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
+                       if (data < 0)
+                               return -EIO;
+               }
+               return 0;
+
+       case V4L2_CID_EXPOSURE_AUTO:
+               if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
+                       unsigned long range = exp->maximum - exp->minimum;
+                       unsigned long shutter = ((exp->val - (s32)exp->minimum) * 1048 +
+                                                range / 2) / range + 1;
+
+                       dev_dbg(&client->dev,
+                               "Setting shutter width from %d to %lu\n",
+                               reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
+                       if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
+                               return -EIO;
+               } else {
+                       const u16 vblank = 25;
+
+                       mt9m001->total_h = mt9m001->rect.height +
+                               mt9m001->y_skip_top + vblank;
+                       if (reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h) < 0)
+                               return -EIO;
+               }
+               return 0;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
+static int mt9m001_video_probe(struct soc_camera_subdev_desc *ssdd,
+                              struct i2c_client *client)
+{
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       s32 data;
+       unsigned long flags;
+       int ret;
+
+       ret = mt9m001_s_power(&mt9m001->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Enable the chip */
+       data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
+       dev_dbg(&client->dev, "write: %d\n", data);
+
+       /* Read out the chip version register */
+       data = reg_read(client, MT9M001_CHIP_VERSION);
+
+       /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
+       switch (data) {
+       case 0x8411:
+       case 0x8421:
+               mt9m001->fmts = mt9m001_colour_fmts;
+               break;
+       case 0x8431:
+               mt9m001->fmts = mt9m001_monochrome_fmts;
+               break;
+       default:
+               dev_err(&client->dev,
+                       "No MT9M001 chip detected, register read %x\n", data);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       mt9m001->num_fmts = 0;
+
+       /*
+        * This is a 10bit sensor, so by default we only allow 10bit.
+        * The platform may support different bus widths due to
+        * different routing of the data lines.
+        */
+       if (ssdd->query_bus_param)
+               flags = ssdd->query_bus_param(ssdd);
+       else
+               flags = SOCAM_DATAWIDTH_10;
+
+       if (flags & SOCAM_DATAWIDTH_10)
+               mt9m001->num_fmts++;
+       else
+               mt9m001->fmts++;
+
+       if (flags & SOCAM_DATAWIDTH_8)
+               mt9m001->num_fmts++;
+
+       mt9m001->fmt = &mt9m001->fmts[0];
+
+       dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
+                data == 0x8431 ? "C12STM" : "C12ST");
+
+       ret = mt9m001_init(client);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to initialise the camera\n");
+               goto done;
+       }
+
+       /* mt9m001_init() has reset the chip, returning registers to defaults */
+       ret = v4l2_ctrl_handler_setup(&mt9m001->hdl);
+
+done:
+       mt9m001_s_power(&mt9m001->subdev, 0);
+       return ret;
+}
+
+static void mt9m001_video_remove(struct soc_camera_subdev_desc *ssdd)
+{
+       if (ssdd->free_bus)
+               ssdd->free_bus(ssdd);
+}
+
+static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+       *lines = mt9m001->y_skip_top;
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
+       .g_volatile_ctrl = mt9m001_g_volatile_ctrl,
+       .s_ctrl = mt9m001_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = mt9m001_g_register,
+       .s_register     = mt9m001_s_register,
+#endif
+       .s_power        = mt9m001_s_power,
+};
+
+static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+       if (code->pad || code->index >= mt9m001->num_fmts)
+               return -EINVAL;
+
+       code->code = mt9m001->fmts[code->index].code;
+       return 0;
+}
+
+static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       /* MT9M001 has all capture_format parameters fixed */
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       const struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample;
+
+       if (ssdd->set_bus_param)
+               return ssdd->set_bus_param(ssdd, 1 << (bps - 1));
+
+       /*
+        * Without board specific bus width settings we only support the
+        * sensors native bus width
+        */
+       return bps == 10 ? 0 : -EINVAL;
+}
+
+static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
+       .s_stream       = mt9m001_s_stream,
+       .g_mbus_config  = mt9m001_g_mbus_config,
+       .s_mbus_config  = mt9m001_s_mbus_config,
+};
+
+static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
+       .g_skip_top_lines       = mt9m001_g_skip_top_lines,
+};
+
+static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = {
+       .enum_mbus_code = mt9m001_enum_mbus_code,
+       .get_selection  = mt9m001_get_selection,
+       .set_selection  = mt9m001_set_selection,
+       .get_fmt        = mt9m001_get_fmt,
+       .set_fmt        = mt9m001_set_fmt,
+};
+
+static const struct v4l2_subdev_ops mt9m001_subdev_ops = {
+       .core   = &mt9m001_subdev_core_ops,
+       .video  = &mt9m001_subdev_video_ops,
+       .sensor = &mt9m001_subdev_sensor_ops,
+       .pad    = &mt9m001_subdev_pad_ops,
+};
+
+static int mt9m001_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+       struct mt9m001 *mt9m001;
+       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       int ret;
+
+       if (!ssdd) {
+               dev_err(&client->dev, "MT9M001 driver needs platform data\n");
+               return -EINVAL;
+       }
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
+               dev_warn(&adapter->dev,
+                        "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
+               return -EIO;
+       }
+
+       mt9m001 = devm_kzalloc(&client->dev, sizeof(struct mt9m001), GFP_KERNEL);
+       if (!mt9m001)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
+       v4l2_ctrl_handler_init(&mt9m001->hdl, 4);
+       v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 64);
+       mt9m001->exposure = v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
+                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
+       /*
+        * Simulated autoexposure. If enabled, we calculate shutter width
+        * ourselves in the driver based on vertical blanking and frame width
+        */
+       mt9m001->autoexposure = v4l2_ctrl_new_std_menu(&mt9m001->hdl,
+                       &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
+                       V4L2_EXPOSURE_AUTO);
+       mt9m001->subdev.ctrl_handler = &mt9m001->hdl;
+       if (mt9m001->hdl.error)
+               return mt9m001->hdl.error;
+
+       v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure,
+                                       V4L2_EXPOSURE_MANUAL, true);
+
+       /* Second stage probe - when a capture adapter is there */
+       mt9m001->y_skip_top     = 0;
+       mt9m001->rect.left      = MT9M001_COLUMN_SKIP;
+       mt9m001->rect.top       = MT9M001_ROW_SKIP;
+       mt9m001->rect.width     = MT9M001_MAX_WIDTH;
+       mt9m001->rect.height    = MT9M001_MAX_HEIGHT;
+
+       mt9m001->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(mt9m001->clk)) {
+               ret = PTR_ERR(mt9m001->clk);
+               goto eclkget;
+       }
+
+       ret = mt9m001_video_probe(ssdd, client);
+       if (ret) {
+               v4l2_clk_put(mt9m001->clk);
+eclkget:
+               v4l2_ctrl_handler_free(&mt9m001->hdl);
+       }
+
+       return ret;
+}
+
+static int mt9m001_remove(struct i2c_client *client)
+{
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       v4l2_clk_put(mt9m001->clk);
+       v4l2_device_unregister_subdev(&mt9m001->subdev);
+       v4l2_ctrl_handler_free(&mt9m001->hdl);
+       mt9m001_video_remove(ssdd);
+
+       return 0;
+}
+
+static const struct i2c_device_id mt9m001_id[] = {
+       { "mt9m001", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mt9m001_id);
+
+static struct i2c_driver mt9m001_i2c_driver = {
+       .driver = {
+               .name = "mt9m001",
+       },
+       .probe          = mt9m001_probe,
+       .remove         = mt9m001_remove,
+       .id_table       = mt9m001_id,
+};
+
+module_i2c_driver(mt9m001_i2c_driver);
+
+MODULE_DESCRIPTION("Micron MT9M001 Camera driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/soc_camera/soc_mt9t112.c b/drivers/media/i2c/soc_camera/soc_mt9t112.c
new file mode 100644 (file)
index 0000000..ea1ff27
--- /dev/null
@@ -0,0 +1,1157 @@
+/*
+ * mt9t112 Camera Driver
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov772x driver, mt9m111 driver,
+ *
+ * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+
+#include <media/i2c/mt9t112.h>
+#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-image-sizes.h>
+
+/* you can check PLL/clock info */
+/* #define EXT_CLOCK 24000000 */
+
+/************************************************************************
+                       macro
+************************************************************************/
+/*
+ * frame size
+ */
+#define MAX_WIDTH   2048
+#define MAX_HEIGHT  1536
+
+/*
+ * macro of read/write
+ */
+#define ECHECKER(ret, x)               \
+       do {                            \
+               (ret) = (x);            \
+               if ((ret) < 0)          \
+                       return (ret);   \
+       } while (0)
+
+#define mt9t112_reg_write(ret, client, a, b) \
+       ECHECKER(ret, __mt9t112_reg_write(client, a, b))
+#define mt9t112_mcu_write(ret, client, a, b) \
+       ECHECKER(ret, __mt9t112_mcu_write(client, a, b))
+
+#define mt9t112_reg_mask_set(ret, client, a, b, c) \
+       ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c))
+#define mt9t112_mcu_mask_set(ret, client, a, b, c) \
+       ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c))
+
+#define mt9t112_reg_read(ret, client, a) \
+       ECHECKER(ret, __mt9t112_reg_read(client, a))
+
+/*
+ * Logical address
+ */
+#define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff))
+#define VAR(id, offset)  _VAR(id, offset, 0x0000)
+#define VAR8(id, offset) _VAR(id, offset, 0x8000)
+
+/************************************************************************
+                       struct
+************************************************************************/
+struct mt9t112_format {
+       u32 code;
+       enum v4l2_colorspace colorspace;
+       u16 fmt;
+       u16 order;
+};
+
+struct mt9t112_priv {
+       struct v4l2_subdev               subdev;
+       struct mt9t112_platform_data    *info;
+       struct i2c_client               *client;
+       struct v4l2_rect                 frame;
+       struct v4l2_clk                 *clk;
+       const struct mt9t112_format     *format;
+       int                              num_formats;
+       u32                              flags;
+/* for flags */
+#define INIT_DONE      (1 << 0)
+#define PCLK_RISING    (1 << 1)
+};
+
+/************************************************************************
+                       supported format
+************************************************************************/
+
+static const struct mt9t112_format mt9t112_cfmts[] = {
+       {
+               .code           = MEDIA_BUS_FMT_UYVY8_2X8,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fmt            = 1,
+               .order          = 0,
+       }, {
+               .code           = MEDIA_BUS_FMT_VYUY8_2X8,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fmt            = 1,
+               .order          = 1,
+       }, {
+               .code           = MEDIA_BUS_FMT_YUYV8_2X8,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fmt            = 1,
+               .order          = 2,
+       }, {
+               .code           = MEDIA_BUS_FMT_YVYU8_2X8,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fmt            = 1,
+               .order          = 3,
+       }, {
+               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fmt            = 8,
+               .order          = 2,
+       }, {
+               .code           = MEDIA_BUS_FMT_RGB565_2X8_LE,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .fmt            = 4,
+               .order          = 2,
+       },
+};
+
+/************************************************************************
+                       general function
+************************************************************************/
+static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client),
+                           struct mt9t112_priv,
+                           subdev);
+}
+
+static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
+{
+       struct i2c_msg msg[2];
+       u8 buf[2];
+       int ret;
+
+       command = swab16(command);
+
+       msg[0].addr  = client->addr;
+       msg[0].flags = 0;
+       msg[0].len   = 2;
+       msg[0].buf   = (u8 *)&command;
+
+       msg[1].addr  = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len   = 2;
+       msg[1].buf   = buf;
+
+       /*
+        * if return value of this function is < 0,
+        * it mean error.
+        * else, under 16bit is valid data.
+        */
+       ret = i2c_transfer(client->adapter, msg, 2);
+       if (ret < 0)
+               return ret;
+
+       memcpy(&ret, buf, 2);
+       return swab16(ret);
+}
+
+static int __mt9t112_reg_write(const struct i2c_client *client,
+                              u16 command, u16 data)
+{
+       struct i2c_msg msg;
+       u8 buf[4];
+       int ret;
+
+       command = swab16(command);
+       data = swab16(data);
+
+       memcpy(buf + 0, &command, 2);
+       memcpy(buf + 2, &data,    2);
+
+       msg.addr  = client->addr;
+       msg.flags = 0;
+       msg.len   = 4;
+       msg.buf   = buf;
+
+       /*
+        * i2c_transfer return message length,
+        * but this function should return 0 if correct case
+        */
+       ret = i2c_transfer(client->adapter, &msg, 1);
+       if (ret >= 0)
+               ret = 0;
+
+       return ret;
+}
+
+static int __mt9t112_reg_mask_set(const struct i2c_client *client,
+                                 u16  command,
+                                 u16  mask,
+                                 u16  set)
+{
+       int val = __mt9t112_reg_read(client, command);
+       if (val < 0)
+               return val;
+
+       val &= ~mask;
+       val |= set & mask;
+
+       return __mt9t112_reg_write(client, command, val);
+}
+
+/* mcu access */
+static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command)
+{
+       int ret;
+
+       ret = __mt9t112_reg_write(client, 0x098E, command);
+       if (ret < 0)
+               return ret;
+
+       return __mt9t112_reg_read(client, 0x0990);
+}
+
+static int __mt9t112_mcu_write(const struct i2c_client *client,
+                              u16 command, u16 data)
+{
+       int ret;
+
+       ret = __mt9t112_reg_write(client, 0x098E, command);
+       if (ret < 0)
+               return ret;
+
+       return __mt9t112_reg_write(client, 0x0990, data);
+}
+
+static int __mt9t112_mcu_mask_set(const struct i2c_client *client,
+                                 u16  command,
+                                 u16  mask,
+                                 u16  set)
+{
+       int val = __mt9t112_mcu_read(client, command);
+       if (val < 0)
+               return val;
+
+       val &= ~mask;
+       val |= set & mask;
+
+       return __mt9t112_mcu_write(client, command, val);
+}
+
+static int mt9t112_reset(const struct i2c_client *client)
+{
+       int ret;
+
+       mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001);
+       msleep(1);
+       mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000);
+
+       return ret;
+}
+
+#ifndef EXT_CLOCK
+#define CLOCK_INFO(a, b)
+#else
+#define CLOCK_INFO(a, b) mt9t112_clock_info(a, b)
+static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
+{
+       int m, n, p1, p2, p3, p4, p5, p6, p7;
+       u32 vco, clk;
+       char *enable;
+
+       ext /= 1000; /* kbyte order */
+
+       mt9t112_reg_read(n, client, 0x0012);
+       p1 = n & 0x000f;
+       n = n >> 4;
+       p2 = n & 0x000f;
+       n = n >> 4;
+       p3 = n & 0x000f;
+
+       mt9t112_reg_read(n, client, 0x002a);
+       p4 = n & 0x000f;
+       n = n >> 4;
+       p5 = n & 0x000f;
+       n = n >> 4;
+       p6 = n & 0x000f;
+
+       mt9t112_reg_read(n, client, 0x002c);
+       p7 = n & 0x000f;
+
+       mt9t112_reg_read(n, client, 0x0010);
+       m = n & 0x00ff;
+       n = (n >> 8) & 0x003f;
+
+       enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
+       dev_dbg(&client->dev, "EXTCLK          : %10u K %s\n", ext, enable);
+
+       vco = 2 * m * ext / (n+1);
+       enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
+       dev_dbg(&client->dev, "VCO             : %10u K %s\n", vco, enable);
+
+       clk = vco / (p1+1) / (p2+1);
+       enable = (96000 < clk) ? "X" : "";
+       dev_dbg(&client->dev, "PIXCLK          : %10u K %s\n", clk, enable);
+
+       clk = vco / (p3+1);
+       enable = (768000 < clk) ? "X" : "";
+       dev_dbg(&client->dev, "MIPICLK         : %10u K %s\n", clk, enable);
+
+       clk = vco / (p6+1);
+       enable = (96000 < clk) ? "X" : "";
+       dev_dbg(&client->dev, "MCU CLK         : %10u K %s\n", clk, enable);
+
+       clk = vco / (p5+1);
+       enable = (54000 < clk) ? "X" : "";
+       dev_dbg(&client->dev, "SOC CLK         : %10u K %s\n", clk, enable);
+
+       clk = vco / (p4+1);
+       enable = (70000 < clk) ? "X" : "";
+       dev_dbg(&client->dev, "Sensor CLK      : %10u K %s\n", clk, enable);
+
+       clk = vco / (p7+1);
+       dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
+
+       clk = ext / (n+1);
+       enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
+       dev_dbg(&client->dev, "PFD             : %10u K %s\n", clk, enable);
+
+       return 0;
+}
+#endif
+
+static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
+{
+       soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
+       soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
+}
+
+static int mt9t112_set_a_frame_size(const struct i2c_client *client,
+                                  u16 width,
+                                  u16 height)
+{
+       int ret;
+       u16 wstart = (MAX_WIDTH - width) / 2;
+       u16 hstart = (MAX_HEIGHT - height) / 2;
+
+       /* (Context A) Image Width/Height */
+       mt9t112_mcu_write(ret, client, VAR(26, 0), width);
+       mt9t112_mcu_write(ret, client, VAR(26, 2), height);
+
+       /* (Context A) Output Width/Height */
+       mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width);
+       mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height);
+
+       /* (Context A) Start Row/Column */
+       mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart);
+       mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart);
+
+       /* (Context A) End Row/Column */
+       mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart);
+       mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width  + wstart);
+
+       mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
+
+       return ret;
+}
+
+static int mt9t112_set_pll_dividers(const struct i2c_client *client,
+                                   u8 m, u8 n,
+                                   u8 p1, u8 p2, u8 p3,
+                                   u8 p4, u8 p5, u8 p6,
+                                   u8 p7)
+{
+       int ret;
+       u16 val;
+
+       /* N/M */
+       val = (n << 8) |
+             (m << 0);
+       mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val);
+
+       /* P1/P2/P3 */
+       val = ((p3 & 0x0F) << 8) |
+             ((p2 & 0x0F) << 4) |
+             ((p1 & 0x0F) << 0);
+       mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val);
+
+       /* P4/P5/P6 */
+       val = (0x7         << 12) |
+             ((p6 & 0x0F) <<  8) |
+             ((p5 & 0x0F) <<  4) |
+             ((p4 & 0x0F) <<  0);
+       mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val);
+
+       /* P7 */
+       val = (0x1         << 12) |
+             ((p7 & 0x0F) <<  0);
+       mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val);
+
+       return ret;
+}
+
+static int mt9t112_init_pll(const struct i2c_client *client)
+{
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       int data, i, ret;
+
+       mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
+
+       /* PLL control: BYPASS PLL = 8517 */
+       mt9t112_reg_write(ret, client, 0x0014, 0x2145);
+
+       /* Replace these registers when new timing parameters are generated */
+       mt9t112_set_pll_dividers(client,
+                                priv->info->divider.m,
+                                priv->info->divider.n,
+                                priv->info->divider.p1,
+                                priv->info->divider.p2,
+                                priv->info->divider.p3,
+                                priv->info->divider.p4,
+                                priv->info->divider.p5,
+                                priv->info->divider.p6,
+                                priv->info->divider.p7);
+
+       /*
+        * TEST_BYPASS  on
+        * PLL_ENABLE   on
+        * SEL_LOCK_DET on
+        * TEST_BYPASS  off
+        */
+       mt9t112_reg_write(ret, client, 0x0014, 0x2525);
+       mt9t112_reg_write(ret, client, 0x0014, 0x2527);
+       mt9t112_reg_write(ret, client, 0x0014, 0x3427);
+       mt9t112_reg_write(ret, client, 0x0014, 0x3027);
+
+       mdelay(10);
+
+       /*
+        * PLL_BYPASS off
+        * Reference clock count
+        * I2C Master Clock Divider
+        */
+       mt9t112_reg_write(ret, client, 0x0014, 0x3046);
+       mt9t112_reg_write(ret, client, 0x0016, 0x0400); /* JPEG initialization workaround */
+       mt9t112_reg_write(ret, client, 0x0022, 0x0190);
+       mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
+
+       /* External sensor clock is PLL bypass */
+       mt9t112_reg_write(ret, client, 0x002E, 0x0500);
+
+       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002);
+       mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004);
+
+       /* MCU disabled */
+       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004);
+
+       /* out of standby */
+       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
+
+       mdelay(50);
+
+       /*
+        * Standby Workaround
+        * Disable Secondary I2C Pads
+        */
+       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+       mdelay(1);
+       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+       mdelay(1);
+       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+       mdelay(1);
+       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+       mdelay(1);
+       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+       mdelay(1);
+       mt9t112_reg_write(ret, client, 0x0614, 0x0001);
+       mdelay(1);
+
+       /* poll to verify out of standby. Must Poll this bit */
+       for (i = 0; i < 100; i++) {
+               mt9t112_reg_read(data, client, 0x0018);
+               if (!(0x4000 & data))
+                       break;
+
+               mdelay(10);
+       }
+
+       return ret;
+}
+
+static int mt9t112_init_setting(const struct i2c_client *client)
+{
+
+       int ret;
+
+       /* Adaptive Output Clock (A) */
+       mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000);
+
+       /* Read Mode (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024);
+
+       /* Fine Correction (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC);
+
+       /* Fine IT Min (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1);
+
+       /* Fine IT Max Margin (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF);
+
+       /* Base Frame Lines (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D);
+
+       /* Min Line Length (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a);
+
+       /* Line Length (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0);
+
+       /* Adaptive Output Clock (B) */
+       mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000);
+
+       /* Row Start (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004);
+
+       /* Column Start (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004);
+
+       /* Row End (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B);
+
+       /* Column End (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B);
+
+       /* Fine Correction (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C);
+
+       /* Fine IT Min (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1);
+
+       /* Fine IT Max Margin (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF);
+
+       /* Base Frame Lines (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668);
+
+       /* Min Line Length (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0);
+
+       /* Line Length (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0);
+
+       /*
+        * Flicker Dectection registers
+        * This section should be replaced whenever new Timing file is generated
+        * All the following registers need to be replaced
+        * Following registers are generated from Register Wizard but user can
+        * modify them. For detail see auto flicker detection tuning
+        */
+
+       /* FD_FDPERIOD_SELECT */
+       mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01);
+
+       /* PRI_B_CONFIG_FD_ALGO_RUN */
+       mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003);
+
+       /* PRI_A_CONFIG_FD_ALGO_RUN */
+       mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003);
+
+       /*
+        * AFD range detection tuning registers
+        */
+
+       /* search_f1_50 */
+       mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25);
+
+       /* search_f2_50 */
+       mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28);
+
+       /* search_f1_60 */
+       mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C);
+
+       /* search_f2_60 */
+       mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F);
+
+       /* period_50Hz (A) */
+       mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA);
+
+       /* secret register by aptina */
+       /* period_50Hz (A MSB) */
+       mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00);
+
+       /* period_60Hz (A) */
+       mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B);
+
+       /* secret register by aptina */
+       /* period_60Hz (A MSB) */
+       mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00);
+
+       /* period_50Hz (B) */
+       mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82);
+
+       /* secret register by aptina */
+       /* period_50Hz (B) MSB */
+       mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00);
+
+       /* period_60Hz (B) */
+       mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D);
+
+       /* secret register by aptina */
+       /* period_60Hz (B) MSB */
+       mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00);
+
+       /* FD Mode */
+       mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10);
+
+       /* Stat_min */
+       mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02);
+
+       /* Stat_max */
+       mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03);
+
+       /* Min_amplitude */
+       mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A);
+
+       /* RX FIFO Watermark (A) */
+       mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014);
+
+       /* RX FIFO Watermark (B) */
+       mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014);
+
+       /* MCLK: 16MHz
+        * PCLK: 73MHz
+        * CorePixCLK: 36.5 MHz
+        */
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133);
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110);
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130);
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108);
+
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27);
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30);
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32);
+       mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35);
+
+       return ret;
+}
+
+static int mt9t112_auto_focus_setting(const struct i2c_client *client)
+{
+       int ret;
+
+       mt9t112_mcu_write(ret, client, VAR(12, 13),     0x000F);
+       mt9t112_mcu_write(ret, client, VAR(12, 23),     0x0F0F);
+       mt9t112_mcu_write(ret, client, VAR8(1, 0),      0x06);
+
+       mt9t112_reg_write(ret, client, 0x0614, 0x0000);
+
+       mt9t112_mcu_write(ret, client, VAR8(1, 0),      0x05);
+       mt9t112_mcu_write(ret, client, VAR8(12, 2),     0x02);
+       mt9t112_mcu_write(ret, client, VAR(12, 3),      0x0002);
+       mt9t112_mcu_write(ret, client, VAR(17, 3),      0x8001);
+       mt9t112_mcu_write(ret, client, VAR(17, 11),     0x0025);
+       mt9t112_mcu_write(ret, client, VAR(17, 13),     0x0193);
+       mt9t112_mcu_write(ret, client, VAR8(17, 33),    0x18);
+       mt9t112_mcu_write(ret, client, VAR8(1, 0),      0x05);
+
+       return ret;
+}
+
+static int mt9t112_auto_focus_trigger(const struct i2c_client *client)
+{
+       int ret;
+
+       mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01);
+
+       return ret;
+}
+
+static int mt9t112_init_camera(const struct i2c_client *client)
+{
+       int ret;
+
+       ECHECKER(ret, mt9t112_reset(client));
+
+       ECHECKER(ret, mt9t112_init_pll(client));
+
+       ECHECKER(ret, mt9t112_init_setting(client));
+
+       ECHECKER(ret, mt9t112_auto_focus_setting(client));
+
+       mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
+
+       /* Analog setting B */
+       mt9t112_reg_write(ret, client, 0x3084, 0x2409);
+       mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
+       mt9t112_reg_write(ret, client, 0x3094, 0x4949);
+       mt9t112_reg_write(ret, client, 0x3096, 0x4950);
+
+       /*
+        * Disable adaptive clock
+        * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
+        * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
+        */
+       mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E);
+       mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E);
+
+       /* Configure STatus in Status_before_length Format and enable header */
+       /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
+       mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4);
+
+       /* Enable JPEG in context B */
+       /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */
+       mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01);
+
+       /* Disable Dac_TXLO */
+       mt9t112_reg_write(ret, client, 0x316C, 0x350F);
+
+       /* Set max slew rates */
+       mt9t112_reg_write(ret, client, 0x1E, 0x777);
+
+       return ret;
+}
+
+/************************************************************************
+                       v4l2_subdev_core_ops
+************************************************************************/
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int mt9t112_g_register(struct v4l2_subdev *sd,
+                             struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int                ret;
+
+       reg->size = 2;
+       mt9t112_reg_read(ret, client, reg->reg);
+
+       reg->val = (__u64)ret;
+
+       return 0;
+}
+
+static int mt9t112_s_register(struct v4l2_subdev *sd,
+                             const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+
+       mt9t112_reg_write(ret, client, reg->reg, reg->val);
+
+       return ret;
+}
+#endif
+
+static int mt9t112_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
+}
+
+static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = mt9t112_g_register,
+       .s_register     = mt9t112_s_register,
+#endif
+       .s_power        = mt9t112_s_power,
+};
+
+
+/************************************************************************
+                       v4l2_subdev_video_ops
+************************************************************************/
+static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       int ret = 0;
+
+       if (!enable) {
+               /* FIXME
+                *
+                * If user selected large output size,
+                * and used it long time,
+                * mt9t112 camera will be very warm.
+                *
+                * But current driver can not stop mt9t112 camera.
+                * So, set small size here to solve this problem.
+                */
+               mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
+               return ret;
+       }
+
+       if (!(priv->flags & INIT_DONE)) {
+               u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000;
+
+               ECHECKER(ret, mt9t112_init_camera(client));
+
+               /* Invert PCLK (Data sampled on falling edge of pixclk) */
+               mt9t112_reg_write(ret, client, 0x3C20, param);
+
+               mdelay(5);
+
+               priv->flags |= INIT_DONE;
+       }
+
+       mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
+       mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
+       mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
+
+       mt9t112_set_a_frame_size(client,
+                                priv->frame.width,
+                                priv->frame.height);
+
+       ECHECKER(ret, mt9t112_auto_focus_trigger(client));
+
+       dev_dbg(&client->dev, "format : %d\n", priv->format->code);
+       dev_dbg(&client->dev, "size   : %d x %d\n",
+               priv->frame.width,
+               priv->frame.height);
+
+       CLOCK_INFO(client, EXT_CLOCK);
+
+       return ret;
+}
+
+static int mt9t112_set_params(struct mt9t112_priv *priv,
+                             const struct v4l2_rect *rect,
+                             u32 code)
+{
+       int i;
+
+       /*
+        * get color format
+        */
+       for (i = 0; i < priv->num_formats; i++)
+               if (mt9t112_cfmts[i].code == code)
+                       break;
+
+       if (i == priv->num_formats)
+               return -EINVAL;
+
+       priv->frame  = *rect;
+
+       /*
+        * frame size check
+        */
+       mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
+                           &priv->frame.left, &priv->frame.top);
+
+       priv->format = mt9t112_cfmts + i;
+
+       return 0;
+}
+
+static int mt9t112_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.left = 0;
+               sel->r.top = 0;
+               sel->r.width = MAX_WIDTH;
+               sel->r.height = MAX_HEIGHT;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = priv->frame;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int mt9t112_set_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       const struct v4l2_rect *rect = &sel->r;
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       return mt9t112_set_params(priv, rect, priv->format->code);
+}
+
+static int mt9t112_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->width       = priv->frame.width;
+       mf->height      = priv->frame.height;
+       mf->colorspace  = priv->format->colorspace;
+       mf->code        = priv->format->code;
+       mf->field       = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int mt9t112_s_fmt(struct v4l2_subdev *sd,
+                        struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       struct v4l2_rect rect = {
+               .width = mf->width,
+               .height = mf->height,
+               .left = priv->frame.left,
+               .top = priv->frame.top,
+       };
+       int ret;
+
+       ret = mt9t112_set_params(priv, &rect, mf->code);
+
+       if (!ret)
+               mf->colorspace = priv->format->colorspace;
+
+       return ret;
+}
+
+static int mt9t112_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       unsigned int top, left;
+       int i;
+
+       if (format->pad)
+               return -EINVAL;
+
+       for (i = 0; i < priv->num_formats; i++)
+               if (mt9t112_cfmts[i].code == mf->code)
+                       break;
+
+       if (i == priv->num_formats) {
+               mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+       } else {
+               mf->colorspace  = mt9t112_cfmts[i].colorspace;
+       }
+
+       mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
+
+       mf->field = V4L2_FIELD_NONE;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return mt9t112_s_fmt(sd, mf);
+       cfg->try_fmt = *mf;
+       return 0;
+}
+
+static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       if (code->pad || code->index >= priv->num_formats)
+               return -EINVAL;
+
+       code->code = mt9t112_cfmts[code->index].code;
+
+       return 0;
+}
+
+static int mt9t112_g_mbus_config(struct v4l2_subdev *sd,
+                                struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH |
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
+                                const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       if (soc_camera_apply_board_flags(ssdd, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING)
+               priv->flags |= PCLK_RISING;
+
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
+       .s_stream       = mt9t112_s_stream,
+       .g_mbus_config  = mt9t112_g_mbus_config,
+       .s_mbus_config  = mt9t112_s_mbus_config,
+};
+
+static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = {
+       .enum_mbus_code = mt9t112_enum_mbus_code,
+       .get_selection  = mt9t112_get_selection,
+       .set_selection  = mt9t112_set_selection,
+       .get_fmt        = mt9t112_get_fmt,
+       .set_fmt        = mt9t112_set_fmt,
+};
+
+/************************************************************************
+                       i2c driver
+************************************************************************/
+static const struct v4l2_subdev_ops mt9t112_subdev_ops = {
+       .core   = &mt9t112_subdev_core_ops,
+       .video  = &mt9t112_subdev_video_ops,
+       .pad    = &mt9t112_subdev_pad_ops,
+};
+
+static int mt9t112_camera_probe(struct i2c_client *client)
+{
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       const char          *devname;
+       int                  chipid;
+       int                  ret;
+
+       ret = mt9t112_s_power(&priv->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * check and show chip ID
+        */
+       mt9t112_reg_read(chipid, client, 0x0000);
+
+       switch (chipid) {
+       case 0x2680:
+               devname = "mt9t111";
+               priv->num_formats = 1;
+               break;
+       case 0x2682:
+               devname = "mt9t112";
+               priv->num_formats = ARRAY_SIZE(mt9t112_cfmts);
+               break;
+       default:
+               dev_err(&client->dev, "Product ID error %04x\n", chipid);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
+
+done:
+       mt9t112_s_power(&priv->subdev, 0);
+       return ret;
+}
+
+static int mt9t112_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+       struct mt9t112_priv *priv;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct v4l2_rect rect = {
+               .width = VGA_WIDTH,
+               .height = VGA_HEIGHT,
+               .left = (MAX_WIDTH - VGA_WIDTH) / 2,
+               .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
+       };
+       int ret;
+
+       if (!ssdd || !ssdd->drv_priv) {
+               dev_err(&client->dev, "mt9t112: missing platform data!\n");
+               return -EINVAL;
+       }
+
+       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->info = ssdd->drv_priv;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
+
+       priv->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(priv->clk))
+               return PTR_ERR(priv->clk);
+
+       ret = mt9t112_camera_probe(client);
+
+       /* Cannot fail: using the default supported pixel code */
+       if (!ret)
+               mt9t112_set_params(priv, &rect, MEDIA_BUS_FMT_UYVY8_2X8);
+       else
+               v4l2_clk_put(priv->clk);
+
+       return ret;
+}
+
+static int mt9t112_remove(struct i2c_client *client)
+{
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       v4l2_clk_put(priv->clk);
+       return 0;
+}
+
+static const struct i2c_device_id mt9t112_id[] = {
+       { "mt9t112", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mt9t112_id);
+
+static struct i2c_driver mt9t112_i2c_driver = {
+       .driver = {
+               .name = "mt9t112",
+       },
+       .probe    = mt9t112_probe,
+       .remove   = mt9t112_remove,
+       .id_table = mt9t112_id,
+};
+
+module_i2c_driver(mt9t112_i2c_driver);
+
+MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
+MODULE_AUTHOR("Kuninori Morimoto");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_mt9v022.c b/drivers/media/i2c/soc_camera/soc_mt9v022.c
new file mode 100644 (file)
index 0000000..6d922b1
--- /dev/null
@@ -0,0 +1,1012 @@
+/*
+ * Driver for MT9V022 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+
+#include <media/i2c/mt9v022.h>
+#include <media/soc_camera.h>
+#include <media/drv-intf/soc_mediabus.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-ctrls.h>
+
+/*
+ * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
+ * The platform has to define struct i2c_board_info objects and link to them
+ * from struct soc_camera_host_desc
+ */
+
+static char *sensor_type;
+module_param(sensor_type, charp, S_IRUGO);
+MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
+
+/* mt9v022 selected register addresses */
+#define MT9V022_CHIP_VERSION           0x00
+#define MT9V022_COLUMN_START           0x01
+#define MT9V022_ROW_START              0x02
+#define MT9V022_WINDOW_HEIGHT          0x03
+#define MT9V022_WINDOW_WIDTH           0x04
+#define MT9V022_HORIZONTAL_BLANKING    0x05
+#define MT9V022_VERTICAL_BLANKING      0x06
+#define MT9V022_CHIP_CONTROL           0x07
+#define MT9V022_SHUTTER_WIDTH1         0x08
+#define MT9V022_SHUTTER_WIDTH2         0x09
+#define MT9V022_SHUTTER_WIDTH_CTRL     0x0a
+#define MT9V022_TOTAL_SHUTTER_WIDTH    0x0b
+#define MT9V022_RESET                  0x0c
+#define MT9V022_READ_MODE              0x0d
+#define MT9V022_MONITOR_MODE           0x0e
+#define MT9V022_PIXEL_OPERATION_MODE   0x0f
+#define MT9V022_LED_OUT_CONTROL                0x1b
+#define MT9V022_ADC_MODE_CONTROL       0x1c
+#define MT9V022_REG32                  0x20
+#define MT9V022_ANALOG_GAIN            0x35
+#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
+#define MT9V022_PIXCLK_FV_LV           0x74
+#define MT9V022_DIGITAL_TEST_PATTERN   0x7f
+#define MT9V022_AEC_AGC_ENABLE         0xAF
+#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH        0xBD
+
+/* mt9v024 partial list register addresses changes with respect to mt9v022 */
+#define MT9V024_PIXCLK_FV_LV           0x72
+#define MT9V024_MAX_TOTAL_SHUTTER_WIDTH        0xAD
+
+/* Progressive scan, master, defaults */
+#define MT9V022_CHIP_CONTROL_DEFAULT   0x188
+
+#define MT9V022_MAX_WIDTH              752
+#define MT9V022_MAX_HEIGHT             480
+#define MT9V022_MIN_WIDTH              48
+#define MT9V022_MIN_HEIGHT             32
+#define MT9V022_COLUMN_SKIP            1
+#define MT9V022_ROW_SKIP               4
+
+#define MT9V022_HORIZONTAL_BLANKING_MIN        43
+#define MT9V022_HORIZONTAL_BLANKING_MAX        1023
+#define MT9V022_HORIZONTAL_BLANKING_DEF        94
+#define MT9V022_VERTICAL_BLANKING_MIN  2
+#define MT9V022_VERTICAL_BLANKING_MAX  3000
+#define MT9V022_VERTICAL_BLANKING_DEF  45
+
+#define is_mt9v022_rev3(id)    (id == 0x1313)
+#define is_mt9v024(id)         (id == 0x1324)
+
+/* MT9V022 has only one fixed colorspace per pixelcode */
+struct mt9v022_datafmt {
+       u32     code;
+       enum v4l2_colorspace            colorspace;
+};
+
+/* Find a data format by a pixel code in an array */
+static const struct mt9v022_datafmt *mt9v022_find_datafmt(
+       u32 code, const struct mt9v022_datafmt *fmt,
+       int n)
+{
+       int i;
+       for (i = 0; i < n; i++)
+               if (fmt[i].code == code)
+                       return fmt + i;
+
+       return NULL;
+}
+
+static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
+       /*
+        * Order important: first natively supported,
+        * second supported with a GPIO extender
+        */
+       {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
+};
+
+static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
+       /* Order important - see above */
+       {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
+       {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
+};
+
+/* only registers with different addresses on different mt9v02x sensors */
+struct mt9v02x_register {
+       u8      max_total_shutter_width;
+       u8      pixclk_fv_lv;
+};
+
+static const struct mt9v02x_register mt9v022_register = {
+       .max_total_shutter_width        = MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+       .pixclk_fv_lv                   = MT9V022_PIXCLK_FV_LV,
+};
+
+static const struct mt9v02x_register mt9v024_register = {
+       .max_total_shutter_width        = MT9V024_MAX_TOTAL_SHUTTER_WIDTH,
+       .pixclk_fv_lv                   = MT9V024_PIXCLK_FV_LV,
+};
+
+enum mt9v022_model {
+       MT9V022IX7ATM,
+       MT9V022IX7ATC,
+};
+
+struct mt9v022 {
+       struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct {
+               /* exposure/auto-exposure cluster */
+               struct v4l2_ctrl *autoexposure;
+               struct v4l2_ctrl *exposure;
+       };
+       struct {
+               /* gain/auto-gain cluster */
+               struct v4l2_ctrl *autogain;
+               struct v4l2_ctrl *gain;
+       };
+       struct v4l2_ctrl *hblank;
+       struct v4l2_ctrl *vblank;
+       struct v4l2_rect rect;  /* Sensor window */
+       struct v4l2_clk *clk;
+       const struct mt9v022_datafmt *fmt;
+       const struct mt9v022_datafmt *fmts;
+       const struct mt9v02x_register *reg;
+       int num_fmts;
+       enum mt9v022_model model;
+       u16 chip_control;
+       u16 chip_version;
+       unsigned short y_skip_top;      /* Lines to skip at the top */
+};
+
+static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
+}
+
+static int reg_read(struct i2c_client *client, const u8 reg)
+{
+       return i2c_smbus_read_word_swapped(client, reg);
+}
+
+static int reg_write(struct i2c_client *client, const u8 reg,
+                    const u16 data)
+{
+       return i2c_smbus_write_word_swapped(client, reg, data);
+}
+
+static int reg_set(struct i2c_client *client, const u8 reg,
+                  const u16 data)
+{
+       int ret;
+
+       ret = reg_read(client, reg);
+       if (ret < 0)
+               return ret;
+       return reg_write(client, reg, ret | data);
+}
+
+static int reg_clear(struct i2c_client *client, const u8 reg,
+                    const u16 data)
+{
+       int ret;
+
+       ret = reg_read(client, reg);
+       if (ret < 0)
+               return ret;
+       return reg_write(client, reg, ret & ~data);
+}
+
+static int mt9v022_init(struct i2c_client *client)
+{
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       int ret;
+
+       /*
+        * Almost the default mode: master, parallel, simultaneous, and an
+        * undocumented bit 0x200, which is present in table 7, but not in 8,
+        * plus snapshot mode to disable scan for now
+        */
+       mt9v022->chip_control |= 0x10;
+       ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+       if (!ret)
+               ret = reg_write(client, MT9V022_READ_MODE, 0x300);
+
+       /* All defaults */
+       if (!ret)
+               /* AEC, AGC on */
+               ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
+       if (!ret)
+               ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
+       if (!ret)
+               ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
+       if (!ret)
+               ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480);
+       if (!ret)
+               /* default - auto */
+               ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
+       if (!ret)
+               ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
+       if (!ret)
+               return v4l2_ctrl_handler_setup(&mt9v022->hdl);
+
+       return ret;
+}
+
+static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+       if (enable) {
+               /* Switch to master "normal" mode */
+               mt9v022->chip_control &= ~0x10;
+               if (is_mt9v022_rev3(mt9v022->chip_version) ||
+                   is_mt9v024(mt9v022->chip_version)) {
+                       /*
+                        * Unset snapshot mode specific settings: clear bit 9
+                        * and bit 2 in reg. 0x20 when in normal mode.
+                        */
+                       if (reg_clear(client, MT9V022_REG32, 0x204))
+                               return -EIO;
+               }
+       } else {
+               /* Switch to snapshot mode */
+               mt9v022->chip_control |= 0x10;
+               if (is_mt9v022_rev3(mt9v022->chip_version) ||
+                   is_mt9v024(mt9v022->chip_version)) {
+                       /*
+                        * Required settings for snapshot mode: set bit 9
+                        * (RST enable) and bit 2 (CR enable) in reg. 0x20
+                        * See TechNote TN0960 or TN-09-225.
+                        */
+                       if (reg_set(client, MT9V022_REG32, 0x204))
+                               return -EIO;
+               }
+       }
+
+       if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
+               return -EIO;
+       return 0;
+}
+
+static int mt9v022_set_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       struct v4l2_rect rect = sel->r;
+       int min_row, min_blank;
+       int ret;
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       /* Bayer format - even size lengths */
+       if (mt9v022->fmts == mt9v022_colour_fmts) {
+               rect.width      = ALIGN(rect.width, 2);
+               rect.height     = ALIGN(rect.height, 2);
+               /* Let the user play with the starting pixel */
+       }
+
+       soc_camera_limit_side(&rect.left, &rect.width,
+                    MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
+
+       soc_camera_limit_side(&rect.top, &rect.height,
+                    MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
+
+       /* Like in example app. Contradicts the datasheet though */
+       ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
+       if (ret >= 0) {
+               if (ret & 1) /* Autoexposure */
+                       ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
+                                       rect.height + mt9v022->y_skip_top + 43);
+               /*
+                * If autoexposure is off, there is no need to set
+                * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off
+                * only if the user has set exposure manually, using the
+                * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL.
+                * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH
+                * already contains the correct value.
+                */
+       }
+       /* Setup frame format: defaults apart from width and height */
+       if (!ret)
+               ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
+       if (!ret)
+               ret = reg_write(client, MT9V022_ROW_START, rect.top);
+       /*
+        * mt9v022: min total row time is 660 columns, min blanking is 43
+        * mt9v024: min total row time is 690 columns, min blanking is 61
+        */
+       if (is_mt9v024(mt9v022->chip_version)) {
+               min_row = 690;
+               min_blank = 61;
+       } else {
+               min_row = 660;
+               min_blank = 43;
+       }
+       if (!ret)
+               ret = v4l2_ctrl_s_ctrl(mt9v022->hblank,
+                               rect.width > min_row - min_blank ?
+                               min_blank : min_row - rect.width);
+       if (!ret)
+               ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45);
+       if (!ret)
+               ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
+       if (!ret)
+               ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
+                               rect.height + mt9v022->y_skip_top);
+
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(&client->dev, "Frame %dx%d pixel\n", rect.width, rect.height);
+
+       mt9v022->rect = rect;
+
+       return 0;
+}
+
+static int mt9v022_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.left = MT9V022_COLUMN_SKIP;
+               sel->r.top = MT9V022_ROW_SKIP;
+               sel->r.width = MT9V022_MAX_WIDTH;
+               sel->r.height = MT9V022_MAX_HEIGHT;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = mt9v022->rect;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int mt9v022_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->width       = mt9v022->rect.width;
+       mf->height      = mt9v022->rect.height;
+       mf->code        = mt9v022->fmt->code;
+       mf->colorspace  = mt9v022->fmt->colorspace;
+       mf->field       = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int mt9v022_s_fmt(struct v4l2_subdev *sd,
+                        const struct mt9v022_datafmt *fmt,
+                        struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       struct v4l2_subdev_selection sel = {
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+               .target = V4L2_SEL_TGT_CROP,
+               .r.left = mt9v022->rect.left,
+               .r.top = mt9v022->rect.top,
+               .r.width = mf->width,
+               .r.height = mf->height,
+       };
+       int ret;
+
+       /*
+        * The caller provides a supported format, as verified per call to
+        * .set_fmt(FORMAT_TRY), datawidth is from our supported format list
+        */
+       switch (mf->code) {
+       case MEDIA_BUS_FMT_Y8_1X8:
+       case MEDIA_BUS_FMT_Y10_1X10:
+               if (mt9v022->model != MT9V022IX7ATM)
+                       return -EINVAL;
+               break;
+       case MEDIA_BUS_FMT_SBGGR8_1X8:
+       case MEDIA_BUS_FMT_SBGGR10_1X10:
+               if (mt9v022->model != MT9V022IX7ATC)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* No support for scaling on this camera, just crop. */
+       ret = mt9v022_set_selection(sd, NULL, &sel);
+       if (!ret) {
+               mf->width       = mt9v022->rect.width;
+               mf->height      = mt9v022->rect.height;
+               mt9v022->fmt    = fmt;
+               mf->colorspace  = fmt->colorspace;
+       }
+
+       return ret;
+}
+
+static int mt9v022_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       const struct mt9v022_datafmt *fmt;
+       int align = mf->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
+               mf->code == MEDIA_BUS_FMT_SBGGR10_1X10;
+
+       if (format->pad)
+               return -EINVAL;
+
+       v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
+               MT9V022_MAX_WIDTH, align,
+               &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
+               MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
+
+       fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
+                                  mt9v022->num_fmts);
+       if (!fmt) {
+               fmt = mt9v022->fmt;
+               mf->code = fmt->code;
+       }
+
+       mf->colorspace  = fmt->colorspace;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return mt9v022_s_fmt(sd, fmt, mf);
+       cfg->try_fmt = *mf;
+       return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int mt9v022_g_register(struct v4l2_subdev *sd,
+                             struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       reg->size = 2;
+       reg->val = reg_read(client, reg->reg);
+
+       if (reg->val > 0xffff)
+               return -EIO;
+
+       return 0;
+}
+
+static int mt9v022_s_register(struct v4l2_subdev *sd,
+                             const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       if (reg_write(client, reg->reg, reg->val) < 0)
+               return -EIO;
+
+       return 0;
+}
+#endif
+
+static int mt9v022_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+       return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
+}
+
+static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct mt9v022 *mt9v022 = container_of(ctrl->handler,
+                                              struct mt9v022, hdl);
+       struct v4l2_subdev *sd = &mt9v022->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct v4l2_ctrl *gain = mt9v022->gain;
+       struct v4l2_ctrl *exp = mt9v022->exposure;
+       unsigned long range;
+       int data;
+
+       switch (ctrl->id) {
+       case V4L2_CID_AUTOGAIN:
+               data = reg_read(client, MT9V022_ANALOG_GAIN);
+               if (data < 0)
+                       return -EIO;
+
+               range = gain->maximum - gain->minimum;
+               gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
+               return 0;
+       case V4L2_CID_EXPOSURE_AUTO:
+               data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
+               if (data < 0)
+                       return -EIO;
+
+               range = exp->maximum - exp->minimum;
+               exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
+               return 0;
+       case V4L2_CID_HBLANK:
+               data = reg_read(client, MT9V022_HORIZONTAL_BLANKING);
+               if (data < 0)
+                       return -EIO;
+               ctrl->val = data;
+               return 0;
+       case V4L2_CID_VBLANK:
+               data = reg_read(client, MT9V022_VERTICAL_BLANKING);
+               if (data < 0)
+                       return -EIO;
+               ctrl->val = data;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct mt9v022 *mt9v022 = container_of(ctrl->handler,
+                                              struct mt9v022, hdl);
+       struct v4l2_subdev *sd = &mt9v022->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int data;
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               if (ctrl->val)
+                       data = reg_set(client, MT9V022_READ_MODE, 0x10);
+               else
+                       data = reg_clear(client, MT9V022_READ_MODE, 0x10);
+               if (data < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_HFLIP:
+               if (ctrl->val)
+                       data = reg_set(client, MT9V022_READ_MODE, 0x20);
+               else
+                       data = reg_clear(client, MT9V022_READ_MODE, 0x20);
+               if (data < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_AUTOGAIN:
+               if (ctrl->val) {
+                       if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
+                               return -EIO;
+               } else {
+                       struct v4l2_ctrl *gain = mt9v022->gain;
+                       /* mt9v022 has minimum == default */
+                       unsigned long range = gain->maximum - gain->minimum;
+                       /* Valid values 16 to 64, 32 to 64 must be even. */
+                       unsigned long gain_val = ((gain->val - (s32)gain->minimum) *
+                                             48 + range / 2) / range + 16;
+
+                       if (gain_val >= 32)
+                               gain_val &= ~1;
+
+                       /*
+                        * The user wants to set gain manually, hope, she
+                        * knows, what she's doing... Switch AGC off.
+                        */
+                       if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
+                               return -EIO;
+
+                       dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
+                               reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
+                       if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
+                               return -EIO;
+               }
+               return 0;
+       case V4L2_CID_EXPOSURE_AUTO:
+               if (ctrl->val == V4L2_EXPOSURE_AUTO) {
+                       data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
+               } else {
+                       struct v4l2_ctrl *exp = mt9v022->exposure;
+                       unsigned long range = exp->maximum - exp->minimum;
+                       unsigned long shutter = ((exp->val - (s32)exp->minimum) *
+                                       479 + range / 2) / range + 1;
+
+                       /*
+                        * The user wants to set shutter width manually, hope,
+                        * she knows, what she's doing... Switch AEC off.
+                        */
+                       data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
+                       if (data < 0)
+                               return -EIO;
+                       dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
+                                       reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
+                                       shutter);
+                       if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
+                                               shutter) < 0)
+                               return -EIO;
+               }
+               return 0;
+       case V4L2_CID_HBLANK:
+               if (reg_write(client, MT9V022_HORIZONTAL_BLANKING,
+                               ctrl->val) < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_VBLANK:
+               if (reg_write(client, MT9V022_VERTICAL_BLANKING,
+                               ctrl->val) < 0)
+                       return -EIO;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
+static int mt9v022_video_probe(struct i2c_client *client)
+{
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       s32 data;
+       int ret;
+       unsigned long flags;
+
+       ret = mt9v022_s_power(&mt9v022->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Read out the chip version register */
+       data = reg_read(client, MT9V022_CHIP_VERSION);
+
+       /* must be 0x1311, 0x1313 or 0x1324 */
+       if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
+               ret = -ENODEV;
+               dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
+                        data);
+               goto ei2c;
+       }
+
+       mt9v022->chip_version = data;
+
+       mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
+                       &mt9v022_register;
+
+       /* Soft reset */
+       ret = reg_write(client, MT9V022_RESET, 1);
+       if (ret < 0)
+               goto ei2c;
+       /* 15 clock cycles */
+       udelay(200);
+       if (reg_read(client, MT9V022_RESET)) {
+               dev_err(&client->dev, "Resetting MT9V022 failed!\n");
+               if (ret > 0)
+                       ret = -EIO;
+               goto ei2c;
+       }
+
+       /* Set monochrome or colour sensor type */
+       if (sensor_type && (!strcmp("colour", sensor_type) ||
+                           !strcmp("color", sensor_type))) {
+               ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
+               mt9v022->model = MT9V022IX7ATC;
+               mt9v022->fmts = mt9v022_colour_fmts;
+       } else {
+               ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
+               mt9v022->model = MT9V022IX7ATM;
+               mt9v022->fmts = mt9v022_monochrome_fmts;
+       }
+
+       if (ret < 0)
+               goto ei2c;
+
+       mt9v022->num_fmts = 0;
+
+       /*
+        * This is a 10bit sensor, so by default we only allow 10bit.
+        * The platform may support different bus widths due to
+        * different routing of the data lines.
+        */
+       if (ssdd->query_bus_param)
+               flags = ssdd->query_bus_param(ssdd);
+       else
+               flags = SOCAM_DATAWIDTH_10;
+
+       if (flags & SOCAM_DATAWIDTH_10)
+               mt9v022->num_fmts++;
+       else
+               mt9v022->fmts++;
+
+       if (flags & SOCAM_DATAWIDTH_8)
+               mt9v022->num_fmts++;
+
+       mt9v022->fmt = &mt9v022->fmts[0];
+
+       dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
+                data, mt9v022->model == MT9V022IX7ATM ?
+                "monochrome" : "colour");
+
+       ret = mt9v022_init(client);
+       if (ret < 0)
+               dev_err(&client->dev, "Failed to initialise the camera\n");
+
+ei2c:
+       mt9v022_s_power(&mt9v022->subdev, 0);
+       return ret;
+}
+
+static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+       *lines = mt9v022->y_skip_top;
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
+       .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
+       .s_ctrl = mt9v022_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = mt9v022_g_register,
+       .s_register     = mt9v022_s_register,
+#endif
+       .s_power        = mt9v022_s_power,
+};
+
+static int mt9v022_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+       if (code->pad || code->index >= mt9v022->num_fmts)
+               return -EINVAL;
+
+       code->code = mt9v022->fmts[code->index].code;
+       return 0;
+}
+
+static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
+                                const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg);
+       unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
+       int ret;
+       u16 pixclk = 0;
+
+       if (ssdd->set_bus_param) {
+               ret = ssdd->set_bus_param(ssdd, 1 << (bps - 1));
+               if (ret)
+                       return ret;
+       } else if (bps != 10) {
+               /*
+                * Without board specific bus width settings we only support the
+                * sensors native bus width
+                */
+               return -EINVAL;
+       }
+
+       if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+               pixclk |= 0x10;
+
+       if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
+               pixclk |= 0x1;
+
+       if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
+               pixclk |= 0x2;
+
+       ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk);
+       if (ret < 0)
+               return ret;
+
+       if (!(flags & V4L2_MBUS_MASTER))
+               mt9v022->chip_control &= ~0x8;
+
+       ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
+               pixclk, mt9v022->chip_control);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
+       .s_stream       = mt9v022_s_stream,
+       .g_mbus_config  = mt9v022_g_mbus_config,
+       .s_mbus_config  = mt9v022_s_mbus_config,
+};
+
+static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
+       .g_skip_top_lines       = mt9v022_g_skip_top_lines,
+};
+
+static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = {
+       .enum_mbus_code = mt9v022_enum_mbus_code,
+       .get_selection  = mt9v022_get_selection,
+       .set_selection  = mt9v022_set_selection,
+       .get_fmt        = mt9v022_get_fmt,
+       .set_fmt        = mt9v022_set_fmt,
+};
+
+static const struct v4l2_subdev_ops mt9v022_subdev_ops = {
+       .core   = &mt9v022_subdev_core_ops,
+       .video  = &mt9v022_subdev_video_ops,
+       .sensor = &mt9v022_subdev_sensor_ops,
+       .pad    = &mt9v022_subdev_pad_ops,
+};
+
+static int mt9v022_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+       struct mt9v022 *mt9v022;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct mt9v022_platform_data *pdata;
+       int ret;
+
+       if (!ssdd) {
+               dev_err(&client->dev, "MT9V022 driver needs platform data\n");
+               return -EINVAL;
+       }
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
+               dev_warn(&adapter->dev,
+                        "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
+               return -EIO;
+       }
+
+       mt9v022 = devm_kzalloc(&client->dev, sizeof(struct mt9v022), GFP_KERNEL);
+       if (!mt9v022)
+               return -ENOMEM;
+
+       pdata = ssdd->drv_priv;
+       v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
+       v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
+       v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+       mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 64);
+
+       /*
+        * Simulated autoexposure. If enabled, we calculate shutter width
+        * ourselves in the driver based on vertical blanking and frame width
+        */
+       mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
+                       &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
+                       V4L2_EXPOSURE_AUTO);
+       mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
+
+       mt9v022->hblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_HBLANK, MT9V022_HORIZONTAL_BLANKING_MIN,
+                       MT9V022_HORIZONTAL_BLANKING_MAX, 1,
+                       MT9V022_HORIZONTAL_BLANKING_DEF);
+
+       mt9v022->vblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_VBLANK, MT9V022_VERTICAL_BLANKING_MIN,
+                       MT9V022_VERTICAL_BLANKING_MAX, 1,
+                       MT9V022_VERTICAL_BLANKING_DEF);
+
+       mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
+       if (mt9v022->hdl.error) {
+               int err = mt9v022->hdl.error;
+
+               dev_err(&client->dev, "control initialisation err %d\n", err);
+               return err;
+       }
+       v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
+                               V4L2_EXPOSURE_MANUAL, true);
+       v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
+
+       mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
+
+       /*
+        * On some platforms the first read out line is corrupted.
+        * Workaround it by skipping if indicated by platform data.
+        */
+       mt9v022->y_skip_top     = pdata ? pdata->y_skip_top : 0;
+       mt9v022->rect.left      = MT9V022_COLUMN_SKIP;
+       mt9v022->rect.top       = MT9V022_ROW_SKIP;
+       mt9v022->rect.width     = MT9V022_MAX_WIDTH;
+       mt9v022->rect.height    = MT9V022_MAX_HEIGHT;
+
+       mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(mt9v022->clk)) {
+               ret = PTR_ERR(mt9v022->clk);
+               goto eclkget;
+       }
+
+       ret = mt9v022_video_probe(client);
+       if (ret) {
+               v4l2_clk_put(mt9v022->clk);
+eclkget:
+               v4l2_ctrl_handler_free(&mt9v022->hdl);
+       }
+
+       return ret;
+}
+
+static int mt9v022_remove(struct i2c_client *client)
+{
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       v4l2_clk_put(mt9v022->clk);
+       v4l2_device_unregister_subdev(&mt9v022->subdev);
+       if (ssdd->free_bus)
+               ssdd->free_bus(ssdd);
+       v4l2_ctrl_handler_free(&mt9v022->hdl);
+
+       return 0;
+}
+static const struct i2c_device_id mt9v022_id[] = {
+       { "mt9v022", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mt9v022_id);
+
+static struct i2c_driver mt9v022_i2c_driver = {
+       .driver = {
+               .name = "mt9v022",
+       },
+       .probe          = mt9v022_probe,
+       .remove         = mt9v022_remove,
+       .id_table       = mt9v022_id,
+};
+
+module_i2c_driver(mt9v022_i2c_driver);
+
+MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/soc_camera/soc_ov5642.c b/drivers/media/i2c/soc_camera/soc_ov5642.c
new file mode 100644 (file)
index 0000000..0931898
--- /dev/null
@@ -0,0 +1,1087 @@
+/*
+ * Driver for OV5642 CMOS Image Sensor from Omnivision
+ *
+ * Copyright (C) 2011, Bastian Hecht <hechtb@gmail.com>
+ *
+ * Based on Sony IMX074 Camera Driver
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * Based on Omnivision OV7670 Camera Driver
+ * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/module.h>
+#include <linux/v4l2-mediabus.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+
+/* OV5642 registers */
+#define REG_CHIP_ID_HIGH               0x300a
+#define REG_CHIP_ID_LOW                        0x300b
+
+#define REG_WINDOW_START_X_HIGH                0x3800
+#define REG_WINDOW_START_X_LOW         0x3801
+#define REG_WINDOW_START_Y_HIGH                0x3802
+#define REG_WINDOW_START_Y_LOW         0x3803
+#define REG_WINDOW_WIDTH_HIGH          0x3804
+#define REG_WINDOW_WIDTH_LOW           0x3805
+#define REG_WINDOW_HEIGHT_HIGH         0x3806
+#define REG_WINDOW_HEIGHT_LOW          0x3807
+#define REG_OUT_WIDTH_HIGH             0x3808
+#define REG_OUT_WIDTH_LOW              0x3809
+#define REG_OUT_HEIGHT_HIGH            0x380a
+#define REG_OUT_HEIGHT_LOW             0x380b
+#define REG_OUT_TOTAL_WIDTH_HIGH       0x380c
+#define REG_OUT_TOTAL_WIDTH_LOW                0x380d
+#define REG_OUT_TOTAL_HEIGHT_HIGH      0x380e
+#define REG_OUT_TOTAL_HEIGHT_LOW       0x380f
+#define REG_OUTPUT_FORMAT              0x4300
+#define REG_ISP_CTRL_01                        0x5001
+#define REG_AVG_WINDOW_END_X_HIGH      0x5682
+#define REG_AVG_WINDOW_END_X_LOW       0x5683
+#define REG_AVG_WINDOW_END_Y_HIGH      0x5686
+#define REG_AVG_WINDOW_END_Y_LOW       0x5687
+
+/* active pixel array size */
+#define OV5642_SENSOR_SIZE_X   2592
+#define OV5642_SENSOR_SIZE_Y   1944
+
+/*
+ * About OV5642 resolution, cropping and binning:
+ * This sensor supports it all, at least in the feature description.
+ * Unfortunately, no combination of appropriate registers settings could make
+ * the chip work the intended way. As it works with predefined register lists,
+ * some undocumented registers are presumably changed there to achieve their
+ * goals.
+ * This driver currently only works for resolutions up to 720 lines with a
+ * 1:1 scale. Hopefully these restrictions will be removed in the future.
+ */
+#define OV5642_MAX_WIDTH       OV5642_SENSOR_SIZE_X
+#define OV5642_MAX_HEIGHT      720
+
+/* default sizes */
+#define OV5642_DEFAULT_WIDTH   1280
+#define OV5642_DEFAULT_HEIGHT  OV5642_MAX_HEIGHT
+
+/* minimum extra blanking */
+#define BLANKING_EXTRA_WIDTH           500
+#define BLANKING_EXTRA_HEIGHT          20
+
+/*
+ * the sensor's autoexposure is buggy when setting total_height low.
+ * It tries to expose longer than 1 frame period without taking care of it
+ * and this leads to weird output. So we set 1000 lines as minimum.
+ */
+#define BLANKING_MIN_HEIGHT            1000
+
+struct regval_list {
+       u16 reg_num;
+       u8 value;
+};
+
+static struct regval_list ov5642_default_regs_init[] = {
+       { 0x3103, 0x93 },
+       { 0x3008, 0x82 },
+       { 0x3017, 0x7f },
+       { 0x3018, 0xfc },
+       { 0x3810, 0xc2 },
+       { 0x3615, 0xf0 },
+       { 0x3000, 0x0  },
+       { 0x3001, 0x0  },
+       { 0x3002, 0x0  },
+       { 0x3003, 0x0  },
+       { 0x3004, 0xff },
+       { 0x3030, 0x2b },
+       { 0x3011, 0x8  },
+       { 0x3010, 0x10 },
+       { 0x3604, 0x60 },
+       { 0x3622, 0x60 },
+       { 0x3621, 0x9  },
+       { 0x3709, 0x0  },
+       { 0x4000, 0x21 },
+       { 0x401d, 0x22 },
+       { 0x3600, 0x54 },
+       { 0x3605, 0x4  },
+       { 0x3606, 0x3f },
+       { 0x3c01, 0x80 },
+       { 0x300d, 0x22 },
+       { 0x3623, 0x22 },
+       { 0x5000, 0x4f },
+       { 0x5020, 0x4  },
+       { 0x5181, 0x79 },
+       { 0x5182, 0x0  },
+       { 0x5185, 0x22 },
+       { 0x5197, 0x1  },
+       { 0x5500, 0xa  },
+       { 0x5504, 0x0  },
+       { 0x5505, 0x7f },
+       { 0x5080, 0x8  },
+       { 0x300e, 0x18 },
+       { 0x4610, 0x0  },
+       { 0x471d, 0x5  },
+       { 0x4708, 0x6  },
+       { 0x370c, 0xa0 },
+       { 0x5687, 0x94 },
+       { 0x501f, 0x0  },
+       { 0x5000, 0x4f },
+       { 0x5001, 0xcf },
+       { 0x4300, 0x30 },
+       { 0x4300, 0x30 },
+       { 0x460b, 0x35 },
+       { 0x471d, 0x0  },
+       { 0x3002, 0xc  },
+       { 0x3002, 0x0  },
+       { 0x4713, 0x3  },
+       { 0x471c, 0x50 },
+       { 0x4721, 0x2  },
+       { 0x4402, 0x90 },
+       { 0x460c, 0x22 },
+       { 0x3815, 0x44 },
+       { 0x3503, 0x7  },
+       { 0x3501, 0x73 },
+       { 0x3502, 0x80 },
+       { 0x350b, 0x0  },
+       { 0x3818, 0xc8 },
+       { 0x3824, 0x11 },
+       { 0x3a00, 0x78 },
+       { 0x3a1a, 0x4  },
+       { 0x3a13, 0x30 },
+       { 0x3a18, 0x0  },
+       { 0x3a19, 0x7c },
+       { 0x3a08, 0x12 },
+       { 0x3a09, 0xc0 },
+       { 0x3a0a, 0xf  },
+       { 0x3a0b, 0xa0 },
+       { 0x350c, 0x7  },
+       { 0x350d, 0xd0 },
+       { 0x3a0d, 0x8  },
+       { 0x3a0e, 0x6  },
+       { 0x3500, 0x0  },
+       { 0x3501, 0x0  },
+       { 0x3502, 0x0  },
+       { 0x350a, 0x0  },
+       { 0x350b, 0x0  },
+       { 0x3503, 0x0  },
+       { 0x3a0f, 0x3c },
+       { 0x3a10, 0x32 },
+       { 0x3a1b, 0x3c },
+       { 0x3a1e, 0x32 },
+       { 0x3a11, 0x80 },
+       { 0x3a1f, 0x20 },
+       { 0x3030, 0x2b },
+       { 0x3a02, 0x0  },
+       { 0x3a03, 0x7d },
+       { 0x3a04, 0x0  },
+       { 0x3a14, 0x0  },
+       { 0x3a15, 0x7d },
+       { 0x3a16, 0x0  },
+       { 0x3a00, 0x78 },
+       { 0x3a08, 0x9  },
+       { 0x3a09, 0x60 },
+       { 0x3a0a, 0x7  },
+       { 0x3a0b, 0xd0 },
+       { 0x3a0d, 0x10 },
+       { 0x3a0e, 0xd  },
+       { 0x4407, 0x4  },
+       { 0x5193, 0x70 },
+       { 0x589b, 0x0  },
+       { 0x589a, 0xc0 },
+       { 0x401e, 0x20 },
+       { 0x4001, 0x42 },
+       { 0x401c, 0x6  },
+       { 0x3825, 0xac },
+       { 0x3827, 0xc  },
+       { 0x528a, 0x1  },
+       { 0x528b, 0x4  },
+       { 0x528c, 0x8  },
+       { 0x528d, 0x10 },
+       { 0x528e, 0x20 },
+       { 0x528f, 0x28 },
+       { 0x5290, 0x30 },
+       { 0x5292, 0x0  },
+       { 0x5293, 0x1  },
+       { 0x5294, 0x0  },
+       { 0x5295, 0x4  },
+       { 0x5296, 0x0  },
+       { 0x5297, 0x8  },
+       { 0x5298, 0x0  },
+       { 0x5299, 0x10 },
+       { 0x529a, 0x0  },
+       { 0x529b, 0x20 },
+       { 0x529c, 0x0  },
+       { 0x529d, 0x28 },
+       { 0x529e, 0x0  },
+       { 0x529f, 0x30 },
+       { 0x5282, 0x0  },
+       { 0x5300, 0x0  },
+       { 0x5301, 0x20 },
+       { 0x5302, 0x0  },
+       { 0x5303, 0x7c },
+       { 0x530c, 0x0  },
+       { 0x530d, 0xc  },
+       { 0x530e, 0x20 },
+       { 0x530f, 0x80 },
+       { 0x5310, 0x20 },
+       { 0x5311, 0x80 },
+       { 0x5308, 0x20 },
+       { 0x5309, 0x40 },
+       { 0x5304, 0x0  },
+       { 0x5305, 0x30 },
+       { 0x5306, 0x0  },
+       { 0x5307, 0x80 },
+       { 0x5314, 0x8  },
+       { 0x5315, 0x20 },
+       { 0x5319, 0x30 },
+       { 0x5316, 0x10 },
+       { 0x5317, 0x0  },
+       { 0x5318, 0x2  },
+       { 0x5380, 0x1  },
+       { 0x5381, 0x0  },
+       { 0x5382, 0x0  },
+       { 0x5383, 0x4e },
+       { 0x5384, 0x0  },
+       { 0x5385, 0xf  },
+       { 0x5386, 0x0  },
+       { 0x5387, 0x0  },
+       { 0x5388, 0x1  },
+       { 0x5389, 0x15 },
+       { 0x538a, 0x0  },
+       { 0x538b, 0x31 },
+       { 0x538c, 0x0  },
+       { 0x538d, 0x0  },
+       { 0x538e, 0x0  },
+       { 0x538f, 0xf  },
+       { 0x5390, 0x0  },
+       { 0x5391, 0xab },
+       { 0x5392, 0x0  },
+       { 0x5393, 0xa2 },
+       { 0x5394, 0x8  },
+       { 0x5480, 0x14 },
+       { 0x5481, 0x21 },
+       { 0x5482, 0x36 },
+       { 0x5483, 0x57 },
+       { 0x5484, 0x65 },
+       { 0x5485, 0x71 },
+       { 0x5486, 0x7d },
+       { 0x5487, 0x87 },
+       { 0x5488, 0x91 },
+       { 0x5489, 0x9a },
+       { 0x548a, 0xaa },
+       { 0x548b, 0xb8 },
+       { 0x548c, 0xcd },
+       { 0x548d, 0xdd },
+       { 0x548e, 0xea },
+       { 0x548f, 0x1d },
+       { 0x5490, 0x5  },
+       { 0x5491, 0x0  },
+       { 0x5492, 0x4  },
+       { 0x5493, 0x20 },
+       { 0x5494, 0x3  },
+       { 0x5495, 0x60 },
+       { 0x5496, 0x2  },
+       { 0x5497, 0xb8 },
+       { 0x5498, 0x2  },
+       { 0x5499, 0x86 },
+       { 0x549a, 0x2  },
+       { 0x549b, 0x5b },
+       { 0x549c, 0x2  },
+       { 0x549d, 0x3b },
+       { 0x549e, 0x2  },
+       { 0x549f, 0x1c },
+       { 0x54a0, 0x2  },
+       { 0x54a1, 0x4  },
+       { 0x54a2, 0x1  },
+       { 0x54a3, 0xed },
+       { 0x54a4, 0x1  },
+       { 0x54a5, 0xc5 },
+       { 0x54a6, 0x1  },
+       { 0x54a7, 0xa5 },
+       { 0x54a8, 0x1  },
+       { 0x54a9, 0x6c },
+       { 0x54aa, 0x1  },
+       { 0x54ab, 0x41 },
+       { 0x54ac, 0x1  },
+       { 0x54ad, 0x20 },
+       { 0x54ae, 0x0  },
+       { 0x54af, 0x16 },
+       { 0x54b0, 0x1  },
+       { 0x54b1, 0x20 },
+       { 0x54b2, 0x0  },
+       { 0x54b3, 0x10 },
+       { 0x54b4, 0x0  },
+       { 0x54b5, 0xf0 },
+       { 0x54b6, 0x0  },
+       { 0x54b7, 0xdf },
+       { 0x5402, 0x3f },
+       { 0x5403, 0x0  },
+       { 0x3406, 0x0  },
+       { 0x5180, 0xff },
+       { 0x5181, 0x52 },
+       { 0x5182, 0x11 },
+       { 0x5183, 0x14 },
+       { 0x5184, 0x25 },
+       { 0x5185, 0x24 },
+       { 0x5186, 0x6  },
+       { 0x5187, 0x8  },
+       { 0x5188, 0x8  },
+       { 0x5189, 0x7c },
+       { 0x518a, 0x60 },
+       { 0x518b, 0xb2 },
+       { 0x518c, 0xb2 },
+       { 0x518d, 0x44 },
+       { 0x518e, 0x3d },
+       { 0x518f, 0x58 },
+       { 0x5190, 0x46 },
+       { 0x5191, 0xf8 },
+       { 0x5192, 0x4  },
+       { 0x5193, 0x70 },
+       { 0x5194, 0xf0 },
+       { 0x5195, 0xf0 },
+       { 0x5196, 0x3  },
+       { 0x5197, 0x1  },
+       { 0x5198, 0x4  },
+       { 0x5199, 0x12 },
+       { 0x519a, 0x4  },
+       { 0x519b, 0x0  },
+       { 0x519c, 0x6  },
+       { 0x519d, 0x82 },
+       { 0x519e, 0x0  },
+       { 0x5025, 0x80 },
+       { 0x3a0f, 0x38 },
+       { 0x3a10, 0x30 },
+       { 0x3a1b, 0x3a },
+       { 0x3a1e, 0x2e },
+       { 0x3a11, 0x60 },
+       { 0x3a1f, 0x10 },
+       { 0x5688, 0xa6 },
+       { 0x5689, 0x6a },
+       { 0x568a, 0xea },
+       { 0x568b, 0xae },
+       { 0x568c, 0xa6 },
+       { 0x568d, 0x6a },
+       { 0x568e, 0x62 },
+       { 0x568f, 0x26 },
+       { 0x5583, 0x40 },
+       { 0x5584, 0x40 },
+       { 0x5580, 0x2  },
+       { 0x5000, 0xcf },
+       { 0x5800, 0x27 },
+       { 0x5801, 0x19 },
+       { 0x5802, 0x12 },
+       { 0x5803, 0xf  },
+       { 0x5804, 0x10 },
+       { 0x5805, 0x15 },
+       { 0x5806, 0x1e },
+       { 0x5807, 0x2f },
+       { 0x5808, 0x15 },
+       { 0x5809, 0xd  },
+       { 0x580a, 0xa  },
+       { 0x580b, 0x9  },
+       { 0x580c, 0xa  },
+       { 0x580d, 0xc  },
+       { 0x580e, 0x12 },
+       { 0x580f, 0x19 },
+       { 0x5810, 0xb  },
+       { 0x5811, 0x7  },
+       { 0x5812, 0x4  },
+       { 0x5813, 0x3  },
+       { 0x5814, 0x3  },
+       { 0x5815, 0x6  },
+       { 0x5816, 0xa  },
+       { 0x5817, 0xf  },
+       { 0x5818, 0xa  },
+       { 0x5819, 0x5  },
+       { 0x581a, 0x1  },
+       { 0x581b, 0x0  },
+       { 0x581c, 0x0  },
+       { 0x581d, 0x3  },
+       { 0x581e, 0x8  },
+       { 0x581f, 0xc  },
+       { 0x5820, 0xa  },
+       { 0x5821, 0x5  },
+       { 0x5822, 0x1  },
+       { 0x5823, 0x0  },
+       { 0x5824, 0x0  },
+       { 0x5825, 0x3  },
+       { 0x5826, 0x8  },
+       { 0x5827, 0xc  },
+       { 0x5828, 0xe  },
+       { 0x5829, 0x8  },
+       { 0x582a, 0x6  },
+       { 0x582b, 0x4  },
+       { 0x582c, 0x5  },
+       { 0x582d, 0x7  },
+       { 0x582e, 0xb  },
+       { 0x582f, 0x12 },
+       { 0x5830, 0x18 },
+       { 0x5831, 0x10 },
+       { 0x5832, 0xc  },
+       { 0x5833, 0xa  },
+       { 0x5834, 0xb  },
+       { 0x5835, 0xe  },
+       { 0x5836, 0x15 },
+       { 0x5837, 0x19 },
+       { 0x5838, 0x32 },
+       { 0x5839, 0x1f },
+       { 0x583a, 0x18 },
+       { 0x583b, 0x16 },
+       { 0x583c, 0x17 },
+       { 0x583d, 0x1e },
+       { 0x583e, 0x26 },
+       { 0x583f, 0x53 },
+       { 0x5840, 0x10 },
+       { 0x5841, 0xf  },
+       { 0x5842, 0xd  },
+       { 0x5843, 0xc  },
+       { 0x5844, 0xe  },
+       { 0x5845, 0x9  },
+       { 0x5846, 0x11 },
+       { 0x5847, 0x10 },
+       { 0x5848, 0x10 },
+       { 0x5849, 0x10 },
+       { 0x584a, 0x10 },
+       { 0x584b, 0xe  },
+       { 0x584c, 0x10 },
+       { 0x584d, 0x10 },
+       { 0x584e, 0x11 },
+       { 0x584f, 0x10 },
+       { 0x5850, 0xf  },
+       { 0x5851, 0xc  },
+       { 0x5852, 0xf  },
+       { 0x5853, 0x10 },
+       { 0x5854, 0x10 },
+       { 0x5855, 0xf  },
+       { 0x5856, 0xe  },
+       { 0x5857, 0xb  },
+       { 0x5858, 0x10 },
+       { 0x5859, 0xd  },
+       { 0x585a, 0xd  },
+       { 0x585b, 0xc  },
+       { 0x585c, 0xc  },
+       { 0x585d, 0xc  },
+       { 0x585e, 0xb  },
+       { 0x585f, 0xc  },
+       { 0x5860, 0xc  },
+       { 0x5861, 0xc  },
+       { 0x5862, 0xd  },
+       { 0x5863, 0x8  },
+       { 0x5864, 0x11 },
+       { 0x5865, 0x18 },
+       { 0x5866, 0x18 },
+       { 0x5867, 0x19 },
+       { 0x5868, 0x17 },
+       { 0x5869, 0x19 },
+       { 0x586a, 0x16 },
+       { 0x586b, 0x13 },
+       { 0x586c, 0x13 },
+       { 0x586d, 0x12 },
+       { 0x586e, 0x13 },
+       { 0x586f, 0x16 },
+       { 0x5870, 0x14 },
+       { 0x5871, 0x12 },
+       { 0x5872, 0x10 },
+       { 0x5873, 0x11 },
+       { 0x5874, 0x11 },
+       { 0x5875, 0x16 },
+       { 0x5876, 0x14 },
+       { 0x5877, 0x11 },
+       { 0x5878, 0x10 },
+       { 0x5879, 0xf  },
+       { 0x587a, 0x10 },
+       { 0x587b, 0x14 },
+       { 0x587c, 0x13 },
+       { 0x587d, 0x12 },
+       { 0x587e, 0x11 },
+       { 0x587f, 0x11 },
+       { 0x5880, 0x12 },
+       { 0x5881, 0x15 },
+       { 0x5882, 0x14 },
+       { 0x5883, 0x15 },
+       { 0x5884, 0x15 },
+       { 0x5885, 0x15 },
+       { 0x5886, 0x13 },
+       { 0x5887, 0x17 },
+       { 0x3710, 0x10 },
+       { 0x3632, 0x51 },
+       { 0x3702, 0x10 },
+       { 0x3703, 0xb2 },
+       { 0x3704, 0x18 },
+       { 0x370b, 0x40 },
+       { 0x370d, 0x3  },
+       { 0x3631, 0x1  },
+       { 0x3632, 0x52 },
+       { 0x3606, 0x24 },
+       { 0x3620, 0x96 },
+       { 0x5785, 0x7  },
+       { 0x3a13, 0x30 },
+       { 0x3600, 0x52 },
+       { 0x3604, 0x48 },
+       { 0x3606, 0x1b },
+       { 0x370d, 0xb  },
+       { 0x370f, 0xc0 },
+       { 0x3709, 0x1  },
+       { 0x3823, 0x0  },
+       { 0x5007, 0x0  },
+       { 0x5009, 0x0  },
+       { 0x5011, 0x0  },
+       { 0x5013, 0x0  },
+       { 0x519e, 0x0  },
+       { 0x5086, 0x0  },
+       { 0x5087, 0x0  },
+       { 0x5088, 0x0  },
+       { 0x5089, 0x0  },
+       { 0x302b, 0x0  },
+       { 0x3503, 0x7  },
+       { 0x3011, 0x8  },
+       { 0x350c, 0x2  },
+       { 0x350d, 0xe4 },
+       { 0x3621, 0xc9 },
+       { 0x370a, 0x81 },
+       { 0xffff, 0xff },
+};
+
+static struct regval_list ov5642_default_regs_finalise[] = {
+       { 0x3810, 0xc2 },
+       { 0x3818, 0xc9 },
+       { 0x381c, 0x10 },
+       { 0x381d, 0xa0 },
+       { 0x381e, 0x5  },
+       { 0x381f, 0xb0 },
+       { 0x3820, 0x0  },
+       { 0x3821, 0x0  },
+       { 0x3824, 0x11 },
+       { 0x3a08, 0x1b },
+       { 0x3a09, 0xc0 },
+       { 0x3a0a, 0x17 },
+       { 0x3a0b, 0x20 },
+       { 0x3a0d, 0x2  },
+       { 0x3a0e, 0x1  },
+       { 0x401c, 0x4  },
+       { 0x5682, 0x5  },
+       { 0x5683, 0x0  },
+       { 0x5686, 0x2  },
+       { 0x5687, 0xcc },
+       { 0x5001, 0x4f },
+       { 0x589b, 0x6  },
+       { 0x589a, 0xc5 },
+       { 0x3503, 0x0  },
+       { 0x460c, 0x20 },
+       { 0x460b, 0x37 },
+       { 0x471c, 0xd0 },
+       { 0x471d, 0x5  },
+       { 0x3815, 0x1  },
+       { 0x3818, 0xc1 },
+       { 0x501f, 0x0  },
+       { 0x5002, 0xe0 },
+       { 0x4300, 0x32 }, /* UYVY */
+       { 0x3002, 0x1c },
+       { 0x4800, 0x14 },
+       { 0x4801, 0xf  },
+       { 0x3007, 0x3b },
+       { 0x300e, 0x4  },
+       { 0x4803, 0x50 },
+       { 0x3815, 0x1  },
+       { 0x4713, 0x2  },
+       { 0x4842, 0x1  },
+       { 0x300f, 0xe  },
+       { 0x3003, 0x3  },
+       { 0x3003, 0x1  },
+       { 0xffff, 0xff },
+};
+
+struct ov5642_datafmt {
+       u32     code;
+       enum v4l2_colorspace            colorspace;
+};
+
+struct ov5642 {
+       struct v4l2_subdev              subdev;
+       const struct ov5642_datafmt     *fmt;
+       struct v4l2_rect                crop_rect;
+       struct v4l2_clk                 *clk;
+
+       /* blanking information */
+       int total_width;
+       int total_height;
+};
+
+static const struct ov5642_datafmt ov5642_colour_fmts[] = {
+       {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
+};
+
+static struct ov5642 *to_ov5642(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client), struct ov5642, subdev);
+}
+
+/* Find a data format by a pixel code in an array */
+static const struct ov5642_datafmt
+                       *ov5642_find_datafmt(u32 code)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ov5642_colour_fmts); i++)
+               if (ov5642_colour_fmts[i].code == code)
+                       return ov5642_colour_fmts + i;
+
+       return NULL;
+}
+
+static int reg_read(struct i2c_client *client, u16 reg, u8 *val)
+{
+       int ret;
+       /* We have 16-bit i2c addresses - care for endianness */
+       unsigned char data[2] = { reg >> 8, reg & 0xff };
+
+       ret = i2c_master_send(client, data, 2);
+       if (ret < 2) {
+               dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
+                       __func__, reg);
+               return ret < 0 ? ret : -EIO;
+       }
+
+       ret = i2c_master_recv(client, val, 1);
+       if (ret < 1) {
+               dev_err(&client->dev, "%s: i2c read error, reg: %x\n",
+                               __func__, reg);
+               return ret < 0 ? ret : -EIO;
+       }
+       return 0;
+}
+
+static int reg_write(struct i2c_client *client, u16 reg, u8 val)
+{
+       int ret;
+       unsigned char data[3] = { reg >> 8, reg & 0xff, val };
+
+       ret = i2c_master_send(client, data, 3);
+       if (ret < 3) {
+               dev_err(&client->dev, "%s: i2c write error, reg: %x\n",
+                       __func__, reg);
+               return ret < 0 ? ret : -EIO;
+       }
+
+       return 0;
+}
+
+/*
+ * convenience function to write 16 bit register values that are split up
+ * into two consecutive high and low parts
+ */
+static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
+{
+       int ret;
+
+       ret = reg_write(client, reg, val16 >> 8);
+       if (ret)
+               return ret;
+       return reg_write(client, reg + 1, val16 & 0x00ff);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+       u8 val;
+
+       if (reg->reg & ~0xffff)
+               return -EINVAL;
+
+       reg->size = 1;
+
+       ret = reg_read(client, reg->reg, &val);
+       if (!ret)
+               reg->val = (__u64)val;
+
+       return ret;
+}
+
+static int ov5642_set_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg & ~0xffff || reg->val & ~0xff)
+               return -EINVAL;
+
+       return reg_write(client, reg->reg, reg->val);
+}
+#endif
+
+static int ov5642_write_array(struct i2c_client *client,
+                               struct regval_list *vals)
+{
+       while (vals->reg_num != 0xffff || vals->value != 0xff) {
+               int ret = reg_write(client, vals->reg_num, vals->value);
+               if (ret < 0)
+                       return ret;
+               vals++;
+       }
+       dev_dbg(&client->dev, "Register list loaded\n");
+       return 0;
+}
+
+static int ov5642_set_resolution(struct v4l2_subdev *sd)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+       int width = priv->crop_rect.width;
+       int height = priv->crop_rect.height;
+       int total_width = priv->total_width;
+       int total_height = priv->total_height;
+       int start_x = (OV5642_SENSOR_SIZE_X - width) / 2;
+       int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2;
+       int ret;
+
+       /*
+        * This should set the starting point for cropping.
+        * Doesn't work so far.
+        */
+       ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x);
+       if (!ret)
+               ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y);
+       if (!ret) {
+               priv->crop_rect.left = start_x;
+               priv->crop_rect.top = start_y;
+       }
+
+       if (!ret)
+               ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width);
+       if (!ret)
+               ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height);
+       if (ret)
+               return ret;
+       priv->crop_rect.width = width;
+       priv->crop_rect.height = height;
+
+       /* Set the output window size. Only 1:1 scale is supported so far. */
+       ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width);
+       if (!ret)
+               ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height);
+
+       /* Total width = output size + blanking */
+       if (!ret)
+               ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width);
+       if (!ret)
+               ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height);
+
+       /* Sets the window for AWB calculations */
+       if (!ret)
+               ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width);
+       if (!ret)
+               ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height);
+
+       return ret;
+}
+
+static int ov5642_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+       const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->width = priv->crop_rect.width;
+       mf->height = priv->crop_rect.height;
+
+       if (!fmt) {
+               if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+                       return -EINVAL;
+               mf->code        = ov5642_colour_fmts[0].code;
+               mf->colorspace  = ov5642_colour_fmts[0].colorspace;
+       }
+
+       mf->field       = V4L2_FIELD_NONE;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               priv->fmt = fmt;
+       else
+               cfg->try_fmt = *mf;
+       return 0;
+}
+
+static int ov5642_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+
+       const struct ov5642_datafmt *fmt = priv->fmt;
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->code        = fmt->code;
+       mf->colorspace  = fmt->colorspace;
+       mf->width       = priv->crop_rect.width;
+       mf->height      = priv->crop_rect.height;
+       mf->field       = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int ov5642_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index >= ARRAY_SIZE(ov5642_colour_fmts))
+               return -EINVAL;
+
+       code->code = ov5642_colour_fmts[code->index].code;
+       return 0;
+}
+
+static int ov5642_set_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+       struct v4l2_rect rect = sel->r;
+       int ret;
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1,
+                             &rect.height, 32, OV5642_MAX_HEIGHT, 1, 0);
+
+       priv->crop_rect.width   = rect.width;
+       priv->crop_rect.height  = rect.height;
+       priv->total_width       = rect.width + BLANKING_EXTRA_WIDTH;
+       priv->total_height      = max_t(int, rect.height +
+                                                       BLANKING_EXTRA_HEIGHT,
+                                                       BLANKING_MIN_HEIGHT);
+       priv->crop_rect.width           = rect.width;
+       priv->crop_rect.height          = rect.height;
+
+       ret = ov5642_write_array(client, ov5642_default_regs_init);
+       if (!ret)
+               ret = ov5642_set_resolution(sd);
+       if (!ret)
+               ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+
+       return ret;
+}
+
+static int ov5642_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.left = 0;
+               sel->r.top = 0;
+               sel->r.width = OV5642_MAX_WIDTH;
+               sel->r.height = OV5642_MAX_HEIGHT;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = priv->crop_rect;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       cfg->type = V4L2_MBUS_CSI2_DPHY;
+       cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
+                                       V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+       return 0;
+}
+
+static int ov5642_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct ov5642 *priv = to_ov5642(client);
+       int ret;
+
+       if (!on)
+               return soc_camera_power_off(&client->dev, ssdd, priv->clk);
+
+       ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
+       if (ret < 0)
+               return ret;
+
+       ret = ov5642_write_array(client, ov5642_default_regs_init);
+       if (!ret)
+               ret = ov5642_set_resolution(sd);
+       if (!ret)
+               ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+
+       return ret;
+}
+
+static const struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
+       .g_mbus_config  = ov5642_g_mbus_config,
+};
+
+static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = {
+       .enum_mbus_code = ov5642_enum_mbus_code,
+       .get_selection  = ov5642_get_selection,
+       .set_selection  = ov5642_set_selection,
+       .get_fmt        = ov5642_get_fmt,
+       .set_fmt        = ov5642_set_fmt,
+};
+
+static const struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
+       .s_power        = ov5642_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = ov5642_get_register,
+       .s_register     = ov5642_set_register,
+#endif
+};
+
+static const struct v4l2_subdev_ops ov5642_subdev_ops = {
+       .core   = &ov5642_subdev_core_ops,
+       .video  = &ov5642_subdev_video_ops,
+       .pad    = &ov5642_subdev_pad_ops,
+};
+
+static int ov5642_video_probe(struct i2c_client *client)
+{
+       struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+       int ret;
+       u8 id_high, id_low;
+       u16 id;
+
+       ret = ov5642_s_power(subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Read sensor Model ID */
+       ret = reg_read(client, REG_CHIP_ID_HIGH, &id_high);
+       if (ret < 0)
+               goto done;
+
+       id = id_high << 8;
+
+       ret = reg_read(client, REG_CHIP_ID_LOW, &id_low);
+       if (ret < 0)
+               goto done;
+
+       id |= id_low;
+
+       dev_info(&client->dev, "Chip ID 0x%04x detected\n", id);
+
+       if (id != 0x5642) {
+               ret = -ENODEV;
+               goto done;
+       }
+
+       ret = 0;
+
+done:
+       ov5642_s_power(subdev, 0);
+       return ret;
+}
+
+static int ov5642_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct ov5642 *priv;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       int ret;
+
+       if (!ssdd) {
+               dev_err(&client->dev, "OV5642: missing platform data!\n");
+               return -EINVAL;
+       }
+
+       priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
+
+       priv->fmt               = &ov5642_colour_fmts[0];
+
+       priv->crop_rect.width   = OV5642_DEFAULT_WIDTH;
+       priv->crop_rect.height  = OV5642_DEFAULT_HEIGHT;
+       priv->crop_rect.left    = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
+       priv->crop_rect.top     = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
+       priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
+       priv->total_height = BLANKING_MIN_HEIGHT;
+
+       priv->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(priv->clk))
+               return PTR_ERR(priv->clk);
+
+       ret = ov5642_video_probe(client);
+       if (ret < 0)
+               v4l2_clk_put(priv->clk);
+
+       return ret;
+}
+
+static int ov5642_remove(struct i2c_client *client)
+{
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct ov5642 *priv = to_ov5642(client);
+
+       v4l2_clk_put(priv->clk);
+       if (ssdd->free_bus)
+               ssdd->free_bus(ssdd);
+
+       return 0;
+}
+
+static const struct i2c_device_id ov5642_id[] = {
+       { "ov5642", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ov5642_id);
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id ov5642_of_match[] = {
+       { .compatible = "ovti,ov5642" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, ov5642_of_match);
+#endif
+
+static struct i2c_driver ov5642_i2c_driver = {
+       .driver = {
+               .name = "ov5642",
+               .of_match_table = of_match_ptr(ov5642_of_match),
+       },
+       .probe          = ov5642_probe,
+       .remove         = ov5642_remove,
+       .id_table       = ov5642_id,
+};
+
+module_i2c_driver(ov5642_i2c_driver);
+
+MODULE_DESCRIPTION("Omnivision OV5642 Camera driver");
+MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_ov772x.c b/drivers/media/i2c/soc_camera/soc_ov772x.c
new file mode 100644 (file)
index 0000000..fafd372
--- /dev/null
@@ -0,0 +1,1123 @@
+/*
+ * ov772x Camera Driver
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov7670 and soc_camera_platform driver,
+ *
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+
+#include <media/i2c/ov772x.h>
+#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-image-sizes.h>
+
+/*
+ * register offset
+ */
+#define GAIN        0x00 /* AGC - Gain control gain setting */
+#define BLUE        0x01 /* AWB - Blue channel gain setting */
+#define RED         0x02 /* AWB - Red   channel gain setting */
+#define GREEN       0x03 /* AWB - Green channel gain setting */
+#define COM1        0x04 /* Common control 1 */
+#define BAVG        0x05 /* U/B Average Level */
+#define GAVG        0x06 /* Y/Gb Average Level */
+#define RAVG        0x07 /* V/R Average Level */
+#define AECH        0x08 /* Exposure Value - AEC MSBs */
+#define COM2        0x09 /* Common control 2 */
+#define PID         0x0A /* Product ID Number MSB */
+#define VER         0x0B /* Product ID Number LSB */
+#define COM3        0x0C /* Common control 3 */
+#define COM4        0x0D /* Common control 4 */
+#define COM5        0x0E /* Common control 5 */
+#define COM6        0x0F /* Common control 6 */
+#define AEC         0x10 /* Exposure Value */
+#define CLKRC       0x11 /* Internal clock */
+#define COM7        0x12 /* Common control 7 */
+#define COM8        0x13 /* Common control 8 */
+#define COM9        0x14 /* Common control 9 */
+#define COM10       0x15 /* Common control 10 */
+#define REG16       0x16 /* Register 16 */
+#define HSTART      0x17 /* Horizontal sensor size */
+#define HSIZE       0x18 /* Horizontal frame (HREF column) end high 8-bit */
+#define VSTART      0x19 /* Vertical frame (row) start high 8-bit */
+#define VSIZE       0x1A /* Vertical sensor size */
+#define PSHFT       0x1B /* Data format - pixel delay select */
+#define MIDH        0x1C /* Manufacturer ID byte - high */
+#define MIDL        0x1D /* Manufacturer ID byte - low  */
+#define LAEC        0x1F /* Fine AEC value */
+#define COM11       0x20 /* Common control 11 */
+#define BDBASE      0x22 /* Banding filter Minimum AEC value */
+#define DBSTEP      0x23 /* Banding filter Maximum Setp */
+#define AEW         0x24 /* AGC/AEC - Stable operating region (upper limit) */
+#define AEB         0x25 /* AGC/AEC - Stable operating region (lower limit) */
+#define VPT         0x26 /* AGC/AEC Fast mode operating region */
+#define REG28       0x28 /* Register 28 */
+#define HOUTSIZE    0x29 /* Horizontal data output size MSBs */
+#define EXHCH       0x2A /* Dummy pixel insert MSB */
+#define EXHCL       0x2B /* Dummy pixel insert LSB */
+#define VOUTSIZE    0x2C /* Vertical data output size MSBs */
+#define ADVFL       0x2D /* LSB of insert dummy lines in Vertical direction */
+#define ADVFH       0x2E /* MSG of insert dummy lines in Vertical direction */
+#define YAVE        0x2F /* Y/G Channel Average value */
+#define LUMHTH      0x30 /* Histogram AEC/AGC Luminance high level threshold */
+#define LUMLTH      0x31 /* Histogram AEC/AGC Luminance low  level threshold */
+#define HREF        0x32 /* Image start and size control */
+#define DM_LNL      0x33 /* Dummy line low  8 bits */
+#define DM_LNH      0x34 /* Dummy line high 8 bits */
+#define ADOFF_B     0x35 /* AD offset compensation value for B  channel */
+#define ADOFF_R     0x36 /* AD offset compensation value for R  channel */
+#define ADOFF_GB    0x37 /* AD offset compensation value for Gb channel */
+#define ADOFF_GR    0x38 /* AD offset compensation value for Gr channel */
+#define OFF_B       0x39 /* Analog process B  channel offset value */
+#define OFF_R       0x3A /* Analog process R  channel offset value */
+#define OFF_GB      0x3B /* Analog process Gb channel offset value */
+#define OFF_GR      0x3C /* Analog process Gr channel offset value */
+#define COM12       0x3D /* Common control 12 */
+#define COM13       0x3E /* Common control 13 */
+#define COM14       0x3F /* Common control 14 */
+#define COM15       0x40 /* Common control 15*/
+#define COM16       0x41 /* Common control 16 */
+#define TGT_B       0x42 /* BLC blue channel target value */
+#define TGT_R       0x43 /* BLC red  channel target value */
+#define TGT_GB      0x44 /* BLC Gb   channel target value */
+#define TGT_GR      0x45 /* BLC Gr   channel target value */
+/* for ov7720 */
+#define LCC0        0x46 /* Lens correction control 0 */
+#define LCC1        0x47 /* Lens correction option 1 - X coordinate */
+#define LCC2        0x48 /* Lens correction option 2 - Y coordinate */
+#define LCC3        0x49 /* Lens correction option 3 */
+#define LCC4        0x4A /* Lens correction option 4 - radius of the circular */
+#define LCC5        0x4B /* Lens correction option 5 */
+#define LCC6        0x4C /* Lens correction option 6 */
+/* for ov7725 */
+#define LC_CTR      0x46 /* Lens correction control */
+#define LC_XC       0x47 /* X coordinate of lens correction center relative */
+#define LC_YC       0x48 /* Y coordinate of lens correction center relative */
+#define LC_COEF     0x49 /* Lens correction coefficient */
+#define LC_RADI     0x4A /* Lens correction radius */
+#define LC_COEFB    0x4B /* Lens B channel compensation coefficient */
+#define LC_COEFR    0x4C /* Lens R channel compensation coefficient */
+
+#define FIXGAIN     0x4D /* Analog fix gain amplifer */
+#define AREF0       0x4E /* Sensor reference control */
+#define AREF1       0x4F /* Sensor reference current control */
+#define AREF2       0x50 /* Analog reference control */
+#define AREF3       0x51 /* ADC    reference control */
+#define AREF4       0x52 /* ADC    reference control */
+#define AREF5       0x53 /* ADC    reference control */
+#define AREF6       0x54 /* Analog reference control */
+#define AREF7       0x55 /* Analog reference control */
+#define UFIX        0x60 /* U channel fixed value output */
+#define VFIX        0x61 /* V channel fixed value output */
+#define AWBB_BLK    0x62 /* AWB option for advanced AWB */
+#define AWB_CTRL0   0x63 /* AWB control byte 0 */
+#define DSP_CTRL1   0x64 /* DSP control byte 1 */
+#define DSP_CTRL2   0x65 /* DSP control byte 2 */
+#define DSP_CTRL3   0x66 /* DSP control byte 3 */
+#define DSP_CTRL4   0x67 /* DSP control byte 4 */
+#define AWB_BIAS    0x68 /* AWB BLC level clip */
+#define AWB_CTRL1   0x69 /* AWB control  1 */
+#define AWB_CTRL2   0x6A /* AWB control  2 */
+#define AWB_CTRL3   0x6B /* AWB control  3 */
+#define AWB_CTRL4   0x6C /* AWB control  4 */
+#define AWB_CTRL5   0x6D /* AWB control  5 */
+#define AWB_CTRL6   0x6E /* AWB control  6 */
+#define AWB_CTRL7   0x6F /* AWB control  7 */
+#define AWB_CTRL8   0x70 /* AWB control  8 */
+#define AWB_CTRL9   0x71 /* AWB control  9 */
+#define AWB_CTRL10  0x72 /* AWB control 10 */
+#define AWB_CTRL11  0x73 /* AWB control 11 */
+#define AWB_CTRL12  0x74 /* AWB control 12 */
+#define AWB_CTRL13  0x75 /* AWB control 13 */
+#define AWB_CTRL14  0x76 /* AWB control 14 */
+#define AWB_CTRL15  0x77 /* AWB control 15 */
+#define AWB_CTRL16  0x78 /* AWB control 16 */
+#define AWB_CTRL17  0x79 /* AWB control 17 */
+#define AWB_CTRL18  0x7A /* AWB control 18 */
+#define AWB_CTRL19  0x7B /* AWB control 19 */
+#define AWB_CTRL20  0x7C /* AWB control 20 */
+#define AWB_CTRL21  0x7D /* AWB control 21 */
+#define GAM1        0x7E /* Gamma Curve  1st segment input end point */
+#define GAM2        0x7F /* Gamma Curve  2nd segment input end point */
+#define GAM3        0x80 /* Gamma Curve  3rd segment input end point */
+#define GAM4        0x81 /* Gamma Curve  4th segment input end point */
+#define GAM5        0x82 /* Gamma Curve  5th segment input end point */
+#define GAM6        0x83 /* Gamma Curve  6th segment input end point */
+#define GAM7        0x84 /* Gamma Curve  7th segment input end point */
+#define GAM8        0x85 /* Gamma Curve  8th segment input end point */
+#define GAM9        0x86 /* Gamma Curve  9th segment input end point */
+#define GAM10       0x87 /* Gamma Curve 10th segment input end point */
+#define GAM11       0x88 /* Gamma Curve 11th segment input end point */
+#define GAM12       0x89 /* Gamma Curve 12th segment input end point */
+#define GAM13       0x8A /* Gamma Curve 13th segment input end point */
+#define GAM14       0x8B /* Gamma Curve 14th segment input end point */
+#define GAM15       0x8C /* Gamma Curve 15th segment input end point */
+#define SLOP        0x8D /* Gamma curve highest segment slope */
+#define DNSTH       0x8E /* De-noise threshold */
+#define EDGE_STRNGT 0x8F /* Edge strength  control when manual mode */
+#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
+#define DNSOFF      0x91 /* Auto De-noise threshold control */
+#define EDGE_UPPER  0x92 /* Edge strength upper limit when Auto mode */
+#define EDGE_LOWER  0x93 /* Edge strength lower limit when Auto mode */
+#define MTX1        0x94 /* Matrix coefficient 1 */
+#define MTX2        0x95 /* Matrix coefficient 2 */
+#define MTX3        0x96 /* Matrix coefficient 3 */
+#define MTX4        0x97 /* Matrix coefficient 4 */
+#define MTX5        0x98 /* Matrix coefficient 5 */
+#define MTX6        0x99 /* Matrix coefficient 6 */
+#define MTX_CTRL    0x9A /* Matrix control */
+#define BRIGHT      0x9B /* Brightness control */
+#define CNTRST      0x9C /* Contrast contrast */
+#define CNTRST_CTRL 0x9D /* Contrast contrast center */
+#define UVAD_J0     0x9E /* Auto UV adjust contrast 0 */
+#define UVAD_J1     0x9F /* Auto UV adjust contrast 1 */
+#define SCAL0       0xA0 /* Scaling control 0 */
+#define SCAL1       0xA1 /* Scaling control 1 */
+#define SCAL2       0xA2 /* Scaling control 2 */
+#define FIFODLYM    0xA3 /* FIFO manual mode delay control */
+#define FIFODLYA    0xA4 /* FIFO auto   mode delay control */
+#define SDE         0xA6 /* Special digital effect control */
+#define USAT        0xA7 /* U component saturation control */
+#define VSAT        0xA8 /* V component saturation control */
+/* for ov7720 */
+#define HUE0        0xA9 /* Hue control 0 */
+#define HUE1        0xAA /* Hue control 1 */
+/* for ov7725 */
+#define HUECOS      0xA9 /* Cosine value */
+#define HUESIN      0xAA /* Sine value */
+
+#define SIGN        0xAB /* Sign bit for Hue and contrast */
+#define DSPAUTO     0xAC /* DSP auto function ON/OFF control */
+
+/*
+ * register detail
+ */
+
+/* COM2 */
+#define SOFT_SLEEP_MODE 0x10   /* Soft sleep mode */
+                               /* Output drive capability */
+#define OCAP_1x         0x00   /* 1x */
+#define OCAP_2x         0x01   /* 2x */
+#define OCAP_3x         0x02   /* 3x */
+#define OCAP_4x         0x03   /* 4x */
+
+/* COM3 */
+#define SWAP_MASK       (SWAP_RGB | SWAP_YUV | SWAP_ML)
+#define IMG_MASK        (VFLIP_IMG | HFLIP_IMG)
+
+#define VFLIP_IMG       0x80   /* Vertical flip image ON/OFF selection */
+#define HFLIP_IMG       0x40   /* Horizontal mirror image ON/OFF selection */
+#define SWAP_RGB        0x20   /* Swap B/R  output sequence in RGB mode */
+#define SWAP_YUV        0x10   /* Swap Y/UV output sequence in YUV mode */
+#define SWAP_ML         0x08   /* Swap output MSB/LSB */
+                               /* Tri-state option for output clock */
+#define NOTRI_CLOCK     0x04   /*   0: Tri-state    at this period */
+                               /*   1: No tri-state at this period */
+                               /* Tri-state option for output data */
+#define NOTRI_DATA      0x02   /*   0: Tri-state    at this period */
+                               /*   1: No tri-state at this period */
+#define SCOLOR_TEST     0x01   /* Sensor color bar test pattern */
+
+/* COM4 */
+                               /* PLL frequency control */
+#define PLL_BYPASS      0x00   /*  00: Bypass PLL */
+#define PLL_4x          0x40   /*  01: PLL 4x */
+#define PLL_6x          0x80   /*  10: PLL 6x */
+#define PLL_8x          0xc0   /*  11: PLL 8x */
+                               /* AEC evaluate window */
+#define AEC_FULL        0x00   /*  00: Full window */
+#define AEC_1p2         0x10   /*  01: 1/2  window */
+#define AEC_1p4         0x20   /*  10: 1/4  window */
+#define AEC_2p3         0x30   /*  11: Low 2/3 window */
+
+/* COM5 */
+#define AFR_ON_OFF      0x80   /* Auto frame rate control ON/OFF selection */
+#define AFR_SPPED       0x40   /* Auto frame rate control speed selection */
+                               /* Auto frame rate max rate control */
+#define AFR_NO_RATE     0x00   /*     No  reduction of frame rate */
+#define AFR_1p2         0x10   /*     Max reduction to 1/2 frame rate */
+#define AFR_1p4         0x20   /*     Max reduction to 1/4 frame rate */
+#define AFR_1p8         0x30   /* Max reduction to 1/8 frame rate */
+                               /* Auto frame rate active point control */
+#define AF_2x           0x00   /*     Add frame when AGC reaches  2x gain */
+#define AF_4x           0x04   /*     Add frame when AGC reaches  4x gain */
+#define AF_8x           0x08   /*     Add frame when AGC reaches  8x gain */
+#define AF_16x          0x0c   /* Add frame when AGC reaches 16x gain */
+                               /* AEC max step control */
+#define AEC_NO_LIMIT    0x01   /*   0 : AEC incease step has limit */
+                               /*   1 : No limit to AEC increase step */
+
+/* COM7 */
+                               /* SCCB Register Reset */
+#define SCCB_RESET      0x80   /*   0 : No change */
+                               /*   1 : Resets all registers to default */
+                               /* Resolution selection */
+#define SLCT_MASK       0x40   /*   Mask of VGA or QVGA */
+#define SLCT_VGA        0x00   /*   0 : VGA */
+#define SLCT_QVGA       0x40   /*   1 : QVGA */
+#define ITU656_ON_OFF   0x20   /* ITU656 protocol ON/OFF selection */
+#define SENSOR_RAW     0x10    /* Sensor RAW */
+                               /* RGB output format control */
+#define FMT_MASK        0x0c   /*      Mask of color format */
+#define FMT_GBR422      0x00   /*      00 : GBR 4:2:2 */
+#define FMT_RGB565      0x04   /*      01 : RGB 565 */
+#define FMT_RGB555      0x08   /*      10 : RGB 555 */
+#define FMT_RGB444      0x0c   /* 11 : RGB 444 */
+                               /* Output format control */
+#define OFMT_MASK       0x03    /*      Mask of output format */
+#define OFMT_YUV        0x00   /*      00 : YUV */
+#define OFMT_P_BRAW     0x01   /*      01 : Processed Bayer RAW */
+#define OFMT_RGB        0x02   /*      10 : RGB */
+#define OFMT_BRAW       0x03   /* 11 : Bayer RAW */
+
+/* COM8 */
+#define FAST_ALGO       0x80   /* Enable fast AGC/AEC algorithm */
+                               /* AEC Setp size limit */
+#define UNLMT_STEP      0x40   /*   0 : Step size is limited */
+                               /*   1 : Unlimited step size */
+#define BNDF_ON_OFF     0x20   /* Banding filter ON/OFF */
+#define AEC_BND         0x10   /* Enable AEC below banding value */
+#define AEC_ON_OFF      0x08   /* Fine AEC ON/OFF control */
+#define AGC_ON          0x04   /* AGC Enable */
+#define AWB_ON          0x02   /* AWB Enable */
+#define AEC_ON          0x01   /* AEC Enable */
+
+/* COM9 */
+#define BASE_AECAGC     0x80   /* Histogram or average based AEC/AGC */
+                               /* Automatic gain ceiling - maximum AGC value */
+#define GAIN_2x         0x00   /*    000 :   2x */
+#define GAIN_4x         0x10   /*    001 :   4x */
+#define GAIN_8x         0x20   /*    010 :   8x */
+#define GAIN_16x        0x30   /*    011 :  16x */
+#define GAIN_32x        0x40   /*    100 :  32x */
+#define GAIN_64x        0x50   /* 101 :  64x */
+#define GAIN_128x       0x60   /* 110 : 128x */
+#define DROP_VSYNC      0x04   /* Drop VSYNC output of corrupt frame */
+#define DROP_HREF       0x02   /* Drop HREF  output of corrupt frame */
+
+/* COM11 */
+#define SGLF_ON_OFF     0x02   /* Single frame ON/OFF selection */
+#define SGLF_TRIG       0x01   /* Single frame transfer trigger */
+
+/* HREF */
+#define HREF_VSTART_SHIFT      6       /* VSTART LSB */
+#define HREF_HSTART_SHIFT      4       /* HSTART 2 LSBs */
+#define HREF_VSIZE_SHIFT       2       /* VSIZE LSB */
+#define HREF_HSIZE_SHIFT       0       /* HSIZE 2 LSBs */
+
+/* EXHCH */
+#define EXHCH_VSIZE_SHIFT      2       /* VOUTSIZE LSB */
+#define EXHCH_HSIZE_SHIFT      0       /* HOUTSIZE 2 LSBs */
+
+/* DSP_CTRL1 */
+#define FIFO_ON         0x80   /* FIFO enable/disable selection */
+#define UV_ON_OFF       0x40   /* UV adjust function ON/OFF selection */
+#define YUV444_2_422    0x20   /* YUV444 to 422 UV channel option selection */
+#define CLR_MTRX_ON_OFF 0x10   /* Color matrix ON/OFF selection */
+#define INTPLT_ON_OFF   0x08   /* Interpolation ON/OFF selection */
+#define GMM_ON_OFF      0x04   /* Gamma function ON/OFF selection */
+#define AUTO_BLK_ON_OFF 0x02   /* Black defect auto correction ON/OFF */
+#define AUTO_WHT_ON_OFF 0x01   /* White define auto correction ON/OFF */
+
+/* DSP_CTRL3 */
+#define UV_MASK         0x80   /* UV output sequence option */
+#define UV_ON           0x80   /*   ON */
+#define UV_OFF          0x00   /*   OFF */
+#define CBAR_MASK       0x20   /* DSP Color bar mask */
+#define CBAR_ON         0x20   /*   ON */
+#define CBAR_OFF        0x00   /*   OFF */
+
+/* DSP_CTRL4 */
+#define DSP_OFMT_YUV   0x00
+#define DSP_OFMT_RGB   0x00
+#define DSP_OFMT_RAW8  0x02
+#define DSP_OFMT_RAW10 0x03
+
+/* DSPAUTO (DSP Auto Function ON/OFF Control) */
+#define AWB_ACTRL       0x80 /* AWB auto threshold control */
+#define DENOISE_ACTRL   0x40 /* De-noise auto threshold control */
+#define EDGE_ACTRL      0x20 /* Edge enhancement auto strength control */
+#define UV_ACTRL        0x10 /* UV adjust auto slope control */
+#define SCAL0_ACTRL     0x08 /* Auto scaling factor control */
+#define SCAL1_2_ACTRL   0x04 /* Auto scaling factor control */
+
+#define OV772X_MAX_WIDTH       VGA_WIDTH
+#define OV772X_MAX_HEIGHT      VGA_HEIGHT
+
+/*
+ * ID
+ */
+#define OV7720  0x7720
+#define OV7725  0x7721
+#define VERSION(pid, ver) ((pid<<8)|(ver&0xFF))
+
+/*
+ * struct
+ */
+
+struct ov772x_color_format {
+       u32 code;
+       enum v4l2_colorspace colorspace;
+       u8 dsp3;
+       u8 dsp4;
+       u8 com3;
+       u8 com7;
+};
+
+struct ov772x_win_size {
+       char                     *name;
+       unsigned char             com7_bit;
+       struct v4l2_rect          rect;
+};
+
+struct ov772x_priv {
+       struct v4l2_subdev                subdev;
+       struct v4l2_ctrl_handler          hdl;
+       struct v4l2_clk                  *clk;
+       struct ov772x_camera_info        *info;
+       const struct ov772x_color_format *cfmt;
+       const struct ov772x_win_size     *win;
+       unsigned short                    flag_vflip:1;
+       unsigned short                    flag_hflip:1;
+       /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
+       unsigned short                    band_filter;
+};
+
+/*
+ * supported color format list
+ */
+static const struct ov772x_color_format ov772x_cfmts[] = {
+       {
+               .code           = MEDIA_BUS_FMT_YUYV8_2X8,
+               .colorspace     = V4L2_COLORSPACE_JPEG,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = SWAP_YUV,
+               .com7           = OFMT_YUV,
+       },
+       {
+               .code           = MEDIA_BUS_FMT_YVYU8_2X8,
+               .colorspace     = V4L2_COLORSPACE_JPEG,
+               .dsp3           = UV_ON,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = SWAP_YUV,
+               .com7           = OFMT_YUV,
+       },
+       {
+               .code           = MEDIA_BUS_FMT_UYVY8_2X8,
+               .colorspace     = V4L2_COLORSPACE_JPEG,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = 0x0,
+               .com7           = OFMT_YUV,
+       },
+       {
+               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = SWAP_RGB,
+               .com7           = FMT_RGB555 | OFMT_RGB,
+       },
+       {
+               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = 0x0,
+               .com7           = FMT_RGB555 | OFMT_RGB,
+       },
+       {
+               .code           = MEDIA_BUS_FMT_RGB565_2X8_LE,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = SWAP_RGB,
+               .com7           = FMT_RGB565 | OFMT_RGB,
+       },
+       {
+               .code           = MEDIA_BUS_FMT_RGB565_2X8_BE,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_YUV,
+               .com3           = 0x0,
+               .com7           = FMT_RGB565 | OFMT_RGB,
+       },
+       {
+               /* Setting DSP4 to DSP_OFMT_RAW8 still gives 10-bit output,
+                * regardless of the COM7 value. We can thus only support 10-bit
+                * Bayer until someone figures it out.
+                */
+               .code           = MEDIA_BUS_FMT_SBGGR10_1X10,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .dsp3           = 0x0,
+               .dsp4           = DSP_OFMT_RAW10,
+               .com3           = 0x0,
+               .com7           = SENSOR_RAW | OFMT_BRAW,
+       },
+};
+
+
+/*
+ * window size list
+ */
+
+static const struct ov772x_win_size ov772x_win_sizes[] = {
+       {
+               .name     = "VGA",
+               .com7_bit = SLCT_VGA,
+               .rect = {
+                       .left = 140,
+                       .top = 14,
+                       .width = VGA_WIDTH,
+                       .height = VGA_HEIGHT,
+               },
+       }, {
+               .name     = "QVGA",
+               .com7_bit = SLCT_QVGA,
+               .rect = {
+                       .left = 252,
+                       .top = 6,
+                       .width = QVGA_WIDTH,
+                       .height = QVGA_HEIGHT,
+               },
+       },
+};
+
+/*
+ * general function
+ */
+
+static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct ov772x_priv, subdev);
+}
+
+static inline int ov772x_read(struct i2c_client *client, u8 addr)
+{
+       return i2c_smbus_read_byte_data(client, addr);
+}
+
+static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
+{
+       return i2c_smbus_write_byte_data(client, addr, value);
+}
+
+static int ov772x_mask_set(struct i2c_client *client, u8  command, u8  mask,
+                          u8  set)
+{
+       s32 val = ov772x_read(client, command);
+       if (val < 0)
+               return val;
+
+       val &= ~mask;
+       val |= set & mask;
+
+       return ov772x_write(client, command, val);
+}
+
+static int ov772x_reset(struct i2c_client *client)
+{
+       int ret;
+
+       ret = ov772x_write(client, COM7, SCCB_RESET);
+       if (ret < 0)
+               return ret;
+
+       msleep(1);
+
+       return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
+}
+
+/*
+ * soc_camera_ops function
+ */
+
+static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov772x_priv *priv = to_ov772x(sd);
+
+       if (!enable) {
+               ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
+               return 0;
+       }
+
+       ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
+
+       dev_dbg(&client->dev, "format %d, win %s\n",
+               priv->cfmt->code, priv->win->name);
+
+       return 0;
+}
+
+static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct ov772x_priv *priv = container_of(ctrl->handler,
+                                               struct ov772x_priv, hdl);
+       struct v4l2_subdev *sd = &priv->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret = 0;
+       u8 val;
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               val = ctrl->val ? VFLIP_IMG : 0x00;
+               priv->flag_vflip = ctrl->val;
+               if (priv->info->flags & OV772X_FLAG_VFLIP)
+                       val ^= VFLIP_IMG;
+               return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
+       case V4L2_CID_HFLIP:
+               val = ctrl->val ? HFLIP_IMG : 0x00;
+               priv->flag_hflip = ctrl->val;
+               if (priv->info->flags & OV772X_FLAG_HFLIP)
+                       val ^= HFLIP_IMG;
+               return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
+       case V4L2_CID_BAND_STOP_FILTER:
+               if (!ctrl->val) {
+                       /* Switch the filter off, it is on now */
+                       ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
+                       if (!ret)
+                               ret = ov772x_mask_set(client, COM8,
+                                                     BNDF_ON_OFF, 0);
+               } else {
+                       /* Switch the filter on, set AEC low limit */
+                       val = 256 - ctrl->val;
+                       ret = ov772x_mask_set(client, COM8,
+                                             BNDF_ON_OFF, BNDF_ON_OFF);
+                       if (!ret)
+                               ret = ov772x_mask_set(client, BDBASE,
+                                                     0xff, val);
+               }
+               if (!ret)
+                       priv->band_filter = ctrl->val;
+               return ret;
+       }
+
+       return -EINVAL;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov772x_g_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+
+       reg->size = 1;
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       ret = ov772x_read(client, reg->reg);
+       if (ret < 0)
+               return ret;
+
+       reg->val = (__u64)ret;
+
+       return 0;
+}
+
+static int ov772x_s_register(struct v4l2_subdev *sd,
+                            const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff ||
+           reg->val > 0xff)
+               return -EINVAL;
+
+       return ov772x_write(client, reg->reg, reg->val);
+}
+#endif
+
+static int ov772x_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct ov772x_priv *priv = to_ov772x(sd);
+
+       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
+}
+
+static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
+{
+       const struct ov772x_win_size *win = &ov772x_win_sizes[0];
+       u32 best_diff = UINT_MAX;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) {
+               u32 diff = abs(width - ov772x_win_sizes[i].rect.width)
+                        + abs(height - ov772x_win_sizes[i].rect.height);
+               if (diff < best_diff) {
+                       best_diff = diff;
+                       win = &ov772x_win_sizes[i];
+               }
+       }
+
+       return win;
+}
+
+static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf,
+                                const struct ov772x_color_format **cfmt,
+                                const struct ov772x_win_size **win)
+{
+       unsigned int i;
+
+       /* Select a format. */
+       *cfmt = &ov772x_cfmts[0];
+
+       for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
+               if (mf->code == ov772x_cfmts[i].code) {
+                       *cfmt = &ov772x_cfmts[i];
+                       break;
+               }
+       }
+
+       /* Select a window size. */
+       *win = ov772x_select_win(mf->width, mf->height);
+}
+
+static int ov772x_set_params(struct ov772x_priv *priv,
+                            const struct ov772x_color_format *cfmt,
+                            const struct ov772x_win_size *win)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
+       int ret;
+       u8  val;
+
+       /*
+        * reset hardware
+        */
+       ov772x_reset(client);
+
+       /*
+        * Edge Ctrl
+        */
+       if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
+
+               /*
+                * Manual Edge Control Mode
+                *
+                * Edge auto strength bit is set by default.
+                * Remove it when manual mode.
+                */
+
+               ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+
+               ret = ov772x_mask_set(client,
+                                     EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
+                                     priv->info->edgectrl.threshold);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+
+               ret = ov772x_mask_set(client,
+                                     EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
+                                     priv->info->edgectrl.strength);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+
+       } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
+               /*
+                * Auto Edge Control Mode
+                *
+                * set upper and lower limit
+                */
+               ret = ov772x_mask_set(client,
+                                     EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
+                                     priv->info->edgectrl.upper);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+
+               ret = ov772x_mask_set(client,
+                                     EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
+                                     priv->info->edgectrl.lower);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+       }
+
+       /* Format and window size */
+       ret = ov772x_write(client, HSTART, win->rect.left >> 2);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, VSTART, win->rect.top >> 1);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, HREF,
+                          ((win->rect.top & 1) << HREF_VSTART_SHIFT) |
+                          ((win->rect.left & 3) << HREF_HSTART_SHIFT) |
+                          ((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
+                          ((win->rect.width & 3) << HREF_HSIZE_SHIFT));
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+       ret = ov772x_write(client, EXHCH,
+                          ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
+                          ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+
+       /*
+        * set DSP_CTRL3
+        */
+       val = cfmt->dsp3;
+       if (val) {
+               ret = ov772x_mask_set(client,
+                                     DSP_CTRL3, UV_MASK, val);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+       }
+
+       /* DSP_CTRL4: AEC reference point and DSP output format. */
+       if (cfmt->dsp4) {
+               ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+       }
+
+       /*
+        * set COM3
+        */
+       val = cfmt->com3;
+       if (priv->info->flags & OV772X_FLAG_VFLIP)
+               val |= VFLIP_IMG;
+       if (priv->info->flags & OV772X_FLAG_HFLIP)
+               val |= HFLIP_IMG;
+       if (priv->flag_vflip)
+               val ^= VFLIP_IMG;
+       if (priv->flag_hflip)
+               val ^= HFLIP_IMG;
+
+       ret = ov772x_mask_set(client,
+                             COM3, SWAP_MASK | IMG_MASK, val);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+
+       /* COM7: Sensor resolution and output format control. */
+       ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7);
+       if (ret < 0)
+               goto ov772x_set_fmt_error;
+
+       /*
+        * set COM8
+        */
+       if (priv->band_filter) {
+               ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, BNDF_ON_OFF);
+               if (!ret)
+                       ret = ov772x_mask_set(client, BDBASE,
+                                             0xff, 256 - priv->band_filter);
+               if (ret < 0)
+                       goto ov772x_set_fmt_error;
+       }
+
+       return ret;
+
+ov772x_set_fmt_error:
+
+       ov772x_reset(client);
+
+       return ret;
+}
+
+static int ov772x_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       sel->r.left = 0;
+       sel->r.top = 0;
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.width = OV772X_MAX_WIDTH;
+               sel->r.height = OV772X_MAX_HEIGHT;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+               sel->r.width = VGA_WIDTH;
+               sel->r.height = VGA_HEIGHT;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ov772x_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct ov772x_priv *priv = to_ov772x(sd);
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->width       = priv->win->rect.width;
+       mf->height      = priv->win->rect.height;
+       mf->code        = priv->cfmt->code;
+       mf->colorspace  = priv->cfmt->colorspace;
+       mf->field       = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int ov772x_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct ov772x_priv *priv = to_ov772x(sd);
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       const struct ov772x_color_format *cfmt;
+       const struct ov772x_win_size *win;
+       int ret;
+
+       if (format->pad)
+               return -EINVAL;
+
+       ov772x_select_params(mf, &cfmt, &win);
+
+       mf->code = cfmt->code;
+       mf->width = win->rect.width;
+       mf->height = win->rect.height;
+       mf->field = V4L2_FIELD_NONE;
+       mf->colorspace = cfmt->colorspace;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+               cfg->try_fmt = *mf;
+               return 0;
+       }
+
+       ret = ov772x_set_params(priv, cfmt, win);
+       if (ret < 0)
+               return ret;
+
+       priv->win = win;
+       priv->cfmt = cfmt;
+       return 0;
+}
+
+static int ov772x_video_probe(struct ov772x_priv *priv)
+{
+       struct i2c_client  *client = v4l2_get_subdevdata(&priv->subdev);
+       u8                  pid, ver;
+       const char         *devname;
+       int                 ret;
+
+       ret = ov772x_s_power(&priv->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * check and show product ID and manufacturer ID
+        */
+       pid = ov772x_read(client, PID);
+       ver = ov772x_read(client, VER);
+
+       switch (VERSION(pid, ver)) {
+       case OV7720:
+               devname     = "ov7720";
+               break;
+       case OV7725:
+               devname     = "ov7725";
+               break;
+       default:
+               dev_err(&client->dev,
+                       "Product ID error %x:%x\n", pid, ver);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       dev_info(&client->dev,
+                "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
+                devname,
+                pid,
+                ver,
+                ov772x_read(client, MIDH),
+                ov772x_read(client, MIDL));
+       ret = v4l2_ctrl_handler_setup(&priv->hdl);
+
+done:
+       ov772x_s_power(&priv->subdev, 0);
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
+       .s_ctrl = ov772x_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = ov772x_g_register,
+       .s_register     = ov772x_s_register,
+#endif
+       .s_power        = ov772x_s_power,
+};
+
+static int ov772x_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts))
+               return -EINVAL;
+
+       code->code = ov772x_cfmts[code->index].code;
+       return 0;
+}
+
+static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
+       .s_stream       = ov772x_s_stream,
+       .g_mbus_config  = ov772x_g_mbus_config,
+};
+
+static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = {
+       .enum_mbus_code = ov772x_enum_mbus_code,
+       .get_selection  = ov772x_get_selection,
+       .get_fmt        = ov772x_get_fmt,
+       .set_fmt        = ov772x_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov772x_subdev_ops = {
+       .core   = &ov772x_subdev_core_ops,
+       .video  = &ov772x_subdev_video_ops,
+       .pad    = &ov772x_subdev_pad_ops,
+};
+
+/*
+ * i2c_driver function
+ */
+
+static int ov772x_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct ov772x_priv      *priv;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
+       int                     ret;
+
+       if (!ssdd || !ssdd->drv_priv) {
+               dev_err(&client->dev, "OV772X: missing platform data!\n");
+               return -EINVAL;
+       }
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+                                             I2C_FUNC_PROTOCOL_MANGLING)) {
+               dev_err(&adapter->dev,
+                       "I2C-Adapter doesn't support SMBUS_BYTE_DATA or PROTOCOL_MANGLING\n");
+               return -EIO;
+       }
+       client->flags |= I2C_CLIENT_SCCB;
+
+       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->info = ssdd->drv_priv;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
+       v4l2_ctrl_handler_init(&priv->hdl, 3);
+       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
+                       V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error)
+               return priv->hdl.error;
+
+       priv->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(priv->clk)) {
+               ret = PTR_ERR(priv->clk);
+               goto eclkget;
+       }
+
+       ret = ov772x_video_probe(priv);
+       if (ret < 0) {
+               v4l2_clk_put(priv->clk);
+eclkget:
+               v4l2_ctrl_handler_free(&priv->hdl);
+       } else {
+               priv->cfmt = &ov772x_cfmts[0];
+               priv->win = &ov772x_win_sizes[0];
+       }
+
+       return ret;
+}
+
+static int ov772x_remove(struct i2c_client *client)
+{
+       struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
+
+       v4l2_clk_put(priv->clk);
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
+       return 0;
+}
+
+static const struct i2c_device_id ov772x_id[] = {
+       { "ov772x", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ov772x_id);
+
+static struct i2c_driver ov772x_i2c_driver = {
+       .driver = {
+               .name = "ov772x",
+       },
+       .probe    = ov772x_probe,
+       .remove   = ov772x_remove,
+       .id_table = ov772x_id,
+};
+
+module_i2c_driver(ov772x_i2c_driver);
+
+MODULE_DESCRIPTION("SoC Camera driver for ov772x");
+MODULE_AUTHOR("Kuninori Morimoto");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_ov9640.c b/drivers/media/i2c/soc_camera/soc_ov9640.c
new file mode 100644 (file)
index 0000000..eb91b82
--- /dev/null
@@ -0,0 +1,738 @@
+/*
+ * OmniVision OV96xx Camera Driver
+ *
+ * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on ov772x camera driver:
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov7670 and soc_camera_platform driver,
+ *
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+
+#include "ov9640.h"
+
+#define to_ov9640_sensor(sd)   container_of(sd, struct ov9640_priv, subdev)
+
+/* default register setup */
+static const struct ov9640_reg ov9640_regs_dflt[] = {
+       { OV9640_COM5,  OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
+       { OV9640_COM6,  OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
+                       OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
+       { OV9640_PSHFT, OV9640_PSHFT_VAL(0x01) },
+       { OV9640_ACOM,  OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
+       { OV9640_TSLB,  OV9640_TSLB_YUYV_UYVY },
+       { OV9640_COM16, OV9640_COM16_RB_AVG },
+
+       /* Gamma curve P */
+       { 0x6c, 0x40 }, { 0x6d, 0x30 }, { 0x6e, 0x4b }, { 0x6f, 0x60 },
+       { 0x70, 0x70 }, { 0x71, 0x70 }, { 0x72, 0x70 }, { 0x73, 0x70 },
+       { 0x74, 0x60 }, { 0x75, 0x60 }, { 0x76, 0x50 }, { 0x77, 0x48 },
+       { 0x78, 0x3a }, { 0x79, 0x2e }, { 0x7a, 0x28 }, { 0x7b, 0x22 },
+
+       /* Gamma curve T */
+       { 0x7c, 0x04 }, { 0x7d, 0x07 }, { 0x7e, 0x10 }, { 0x7f, 0x28 },
+       { 0x80, 0x36 }, { 0x81, 0x44 }, { 0x82, 0x52 }, { 0x83, 0x60 },
+       { 0x84, 0x6c }, { 0x85, 0x78 }, { 0x86, 0x8c }, { 0x87, 0x9e },
+       { 0x88, 0xbb }, { 0x89, 0xd2 }, { 0x8a, 0xe6 },
+};
+
+/* Configurations
+ * NOTE: for YUV, alter the following registers:
+ *             COM12 |= OV9640_COM12_YUV_AVG
+ *
+ *      for RGB, alter the following registers:
+ *             COM7  |= OV9640_COM7_RGB
+ *             COM13 |= OV9640_COM13_RGB_AVG
+ *             COM15 |= proper RGB color encoding mode
+ */
+static const struct ov9640_reg ov9640_regs_qqcif[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
+       { OV9640_COM1,  OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
+       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+       { OV9640_COM7,  OV9640_COM7_QCIF },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qqvga[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
+       { OV9640_COM1,  OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
+       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+       { OV9640_COM7,  OV9640_COM7_QVGA },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qcif[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
+       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+       { OV9640_COM7,  OV9640_COM7_QCIF },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_qvga[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
+       { OV9640_COM4,  OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
+       { OV9640_COM7,  OV9640_COM7_QVGA },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_cif[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
+       { OV9640_COM3,  OV9640_COM3_VP },
+       { OV9640_COM7,  OV9640_COM7_CIF },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_vga[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
+       { OV9640_COM3,  OV9640_COM3_VP },
+       { OV9640_COM7,  OV9640_COM7_VGA },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_sxga[] = {
+       { OV9640_CLKRC, OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
+       { OV9640_COM3,  OV9640_COM3_VP },
+       { OV9640_COM7,  0 },
+       { OV9640_COM12, OV9640_COM12_RSVD },
+       { OV9640_COM13, OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
+       { OV9640_COM15, OV9640_COM15_OR_10F0 },
+};
+
+static const struct ov9640_reg ov9640_regs_yuv[] = {
+       { OV9640_MTX1,  0x58 },
+       { OV9640_MTX2,  0x48 },
+       { OV9640_MTX3,  0x10 },
+       { OV9640_MTX4,  0x28 },
+       { OV9640_MTX5,  0x48 },
+       { OV9640_MTX6,  0x70 },
+       { OV9640_MTX7,  0x40 },
+       { OV9640_MTX8,  0x40 },
+       { OV9640_MTX9,  0x40 },
+       { OV9640_MTXS,  0x0f },
+};
+
+static const struct ov9640_reg ov9640_regs_rgb[] = {
+       { OV9640_MTX1,  0x71 },
+       { OV9640_MTX2,  0x3e },
+       { OV9640_MTX3,  0x0c },
+       { OV9640_MTX4,  0x33 },
+       { OV9640_MTX5,  0x72 },
+       { OV9640_MTX6,  0x00 },
+       { OV9640_MTX7,  0x2b },
+       { OV9640_MTX8,  0x66 },
+       { OV9640_MTX9,  0xd2 },
+       { OV9640_MTXS,  0x65 },
+};
+
+static u32 ov9640_codes[] = {
+       MEDIA_BUS_FMT_UYVY8_2X8,
+       MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+       MEDIA_BUS_FMT_RGB565_2X8_LE,
+};
+
+/* read a register */
+static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+       int ret;
+       u8 data = reg;
+       struct i2c_msg msg = {
+               .addr   = client->addr,
+               .flags  = 0,
+               .len    = 1,
+               .buf    = &data,
+       };
+
+       ret = i2c_transfer(client->adapter, &msg, 1);
+       if (ret < 0)
+               goto err;
+
+       msg.flags = I2C_M_RD;
+       ret = i2c_transfer(client->adapter, &msg, 1);
+       if (ret < 0)
+               goto err;
+
+       *val = data;
+       return 0;
+
+err:
+       dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
+       return ret;
+}
+
+/* write a register */
+static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
+{
+       int ret;
+       u8 _val;
+       unsigned char data[2] = { reg, val };
+       struct i2c_msg msg = {
+               .addr   = client->addr,
+               .flags  = 0,
+               .len    = 2,
+               .buf    = data,
+       };
+
+       ret = i2c_transfer(client->adapter, &msg, 1);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
+               return ret;
+       }
+
+       /* we have to read the register back ... no idea why, maybe HW bug */
+       ret = ov9640_reg_read(client, reg, &_val);
+       if (ret)
+               dev_err(&client->dev,
+                       "Failed reading back register 0x%02x!\n", reg);
+
+       return 0;
+}
+
+
+/* Read a register, alter its bits, write it back */
+static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
+{
+       u8 val;
+       int ret;
+
+       ret = ov9640_reg_read(client, reg, &val);
+       if (ret) {
+               dev_err(&client->dev,
+                       "[Read]-Modify-Write of register %02x failed!\n", reg);
+               return ret;
+       }
+
+       val |= set;
+       val &= ~unset;
+
+       ret = ov9640_reg_write(client, reg, val);
+       if (ret)
+               dev_err(&client->dev,
+                       "Read-Modify-[Write] of register %02x failed!\n", reg);
+
+       return ret;
+}
+
+/* Soft reset the camera. This has nothing to do with the RESET pin! */
+static int ov9640_reset(struct i2c_client *client)
+{
+       int ret;
+
+       ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
+       if (ret)
+               dev_err(&client->dev,
+                       "An error occurred while entering soft reset!\n");
+
+       return ret;
+}
+
+/* Start/Stop streaming from the device */
+static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       return 0;
+}
+
+/* Set status of additional camera capabilities */
+static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct ov9640_priv *priv = container_of(ctrl->handler, struct ov9640_priv, hdl);
+       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               if (ctrl->val)
+                       return ov9640_reg_rmw(client, OV9640_MVFP,
+                                                       OV9640_MVFP_V, 0);
+               return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
+       case V4L2_CID_HFLIP:
+               if (ctrl->val)
+                       return ov9640_reg_rmw(client, OV9640_MVFP,
+                                                       OV9640_MVFP_H, 0);
+               return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
+       }
+       return -EINVAL;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov9640_get_register(struct v4l2_subdev *sd,
+                               struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+       u8 val;
+
+       if (reg->reg & ~0xff)
+               return -EINVAL;
+
+       reg->size = 1;
+
+       ret = ov9640_reg_read(client, reg->reg, &val);
+       if (ret)
+               return ret;
+
+       reg->val = (__u64)val;
+
+       return 0;
+}
+
+static int ov9640_set_register(struct v4l2_subdev *sd,
+                               const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg & ~0xff || reg->val & ~0xff)
+               return -EINVAL;
+
+       return ov9640_reg_write(client, reg->reg, reg->val);
+}
+#endif
+
+static int ov9640_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct ov9640_priv *priv = to_ov9640_sensor(sd);
+
+       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
+}
+
+/* select nearest higher resolution for capture */
+static void ov9640_res_roundup(u32 *width, u32 *height)
+{
+       int i;
+       enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
+       static const int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
+       static const int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
+
+       for (i = 0; i < ARRAY_SIZE(res_x); i++) {
+               if (res_x[i] >= *width && res_y[i] >= *height) {
+                       *width = res_x[i];
+                       *height = res_y[i];
+                       return;
+               }
+       }
+
+       *width = res_x[SXGA];
+       *height = res_y[SXGA];
+}
+
+/* Prepare necessary register changes depending on color encoding */
+static void ov9640_alter_regs(u32 code,
+                             struct ov9640_reg_alt *alt)
+{
+       switch (code) {
+       default:
+       case MEDIA_BUS_FMT_UYVY8_2X8:
+               alt->com12      = OV9640_COM12_YUV_AVG;
+               alt->com13      = OV9640_COM13_Y_DELAY_EN |
+                                       OV9640_COM13_YUV_DLY(0x01);
+               break;
+       case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
+               alt->com7       = OV9640_COM7_RGB;
+               alt->com13      = OV9640_COM13_RGB_AVG;
+               alt->com15      = OV9640_COM15_RGB_555;
+               break;
+       case MEDIA_BUS_FMT_RGB565_2X8_LE:
+               alt->com7       = OV9640_COM7_RGB;
+               alt->com13      = OV9640_COM13_RGB_AVG;
+               alt->com15      = OV9640_COM15_RGB_565;
+               break;
+       }
+}
+
+/* Setup registers according to resolution and color encoding */
+static int ov9640_write_regs(struct i2c_client *client, u32 width,
+               u32 code, struct ov9640_reg_alt *alts)
+{
+       const struct ov9640_reg *ov9640_regs, *matrix_regs;
+       int                     ov9640_regs_len, matrix_regs_len;
+       int                     i, ret;
+       u8                      val;
+
+       /* select register configuration for given resolution */
+       switch (width) {
+       case W_QQCIF:
+               ov9640_regs     = ov9640_regs_qqcif;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqcif);
+               break;
+       case W_QQVGA:
+               ov9640_regs     = ov9640_regs_qqvga;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qqvga);
+               break;
+       case W_QCIF:
+               ov9640_regs     = ov9640_regs_qcif;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qcif);
+               break;
+       case W_QVGA:
+               ov9640_regs     = ov9640_regs_qvga;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_qvga);
+               break;
+       case W_CIF:
+               ov9640_regs     = ov9640_regs_cif;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_cif);
+               break;
+       case W_VGA:
+               ov9640_regs     = ov9640_regs_vga;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_vga);
+               break;
+       case W_SXGA:
+               ov9640_regs     = ov9640_regs_sxga;
+               ov9640_regs_len = ARRAY_SIZE(ov9640_regs_sxga);
+               break;
+       default:
+               dev_err(&client->dev, "Failed to select resolution!\n");
+               return -EINVAL;
+       }
+
+       /* select color matrix configuration for given color encoding */
+       if (code == MEDIA_BUS_FMT_UYVY8_2X8) {
+               matrix_regs     = ov9640_regs_yuv;
+               matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv);
+       } else {
+               matrix_regs     = ov9640_regs_rgb;
+               matrix_regs_len = ARRAY_SIZE(ov9640_regs_rgb);
+       }
+
+       /* write register settings into the module */
+       for (i = 0; i < ov9640_regs_len; i++) {
+               val = ov9640_regs[i].val;
+
+               switch (ov9640_regs[i].reg) {
+               case OV9640_COM7:
+                       val |= alts->com7;
+                       break;
+               case OV9640_COM12:
+                       val |= alts->com12;
+                       break;
+               case OV9640_COM13:
+                       val |= alts->com13;
+                       break;
+               case OV9640_COM15:
+                       val |= alts->com15;
+                       break;
+               }
+
+               ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
+               if (ret)
+                       return ret;
+       }
+
+       /* write color matrix configuration into the module */
+       for (i = 0; i < matrix_regs_len; i++) {
+               ret = ov9640_reg_write(client, matrix_regs[i].reg,
+                                               matrix_regs[i].val);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+/* program default register values */
+static int ov9640_prog_dflt(struct i2c_client *client)
+{
+       int i, ret;
+
+       for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
+               ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
+                                               ov9640_regs_dflt[i].val);
+               if (ret)
+                       return ret;
+       }
+
+       /* wait for the changes to actually happen, 140ms are not enough yet */
+       mdelay(150);
+
+       return 0;
+}
+
+/* set the format we will capture in */
+static int ov9640_s_fmt(struct v4l2_subdev *sd,
+                       struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov9640_reg_alt alts = {0};
+       int ret;
+
+       ov9640_alter_regs(mf->code, &alts);
+
+       ov9640_reset(client);
+
+       ret = ov9640_prog_dflt(client);
+       if (ret)
+               return ret;
+
+       return ov9640_write_regs(client, mf->width, mf->code, &alts);
+}
+
+static int ov9640_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+
+       if (format->pad)
+               return -EINVAL;
+
+       ov9640_res_roundup(&mf->width, &mf->height);
+
+       mf->field = V4L2_FIELD_NONE;
+
+       switch (mf->code) {
+       case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
+       case MEDIA_BUS_FMT_RGB565_2X8_LE:
+               mf->colorspace = V4L2_COLORSPACE_SRGB;
+               break;
+       default:
+               mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
+               /* fall through */
+       case MEDIA_BUS_FMT_UYVY8_2X8:
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+               break;
+       }
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return ov9640_s_fmt(sd, mf);
+
+       cfg->try_fmt = *mf;
+       return 0;
+}
+
+static int ov9640_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes))
+               return -EINVAL;
+
+       code->code = ov9640_codes[code->index];
+       return 0;
+}
+
+static int ov9640_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       sel->r.left = 0;
+       sel->r.top = 0;
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+       case V4L2_SEL_TGT_CROP:
+               sel->r.width = W_SXGA;
+               sel->r.height = H_SXGA;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int ov9640_video_probe(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov9640_priv *priv = to_ov9640_sensor(sd);
+       u8              pid, ver, midh, midl;
+       const char      *devname;
+       int             ret;
+
+       ret = ov9640_s_power(&priv->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * check and show product ID and manufacturer ID
+        */
+
+       ret = ov9640_reg_read(client, OV9640_PID, &pid);
+       if (!ret)
+               ret = ov9640_reg_read(client, OV9640_VER, &ver);
+       if (!ret)
+               ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
+       if (!ret)
+               ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
+       if (ret)
+               goto done;
+
+       switch (VERSION(pid, ver)) {
+       case OV9640_V2:
+               devname         = "ov9640";
+               priv->revision  = 2;
+               break;
+       case OV9640_V3:
+               devname         = "ov9640";
+               priv->revision  = 3;
+               break;
+       default:
+               dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
+                devname, pid, ver, midh, midl);
+
+       ret = v4l2_ctrl_handler_setup(&priv->hdl);
+
+done:
+       ov9640_s_power(&priv->subdev, 0);
+       return ret;
+}
+
+static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
+       .s_ctrl = ov9640_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops ov9640_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register             = ov9640_get_register,
+       .s_register             = ov9640_set_register,
+#endif
+       .s_power                = ov9640_s_power,
+};
+
+/* Request bus settings on camera side */
+static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov9640_video_ops = {
+       .s_stream       = ov9640_s_stream,
+       .g_mbus_config  = ov9640_g_mbus_config,
+};
+
+static const struct v4l2_subdev_pad_ops ov9640_pad_ops = {
+       .enum_mbus_code = ov9640_enum_mbus_code,
+       .get_selection  = ov9640_get_selection,
+       .set_fmt        = ov9640_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov9640_subdev_ops = {
+       .core   = &ov9640_core_ops,
+       .video  = &ov9640_video_ops,
+       .pad    = &ov9640_pad_ops,
+};
+
+/*
+ * i2c_driver function
+ */
+static int ov9640_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct ov9640_priv *priv;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       int ret;
+
+       if (!ssdd) {
+               dev_err(&client->dev, "Missing platform_data for driver\n");
+               return -EINVAL;
+       }
+
+       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
+
+       v4l2_ctrl_handler_init(&priv->hdl, 2);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error)
+               return priv->hdl.error;
+
+       priv->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(priv->clk)) {
+               ret = PTR_ERR(priv->clk);
+               goto eclkget;
+       }
+
+       ret = ov9640_video_probe(client);
+       if (ret) {
+               v4l2_clk_put(priv->clk);
+eclkget:
+               v4l2_ctrl_handler_free(&priv->hdl);
+       }
+
+       return ret;
+}
+
+static int ov9640_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov9640_priv *priv = to_ov9640_sensor(sd);
+
+       v4l2_clk_put(priv->clk);
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
+       return 0;
+}
+
+static const struct i2c_device_id ov9640_id[] = {
+       { "ov9640", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ov9640_id);
+
+static struct i2c_driver ov9640_i2c_driver = {
+       .driver = {
+               .name = "ov9640",
+       },
+       .probe    = ov9640_probe,
+       .remove   = ov9640_remove,
+       .id_table = ov9640_id,
+};
+
+module_i2c_driver(ov9640_i2c_driver);
+
+MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_ov9740.c b/drivers/media/i2c/soc_camera/soc_ov9740.c
new file mode 100644 (file)
index 0000000..a07d314
--- /dev/null
@@ -0,0 +1,996 @@
+/*
+ * OmniVision OV9740 Camera Driver
+ *
+ * Copyright (C) 2011 NVIDIA Corporation
+ *
+ * Based on ov9640 camera driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-ctrls.h>
+
+#define to_ov9740(sd)          container_of(sd, struct ov9740_priv, subdev)
+
+/* General Status Registers */
+#define OV9740_MODEL_ID_HI             0x0000
+#define OV9740_MODEL_ID_LO             0x0001
+#define OV9740_REVISION_NUMBER         0x0002
+#define OV9740_MANUFACTURER_ID         0x0003
+#define OV9740_SMIA_VERSION            0x0004
+
+/* General Setup Registers */
+#define OV9740_MODE_SELECT             0x0100
+#define OV9740_IMAGE_ORT               0x0101
+#define OV9740_SOFTWARE_RESET          0x0103
+#define OV9740_GRP_PARAM_HOLD          0x0104
+#define OV9740_MSK_CORRUP_FM           0x0105
+
+/* Timing Setting */
+#define OV9740_FRM_LENGTH_LN_HI                0x0340 /* VTS */
+#define OV9740_FRM_LENGTH_LN_LO                0x0341 /* VTS */
+#define OV9740_LN_LENGTH_PCK_HI                0x0342 /* HTS */
+#define OV9740_LN_LENGTH_PCK_LO                0x0343 /* HTS */
+#define OV9740_X_ADDR_START_HI         0x0344
+#define OV9740_X_ADDR_START_LO         0x0345
+#define OV9740_Y_ADDR_START_HI         0x0346
+#define OV9740_Y_ADDR_START_LO         0x0347
+#define OV9740_X_ADDR_END_HI           0x0348
+#define OV9740_X_ADDR_END_LO           0x0349
+#define OV9740_Y_ADDR_END_HI           0x034a
+#define OV9740_Y_ADDR_END_LO           0x034b
+#define OV9740_X_OUTPUT_SIZE_HI                0x034c
+#define OV9740_X_OUTPUT_SIZE_LO                0x034d
+#define OV9740_Y_OUTPUT_SIZE_HI                0x034e
+#define OV9740_Y_OUTPUT_SIZE_LO                0x034f
+
+/* IO Control Registers */
+#define OV9740_IO_CREL00               0x3002
+#define OV9740_IO_CREL01               0x3004
+#define OV9740_IO_CREL02               0x3005
+#define OV9740_IO_OUTPUT_SEL01         0x3026
+#define OV9740_IO_OUTPUT_SEL02         0x3027
+
+/* AWB Registers */
+#define OV9740_AWB_MANUAL_CTRL         0x3406
+
+/* Analog Control Registers */
+#define OV9740_ANALOG_CTRL01           0x3601
+#define OV9740_ANALOG_CTRL02           0x3602
+#define OV9740_ANALOG_CTRL03           0x3603
+#define OV9740_ANALOG_CTRL04           0x3604
+#define OV9740_ANALOG_CTRL10           0x3610
+#define OV9740_ANALOG_CTRL12           0x3612
+#define OV9740_ANALOG_CTRL15           0x3615
+#define OV9740_ANALOG_CTRL20           0x3620
+#define OV9740_ANALOG_CTRL21           0x3621
+#define OV9740_ANALOG_CTRL22           0x3622
+#define OV9740_ANALOG_CTRL30           0x3630
+#define OV9740_ANALOG_CTRL31           0x3631
+#define OV9740_ANALOG_CTRL32           0x3632
+#define OV9740_ANALOG_CTRL33           0x3633
+
+/* Sensor Control */
+#define OV9740_SENSOR_CTRL03           0x3703
+#define OV9740_SENSOR_CTRL04           0x3704
+#define OV9740_SENSOR_CTRL05           0x3705
+#define OV9740_SENSOR_CTRL07           0x3707
+
+/* Timing Control */
+#define OV9740_TIMING_CTRL17           0x3817
+#define OV9740_TIMING_CTRL19           0x3819
+#define OV9740_TIMING_CTRL33           0x3833
+#define OV9740_TIMING_CTRL35           0x3835
+
+/* Banding Filter */
+#define OV9740_AEC_MAXEXPO_60_H                0x3a02
+#define OV9740_AEC_MAXEXPO_60_L                0x3a03
+#define OV9740_AEC_B50_STEP_HI         0x3a08
+#define OV9740_AEC_B50_STEP_LO         0x3a09
+#define OV9740_AEC_B60_STEP_HI         0x3a0a
+#define OV9740_AEC_B60_STEP_LO         0x3a0b
+#define OV9740_AEC_CTRL0D              0x3a0d
+#define OV9740_AEC_CTRL0E              0x3a0e
+#define OV9740_AEC_MAXEXPO_50_H                0x3a14
+#define OV9740_AEC_MAXEXPO_50_L                0x3a15
+
+/* AEC/AGC Control */
+#define OV9740_AEC_ENABLE              0x3503
+#define OV9740_GAIN_CEILING_01         0x3a18
+#define OV9740_GAIN_CEILING_02         0x3a19
+#define OV9740_AEC_HI_THRESHOLD                0x3a11
+#define OV9740_AEC_3A1A                        0x3a1a
+#define OV9740_AEC_CTRL1B_WPT2         0x3a1b
+#define OV9740_AEC_CTRL0F_WPT          0x3a0f
+#define OV9740_AEC_CTRL10_BPT          0x3a10
+#define OV9740_AEC_CTRL1E_BPT2         0x3a1e
+#define OV9740_AEC_LO_THRESHOLD                0x3a1f
+
+/* BLC Control */
+#define OV9740_BLC_AUTO_ENABLE         0x4002
+#define OV9740_BLC_MODE                        0x4005
+
+/* VFIFO */
+#define OV9740_VFIFO_READ_START_HI     0x4608
+#define OV9740_VFIFO_READ_START_LO     0x4609
+
+/* DVP Control */
+#define OV9740_DVP_VSYNC_CTRL02                0x4702
+#define OV9740_DVP_VSYNC_MODE          0x4704
+#define OV9740_DVP_VSYNC_CTRL06                0x4706
+
+/* PLL Setting */
+#define OV9740_PLL_MODE_CTRL01         0x3104
+#define OV9740_PRE_PLL_CLK_DIV         0x0305
+#define OV9740_PLL_MULTIPLIER          0x0307
+#define OV9740_VT_SYS_CLK_DIV          0x0303
+#define OV9740_VT_PIX_CLK_DIV          0x0301
+#define OV9740_PLL_CTRL3010            0x3010
+#define OV9740_VFIFO_CTRL00            0x460e
+
+/* ISP Control */
+#define OV9740_ISP_CTRL00              0x5000
+#define OV9740_ISP_CTRL01              0x5001
+#define OV9740_ISP_CTRL03              0x5003
+#define OV9740_ISP_CTRL05              0x5005
+#define OV9740_ISP_CTRL12              0x5012
+#define OV9740_ISP_CTRL19              0x5019
+#define OV9740_ISP_CTRL1A              0x501a
+#define OV9740_ISP_CTRL1E              0x501e
+#define OV9740_ISP_CTRL1F              0x501f
+#define OV9740_ISP_CTRL20              0x5020
+#define OV9740_ISP_CTRL21              0x5021
+
+/* AWB */
+#define OV9740_AWB_CTRL00              0x5180
+#define OV9740_AWB_CTRL01              0x5181
+#define OV9740_AWB_CTRL02              0x5182
+#define OV9740_AWB_CTRL03              0x5183
+#define OV9740_AWB_ADV_CTRL01          0x5184
+#define OV9740_AWB_ADV_CTRL02          0x5185
+#define OV9740_AWB_ADV_CTRL03          0x5186
+#define OV9740_AWB_ADV_CTRL04          0x5187
+#define OV9740_AWB_ADV_CTRL05          0x5188
+#define OV9740_AWB_ADV_CTRL06          0x5189
+#define OV9740_AWB_ADV_CTRL07          0x518a
+#define OV9740_AWB_ADV_CTRL08          0x518b
+#define OV9740_AWB_ADV_CTRL09          0x518c
+#define OV9740_AWB_ADV_CTRL10          0x518d
+#define OV9740_AWB_ADV_CTRL11          0x518e
+#define OV9740_AWB_CTRL0F              0x518f
+#define OV9740_AWB_CTRL10              0x5190
+#define OV9740_AWB_CTRL11              0x5191
+#define OV9740_AWB_CTRL12              0x5192
+#define OV9740_AWB_CTRL13              0x5193
+#define OV9740_AWB_CTRL14              0x5194
+
+/* MIPI Control */
+#define OV9740_MIPI_CTRL00             0x4800
+#define OV9740_MIPI_3837               0x3837
+#define OV9740_MIPI_CTRL01             0x4801
+#define OV9740_MIPI_CTRL03             0x4803
+#define OV9740_MIPI_CTRL05             0x4805
+#define OV9740_VFIFO_RD_CTRL           0x4601
+#define OV9740_MIPI_CTRL_3012          0x3012
+#define OV9740_SC_CMMM_MIPI_CTR                0x3014
+
+#define OV9740_MAX_WIDTH               1280
+#define OV9740_MAX_HEIGHT              720
+
+/* Misc. structures */
+struct ov9740_reg {
+       u16                             reg;
+       u8                              val;
+};
+
+struct ov9740_priv {
+       struct v4l2_subdev              subdev;
+       struct v4l2_ctrl_handler        hdl;
+       struct v4l2_clk                 *clk;
+
+       u16                             model;
+       u8                              revision;
+       u8                              manid;
+       u8                              smiaver;
+
+       bool                            flag_vflip;
+       bool                            flag_hflip;
+
+       /* For suspend/resume. */
+       struct v4l2_mbus_framefmt       current_mf;
+       bool                            current_enable;
+};
+
+static const struct ov9740_reg ov9740_defaults[] = {
+       /* Software Reset */
+       { OV9740_SOFTWARE_RESET,        0x01 },
+
+       /* Banding Filter */
+       { OV9740_AEC_B50_STEP_HI,       0x00 },
+       { OV9740_AEC_B50_STEP_LO,       0xe8 },
+       { OV9740_AEC_CTRL0E,            0x03 },
+       { OV9740_AEC_MAXEXPO_50_H,      0x15 },
+       { OV9740_AEC_MAXEXPO_50_L,      0xc6 },
+       { OV9740_AEC_B60_STEP_HI,       0x00 },
+       { OV9740_AEC_B60_STEP_LO,       0xc0 },
+       { OV9740_AEC_CTRL0D,            0x04 },
+       { OV9740_AEC_MAXEXPO_60_H,      0x18 },
+       { OV9740_AEC_MAXEXPO_60_L,      0x20 },
+
+       /* LC */
+       { 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 },
+       { 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc },
+
+       /* Un-documented OV9740 registers */
+       { 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 },
+       { 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c },
+       { 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580a, 0x0e }, { 0x580b, 0x16 },
+       { 0x580c, 0x06 }, { 0x580d, 0x02 }, { 0x580e, 0x00 }, { 0x580f, 0x00 },
+       { 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 },
+       { 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 },
+       { 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581a, 0x07 }, { 0x581b, 0x08 },
+       { 0x581c, 0x0b }, { 0x581d, 0x14 }, { 0x581e, 0x28 }, { 0x581f, 0x23 },
+       { 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a },
+       { 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f },
+       { 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582a, 0x8f }, { 0x582b, 0x9e },
+       { 0x582c, 0x8f }, { 0x582d, 0x9f }, { 0x582e, 0x4f }, { 0x582f, 0x87 },
+       { 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f },
+       { 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf },
+       { 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583a, 0x9f }, { 0x583b, 0x7f },
+       { 0x583c, 0x5f },
+
+       /* Y Gamma */
+       { 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e },
+       { 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 },
+       { 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548a, 0xa4 }, { 0x548b, 0xb1 },
+       { 0x548c, 0xc6 }, { 0x548d, 0xd8 }, { 0x548e, 0xe9 },
+
+       /* UV Gamma */
+       { 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 },
+       { 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 },
+       { 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549a, 0x02 }, { 0x549b, 0xeb },
+       { 0x549c, 0x02 }, { 0x549d, 0xa0 }, { 0x549e, 0x02 }, { 0x549f, 0x67 },
+       { 0x54a0, 0x02 }, { 0x54a1, 0x3b }, { 0x54a2, 0x02 }, { 0x54a3, 0x18 },
+       { 0x54a4, 0x01 }, { 0x54a5, 0xe7 }, { 0x54a6, 0x01 }, { 0x54a7, 0xc3 },
+       { 0x54a8, 0x01 }, { 0x54a9, 0x94 }, { 0x54aa, 0x01 }, { 0x54ab, 0x72 },
+       { 0x54ac, 0x01 }, { 0x54ad, 0x57 },
+
+       /* AWB */
+       { OV9740_AWB_CTRL00,            0xf0 },
+       { OV9740_AWB_CTRL01,            0x00 },
+       { OV9740_AWB_CTRL02,            0x41 },
+       { OV9740_AWB_CTRL03,            0x42 },
+       { OV9740_AWB_ADV_CTRL01,        0x8a },
+       { OV9740_AWB_ADV_CTRL02,        0x61 },
+       { OV9740_AWB_ADV_CTRL03,        0xce },
+       { OV9740_AWB_ADV_CTRL04,        0xa8 },
+       { OV9740_AWB_ADV_CTRL05,        0x17 },
+       { OV9740_AWB_ADV_CTRL06,        0x1f },
+       { OV9740_AWB_ADV_CTRL07,        0x27 },
+       { OV9740_AWB_ADV_CTRL08,        0x41 },
+       { OV9740_AWB_ADV_CTRL09,        0x34 },
+       { OV9740_AWB_ADV_CTRL10,        0xf0 },
+       { OV9740_AWB_ADV_CTRL11,        0x10 },
+       { OV9740_AWB_CTRL0F,            0xff },
+       { OV9740_AWB_CTRL10,            0x00 },
+       { OV9740_AWB_CTRL11,            0xff },
+       { OV9740_AWB_CTRL12,            0x00 },
+       { OV9740_AWB_CTRL13,            0xff },
+       { OV9740_AWB_CTRL14,            0x00 },
+
+       /* CIP */
+       { 0x530d, 0x12 },
+
+       /* CMX */
+       { 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 },
+       { 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 },
+       { 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538a, 0x00 }, { 0x538b, 0x20 },
+       { 0x538c, 0x00 }, { 0x538d, 0x00 }, { 0x538e, 0x00 }, { 0x538f, 0x16 },
+       { 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 },
+       { 0x5394, 0x18 },
+
+       /* 50/60 Detection */
+       { 0x3c0a, 0x9c }, { 0x3c0b, 0x3f },
+
+       /* Output Select */
+       { OV9740_IO_OUTPUT_SEL01,       0x00 },
+       { OV9740_IO_OUTPUT_SEL02,       0x00 },
+       { OV9740_IO_CREL00,             0x00 },
+       { OV9740_IO_CREL01,             0x00 },
+       { OV9740_IO_CREL02,             0x00 },
+
+       /* AWB Control */
+       { OV9740_AWB_MANUAL_CTRL,       0x00 },
+
+       /* Analog Control */
+       { OV9740_ANALOG_CTRL03,         0xaa },
+       { OV9740_ANALOG_CTRL32,         0x2f },
+       { OV9740_ANALOG_CTRL20,         0x66 },
+       { OV9740_ANALOG_CTRL21,         0xc0 },
+       { OV9740_ANALOG_CTRL31,         0x52 },
+       { OV9740_ANALOG_CTRL33,         0x50 },
+       { OV9740_ANALOG_CTRL30,         0xca },
+       { OV9740_ANALOG_CTRL04,         0x0c },
+       { OV9740_ANALOG_CTRL01,         0x40 },
+       { OV9740_ANALOG_CTRL02,         0x16 },
+       { OV9740_ANALOG_CTRL10,         0xa1 },
+       { OV9740_ANALOG_CTRL12,         0x24 },
+       { OV9740_ANALOG_CTRL22,         0x9f },
+       { OV9740_ANALOG_CTRL15,         0xf0 },
+
+       /* Sensor Control */
+       { OV9740_SENSOR_CTRL03,         0x42 },
+       { OV9740_SENSOR_CTRL04,         0x10 },
+       { OV9740_SENSOR_CTRL05,         0x45 },
+       { OV9740_SENSOR_CTRL07,         0x14 },
+
+       /* Timing Control */
+       { OV9740_TIMING_CTRL33,         0x04 },
+       { OV9740_TIMING_CTRL35,         0x02 },
+       { OV9740_TIMING_CTRL19,         0x6e },
+       { OV9740_TIMING_CTRL17,         0x94 },
+
+       /* AEC/AGC Control */
+       { OV9740_AEC_ENABLE,            0x10 },
+       { OV9740_GAIN_CEILING_01,       0x00 },
+       { OV9740_GAIN_CEILING_02,       0x7f },
+       { OV9740_AEC_HI_THRESHOLD,      0xa0 },
+       { OV9740_AEC_3A1A,              0x05 },
+       { OV9740_AEC_CTRL1B_WPT2,       0x50 },
+       { OV9740_AEC_CTRL0F_WPT,        0x50 },
+       { OV9740_AEC_CTRL10_BPT,        0x4c },
+       { OV9740_AEC_CTRL1E_BPT2,       0x4c },
+       { OV9740_AEC_LO_THRESHOLD,      0x26 },
+
+       /* BLC Control */
+       { OV9740_BLC_AUTO_ENABLE,       0x45 },
+       { OV9740_BLC_MODE,              0x18 },
+
+       /* DVP Control */
+       { OV9740_DVP_VSYNC_CTRL02,      0x04 },
+       { OV9740_DVP_VSYNC_MODE,        0x00 },
+       { OV9740_DVP_VSYNC_CTRL06,      0x08 },
+
+       /* PLL Setting */
+       { OV9740_PLL_MODE_CTRL01,       0x20 },
+       { OV9740_PRE_PLL_CLK_DIV,       0x03 },
+       { OV9740_PLL_MULTIPLIER,        0x4c },
+       { OV9740_VT_SYS_CLK_DIV,        0x01 },
+       { OV9740_VT_PIX_CLK_DIV,        0x08 },
+       { OV9740_PLL_CTRL3010,          0x01 },
+       { OV9740_VFIFO_CTRL00,          0x82 },
+
+       /* Timing Setting */
+       /* VTS */
+       { OV9740_FRM_LENGTH_LN_HI,      0x03 },
+       { OV9740_FRM_LENGTH_LN_LO,      0x07 },
+       /* HTS */
+       { OV9740_LN_LENGTH_PCK_HI,      0x06 },
+       { OV9740_LN_LENGTH_PCK_LO,      0x62 },
+
+       /* MIPI Control */
+       { OV9740_MIPI_CTRL00,           0x44 }, /* 0x64 for discontinuous clk */
+       { OV9740_MIPI_3837,             0x01 },
+       { OV9740_MIPI_CTRL01,           0x0f },
+       { OV9740_MIPI_CTRL03,           0x05 },
+       { OV9740_MIPI_CTRL05,           0x10 },
+       { OV9740_VFIFO_RD_CTRL,         0x16 },
+       { OV9740_MIPI_CTRL_3012,        0x70 },
+       { OV9740_SC_CMMM_MIPI_CTR,      0x01 },
+
+       /* YUYV order */
+       { OV9740_ISP_CTRL19,            0x02 },
+};
+
+static u32 ov9740_codes[] = {
+       MEDIA_BUS_FMT_YUYV8_2X8,
+};
+
+/* read a register */
+static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
+{
+       int ret;
+       struct i2c_msg msg[] = {
+               {
+                       .addr   = client->addr,
+                       .flags  = 0,
+                       .len    = 2,
+                       .buf    = (u8 *)&reg,
+               },
+               {
+                       .addr   = client->addr,
+                       .flags  = I2C_M_RD,
+                       .len    = 1,
+                       .buf    = val,
+               },
+       };
+
+       reg = swab16(reg);
+
+       ret = i2c_transfer(client->adapter, msg, 2);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg);
+               return ret;
+       }
+
+       return 0;
+}
+
+/* write a register */
+static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val)
+{
+       struct i2c_msg msg;
+       struct {
+               u16 reg;
+               u8 val;
+       } __packed buf;
+       int ret;
+
+       reg = swab16(reg);
+
+       buf.reg = reg;
+       buf.val = val;
+
+       msg.addr        = client->addr;
+       msg.flags       = 0;
+       msg.len         = 3;
+       msg.buf         = (u8 *)&buf;
+
+       ret = i2c_transfer(client->adapter, &msg, 1);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg);
+               return ret;
+       }
+
+       return 0;
+}
+
+
+/* Read a register, alter its bits, write it back */
+static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset)
+{
+       u8 val;
+       int ret;
+
+       ret = ov9740_reg_read(client, reg, &val);
+       if (ret < 0) {
+               dev_err(&client->dev,
+                       "[Read]-Modify-Write of register 0x%04x failed!\n",
+                       reg);
+               return ret;
+       }
+
+       val |= set;
+       val &= ~unset;
+
+       ret = ov9740_reg_write(client, reg, val);
+       if (ret < 0) {
+               dev_err(&client->dev,
+                       "Read-Modify-[Write] of register 0x%04x failed!\n",
+                       reg);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int ov9740_reg_write_array(struct i2c_client *client,
+                                 const struct ov9740_reg *regarray,
+                                 int regarraylen)
+{
+       int i;
+       int ret;
+
+       for (i = 0; i < regarraylen; i++) {
+               ret = ov9740_reg_write(client,
+                                      regarray[i].reg, regarray[i].val);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+/* Start/Stop streaming from the device */
+static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov9740_priv *priv = to_ov9740(sd);
+       int ret;
+
+       /* Program orientation register. */
+       if (priv->flag_vflip)
+               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0);
+       else
+               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2);
+       if (ret < 0)
+               return ret;
+
+       if (priv->flag_hflip)
+               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0);
+       else
+               ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1);
+       if (ret < 0)
+               return ret;
+
+       if (enable) {
+               dev_dbg(&client->dev, "Enabling Streaming\n");
+               /* Start Streaming */
+               ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01);
+
+       } else {
+               dev_dbg(&client->dev, "Disabling Streaming\n");
+               /* Software Reset */
+               ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01);
+               if (!ret)
+                       /* Setting Streaming to Standby */
+                       ret = ov9740_reg_write(client, OV9740_MODE_SELECT,
+                                              0x00);
+       }
+
+       priv->current_enable = enable;
+
+       return ret;
+}
+
+/* select nearest higher resolution for capture */
+static void ov9740_res_roundup(u32 *width, u32 *height)
+{
+       /* Width must be a multiple of 4 pixels. */
+       *width = ALIGN(*width, 4);
+
+       /* Max resolution is 1280x720 (720p). */
+       if (*width > OV9740_MAX_WIDTH)
+               *width = OV9740_MAX_WIDTH;
+
+       if (*height > OV9740_MAX_HEIGHT)
+               *height = OV9740_MAX_HEIGHT;
+}
+
+/* Setup registers according to resolution and color encoding */
+static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
+{
+       u32 x_start;
+       u32 y_start;
+       u32 x_end;
+       u32 y_end;
+       bool scaling = false;
+       u32 scale_input_x;
+       u32 scale_input_y;
+       int ret;
+
+       if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
+               scaling = true;
+
+       /*
+        * Try to use as much of the sensor area as possible when supporting
+        * smaller resolutions.  Depending on the aspect ratio of the
+        * chosen resolution, we can either use the full width of the sensor,
+        * or the full height of the sensor (or both if the aspect ratio is
+        * the same as 1280x720.
+        */
+       if ((OV9740_MAX_WIDTH * height) > (OV9740_MAX_HEIGHT * width)) {
+               scale_input_x = (OV9740_MAX_HEIGHT * width) / height;
+               scale_input_y = OV9740_MAX_HEIGHT;
+       } else {
+               scale_input_x = OV9740_MAX_WIDTH;
+               scale_input_y = (OV9740_MAX_WIDTH * height) / width;
+       }
+
+       /* These describe the area of the sensor to use. */
+       x_start = (OV9740_MAX_WIDTH - scale_input_x) / 2;
+       y_start = (OV9740_MAX_HEIGHT - scale_input_y) / 2;
+       x_end = x_start + scale_input_x - 1;
+       y_end = y_start + scale_input_y - 1;
+
+       ret = ov9740_reg_write(client, OV9740_X_ADDR_START_HI, x_start >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_X_ADDR_START_LO, x_start & 0xff);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_HI, y_start >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_Y_ADDR_START_LO, y_start & 0xff);
+       if (ret)
+               goto done;
+
+       ret = ov9740_reg_write(client, OV9740_X_ADDR_END_HI, x_end >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_X_ADDR_END_LO, x_end & 0xff);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_HI, y_end >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_Y_ADDR_END_LO, y_end & 0xff);
+       if (ret)
+               goto done;
+
+       ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_HI, width >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_X_OUTPUT_SIZE_LO, width & 0xff);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_HI, height >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_Y_OUTPUT_SIZE_LO, height & 0xff);
+       if (ret)
+               goto done;
+
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL1E, scale_input_x >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL1F, scale_input_x & 0xff);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL20, scale_input_y >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL21, scale_input_y & 0xff);
+       if (ret)
+               goto done;
+
+       ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_HI,
+                              (scale_input_x - width) >> 8);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_VFIFO_READ_START_LO,
+                              (scale_input_x - width) & 0xff);
+       if (ret)
+               goto done;
+
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL00, 0xff);
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL01, 0xef |
+                                                         (scaling << 4));
+       if (ret)
+               goto done;
+       ret = ov9740_reg_write(client, OV9740_ISP_CTRL03, 0xff);
+
+done:
+       return ret;
+}
+
+/* set the format we will capture in */
+static int ov9740_s_fmt(struct v4l2_subdev *sd,
+                       struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov9740_priv *priv = to_ov9740(sd);
+       int ret;
+
+       ret = ov9740_reg_write_array(client, ov9740_defaults,
+                                    ARRAY_SIZE(ov9740_defaults));
+       if (ret < 0)
+               return ret;
+
+       ret = ov9740_set_res(client, mf->width, mf->height);
+       if (ret < 0)
+               return ret;
+
+       priv->current_mf = *mf;
+       return ret;
+}
+
+static int ov9740_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+
+       if (format->pad)
+               return -EINVAL;
+
+       ov9740_res_roundup(&mf->width, &mf->height);
+
+       mf->field = V4L2_FIELD_NONE;
+       mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
+       mf->colorspace = V4L2_COLORSPACE_SRGB;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return ov9740_s_fmt(sd, mf);
+       cfg->try_fmt = *mf;
+       return 0;
+}
+
+static int ov9740_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index >= ARRAY_SIZE(ov9740_codes))
+               return -EINVAL;
+
+       code->code = ov9740_codes[code->index];
+
+       return 0;
+}
+
+static int ov9740_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+       case V4L2_SEL_TGT_CROP:
+               sel->r.left = 0;
+               sel->r.top = 0;
+               sel->r.width = OV9740_MAX_WIDTH;
+               sel->r.height = OV9740_MAX_HEIGHT;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+/* Set status of additional camera capabilities */
+static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct ov9740_priv *priv =
+               container_of(ctrl->handler, struct ov9740_priv, hdl);
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               priv->flag_vflip = ctrl->val;
+               break;
+       case V4L2_CID_HFLIP:
+               priv->flag_hflip = ctrl->val;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int ov9740_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct ov9740_priv *priv = to_ov9740(sd);
+       int ret;
+
+       if (on) {
+               ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
+               if (ret < 0)
+                       return ret;
+
+               if (priv->current_enable) {
+                       ov9740_s_fmt(sd, &priv->current_mf);
+                       ov9740_s_stream(sd, 1);
+               }
+       } else {
+               if (priv->current_enable) {
+                       ov9740_s_stream(sd, 0);
+                       priv->current_enable = true;
+               }
+
+               soc_camera_power_off(&client->dev, ssdd, priv->clk);
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov9740_get_register(struct v4l2_subdev *sd,
+                              struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+       u8 val;
+
+       if (reg->reg & ~0xffff)
+               return -EINVAL;
+
+       reg->size = 2;
+
+       ret = ov9740_reg_read(client, reg->reg, &val);
+       if (ret)
+               return ret;
+
+       reg->val = (__u64)val;
+
+       return ret;
+}
+
+static int ov9740_set_register(struct v4l2_subdev *sd,
+                              const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg & ~0xffff || reg->val & ~0xff)
+               return -EINVAL;
+
+       return ov9740_reg_write(client, reg->reg, reg->val);
+}
+#endif
+
+static int ov9740_video_probe(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov9740_priv *priv = to_ov9740(sd);
+       u8 modelhi, modello;
+       int ret;
+
+       ret = ov9740_s_power(&priv->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * check and show product ID and manufacturer ID
+        */
+       ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
+       if (ret < 0)
+               goto done;
+
+       ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
+       if (ret < 0)
+               goto done;
+
+       priv->model = (modelhi << 8) | modello;
+
+       ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
+       if (ret < 0)
+               goto done;
+
+       ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
+       if (ret < 0)
+               goto done;
+
+       ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
+       if (ret < 0)
+               goto done;
+
+       if (priv->model != 0x9740) {
+               ret = -ENODEV;
+               goto done;
+       }
+
+       dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, Manufacturer 0x%02x, SMIA Version 0x%02x\n",
+                priv->model, priv->revision, priv->manid, priv->smiaver);
+
+       ret = v4l2_ctrl_handler_setup(&priv->hdl);
+
+done:
+       ov9740_s_power(&priv->subdev, 0);
+       return ret;
+}
+
+/* Request bus settings on camera side */
+static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov9740_video_ops = {
+       .s_stream       = ov9740_s_stream,
+       .g_mbus_config  = ov9740_g_mbus_config,
+};
+
+static const struct v4l2_subdev_core_ops ov9740_core_ops = {
+       .s_power                = ov9740_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register             = ov9740_get_register,
+       .s_register             = ov9740_set_register,
+#endif
+};
+
+static const struct v4l2_subdev_pad_ops ov9740_pad_ops = {
+       .enum_mbus_code = ov9740_enum_mbus_code,
+       .get_selection  = ov9740_get_selection,
+       .set_fmt        = ov9740_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov9740_subdev_ops = {
+       .core   = &ov9740_core_ops,
+       .video  = &ov9740_video_ops,
+       .pad    = &ov9740_pad_ops,
+};
+
+static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
+       .s_ctrl = ov9740_s_ctrl,
+};
+
+/*
+ * i2c_driver function
+ */
+static int ov9740_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct ov9740_priv *priv;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       int ret;
+
+       if (!ssdd) {
+               dev_err(&client->dev, "Missing platform_data for driver\n");
+               return -EINVAL;
+       }
+
+       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
+       v4l2_ctrl_handler_init(&priv->hdl, 13);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error)
+               return priv->hdl.error;
+
+       priv->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(priv->clk)) {
+               ret = PTR_ERR(priv->clk);
+               goto eclkget;
+       }
+
+       ret = ov9740_video_probe(client);
+       if (ret < 0) {
+               v4l2_clk_put(priv->clk);
+eclkget:
+               v4l2_ctrl_handler_free(&priv->hdl);
+       }
+
+       return ret;
+}
+
+static int ov9740_remove(struct i2c_client *client)
+{
+       struct ov9740_priv *priv = i2c_get_clientdata(client);
+
+       v4l2_clk_put(priv->clk);
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
+       return 0;
+}
+
+static const struct i2c_device_id ov9740_id[] = {
+       { "ov9740", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ov9740_id);
+
+static struct i2c_driver ov9740_i2c_driver = {
+       .driver = {
+               .name = "ov9740",
+       },
+       .probe    = ov9740_probe,
+       .remove   = ov9740_remove,
+       .id_table = ov9740_id,
+};
+
+module_i2c_driver(ov9740_i2c_driver);
+
+MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
+MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_rj54n1cb0c.c b/drivers/media/i2c/soc_camera/soc_rj54n1cb0c.c
new file mode 100644 (file)
index 0000000..f0cb49a
--- /dev/null
@@ -0,0 +1,1415 @@
+/*
+ * Driver for RJ54N1CB0C CMOS Image Sensor from Sharp
+ *
+ * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+#include <linux/module.h>
+
+#include <media/i2c/rj54n1cb0c.h>
+#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+
+#define RJ54N1_DEV_CODE                        0x0400
+#define RJ54N1_DEV_CODE2               0x0401
+#define RJ54N1_OUT_SEL                 0x0403
+#define RJ54N1_XY_OUTPUT_SIZE_S_H      0x0404
+#define RJ54N1_X_OUTPUT_SIZE_S_L       0x0405
+#define RJ54N1_Y_OUTPUT_SIZE_S_L       0x0406
+#define RJ54N1_XY_OUTPUT_SIZE_P_H      0x0407
+#define RJ54N1_X_OUTPUT_SIZE_P_L       0x0408
+#define RJ54N1_Y_OUTPUT_SIZE_P_L       0x0409
+#define RJ54N1_LINE_LENGTH_PCK_S_H     0x040a
+#define RJ54N1_LINE_LENGTH_PCK_S_L     0x040b
+#define RJ54N1_LINE_LENGTH_PCK_P_H     0x040c
+#define RJ54N1_LINE_LENGTH_PCK_P_L     0x040d
+#define RJ54N1_RESIZE_N                        0x040e
+#define RJ54N1_RESIZE_N_STEP           0x040f
+#define RJ54N1_RESIZE_STEP             0x0410
+#define RJ54N1_RESIZE_HOLD_H           0x0411
+#define RJ54N1_RESIZE_HOLD_L           0x0412
+#define RJ54N1_H_OBEN_OFS              0x0413
+#define RJ54N1_V_OBEN_OFS              0x0414
+#define RJ54N1_RESIZE_CONTROL          0x0415
+#define RJ54N1_STILL_CONTROL           0x0417
+#define RJ54N1_INC_USE_SEL_H           0x0425
+#define RJ54N1_INC_USE_SEL_L           0x0426
+#define RJ54N1_MIRROR_STILL_MODE       0x0427
+#define RJ54N1_INIT_START              0x0428
+#define RJ54N1_SCALE_1_2_LEV           0x0429
+#define RJ54N1_SCALE_4_LEV             0x042a
+#define RJ54N1_Y_GAIN                  0x04d8
+#define RJ54N1_APT_GAIN_UP             0x04fa
+#define RJ54N1_RA_SEL_UL               0x0530
+#define RJ54N1_BYTE_SWAP               0x0531
+#define RJ54N1_OUT_SIGPO               0x053b
+#define RJ54N1_WB_SEL_WEIGHT_I         0x054e
+#define RJ54N1_BIT8_WB                 0x0569
+#define RJ54N1_HCAPS_WB                        0x056a
+#define RJ54N1_VCAPS_WB                        0x056b
+#define RJ54N1_HCAPE_WB                        0x056c
+#define RJ54N1_VCAPE_WB                        0x056d
+#define RJ54N1_EXPOSURE_CONTROL                0x058c
+#define RJ54N1_FRAME_LENGTH_S_H                0x0595
+#define RJ54N1_FRAME_LENGTH_S_L                0x0596
+#define RJ54N1_FRAME_LENGTH_P_H                0x0597
+#define RJ54N1_FRAME_LENGTH_P_L                0x0598
+#define RJ54N1_PEAK_H                  0x05b7
+#define RJ54N1_PEAK_50                 0x05b8
+#define RJ54N1_PEAK_60                 0x05b9
+#define RJ54N1_PEAK_DIFF               0x05ba
+#define RJ54N1_IOC                     0x05ef
+#define RJ54N1_TG_BYPASS               0x0700
+#define RJ54N1_PLL_L                   0x0701
+#define RJ54N1_PLL_N                   0x0702
+#define RJ54N1_PLL_EN                  0x0704
+#define RJ54N1_RATIO_TG                        0x0706
+#define RJ54N1_RATIO_T                 0x0707
+#define RJ54N1_RATIO_R                 0x0708
+#define RJ54N1_RAMP_TGCLK_EN           0x0709
+#define RJ54N1_OCLK_DSP                        0x0710
+#define RJ54N1_RATIO_OP                        0x0711
+#define RJ54N1_RATIO_O                 0x0712
+#define RJ54N1_OCLK_SEL_EN             0x0713
+#define RJ54N1_CLK_RST                 0x0717
+#define RJ54N1_RESET_STANDBY           0x0718
+#define RJ54N1_FWFLG                   0x07fe
+
+#define E_EXCLK                                (1 << 7)
+#define SOFT_STDBY                     (1 << 4)
+#define SEN_RSTX                       (1 << 2)
+#define TG_RSTX                                (1 << 1)
+#define DSP_RSTX                       (1 << 0)
+
+#define RESIZE_HOLD_SEL                        (1 << 2)
+#define RESIZE_GO                      (1 << 1)
+
+/*
+ * When cropping, the camera automatically centers the cropped region, there
+ * doesn't seem to be a way to specify an explicit location of the rectangle.
+ */
+#define RJ54N1_COLUMN_SKIP             0
+#define RJ54N1_ROW_SKIP                        0
+#define RJ54N1_MAX_WIDTH               1600
+#define RJ54N1_MAX_HEIGHT              1200
+
+#define PLL_L                          2
+#define PLL_N                          0x31
+
+/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
+
+/* RJ54N1CB0C has only one fixed colorspace per pixelcode */
+struct rj54n1_datafmt {
+       u32     code;
+       enum v4l2_colorspace            colorspace;
+};
+
+/* Find a data format by a pixel code in an array */
+static const struct rj54n1_datafmt *rj54n1_find_datafmt(
+       u32 code, const struct rj54n1_datafmt *fmt,
+       int n)
+{
+       int i;
+       for (i = 0; i < n; i++)
+               if (fmt[i].code == code)
+                       return fmt + i;
+
+       return NULL;
+}
+
+static const struct rj54n1_datafmt rj54n1_colour_fmts[] = {
+       {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
+       {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_JPEG},
+       {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB},
+       {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
+};
+
+struct rj54n1_clock_div {
+       u8 ratio_tg;    /* can be 0 or an odd number */
+       u8 ratio_t;
+       u8 ratio_r;
+       u8 ratio_op;
+       u8 ratio_o;
+};
+
+struct rj54n1 {
+       struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct v4l2_clk *clk;
+       struct rj54n1_clock_div clk_div;
+       const struct rj54n1_datafmt *fmt;
+       struct v4l2_rect rect;  /* Sensor window */
+       unsigned int tgclk_mhz;
+       bool auto_wb;
+       unsigned short width;   /* Output window */
+       unsigned short height;
+       unsigned short resize;  /* Sensor * 1024 / resize = Output */
+       unsigned short scale;
+       u8 bank;
+};
+
+struct rj54n1_reg_val {
+       u16 reg;
+       u8 val;
+};
+
+static const struct rj54n1_reg_val bank_4[] = {
+       {0x417, 0},
+       {0x42c, 0},
+       {0x42d, 0xf0},
+       {0x42e, 0},
+       {0x42f, 0x50},
+       {0x430, 0xf5},
+       {0x431, 0x16},
+       {0x432, 0x20},
+       {0x433, 0},
+       {0x434, 0xc8},
+       {0x43c, 8},
+       {0x43e, 0x90},
+       {0x445, 0x83},
+       {0x4ba, 0x58},
+       {0x4bb, 4},
+       {0x4bc, 0x20},
+       {0x4db, 4},
+       {0x4fe, 2},
+};
+
+static const struct rj54n1_reg_val bank_5[] = {
+       {0x514, 0},
+       {0x516, 0},
+       {0x518, 0},
+       {0x51a, 0},
+       {0x51d, 0xff},
+       {0x56f, 0x28},
+       {0x575, 0x40},
+       {0x5bc, 0x48},
+       {0x5c1, 6},
+       {0x5e5, 0x11},
+       {0x5e6, 0x43},
+       {0x5e7, 0x33},
+       {0x5e8, 0x21},
+       {0x5e9, 0x30},
+       {0x5ea, 0x0},
+       {0x5eb, 0xa5},
+       {0x5ec, 0xff},
+       {0x5fe, 2},
+};
+
+static const struct rj54n1_reg_val bank_7[] = {
+       {0x70a, 0},
+       {0x714, 0xff},
+       {0x715, 0xff},
+       {0x716, 0x1f},
+       {0x7FE, 2},
+};
+
+static const struct rj54n1_reg_val bank_8[] = {
+       {0x800, 0x00},
+       {0x801, 0x01},
+       {0x802, 0x61},
+       {0x805, 0x00},
+       {0x806, 0x00},
+       {0x807, 0x00},
+       {0x808, 0x00},
+       {0x809, 0x01},
+       {0x80A, 0x61},
+       {0x80B, 0x00},
+       {0x80C, 0x01},
+       {0x80D, 0x00},
+       {0x80E, 0x00},
+       {0x80F, 0x00},
+       {0x810, 0x00},
+       {0x811, 0x01},
+       {0x812, 0x61},
+       {0x813, 0x00},
+       {0x814, 0x11},
+       {0x815, 0x00},
+       {0x816, 0x41},
+       {0x817, 0x00},
+       {0x818, 0x51},
+       {0x819, 0x01},
+       {0x81A, 0x1F},
+       {0x81B, 0x00},
+       {0x81C, 0x01},
+       {0x81D, 0x00},
+       {0x81E, 0x11},
+       {0x81F, 0x00},
+       {0x820, 0x41},
+       {0x821, 0x00},
+       {0x822, 0x51},
+       {0x823, 0x00},
+       {0x824, 0x00},
+       {0x825, 0x00},
+       {0x826, 0x47},
+       {0x827, 0x01},
+       {0x828, 0x4F},
+       {0x829, 0x00},
+       {0x82A, 0x00},
+       {0x82B, 0x00},
+       {0x82C, 0x30},
+       {0x82D, 0x00},
+       {0x82E, 0x40},
+       {0x82F, 0x00},
+       {0x830, 0xB3},
+       {0x831, 0x00},
+       {0x832, 0xE3},
+       {0x833, 0x00},
+       {0x834, 0x00},
+       {0x835, 0x00},
+       {0x836, 0x00},
+       {0x837, 0x00},
+       {0x838, 0x00},
+       {0x839, 0x01},
+       {0x83A, 0x61},
+       {0x83B, 0x00},
+       {0x83C, 0x01},
+       {0x83D, 0x00},
+       {0x83E, 0x00},
+       {0x83F, 0x00},
+       {0x840, 0x00},
+       {0x841, 0x01},
+       {0x842, 0x61},
+       {0x843, 0x00},
+       {0x844, 0x1D},
+       {0x845, 0x00},
+       {0x846, 0x00},
+       {0x847, 0x00},
+       {0x848, 0x00},
+       {0x849, 0x01},
+       {0x84A, 0x1F},
+       {0x84B, 0x00},
+       {0x84C, 0x05},
+       {0x84D, 0x00},
+       {0x84E, 0x19},
+       {0x84F, 0x01},
+       {0x850, 0x21},
+       {0x851, 0x01},
+       {0x852, 0x5D},
+       {0x853, 0x00},
+       {0x854, 0x00},
+       {0x855, 0x00},
+       {0x856, 0x19},
+       {0x857, 0x01},
+       {0x858, 0x21},
+       {0x859, 0x00},
+       {0x85A, 0x00},
+       {0x85B, 0x00},
+       {0x85C, 0x00},
+       {0x85D, 0x00},
+       {0x85E, 0x00},
+       {0x85F, 0x00},
+       {0x860, 0xB3},
+       {0x861, 0x00},
+       {0x862, 0xE3},
+       {0x863, 0x00},
+       {0x864, 0x00},
+       {0x865, 0x00},
+       {0x866, 0x00},
+       {0x867, 0x00},
+       {0x868, 0x00},
+       {0x869, 0xE2},
+       {0x86A, 0x00},
+       {0x86B, 0x01},
+       {0x86C, 0x06},
+       {0x86D, 0x00},
+       {0x86E, 0x00},
+       {0x86F, 0x00},
+       {0x870, 0x60},
+       {0x871, 0x8C},
+       {0x872, 0x10},
+       {0x873, 0x00},
+       {0x874, 0xE0},
+       {0x875, 0x00},
+       {0x876, 0x27},
+       {0x877, 0x01},
+       {0x878, 0x00},
+       {0x879, 0x00},
+       {0x87A, 0x00},
+       {0x87B, 0x03},
+       {0x87C, 0x00},
+       {0x87D, 0x00},
+       {0x87E, 0x00},
+       {0x87F, 0x00},
+       {0x880, 0x00},
+       {0x881, 0x00},
+       {0x882, 0x00},
+       {0x883, 0x00},
+       {0x884, 0x00},
+       {0x885, 0x00},
+       {0x886, 0xF8},
+       {0x887, 0x00},
+       {0x888, 0x03},
+       {0x889, 0x00},
+       {0x88A, 0x64},
+       {0x88B, 0x00},
+       {0x88C, 0x03},
+       {0x88D, 0x00},
+       {0x88E, 0xB1},
+       {0x88F, 0x00},
+       {0x890, 0x03},
+       {0x891, 0x01},
+       {0x892, 0x1D},
+       {0x893, 0x00},
+       {0x894, 0x03},
+       {0x895, 0x01},
+       {0x896, 0x4B},
+       {0x897, 0x00},
+       {0x898, 0xE5},
+       {0x899, 0x00},
+       {0x89A, 0x01},
+       {0x89B, 0x00},
+       {0x89C, 0x01},
+       {0x89D, 0x04},
+       {0x89E, 0xC8},
+       {0x89F, 0x00},
+       {0x8A0, 0x01},
+       {0x8A1, 0x01},
+       {0x8A2, 0x61},
+       {0x8A3, 0x00},
+       {0x8A4, 0x01},
+       {0x8A5, 0x00},
+       {0x8A6, 0x00},
+       {0x8A7, 0x00},
+       {0x8A8, 0x00},
+       {0x8A9, 0x00},
+       {0x8AA, 0x7F},
+       {0x8AB, 0x03},
+       {0x8AC, 0x00},
+       {0x8AD, 0x00},
+       {0x8AE, 0x00},
+       {0x8AF, 0x00},
+       {0x8B0, 0x00},
+       {0x8B1, 0x00},
+       {0x8B6, 0x00},
+       {0x8B7, 0x01},
+       {0x8B8, 0x00},
+       {0x8B9, 0x00},
+       {0x8BA, 0x02},
+       {0x8BB, 0x00},
+       {0x8BC, 0xFF},
+       {0x8BD, 0x00},
+       {0x8FE, 2},
+};
+
+static const struct rj54n1_reg_val bank_10[] = {
+       {0x10bf, 0x69}
+};
+
+/* Clock dividers - these are default register values, divider = register + 1 */
+static const struct rj54n1_clock_div clk_div = {
+       .ratio_tg       = 3 /* default: 5 */,
+       .ratio_t        = 4 /* default: 1 */,
+       .ratio_r        = 4 /* default: 0 */,
+       .ratio_op       = 1 /* default: 5 */,
+       .ratio_o        = 9 /* default: 0 */,
+};
+
+static struct rj54n1 *to_rj54n1(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client), struct rj54n1, subdev);
+}
+
+static int reg_read(struct i2c_client *client, const u16 reg)
+{
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       int ret;
+
+       /* set bank */
+       if (rj54n1->bank != reg >> 8) {
+               dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
+               ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
+               if (ret < 0)
+                       return ret;
+               rj54n1->bank = reg >> 8;
+       }
+       return i2c_smbus_read_byte_data(client, reg & 0xff);
+}
+
+static int reg_write(struct i2c_client *client, const u16 reg,
+                    const u8 data)
+{
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       int ret;
+
+       /* set bank */
+       if (rj54n1->bank != reg >> 8) {
+               dev_dbg(&client->dev, "[0x%x] = 0x%x\n", 0xff, reg >> 8);
+               ret = i2c_smbus_write_byte_data(client, 0xff, reg >> 8);
+               if (ret < 0)
+                       return ret;
+               rj54n1->bank = reg >> 8;
+       }
+       dev_dbg(&client->dev, "[0x%x] = 0x%x\n", reg & 0xff, data);
+       return i2c_smbus_write_byte_data(client, reg & 0xff, data);
+}
+
+static int reg_set(struct i2c_client *client, const u16 reg,
+                  const u8 data, const u8 mask)
+{
+       int ret;
+
+       ret = reg_read(client, reg);
+       if (ret < 0)
+               return ret;
+       return reg_write(client, reg, (ret & ~mask) | (data & mask));
+}
+
+static int reg_write_multiple(struct i2c_client *client,
+                             const struct rj54n1_reg_val *rv, const int n)
+{
+       int i, ret;
+
+       for (i = 0; i < n; i++) {
+               ret = reg_write(client, rv->reg, rv->val);
+               if (ret < 0)
+                       return ret;
+               rv++;
+       }
+
+       return 0;
+}
+
+static int rj54n1_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index >= ARRAY_SIZE(rj54n1_colour_fmts))
+               return -EINVAL;
+
+       code->code = rj54n1_colour_fmts[code->index].code;
+       return 0;
+}
+
+static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       /* Switch between preview and still shot modes */
+       return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
+}
+
+static int rj54n1_set_rect(struct i2c_client *client,
+                          u16 reg_x, u16 reg_y, u16 reg_xy,
+                          u32 width, u32 height)
+{
+       int ret;
+
+       ret = reg_write(client, reg_xy,
+                       ((width >> 4) & 0x70) |
+                       ((height >> 8) & 7));
+
+       if (!ret)
+               ret = reg_write(client, reg_x, width & 0xff);
+       if (!ret)
+               ret = reg_write(client, reg_y, height & 0xff);
+
+       return ret;
+}
+
+/*
+ * Some commands, specifically certain initialisation sequences, require
+ * a commit operation.
+ */
+static int rj54n1_commit(struct i2c_client *client)
+{
+       int ret = reg_write(client, RJ54N1_INIT_START, 1);
+       msleep(10);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_INIT_START, 0);
+       return ret;
+}
+
+static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
+                              s32 *out_w, s32 *out_h);
+
+static int rj54n1_set_selection(struct v4l2_subdev *sd,
+                               struct v4l2_subdev_pad_config *cfg,
+                               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       const struct v4l2_rect *rect = &sel->r;
+       int dummy = 0, output_w, output_h,
+               input_w = rect->width, input_h = rect->height;
+       int ret;
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       /* arbitrary minimum width and height, edges unimportant */
+       soc_camera_limit_side(&dummy, &input_w,
+                    RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH);
+
+       soc_camera_limit_side(&dummy, &input_h,
+                    RJ54N1_ROW_SKIP, 8, RJ54N1_MAX_HEIGHT);
+
+       output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize;
+       output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize;
+
+       dev_dbg(&client->dev, "Scaling for %dx%d : %u = %dx%d\n",
+               input_w, input_h, rj54n1->resize, output_w, output_h);
+
+       ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
+       if (ret < 0)
+               return ret;
+
+       rj54n1->width           = output_w;
+       rj54n1->height          = output_h;
+       rj54n1->resize          = ret;
+       rj54n1->rect.width      = input_w;
+       rj54n1->rect.height     = input_h;
+
+       return 0;
+}
+
+static int rj54n1_get_selection(struct v4l2_subdev *sd,
+                               struct v4l2_subdev_pad_config *cfg,
+                               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.left = RJ54N1_COLUMN_SKIP;
+               sel->r.top = RJ54N1_ROW_SKIP;
+               sel->r.width = RJ54N1_MAX_WIDTH;
+               sel->r.height = RJ54N1_MAX_HEIGHT;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+               sel->r = rj54n1->rect;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int rj54n1_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+
+       if (format->pad)
+               return -EINVAL;
+
+       mf->code        = rj54n1->fmt->code;
+       mf->colorspace  = rj54n1->fmt->colorspace;
+       mf->field       = V4L2_FIELD_NONE;
+       mf->width       = rj54n1->width;
+       mf->height      = rj54n1->height;
+
+       return 0;
+}
+
+/*
+ * The actual geometry configuration routine. It scales the input window into
+ * the output one, updates the window sizes and returns an error or the resize
+ * coefficient on success. Note: we only use the "Fixed Scaling" on this camera.
+ */
+static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h,
+                              s32 *out_w, s32 *out_h)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       unsigned int skip, resize, input_w = *in_w, input_h = *in_h,
+               output_w = *out_w, output_h = *out_h;
+       u16 inc_sel, wb_bit8, wb_left, wb_right, wb_top, wb_bottom;
+       unsigned int peak, peak_50, peak_60;
+       int ret;
+
+       /*
+        * We have a problem with crops, where the window is larger than 512x384
+        * and output window is larger than a half of the input one. In this
+        * case we have to either reduce the input window to equal or below
+        * 512x384 or the output window to equal or below 1/2 of the input.
+        */
+       if (output_w > max(512U, input_w / 2)) {
+               if (2 * output_w > RJ54N1_MAX_WIDTH) {
+                       input_w = RJ54N1_MAX_WIDTH;
+                       output_w = RJ54N1_MAX_WIDTH / 2;
+               } else {
+                       input_w = output_w * 2;
+               }
+
+               dev_dbg(&client->dev, "Adjusted output width: in %u, out %u\n",
+                       input_w, output_w);
+       }
+
+       if (output_h > max(384U, input_h / 2)) {
+               if (2 * output_h > RJ54N1_MAX_HEIGHT) {
+                       input_h = RJ54N1_MAX_HEIGHT;
+                       output_h = RJ54N1_MAX_HEIGHT / 2;
+               } else {
+                       input_h = output_h * 2;
+               }
+
+               dev_dbg(&client->dev, "Adjusted output height: in %u, out %u\n",
+                       input_h, output_h);
+       }
+
+       /* Idea: use the read mode for snapshots, handle separate geometries */
+       ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L,
+                             RJ54N1_Y_OUTPUT_SIZE_S_L,
+                             RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h);
+       if (!ret)
+               ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_P_L,
+                             RJ54N1_Y_OUTPUT_SIZE_P_L,
+                             RJ54N1_XY_OUTPUT_SIZE_P_H, output_w, output_h);
+
+       if (ret < 0)
+               return ret;
+
+       if (output_w > input_w && output_h > input_h) {
+               input_w = output_w;
+               input_h = output_h;
+
+               resize = 1024;
+       } else {
+               unsigned int resize_x, resize_y;
+               resize_x = (input_w * 1024 + output_w / 2) / output_w;
+               resize_y = (input_h * 1024 + output_h / 2) / output_h;
+
+               /* We want max(resize_x, resize_y), check if it still fits */
+               if (resize_x > resize_y &&
+                   (output_h * resize_x + 512) / 1024 > RJ54N1_MAX_HEIGHT)
+                       resize = (RJ54N1_MAX_HEIGHT * 1024 + output_h / 2) /
+                               output_h;
+               else if (resize_y > resize_x &&
+                        (output_w * resize_y + 512) / 1024 > RJ54N1_MAX_WIDTH)
+                       resize = (RJ54N1_MAX_WIDTH * 1024 + output_w / 2) /
+                               output_w;
+               else
+                       resize = max(resize_x, resize_y);
+
+               /* Prohibited value ranges */
+               switch (resize) {
+               case 2040 ... 2047:
+                       resize = 2039;
+                       break;
+               case 4080 ... 4095:
+                       resize = 4079;
+                       break;
+               case 8160 ... 8191:
+                       resize = 8159;
+                       break;
+               case 16320 ... 16384:
+                       resize = 16319;
+               }
+       }
+
+       /* Set scaling */
+       ret = reg_write(client, RJ54N1_RESIZE_HOLD_L, resize & 0xff);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESIZE_HOLD_H, resize >> 8);
+
+       if (ret < 0)
+               return ret;
+
+       /*
+        * Configure a skipping bitmask. The sensor will select a skipping value
+        * among set bits automatically. This is very unclear in the datasheet
+        * too. I was told, in this register one enables all skipping values,
+        * that are required for a specific resize, and the camera selects
+        * automatically, which ones to use. But it is unclear how to identify,
+        * which cropping values are needed. Secondly, why don't we just set all
+        * bits and let the camera choose? Would it increase processing time and
+        * reduce the framerate? Using 0xfffc for INC_USE_SEL doesn't seem to
+        * improve the image quality or stability for larger frames (see comment
+        * above), but I didn't check the framerate.
+        */
+       skip = min(resize / 1024, 15U);
+
+       inc_sel = 1 << skip;
+
+       if (inc_sel <= 2)
+               inc_sel = 0xc;
+       else if (resize & 1023 && skip < 15)
+               inc_sel |= 1 << (skip + 1);
+
+       ret = reg_write(client, RJ54N1_INC_USE_SEL_L, inc_sel & 0xfc);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8);
+
+       if (!rj54n1->auto_wb) {
+               /* Auto white balance window */
+               wb_left   = output_w / 16;
+               wb_right  = (3 * output_w / 4 - 3) / 4;
+               wb_top    = output_h / 16;
+               wb_bottom = (3 * output_h / 4 - 3) / 4;
+               wb_bit8   = ((wb_left >> 2) & 0x40) | ((wb_top >> 4) & 0x10) |
+                       ((wb_right >> 6) & 4) | ((wb_bottom >> 8) & 1);
+
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_BIT8_WB, wb_bit8);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_HCAPS_WB, wb_left);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_VCAPS_WB, wb_top);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_HCAPE_WB, wb_right);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_VCAPE_WB, wb_bottom);
+       }
+
+       /* Antiflicker */
+       peak = 12 * RJ54N1_MAX_WIDTH * (1 << 14) * resize / rj54n1->tgclk_mhz /
+               10000;
+       peak_50 = peak / 6;
+       peak_60 = peak / 5;
+
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PEAK_H,
+                               ((peak_50 >> 4) & 0xf0) | (peak_60 >> 8));
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PEAK_50, peak_50);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PEAK_60, peak_60);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PEAK_DIFF, peak / 150);
+
+       /* Start resizing */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
+                               RESIZE_HOLD_SEL | RESIZE_GO | 1);
+
+       if (ret < 0)
+               return ret;
+
+       /* Constant taken from manufacturer's example */
+       msleep(230);
+
+       ret = reg_write(client, RJ54N1_RESIZE_CONTROL, RESIZE_HOLD_SEL | 1);
+       if (ret < 0)
+               return ret;
+
+       *in_w = (output_w * resize + 512) / 1024;
+       *in_h = (output_h * resize + 512) / 1024;
+       *out_w = output_w;
+       *out_h = output_h;
+
+       dev_dbg(&client->dev, "Scaled for %dx%d : %u = %ux%u, skip %u\n",
+               *in_w, *in_h, resize, output_w, output_h, skip);
+
+       return resize;
+}
+
+static int rj54n1_set_clock(struct i2c_client *client)
+{
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       int ret;
+
+       /* Enable external clock */
+       ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY);
+       /* Leave stand-by. Note: use this when implementing suspend / resume */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK);
+
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PLL_L, PLL_L);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PLL_N, PLL_N);
+
+       /* TGCLK dividers */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RATIO_TG,
+                               rj54n1->clk_div.ratio_tg);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RATIO_T,
+                               rj54n1->clk_div.ratio_t);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RATIO_R,
+                               rj54n1->clk_div.ratio_r);
+
+       /* Enable TGCLK & RAMP */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RAMP_TGCLK_EN, 3);
+
+       /* Disable clock output */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_OCLK_DSP, 0);
+
+       /* Set divisors */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RATIO_OP,
+                               rj54n1->clk_div.ratio_op);
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RATIO_O,
+                               rj54n1->clk_div.ratio_o);
+
+       /* Enable OCLK */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
+
+       /* Use PLL for Timing Generator, write 2 to reserved bits */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_TG_BYPASS, 2);
+
+       /* Take sensor out of reset */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESET_STANDBY,
+                               E_EXCLK | SEN_RSTX);
+       /* Enable PLL */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_PLL_EN, 1);
+
+       /* Wait for PLL to stabilise */
+       msleep(10);
+
+       /* Enable clock to frequency divider */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_CLK_RST, 1);
+
+       if (!ret)
+               ret = reg_read(client, RJ54N1_CLK_RST);
+       if (ret != 1) {
+               dev_err(&client->dev,
+                       "Resetting RJ54N1CB0C clock failed: %d!\n", ret);
+               return -EIO;
+       }
+
+       /* Start the PLL */
+       ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1);
+
+       /* Enable OCLK */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_OCLK_SEL_EN, 1);
+
+       return ret;
+}
+
+static int rj54n1_reg_init(struct i2c_client *client)
+{
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       int ret = rj54n1_set_clock(client);
+
+       if (!ret)
+               ret = reg_write_multiple(client, bank_7, ARRAY_SIZE(bank_7));
+       if (!ret)
+               ret = reg_write_multiple(client, bank_10, ARRAY_SIZE(bank_10));
+
+       /* Set binning divisors */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_SCALE_1_2_LEV, 3 | (7 << 4));
+       if (!ret)
+               ret = reg_write(client, RJ54N1_SCALE_4_LEV, 0xf);
+
+       /* Switch to fixed resize mode */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESIZE_CONTROL,
+                               RESIZE_HOLD_SEL | 1);
+
+       /* Set gain */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_Y_GAIN, 0x84);
+
+       /*
+        * Mirror the image back: default is upside down and left-to-right...
+        * Set manual preview / still shot switching
+        */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_MIRROR_STILL_MODE, 0x27);
+
+       if (!ret)
+               ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4));
+
+       /* Auto exposure area */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_EXPOSURE_CONTROL, 0x80);
+       /* Check current auto WB config */
+       if (!ret)
+               ret = reg_read(client, RJ54N1_WB_SEL_WEIGHT_I);
+       if (ret >= 0) {
+               rj54n1->auto_wb = ret & 0x80;
+               ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5));
+       }
+       if (!ret)
+               ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8));
+
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESET_STANDBY,
+                               E_EXCLK | DSP_RSTX | SEN_RSTX);
+
+       /* Commit init */
+       if (!ret)
+               ret = rj54n1_commit(client);
+
+       /* Take DSP, TG, sensor out of reset */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_RESET_STANDBY,
+                               E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX);
+
+       /* Start register update? Same register as 0x?FE in many bank_* sets */
+       if (!ret)
+               ret = reg_write(client, RJ54N1_FWFLG, 2);
+
+       /* Constant taken from manufacturer's example */
+       msleep(700);
+
+       return ret;
+}
+
+static int rj54n1_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       const struct rj54n1_datafmt *fmt;
+       int output_w, output_h, max_w, max_h,
+               input_w = rj54n1->rect.width, input_h = rj54n1->rect.height;
+       int align = mf->code == MEDIA_BUS_FMT_SBGGR10_1X10 ||
+               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE ||
+               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE ||
+               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE ||
+               mf->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE;
+       int ret;
+
+       if (format->pad)
+               return -EINVAL;
+
+       dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n",
+               __func__, mf->code, mf->width, mf->height);
+
+       fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
+                                 ARRAY_SIZE(rj54n1_colour_fmts));
+       if (!fmt) {
+               fmt = rj54n1->fmt;
+               mf->code = fmt->code;
+       }
+
+       mf->field       = V4L2_FIELD_NONE;
+       mf->colorspace  = fmt->colorspace;
+
+       v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align,
+                             &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0);
+
+       if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+               cfg->try_fmt = *mf;
+               return 0;
+       }
+
+       /*
+        * Verify if the sensor has just been powered on. TODO: replace this
+        * with proper PM, when a suitable API is available.
+        */
+       ret = reg_read(client, RJ54N1_RESET_STANDBY);
+       if (ret < 0)
+               return ret;
+
+       if (!(ret & E_EXCLK)) {
+               ret = rj54n1_reg_init(client);
+               if (ret < 0)
+                       return ret;
+       }
+
+       /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */
+       switch (mf->code) {
+       case MEDIA_BUS_FMT_YUYV8_2X8:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 0);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+               break;
+       case MEDIA_BUS_FMT_YVYU8_2X8:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 0);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+               break;
+       case MEDIA_BUS_FMT_RGB565_2X8_LE:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+               break;
+       case MEDIA_BUS_FMT_RGB565_2X8_BE:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 0x11);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+               break;
+       case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
+               break;
+       case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
+               break;
+       case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 0);
+               break;
+       case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 4);
+               if (!ret)
+                       ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8);
+               if (!ret)
+                       ret = reg_write(client, RJ54N1_RA_SEL_UL, 8);
+               break;
+       case MEDIA_BUS_FMT_SBGGR10_1X10:
+               ret = reg_write(client, RJ54N1_OUT_SEL, 5);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       /* Special case: a raw mode with 10 bits of data per clock tick */
+       if (!ret)
+               ret = reg_set(client, RJ54N1_OCLK_SEL_EN,
+                             (mf->code == MEDIA_BUS_FMT_SBGGR10_1X10) << 1, 2);
+
+       if (ret < 0)
+               return ret;
+
+       /* Supported scales 1:1 >= scale > 1:16 */
+       max_w = mf->width * (16 * 1024 - 1) / 1024;
+       if (input_w > max_w)
+               input_w = max_w;
+       max_h = mf->height * (16 * 1024 - 1) / 1024;
+       if (input_h > max_h)
+               input_h = max_h;
+
+       output_w = mf->width;
+       output_h = mf->height;
+
+       ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h);
+       if (ret < 0)
+               return ret;
+
+       fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts,
+                                 ARRAY_SIZE(rj54n1_colour_fmts));
+
+       rj54n1->fmt             = fmt;
+       rj54n1->resize          = ret;
+       rj54n1->rect.width      = input_w;
+       rj54n1->rect.height     = input_h;
+       rj54n1->width           = output_w;
+       rj54n1->height          = output_h;
+
+       mf->width               = output_w;
+       mf->height              = output_h;
+       mf->field               = V4L2_FIELD_NONE;
+       mf->colorspace          = fmt->colorspace;
+
+       return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int rj54n1_g_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg < 0x400 || reg->reg > 0x1fff)
+               /* Registers > 0x0800 are only available from Sharp support */
+               return -EINVAL;
+
+       reg->size = 1;
+       reg->val = reg_read(client, reg->reg);
+
+       if (reg->val > 0xff)
+               return -EIO;
+
+       return 0;
+}
+
+static int rj54n1_s_register(struct v4l2_subdev *sd,
+                            const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg < 0x400 || reg->reg > 0x1fff)
+               /* Registers >= 0x0800 are only available from Sharp support */
+               return -EINVAL;
+
+       if (reg_write(client, reg->reg, reg->val) < 0)
+               return -EIO;
+
+       return 0;
+}
+#endif
+
+static int rj54n1_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+
+       return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on);
+}
+
+static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
+       struct v4l2_subdev *sd = &rj54n1->subdev;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int data;
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               if (ctrl->val)
+                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
+               else
+                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
+               if (data < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_HFLIP:
+               if (ctrl->val)
+                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
+               else
+                       data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
+               if (data < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_GAIN:
+               if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_AUTO_WHITE_BALANCE:
+               /* Auto WB area - whole image */
+               if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7,
+                           0x80) < 0)
+                       return -EIO;
+               rj54n1->auto_wb = ctrl->val;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
+       .s_ctrl = rj54n1_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = rj54n1_g_register,
+       .s_register     = rj54n1_s_register,
+#endif
+       .s_power        = rj54n1_s_power,
+};
+
+static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags =
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
+       if (soc_camera_apply_board_flags(ssdd, cfg) &
+           V4L2_MBUS_PCLK_SAMPLE_RISING)
+               return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
+       else
+               return reg_write(client, RJ54N1_OUT_SIGPO, 0);
+}
+
+static const struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
+       .s_stream       = rj54n1_s_stream,
+       .g_mbus_config  = rj54n1_g_mbus_config,
+       .s_mbus_config  = rj54n1_s_mbus_config,
+};
+
+static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = {
+       .enum_mbus_code = rj54n1_enum_mbus_code,
+       .get_selection  = rj54n1_get_selection,
+       .set_selection  = rj54n1_set_selection,
+       .get_fmt        = rj54n1_get_fmt,
+       .set_fmt        = rj54n1_set_fmt,
+};
+
+static const struct v4l2_subdev_ops rj54n1_subdev_ops = {
+       .core   = &rj54n1_subdev_core_ops,
+       .video  = &rj54n1_subdev_video_ops,
+       .pad    = &rj54n1_subdev_pad_ops,
+};
+
+/*
+ * Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one
+ */
+static int rj54n1_video_probe(struct i2c_client *client,
+                             struct rj54n1_pdata *priv)
+{
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       int data1, data2;
+       int ret;
+
+       ret = rj54n1_s_power(&rj54n1->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Read out the chip version register */
+       data1 = reg_read(client, RJ54N1_DEV_CODE);
+       data2 = reg_read(client, RJ54N1_DEV_CODE2);
+
+       if (data1 != 0x51 || data2 != 0x10) {
+               ret = -ENODEV;
+               dev_info(&client->dev, "No RJ54N1CB0C found, read 0x%x:0x%x\n",
+                        data1, data2);
+               goto done;
+       }
+
+       /* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */
+       ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7);
+       if (ret < 0)
+               goto done;
+
+       dev_info(&client->dev, "Detected a RJ54N1CB0C chip ID 0x%x:0x%x\n",
+                data1, data2);
+
+       ret = v4l2_ctrl_handler_setup(&rj54n1->hdl);
+
+done:
+       rj54n1_s_power(&rj54n1->subdev, 0);
+       return ret;
+}
+
+static int rj54n1_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct rj54n1 *rj54n1;
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct rj54n1_pdata *rj54n1_priv;
+       int ret;
+
+       if (!ssdd || !ssdd->drv_priv) {
+               dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
+               return -EINVAL;
+       }
+
+       rj54n1_priv = ssdd->drv_priv;
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+               dev_warn(&adapter->dev,
+                        "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
+               return -EIO;
+       }
+
+       rj54n1 = devm_kzalloc(&client->dev, sizeof(struct rj54n1), GFP_KERNEL);
+       if (!rj54n1)
+               return -ENOMEM;
+
+       v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
+       v4l2_ctrl_handler_init(&rj54n1->hdl, 4);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 66);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+       rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
+       if (rj54n1->hdl.error)
+               return rj54n1->hdl.error;
+
+       rj54n1->clk_div         = clk_div;
+       rj54n1->rect.left       = RJ54N1_COLUMN_SKIP;
+       rj54n1->rect.top        = RJ54N1_ROW_SKIP;
+       rj54n1->rect.width      = RJ54N1_MAX_WIDTH;
+       rj54n1->rect.height     = RJ54N1_MAX_HEIGHT;
+       rj54n1->width           = RJ54N1_MAX_WIDTH;
+       rj54n1->height          = RJ54N1_MAX_HEIGHT;
+       rj54n1->fmt             = &rj54n1_colour_fmts[0];
+       rj54n1->resize          = 1024;
+       rj54n1->tgclk_mhz       = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
+               (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
+
+       rj54n1->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(rj54n1->clk)) {
+               ret = PTR_ERR(rj54n1->clk);
+               goto eclkget;
+       }
+
+       ret = rj54n1_video_probe(client, rj54n1_priv);
+       if (ret < 0) {
+               v4l2_clk_put(rj54n1->clk);
+eclkget:
+               v4l2_ctrl_handler_free(&rj54n1->hdl);
+       }
+
+       return ret;
+}
+
+static int rj54n1_remove(struct i2c_client *client)
+{
+       struct rj54n1 *rj54n1 = to_rj54n1(client);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       v4l2_clk_put(rj54n1->clk);
+       v4l2_device_unregister_subdev(&rj54n1->subdev);
+       if (ssdd->free_bus)
+               ssdd->free_bus(ssdd);
+       v4l2_ctrl_handler_free(&rj54n1->hdl);
+
+       return 0;
+}
+
+static const struct i2c_device_id rj54n1_id[] = {
+       { "rj54n1cb0c", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, rj54n1_id);
+
+static struct i2c_driver rj54n1_i2c_driver = {
+       .driver = {
+               .name = "rj54n1cb0c",
+       },
+       .probe          = rj54n1_probe,
+       .remove         = rj54n1_remove,
+       .id_table       = rj54n1_id,
+};
+
+module_i2c_driver(rj54n1_i2c_driver);
+
+MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/soc_tw9910.c b/drivers/media/i2c/soc_camera/soc_tw9910.c
new file mode 100644 (file)
index 0000000..bdb5e0a
--- /dev/null
@@ -0,0 +1,999 @@
+/*
+ * tw9910 Video Driver
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov772x driver,
+ *
+ * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+
+#include <media/soc_camera.h>
+#include <media/i2c/tw9910.h>
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+
+#define GET_ID(val)  ((val & 0xF8) >> 3)
+#define GET_REV(val) (val & 0x07)
+
+/*
+ * register offset
+ */
+#define ID             0x00 /* Product ID Code Register */
+#define STATUS1                0x01 /* Chip Status Register I */
+#define INFORM         0x02 /* Input Format */
+#define OPFORM         0x03 /* Output Format Control Register */
+#define DLYCTR         0x04 /* Hysteresis and HSYNC Delay Control */
+#define OUTCTR1                0x05 /* Output Control I */
+#define ACNTL1         0x06 /* Analog Control Register 1 */
+#define CROP_HI                0x07 /* Cropping Register, High */
+#define VDELAY_LO      0x08 /* Vertical Delay Register, Low */
+#define VACTIVE_LO     0x09 /* Vertical Active Register, Low */
+#define HDELAY_LO      0x0A /* Horizontal Delay Register, Low */
+#define HACTIVE_LO     0x0B /* Horizontal Active Register, Low */
+#define CNTRL1         0x0C /* Control Register I */
+#define VSCALE_LO      0x0D /* Vertical Scaling Register, Low */
+#define SCALE_HI       0x0E /* Scaling Register, High */
+#define HSCALE_LO      0x0F /* Horizontal Scaling Register, Low */
+#define BRIGHT         0x10 /* BRIGHTNESS Control Register */
+#define CONTRAST       0x11 /* CONTRAST Control Register */
+#define SHARPNESS      0x12 /* SHARPNESS Control Register I */
+#define SAT_U          0x13 /* Chroma (U) Gain Register */
+#define SAT_V          0x14 /* Chroma (V) Gain Register */
+#define HUE            0x15 /* Hue Control Register */
+#define CORING1                0x17
+#define CORING2                0x18 /* Coring and IF compensation */
+#define VBICNTL                0x19 /* VBI Control Register */
+#define ACNTL2         0x1A /* Analog Control 2 */
+#define OUTCTR2                0x1B /* Output Control 2 */
+#define SDT            0x1C /* Standard Selection */
+#define SDTR           0x1D /* Standard Recognition */
+#define TEST           0x1F /* Test Control Register */
+#define CLMPG          0x20 /* Clamping Gain */
+#define IAGC           0x21 /* Individual AGC Gain */
+#define AGCGAIN                0x22 /* AGC Gain */
+#define PEAKWT         0x23 /* White Peak Threshold */
+#define CLMPL          0x24 /* Clamp level */
+#define SYNCT          0x25 /* Sync Amplitude */
+#define MISSCNT                0x26 /* Sync Miss Count Register */
+#define PCLAMP         0x27 /* Clamp Position Register */
+#define VCNTL1         0x28 /* Vertical Control I */
+#define VCNTL2         0x29 /* Vertical Control II */
+#define CKILL          0x2A /* Color Killer Level Control */
+#define COMB           0x2B /* Comb Filter Control */
+#define LDLY           0x2C /* Luma Delay and H Filter Control */
+#define MISC1          0x2D /* Miscellaneous Control I */
+#define LOOP           0x2E /* LOOP Control Register */
+#define MISC2          0x2F /* Miscellaneous Control II */
+#define MVSN           0x30 /* Macrovision Detection */
+#define STATUS2                0x31 /* Chip STATUS II */
+#define HFREF          0x32 /* H monitor */
+#define CLMD           0x33 /* CLAMP MODE */
+#define IDCNTL         0x34 /* ID Detection Control */
+#define CLCNTL1                0x35 /* Clamp Control I */
+#define ANAPLLCTL      0x4C
+#define VBIMIN         0x4D
+#define HSLOWCTL       0x4E
+#define WSS3           0x4F
+#define FILLDATA       0x50
+#define SDID           0x51
+#define DID            0x52
+#define WSS1           0x53
+#define WSS2           0x54
+#define VVBI           0x55
+#define LCTL6          0x56
+#define LCTL7          0x57
+#define LCTL8          0x58
+#define LCTL9          0x59
+#define LCTL10         0x5A
+#define LCTL11         0x5B
+#define LCTL12         0x5C
+#define LCTL13         0x5D
+#define LCTL14         0x5E
+#define LCTL15         0x5F
+#define LCTL16         0x60
+#define LCTL17         0x61
+#define LCTL18         0x62
+#define LCTL19         0x63
+#define LCTL20         0x64
+#define LCTL21         0x65
+#define LCTL22         0x66
+#define LCTL23         0x67
+#define LCTL24         0x68
+#define LCTL25         0x69
+#define LCTL26         0x6A
+#define HSBEGIN                0x6B
+#define HSEND          0x6C
+#define OVSDLY         0x6D
+#define OVSEND         0x6E
+#define VBIDELAY       0x6F
+
+/*
+ * register detail
+ */
+
+/* INFORM */
+#define FC27_ON     0x40 /* 1 : Input crystal clock frequency is 27MHz */
+#define FC27_FF     0x00 /* 0 : Square pixel mode. */
+                        /*     Must use 24.54MHz for 60Hz field rate */
+                        /*     source or 29.5MHz for 50Hz field rate */
+#define IFSEL_S     0x10 /* 01 : S-video decoding */
+#define IFSEL_C     0x00 /* 00 : Composite video decoding */
+                        /* Y input video selection */
+#define YSEL_M0     0x00 /*  00 : Mux0 selected */
+#define YSEL_M1     0x04 /*  01 : Mux1 selected */
+#define YSEL_M2     0x08 /*  10 : Mux2 selected */
+#define YSEL_M3     0x10 /*  11 : Mux3 selected */
+
+/* OPFORM */
+#define MODE        0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
+                        /* 1 : ITU-R-656 compatible data sequence format */
+#define LEN         0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
+                        /* 1 : 16-bit YCrCb 4:2:2 output format.*/
+#define LLCMODE     0x20 /* 1 : LLC output mode. */
+                        /* 0 : free-run output mode */
+#define AINC        0x10 /* Serial interface auto-indexing control */
+                        /* 0 : auto-increment */
+                        /* 1 : non-auto */
+#define VSCTL       0x08 /* 1 : Vertical out ctrl by DVALID */
+                        /* 0 : Vertical out ctrl by HACTIVE and DVALID */
+#define OEN_TRI_SEL_MASK       0x07
+#define OEN_TRI_SEL_ALL_ON     0x00 /* Enable output for Rev0/Rev1 */
+#define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */
+#define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */
+
+/* OUTCTR1 */
+#define VSP_LO      0x00 /* 0 : VS pin output polarity is active low */
+#define VSP_HI      0x80 /* 1 : VS pin output polarity is active high. */
+                        /* VS pin output control */
+#define VSSL_VSYNC  0x00 /*   0 : VSYNC  */
+#define VSSL_VACT   0x10 /*   1 : VACT   */
+#define VSSL_FIELD  0x20 /*   2 : FIELD  */
+#define VSSL_VVALID 0x30 /*   3 : VVALID */
+#define VSSL_ZERO   0x70 /*   7 : 0      */
+#define HSP_LOW     0x00 /* 0 : HS pin output polarity is active low */
+#define HSP_HI      0x08 /* 1 : HS pin output polarity is active high.*/
+                        /* HS pin output control */
+#define HSSL_HACT   0x00 /*   0 : HACT   */
+#define HSSL_HSYNC  0x01 /*   1 : HSYNC  */
+#define HSSL_DVALID 0x02 /*   2 : DVALID */
+#define HSSL_HLOCK  0x03 /*   3 : HLOCK  */
+#define HSSL_ASYNCW 0x04 /*   4 : ASYNCW */
+#define HSSL_ZERO   0x07 /*   7 : 0      */
+
+/* ACNTL1 */
+#define SRESET      0x80 /* resets the device to its default state
+                         * but all register content remain unchanged.
+                         * This bit is self-resetting.
+                         */
+#define ACNTL1_PDN_MASK        0x0e
+#define CLK_PDN                0x08 /* system clock power down */
+#define Y_PDN          0x04 /* Luma ADC power down */
+#define C_PDN          0x02 /* Chroma ADC power down */
+
+/* ACNTL2 */
+#define ACNTL2_PDN_MASK        0x40
+#define PLL_PDN                0x40 /* PLL power down */
+
+/* VBICNTL */
+
+/* RTSEL : control the real time signal output from the MPOUT pin */
+#define RTSEL_MASK  0x07
+#define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
+#define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
+#define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
+#define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
+#define RTSEL_MONO  0x04 /* 0100 = MONO */
+#define RTSEL_DET50 0x05 /* 0101 = DET50 */
+#define RTSEL_FIELD 0x06 /* 0110 = FIELD */
+#define RTSEL_RTCO  0x07 /* 0111 = RTCO ( Real Time Control ) */
+
+/* HSYNC start and end are constant for now */
+#define HSYNC_START    0x0260
+#define HSYNC_END      0x0300
+
+/*
+ * structure
+ */
+
+struct regval_list {
+       unsigned char reg_num;
+       unsigned char value;
+};
+
+struct tw9910_scale_ctrl {
+       char           *name;
+       unsigned short  width;
+       unsigned short  height;
+       u16             hscale;
+       u16             vscale;
+};
+
+struct tw9910_priv {
+       struct v4l2_subdev              subdev;
+       struct v4l2_clk                 *clk;
+       struct tw9910_video_info        *info;
+       const struct tw9910_scale_ctrl  *scale;
+       v4l2_std_id                     norm;
+       u32                             revision;
+};
+
+static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
+       {
+               .name   = "NTSC SQ",
+               .width  = 640,
+               .height = 480,
+               .hscale = 0x0100,
+               .vscale = 0x0100,
+       },
+       {
+               .name   = "NTSC CCIR601",
+               .width  = 720,
+               .height = 480,
+               .hscale = 0x0100,
+               .vscale = 0x0100,
+       },
+       {
+               .name   = "NTSC SQ (CIF)",
+               .width  = 320,
+               .height = 240,
+               .hscale = 0x0200,
+               .vscale = 0x0200,
+       },
+       {
+               .name   = "NTSC CCIR601 (CIF)",
+               .width  = 360,
+               .height = 240,
+               .hscale = 0x0200,
+               .vscale = 0x0200,
+       },
+       {
+               .name   = "NTSC SQ (QCIF)",
+               .width  = 160,
+               .height = 120,
+               .hscale = 0x0400,
+               .vscale = 0x0400,
+       },
+       {
+               .name   = "NTSC CCIR601 (QCIF)",
+               .width  = 180,
+               .height = 120,
+               .hscale = 0x0400,
+               .vscale = 0x0400,
+       },
+};
+
+static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
+       {
+               .name   = "PAL SQ",
+               .width  = 768,
+               .height = 576,
+               .hscale = 0x0100,
+               .vscale = 0x0100,
+       },
+       {
+               .name   = "PAL CCIR601",
+               .width  = 720,
+               .height = 576,
+               .hscale = 0x0100,
+               .vscale = 0x0100,
+       },
+       {
+               .name   = "PAL SQ (CIF)",
+               .width  = 384,
+               .height = 288,
+               .hscale = 0x0200,
+               .vscale = 0x0200,
+       },
+       {
+               .name   = "PAL CCIR601 (CIF)",
+               .width  = 360,
+               .height = 288,
+               .hscale = 0x0200,
+               .vscale = 0x0200,
+       },
+       {
+               .name   = "PAL SQ (QCIF)",
+               .width  = 192,
+               .height = 144,
+               .hscale = 0x0400,
+               .vscale = 0x0400,
+       },
+       {
+               .name   = "PAL CCIR601 (QCIF)",
+               .width  = 180,
+               .height = 144,
+               .hscale = 0x0400,
+               .vscale = 0x0400,
+       },
+};
+
+/*
+ * general function
+ */
+static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client), struct tw9910_priv,
+                           subdev);
+}
+
+static int tw9910_mask_set(struct i2c_client *client, u8 command,
+                          u8 mask, u8 set)
+{
+       s32 val = i2c_smbus_read_byte_data(client, command);
+       if (val < 0)
+               return val;
+
+       val &= ~mask;
+       val |= set & mask;
+
+       return i2c_smbus_write_byte_data(client, command, val);
+}
+
+static int tw9910_set_scale(struct i2c_client *client,
+                           const struct tw9910_scale_ctrl *scale)
+{
+       int ret;
+
+       ret = i2c_smbus_write_byte_data(client, SCALE_HI,
+                                       (scale->vscale & 0x0F00) >> 4 |
+                                       (scale->hscale & 0x0F00) >> 8);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
+                                       scale->hscale & 0x00FF);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
+                                       scale->vscale & 0x00FF);
+
+       return ret;
+}
+
+static int tw9910_set_hsync(struct i2c_client *client)
+{
+       struct tw9910_priv *priv = to_tw9910(client);
+       int ret;
+
+       /* bit 10 - 3 */
+       ret = i2c_smbus_write_byte_data(client, HSBEGIN,
+                                       (HSYNC_START & 0x07F8) >> 3);
+       if (ret < 0)
+               return ret;
+
+       /* bit 10 - 3 */
+       ret = i2c_smbus_write_byte_data(client, HSEND,
+                                       (HSYNC_END & 0x07F8) >> 3);
+       if (ret < 0)
+               return ret;
+
+       /* So far only revisions 0 and 1 have been seen */
+       /* bit 2 - 0 */
+       if (1 == priv->revision)
+               ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
+                                     (HSYNC_START & 0x0007) << 4 |
+                                     (HSYNC_END   & 0x0007));
+
+       return ret;
+}
+
+static void tw9910_reset(struct i2c_client *client)
+{
+       tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
+       msleep(1);
+}
+
+static int tw9910_power(struct i2c_client *client, int enable)
+{
+       int ret;
+       u8 acntl1;
+       u8 acntl2;
+
+       if (enable) {
+               acntl1 = 0;
+               acntl2 = 0;
+       } else {
+               acntl1 = CLK_PDN | Y_PDN | C_PDN;
+               acntl2 = PLL_PDN;
+       }
+
+       ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
+       if (ret < 0)
+               return ret;
+
+       return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
+}
+
+static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
+                                                         u32 width, u32 height)
+{
+       const struct tw9910_scale_ctrl *scale;
+       const struct tw9910_scale_ctrl *ret = NULL;
+       __u32 diff = 0xffffffff, tmp;
+       int size, i;
+
+       if (norm & V4L2_STD_NTSC) {
+               scale = tw9910_ntsc_scales;
+               size = ARRAY_SIZE(tw9910_ntsc_scales);
+       } else if (norm & V4L2_STD_PAL) {
+               scale = tw9910_pal_scales;
+               size = ARRAY_SIZE(tw9910_pal_scales);
+       } else {
+               return NULL;
+       }
+
+       for (i = 0; i < size; i++) {
+               tmp = abs(width - scale[i].width) +
+                       abs(height - scale[i].height);
+               if (tmp < diff) {
+                       diff = tmp;
+                       ret = scale + i;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * subdevice operations
+ */
+static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+       u8 val;
+       int ret;
+
+       if (!enable) {
+               switch (priv->revision) {
+               case 0:
+                       val = OEN_TRI_SEL_ALL_OFF_r0;
+                       break;
+               case 1:
+                       val = OEN_TRI_SEL_ALL_OFF_r1;
+                       break;
+               default:
+                       dev_err(&client->dev, "un-supported revision\n");
+                       return -EINVAL;
+               }
+       } else {
+               val = OEN_TRI_SEL_ALL_ON;
+
+               if (!priv->scale) {
+                       dev_err(&client->dev, "norm select error\n");
+                       return -EPERM;
+               }
+
+               dev_dbg(&client->dev, "%s %dx%d\n",
+                       priv->scale->name,
+                       priv->scale->width,
+                       priv->scale->height);
+       }
+
+       ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
+       if (ret < 0)
+               return ret;
+
+       return tw9910_power(client, enable);
+}
+
+static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+
+       *norm = priv->norm;
+
+       return 0;
+}
+
+static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+       const unsigned hact = 720;
+       const unsigned hdelay = 15;
+       unsigned vact;
+       unsigned vdelay;
+       int ret;
+
+       if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
+               return -EINVAL;
+
+       priv->norm = norm;
+       if (norm & V4L2_STD_525_60) {
+               vact = 240;
+               vdelay = 18;
+               ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
+       } else {
+               vact = 288;
+               vdelay = 24;
+               ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
+       }
+       if (!ret)
+               ret = i2c_smbus_write_byte_data(client, CROP_HI,
+                       ((vdelay >> 2) & 0xc0) |
+                       ((vact >> 4) & 0x30) |
+                       ((hdelay >> 6) & 0x0c) |
+                       ((hact >> 8) & 0x03));
+       if (!ret)
+               ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
+                       vdelay & 0xff);
+       if (!ret)
+               ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
+                       vact & 0xff);
+
+       return ret;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int tw9910_g_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       reg->size = 1;
+       ret = i2c_smbus_read_byte_data(client, reg->reg);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * ret      = int
+        * reg->val = __u64
+        */
+       reg->val = (__u64)ret;
+
+       return 0;
+}
+
+static int tw9910_s_register(struct v4l2_subdev *sd,
+                            const struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff ||
+           reg->val > 0xff)
+               return -EINVAL;
+
+       return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
+}
+#endif
+
+static int tw9910_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       struct tw9910_priv *priv = to_tw9910(client);
+
+       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
+}
+
+static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+       int ret = -EINVAL;
+       u8 val;
+
+       /*
+        * select suitable norm
+        */
+       priv->scale = tw9910_select_norm(priv->norm, *width, *height);
+       if (!priv->scale)
+               goto tw9910_set_fmt_error;
+
+       /*
+        * reset hardware
+        */
+       tw9910_reset(client);
+
+       /*
+        * set bus width
+        */
+       val = 0x00;
+       if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
+               val = LEN;
+
+       ret = tw9910_mask_set(client, OPFORM, LEN, val);
+       if (ret < 0)
+               goto tw9910_set_fmt_error;
+
+       /*
+        * select MPOUT behavior
+        */
+       switch (priv->info->mpout) {
+       case TW9910_MPO_VLOSS:
+               val = RTSEL_VLOSS; break;
+       case TW9910_MPO_HLOCK:
+               val = RTSEL_HLOCK; break;
+       case TW9910_MPO_SLOCK:
+               val = RTSEL_SLOCK; break;
+       case TW9910_MPO_VLOCK:
+               val = RTSEL_VLOCK; break;
+       case TW9910_MPO_MONO:
+               val = RTSEL_MONO;  break;
+       case TW9910_MPO_DET50:
+               val = RTSEL_DET50; break;
+       case TW9910_MPO_FIELD:
+               val = RTSEL_FIELD; break;
+       case TW9910_MPO_RTCO:
+               val = RTSEL_RTCO;  break;
+       default:
+               val = 0;
+       }
+
+       ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
+       if (ret < 0)
+               goto tw9910_set_fmt_error;
+
+       /*
+        * set scale
+        */
+       ret = tw9910_set_scale(client, priv->scale);
+       if (ret < 0)
+               goto tw9910_set_fmt_error;
+
+       /*
+        * set hsync
+        */
+       ret = tw9910_set_hsync(client);
+       if (ret < 0)
+               goto tw9910_set_fmt_error;
+
+       *width = priv->scale->width;
+       *height = priv->scale->height;
+
+       return ret;
+
+tw9910_set_fmt_error:
+
+       tw9910_reset(client);
+       priv->scale = NULL;
+
+       return ret;
+}
+
+static int tw9910_get_selection(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_selection *sel)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+       /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported */
+       if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS)
+               return -EINVAL;
+
+       sel->r.left     = 0;
+       sel->r.top      = 0;
+       if (priv->norm & V4L2_STD_NTSC) {
+               sel->r.width    = 640;
+               sel->r.height   = 480;
+       } else {
+               sel->r.width    = 768;
+               sel->r.height   = 576;
+       }
+       return 0;
+}
+
+static int tw9910_get_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+
+       if (format->pad)
+               return -EINVAL;
+
+       if (!priv->scale) {
+               priv->scale = tw9910_select_norm(priv->norm, 640, 480);
+               if (!priv->scale)
+                       return -EINVAL;
+       }
+
+       mf->width       = priv->scale->width;
+       mf->height      = priv->scale->height;
+       mf->code        = MEDIA_BUS_FMT_UYVY8_2X8;
+       mf->colorspace  = V4L2_COLORSPACE_SMPTE170M;
+       mf->field       = V4L2_FIELD_INTERLACED_BT;
+
+       return 0;
+}
+
+static int tw9910_s_fmt(struct v4l2_subdev *sd,
+                       struct v4l2_mbus_framefmt *mf)
+{
+       u32 width = mf->width, height = mf->height;
+       int ret;
+
+       WARN_ON(mf->field != V4L2_FIELD_ANY &&
+               mf->field != V4L2_FIELD_INTERLACED_BT);
+
+       /*
+        * check color format
+        */
+       if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
+               return -EINVAL;
+
+       mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+       ret = tw9910_set_frame(sd, &width, &height);
+       if (!ret) {
+               mf->width       = width;
+               mf->height      = height;
+       }
+       return ret;
+}
+
+static int tw9910_set_fmt(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_format *format)
+{
+       struct v4l2_mbus_framefmt *mf = &format->format;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+       const struct tw9910_scale_ctrl *scale;
+
+       if (format->pad)
+               return -EINVAL;
+
+       if (V4L2_FIELD_ANY == mf->field) {
+               mf->field = V4L2_FIELD_INTERLACED_BT;
+       } else if (V4L2_FIELD_INTERLACED_BT != mf->field) {
+               dev_err(&client->dev, "Field type %d invalid.\n", mf->field);
+               return -EINVAL;
+       }
+
+       mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+       /*
+        * select suitable norm
+        */
+       scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
+       if (!scale)
+               return -EINVAL;
+
+       mf->width       = scale->width;
+       mf->height      = scale->height;
+
+       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return tw9910_s_fmt(sd, mf);
+       cfg->try_fmt = *mf;
+       return 0;
+}
+
+static int tw9910_video_probe(struct i2c_client *client)
+{
+       struct tw9910_priv *priv = to_tw9910(client);
+       s32 id;
+       int ret;
+
+       /*
+        * tw9910 only use 8 or 16 bit bus width
+        */
+       if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
+           SOCAM_DATAWIDTH_8  != priv->info->buswidth) {
+               dev_err(&client->dev, "bus width error\n");
+               return -ENODEV;
+       }
+
+       ret = tw9910_s_power(&priv->subdev, 1);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * check and show Product ID
+        * So far only revisions 0 and 1 have been seen
+        */
+       id = i2c_smbus_read_byte_data(client, ID);
+       priv->revision = GET_REV(id);
+       id = GET_ID(id);
+
+       if (0x0B != id ||
+           0x01 < priv->revision) {
+               dev_err(&client->dev,
+                       "Product ID error %x:%x\n",
+                       id, priv->revision);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       dev_info(&client->dev,
+                "tw9910 Product ID %0x:%0x\n", id, priv->revision);
+
+       priv->norm = V4L2_STD_NTSC;
+       priv->scale = &tw9910_ntsc_scales[0];
+
+done:
+       tw9910_s_power(&priv->subdev, 0);
+       return ret;
+}
+
+static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = tw9910_g_register,
+       .s_register     = tw9910_s_register,
+#endif
+       .s_power        = tw9910_s_power,
+};
+
+static int tw9910_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index)
+               return -EINVAL;
+
+       code->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       return 0;
+}
+
+static int tw9910_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       return 0;
+}
+
+static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+       u8 val = VSSL_VVALID | HSSL_DVALID;
+       unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg);
+
+       /*
+        * set OUTCTR1
+        *
+        * We use VVALID and DVALID signals to control VSYNC and HSYNC
+        * outputs, in this mode their polarity is inverted.
+        */
+       if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+               val |= HSP_HI;
+
+       if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+               val |= VSP_HI;
+
+       return i2c_smbus_write_byte_data(client, OUTCTR1, val);
+}
+
+static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
+{
+       *norm = V4L2_STD_NTSC | V4L2_STD_PAL;
+       return 0;
+}
+
+static const struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
+       .s_std          = tw9910_s_std,
+       .g_std          = tw9910_g_std,
+       .s_stream       = tw9910_s_stream,
+       .g_mbus_config  = tw9910_g_mbus_config,
+       .s_mbus_config  = tw9910_s_mbus_config,
+       .g_tvnorms      = tw9910_g_tvnorms,
+};
+
+static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
+       .enum_mbus_code = tw9910_enum_mbus_code,
+       .get_selection  = tw9910_get_selection,
+       .get_fmt        = tw9910_get_fmt,
+       .set_fmt        = tw9910_set_fmt,
+};
+
+static const struct v4l2_subdev_ops tw9910_subdev_ops = {
+       .core   = &tw9910_subdev_core_ops,
+       .video  = &tw9910_subdev_video_ops,
+       .pad    = &tw9910_subdev_pad_ops,
+};
+
+/*
+ * i2c_driver function
+ */
+
+static int tw9910_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+
+{
+       struct tw9910_priv              *priv;
+       struct tw9910_video_info        *info;
+       struct i2c_adapter              *adapter =
+               to_i2c_adapter(client->dev.parent);
+       struct soc_camera_subdev_desc   *ssdd = soc_camera_i2c_to_desc(client);
+       int ret;
+
+       if (!ssdd || !ssdd->drv_priv) {
+               dev_err(&client->dev, "TW9910: missing platform data!\n");
+               return -EINVAL;
+       }
+
+       info = ssdd->drv_priv;
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+               dev_err(&client->dev,
+                       "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n");
+               return -EIO;
+       }
+
+       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->info   = info;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
+
+       priv->clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(priv->clk))
+               return PTR_ERR(priv->clk);
+
+       ret = tw9910_video_probe(client);
+       if (ret < 0)
+               v4l2_clk_put(priv->clk);
+
+       return ret;
+}
+
+static int tw9910_remove(struct i2c_client *client)
+{
+       struct tw9910_priv *priv = to_tw9910(client);
+       v4l2_clk_put(priv->clk);
+       return 0;
+}
+
+static const struct i2c_device_id tw9910_id[] = {
+       { "tw9910", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tw9910_id);
+
+static struct i2c_driver tw9910_i2c_driver = {
+       .driver = {
+               .name = "tw9910",
+       },
+       .probe    = tw9910_probe,
+       .remove   = tw9910_remove,
+       .id_table = tw9910_id,
+};
+
+module_i2c_driver(tw9910_i2c_driver);
+
+MODULE_DESCRIPTION("SoC Camera driver for tw9910");
+MODULE_AUTHOR("Kuninori Morimoto");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
deleted file mode 100644 (file)
index bdb5e0a..0000000
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * tw9910 Video Driver
- *
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov772x driver,
- *
- * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/i2c/tw9910.h>
-#include <media/v4l2-clk.h>
-#include <media/v4l2-subdev.h>
-
-#define GET_ID(val)  ((val & 0xF8) >> 3)
-#define GET_REV(val) (val & 0x07)
-
-/*
- * register offset
- */
-#define ID             0x00 /* Product ID Code Register */
-#define STATUS1                0x01 /* Chip Status Register I */
-#define INFORM         0x02 /* Input Format */
-#define OPFORM         0x03 /* Output Format Control Register */
-#define DLYCTR         0x04 /* Hysteresis and HSYNC Delay Control */
-#define OUTCTR1                0x05 /* Output Control I */
-#define ACNTL1         0x06 /* Analog Control Register 1 */
-#define CROP_HI                0x07 /* Cropping Register, High */
-#define VDELAY_LO      0x08 /* Vertical Delay Register, Low */
-#define VACTIVE_LO     0x09 /* Vertical Active Register, Low */
-#define HDELAY_LO      0x0A /* Horizontal Delay Register, Low */
-#define HACTIVE_LO     0x0B /* Horizontal Active Register, Low */
-#define CNTRL1         0x0C /* Control Register I */
-#define VSCALE_LO      0x0D /* Vertical Scaling Register, Low */
-#define SCALE_HI       0x0E /* Scaling Register, High */
-#define HSCALE_LO      0x0F /* Horizontal Scaling Register, Low */
-#define BRIGHT         0x10 /* BRIGHTNESS Control Register */
-#define CONTRAST       0x11 /* CONTRAST Control Register */
-#define SHARPNESS      0x12 /* SHARPNESS Control Register I */
-#define SAT_U          0x13 /* Chroma (U) Gain Register */
-#define SAT_V          0x14 /* Chroma (V) Gain Register */
-#define HUE            0x15 /* Hue Control Register */
-#define CORING1                0x17
-#define CORING2                0x18 /* Coring and IF compensation */
-#define VBICNTL                0x19 /* VBI Control Register */
-#define ACNTL2         0x1A /* Analog Control 2 */
-#define OUTCTR2                0x1B /* Output Control 2 */
-#define SDT            0x1C /* Standard Selection */
-#define SDTR           0x1D /* Standard Recognition */
-#define TEST           0x1F /* Test Control Register */
-#define CLMPG          0x20 /* Clamping Gain */
-#define IAGC           0x21 /* Individual AGC Gain */
-#define AGCGAIN                0x22 /* AGC Gain */
-#define PEAKWT         0x23 /* White Peak Threshold */
-#define CLMPL          0x24 /* Clamp level */
-#define SYNCT          0x25 /* Sync Amplitude */
-#define MISSCNT                0x26 /* Sync Miss Count Register */
-#define PCLAMP         0x27 /* Clamp Position Register */
-#define VCNTL1         0x28 /* Vertical Control I */
-#define VCNTL2         0x29 /* Vertical Control II */
-#define CKILL          0x2A /* Color Killer Level Control */
-#define COMB           0x2B /* Comb Filter Control */
-#define LDLY           0x2C /* Luma Delay and H Filter Control */
-#define MISC1          0x2D /* Miscellaneous Control I */
-#define LOOP           0x2E /* LOOP Control Register */
-#define MISC2          0x2F /* Miscellaneous Control II */
-#define MVSN           0x30 /* Macrovision Detection */
-#define STATUS2                0x31 /* Chip STATUS II */
-#define HFREF          0x32 /* H monitor */
-#define CLMD           0x33 /* CLAMP MODE */
-#define IDCNTL         0x34 /* ID Detection Control */
-#define CLCNTL1                0x35 /* Clamp Control I */
-#define ANAPLLCTL      0x4C
-#define VBIMIN         0x4D
-#define HSLOWCTL       0x4E
-#define WSS3           0x4F
-#define FILLDATA       0x50
-#define SDID           0x51
-#define DID            0x52
-#define WSS1           0x53
-#define WSS2           0x54
-#define VVBI           0x55
-#define LCTL6          0x56
-#define LCTL7          0x57
-#define LCTL8          0x58
-#define LCTL9          0x59
-#define LCTL10         0x5A
-#define LCTL11         0x5B
-#define LCTL12         0x5C
-#define LCTL13         0x5D
-#define LCTL14         0x5E
-#define LCTL15         0x5F
-#define LCTL16         0x60
-#define LCTL17         0x61
-#define LCTL18         0x62
-#define LCTL19         0x63
-#define LCTL20         0x64
-#define LCTL21         0x65
-#define LCTL22         0x66
-#define LCTL23         0x67
-#define LCTL24         0x68
-#define LCTL25         0x69
-#define LCTL26         0x6A
-#define HSBEGIN                0x6B
-#define HSEND          0x6C
-#define OVSDLY         0x6D
-#define OVSEND         0x6E
-#define VBIDELAY       0x6F
-
-/*
- * register detail
- */
-
-/* INFORM */
-#define FC27_ON     0x40 /* 1 : Input crystal clock frequency is 27MHz */
-#define FC27_FF     0x00 /* 0 : Square pixel mode. */
-                        /*     Must use 24.54MHz for 60Hz field rate */
-                        /*     source or 29.5MHz for 50Hz field rate */
-#define IFSEL_S     0x10 /* 01 : S-video decoding */
-#define IFSEL_C     0x00 /* 00 : Composite video decoding */
-                        /* Y input video selection */
-#define YSEL_M0     0x00 /*  00 : Mux0 selected */
-#define YSEL_M1     0x04 /*  01 : Mux1 selected */
-#define YSEL_M2     0x08 /*  10 : Mux2 selected */
-#define YSEL_M3     0x10 /*  11 : Mux3 selected */
-
-/* OPFORM */
-#define MODE        0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
-                        /* 1 : ITU-R-656 compatible data sequence format */
-#define LEN         0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
-                        /* 1 : 16-bit YCrCb 4:2:2 output format.*/
-#define LLCMODE     0x20 /* 1 : LLC output mode. */
-                        /* 0 : free-run output mode */
-#define AINC        0x10 /* Serial interface auto-indexing control */
-                        /* 0 : auto-increment */
-                        /* 1 : non-auto */
-#define VSCTL       0x08 /* 1 : Vertical out ctrl by DVALID */
-                        /* 0 : Vertical out ctrl by HACTIVE and DVALID */
-#define OEN_TRI_SEL_MASK       0x07
-#define OEN_TRI_SEL_ALL_ON     0x00 /* Enable output for Rev0/Rev1 */
-#define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */
-#define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */
-
-/* OUTCTR1 */
-#define VSP_LO      0x00 /* 0 : VS pin output polarity is active low */
-#define VSP_HI      0x80 /* 1 : VS pin output polarity is active high. */
-                        /* VS pin output control */
-#define VSSL_VSYNC  0x00 /*   0 : VSYNC  */
-#define VSSL_VACT   0x10 /*   1 : VACT   */
-#define VSSL_FIELD  0x20 /*   2 : FIELD  */
-#define VSSL_VVALID 0x30 /*   3 : VVALID */
-#define VSSL_ZERO   0x70 /*   7 : 0      */
-#define HSP_LOW     0x00 /* 0 : HS pin output polarity is active low */
-#define HSP_HI      0x08 /* 1 : HS pin output polarity is active high.*/
-                        /* HS pin output control */
-#define HSSL_HACT   0x00 /*   0 : HACT   */
-#define HSSL_HSYNC  0x01 /*   1 : HSYNC  */
-#define HSSL_DVALID 0x02 /*   2 : DVALID */
-#define HSSL_HLOCK  0x03 /*   3 : HLOCK  */
-#define HSSL_ASYNCW 0x04 /*   4 : ASYNCW */
-#define HSSL_ZERO   0x07 /*   7 : 0      */
-
-/* ACNTL1 */
-#define SRESET      0x80 /* resets the device to its default state
-                         * but all register content remain unchanged.
-                         * This bit is self-resetting.
-                         */
-#define ACNTL1_PDN_MASK        0x0e
-#define CLK_PDN                0x08 /* system clock power down */
-#define Y_PDN          0x04 /* Luma ADC power down */
-#define C_PDN          0x02 /* Chroma ADC power down */
-
-/* ACNTL2 */
-#define ACNTL2_PDN_MASK        0x40
-#define PLL_PDN                0x40 /* PLL power down */
-
-/* VBICNTL */
-
-/* RTSEL : control the real time signal output from the MPOUT pin */
-#define RTSEL_MASK  0x07
-#define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
-#define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
-#define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
-#define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
-#define RTSEL_MONO  0x04 /* 0100 = MONO */
-#define RTSEL_DET50 0x05 /* 0101 = DET50 */
-#define RTSEL_FIELD 0x06 /* 0110 = FIELD */
-#define RTSEL_RTCO  0x07 /* 0111 = RTCO ( Real Time Control ) */
-
-/* HSYNC start and end are constant for now */
-#define HSYNC_START    0x0260
-#define HSYNC_END      0x0300
-
-/*
- * structure
- */
-
-struct regval_list {
-       unsigned char reg_num;
-       unsigned char value;
-};
-
-struct tw9910_scale_ctrl {
-       char           *name;
-       unsigned short  width;
-       unsigned short  height;
-       u16             hscale;
-       u16             vscale;
-};
-
-struct tw9910_priv {
-       struct v4l2_subdev              subdev;
-       struct v4l2_clk                 *clk;
-       struct tw9910_video_info        *info;
-       const struct tw9910_scale_ctrl  *scale;
-       v4l2_std_id                     norm;
-       u32                             revision;
-};
-
-static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
-       {
-               .name   = "NTSC SQ",
-               .width  = 640,
-               .height = 480,
-               .hscale = 0x0100,
-               .vscale = 0x0100,
-       },
-       {
-               .name   = "NTSC CCIR601",
-               .width  = 720,
-               .height = 480,
-               .hscale = 0x0100,
-               .vscale = 0x0100,
-       },
-       {
-               .name   = "NTSC SQ (CIF)",
-               .width  = 320,
-               .height = 240,
-               .hscale = 0x0200,
-               .vscale = 0x0200,
-       },
-       {
-               .name   = "NTSC CCIR601 (CIF)",
-               .width  = 360,
-               .height = 240,
-               .hscale = 0x0200,
-               .vscale = 0x0200,
-       },
-       {
-               .name   = "NTSC SQ (QCIF)",
-               .width  = 160,
-               .height = 120,
-               .hscale = 0x0400,
-               .vscale = 0x0400,
-       },
-       {
-               .name   = "NTSC CCIR601 (QCIF)",
-               .width  = 180,
-               .height = 120,
-               .hscale = 0x0400,
-               .vscale = 0x0400,
-       },
-};
-
-static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
-       {
-               .name   = "PAL SQ",
-               .width  = 768,
-               .height = 576,
-               .hscale = 0x0100,
-               .vscale = 0x0100,
-       },
-       {
-               .name   = "PAL CCIR601",
-               .width  = 720,
-               .height = 576,
-               .hscale = 0x0100,
-               .vscale = 0x0100,
-       },
-       {
-               .name   = "PAL SQ (CIF)",
-               .width  = 384,
-               .height = 288,
-               .hscale = 0x0200,
-               .vscale = 0x0200,
-       },
-       {
-               .name   = "PAL CCIR601 (CIF)",
-               .width  = 360,
-               .height = 288,
-               .hscale = 0x0200,
-               .vscale = 0x0200,
-       },
-       {
-               .name   = "PAL SQ (QCIF)",
-               .width  = 192,
-               .height = 144,
-               .hscale = 0x0400,
-               .vscale = 0x0400,
-       },
-       {
-               .name   = "PAL CCIR601 (QCIF)",
-               .width  = 180,
-               .height = 144,
-               .hscale = 0x0400,
-               .vscale = 0x0400,
-       },
-};
-
-/*
- * general function
- */
-static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
-{
-       return container_of(i2c_get_clientdata(client), struct tw9910_priv,
-                           subdev);
-}
-
-static int tw9910_mask_set(struct i2c_client *client, u8 command,
-                          u8 mask, u8 set)
-{
-       s32 val = i2c_smbus_read_byte_data(client, command);
-       if (val < 0)
-               return val;
-
-       val &= ~mask;
-       val |= set & mask;
-
-       return i2c_smbus_write_byte_data(client, command, val);
-}
-
-static int tw9910_set_scale(struct i2c_client *client,
-                           const struct tw9910_scale_ctrl *scale)
-{
-       int ret;
-
-       ret = i2c_smbus_write_byte_data(client, SCALE_HI,
-                                       (scale->vscale & 0x0F00) >> 4 |
-                                       (scale->hscale & 0x0F00) >> 8);
-       if (ret < 0)
-               return ret;
-
-       ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
-                                       scale->hscale & 0x00FF);
-       if (ret < 0)
-               return ret;
-
-       ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
-                                       scale->vscale & 0x00FF);
-
-       return ret;
-}
-
-static int tw9910_set_hsync(struct i2c_client *client)
-{
-       struct tw9910_priv *priv = to_tw9910(client);
-       int ret;
-
-       /* bit 10 - 3 */
-       ret = i2c_smbus_write_byte_data(client, HSBEGIN,
-                                       (HSYNC_START & 0x07F8) >> 3);
-       if (ret < 0)
-               return ret;
-
-       /* bit 10 - 3 */
-       ret = i2c_smbus_write_byte_data(client, HSEND,
-                                       (HSYNC_END & 0x07F8) >> 3);
-       if (ret < 0)
-               return ret;
-
-       /* So far only revisions 0 and 1 have been seen */
-       /* bit 2 - 0 */
-       if (1 == priv->revision)
-               ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
-                                     (HSYNC_START & 0x0007) << 4 |
-                                     (HSYNC_END   & 0x0007));
-
-       return ret;
-}
-
-static void tw9910_reset(struct i2c_client *client)
-{
-       tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
-       msleep(1);
-}
-
-static int tw9910_power(struct i2c_client *client, int enable)
-{
-       int ret;
-       u8 acntl1;
-       u8 acntl2;
-
-       if (enable) {
-               acntl1 = 0;
-               acntl2 = 0;
-       } else {
-               acntl1 = CLK_PDN | Y_PDN | C_PDN;
-               acntl2 = PLL_PDN;
-       }
-
-       ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
-       if (ret < 0)
-               return ret;
-
-       return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
-}
-
-static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
-                                                         u32 width, u32 height)
-{
-       const struct tw9910_scale_ctrl *scale;
-       const struct tw9910_scale_ctrl *ret = NULL;
-       __u32 diff = 0xffffffff, tmp;
-       int size, i;
-
-       if (norm & V4L2_STD_NTSC) {
-               scale = tw9910_ntsc_scales;
-               size = ARRAY_SIZE(tw9910_ntsc_scales);
-       } else if (norm & V4L2_STD_PAL) {
-               scale = tw9910_pal_scales;
-               size = ARRAY_SIZE(tw9910_pal_scales);
-       } else {
-               return NULL;
-       }
-
-       for (i = 0; i < size; i++) {
-               tmp = abs(width - scale[i].width) +
-                       abs(height - scale[i].height);
-               if (tmp < diff) {
-                       diff = tmp;
-                       ret = scale + i;
-               }
-       }
-
-       return ret;
-}
-
-/*
- * subdevice operations
- */
-static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-       u8 val;
-       int ret;
-
-       if (!enable) {
-               switch (priv->revision) {
-               case 0:
-                       val = OEN_TRI_SEL_ALL_OFF_r0;
-                       break;
-               case 1:
-                       val = OEN_TRI_SEL_ALL_OFF_r1;
-                       break;
-               default:
-                       dev_err(&client->dev, "un-supported revision\n");
-                       return -EINVAL;
-               }
-       } else {
-               val = OEN_TRI_SEL_ALL_ON;
-
-               if (!priv->scale) {
-                       dev_err(&client->dev, "norm select error\n");
-                       return -EPERM;
-               }
-
-               dev_dbg(&client->dev, "%s %dx%d\n",
-                       priv->scale->name,
-                       priv->scale->width,
-                       priv->scale->height);
-       }
-
-       ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
-       if (ret < 0)
-               return ret;
-
-       return tw9910_power(client, enable);
-}
-
-static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-
-       *norm = priv->norm;
-
-       return 0;
-}
-
-static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-       const unsigned hact = 720;
-       const unsigned hdelay = 15;
-       unsigned vact;
-       unsigned vdelay;
-       int ret;
-
-       if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
-               return -EINVAL;
-
-       priv->norm = norm;
-       if (norm & V4L2_STD_525_60) {
-               vact = 240;
-               vdelay = 18;
-               ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
-       } else {
-               vact = 288;
-               vdelay = 24;
-               ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
-       }
-       if (!ret)
-               ret = i2c_smbus_write_byte_data(client, CROP_HI,
-                       ((vdelay >> 2) & 0xc0) |
-                       ((vact >> 4) & 0x30) |
-                       ((hdelay >> 6) & 0x0c) |
-                       ((hact >> 8) & 0x03));
-       if (!ret)
-               ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
-                       vdelay & 0xff);
-       if (!ret)
-               ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
-                       vact & 0xff);
-
-       return ret;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int tw9910_g_register(struct v4l2_subdev *sd,
-                            struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int ret;
-
-       if (reg->reg > 0xff)
-               return -EINVAL;
-
-       reg->size = 1;
-       ret = i2c_smbus_read_byte_data(client, reg->reg);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * ret      = int
-        * reg->val = __u64
-        */
-       reg->val = (__u64)ret;
-
-       return 0;
-}
-
-static int tw9910_s_register(struct v4l2_subdev *sd,
-                            const struct v4l2_dbg_register *reg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (reg->reg > 0xff ||
-           reg->val > 0xff)
-               return -EINVAL;
-
-       return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
-}
-#endif
-
-static int tw9910_s_power(struct v4l2_subdev *sd, int on)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       struct tw9910_priv *priv = to_tw9910(client);
-
-       return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
-}
-
-static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-       int ret = -EINVAL;
-       u8 val;
-
-       /*
-        * select suitable norm
-        */
-       priv->scale = tw9910_select_norm(priv->norm, *width, *height);
-       if (!priv->scale)
-               goto tw9910_set_fmt_error;
-
-       /*
-        * reset hardware
-        */
-       tw9910_reset(client);
-
-       /*
-        * set bus width
-        */
-       val = 0x00;
-       if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
-               val = LEN;
-
-       ret = tw9910_mask_set(client, OPFORM, LEN, val);
-       if (ret < 0)
-               goto tw9910_set_fmt_error;
-
-       /*
-        * select MPOUT behavior
-        */
-       switch (priv->info->mpout) {
-       case TW9910_MPO_VLOSS:
-               val = RTSEL_VLOSS; break;
-       case TW9910_MPO_HLOCK:
-               val = RTSEL_HLOCK; break;
-       case TW9910_MPO_SLOCK:
-               val = RTSEL_SLOCK; break;
-       case TW9910_MPO_VLOCK:
-               val = RTSEL_VLOCK; break;
-       case TW9910_MPO_MONO:
-               val = RTSEL_MONO;  break;
-       case TW9910_MPO_DET50:
-               val = RTSEL_DET50; break;
-       case TW9910_MPO_FIELD:
-               val = RTSEL_FIELD; break;
-       case TW9910_MPO_RTCO:
-               val = RTSEL_RTCO;  break;
-       default:
-               val = 0;
-       }
-
-       ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
-       if (ret < 0)
-               goto tw9910_set_fmt_error;
-
-       /*
-        * set scale
-        */
-       ret = tw9910_set_scale(client, priv->scale);
-       if (ret < 0)
-               goto tw9910_set_fmt_error;
-
-       /*
-        * set hsync
-        */
-       ret = tw9910_set_hsync(client);
-       if (ret < 0)
-               goto tw9910_set_fmt_error;
-
-       *width = priv->scale->width;
-       *height = priv->scale->height;
-
-       return ret;
-
-tw9910_set_fmt_error:
-
-       tw9910_reset(client);
-       priv->scale = NULL;
-
-       return ret;
-}
-
-static int tw9910_get_selection(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_selection *sel)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-
-       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
-               return -EINVAL;
-       /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported */
-       if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS)
-               return -EINVAL;
-
-       sel->r.left     = 0;
-       sel->r.top      = 0;
-       if (priv->norm & V4L2_STD_NTSC) {
-               sel->r.width    = 640;
-               sel->r.height   = 480;
-       } else {
-               sel->r.width    = 768;
-               sel->r.height   = 576;
-       }
-       return 0;
-}
-
-static int tw9910_get_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-
-       if (format->pad)
-               return -EINVAL;
-
-       if (!priv->scale) {
-               priv->scale = tw9910_select_norm(priv->norm, 640, 480);
-               if (!priv->scale)
-                       return -EINVAL;
-       }
-
-       mf->width       = priv->scale->width;
-       mf->height      = priv->scale->height;
-       mf->code        = MEDIA_BUS_FMT_UYVY8_2X8;
-       mf->colorspace  = V4L2_COLORSPACE_SMPTE170M;
-       mf->field       = V4L2_FIELD_INTERLACED_BT;
-
-       return 0;
-}
-
-static int tw9910_s_fmt(struct v4l2_subdev *sd,
-                       struct v4l2_mbus_framefmt *mf)
-{
-       u32 width = mf->width, height = mf->height;
-       int ret;
-
-       WARN_ON(mf->field != V4L2_FIELD_ANY &&
-               mf->field != V4L2_FIELD_INTERLACED_BT);
-
-       /*
-        * check color format
-        */
-       if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
-               return -EINVAL;
-
-       mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
-       ret = tw9910_set_frame(sd, &width, &height);
-       if (!ret) {
-               mf->width       = width;
-               mf->height      = height;
-       }
-       return ret;
-}
-
-static int tw9910_set_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
-{
-       struct v4l2_mbus_framefmt *mf = &format->format;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-       const struct tw9910_scale_ctrl *scale;
-
-       if (format->pad)
-               return -EINVAL;
-
-       if (V4L2_FIELD_ANY == mf->field) {
-               mf->field = V4L2_FIELD_INTERLACED_BT;
-       } else if (V4L2_FIELD_INTERLACED_BT != mf->field) {
-               dev_err(&client->dev, "Field type %d invalid.\n", mf->field);
-               return -EINVAL;
-       }
-
-       mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
-       mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
-
-       /*
-        * select suitable norm
-        */
-       scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
-       if (!scale)
-               return -EINVAL;
-
-       mf->width       = scale->width;
-       mf->height      = scale->height;
-
-       if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               return tw9910_s_fmt(sd, mf);
-       cfg->try_fmt = *mf;
-       return 0;
-}
-
-static int tw9910_video_probe(struct i2c_client *client)
-{
-       struct tw9910_priv *priv = to_tw9910(client);
-       s32 id;
-       int ret;
-
-       /*
-        * tw9910 only use 8 or 16 bit bus width
-        */
-       if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
-           SOCAM_DATAWIDTH_8  != priv->info->buswidth) {
-               dev_err(&client->dev, "bus width error\n");
-               return -ENODEV;
-       }
-
-       ret = tw9910_s_power(&priv->subdev, 1);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * check and show Product ID
-        * So far only revisions 0 and 1 have been seen
-        */
-       id = i2c_smbus_read_byte_data(client, ID);
-       priv->revision = GET_REV(id);
-       id = GET_ID(id);
-
-       if (0x0B != id ||
-           0x01 < priv->revision) {
-               dev_err(&client->dev,
-                       "Product ID error %x:%x\n",
-                       id, priv->revision);
-               ret = -ENODEV;
-               goto done;
-       }
-
-       dev_info(&client->dev,
-                "tw9910 Product ID %0x:%0x\n", id, priv->revision);
-
-       priv->norm = V4L2_STD_NTSC;
-       priv->scale = &tw9910_ntsc_scales[0];
-
-done:
-       tw9910_s_power(&priv->subdev, 0);
-       return ret;
-}
-
-static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       .g_register     = tw9910_g_register,
-       .s_register     = tw9910_s_register,
-#endif
-       .s_power        = tw9910_s_power,
-};
-
-static int tw9910_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index)
-               return -EINVAL;
-
-       code->code = MEDIA_BUS_FMT_UYVY8_2X8;
-       return 0;
-}
-
-static int tw9910_g_mbus_config(struct v4l2_subdev *sd,
-                               struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
-               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
-       cfg->type = V4L2_MBUS_PARALLEL;
-       cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       return 0;
-}
-
-static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
-                               const struct v4l2_mbus_config *cfg)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
-       u8 val = VSSL_VVALID | HSSL_DVALID;
-       unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg);
-
-       /*
-        * set OUTCTR1
-        *
-        * We use VVALID and DVALID signals to control VSYNC and HSYNC
-        * outputs, in this mode their polarity is inverted.
-        */
-       if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
-               val |= HSP_HI;
-
-       if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
-               val |= VSP_HI;
-
-       return i2c_smbus_write_byte_data(client, OUTCTR1, val);
-}
-
-static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
-{
-       *norm = V4L2_STD_NTSC | V4L2_STD_PAL;
-       return 0;
-}
-
-static const struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
-       .s_std          = tw9910_s_std,
-       .g_std          = tw9910_g_std,
-       .s_stream       = tw9910_s_stream,
-       .g_mbus_config  = tw9910_g_mbus_config,
-       .s_mbus_config  = tw9910_s_mbus_config,
-       .g_tvnorms      = tw9910_g_tvnorms,
-};
-
-static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
-       .enum_mbus_code = tw9910_enum_mbus_code,
-       .get_selection  = tw9910_get_selection,
-       .get_fmt        = tw9910_get_fmt,
-       .set_fmt        = tw9910_set_fmt,
-};
-
-static const struct v4l2_subdev_ops tw9910_subdev_ops = {
-       .core   = &tw9910_subdev_core_ops,
-       .video  = &tw9910_subdev_video_ops,
-       .pad    = &tw9910_subdev_pad_ops,
-};
-
-/*
- * i2c_driver function
- */
-
-static int tw9910_probe(struct i2c_client *client,
-                       const struct i2c_device_id *did)
-
-{
-       struct tw9910_priv              *priv;
-       struct tw9910_video_info        *info;
-       struct i2c_adapter              *adapter =
-               to_i2c_adapter(client->dev.parent);
-       struct soc_camera_subdev_desc   *ssdd = soc_camera_i2c_to_desc(client);
-       int ret;
-
-       if (!ssdd || !ssdd->drv_priv) {
-               dev_err(&client->dev, "TW9910: missing platform data!\n");
-               return -EINVAL;
-       }
-
-       info = ssdd->drv_priv;
-
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-               dev_err(&client->dev,
-                       "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n");
-               return -EIO;
-       }
-
-       priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->info   = info;
-
-       v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
-
-       priv->clk = v4l2_clk_get(&client->dev, "mclk");
-       if (IS_ERR(priv->clk))
-               return PTR_ERR(priv->clk);
-
-       ret = tw9910_video_probe(client);
-       if (ret < 0)
-               v4l2_clk_put(priv->clk);
-
-       return ret;
-}
-
-static int tw9910_remove(struct i2c_client *client)
-{
-       struct tw9910_priv *priv = to_tw9910(client);
-       v4l2_clk_put(priv->clk);
-       return 0;
-}
-
-static const struct i2c_device_id tw9910_id[] = {
-       { "tw9910", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, tw9910_id);
-
-static struct i2c_driver tw9910_i2c_driver = {
-       .driver = {
-               .name = "tw9910",
-       },
-       .probe    = tw9910_probe,
-       .remove   = tw9910_remove,
-       .id_table = tw9910_id,
-};
-
-module_i2c_driver(tw9910_i2c_driver);
-
-MODULE_DESCRIPTION("SoC Camera driver for tw9910");
-MODULE_AUTHOR("Kuninori Morimoto");
-MODULE_LICENSE("GPL v2");
index 2a4882cddc51950a4dabf8aa2a99784904d9d1cf..11f6c7a5e0e79bdf3451063db87d5628bbd3615b 100644 (file)
@@ -569,7 +569,7 @@ static int sr030pc30_base_config(struct v4l2_subdev *sd)
        if (!ret)
                ret = sr030pc30_pwr_ctrl(sd, false, false);
 
-       if (!ret && !info->pdata)
+       if (ret)
                return ret;
 
        expmin = EXPOS_MIN_MS * info->pdata->clk_rate / (8 * 1000);
@@ -703,7 +703,6 @@ static int sr030pc30_probe(struct i2c_client *client,
                return -ENOMEM;
 
        sd = &info->sd;
-       strcpy(sd->name, MODULE_NAME);
        info->pdata = client->dev.platform_data;
 
        v4l2_i2c_subdev_init(sd, client, &sr030pc30_ops);
index 44c41933415ab89aea8c847687615a3f0813341d..ca5d92942820a2fcb439ec1e7d277dd445214276 100644 (file)
@@ -1243,9 +1243,9 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
        u8 vi_status3 =  i2c_rd8(sd, VI_STATUS3);
        const int deep_color_mode[4] = { 8, 10, 12, 16 };
        static const char * const input_color_space[] = {
-               "RGB", "YCbCr 601", "Adobe RGB", "YCbCr 709", "NA (4)",
+               "RGB", "YCbCr 601", "opRGB", "YCbCr 709", "NA (4)",
                "xvYCC 601", "NA(6)", "xvYCC 709", "NA(8)", "sYCC601",
-               "NA(10)", "NA(11)", "NA(12)", "Adobe YCC 601"};
+               "NA(10)", "NA(11)", "NA(12)", "opYCC 601"};
 
        v4l2_info(sd, "-----Chip status-----\n");
        v4l2_info(sd, "Chip ID: 0x%02x\n",
@@ -1607,7 +1607,7 @@ static int tc358743_g_mbus_config(struct v4l2_subdev *sd,
 {
        struct tc358743_state *state = to_state(sd);
 
-       cfg->type = V4L2_MBUS_CSI2;
+       cfg->type = V4L2_MBUS_CSI2_DPHY;
 
        /* Support for non-continuous CSI-2 clock is missing in the driver */
        cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
@@ -1789,7 +1789,7 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
                return -E2BIG;
        }
        pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL);
-       err = cec_phys_addr_validate(pa, &pa, NULL);
+       err = v4l2_phys_addr_validate(pa, &pa, NULL);
        if (err)
                return err;
 
@@ -1895,11 +1895,11 @@ static void tc358743_gpio_reset(struct tc358743_state *state)
 static int tc358743_probe_of(struct tc358743_state *state)
 {
        struct device *dev = &state->i2c_client->dev;
-       struct v4l2_fwnode_endpoint *endpoint;
+       struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
        struct device_node *ep;
        struct clk *refclk;
        u32 bps_pr_lane;
-       int ret = -EINVAL;
+       int ret;
 
        refclk = devm_clk_get(dev, "refclk");
        if (IS_ERR(refclk)) {
@@ -1915,26 +1915,28 @@ static int tc358743_probe_of(struct tc358743_state *state)
                return -EINVAL;
        }
 
-       endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
-       if (IS_ERR(endpoint)) {
+       ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
+       if (ret) {
                dev_err(dev, "failed to parse endpoint\n");
-               ret = PTR_ERR(endpoint);
+               ret = ret;
                goto put_node;
        }
 
-       if (endpoint->bus_type != V4L2_MBUS_CSI2 ||
-           endpoint->bus.mipi_csi2.num_data_lanes == 0 ||
-           endpoint->nr_of_link_frequencies == 0) {
+       if (endpoint.bus_type != V4L2_MBUS_CSI2_DPHY ||
+           endpoint.bus.mipi_csi2.num_data_lanes == 0 ||
+           endpoint.nr_of_link_frequencies == 0) {
                dev_err(dev, "missing CSI-2 properties in endpoint\n");
+               ret = -EINVAL;
                goto free_endpoint;
        }
 
-       if (endpoint->bus.mipi_csi2.num_data_lanes > 4) {
+       if (endpoint.bus.mipi_csi2.num_data_lanes > 4) {
                dev_err(dev, "invalid number of lanes\n");
+               ret = -EINVAL;
                goto free_endpoint;
        }
 
-       state->bus = endpoint->bus.mipi_csi2;
+       state->bus = endpoint.bus.mipi_csi2;
 
        ret = clk_prepare_enable(refclk);
        if (ret) {
@@ -1967,7 +1969,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
         * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps.
         * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60.
         */
-       bps_pr_lane = 2 * endpoint->link_frequencies[0];
+       bps_pr_lane = 2 * endpoint.link_frequencies[0];
        if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) {
                dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane);
                goto disable_clk;
@@ -2013,7 +2015,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
 disable_clk:
        clk_disable_unprepare(refclk);
 free_endpoint:
-       v4l2_fwnode_endpoint_free(endpoint);
+       v4l2_fwnode_endpoint_free(&endpoint);
 put_node:
        of_node_put(ep);
        return ret;
index d114ac5243ecaff1f1c0be6de13c632b0c0a4b5c..c4c2a6134e1eb047fb8687a6c235e49c358f089b 100644 (file)
@@ -2265,7 +2265,7 @@ MODULE_DEVICE_TABLE(of, tda1997x_of_id);
 static int tda1997x_parse_dt(struct tda1997x_state *state)
 {
        struct tda1997x_platform_data *pdata = &state->pdata;
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct device_node *ep;
        struct device_node *np;
        unsigned int flags;
index 5919214a56bf3f7dadc5763f08bf90ca3330f558..af2da977a685455da542b1964a793613e58ecef9 100644 (file)
@@ -1981,7 +1981,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
 
        /* fill required data structures */
        if (!id)
-               strlcpy(client->name, desc->name, I2C_NAME_SIZE);
+               strscpy(client->name, desc->name, I2C_NAME_SIZE);
        chip->desc = desc;
        chip->shadow.count = desc->registers+1;
        chip->prevmode = -1;
index 675b9ae212abf61b92ef7bc8bcfac460ece2f19b..1cc83cb934e2d04f6640689b7583017edf8b71ad 100644 (file)
@@ -989,7 +989,7 @@ static struct tvp514x_platform_data *
 tvp514x_get_pdata(struct i2c_client *client)
 {
        struct tvp514x_platform_data *pdata = NULL;
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct device_node *endpoint;
        unsigned int flags;
 
index 76e6bed5a1da22c24e7289fc9e40010b24e7ac0b..0e91b9949c3a9976e58b584546730b23266be0f6 100644 (file)
 #include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
+#include <linux/regmap.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
@@ -26,6 +28,9 @@
 #define TVP5150_MAX_CROP_LEFT  511
 #define TVP5150_MAX_CROP_TOP   127
 #define TVP5150_CROP_SHIFT     2
+#define TVP5150_MBUS_FMT       MEDIA_BUS_FMT_UYVY8_2X8
+#define TVP5150_FIELD          V4L2_FIELD_ALTERNATE
+#define TVP5150_COLORSPACE     V4L2_COLORSPACE_SMPTE170M
 
 MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video decoder driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
@@ -38,20 +43,31 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 #define dprintk0(__dev, __arg...) dev_dbg_lvl(__dev, 0, 0, __arg)
 
+enum tvp5150_pads {
+       TVP5150_PAD_IF_INPUT,
+       TVP5150_PAD_VID_OUT,
+       TVP5150_NUM_PADS
+};
+
 struct tvp5150 {
        struct v4l2_subdev sd;
 #ifdef CONFIG_MEDIA_CONTROLLER
-       struct media_pad pads[DEMOD_NUM_PADS];
+       struct media_pad pads[TVP5150_NUM_PADS];
        struct media_entity input_ent[TVP5150_INPUT_NUM];
        struct media_pad input_pad[TVP5150_INPUT_NUM];
 #endif
        struct v4l2_ctrl_handler hdl;
        struct v4l2_rect rect;
+       struct regmap *regmap;
+       int irq;
 
        v4l2_std_id norm;       /* Current set standard */
+       v4l2_std_id detected_norm;
        u32 input;
        u32 output;
+       u32 oe;
        int enable;
+       bool lock;
 
        u16 dev_id;
        u16 rom_ver;
@@ -71,32 +87,14 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
 
 static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
 {
-       struct i2c_client *c = v4l2_get_subdevdata(sd);
-       int rc;
-
-       rc = i2c_smbus_read_byte_data(c, addr);
-       if (rc < 0) {
-               dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc);
-               return rc;
-       }
-
-       dev_dbg_lvl(sd->dev, 2, debug, "tvp5150: read 0x%02x = %02x\n", addr, rc);
-
-       return rc;
-}
-
-static int tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
-                                unsigned char value)
-{
-       struct i2c_client *c = v4l2_get_subdevdata(sd);
-       int rc;
+       struct tvp5150 *decoder = to_tvp5150(sd);
+       int ret, val;
 
-       dev_dbg_lvl(sd->dev, 2, debug, "tvp5150: writing %02x %02x\n", addr, value);
-       rc = i2c_smbus_write_byte_data(c, addr, value);
-       if (rc < 0)
-               dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc);
+       ret = regmap_read(decoder->regmap, addr, &val);
+       if (ret < 0)
+               return ret;
 
-       return rc;
+       return val;
 }
 
 static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
@@ -262,8 +260,8 @@ static void tvp5150_selmux(struct v4l2_subdev *sd)
 {
        int opmode = 0;
        struct tvp5150 *decoder = to_tvp5150(sd);
+       unsigned int mask, val;
        int input = 0;
-       int val;
 
        /* Only tvp5150am1 and tvp5151 have signal generator support */
        if ((decoder->dev_id == 0x5150 && decoder->rom_ver == 0x0400) ||
@@ -288,8 +286,8 @@ static void tvp5150_selmux(struct v4l2_subdev *sd)
                        decoder->input, decoder->output,
                        input, opmode);
 
-       tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
-       tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
+       regmap_write(decoder->regmap, TVP5150_OP_MODE_CTL, opmode);
+       regmap_write(decoder->regmap, TVP5150_VD_IN_SRC_SEL_1, input);
 
        /*
         * Setup the FID/GLCO/VLK/HVLK and INTREQ/GPCL/VBLK output signals. For
@@ -298,17 +296,12 @@ static void tvp5150_selmux(struct v4l2_subdev *sd)
         * field indicator (FID) signal on FID/GLCO/VLK/HVLK and set
         * INTREQ/GPCL/VBLK to logic 1.
         */
-       val = tvp5150_read(sd, TVP5150_MISC_CTL);
-       if (val < 0) {
-               dev_err(sd->dev, "%s: failed with error = %d\n", __func__, val);
-               return;
-       }
-
+       mask = TVP5150_MISC_CTL_GPCL | TVP5150_MISC_CTL_HVLK;
        if (decoder->input == TVP5150_SVIDEO)
-               val = (val & ~TVP5150_MISC_CTL_GPCL) | TVP5150_MISC_CTL_HVLK;
+               val = TVP5150_MISC_CTL_HVLK;
        else
-               val = (val & ~TVP5150_MISC_CTL_HVLK) | TVP5150_MISC_CTL_GPCL;
-       tvp5150_write(sd, TVP5150_MISC_CTL, val);
+               val = TVP5150_MISC_CTL_GPCL;
+       regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val);
 };
 
 struct i2c_reg_value {
@@ -454,9 +447,7 @@ static const struct i2c_reg_value tvp5150_init_default[] = {
 
 /* Default values as sugested at TVP5150AM1 datasheet */
 static const struct i2c_reg_value tvp5150_init_enable[] = {
-       {
-               TVP5150_CONF_SHARED_PIN, 2
-       }, {    /* Automatic offset and AGC enabled */
+       {       /* Automatic offset and AGC enabled */
                TVP5150_ANAL_CHL_CTL, 0x15
        }, {    /* Activate YCrCb output 0x9 or 0xd ? */
                TVP5150_MISC_CTL, TVP5150_MISC_CTL_GPCL |
@@ -583,8 +574,10 @@ static struct i2c_vbi_ram_value vbi_ram_default[] = {
 static int tvp5150_write_inittab(struct v4l2_subdev *sd,
                                const struct i2c_reg_value *regs)
 {
+       struct tvp5150 *decoder = to_tvp5150(sd);
+
        while (regs->reg != 0xff) {
-               tvp5150_write(sd, regs->reg, regs->value);
+               regmap_write(decoder->regmap, regs->reg, regs->value);
                regs++;
        }
        return 0;
@@ -592,15 +585,17 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd,
 
 static int tvp5150_vdp_init(struct v4l2_subdev *sd)
 {
+       struct tvp5150 *decoder = to_tvp5150(sd);
+       struct regmap *map = decoder->regmap;
        unsigned int i;
        int j;
 
        /* Disable Full Field */
-       tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
+       regmap_write(map, TVP5150_FULL_FIELD_ENA, 0);
 
        /* Before programming, Line mode should be at 0xff */
        for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
-               tvp5150_write(sd, i, 0xff);
+               regmap_write(map, i, 0xff);
 
        /* Load Ram Table */
        for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) {
@@ -609,11 +604,12 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd)
                if (!regs->type.vbi_type)
                        continue;
 
-               tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
-               tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
+               regmap_write(map, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
+               regmap_write(map, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
 
                for (i = 0; i < 16; i++)
-                       tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
+                       regmap_write(map, TVP5150_VDP_CONF_RAM_DATA,
+                                    regs->values[i]);
        }
        return 0;
 }
@@ -693,10 +689,10 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
        reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
 
        if (fields & 1)
-               tvp5150_write(sd, reg, type);
+               regmap_write(decoder->regmap, reg, type);
 
        if (fields & 2)
-               tvp5150_write(sd, reg + 1, type);
+               regmap_write(decoder->regmap, reg + 1, type);
 
        return type;
 }
@@ -742,8 +738,6 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
        struct tvp5150 *decoder = to_tvp5150(sd);
        int fmt = 0;
 
-       decoder->norm = std;
-
        /* First tests should be against specific std */
 
        if (std == V4L2_STD_NTSC_443) {
@@ -763,7 +757,16 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
        }
 
        dev_dbg_lvl(sd->dev, 1, debug, "Set video std register to %d.\n", fmt);
-       tvp5150_write(sd, TVP5150_VIDEO_STD, fmt);
+       regmap_write(decoder->regmap, TVP5150_VIDEO_STD, fmt);
+       return 0;
+}
+
+static int tvp5150_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+
+       *std = decoder->norm;
+
        return 0;
 }
 
@@ -780,33 +783,166 @@ static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
        else
                decoder->rect.height = TVP5150_V_MAX_OTHERS;
 
+       decoder->norm = std;
 
        return tvp5150_set_std(sd, std);
 }
 
+static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
+{
+       int val = tvp5150_read(sd, TVP5150_STATUS_REG_5);
+
+       switch (val & 0x0F) {
+       case 0x01:
+               return V4L2_STD_NTSC;
+       case 0x03:
+               return V4L2_STD_PAL;
+       case 0x05:
+               return V4L2_STD_PAL_M;
+       case 0x07:
+               return V4L2_STD_PAL_N | V4L2_STD_PAL_Nc;
+       case 0x09:
+               return V4L2_STD_NTSC_443;
+       case 0xb:
+               return V4L2_STD_SECAM;
+       default:
+               return V4L2_STD_UNKNOWN;
+       }
+}
+
+static int query_lock(struct v4l2_subdev *sd)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+       int status;
+
+       if (decoder->irq)
+               return decoder->lock;
+
+       regmap_read(decoder->regmap, TVP5150_STATUS_REG_1, &status);
+
+       /* For standard detection, we need the 3 locks */
+       return (status & 0x0e) == 0x0e;
+}
+
+static int tvp5150_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
+{
+       *std_id = query_lock(sd) ? tvp5150_read_std(sd) : V4L2_STD_UNKNOWN;
+
+       return 0;
+}
+
+static const struct v4l2_event tvp5150_ev_fmt = {
+       .type = V4L2_EVENT_SOURCE_CHANGE,
+       .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+};
+
+static irqreturn_t tvp5150_isr(int irq, void *dev_id)
+{
+       struct tvp5150 *decoder = dev_id;
+       struct regmap *map = decoder->regmap;
+       unsigned int mask, active = 0, status = 0;
+
+       mask = TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |
+              TVP5150_MISC_CTL_CLOCK_OE;
+
+       regmap_read(map, TVP5150_INT_STATUS_REG_A, &status);
+       if (status) {
+               regmap_write(map, TVP5150_INT_STATUS_REG_A, status);
+
+               if (status & TVP5150_INT_A_LOCK) {
+                       decoder->lock = !!(status & TVP5150_INT_A_LOCK_STATUS);
+                       dev_dbg_lvl(decoder->sd.dev, 1, debug,
+                                   "sync lo%s signal\n",
+                                   decoder->lock ? "ck" : "ss");
+                       v4l2_subdev_notify_event(&decoder->sd, &tvp5150_ev_fmt);
+                       regmap_update_bits(map, TVP5150_MISC_CTL, mask,
+                                          decoder->lock ? decoder->oe : 0);
+               }
+
+               return IRQ_HANDLED;
+       }
+
+       regmap_read(map, TVP5150_INT_ACTIVE_REG_B, &active);
+       if (active) {
+               status = 0;
+               regmap_read(map, TVP5150_INT_STATUS_REG_B, &status);
+               if (status)
+                       regmap_write(map, TVP5150_INT_RESET_REG_B, status);
+       }
+
+       return IRQ_HANDLED;
+}
+
 static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 {
        struct tvp5150 *decoder = to_tvp5150(sd);
+       struct regmap *map = decoder->regmap;
 
        /* Initializes TVP5150 to its default values */
        tvp5150_write_inittab(sd, tvp5150_init_default);
 
+       if (decoder->irq) {
+               /* Configure pins: FID, VSYNC, INTREQ, SCLK */
+               regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x0);
+               /* Set interrupt polarity to active high */
+               regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE | 0x1);
+               regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x1);
+       } else {
+               /* Configure pins: FID, VSYNC, GPCL/VBLK, SCLK */
+               regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x2);
+               /* Keep interrupt polarity active low */
+               regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE);
+               regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x0);
+       }
+
        /* Initializes VDP registers */
        tvp5150_vdp_init(sd);
 
        /* Selects decoder input */
        tvp5150_selmux(sd);
 
+       /* Initialize image preferences */
+       v4l2_ctrl_handler_setup(&decoder->hdl);
+
+       return 0;
+}
+
+static int tvp5150_enable(struct v4l2_subdev *sd)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+       v4l2_std_id std;
+
        /* Initializes TVP5150 to stream enabled values */
        tvp5150_write_inittab(sd, tvp5150_init_enable);
 
-       /* Initialize image preferences */
-       v4l2_ctrl_handler_setup(&decoder->hdl);
+       if (decoder->norm == V4L2_STD_ALL)
+               std = tvp5150_read_std(sd);
+       else
+               std = decoder->norm;
 
-       tvp5150_set_std(sd, decoder->norm);
+       /* Disable autoswitch mode */
+       tvp5150_set_std(sd, std);
 
-       if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
-               tvp5150_write(sd, TVP5150_DATA_RATE_SEL, 0x40);
+       /*
+        * Enable the YCbCr and clock outputs. In discrete sync mode
+        * (non-BT.656) additionally enable the the sync outputs.
+        */
+       switch (decoder->mbus_type) {
+       case V4L2_MBUS_PARALLEL:
+               /* 8-bit 4:2:2 YUV with discrete sync output */
+               regmap_update_bits(decoder->regmap, TVP5150_DATA_RATE_SEL,
+                                  0x7, 0x0);
+               decoder->oe = TVP5150_MISC_CTL_YCBCR_OE |
+                             TVP5150_MISC_CTL_CLOCK_OE |
+                             TVP5150_MISC_CTL_SYNC_OE;
+               break;
+       case V4L2_MBUS_BT656:
+               decoder->oe = TVP5150_MISC_CTL_YCBCR_OE |
+                             TVP5150_MISC_CTL_CLOCK_OE;
+               break;
+       default:
+               return -EINVAL;
+       }
 
        return 0;
 };
@@ -818,17 +954,18 @@ static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
 
        switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
-               tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val);
+               regmap_write(decoder->regmap, TVP5150_BRIGHT_CTL, ctrl->val);
                return 0;
        case V4L2_CID_CONTRAST:
-               tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val);
+               regmap_write(decoder->regmap, TVP5150_CONTRAST_CTL, ctrl->val);
                return 0;
        case V4L2_CID_SATURATION:
-               tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val);
+               regmap_write(decoder->regmap, TVP5150_SATURATION_CTL,
+                            ctrl->val);
                return 0;
        case V4L2_CID_HUE:
-               tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val);
-               break;
+               regmap_write(decoder->regmap, TVP5150_HUE_CTL, ctrl->val);
+               return 0;
        case V4L2_CID_TEST_PATTERN:
                decoder->enable = ctrl->val ? false : true;
                tvp5150_selmux(sd);
@@ -837,36 +974,26 @@ static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
        return -EINVAL;
 }
 
-static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
+static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop)
 {
-       int val = tvp5150_read(sd, TVP5150_STATUS_REG_5);
-
-       switch (val & 0x0F) {
-       case 0x01:
-               return V4L2_STD_NTSC;
-       case 0x03:
-               return V4L2_STD_PAL;
-       case 0x05:
-               return V4L2_STD_PAL_M;
-       case 0x07:
-               return V4L2_STD_PAL_N | V4L2_STD_PAL_Nc;
-       case 0x09:
-               return V4L2_STD_NTSC_443;
-       case 0xb:
-               return V4L2_STD_SECAM;
-       default:
-               return V4L2_STD_UNKNOWN;
-       }
+       /* Default is no cropping */
+       crop->top = 0;
+       crop->left = 0;
+       crop->width = TVP5150_H_MAX;
+       if (std & V4L2_STD_525_60)
+               crop->height = TVP5150_V_MAX_525_60;
+       else
+               crop->height = TVP5150_V_MAX_OTHERS;
 }
 
 static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_format *format)
+                           struct v4l2_subdev_pad_config *cfg,
+                           struct v4l2_subdev_format *format)
 {
        struct v4l2_mbus_framefmt *f;
        struct tvp5150 *decoder = to_tvp5150(sd);
 
-       if (!format || (format->pad != DEMOD_PAD_VID_OUT))
+       if (!format || (format->pad != TVP5150_PAD_VID_OUT))
                return -EINVAL;
 
        f = &format->format;
@@ -874,12 +1001,12 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
        f->width = decoder->rect.width;
        f->height = decoder->rect.height / 2;
 
-       f->code = MEDIA_BUS_FMT_UYVY8_2X8;
-       f->field = V4L2_FIELD_ALTERNATE;
-       f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+       f->code = TVP5150_MBUS_FMT;
+       f->field = TVP5150_FIELD;
+       f->colorspace = TVP5150_COLORSPACE;
 
        dev_dbg_lvl(sd->dev, 1, debug, "width = %d, height = %d\n", f->width,
-                       f->height);
+                   f->height);
        return 0;
 }
 
@@ -901,9 +1028,6 @@ static int tvp5150_set_selection(struct v4l2_subdev *sd,
 
        /* tvp5150 has some special limits */
        rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
-       rect.width = clamp_t(unsigned int, rect.width,
-                            TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
-                            TVP5150_H_MAX - rect.left);
        rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP);
 
        /* Calculate height based on current standard */
@@ -917,22 +1041,29 @@ static int tvp5150_set_selection(struct v4l2_subdev *sd,
        else
                hmax = TVP5150_V_MAX_OTHERS;
 
-       rect.height = clamp_t(unsigned int, rect.height,
+       /*
+        * alignments:
+        *  - width = 2 due to UYVY colorspace
+        *  - height, image = no special alignment
+        */
+       v4l_bound_align_image(&rect.width,
+                             TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
+                             TVP5150_H_MAX - rect.left, 1, &rect.height,
                              hmax - TVP5150_MAX_CROP_TOP - rect.top,
-                             hmax - rect.top);
-
-       tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top);
-       tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP,
-                     rect.top + rect.height - hmax);
-       tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_MSB,
-                     rect.left >> TVP5150_CROP_SHIFT);
-       tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_LSB,
-                     rect.left | (1 << TVP5150_CROP_SHIFT));
-       tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_MSB,
-                     (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>
-                     TVP5150_CROP_SHIFT);
-       tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_LSB,
-                     rect.left + rect.width - TVP5150_MAX_CROP_LEFT);
+                             hmax - rect.top, 0, 0);
+
+       regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, rect.top);
+       regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP,
+                    rect.top + rect.height - hmax);
+       regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_MSB,
+                    rect.left >> TVP5150_CROP_SHIFT);
+       regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_LSB,
+                    rect.left | (1 << TVP5150_CROP_SHIFT));
+       regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_MSB,
+                    (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>
+                    TVP5150_CROP_SHIFT);
+       regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_LSB,
+                    rect.left + rect.width - TVP5150_MAX_CROP_LEFT);
 
        decoder->rect = rect;
 
@@ -951,7 +1082,6 @@ static int tvp5150_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
                sel->r.left = 0;
                sel->r.top = 0;
                sel->r.width = TVP5150_H_MAX;
@@ -989,6 +1119,27 @@ static int tvp5150_g_mbus_config(struct v4l2_subdev *sd,
 /****************************************************************************
                        V4L2 subdev pad ops
  ****************************************************************************/
+static int tvp5150_init_cfg(struct v4l2_subdev *sd,
+                           struct v4l2_subdev_pad_config *cfg)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+       v4l2_std_id std;
+
+       /*
+        * Reset selection to maximum on subdev_open() if autodetection is on
+        * and a standard change is detected.
+        */
+       if (decoder->norm == V4L2_STD_ALL) {
+               std = tvp5150_read_std(sd);
+               if (std != decoder->detected_norm) {
+                       decoder->detected_norm = std;
+                       tvp5150_set_default(std, &decoder->rect);
+               }
+       }
+
+       return 0;
+}
+
 static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
                struct v4l2_subdev_pad_config *cfg,
                struct v4l2_subdev_mbus_code_enum *code)
@@ -996,7 +1147,7 @@ static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
        if (code->pad || code->index)
                return -EINVAL;
 
-       code->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       code->code = TVP5150_MBUS_FMT;
        return 0;
 }
 
@@ -1006,10 +1157,10 @@ static int tvp5150_enum_frame_size(struct v4l2_subdev *sd,
 {
        struct tvp5150 *decoder = to_tvp5150(sd);
 
-       if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_UYVY8_2X8)
+       if (fse->index >= 8 || fse->code != TVP5150_MBUS_FMT)
                return -EINVAL;
 
-       fse->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       fse->code = TVP5150_MBUS_FMT;
        fse->min_width = decoder->rect.width;
        fse->max_width = decoder->rect.width;
        fse->min_height = decoder->rect.height / 2;
@@ -1059,27 +1210,28 @@ static const struct media_entity_operations tvp5150_sd_media_ops = {
 static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
 {
        struct tvp5150 *decoder = to_tvp5150(sd);
-       int val;
+       unsigned int mask, val = 0, int_val = 0;
 
-       /* Enable or disable the video output signals. */
-       val = tvp5150_read(sd, TVP5150_MISC_CTL);
-       if (val < 0)
-               return val;
-
-       val &= ~(TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |
-                TVP5150_MISC_CTL_CLOCK_OE);
+       mask = TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |
+              TVP5150_MISC_CTL_CLOCK_OE;
 
        if (enable) {
-               /*
-                * Enable the YCbCr and clock outputs. In discrete sync mode
-                * (non-BT.656) additionally enable the the sync outputs.
-                */
-               val |= TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_CLOCK_OE;
-               if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
-                       val |= TVP5150_MISC_CTL_SYNC_OE;
+               tvp5150_enable(sd);
+
+               /* Enable outputs if decoder is locked */
+               if (decoder->irq)
+                       val = decoder->lock ? decoder->oe : 0;
+               else
+                       val = decoder->oe;
+               int_val = TVP5150_INT_A_LOCK;
+               v4l2_subdev_notify_event(&decoder->sd, &tvp5150_ev_fmt);
        }
 
-       tvp5150_write(sd, TVP5150_MISC_CTL, val);
+       regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val);
+       if (decoder->irq)
+               /* Enable / Disable lock interrupt */
+               regmap_update_bits(decoder->regmap, TVP5150_INT_ENABLE_REG_A,
+                                  TVP5150_INT_A_LOCK, int_val);
 
        return 0;
 }
@@ -1103,6 +1255,8 @@ static int tvp5150_s_routing(struct v4l2_subdev *sd,
 
 static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
 {
+       struct tvp5150 *decoder = to_tvp5150(sd);
+
        /*
         * this is for capturing 36 raw vbi lines
         * if there's a way to cut off the beginning 2 vbi lines
@@ -1112,16 +1266,18 @@ static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt
         */
 
        if (fmt->sample_format == V4L2_PIX_FMT_GREY)
-               tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70);
+               regmap_write(decoder->regmap, TVP5150_LUMA_PROC_CTL_1, 0x70);
        if (fmt->count[0] == 18 && fmt->count[1] == 18) {
-               tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00);
-               tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01);
+               regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START,
+                            0x00);
+               regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP, 0x01);
        }
        return 0;
 }
 
 static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
 {
+       struct tvp5150 *decoder = to_tvp5150(sd);
        int i;
 
        if (svbi->service_set != 0) {
@@ -1132,17 +1288,17 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
                                                0xf0, i, 3);
                }
                /* Enables FIFO */
-               tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
+               regmap_write(decoder->regmap, TVP5150_FIFO_OUT_CTRL, 1);
        } else {
                /* Disables FIFO*/
-               tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 0);
+               regmap_write(decoder->regmap, TVP5150_FIFO_OUT_CTRL, 0);
 
                /* Disable Full Field */
-               tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
+               regmap_write(decoder->regmap, TVP5150_FULL_FIELD_ENA, 0);
 
                /* Disable Line modes */
                for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
-                       tvp5150_write(sd, i, 0xff);
+                       regmap_write(decoder->regmap, i, 0xff);
        }
        return 0;
 }
@@ -1180,7 +1336,9 @@ static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
 
 static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-       return tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
+       struct tvp5150 *decoder = to_tvp5150(sd);
+
+       return regmap_write(decoder->regmap, reg->reg & 0xff, reg->val & 0xff);
 }
 #endif
 
@@ -1217,7 +1375,7 @@ static int tvp5150_registered(struct v4l2_subdev *sd)
                        return ret;
 
                ret = media_create_pad_link(input, 0, &sd->entity,
-                                           DEMOD_PAD_IF_INPUT, 0);
+                                           TVP5150_PAD_IF_INPUT, 0);
                if (ret < 0) {
                        media_device_unregister_entity(input);
                        return ret;
@@ -1249,6 +1407,8 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
 
 static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
        .s_std = tvp5150_s_std,
+       .g_std = tvp5150_g_std,
+       .querystd = tvp5150_querystd,
        .s_stream = tvp5150_s_stream,
        .s_routing = tvp5150_s_routing,
        .g_mbus_config = tvp5150_g_mbus_config,
@@ -1262,6 +1422,7 @@ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
 };
 
 static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
+       .init_cfg = tvp5150_init_cfg,
        .enum_mbus_code = tvp5150_enum_mbus_code,
        .enum_frame_size = tvp5150_enum_frame_size,
        .set_fmt = tvp5150_fill_fmt,
@@ -1282,16 +1443,87 @@ static const struct v4l2_subdev_internal_ops tvp5150_internal_ops = {
        .registered = tvp5150_registered,
 };
 
-
 /****************************************************************************
                        I2C Client & Driver
  ****************************************************************************/
 
+static const struct regmap_range tvp5150_readable_ranges[] = {
+       {
+               .range_min = TVP5150_VD_IN_SRC_SEL_1,
+               .range_max = TVP5150_AUTOSW_MSK,
+       }, {
+               .range_min = TVP5150_COLOR_KIL_THSH_CTL,
+               .range_max = TVP5150_CONF_SHARED_PIN,
+       }, {
+               .range_min = TVP5150_ACT_VD_CROP_ST_MSB,
+               .range_max = TVP5150_HORIZ_SYNC_START,
+       }, {
+               .range_min = TVP5150_VERT_BLANKING_START,
+               .range_max = TVP5150_INTT_CONFIG_REG_B,
+       }, {
+               .range_min = TVP5150_VIDEO_STD,
+               .range_max = TVP5150_VIDEO_STD,
+       }, {
+               .range_min = TVP5150_CB_GAIN_FACT,
+               .range_max = TVP5150_REV_SELECT,
+       }, {
+               .range_min = TVP5150_MSB_DEV_ID,
+               .range_max = TVP5150_STATUS_REG_5,
+       }, {
+               .range_min = TVP5150_CC_DATA_INI,
+               .range_max = TVP5150_TELETEXT_FIL_ENA,
+       }, {
+               .range_min = TVP5150_INT_STATUS_REG_A,
+               .range_max = TVP5150_FIFO_OUT_CTRL,
+       }, {
+               .range_min = TVP5150_FULL_FIELD_ENA,
+               .range_max = TVP5150_FULL_FIELD_MODE_REG,
+       },
+};
+
+static bool tvp5150_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case TVP5150_VERT_LN_COUNT_MSB:
+       case TVP5150_VERT_LN_COUNT_LSB:
+       case TVP5150_INT_STATUS_REG_A:
+       case TVP5150_INT_STATUS_REG_B:
+       case TVP5150_INT_ACTIVE_REG_B:
+       case TVP5150_STATUS_REG_1:
+       case TVP5150_STATUS_REG_2:
+       case TVP5150_STATUS_REG_3:
+       case TVP5150_STATUS_REG_4:
+       case TVP5150_STATUS_REG_5:
+       /* CC, WSS, VPS, VITC data? */
+       case TVP5150_VBI_FIFO_READ_DATA:
+       case TVP5150_VDP_STATUS_REG:
+       case TVP5150_FIFO_WORD_COUNT:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const struct regmap_access_table tvp5150_readable_table = {
+       .yes_ranges = tvp5150_readable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(tvp5150_readable_ranges),
+};
+
+static struct regmap_config tvp5150_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = 0xff,
+
+       .cache_type = REGCACHE_RBTREE,
+
+       .rd_table = &tvp5150_readable_table,
+       .volatile_reg = tvp5150_volatile_reg,
+};
+
 static int tvp5150_detect_version(struct tvp5150 *core)
 {
        struct v4l2_subdev *sd = &core->sd;
        struct i2c_client *c = v4l2_get_subdevdata(sd);
-       unsigned int i;
        u8 regs[4];
        int res;
 
@@ -1299,11 +1531,10 @@ static int tvp5150_detect_version(struct tvp5150 *core)
         * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID,
         * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER
         */
-       for (i = 0; i < 4; i++) {
-               res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
-               if (res < 0)
-                       return res;
-               regs[i] = res;
+       res = regmap_bulk_read(core->regmap, TVP5150_MSB_DEV_ID, regs, 4);
+       if (res < 0) {
+               dev_err(&c->dev, "reading ID registers failed: %d\n", res);
+               return res;
        }
 
        core->dev_id = (regs[0] << 8) | regs[1];
@@ -1319,7 +1550,7 @@ static int tvp5150_detect_version(struct tvp5150 *core)
                dev_info(sd->dev, "tvp5150am1 detected.\n");
 
                /* ITU-T BT.656.4 timing */
-               tvp5150_write(sd, TVP5150_REV_SELECT, 0);
+               regmap_write(core->regmap, TVP5150_REV_SELECT, 0);
        } else if (core->dev_id == 0x5151 && core->rom_ver == 0x0100) {
                dev_info(sd->dev, "tvp5151 detected.\n");
        } else {
@@ -1362,7 +1593,7 @@ static int tvp5150_init(struct i2c_client *c)
 
 static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
 {
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct device_node *ep;
 #ifdef CONFIG_MEDIA_CONTROLLER
        struct device_node *connectors, *child;
@@ -1403,8 +1634,8 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
                ret = of_property_read_u32(child, "input", &input_type);
                if (ret) {
                        dev_err(decoder->sd.dev,
-                                "missing type property in node %s\n",
-                                child->name);
+                                "missing type property in node %pOFn\n",
+                                child);
                        goto err_connector;
                }
 
@@ -1439,8 +1670,8 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
                ret = of_property_read_string(child, "label", &name);
                if (ret < 0) {
                        dev_err(decoder->sd.dev,
-                                "missing label property in node %s\n",
-                                child->name);
+                                "missing label property in node %pOFn\n",
+                                child);
                        goto err_connector;
                }
 
@@ -1466,6 +1697,7 @@ static int tvp5150_probe(struct i2c_client *c,
        struct tvp5150 *core;
        struct v4l2_subdev *sd;
        struct device_node *np = c->dev.of_node;
+       struct regmap *map;
        int res;
 
        /* Check if the adapter supports the needed features */
@@ -1481,6 +1713,11 @@ static int tvp5150_probe(struct i2c_client *c,
        if (!core)
                return -ENOMEM;
 
+       map = devm_regmap_init_i2c(c, &tvp5150_config);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
+
+       core->regmap = map;
        sd = &core->sd;
 
        if (IS_ENABLED(CONFIG_OF) && np) {
@@ -1499,13 +1736,14 @@ static int tvp5150_probe(struct i2c_client *c,
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
-       core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       core->pads[TVP5150_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       core->pads[TVP5150_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
+       core->pads[TVP5150_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       core->pads[TVP5150_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
 
        sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
 
-       res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
+       res = media_entity_pads_init(&sd->entity, TVP5150_NUM_PADS, core->pads);
        if (res < 0)
                return res;
 
@@ -1517,6 +1755,7 @@ static int tvp5150_probe(struct i2c_client *c,
                return res;
 
        core->norm = V4L2_STD_ALL;      /* Default is autodetect */
+       core->detected_norm = V4L2_STD_UNKNOWN;
        core->input = TVP5150_COMPOSITE1;
        core->enable = true;
 
@@ -1534,7 +1773,7 @@ static int tvp5150_probe(struct i2c_client *c,
                        27000000, 1, 27000000);
        v4l2_ctrl_new_std_menu_items(&core->hdl, &tvp5150_ctrl_ops,
                                     V4L2_CID_TEST_PATTERN,
-                                    ARRAY_SIZE(tvp5150_test_patterns),
+                                    ARRAY_SIZE(tvp5150_test_patterns) - 1,
                                     0, 0, tvp5150_test_patterns);
        sd->ctrl_handler = &core->hdl;
        if (core->hdl.error) {
@@ -1542,16 +1781,17 @@ static int tvp5150_probe(struct i2c_client *c,
                goto err;
        }
 
-       /* Default is no cropping */
-       core->rect.top = 0;
-       if (tvp5150_read_std(sd) & V4L2_STD_525_60)
-               core->rect.height = TVP5150_V_MAX_525_60;
-       else
-               core->rect.height = TVP5150_V_MAX_OTHERS;
-       core->rect.left = 0;
-       core->rect.width = TVP5150_H_MAX;
+       tvp5150_set_default(tvp5150_read_std(sd), &core->rect);
 
+       core->irq = c->irq;
        tvp5150_reset(sd, 0);   /* Calls v4l2_ctrl_handler_setup() */
+       if (c->irq) {
+               res = devm_request_threaded_irq(&c->dev, c->irq, NULL,
+                                               tvp5150_isr, IRQF_TRIGGER_HIGH |
+                                               IRQF_ONESHOT, "tvp5150", core);
+               if (res)
+                       return res;
+       }
 
        res = v4l2_async_register_subdev(sd);
        if (res < 0)
index d3a764cae1a04dcb514026bbf7b5dafbc12887e1..9088186c24d15cd3800984f1cb57573401d0f571 100644 (file)
 #define TVP5150_TELETEXT_FIL_ENA    0xbb /* Teletext filter enable */
 /* Reserved    BCh-BFh */
 #define TVP5150_INT_STATUS_REG_A    0xc0 /* Interrupt status register A */
+#define   TVP5150_INT_A_LOCK_STATUS BIT(7)
+#define   TVP5150_INT_A_LOCK        BIT(6)
 #define TVP5150_INT_ENABLE_REG_A    0xc1 /* Interrupt enable register A */
 #define TVP5150_INT_CONF            0xc2 /* Interrupt configuration */
+#define   TVP5150_VDPOE             BIT(2)
 #define TVP5150_VDP_CONF_RAM_DATA   0xc3 /* VDP configuration RAM data */
 #define TVP5150_CONF_RAM_ADDR_LOW   0xc4 /* Configuration RAM address low byte */
 #define TVP5150_CONF_RAM_ADDR_HIGH  0xc5 /* Configuration RAM address high byte */
index 4f5c627579c75566a5cb532a90bdce8954da1bcb..cab2f2bd0aa9910c78fbbdfd7b54b689f3d4359e 100644 (file)
@@ -889,7 +889,7 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
 static struct tvp7002_config *
 tvp7002_get_pdata(struct i2c_client *client)
 {
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
        struct tvp7002_config *pdata = NULL;
        struct device_node *endpoint;
        unsigned int flags;
index 06d29d8f6be8ed8e7cb7c7418c58643e6a9eda58..4d49af86c15ee4a21b6f2e58d51dac4de6a6ddb9 100644 (file)
@@ -352,8 +352,8 @@ static int video_i2c_querycap(struct file *file, void  *priv,
        struct video_i2c_data *data = video_drvdata(file);
        struct i2c_client *client = data->client;
 
-       strlcpy(vcap->driver, data->v4l2_dev.name, sizeof(vcap->driver));
-       strlcpy(vcap->card, data->vdev.name, sizeof(vcap->card));
+       strscpy(vcap->driver, data->v4l2_dev.name, sizeof(vcap->driver));
+       strscpy(vcap->card, data->vdev.name, sizeof(vcap->card));
 
        sprintf(vcap->bus_info, "I2C:%d-%d", client->adapter->nr, client->addr);
 
@@ -378,7 +378,7 @@ static int video_i2c_enum_input(struct file *file, void *fh,
        if (vin->index > 0)
                return -EINVAL;
 
-       strlcpy(vin->name, "Camera", sizeof(vin->name));
+       strscpy(vin->name, "Camera", sizeof(vin->name));
 
        vin->type = V4L2_INPUT_TYPE_CAMERA;
 
@@ -534,7 +534,7 @@ static int video_i2c_probe(struct i2c_client *client,
 
        data->client = client;
        v4l2_dev = &data->v4l2_dev;
-       strlcpy(v4l2_dev->name, VIDEO_I2C_DRIVER, sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, VIDEO_I2C_DRIVER, sizeof(v4l2_dev->name));
 
        ret = v4l2_device_register(&client->dev, v4l2_dev);
        if (ret < 0)
index 3bae24b15eaa4cbd5e25485121e50ddcb5991af2..bed24372e61fcd8c8f588321ceb4243b457afc88 100644 (file)
@@ -30,6 +30,7 @@
 #include <media/media-device.h>
 #include <media/media-devnode.h>
 #include <media/media-entity.h>
+#include <media/media-request.h>
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
@@ -69,14 +70,14 @@ static long media_device_get_info(struct media_device *dev, void *arg)
        memset(info, 0, sizeof(*info));
 
        if (dev->driver_name[0])
-               strlcpy(info->driver, dev->driver_name, sizeof(info->driver));
+               strscpy(info->driver, dev->driver_name, sizeof(info->driver));
        else
-               strlcpy(info->driver, dev->dev->driver->name,
+               strscpy(info->driver, dev->dev->driver->name,
                        sizeof(info->driver));
 
-       strlcpy(info->model, dev->model, sizeof(info->model));
-       strlcpy(info->serial, dev->serial, sizeof(info->serial));
-       strlcpy(info->bus_info, dev->bus_info, sizeof(info->bus_info));
+       strscpy(info->model, dev->model, sizeof(info->model));
+       strscpy(info->serial, dev->serial, sizeof(info->serial));
+       strscpy(info->bus_info, dev->bus_info, sizeof(info->bus_info));
 
        info->media_version = LINUX_VERSION_CODE;
        info->driver_version = info->media_version;
@@ -115,7 +116,7 @@ static long media_device_enum_entities(struct media_device *mdev, void *arg)
 
        entd->id = media_entity_id(ent);
        if (ent->name)
-               strlcpy(entd->name, ent->name, sizeof(entd->name));
+               strscpy(entd->name, ent->name, sizeof(entd->name));
        entd->type = ent->function;
        entd->revision = 0;             /* Unused */
        entd->flags = ent->flags;
@@ -268,7 +269,7 @@ static long media_device_get_topology(struct media_device *mdev, void *arg)
                kentity.id = entity->graph_obj.id;
                kentity.function = entity->function;
                kentity.flags = entity->flags;
-               strlcpy(kentity.name, entity->name,
+               strscpy(kentity.name, entity->name,
                        sizeof(kentity.name));
 
                if (copy_to_user(uentity, &kentity, sizeof(kentity)))
@@ -377,10 +378,19 @@ static long media_device_get_topology(struct media_device *mdev, void *arg)
        return ret;
 }
 
+static long media_device_request_alloc(struct media_device *mdev,
+                                      int *alloc_fd)
+{
+       if (!mdev->ops || !mdev->ops->req_validate || !mdev->ops->req_queue)
+               return -ENOTTY;
+
+       return media_request_alloc(mdev, alloc_fd);
+}
+
 static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
 {
-       /* All media IOCTLs are _IOWR() */
-       if (copy_from_user(karg, uarg, _IOC_SIZE(cmd)))
+       if ((_IOC_DIR(cmd) & _IOC_WRITE) &&
+           copy_from_user(karg, uarg, _IOC_SIZE(cmd)))
                return -EFAULT;
 
        return 0;
@@ -388,8 +398,8 @@ static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
 
 static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd)
 {
-       /* All media IOCTLs are _IOWR() */
-       if (copy_to_user(uarg, karg, _IOC_SIZE(cmd)))
+       if ((_IOC_DIR(cmd) & _IOC_READ) &&
+           copy_to_user(uarg, karg, _IOC_SIZE(cmd)))
                return -EFAULT;
 
        return 0;
@@ -425,6 +435,7 @@ static const struct media_ioctl_info ioctl_info[] = {
        MEDIA_IOC(ENUM_LINKS, media_device_enum_links, MEDIA_IOC_FL_GRAPH_MUTEX),
        MEDIA_IOC(SETUP_LINK, media_device_setup_link, MEDIA_IOC_FL_GRAPH_MUTEX),
        MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX),
+       MEDIA_IOC(REQUEST_ALLOC, media_device_request_alloc, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
@@ -691,9 +702,13 @@ void media_device_init(struct media_device *mdev)
        INIT_LIST_HEAD(&mdev->pads);
        INIT_LIST_HEAD(&mdev->links);
        INIT_LIST_HEAD(&mdev->entity_notify);
+
+       mutex_init(&mdev->req_queue_mutex);
        mutex_init(&mdev->graph_mutex);
        ida_init(&mdev->entity_internal_idx);
 
+       atomic_set(&mdev->request_id, 0);
+
        dev_dbg(mdev->dev, "Media device initialized\n");
 }
 EXPORT_SYMBOL_GPL(media_device_init);
@@ -704,6 +719,7 @@ void media_device_cleanup(struct media_device *mdev)
        mdev->entity_internal_idx_max = 0;
        media_graph_walk_cleanup(&mdev->pm_count_walk);
        mutex_destroy(&mdev->graph_mutex);
+       mutex_destroy(&mdev->req_queue_mutex);
 }
 EXPORT_SYMBOL_GPL(media_device_cleanup);
 
@@ -836,9 +852,9 @@ void media_device_pci_init(struct media_device *mdev,
        mdev->dev = &pci_dev->dev;
 
        if (name)
-               strlcpy(mdev->model, name, sizeof(mdev->model));
+               strscpy(mdev->model, name, sizeof(mdev->model));
        else
-               strlcpy(mdev->model, pci_name(pci_dev), sizeof(mdev->model));
+               strscpy(mdev->model, pci_name(pci_dev), sizeof(mdev->model));
 
        sprintf(mdev->bus_info, "PCI:%s", pci_name(pci_dev));
 
@@ -859,17 +875,17 @@ void __media_device_usb_init(struct media_device *mdev,
        mdev->dev = &udev->dev;
 
        if (driver_name)
-               strlcpy(mdev->driver_name, driver_name,
+               strscpy(mdev->driver_name, driver_name,
                        sizeof(mdev->driver_name));
 
        if (board_name)
-               strlcpy(mdev->model, board_name, sizeof(mdev->model));
+               strscpy(mdev->model, board_name, sizeof(mdev->model));
        else if (udev->product)
-               strlcpy(mdev->model, udev->product, sizeof(mdev->model));
+               strscpy(mdev->model, udev->product, sizeof(mdev->model));
        else
-               strlcpy(mdev->model, "unknown model", sizeof(mdev->model));
+               strscpy(mdev->model, "unknown model", sizeof(mdev->model));
        if (udev->serial)
-               strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
+               strscpy(mdev->serial, udev->serial, sizeof(mdev->serial));
        usb_make_path(udev, mdev->bus_info, sizeof(mdev->bus_info));
        mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
 
index 3498551e618e543799e42ecfff441a597ede5967..0b1cb3559140a1fee04af77890f8dd1131b0f484 100644 (file)
@@ -662,6 +662,32 @@ static void __media_entity_remove_link(struct media_entity *entity,
        kfree(link);
 }
 
+int media_get_pad_index(struct media_entity *entity, bool is_sink,
+                       enum media_pad_signal_type sig_type)
+{
+       int i;
+       bool pad_is_sink;
+
+       if (!entity)
+               return -EINVAL;
+
+       for (i = 0; i < entity->num_pads; i++) {
+               if (entity->pads[i].flags == MEDIA_PAD_FL_SINK)
+                       pad_is_sink = true;
+               else if (entity->pads[i].flags == MEDIA_PAD_FL_SOURCE)
+                       pad_is_sink = false;
+               else
+                       continue;       /* This is an error! */
+
+               if (pad_is_sink != is_sink)
+                       continue;
+               if (entity->pads[i].sig_type == sig_type)
+                       return i;
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(media_get_pad_index);
+
 int
 media_create_pad_link(struct media_entity *source, u16 source_pad,
                         struct media_entity *sink, u16 sink_pad, u32 flags)
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c
new file mode 100644 (file)
index 0000000..4e9db1f
--- /dev/null
@@ -0,0 +1,501 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Media device request objects
+ *
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 Google, Inc.
+ *
+ * Author: Hans Verkuil <hans.verkuil@cisco.com>
+ * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
+ */
+
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/refcount.h>
+
+#include <media/media-device.h>
+#include <media/media-request.h>
+
+static const char * const request_state[] = {
+       [MEDIA_REQUEST_STATE_IDLE]       = "idle",
+       [MEDIA_REQUEST_STATE_VALIDATING] = "validating",
+       [MEDIA_REQUEST_STATE_QUEUED]     = "queued",
+       [MEDIA_REQUEST_STATE_COMPLETE]   = "complete",
+       [MEDIA_REQUEST_STATE_CLEANING]   = "cleaning",
+       [MEDIA_REQUEST_STATE_UPDATING]   = "updating",
+};
+
+static const char *
+media_request_state_str(enum media_request_state state)
+{
+       BUILD_BUG_ON(ARRAY_SIZE(request_state) != NR_OF_MEDIA_REQUEST_STATE);
+
+       if (WARN_ON(state >= ARRAY_SIZE(request_state)))
+               return "invalid";
+       return request_state[state];
+}
+
+static void media_request_clean(struct media_request *req)
+{
+       struct media_request_object *obj, *obj_safe;
+
+       /* Just a sanity check. No other code path is allowed to change this. */
+       WARN_ON(req->state != MEDIA_REQUEST_STATE_CLEANING);
+       WARN_ON(req->updating_count);
+       WARN_ON(req->access_count);
+
+       list_for_each_entry_safe(obj, obj_safe, &req->objects, list) {
+               media_request_object_unbind(obj);
+               media_request_object_put(obj);
+       }
+
+       req->updating_count = 0;
+       req->access_count = 0;
+       WARN_ON(req->num_incomplete_objects);
+       req->num_incomplete_objects = 0;
+       wake_up_interruptible_all(&req->poll_wait);
+}
+
+static void media_request_release(struct kref *kref)
+{
+       struct media_request *req =
+               container_of(kref, struct media_request, kref);
+       struct media_device *mdev = req->mdev;
+
+       dev_dbg(mdev->dev, "request: release %s\n", req->debug_str);
+
+       /* No other users, no need for a spinlock */
+       req->state = MEDIA_REQUEST_STATE_CLEANING;
+
+       media_request_clean(req);
+
+       if (mdev->ops->req_free)
+               mdev->ops->req_free(req);
+       else
+               kfree(req);
+}
+
+void media_request_put(struct media_request *req)
+{
+       kref_put(&req->kref, media_request_release);
+}
+EXPORT_SYMBOL_GPL(media_request_put);
+
+static int media_request_close(struct inode *inode, struct file *filp)
+{
+       struct media_request *req = filp->private_data;
+
+       media_request_put(req);
+       return 0;
+}
+
+static __poll_t media_request_poll(struct file *filp,
+                                  struct poll_table_struct *wait)
+{
+       struct media_request *req = filp->private_data;
+       unsigned long flags;
+       __poll_t ret = 0;
+
+       if (!(poll_requested_events(wait) & EPOLLPRI))
+               return 0;
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (req->state == MEDIA_REQUEST_STATE_COMPLETE) {
+               ret = EPOLLPRI;
+               goto unlock;
+       }
+       if (req->state != MEDIA_REQUEST_STATE_QUEUED) {
+               ret = EPOLLERR;
+               goto unlock;
+       }
+
+       poll_wait(filp, &req->poll_wait, wait);
+
+unlock:
+       spin_unlock_irqrestore(&req->lock, flags);
+       return ret;
+}
+
+static long media_request_ioctl_queue(struct media_request *req)
+{
+       struct media_device *mdev = req->mdev;
+       enum media_request_state state;
+       unsigned long flags;
+       int ret;
+
+       dev_dbg(mdev->dev, "request: queue %s\n", req->debug_str);
+
+       /*
+        * Ensure the request that is validated will be the one that gets queued
+        * next by serialising the queueing process. This mutex is also used
+        * to serialize with canceling a vb2 queue and with setting values such
+        * as controls in a request.
+        */
+       mutex_lock(&mdev->req_queue_mutex);
+
+       media_request_get(req);
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (req->state == MEDIA_REQUEST_STATE_IDLE)
+               req->state = MEDIA_REQUEST_STATE_VALIDATING;
+       state = req->state;
+       spin_unlock_irqrestore(&req->lock, flags);
+       if (state != MEDIA_REQUEST_STATE_VALIDATING) {
+               dev_dbg(mdev->dev,
+                       "request: unable to queue %s, request in state %s\n",
+                       req->debug_str, media_request_state_str(state));
+               media_request_put(req);
+               mutex_unlock(&mdev->req_queue_mutex);
+               return -EBUSY;
+       }
+
+       ret = mdev->ops->req_validate(req);
+
+       /*
+        * If the req_validate was successful, then we mark the state as QUEUED
+        * and call req_queue. The reason we set the state first is that this
+        * allows req_queue to unbind or complete the queued objects in case
+        * they are immediately 'consumed'. State changes from QUEUED to another
+        * state can only happen if either the driver changes the state or if
+        * the user cancels the vb2 queue. The driver can only change the state
+        * after each object is queued through the req_queue op (and note that
+        * that op cannot fail), so setting the state to QUEUED up front is
+        * safe.
+        *
+        * The other reason for changing the state is if the vb2 queue is
+        * canceled, and that uses the req_queue_mutex which is still locked
+        * while req_queue is called, so that's safe as well.
+        */
+       spin_lock_irqsave(&req->lock, flags);
+       req->state = ret ? MEDIA_REQUEST_STATE_IDLE
+                        : MEDIA_REQUEST_STATE_QUEUED;
+       spin_unlock_irqrestore(&req->lock, flags);
+
+       if (!ret)
+               mdev->ops->req_queue(req);
+
+       mutex_unlock(&mdev->req_queue_mutex);
+
+       if (ret) {
+               dev_dbg(mdev->dev, "request: can't queue %s (%d)\n",
+                       req->debug_str, ret);
+               media_request_put(req);
+       }
+
+       return ret;
+}
+
+static long media_request_ioctl_reinit(struct media_request *req)
+{
+       struct media_device *mdev = req->mdev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (req->state != MEDIA_REQUEST_STATE_IDLE &&
+           req->state != MEDIA_REQUEST_STATE_COMPLETE) {
+               dev_dbg(mdev->dev,
+                       "request: %s not in idle or complete state, cannot reinit\n",
+                       req->debug_str);
+               spin_unlock_irqrestore(&req->lock, flags);
+               return -EBUSY;
+       }
+       if (req->access_count) {
+               dev_dbg(mdev->dev,
+                       "request: %s is being accessed, cannot reinit\n",
+                       req->debug_str);
+               spin_unlock_irqrestore(&req->lock, flags);
+               return -EBUSY;
+       }
+       req->state = MEDIA_REQUEST_STATE_CLEANING;
+       spin_unlock_irqrestore(&req->lock, flags);
+
+       media_request_clean(req);
+
+       spin_lock_irqsave(&req->lock, flags);
+       req->state = MEDIA_REQUEST_STATE_IDLE;
+       spin_unlock_irqrestore(&req->lock, flags);
+
+       return 0;
+}
+
+static long media_request_ioctl(struct file *filp, unsigned int cmd,
+                               unsigned long arg)
+{
+       struct media_request *req = filp->private_data;
+
+       switch (cmd) {
+       case MEDIA_REQUEST_IOC_QUEUE:
+               return media_request_ioctl_queue(req);
+       case MEDIA_REQUEST_IOC_REINIT:
+               return media_request_ioctl_reinit(req);
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+static const struct file_operations request_fops = {
+       .owner = THIS_MODULE,
+       .poll = media_request_poll,
+       .unlocked_ioctl = media_request_ioctl,
+       .release = media_request_close,
+};
+
+struct media_request *
+media_request_get_by_fd(struct media_device *mdev, int request_fd)
+{
+       struct file *filp;
+       struct media_request *req;
+
+       if (!mdev || !mdev->ops ||
+           !mdev->ops->req_validate || !mdev->ops->req_queue)
+               return ERR_PTR(-EACCES);
+
+       filp = fget(request_fd);
+       if (!filp)
+               goto err_no_req_fd;
+
+       if (filp->f_op != &request_fops)
+               goto err_fput;
+       req = filp->private_data;
+       if (req->mdev != mdev)
+               goto err_fput;
+
+       /*
+        * Note: as long as someone has an open filehandle of the request,
+        * the request can never be released. The fget() above ensures that
+        * even if userspace closes the request filehandle, the release()
+        * fop won't be called, so the media_request_get() always succeeds
+        * and there is no race condition where the request was released
+        * before media_request_get() is called.
+        */
+       media_request_get(req);
+       fput(filp);
+
+       return req;
+
+err_fput:
+       fput(filp);
+
+err_no_req_fd:
+       dev_dbg(mdev->dev, "cannot find request_fd %d\n", request_fd);
+       return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(media_request_get_by_fd);
+
+int media_request_alloc(struct media_device *mdev, int *alloc_fd)
+{
+       struct media_request *req;
+       struct file *filp;
+       int fd;
+       int ret;
+
+       /* Either both are NULL or both are non-NULL */
+       if (WARN_ON(!mdev->ops->req_alloc ^ !mdev->ops->req_free))
+               return -ENOMEM;
+
+       fd = get_unused_fd_flags(O_CLOEXEC);
+       if (fd < 0)
+               return fd;
+
+       filp = anon_inode_getfile("request", &request_fops, NULL, O_CLOEXEC);
+       if (IS_ERR(filp)) {
+               ret = PTR_ERR(filp);
+               goto err_put_fd;
+       }
+
+       if (mdev->ops->req_alloc)
+               req = mdev->ops->req_alloc(mdev);
+       else
+               req = kzalloc(sizeof(*req), GFP_KERNEL);
+       if (!req) {
+               ret = -ENOMEM;
+               goto err_fput;
+       }
+
+       filp->private_data = req;
+       req->mdev = mdev;
+       req->state = MEDIA_REQUEST_STATE_IDLE;
+       req->num_incomplete_objects = 0;
+       kref_init(&req->kref);
+       INIT_LIST_HEAD(&req->objects);
+       spin_lock_init(&req->lock);
+       init_waitqueue_head(&req->poll_wait);
+       req->updating_count = 0;
+       req->access_count = 0;
+
+       *alloc_fd = fd;
+
+       snprintf(req->debug_str, sizeof(req->debug_str), "%u:%d",
+                atomic_inc_return(&mdev->request_id), fd);
+       dev_dbg(mdev->dev, "request: allocated %s\n", req->debug_str);
+
+       fd_install(fd, filp);
+
+       return 0;
+
+err_fput:
+       fput(filp);
+
+err_put_fd:
+       put_unused_fd(fd);
+
+       return ret;
+}
+
+static void media_request_object_release(struct kref *kref)
+{
+       struct media_request_object *obj =
+               container_of(kref, struct media_request_object, kref);
+       struct media_request *req = obj->req;
+
+       if (WARN_ON(req))
+               media_request_object_unbind(obj);
+       obj->ops->release(obj);
+}
+
+struct media_request_object *
+media_request_object_find(struct media_request *req,
+                         const struct media_request_object_ops *ops,
+                         void *priv)
+{
+       struct media_request_object *obj;
+       struct media_request_object *found = NULL;
+       unsigned long flags;
+
+       if (WARN_ON(!ops || !priv))
+               return NULL;
+
+       spin_lock_irqsave(&req->lock, flags);
+       list_for_each_entry(obj, &req->objects, list) {
+               if (obj->ops == ops && obj->priv == priv) {
+                       media_request_object_get(obj);
+                       found = obj;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&req->lock, flags);
+       return found;
+}
+EXPORT_SYMBOL_GPL(media_request_object_find);
+
+void media_request_object_put(struct media_request_object *obj)
+{
+       kref_put(&obj->kref, media_request_object_release);
+}
+EXPORT_SYMBOL_GPL(media_request_object_put);
+
+void media_request_object_init(struct media_request_object *obj)
+{
+       obj->ops = NULL;
+       obj->req = NULL;
+       obj->priv = NULL;
+       obj->completed = false;
+       INIT_LIST_HEAD(&obj->list);
+       kref_init(&obj->kref);
+}
+EXPORT_SYMBOL_GPL(media_request_object_init);
+
+int media_request_object_bind(struct media_request *req,
+                             const struct media_request_object_ops *ops,
+                             void *priv, bool is_buffer,
+                             struct media_request_object *obj)
+{
+       unsigned long flags;
+       int ret = -EBUSY;
+
+       if (WARN_ON(!ops->release))
+               return -EACCES;
+
+       spin_lock_irqsave(&req->lock, flags);
+
+       if (WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING))
+               goto unlock;
+
+       obj->req = req;
+       obj->ops = ops;
+       obj->priv = priv;
+
+       if (is_buffer)
+               list_add_tail(&obj->list, &req->objects);
+       else
+               list_add(&obj->list, &req->objects);
+       req->num_incomplete_objects++;
+       ret = 0;
+
+unlock:
+       spin_unlock_irqrestore(&req->lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(media_request_object_bind);
+
+void media_request_object_unbind(struct media_request_object *obj)
+{
+       struct media_request *req = obj->req;
+       unsigned long flags;
+       bool completed = false;
+
+       if (WARN_ON(!req))
+               return;
+
+       spin_lock_irqsave(&req->lock, flags);
+       list_del(&obj->list);
+       obj->req = NULL;
+
+       if (req->state == MEDIA_REQUEST_STATE_COMPLETE)
+               goto unlock;
+
+       if (WARN_ON(req->state == MEDIA_REQUEST_STATE_VALIDATING))
+               goto unlock;
+
+       if (req->state == MEDIA_REQUEST_STATE_CLEANING) {
+               if (!obj->completed)
+                       req->num_incomplete_objects--;
+               goto unlock;
+       }
+
+       if (WARN_ON(!req->num_incomplete_objects))
+               goto unlock;
+
+       req->num_incomplete_objects--;
+       if (req->state == MEDIA_REQUEST_STATE_QUEUED &&
+           !req->num_incomplete_objects) {
+               req->state = MEDIA_REQUEST_STATE_COMPLETE;
+               completed = true;
+               wake_up_interruptible_all(&req->poll_wait);
+       }
+
+unlock:
+       spin_unlock_irqrestore(&req->lock, flags);
+       if (obj->ops->unbind)
+               obj->ops->unbind(obj);
+       if (completed)
+               media_request_put(req);
+}
+EXPORT_SYMBOL_GPL(media_request_object_unbind);
+
+void media_request_object_complete(struct media_request_object *obj)
+{
+       struct media_request *req = obj->req;
+       unsigned long flags;
+       bool completed = false;
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (obj->completed)
+               goto unlock;
+       obj->completed = true;
+       if (WARN_ON(!req->num_incomplete_objects) ||
+           WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
+               goto unlock;
+
+       if (!--req->num_incomplete_objects) {
+               req->state = MEDIA_REQUEST_STATE_COMPLETE;
+               wake_up_interruptible_all(&req->poll_wait);
+               completed = true;
+       }
+unlock:
+       spin_unlock_irqrestore(&req->lock, flags);
+       if (completed)
+               media_request_put(req);
+}
+EXPORT_SYMBOL_GPL(media_request_object_complete);
index cf05e11da01b06c71bccbd17e080d806709cbd06..d4906c04dc6eeddc56e270842d48a166057abad3 100644 (file)
@@ -2040,7 +2040,6 @@ limit_scaled_size_lock       (struct bttv_fh *               fh,
        max_width = max_width & width_mask;
 
        /* Max. scale factor is 16:1 for frames, 8:1 for fields. */
-       min_height = min_height;
        /* Min. scale factor is 1:1. */
        max_height >>= !V4L2_FIELD_HAS_BOTH(field);
 
@@ -2473,8 +2472,8 @@ static int bttv_querycap(struct file *file, void  *priv,
        if (0 == v4l2)
                return -EINVAL;
 
-       strlcpy(cap->driver, "bttv", sizeof(cap->driver));
-       strlcpy(cap->card, btv->video_dev.name, sizeof(cap->card));
+       strscpy(cap->driver, "bttv", sizeof(cap->driver));
+       strscpy(cap->card, btv->video_dev.name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "PCI:%s", pci_name(btv->c.pci));
        cap->capabilities =
@@ -2535,7 +2534,7 @@ static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f)
                return -EINVAL;
 
        f->pixelformat = formats[i].fourcc;
-       strlcpy(f->description, formats[i].name, sizeof(f->description));
+       strscpy(f->description, formats[i].name, sizeof(f->description));
 
        return i;
 }
@@ -2782,7 +2781,7 @@ static int bttv_g_tuner(struct file *file, void *priv,
        t->rxsubchans = V4L2_TUNER_SUB_MONO;
        t->capability = V4L2_TUNER_CAP_NORM;
        bttv_call_all(btv, tuner, g_tuner, t);
-       strcpy(t->name, "Television");
+       strscpy(t->name, "Television", sizeof(t->name));
        t->type       = V4L2_TUNER_ANALOG_TV;
        if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
                t->signal = 0xffff;
@@ -3257,7 +3256,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
 
        if (0 != t->index)
                return -EINVAL;
-       strcpy(t->name, "Radio");
+       strscpy(t->name, "Radio", sizeof(t->name));
        t->type = V4L2_TUNER_RADIO;
        radio_enable(btv);
 
@@ -4211,7 +4210,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
        /* register video4linux + input */
        if (!bttv_tvcards[btv->c.type].no_video) {
                v4l2_ctrl_add_handler(&btv->radio_ctrl_handler, hdl,
-                               v4l2_ctrl_radio_filter);
+                               v4l2_ctrl_radio_filter, false);
                if (btv->radio_ctrl_handler.error) {
                        result = btv->radio_ctrl_handler.error;
                        goto fail2;
index c76823eb399dca1e1a0ceacf15ad60c10d27613a..15ff7f9d8373822fccd33e6cb842d29d2f527f90 100644 (file)
@@ -347,13 +347,13 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
 /* init + register i2c adapter */
 int init_bttv_i2c(struct bttv *btv)
 {
-       strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);
+       strscpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);
 
        if (i2c_hw)
                btv->use_i2c_hw = 1;
        if (btv->use_i2c_hw) {
                /* bt878 */
-               strlcpy(btv->c.i2c_adap.name, "bt878",
+               strscpy(btv->c.i2c_adap.name, "bt878",
                        sizeof(btv->c.i2c_adap.name));
                btv->c.i2c_adap.algo = &bttv_algo;
        } else {
@@ -362,7 +362,7 @@ int init_bttv_i2c(struct bttv *btv)
                if (i2c_udelay<5)
                        i2c_udelay=5;
 
-               strlcpy(btv->c.i2c_adap.name, "bttv",
+               strscpy(btv->c.i2c_adap.name, "bttv",
                        sizeof(btv->c.i2c_adap.name));
                btv->i2c_algo = bttv_i2c_algo_bit_template;
                btv->i2c_algo.udelay = i2c_udelay;
index 08266b23826e10418a0d0a91a0603199f0d7124c..d34fbaa027c2348ced8a82b92c318bdc7b615258 100644 (file)
@@ -370,7 +370,7 @@ static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol,
 /* Instantiate the I2C IR receiver device, if present */
 void init_bttv_i2c_ir(struct bttv *btv)
 {
-       const unsigned short addr_list[] = {
+       static const unsigned short addr_list[] = {
                0x1a, 0x18, 0x64, 0x30, 0x71,
                I2C_CLIENT_END
        };
@@ -382,7 +382,7 @@ void init_bttv_i2c_ir(struct bttv *btv)
 
        memset(&info, 0, sizeof(struct i2c_board_info));
        memset(&btv->init_data, 0, sizeof(btv->init_data));
-       strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+       strscpy(info.type, "ir_video", I2C_NAME_SIZE);
 
        switch (btv->c.type) {
        case BTTV_BOARD_PV951:
index 2f810b7130e6cec0c961a1e47cabb5cbac31a34f..b46fbe557dd93f775afb490319732b08cf430a74 100644 (file)
@@ -819,7 +819,8 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
 
        mutex_init(&card->lock);
        card->bttv_nr = sub->core->nr;
-       strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
+       strscpy(card->card_name, sub->core->v4l2_dev.name,
+               sizeof(card->card_name));
        card->i2c_adapter = &sub->core->i2c_adap;
 
        switch(sub->core->type) {
index e5022b620856192f302514c87920a5b75bdb80a9..c57f87a68269087673b23533bbbbbf1432ddf3d4 100644 (file)
@@ -65,7 +65,7 @@ static int snd_cobalt_card_set_names(struct snd_cobalt_card *cobsc)
        struct snd_card *sc = cobsc->sc;
 
        /* sc->driver is used by alsa-lib's configurator: simple, unique */
-       strlcpy(sc->driver, "cobalt", sizeof(sc->driver));
+       strscpy(sc->driver, "cobalt", sizeof(sc->driver));
 
        /* sc->shortname is a symlink in /proc/asound: COBALT-M -> cardN */
        snprintf(sc->shortname,  sizeof(sc->shortname), "cobalt-%d-%d",
index f6a7df13cd048a4ee0fa5015d7fbb953ff4d154a..38d00935a2927220bede32e2ec04cb52b411cb46 100644 (file)
@@ -557,7 +557,7 @@ int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
                                &snd_cobalt_pcm_capture_ops);
                sp->info_flags = 0;
                sp->private_data = cobsc;
-               strlcpy(sp->name, "cobalt", sizeof(sp->name));
+               strscpy(sp->name, "cobalt", sizeof(sp->name));
        } else {
                cobalt_s_bit_sysctrl(cobalt,
                        COBALT_SYS_CTRL_AUDIO_OPP_RESETN_BIT, 0);
@@ -581,7 +581,7 @@ int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
                                &snd_cobalt_pcm_playback_ops);
                sp->info_flags = 0;
                sp->private_data = cobsc;
-               strlcpy(sp->name, "cobalt", sizeof(sp->name));
+               strscpy(sp->name, "cobalt", sizeof(sp->name));
        }
 
        return 0;
index e2a4c705d35392db5c2308a9807e1d7ea9b29966..0525f5e1565b3187758a45e457f47d22ebc29771 100644 (file)
@@ -479,8 +479,8 @@ static int cobalt_querycap(struct file *file, void *priv_fh,
        struct cobalt_stream *s = video_drvdata(file);
        struct cobalt *cobalt = s->cobalt;
 
-       strlcpy(vcap->driver, "cobalt", sizeof(vcap->driver));
-       strlcpy(vcap->card, "cobalt", sizeof(vcap->card));
+       strscpy(vcap->driver, "cobalt", sizeof(vcap->driver));
+       strscpy(vcap->card, "cobalt", sizeof(vcap->card));
        snprintf(vcap->bus_info, sizeof(vcap->bus_info),
                 "PCIe:%s", pci_name(cobalt->pci_dev));
        vcap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
@@ -693,15 +693,15 @@ static int cobalt_enum_fmt_vid_cap(struct file *file, void *priv_fh,
 {
        switch (f->index) {
        case 0:
-               strlcpy(f->description, "YUV 4:2:2", sizeof(f->description));
+               strscpy(f->description, "YUV 4:2:2", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_YUYV;
                break;
        case 1:
-               strlcpy(f->description, "RGB24", sizeof(f->description));
+               strscpy(f->description, "RGB24", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_RGB24;
                break;
        case 2:
-               strlcpy(f->description, "RGB32", sizeof(f->description));
+               strscpy(f->description, "RGB32", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_BGR32;
                break;
        default:
@@ -898,11 +898,11 @@ static int cobalt_enum_fmt_vid_out(struct file *file, void *priv_fh,
 {
        switch (f->index) {
        case 0:
-               strlcpy(f->description, "YUV 4:2:2", sizeof(f->description));
+               strscpy(f->description, "YUV 4:2:2", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_YUYV;
                break;
        case 1:
-               strlcpy(f->description, "RGB32", sizeof(f->description));
+               strscpy(f->description, "RGB32", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_BGR32;
                break;
        default:
@@ -1064,10 +1064,15 @@ static int cobalt_subscribe_event(struct v4l2_fh *fh,
 
 static int cobalt_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
 {
+       struct cobalt_stream *s = video_drvdata(file);
+       struct v4l2_fract fps;
+
        if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
-       a->parm.capture.timeperframe.numerator = 1;
-       a->parm.capture.timeperframe.denominator = 60;
+
+       fps = v4l2_calc_timeperframe(&s->timings);
+       a->parm.capture.timeperframe.numerator = fps.numerator;
+       a->parm.capture.timeperframe.denominator = fps.denominator;
        a->parm.capture.readbuffers = 3;
        return 0;
 }
index 93443d1457c58f4854c50c8d7c38d47e0d792d41..687477748fdd28a4d277324c1826611d7c80b9ae 100644 (file)
@@ -112,7 +112,7 @@ static int snd_cx18_card_set_names(struct snd_cx18_card *cxsc)
        struct snd_card *sc = cxsc->sc;
 
        /* sc->driver is used by alsa-lib's configurator: simple, unique */
-       strlcpy(sc->driver, "CX23418", sizeof(sc->driver));
+       strscpy(sc->driver, "CX23418", sizeof(sc->driver));
 
        /* sc->shortname is a symlink in /proc/asound: CX18-M -> cardN */
        snprintf(sc->shortname,  sizeof(sc->shortname), "CX18-%d",
index 4f31042a442ace9562bd348661d26fb88e8f3d58..3eafc27956c2b81f7c8ec3d015841337d312535a 100644 (file)
@@ -345,7 +345,7 @@ int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
                        &snd_cx18_pcm_capture_ops);
        sp->info_flags = 0;
        sp->private_data = cxsc;
-       strlcpy(sp->name, cx->card_name, sizeof(sp->name));
+       strscpy(sp->name, cx->card_name, sizeof(sp->name));
 
        return 0;
 
index c2cf965d639e8d89e613e078ce2eab69054d45f4..2dcbccfbd60d7a457d68c9d2c1f4b9fc7b9812db 100644 (file)
@@ -602,8 +602,8 @@ int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
        if (index >= cx->nof_inputs)
                return -EINVAL;
        input->index = index;
-       strlcpy(input->name, input_strs[card_input->video_type - 1],
-                       sizeof(input->name));
+       strscpy(input->name, input_strs[card_input->video_type - 1],
+               sizeof(input->name));
        input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
                        V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
        input->audioset = (1 << cx->nof_audio_inputs) - 1;
@@ -625,8 +625,8 @@ int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
        memset(audio, 0, sizeof(*audio));
        if (index >= cx->nof_audio_inputs)
                return -EINVAL;
-       strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
-                       sizeof(audio->name));
+       strscpy(audio->name, input_strs[aud_input->audio_type - 1],
+               sizeof(audio->name));
        audio->index = index;
        audio->capability = V4L2_AUDCAP_STEREO;
        return 0;
index 0c389a3fb4e5f0fb9bdaaa75128e0a177898ba10..a6ba4ca5aa916f2ff954a49a756a15d3a0b032d0 100644 (file)
@@ -328,7 +328,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
        if (!c)
                return;
 
-       strlcpy(c->name, "cx18 tveeprom tmp", sizeof(c->name));
+       strscpy(c->name, "cx18 tveeprom tmp", sizeof(c->name));
        c->adapter = &cx->i2c_adap[0];
        c->addr = 0xa0 >> 1;
 
@@ -1252,7 +1252,7 @@ static void cx18_cancel_out_work_orders(struct cx18 *cx)
 {
        int i;
        for (i = 0; i < CX18_MAX_STREAMS; i++)
-               if (&cx->streams[i].video_dev)
+               if (cx->streams[i].video_dev.v4l2_dev)
                        cancel_work_sync(&cx->streams[i].out_work_order);
 }
 
index f0eb181f2b94903e7cafc2bf71b2b8b3c58ffb9b..a89c666953f5680cbdfb7e39bbf80d5e6855bc3c 100644 (file)
@@ -83,7 +83,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
        unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
 
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, type, I2C_NAME_SIZE);
+       strscpy(info.type, type, I2C_NAME_SIZE);
 
        /* Our default information for ir-kbd-i2c.c to use */
        switch (hw) {
index 80b902b12a78a97880786c0afe3143fb1db62c46..854116375a7ccb9c4af89e6c648dd192263e2fce 100644 (file)
@@ -397,8 +397,8 @@ static int cx18_querycap(struct file *file, void *fh,
        struct cx18_stream *s = video_drvdata(file);
        struct cx18 *cx = id->cx;
 
-       strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
-       strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
+       strscpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
+       strscpy(vcap->card, cx->card_name, sizeof(vcap->card));
        snprintf(vcap->bus_info, sizeof(vcap->bus_info),
                 "PCI:%s", pci_name(cx->pci_dev));
        vcap->capabilities = cx->v4l2_cap;      /* capabilities */
@@ -632,9 +632,9 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        cx18_call_all(cx, tuner, g_tuner, vt);
 
        if (vt->type == V4L2_TUNER_RADIO)
-               strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
+               strscpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
        else
-               strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
+               strscpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
        return 0;
 }
 
index 62bc8049b320122d397ff18eeb06562311c724fa..198c05e83f5c0b1a106564e3c94f18e06ce6214f 100644 (file)
@@ -665,6 +665,10 @@ static int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
                }
 
                temp_int = append_internal(inter);
+               if (!temp_int) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
                inter->filts_used = 1;
                inter->dev = config->dev;
                inter->fpga_rw = config->fpga_rw;
@@ -699,6 +703,7 @@ err:
                     __func__, ret);
 
        kfree(pid_filt);
+       kfree(inter);
 
        return ret;
 }
@@ -733,6 +738,10 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr)
                }
 
                temp_int = append_internal(inter);
+               if (!temp_int) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
                inter->cis_used = 1;
                inter->dev = config->dev;
                inter->fpga_rw = config->fpga_rw;
@@ -801,6 +810,7 @@ err:
        ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
 
        kfree(state);
+       kfree(inter);
 
        return ret;
 }
index a71f3c7569ce3fb9b331cc5f0ba8a1298816b54f..a00b77d80ed9616e7da565e57f50cc6defcf8b11 100644 (file)
@@ -1280,7 +1280,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
                return -EINVAL;
        if (0 != t->index)
                return -EINVAL;
-       strcpy(t->name, "Television");
+       strscpy(t->name, "Television", sizeof(t->name));
        call_all(dev, tuner, g_tuner, t);
 
        dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
@@ -1329,8 +1329,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct cx23885_dev *dev = video_drvdata(file);
        struct cx23885_tsport  *tsport = &dev->ts1;
 
-       strlcpy(cap->driver, dev->name, sizeof(cap->driver));
-       strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
+       strscpy(cap->driver, dev->name, sizeof(cap->driver));
+       strscpy(cap->card, cx23885_boards[tsport->dev->board].name,
                sizeof(cap->card));
        sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
@@ -1349,7 +1349,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strlcpy(f->description, "MPEG", sizeof(f->description));
+       strscpy(f->description, "MPEG", sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_MPEG;
 
        return 0;
@@ -1527,7 +1527,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
        dev->cxhdl.priv = dev;
        dev->cxhdl.func = cx23885_api_func;
        cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
-       v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL);
+       v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL, false);
 
        /* Allocate and initialize V4L video device */
        dev->v4l_device = cx23885_video_dev_alloc(tsport,
index db1e8ff35474a9d3875b1f01d5243d878a3e6cf6..ee9d329c40389e7094ccd26940ac1ad7ceb84ad9 100644 (file)
@@ -526,7 +526,7 @@ static int snd_cx23885_pcm(struct cx23885_audio_dev *chip, int device,
        if (err < 0)
                return err;
        pcm->private_data = chip;
-       strcpy(pcm->name, name);
+       strscpy(pcm->name, name, sizeof(pcm->name));
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx23885_pcm_ops);
 
        return 0;
@@ -571,7 +571,7 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev)
        if (err < 0)
                goto error;
 
-       strcpy(card->driver, "CX23885");
+       strscpy(card->driver, "CX23885", sizeof(card->driver));
        sprintf(card->shortname, "Conexant CX23885");
        sprintf(card->longname, "%s at %s", card->shortname, dev->name);
 
index 7d52173073d6eedf23fcd19e8de01f848a81311a..0d0929c54f93b1753af3e53625a929fd7bda42c4 100644 (file)
@@ -1165,7 +1165,7 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port)
                sp2_config.priv = port;
                sp2_config.ci_control = cx23885_sp2_ci_ctrl;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "sp2", I2C_NAME_SIZE);
+               strscpy(info.type, "sp2", I2C_NAME_SIZE);
                info.addr = 0x40;
                info.platform_data = &sp2_config;
                request_module(info.type);
@@ -1831,7 +1831,7 @@ static int dvb_register(struct cx23885_tsport *port)
                case 1:
                        /* attach demod + tuner combo */
                        memset(&info, 0, sizeof(info));
-                       strlcpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
+                       strscpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
                        info.addr = 0x05;
                        info.platform_data = &tda10071_pdata;
                        request_module("tda10071");
@@ -1848,7 +1848,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        /* attach SEC */
                        a8293_pdata.dvb_frontend = fe0->dvb.frontend;
                        memset(&info, 0, sizeof(info));
-                       strlcpy(info.type, "a8293", I2C_NAME_SIZE);
+                       strscpy(info.type, "a8293", I2C_NAME_SIZE);
                        info.addr = 0x0b;
                        info.platform_data = &a8293_pdata;
                        request_module("a8293");
@@ -1869,7 +1869,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
                        si2165_pdata.ref_freq_hz = 16000000;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2165", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2165", I2C_NAME_SIZE);
                        info.addr = 0x64;
                        info.platform_data = &si2165_pdata;
                        request_module(info.type);
@@ -1903,7 +1903,7 @@ static int dvb_register(struct cx23885_tsport *port)
 
                /* attach demod + tuner combo */
                memset(&info, 0, sizeof(info));
-               strlcpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
+               strscpy(info.type, "tda10071_cx24118", I2C_NAME_SIZE);
                info.addr = 0x05;
                info.platform_data = &tda10071_pdata;
                request_module("tda10071");
@@ -1920,7 +1920,7 @@ static int dvb_register(struct cx23885_tsport *port)
                /* attach SEC */
                a8293_pdata.dvb_frontend = fe0->dvb.frontend;
                memset(&info, 0, sizeof(info));
-               strlcpy(info.type, "a8293", I2C_NAME_SIZE);
+               strscpy(info.type, "a8293", I2C_NAME_SIZE);
                info.addr = 0x0b;
                info.platform_data = &a8293_pdata;
                request_module("a8293");
@@ -1953,7 +1953,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        ts2020_config.fe = fe0->dvb.frontend;
                        ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "ts2020", I2C_NAME_SIZE);
+                       strscpy(info.type, "ts2020", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &ts2020_config;
                        request_module(info.type);
@@ -1990,7 +1990,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2168_config.fe = &fe0->dvb.frontend;
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0x64;
                        info.platform_data = &si2168_config;
                        request_module(info.type);
@@ -2009,7 +2009,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.fe = fe0->dvb.frontend;
                        si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &si2157_config;
                        request_module(info.type);
@@ -2037,7 +2037,7 @@ static int dvb_register(struct cx23885_tsport *port)
                si2168_config.fe = &fe0->dvb.frontend;
                si2168_config.ts_mode = SI2168_TS_PARALLEL;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+               strscpy(info.type, "si2168", I2C_NAME_SIZE);
                info.addr = 0x64;
                info.platform_data = &si2168_config;
                request_module(info.type);
@@ -2055,7 +2055,7 @@ static int dvb_register(struct cx23885_tsport *port)
                si2157_config.fe = fe0->dvb.frontend;
                si2157_config.if_port = 1;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+               strscpy(info.type, "si2157", I2C_NAME_SIZE);
                info.addr = 0x60;
                info.platform_data = &si2157_config;
                request_module(info.type);
@@ -2085,7 +2085,7 @@ static int dvb_register(struct cx23885_tsport *port)
                ts2020_config.fe = fe0->dvb.frontend;
                ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "ts2020", I2C_NAME_SIZE);
+               strscpy(info.type, "ts2020", I2C_NAME_SIZE);
                info.addr = 0x60;
                info.platform_data = &ts2020_config;
                request_module(info.type);
@@ -2134,7 +2134,7 @@ static int dvb_register(struct cx23885_tsport *port)
                }
 
                memset(&info, 0, sizeof(info));
-               strlcpy(info.type, "m88ds3103", I2C_NAME_SIZE);
+               strscpy(info.type, "m88ds3103", I2C_NAME_SIZE);
                info.addr = 0x68;
                info.platform_data = &m88ds3103_pdata;
                request_module(info.type);
@@ -2154,7 +2154,7 @@ static int dvb_register(struct cx23885_tsport *port)
                ts2020_config.fe = fe0->dvb.frontend;
                ts2020_config.get_agc_pwm = m88ds3103_get_agc_pwm;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "ts2020", I2C_NAME_SIZE);
+               strscpy(info.type, "ts2020", I2C_NAME_SIZE);
                info.addr = 0x60;
                info.platform_data = &ts2020_config;
                request_module(info.type);
@@ -2199,7 +2199,7 @@ static int dvb_register(struct cx23885_tsport *port)
                si2168_config.i2c_adapter = &adapter;
                si2168_config.fe = &fe0->dvb.frontend;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+               strscpy(info.type, "si2168", I2C_NAME_SIZE);
                info.addr = 0x64;
                info.platform_data = &si2168_config;
                request_module(info.type);
@@ -2217,7 +2217,7 @@ static int dvb_register(struct cx23885_tsport *port)
                si2157_config.fe = fe0->dvb.frontend;
                si2157_config.if_port = 1;
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+               strscpy(info.type, "si2157", I2C_NAME_SIZE);
                info.addr = 0x60;
                info.platform_data = &si2157_config;
                request_module(info.type);
@@ -2250,7 +2250,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        /* attach SEC */
                        a8293_pdata.dvb_frontend = fe0->dvb.frontend;
                        memset(&info, 0, sizeof(info));
-                       strlcpy(info.type, "a8293", I2C_NAME_SIZE);
+                       strscpy(info.type, "a8293", I2C_NAME_SIZE);
                        info.addr = 0x0b;
                        info.platform_data = &a8293_pdata;
                        request_module("a8293");
@@ -2267,7 +2267,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        memset(&m88rs6000t_config, 0, sizeof(m88rs6000t_config));
                        m88rs6000t_config.fe = fe0->dvb.frontend;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "m88rs6000t", I2C_NAME_SIZE);
+                       strscpy(info.type, "m88rs6000t", I2C_NAME_SIZE);
                        info.addr = 0x21;
                        info.platform_data = &m88rs6000t_config;
                        request_module("%s", info.type);
@@ -2292,7 +2292,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2168_config.fe = &fe0->dvb.frontend;
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0x64;
                        info.platform_data = &si2168_config;
                        request_module("%s", info.type);
@@ -2310,7 +2310,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.fe = fe0->dvb.frontend;
                        si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &si2157_config;
                        request_module("%s", info.type);
@@ -2345,7 +2345,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2168_config.fe = &fe0->dvb.frontend;
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0x64;
                        info.platform_data = &si2168_config;
                        request_module("%s", info.type);
@@ -2363,7 +2363,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.fe = fe0->dvb.frontend;
                        si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &si2157_config;
                        request_module("%s", info.type);
@@ -2392,7 +2392,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2168_config.fe = &fe0->dvb.frontend;
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0x66;
                        info.platform_data = &si2168_config;
                        request_module("%s", info.type);
@@ -2410,7 +2410,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.fe = fe0->dvb.frontend;
                        si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x62;
                        info.platform_data = &si2157_config;
                        request_module("%s", info.type);
@@ -2452,7 +2452,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.if_port = 1;
                        si2157_config.inversion = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &si2157_config;
                        request_module("%s", info.type);
@@ -2488,7 +2488,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.if_port = 1;
                        si2157_config.inversion = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x62;
                        info.platform_data = &si2157_config;
                        request_module("%s", info.type);
@@ -2528,7 +2528,7 @@ static int dvb_register(struct cx23885_tsport *port)
                        si2157_config.if_port = 1;
                        si2157_config.inversion = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &si2157_config;
                        request_module("%s", info.type);
index ef863492c0ac7be67824e81057285ccd1ed5b3bf..d0df3dfff694e4b3e088b8a893ae0f82eb28e37a 100644 (file)
@@ -317,7 +317,7 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
        bus->i2c_client = cx23885_i2c_client_template;
        bus->i2c_adap.dev.parent = &dev->pci->dev;
 
-       strlcpy(bus->i2c_adap.name, bus->dev->name,
+       strscpy(bus->i2c_adap.name, bus->dev->name,
                sizeof(bus->i2c_adap.name));
 
        bus->i2c_adap.algo_data = bus;
@@ -340,12 +340,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
        /* Instantiate the IR receiver device, if present */
        if (0 == bus->i2c_rc) {
                struct i2c_board_info info;
-               const unsigned short addr_list[] = {
+               static const unsigned short addr_list[] = {
                        0x6b, I2C_CLIENT_END
                };
 
                memset(&info, 0, sizeof(struct i2c_board_info));
-               strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+               strscpy(info.type, "ir_video", I2C_NAME_SIZE);
                /* Use quick read command for probe, some IR chips don't
                 * support writes */
                i2c_new_probed_device(&bus->i2c_adap, &info, addr_list,
index d2cdd40f79f54611b9b6aa46ad7a0d5a9b00d9f0..d162bf4b4800e21e408c95c1d0cd6ac77be0ac42 100644 (file)
@@ -31,9 +31,9 @@ int cx23885_g_chip_info(struct file *file, void *fh,
        if (chip->match.addr == 1) {
                if (dev->v4l_device == NULL)
                        return -EINVAL;
-               strlcpy(chip->name, "cx23417", sizeof(chip->name));
+               strscpy(chip->name, "cx23417", sizeof(chip->name));
        } else {
-               strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
+               strscpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
        }
        return 0;
 }
index f8a3deadc77a19e2b1fdd0d404dfb3948f52a0f6..92d32a733f1b4a32b4ef0b3dc6c49b838001d788 100644 (file)
@@ -639,8 +639,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct cx23885_dev *dev = video_drvdata(file);
        struct video_device *vdev = video_devdata(file);
 
-       strcpy(cap->driver, "cx23885");
-       strlcpy(cap->card, cx23885_boards[dev->board].name,
+       strscpy(cap->driver, "cx23885", sizeof(cap->driver));
+       strscpy(cap->card, cx23885_boards[dev->board].name,
                sizeof(cap->card));
        sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
        cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO;
@@ -661,7 +661,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (unlikely(f->index >= ARRAY_SIZE(formats)))
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name,
+       strscpy(f->description, formats[f->index].name,
                sizeof(f->description));
        f->pixelformat = formats[f->index].fourcc;
 
@@ -731,7 +731,7 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
 
        i->index = n;
        i->type  = V4L2_INPUT_TYPE_CAMERA;
-       strcpy(i->name, iname[INPUT(n)->type]);
+       strscpy(i->name, iname[INPUT(n)->type], sizeof(i->name));
        i->std = CX23885_NORMS;
        if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) ||
                (CX23885_VMUX_CABLE == INPUT(n)->type)) {
@@ -828,7 +828,7 @@ static int cx23885_query_audinput(struct file *file, void *priv,
 
        memset(i, 0, sizeof(*i));
        i->index = n;
-       strcpy(i->name, iname[n]);
+       strscpy(i->name, iname[n], sizeof(i->name));
        i->capability = V4L2_AUDCAP_STEREO;
        return 0;
 
@@ -887,7 +887,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (0 != t->index)
                return -EINVAL;
 
-       strcpy(t->name, "Television");
+       strscpy(t->name, "Television", sizeof(t->name));
 
        call_all(dev, tuner, g_tuner, t);
        return 0;
@@ -1186,7 +1186,8 @@ int cx23885_video_register(struct cx23885_dev *dev)
 
        /* Initialize VBI template */
        cx23885_vbi_template = cx23885_video_template;
-       strcpy(cx23885_vbi_template.name, "cx23885-vbi");
+       strscpy(cx23885_vbi_template.name, "cx23885-vbi",
+               sizeof(cx23885_vbi_template.name));
 
        dev->tvnorm = V4L2_STD_NTSC_M;
        dev->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
index 00329f668b590260713d3dab844179398f55b465..1d775c90df51bf6bbe120dacca2b2474fd15418e 100644 (file)
@@ -696,10 +696,8 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
                if (v > IR_MAX_DURATION)
                        v = IR_MAX_DURATION;
 
-               init_ir_raw_event(&p->ir_core_data);
-               p->ir_core_data.pulse = u;
-               p->ir_core_data.duration = v;
-               p->ir_core_data.timeout = w;
+               p->ir_core_data = (struct ir_raw_event)
+                       { .pulse = u, .duration = v, .timeout = w };
 
                v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns  %s  %s\n",
                         v, u ? "mark" : "space", w ? "(timed out)" : "");
index ef6380651c10b133504e86d51ebe3199db8602c2..0a6c90e925572747e35ef1e4847cb66a1f2cbac5 100644 (file)
@@ -674,7 +674,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
        }
        pcm->private_data = chip;
        pcm->info_flags = 0;
-       strcpy(pcm->name, name);
+       strscpy(pcm->name, name, sizeof(pcm->name));
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
 
        return 0;
@@ -725,7 +725,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
                return err;
        }
 
-       strcpy(card->driver, "cx25821");
+       strscpy(card->driver, "cx25821", sizeof(card->driver));
 
        /* Card "creation" */
        chip = card->private_data;
@@ -754,10 +754,10 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev)
                goto error;
        }
 
-       strcpy(card->shortname, "cx25821");
+       strscpy(card->shortname, "cx25821", sizeof(card->shortname));
        sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
                chip->iobase, chip->irq);
-       strcpy(card->mixername, "CX25821");
+       strscpy(card->mixername, "CX25821", sizeof(card->mixername));
 
        pr_info("%s/%i: ALSA support for cx25821 boards\n", card->driver,
                devno);
index 31479a41f359dfe589f395bd62346a93d82bb71b..67d2f76100118c1b9bfd2e187b0ed97b43813fc8 100644 (file)
@@ -306,7 +306,7 @@ int cx25821_i2c_register(struct cx25821_i2c *bus)
        bus->i2c_client = cx25821_i2c_client_template;
        bus->i2c_adap.dev.parent = &dev->pci->dev;
 
-       strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
+       strscpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
 
        bus->i2c_adap.algo_data = bus;
        i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
index dbaf42ec26cd8efd4076a53419262fc0855f12fc..3d23c2e64102f7680b7860d5a003b7adec02c12c 100644 (file)
@@ -322,7 +322,7 @@ static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
        if (unlikely(f->index >= ARRAY_SIZE(formats)))
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       strscpy(f->description, formats[f->index].name, sizeof(f->description));
        f->pixelformat = formats[f->index].fourcc;
 
        return 0;
@@ -441,8 +441,8 @@ static int cx25821_vidioc_querycap(struct file *file, void *priv,
                        V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
        const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE;
 
-       strcpy(cap->driver, "cx25821");
-       strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
+       strscpy(cap->driver, "cx25821", sizeof(cap->driver));
+       strscpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
        sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
        if (chan->id >= VID_CHANNEL_NUM)
                cap->device_caps = cap_output;
@@ -486,7 +486,7 @@ static int cx25821_vidioc_enum_input(struct file *file, void *priv,
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
        i->std = CX25821_NORMS;
-       strcpy(i->name, "Composite");
+       strscpy(i->name, "Composite", sizeof(i->name));
        return 0;
 }
 
@@ -534,7 +534,7 @@ static int cx25821_vidioc_enum_output(struct file *file, void *priv,
 
        o->type = V4L2_INPUT_TYPE_CAMERA;
        o->std = CX25821_NORMS;
-       strcpy(o->name, "Composite");
+       strscpy(o->name, "Composite", sizeof(o->name));
        return 0;
 }
 
index 89a65478ae36d4eed134fccbf69a2223c9aae6f2..b683cbe13dee0135a1a111e7e3be99715ef7e629 100644 (file)
@@ -616,7 +616,7 @@ static int snd_cx88_pcm(struct cx88_audio_dev *chip, int device,
        if (err < 0)
                return err;
        pcm->private_data = chip;
-       strcpy(pcm->name, name);
+       strscpy(pcm->name, name, sizeof(pcm->name));
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
 
        return 0;
@@ -968,12 +968,12 @@ static int cx88_audio_initdev(struct pci_dev *pci,
                        goto error;
        }
 
-       strcpy(card->driver, "CX88x");
+       strscpy(card->driver, "CX88x", sizeof(card->driver));
        sprintf(card->shortname, "Conexant CX%x", pci->device);
        sprintf(card->longname, "%s at %#llx",
                card->shortname,
                (unsigned long long)pci_resource_start(pci, 0));
-       strcpy(card->mixername, "CX88");
+       strscpy(card->mixername, "CX88", sizeof(card->mixername));
 
        dprintk(0, "%s/%i: ALSA support for cx2388x boards\n",
                card->driver, devno);
index 7a4876cf9f088c32abdf3dff4cac8df4c21fb7b5..6c0bb9fe4a31b9207ef441b744a8cefb9efc46c8 100644 (file)
@@ -803,7 +803,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct cx8802_dev *dev = video_drvdata(file);
        struct cx88_core *core = dev->core;
 
-       strcpy(cap->driver, "cx88_blackbird");
+       strscpy(cap->driver, "cx88_blackbird", sizeof(cap->driver));
        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
        return cx88_querycap(file, core, cap);
 }
@@ -814,7 +814,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strlcpy(f->description, "MPEG", sizeof(f->description));
+       strscpy(f->description, "MPEG", sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_MPEG;
        f->flags = V4L2_FMT_FLAG_COMPRESSED;
        return 0;
@@ -995,7 +995,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (t->index != 0)
                return -EINVAL;
 
-       strcpy(t->name, "Television");
+       strscpy(t->name, "Television", sizeof(t->name));
        t->capability = V4L2_TUNER_CAP_NORM;
        t->rangehigh  = 0xffffffffUL;
        call_all(core, tuner, g_tuner, t);
@@ -1183,7 +1183,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
        err = cx2341x_handler_init(&dev->cxhdl, 36);
        if (err)
                goto fail_core;
-       v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL);
+       v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL, false);
 
        /* blackbird stuff */
        pr_info("cx23416 based mpeg encoder (blackbird reference design)\n");
index 07e1483e987d506a9145838a9192af6355c0f7dc..382af90fd4a900c6e72f203adf212d664079a1aa 100644 (file)
@@ -3693,7 +3693,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
        core->height  = 240;
        core->field   = V4L2_FIELD_INTERLACED;
 
-       strcpy(core->v4l2_dev.name, core->name);
+       strscpy(core->v4l2_dev.name, core->name, sizeof(core->v4l2_dev.name));
        if (v4l2_device_register(NULL, &core->v4l2_dev)) {
                kfree(core);
                return NULL;
index 99f88a05a7c93ed0ed7a301dfa6fade8209b6773..48be0b0ad68081a895e64a12b6f79ffd8747103a 100644 (file)
@@ -140,14 +140,14 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
        core->i2c_algo = cx8800_i2c_algo_template;
 
        core->i2c_adap.dev.parent = &pci->dev;
-       strlcpy(core->i2c_adap.name, core->name, sizeof(core->i2c_adap.name));
+       strscpy(core->i2c_adap.name, core->name, sizeof(core->i2c_adap.name));
        core->i2c_adap.owner = THIS_MODULE;
        core->i2c_algo.udelay = i2c_udelay;
        core->i2c_algo.data = core;
        i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
        core->i2c_adap.algo_data = &core->i2c_algo;
        core->i2c_client.adapter = &core->i2c_adap;
-       strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
+       strscpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
 
        cx8800_bit_setscl(core, 1);
        cx8800_bit_setsda(core, 1);
index 2f5debce4905fdf66f7fb1b7f395e3a7ca96fc60..ca76da04b47626e24521f9b405304032d1832bfb 100644 (file)
@@ -535,7 +535,7 @@ void cx88_ir_irq(struct cx88_core *core)
        struct cx88_IR *ir = core->ir;
        u32 samples;
        unsigned int todo, bits;
-       struct ir_raw_event ev;
+       struct ir_raw_event ev = {};
 
        if (!ir || !ir->sampling)
                return;
@@ -550,7 +550,6 @@ void cx88_ir_irq(struct cx88_core *core)
        if (samples == 0xff && ir->dev->idle)
                return;
 
-       init_ir_raw_event(&ev);
        for (todo = 32; todo > 0; todo -= bits) {
                ev.pulse = samples & 0x80000000 ? false : true;
                bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
@@ -610,7 +609,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
                return;
 
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+       strscpy(info.type, "ir_video", I2C_NAME_SIZE);
 
        switch (core->boardnr) {
        case CX88_BOARD_LEADTEK_PVR2000:
@@ -635,7 +634,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
 
                if (*addrp == 0x71) {
                        /* Hauppauge Z8F0811 */
-                       strlcpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
+                       strscpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
                        core->init_data.name = core->board.name;
                        core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
                        core->init_data.type = RC_PROTO_BIT_RC5 |
index 7b113bad70d23b2857dfcf26dd3648d465abffa3..e1549d352f707dcb59b17d0b8f69c1ba78871e70 100644 (file)
@@ -811,7 +811,7 @@ int cx88_querycap(struct file *file, struct cx88_core *core,
 {
        struct video_device *vdev = video_devdata(file);
 
-       strlcpy(cap->card, core->board.name, sizeof(cap->card));
+       strscpy(cap->card, core->board.name, sizeof(cap->card));
        cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
        if (core->board.tuner_type != UNSET)
                cap->device_caps |= V4L2_CAP_TUNER;
@@ -842,7 +842,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct cx8800_dev *dev = video_drvdata(file);
        struct cx88_core *core = dev->core;
 
-       strcpy(cap->driver, "cx8800");
+       strscpy(cap->driver, "cx8800", sizeof(cap->driver));
        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
        return cx88_querycap(file, core, cap);
 }
@@ -853,7 +853,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (unlikely(f->index >= ARRAY_SIZE(formats)))
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       strscpy(f->description, formats[f->index].name, sizeof(f->description));
        f->pixelformat = formats[f->index].fourcc;
 
        return 0;
@@ -897,7 +897,7 @@ int cx88_enum_input(struct cx88_core  *core, struct v4l2_input *i)
        if (!INPUT(n).type)
                return -EINVAL;
        i->type  = V4L2_INPUT_TYPE_CAMERA;
-       strcpy(i->name, iname[INPUT(n).type]);
+       strscpy(i->name, iname[INPUT(n).type], sizeof(i->name));
        if ((INPUT(n).type == CX88_VMUX_TELEVISION) ||
            (INPUT(n).type == CX88_VMUX_CABLE))
                i->type = V4L2_INPUT_TYPE_TUNER;
@@ -952,7 +952,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (t->index != 0)
                return -EINVAL;
 
-       strcpy(t->name, "Television");
+       strscpy(t->name, "Television", sizeof(t->name));
        t->capability = V4L2_TUNER_CAP_NORM;
        t->rangehigh  = 0xffffffffUL;
        call_all(core, tuner, g_tuner, t);
@@ -1065,7 +1065,7 @@ static int radio_g_tuner(struct file *file, void *priv,
        if (unlikely(t->index > 0))
                return -EINVAL;
 
-       strcpy(t->name, "Radio");
+       strscpy(t->name, "Radio", sizeof(t->name));
 
        call_all(core, tuner, g_tuner, t);
        return 0;
@@ -1378,7 +1378,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
                if (vc->id == V4L2_CID_CHROMA_AGC)
                        core->chroma_agc = vc;
        }
-       v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL);
+       v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL, false);
 
        /* load and configure helper modules */
 
index 92876de3841ce4987167c7a59ca91956f47fd87c..e4db636e9fad4959ba2d672ebed91ee43f669b6c 100644 (file)
@@ -114,7 +114,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
        vp3054_i2c->algo = vp3054_i2c_algo_template;
 
        vp3054_i2c->adap.dev.parent = &dev->pci->dev;
-       strlcpy(vp3054_i2c->adap.name, core->name,
+       strscpy(vp3054_i2c->adap.name, core->name,
                sizeof(vp3054_i2c->adap.name));
        vp3054_i2c->adap.owner = THIS_MODULE;
        vp3054_i2c->algo.data = dev;
index cfe23d02e5613d432ba52eab2ef273026b98e3c5..377991095abaed5d2e38369abe5386f59cb5de00 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ddbridge-ci.c: Digital Devices bridge CI (DuoFlex, CI Bridge) support
  *
@@ -13,9 +14,6 @@
  * 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.
- *
- * To obtain the license, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include "ddbridge.h"
index 35a39182dd835dfbf567f972acbf681c3ff1f669..cc98656af34973096db0d5840d49a159fd580f10 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * ddbridge-ci.h: Digital Devices bridge CI (DuoFlex, CI Bridge) support
  *
@@ -13,9 +14,6 @@
  * 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.
- *
- * To obtain the license, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef __DDBRIDGE_CI_H__
index c1b982e8e6c9b8f811decaba0e2c276908adbe75..7a2d19682fe375627ca09d0a82b4f33018da791e 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ddbridge-core.c: Digital Devices bridge core functions
  *
@@ -5,19 +6,14 @@
  *                         Marcus Metzler <mocm@metzlerbros.de>
  *                         Ralph Metzler <rjkm@metzlerbros.de>
  *
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * version 2 only, 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.
- *
- * To obtain the license, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/module.h>
index f3cbac07b41f421ca291cdf57aac418e50293f96..f9c91bdbd04124ce6afa1e3cff8a054b9d40e593 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ddbridge-hw.c: Digital Devices bridge hardware maps
  *
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #include "ddbridge.h"
index 7c142419419c0ec8d64c48beceb8495ca9abb7fc..e34bd94c266b913d15b4635ea799927e3c32bb7b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * ddbridge-hw.h: Digital Devices bridge hardware maps
  *
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #ifndef _DDBRIDGE_HW_H_
index 5a28d76117134f7d6a721351b0e594c393f22226..aafa6030c8cc728d645ecd5f3ebd23f801a41d61 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ddbridge-i2c.c: Digital Devices bridge i2c driver
  *
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #include <linux/module.h>
index 7ed220506c05e5e95c28005b24ece2b304dc88b5..90830f7b1638bc43549f600f1edf5a9d20aa3a2a 100644 (file)
@@ -1,5 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
- * ddbridge-i2c.c: Digital Devices bridge i2c driver
+ * ddbridge-i2c.h: Digital Devices bridge i2c driver
  *
  * Copyright (C) 2010-2017 Digital Devices GmbH
  *                         Ralph Metzler <rjkm@metzlerbros.de>
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #ifndef __DDBRIDGE_I2C_H__
index b3646c04f1a777962c9ff2ec83f2abfb2764e1fe..1a5b31b524942c8dc5d23ac0daa1a03583f7d461 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * ddbridge-io.h: Digital Devices bridge I/O inline functions
  *
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #ifndef __DDBRIDGE_IO_H__
index f4748cfd904bf5d2888b38ebb811d4ddb55479a1..03dc9924fa2cca84f957d520a84ac720140a192b 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ddbridge.c: Digital Devices PCIe bridge driver
  *
@@ -13,7 +14,6 @@
  * 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.
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -318,5 +318,5 @@ module_exit(module_exit_ddbridge);
 
 MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
 MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_VERSION(DDBRIDGE_VERSION);
index 8da1c7b915778ee3ce349f5b25ad94addd328fdf..576dd2318e4de0af74b4ba8d4fdb01c39a63b911 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ddbridge-max.c: Digital Devices bridge MAX card support
  *
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #include <linux/module.h>
index 9838c73973b6637cb54202544a4f519efee5f143..6543dfc7713875cc510f5db921d1a24b99f1ec35 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * ddbridge-max.h: Digital Devices bridge MAX card support
  *
@@ -13,7 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
  */
 
 #ifndef _DDBRIDGE_MAX_H_
index f9e1cbb99b53fe06352649f181e03989433e8a26..2942a7f35099515db50f13eaba6709aa21eb780d 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * ddbridge-regs.h: Digital Devices PCIe bridge driver
  *
@@ -7,14 +8,10 @@
  * modify it under the terms of the GNU General Public License
  * version 2 only, 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.
- *
- * To obtain the license, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef __DDBRIDGE_REGS_H__
index 64f05f5ee039f6fa5d9b9f606cff1df12155e73a..374fcee949602e61f5d3e24b664b0e68616c8f45 100644 (file)
@@ -398,9 +398,7 @@ static int set_parameters(struct dvb_frontend *fe)
                }
                stat = start(fe, 3, mask, ts_config);
        } else {
-               u32 flags = (iq_mode == 2) ? 1 : 0;
-
-               stat = start_iq(fe, flags, 4, ts_config);
+               stat = start_iq(fe, 0, 4, ts_config);
        }
        if (!stat) {
                state->started = 1;
index 8a354dfb6c22401235576e447593abce12a246b1..f137155bf79e569636ca692779c8d1f340ca71d3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * ddbridge.h: Digital Devices PCIe bridge driver
  *
@@ -8,14 +9,10 @@
  * modify it under the terms of the GNU General Public License
  * version 2 only, 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.
- *
- * To obtain the license, point your browser to
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef _DDBRIDGE_H_
index 1ddb0576fb7b1af37d8c681d925df6260bc2ff4a..a84c8270ea13e82de70a1467fd0e2fba767ed7f7 100644 (file)
@@ -1046,7 +1046,7 @@ static int dm1105_probe(struct pci_dev *pdev,
 
        /* i2c */
        i2c_set_adapdata(&dev->i2c_adap, dev);
-       strcpy(dev->i2c_adap.name, DRIVER_NAME);
+       strscpy(dev->i2c_adap.name, DRIVER_NAME, sizeof(dev->i2c_adap.name));
        dev->i2c_adap.owner = THIS_MODULE;
        dev->i2c_adap.dev.parent = &pdev->dev;
        dev->i2c_adap.algo = &dm1105_algo;
@@ -1057,7 +1057,8 @@ static int dm1105_probe(struct pci_dev *pdev,
                goto err_dm1105_hw_exit;
 
        i2c_set_adapdata(&dev->i2c_bb_adap, dev);
-       strcpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME);
+       strscpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME,
+               sizeof(dev->i2c_bb_adap.name));
        dev->i2c_bb_adap.owner = THIS_MODULE;
        dev->i2c_bb_adap.dev.parent = &pdev->dev;
        dev->i2c_bb_adap.algo_data = &dev->i2c_bit;
index 1775c36891ae16786b38f3cf32b79f901a4ba2b5..17d69bd5d7f112f970465e8511602eaa8b8100ac 100644 (file)
@@ -307,8 +307,8 @@ static int dt3155_querycap(struct file *filp, void *p,
 {
        struct dt3155_priv *pd = video_drvdata(filp);
 
-       strcpy(cap->driver, DT3155_NAME);
-       strcpy(cap->card, DT3155_NAME " frame grabber");
+       strscpy(cap->driver, DT3155_NAME, sizeof(cap->driver));
+       strscpy(cap->card, DT3155_NAME " frame grabber", sizeof(cap->card));
        sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
                V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
@@ -322,7 +322,7 @@ static int dt3155_enum_fmt_vid_cap(struct file *filp,
        if (f->index)
                return -EINVAL;
        f->pixelformat = V4L2_PIX_FMT_GREY;
-       strcpy(f->description, "8-bit Greyscale");
+       strscpy(f->description, "8-bit Greyscale", sizeof(f->description));
        return 0;
 }
 
@@ -378,7 +378,7 @@ static int dt3155_enum_input(struct file *filp, void *p,
                snprintf(input->name, sizeof(input->name), "VID%d",
                         input->index);
        else
-               strlcpy(input->name, "J2/VID0", sizeof(input->name));
+               strscpy(input->name, "J2/VID0", sizeof(input->name));
        input->type = V4L2_INPUT_TYPE_CAMERA;
        input->std = V4L2_STD_ALL;
        input->status = 0;
index 29027159eced88a57b9a39feba4197e45c1a2d00..452eb9b42140bb927e7af8287dcbe99b45ef51dd 100644 (file)
@@ -218,13 +218,11 @@ static int cio2_fbpt_init(struct cio2_device *cio2, struct cio2_queue *q)
 {
        struct device *dev = &cio2->pci_dev->dev;
 
-       q->fbpt = dma_alloc_coherent(dev, CIO2_FBPT_SIZE, &q->fbpt_bus_addr,
-                                    GFP_KERNEL);
+       q->fbpt = dma_zalloc_coherent(dev, CIO2_FBPT_SIZE, &q->fbpt_bus_addr,
+                                     GFP_KERNEL);
        if (!q->fbpt)
                return -ENOMEM;
 
-       memset(q->fbpt, 0, CIO2_FBPT_SIZE);
-
        return 0;
 }
 
@@ -1066,8 +1064,8 @@ static int cio2_v4l2_querycap(struct file *file, void *fh,
 {
        struct cio2_device *cio2 = video_drvdata(file);
 
-       strlcpy(cap->driver, CIO2_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, CIO2_DEVICE_NAME, sizeof(cap->card));
+       strscpy(cap->driver, CIO2_NAME, sizeof(cap->driver));
+       strscpy(cap->card, CIO2_DEVICE_NAME, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "PCI:%s", pci_name(cio2->pci_dev));
 
@@ -1145,7 +1143,7 @@ cio2_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
        if (input->index > 0)
                return -EINVAL;
 
-       strlcpy(input->name, "camera", sizeof(input->name));
+       strscpy(input->name, "camera", sizeof(input->name));
        input->type = V4L2_INPUT_TYPE_CAMERA;
 
        return 0;
@@ -1435,13 +1433,13 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
        struct cio2_device *cio2 = container_of(notifier, struct cio2_device,
                                                notifier);
        struct sensor_async_subdev *s_asd;
+       struct v4l2_async_subdev *asd;
        struct cio2_queue *q;
-       unsigned int i, pad;
+       unsigned int pad;
        int ret;
 
-       for (i = 0; i < notifier->num_subdevs; i++) {
-               s_asd = container_of(cio2->notifier.subdevs[i],
-                                    struct sensor_async_subdev, asd);
+       list_for_each_entry(asd, &cio2->notifier.asd_list, asd_list) {
+               s_asd = container_of(asd, struct sensor_async_subdev, asd);
                q = &cio2->queue[s_asd->csi2.port];
 
                for (pad = 0; pad < q->sensor->entity.num_pads; pad++)
@@ -1463,7 +1461,7 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
                if (ret) {
                        dev_err(&cio2->pci_dev->dev,
                                "failed to create link for %s\n",
-                               cio2->queue[i].sensor->name);
+                               q->sensor->name);
                        return ret;
                }
        }
@@ -1484,7 +1482,7 @@ static int cio2_fwnode_parse(struct device *dev,
        struct sensor_async_subdev *s_asd =
                        container_of(asd, struct sensor_async_subdev, asd);
 
-       if (vep->bus_type != V4L2_MBUS_CSI2) {
+       if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(dev, "Only CSI2 bus type is currently supported\n");
                return -EINVAL;
        }
@@ -1499,6 +1497,8 @@ static int cio2_notifier_init(struct cio2_device *cio2)
 {
        int ret;
 
+       v4l2_async_notifier_init(&cio2->notifier);
+
        ret = v4l2_async_notifier_parse_fwnode_endpoints(
                &cio2->pci_dev->dev, &cio2->notifier,
                sizeof(struct sensor_async_subdev),
@@ -1506,7 +1506,7 @@ static int cio2_notifier_init(struct cio2_device *cio2)
        if (ret < 0)
                return ret;
 
-       if (!cio2->notifier.num_subdevs)
+       if (list_empty(&cio2->notifier.asd_list))
                return -ENODEV; /* no endpoint */
 
        cio2->notifier.ops = &cio2_async_ops;
@@ -1785,7 +1785,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
        mutex_init(&cio2->lock);
 
        cio2->media_dev.dev = &cio2->pci_dev->dev;
-       strlcpy(cio2->media_dev.model, CIO2_DEVICE_NAME,
+       strscpy(cio2->media_dev.model, CIO2_DEVICE_NAME,
                sizeof(cio2->media_dev.model));
        snprintf(cio2->media_dev.bus_info, sizeof(cio2->media_dev.bus_info),
                 "PCI:%s", pci_name(cio2->pci_dev));
index c1856f609d2c06f205c25c466b32822c32bed077..0de8a9f5011ab0a78ece14b16ab60c46bffc309a 100644 (file)
@@ -109,7 +109,7 @@ static int snd_ivtv_card_set_names(struct snd_ivtv_card *itvsc)
        struct snd_card *sc = itvsc->sc;
 
        /* sc->driver is used by alsa-lib's configurator: simple, unique */
-       strlcpy(sc->driver, "CX2341[56]", sizeof(sc->driver));
+       strscpy(sc->driver, "CX2341[56]", sizeof(sc->driver));
 
        /* sc->shortname is a symlink in /proc/asound: IVTV-M -> cardN */
        snprintf(sc->shortname,  sizeof(sc->shortname), "IVTV-%d",
index 5326d86fa3753d6d751fd41924ba94940b1c2c02..737c52de755889f9387a964d7e9ef86816d0e5cf 100644 (file)
@@ -350,7 +350,7 @@ int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
                        &snd_ivtv_pcm_capture_ops);
        sp->info_flags = 0;
        sp->private_data = itvsc;
-       strlcpy(sp->name, itv->card_name, sizeof(sp->name));
+       strscpy(sp->name, itv->card_name, sizeof(sp->name));
 
        return 0;
 
index c63792964a03d4f9f5ac5b630dc6ff0ac16c57a7..4ff46a6d05038c0ed961af4e1aea4bcd6420268b 100644 (file)
@@ -1317,8 +1317,8 @@ int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
        if (index >= itv->nof_inputs)
                return -EINVAL;
        input->index = index;
-       strlcpy(input->name, input_strs[card_input->video_type - 1],
-                       sizeof(input->name));
+       strscpy(input->name, input_strs[card_input->video_type - 1],
+               sizeof(input->name));
        input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ?
                        V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
        input->audioset = (1 << itv->nof_audio_inputs) - 1;
@@ -1334,7 +1334,7 @@ int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
        if (index >= itv->card->nof_outputs)
                return -EINVAL;
        output->index = index;
-       strlcpy(output->name, card_output->name, sizeof(output->name));
+       strscpy(output->name, card_output->name, sizeof(output->name));
        output->type = V4L2_OUTPUT_TYPE_ANALOG;
        output->audioset = 1;
        output->std = V4L2_STD_ALL;
@@ -1353,8 +1353,8 @@ int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio)
        memset(audio, 0, sizeof(*audio));
        if (index >= itv->nof_audio_inputs)
                return -EINVAL;
-       strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
-                       sizeof(audio->name));
+       strscpy(audio->name, input_strs[aud_input->audio_type - 1],
+               sizeof(audio->name));
        audio->index = index;
        audio->capability = V4L2_AUDCAP_STEREO;
        return 0;
@@ -1365,6 +1365,6 @@ int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud
        memset(aud_output, 0, sizeof(*aud_output));
        if (itv->card->video_outputs == NULL || index != 0)
                return -EINVAL;
-       strlcpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name));
+       strscpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name));
        return 0;
 }
index e9ce54dd5e011808690bed7aa1a669eee935e9a3..55ef1385519e1610018e7a36b3bac6dce697bef2 100644 (file)
@@ -218,7 +218,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
 
        memset(&info, 0, sizeof(struct i2c_board_info));
        info.platform_data = init_data;
-       strlcpy(info.type, type, I2C_NAME_SIZE);
+       strscpy(info.type, type, I2C_NAME_SIZE);
 
        return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
               -1 : 0;
@@ -239,14 +239,14 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
         * allocations, so this function must be called after all other i2c
         * devices we care about are registered.
         */
-       const unsigned short addr_list[] = {
+       static const unsigned short addr_list[] = {
                0x1a,   /* Hauppauge IR external - collides with WM8739 */
                0x18,   /* Hauppauge IR internal */
                I2C_CLIENT_END
        };
 
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+       strscpy(info.type, "ir_video", I2C_NAME_SIZE);
        return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL);
 }
 
index 4cdc6d2be85de973e3548001ba54a3f78c237207..a66f8b87252014131f7ca2b30066e0047bc213db 100644 (file)
@@ -36,6 +36,7 @@
 #include <media/tveeprom.h>
 #include <media/v4l2-event.h>
 #ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS
+#include <linux/compat.h>
 #include <linux/dvb/audio.h>
 #include <linux/dvb/video.h>
 #endif
@@ -747,8 +748,8 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
        struct ivtv *itv = id->itv;
        struct ivtv_stream *s = &itv->streams[id->type];
 
-       strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
-       strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
+       strscpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
+       strscpy(vcap->card, itv->card_name, sizeof(vcap->card));
        snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
        vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
        vcap->device_caps = s->caps;
@@ -1227,9 +1228,9 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        ivtv_call_all(itv, tuner, g_tuner, vt);
 
        if (vt->type == V4L2_TUNER_RADIO)
-               strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
+               strscpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
        else
-               strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
+               strscpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
        return 0;
 }
 
@@ -1627,6 +1628,21 @@ static __inline__ void warn_deprecated_ioctl(const char *name)
        pr_warn_once("warning: the %s ioctl is deprecated. Don't use it, as it will be removed soon\n",
                     name);
 }
+
+#ifdef CONFIG_COMPAT
+struct compat_video_event {
+       __s32 type;
+       /* unused, make sure to use atomic time for y2038 if it ever gets used */
+       compat_long_t timestamp;
+       union {
+               video_size_t size;
+               unsigned int frame_rate;        /* in frames per 1000sec */
+               unsigned char vsync_field;      /* unknown/odd/even/progressive */
+       } u;
+};
+#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event)
+#endif
+
 #endif
 
 static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
@@ -1749,7 +1765,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                return ivtv_video_command(itv, id, dc, try);
        }
 
+#ifdef CONFIG_COMPAT
+       case VIDEO_GET_EVENT32:
+#endif
        case VIDEO_GET_EVENT: {
+#ifdef CONFIG_COMPAT
+               struct compat_video_event *ev32 = arg;
+#endif
                struct video_event *ev = arg;
                DEFINE_WAIT(wait);
 
@@ -1763,14 +1785,22 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                        if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
                                ev->type = VIDEO_EVENT_DECODER_STOPPED;
                        else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
+                               unsigned char vsync_field;
+
                                ev->type = VIDEO_EVENT_VSYNC;
-                               ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
+                               vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
                                        VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
                                if (itv->output_mode == OUT_UDMA_YUV &&
                                        (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
                                                                IVTV_YUV_MODE_PROGRESSIVE) {
-                                       ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
+                                       vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
                                }
+#ifdef CONFIG_COMPAT
+                               if (cmd == VIDEO_GET_EVENT32)
+                                       ev32->u.vsync_field = vsync_field;
+                               else
+#endif
+                                       ev->u.vsync_field = vsync_field;
                        }
                        if (ev->type)
                                return 0;
index d27c6df975668423cd6ed57d626a0cb8aac60de3..a641f20e3f86fb00d9880af19beddb3dc3120348 100644 (file)
@@ -51,6 +51,9 @@ static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
        .write = ivtv_v4l2_write,
        .open = ivtv_v4l2_open,
        .unlocked_ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl32 = video_ioctl2, /* for ivtv_default() */
+#endif
        .release = ivtv_v4l2_close,
        .poll = ivtv_v4l2_enc_poll,
 };
@@ -61,6 +64,9 @@ static const struct v4l2_file_operations ivtv_v4l2_dec_fops = {
        .write = ivtv_v4l2_write,
        .open = ivtv_v4l2_open,
        .unlocked_ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl32 = video_ioctl2, /* for ivtv_default() */
+#endif
        .release = ivtv_v4l2_close,
        .poll = ivtv_v4l2_dec_poll,
 };
@@ -69,6 +75,9 @@ static const struct v4l2_file_operations ivtv_v4l2_radio_fops = {
        .owner = THIS_MODULE,
        .open = ivtv_v4l2_open,
        .unlocked_ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl32 = video_ioctl2, /* for ivtv_default() */
+#endif
        .release = ivtv_v4l2_close,
        .poll = ivtv_v4l2_enc_poll,
 };
index 44936d6d7c3967e28c9d1dcbaa722cf7e380c39e..1380474519f2bf045cae322ee0fa84414289397d 100644 (file)
@@ -935,7 +935,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
        }
 
        /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
-       yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
+       yi->blanking_ptr = kzalloc(720 * 16, GFP_ATOMIC|__GFP_NOWARN);
        if (yi->blanking_ptr) {
                yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
        } else {
index 5ddaa8ed11a566c8fcc405ce60c9617c84f91e41..3e02de02ffdd624683da0f74353f7ee28927ccd8 100644 (file)
@@ -624,7 +624,7 @@ static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
 
        IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-       strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
+       strscpy(fix->id, "cx23415 TV out", sizeof(fix->id));
        fix->smem_start = oi->video_pbase;
        fix->smem_len = oi->video_buffer_size;
        fix->type = FB_TYPE_PACKED_PIXELS;
index 8001d3e9134e440836fdf39b5b3624fd75b5ebe7..bd870e60c32b06dd5131272ab3c07ab71827d1d5 100644 (file)
@@ -1019,8 +1019,8 @@ static int meyeioc_stilljcapt(int *len)
 static int vidioc_querycap(struct file *file, void *fh,
                                struct v4l2_capability *cap)
 {
-       strcpy(cap->driver, "meye");
-       strcpy(cap->card, "meye");
+       strscpy(cap->driver, "meye", sizeof(cap->driver));
+       strscpy(cap->card, "meye", sizeof(cap->card));
        sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
 
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
@@ -1035,7 +1035,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
        if (i->index != 0)
                return -EINVAL;
 
-       strcpy(i->name, "Camera");
+       strscpy(i->name, "Camera", sizeof(i->name));
        i->type = V4L2_INPUT_TYPE_CAMERA;
 
        return 0;
@@ -1118,12 +1118,12 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
        if (f->index == 0) {
                /* standard YUV 422 capture */
                f->flags = 0;
-               strcpy(f->description, "YUV422");
+               strscpy(f->description, "YUV422", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_YUYV;
        } else {
                /* compressed MJPEG capture */
                f->flags = V4L2_FMT_FLAG_COMPRESSED;
-               strcpy(f->description, "MJPEG");
+               strscpy(f->description, "MJPEG", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_MJPEG;
        }
 
@@ -1460,7 +1460,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
        unsigned long page, pos;
 
        mutex_lock(&meye.lock);
-       if (size > gbuffers * gbufsize) {
+       if (size > gbuffers * gbufsize || offset > gbuffers * gbufsize - size) {
                mutex_unlock(&meye.lock);
                return -EINVAL;
        }
index 092d46c2a3a9471f1bb57c6d33c495b9268e2bfb..02a06f6c97f85cdeb3b279f38eb3a65725fc3205 100644 (file)
@@ -161,7 +161,7 @@ int ngene_i2c_init(struct ngene *dev, int dev_nr)
 
        i2c_set_adapdata(adap, &(dev->channel[dev_nr]));
 
-       strcpy(adap->name, "nGene");
+       strscpy(adap->name, "nGene", sizeof(adap->name));
 
        adap->algo = &ngene_i2c_algo;
        adap->algo_data = (void *)&(dev->channel[dev_nr]);
index 5e6fe686f420b5b73fb01bd0f8977bb58ac8c0e6..872c796621d20ad922f0eeca16ca39c463fe9ac7 100644 (file)
@@ -633,7 +633,7 @@ static int pluto2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* i2c */
        i2c_set_adapdata(&pluto->i2c_adap, pluto);
-       strcpy(pluto->i2c_adap.name, DRIVER_NAME);
+       strscpy(pluto->i2c_adap.name, DRIVER_NAME, sizeof(pluto->i2c_adap.name));
        pluto->i2c_adap.owner = THIS_MODULE;
        pluto->i2c_adap.dev.parent = &pdev->dev;
        pluto->i2c_adap.algo_data = &pluto->i2c_bit;
index 7f878fc41b7e68dad6be30cfa8a3565c4e6a6704..f4b8030e236952858d8242fdf2fc90b4f0b7ff85 100644 (file)
@@ -1354,7 +1354,7 @@ static int pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        i2c_adap->algo = &pt1_i2c_algo;
        i2c_adap->algo_data = NULL;
        i2c_adap->dev.parent = &pdev->dev;
-       strcpy(i2c_adap->name, DRIVER_NAME);
+       strscpy(i2c_adap->name, DRIVER_NAME, sizeof(i2c_adap->name));
        i2c_set_adapdata(i2c_adap, pt1);
        ret = i2c_add_adapter(i2c_adap);
        if (ret < 0)
index 90273b4d772f809792cb28f4c3db582217d4af4c..7a7afae4c84ce28dc557f551c776a366fdec1f9e 100644 (file)
@@ -765,7 +765,7 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        i2c->algo = &pt3_i2c_algo;
        i2c->algo_data = NULL;
        i2c->dev.parent = &pdev->dev;
-       strlcpy(i2c->name, DRV_NAME, sizeof(i2c->name));
+       strscpy(i2c->name, DRV_NAME, sizeof(i2c->name));
        i2c_set_adapdata(i2c, pt3);
        ret = i2c_add_adapter(i2c);
        if (ret < 0)
index b90cfde6e3016bb2d63d23dafe8f99da6015b1d9..dc9cdaaee1fb80923b04e89d6ef25c185601acb9 100644 (file)
@@ -901,7 +901,7 @@ static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
        pcm->private_data = saa7134;
        pcm->info_flags = 0;
-       strcpy(pcm->name, "SAA7134 PCM");
+       strscpy(pcm->name, "SAA7134 PCM", sizeof(pcm->name));
        return 0;
 }
 
@@ -1074,7 +1074,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
        unsigned int idx;
        int err, addr;
 
-       strcpy(card->mixername, "SAA7134 Mixer");
+       strscpy(card->mixername, "SAA7134 Mixer", sizeof(card->mixername));
 
        for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
                kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
@@ -1138,7 +1138,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
        if (err < 0)
                return err;
 
-       strcpy(card->driver, "SAA7134");
+       strscpy(card->driver, "SAA7134", sizeof(card->driver));
 
        /* Card "creation" */
 
@@ -1178,7 +1178,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 
        /* End of "creation" */
 
-       strcpy(card->shortname, "SAA7134");
+       strscpy(card->shortname, "SAA7134", sizeof(card->shortname));
        sprintf(card->longname, "%s at 0x%lx irq %d",
                chip->dev->name, chip->iobase, chip->irq);
 
index 9d6688a82b509466a60522afe6d620c6c7b2627d..40ce033cb8840388723c1896d940075ddcb87b0b 100644 (file)
@@ -3628,6 +3628,21 @@ struct saa7134_board saa7134_boards[] = {
                        .vmux   = 1,
                        .amux   = TV,
                        .gpio   = 0x0200000,
+               },{
+                       .type = SAA7134_INPUT_COMPOSITE1,
+                       .vmux = 3,
+                       .amux = LINE2,
+                       .gpio = 0x0200000,
+               },{
+                       .type = SAA7134_INPUT_COMPOSITE2,
+                       .vmux = 0,
+                       .amux = LINE2,
+                       .gpio = 0x0200000,
+               },{
+                       .type = SAA7134_INPUT_SVIDEO,
+                       .vmux = 8,
+                       .amux = LINE2,
+                       .gpio = 0x0200000,
                }},
        },
        [SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA] = {
index 9e76de2411ae6c77ac8b5c20097b05c9e12f7532..8984b1bf57a58f88604479fb5f813b7d21555545 100644 (file)
@@ -845,12 +845,13 @@ static void saa7134_create_entities(struct saa7134_dev *dev)
         */
        if (!decoder) {
                dev->demod.name = "saa713x";
-               dev->demod_pad[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
-               dev->demod_pad[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
-               dev->demod_pad[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               dev->demod_pad[SAA7134_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+               dev->demod_pad[SAA7134_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
+               dev->demod_pad[SAA7134_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               dev->demod_pad[SAA7134_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
                dev->demod.function = MEDIA_ENT_F_ATV_DECODER;
 
-               ret = media_entity_pads_init(&dev->demod, DEMOD_NUM_PADS,
+               ret = media_entity_pads_init(&dev->demod, SAA7134_NUM_PADS,
                                             dev->demod_pad);
                if (ret < 0)
                        pr_err("failed to initialize demod pad!\n");
index 66acfd35ffc601f84f3b8bc718aeb9896402ee17..9735bbb908e3cb02b59ce1892803029c508f15b8 100644 (file)
@@ -100,7 +100,7 @@ static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strlcpy(f->description, "MPEG TS", sizeof(f->description));
+       strscpy(f->description, "MPEG TS", sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_MPEG;
        f->flags = V4L2_FMT_FLAG_COMPRESSED;
        return 0;
@@ -265,9 +265,9 @@ static int empress_init(struct saa7134_dev *dev)
                 "%s empress (%s)", dev->name,
                 saa7134_boards[dev->board].name);
        v4l2_ctrl_handler_init(hdl, 21);
-       v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter);
+       v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter, false);
        if (dev->empress_sd)
-               v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL);
+               v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL, true);
        if (hdl->error) {
                video_device_release(dev->empress_dev);
                return hdl->error;
index 2799538e2d7e043ac70a4985daee314a9392f18b..275c5e15181886f20218ca519bc8a6d32a8ca49b 100644 (file)
@@ -435,7 +435,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev)
 
        go->board_id = GO7007_BOARDID_PCI_VOYAGER;
        snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
-       strlcpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
+       strscpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
        go->hpi_ops = &saa7134_go7007_hpi_ops;
        go->hpi_context = saa;
        saa->dev = dev;
index cf1e526de56ac0fadd1c75b05b964481d8ec3e09..51af3310654c2d12e7e6dc6c8d59c588490c0503 100644 (file)
@@ -437,7 +437,7 @@ int saa7134_i2c_register(struct saa7134_dev *dev)
 {
        dev->i2c_adap = saa7134_adap_template;
        dev->i2c_adap.dev.parent = &dev->pci->dev;
-       strcpy(dev->i2c_adap.name,dev->name);
+       strscpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
        dev->i2c_adap.algo_data = dev;
        i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
        i2c_add_adapter(&dev->i2c_adap);
index 0e28c5021ac480f733cace74fa401b252da4d5ab..999b2774b220afb0269d2d1b08cc825b46201689 100644 (file)
@@ -953,7 +953,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 
        memset(&info, 0, sizeof(struct i2c_board_info));
        memset(&dev->init_data, 0, sizeof(dev->init_data));
-       strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+       strscpy(info.type, "ir_video", I2C_NAME_SIZE);
 
        switch (dev->board) {
        case SAA7134_BOARD_PINNACLE_PCTV_110i:
index 1a50ec9d084f3d6e78fb50ae818b9330071e4ba2..8f28741ebb359c7a77456cf6637ed9e689be10d1 100644 (file)
@@ -1445,7 +1445,8 @@ int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i)
        if (card_in(dev, i->index).type == SAA7134_NO_INPUT)
                return -EINVAL;
        i->index = n;
-       strcpy(i->name, saa7134_input_name[card_in(dev, n).type]);
+       strscpy(i->name, saa7134_input_name[card_in(dev, n).type],
+               sizeof(i->name));
        switch (card_in(dev, n).type) {
        case SAA7134_INPUT_TV:
        case SAA7134_INPUT_TV_MONO:
@@ -1502,8 +1503,8 @@ int saa7134_querycap(struct file *file, void *priv,
 
        unsigned int tuner_type = dev->tuner_type;
 
-       strcpy(cap->driver, "saa7134");
-       strlcpy(cap->card, saa7134_boards[dev->board].name,
+       strscpy(cap->driver, "saa7134", sizeof(cap->driver));
+       strscpy(cap->card, saa7134_boards[dev->board].name,
                sizeof(cap->card));
        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
 
@@ -1747,7 +1748,7 @@ int saa7134_g_tuner(struct file *file, void *priv,
        if (n == SAA7134_INPUT_MAX)
                return -EINVAL;
        if (card_in(dev, n).type != SAA7134_NO_INPUT) {
-               strcpy(t->name, "Television");
+               strscpy(t->name, "Television", sizeof(t->name));
                t->type = V4L2_TUNER_ANALOG_TV;
                saa_call_all(dev, tuner, g_tuner, t);
                t->capability = V4L2_TUNER_CAP_NORM |
@@ -1819,7 +1820,7 @@ static int saa7134_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index >= FORMATS)
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name,
+       strscpy(f->description, formats[f->index].name,
                sizeof(f->description));
 
        f->pixelformat = formats[f->index].fourcc;
@@ -1838,7 +1839,7 @@ static int saa7134_enum_fmt_vid_overlay(struct file *file, void  *priv,
        if ((f->index >= FORMATS) || formats[f->index].planar)
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name,
+       strscpy(f->description, formats[f->index].name,
                sizeof(f->description));
 
        f->pixelformat = formats[f->index].fourcc;
@@ -1939,7 +1940,7 @@ static int radio_g_tuner(struct file *file, void *priv,
        if (0 != t->index)
                return -EINVAL;
 
-       strcpy(t->name, "Radio");
+       strscpy(t->name, "Radio", sizeof(t->name));
 
        saa_call_all(dev, tuner, g_tuner, t);
        t->audmode &= V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO;
@@ -2136,7 +2137,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
                hdl = &dev->radio_ctrl_handler;
                v4l2_ctrl_handler_init(hdl, 2);
                v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler,
-                               v4l2_ctrl_radio_filter);
+                               v4l2_ctrl_radio_filter, false);
                if (hdl->error)
                        return hdl->error;
        }
index d99e937a98c120a3aafa1f739c9ed83257fbe7a8..4802284560140ec1395b69daba439ef4bdf6ceb4 100644 (file)
@@ -547,6 +547,12 @@ struct saa7134_mpeg_ops {
                                                  unsigned long status);
 };
 
+enum saa7134_pads {
+       SAA7134_PAD_IF_INPUT,
+       SAA7134_PAD_VID_OUT,
+       SAA7134_NUM_PADS
+};
+
 /* global device status */
 struct saa7134_dev {
        struct list_head           devlist;
@@ -674,7 +680,7 @@ struct saa7134_dev {
        struct media_pad input_pad[SAA7134_INPUT_MAX + 1];
 
        struct media_entity demod;
-       struct media_pad demod_pad[DEMOD_NUM_PADS];
+       struct media_pad demod_pad[SAA7134_NUM_PADS];
 
        struct media_pad video_pad, vbi_pad;
        struct media_entity *decoder;
index 6b5582b7c5955ca1b514712ac83f60a228f6c16c..44440c6208df3fa66c2fbe5c26430ca72658604b 100644 (file)
@@ -553,7 +553,7 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
        DEB_EE("VIDIOC_G_TUNER: %d\n", t->index);
 
        memset(t, 0, sizeof(*t));
-       strlcpy(t->name, "TV Tuner", sizeof(t->name));
+       strscpy(t->name, "TV Tuner", sizeof(t->name));
        t->type = V4L2_TUNER_ANALOG_TV;
        t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
                        V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
index d697e1ad929c2d8e765feb15f136563b103bef05..f33349e163591ab8867836946bde988eb552d3f3 100644 (file)
@@ -179,7 +179,7 @@ static void saa7164_histogram_reset(struct saa7164_histogram *hg, char *name)
        int i;
 
        memset(hg, 0, sizeof(struct saa7164_histogram));
-       strcpy(hg->name, name);
+       strscpy(hg->name, name, sizeof(hg->name));
 
        /* First 30ms x 1ms */
        for (i = 0; i < 30; i++)
index 4f9f03c3b2523e5485970b7a2a8f78cd8e0f826b..dfb118d7d1ec9d8da27dea14ea76b9c98d3d4265 100644 (file)
@@ -120,7 +120,7 @@ static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter,
 
        memset(&bi, 0, sizeof(bi));
 
-       strlcpy(bi.type, "si2157", I2C_NAME_SIZE);
+       strscpy(bi.type, "si2157", I2C_NAME_SIZE);
        bi.platform_data = cfg;
        bi.addr = addr8bit >> 1;
 
@@ -643,7 +643,7 @@ int saa7164_dvb_register(struct saa7164_port *port)
                        si2168_config.fe = &port->dvb.frontend;
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0xc8 >> 1;
                        info.platform_data = &si2168_config;
                        request_module(info.type);
@@ -663,7 +663,7 @@ int saa7164_dvb_register(struct saa7164_port *port)
                        si2157_config.if_port = 1;
                        si2157_config.fe = port->dvb.frontend;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0xc0 >> 1;
                        info.platform_data = &si2157_config;
                        request_module(info.type);
@@ -688,7 +688,7 @@ int saa7164_dvb_register(struct saa7164_port *port)
                        si2168_config.fe = &port->dvb.frontend;
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0xcc >> 1;
                        info.platform_data = &si2168_config;
                        request_module(info.type);
@@ -708,7 +708,7 @@ int saa7164_dvb_register(struct saa7164_port *port)
                        si2157_config.fe = port->dvb.frontend;
                        si2157_config.if_port = 1;
                        memset(&info, 0, sizeof(struct i2c_board_info));
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0xc0 >> 1;
                        info.platform_data = &si2157_config;
                        request_module(info.type);
index 32136ebe4f61c638c3eaa0e613ff4589655bdccd..adec2bab8352daedf0016ceef827cb6c6a909ecd 100644 (file)
@@ -258,7 +258,7 @@ int saa7164_enum_input(struct file *file, void *priv, struct v4l2_input *i)
        if (i->index >= 7)
                return -EINVAL;
 
-       strcpy(i->name, inputs[i->index]);
+       strscpy(i->name, inputs[i->index], sizeof(i->name));
 
        if (i->index == 0)
                i->type = V4L2_INPUT_TYPE_TUNER;
@@ -325,7 +325,7 @@ int saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
        if (0 != t->index)
                return -EINVAL;
 
-       strcpy(t->name, "tuner");
+       strscpy(t->name, "tuner", sizeof(t->name));
        t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
        t->rangelow = SAA7164_TV_MIN_FREQ;
        t->rangehigh = SAA7164_TV_MAX_FREQ;
@@ -497,8 +497,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct saa7164_port *port = fh->port;
        struct saa7164_dev *dev = port->dev;
 
-       strcpy(cap->driver, dev->name);
-       strlcpy(cap->card, saa7164_boards[dev->board].name,
+       strscpy(cap->driver, dev->name, sizeof(cap->driver));
+       strscpy(cap->card, saa7164_boards[dev->board].name,
                sizeof(cap->card));
        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
 
@@ -520,7 +520,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strlcpy(f->description, "MPEG", sizeof(f->description));
+       strscpy(f->description, "MPEG", sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_MPEG;
 
        return 0;
index 6d13cbb9d010d556a34e44bf40d16324532b6258..317f48bc65068a088ae2c7347df022168575f62a 100644 (file)
@@ -99,7 +99,7 @@ int saa7164_i2c_register(struct saa7164_i2c *bus)
 
        bus->i2c_adap.dev.parent = &dev->pci->dev;
 
-       strlcpy(bus->i2c_adap.name, bus->dev->name,
+       strscpy(bus->i2c_adap.name, bus->dev->name,
                sizeof(bus->i2c_adap.name));
 
        bus->i2c_adap.algo_data = bus;
index 221de91a8bae5731a1e046ab77458a4880a9e122..841c7e94405d28c6cb701cd15dc87084c4ed5994 100644 (file)
@@ -208,8 +208,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct saa7164_port *port = fh->port;
        struct saa7164_dev *dev = port->dev;
 
-       strcpy(cap->driver, dev->name);
-       strlcpy(cap->card, saa7164_boards[dev->board].name,
+       strscpy(cap->driver, dev->name, sizeof(cap->driver));
+       strscpy(cap->card, saa7164_boards[dev->board].name,
                sizeof(cap->card));
        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
 
index 6dbe3b4d09cee5e5d37bc7aac86fdb1db9afbb1a..4d5ddbcb35149e5bdb059470b2ddc7a843f23249 100644 (file)
@@ -191,7 +191,7 @@ static int smi_i2c_init(struct smi_dev *dev)
        /* i2c bus 0 */
        smi_i2c_cfg(dev, I2C_A_SW_CTL);
        i2c_set_adapdata(&dev->i2c_bus[0], dev);
-       strcpy(dev->i2c_bus[0].name, "SMI-I2C0");
+       strscpy(dev->i2c_bus[0].name, "SMI-I2C0", sizeof(dev->i2c_bus[0].name));
        dev->i2c_bus[0].owner = THIS_MODULE;
        dev->i2c_bus[0].dev.parent = &dev->pci_dev->dev;
        dev->i2c_bus[0].algo_data = &dev->i2c_bit[0];
@@ -213,7 +213,7 @@ static int smi_i2c_init(struct smi_dev *dev)
        /* i2c bus 1 */
        smi_i2c_cfg(dev, I2C_B_SW_CTL);
        i2c_set_adapdata(&dev->i2c_bus[1], dev);
-       strcpy(dev->i2c_bus[1].name, "SMI-I2C1");
+       strscpy(dev->i2c_bus[1].name, "SMI-I2C1", sizeof(dev->i2c_bus[1].name));
        dev->i2c_bus[1].owner = THIS_MODULE;
        dev->i2c_bus[1].dev.parent = &dev->pci_dev->dev;
        dev->i2c_bus[1].algo_data = &dev->i2c_bit[1];
@@ -549,7 +549,7 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port)
        }
        /* attach tuner */
        ts2020_config.fe = port->fe;
-       strlcpy(tuner_info.type, "ts2020", I2C_NAME_SIZE);
+       strscpy(tuner_info.type, "ts2020", I2C_NAME_SIZE);
        tuner_info.addr = 0x60;
        tuner_info.platform_data = &ts2020_config;
        tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info);
@@ -605,7 +605,7 @@ static int smi_dvbsky_m88rs6000_fe_attach(struct smi_port *port)
        }
        /* attach tuner */
        m88rs6000t_config.fe = port->fe;
-       strlcpy(tuner_info.type, "m88rs6000t", I2C_NAME_SIZE);
+       strscpy(tuner_info.type, "m88rs6000t", I2C_NAME_SIZE);
        tuner_info.addr = 0x21;
        tuner_info.platform_data = &m88rs6000t_config;
        tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info);
@@ -647,7 +647,7 @@ static int smi_dvbsky_sit2_fe_attach(struct smi_port *port)
        si2168_config.ts_mode = SI2168_TS_PARALLEL;
 
        memset(&client_info, 0, sizeof(struct i2c_board_info));
-       strlcpy(client_info.type, "si2168", I2C_NAME_SIZE);
+       strscpy(client_info.type, "si2168", I2C_NAME_SIZE);
        client_info.addr = 0x64;
        client_info.platform_data = &si2168_config;
 
@@ -664,7 +664,7 @@ static int smi_dvbsky_sit2_fe_attach(struct smi_port *port)
        si2157_config.if_port = 1;
 
        memset(&client_info, 0, sizeof(struct i2c_board_info));
-       strlcpy(client_info.type, "si2157", I2C_NAME_SIZE);
+       strscpy(client_info.type, "si2157", I2C_NAME_SIZE);
        client_info.addr = 0x60;
        client_info.platform_data = &si2157_config;
 
index 2ac33b5cc45466ba2455455343aefc93f835f2e9..2cc05a9d57ac17e854533c1a8d68e5c6e5de1e04 100644 (file)
@@ -354,7 +354,7 @@ static int solo_snd_pcm_init(struct solo_dev *solo_dev)
 
        snd_pcm_chip(pcm) = solo_dev;
        pcm->info_flags = 0;
-       strcpy(pcm->name, card->shortname);
+       strscpy(pcm->name, card->shortname, sizeof(pcm->name));
 
        for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
             ss; ss = ss->next, i++)
@@ -394,8 +394,8 @@ int solo_g723_init(struct solo_dev *solo_dev)
 
        card = solo_dev->snd_card;
 
-       strcpy(card->driver, SOLO6X10_NAME);
-       strcpy(card->shortname, "SOLO-6x10 Audio");
+       strscpy(card->driver, SOLO6X10_NAME, sizeof(card->driver));
+       strscpy(card->shortname, "SOLO-6x10 Audio", sizeof(card->shortname));
        sprintf(card->longname, "%s on %s IRQ %d", card->shortname,
                pci_name(solo_dev->pdev), solo_dev->pdev->irq);
 
@@ -404,7 +404,7 @@ int solo_g723_init(struct solo_dev *solo_dev)
                goto snd_error;
 
        /* Mixer controls */
-       strcpy(card->mixername, "SOLO-6x10");
+       strscpy(card->mixername, "SOLO-6x10", sizeof(card->mixername));
        kctl = snd_solo_capture_volume;
        kctl.count = solo_dev->nr_chans;
 
index 25f9f2ebff1da3ace2e4c1192ba83ec0fe66b2f3..9d27e7463070f3bc3821dfd1b91a0b68144528a0 100644 (file)
@@ -775,7 +775,7 @@ static int solo_enc_querycap(struct file *file, void  *priv,
        struct solo_enc_dev *solo_enc = video_drvdata(file);
        struct solo_dev *solo_dev = solo_enc->solo_dev;
 
-       strcpy(cap->driver, SOLO6X10_NAME);
+       strscpy(cap->driver, SOLO6X10_NAME, sizeof(cap->driver));
        snprintf(cap->card, sizeof(cap->card), "Softlogic 6x10 Enc %d",
                 solo_enc->ch);
        snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
@@ -834,17 +834,18 @@ static int solo_enc_enum_fmt_cap(struct file *file, void *priv,
                switch (dev_type) {
                case SOLO_DEV_6010:
                        f->pixelformat = V4L2_PIX_FMT_MPEG4;
-                       strcpy(f->description, "MPEG-4 part 2");
+                       strscpy(f->description, "MPEG-4 part 2",
+                               sizeof(f->description));
                        break;
                case SOLO_DEV_6110:
                        f->pixelformat = V4L2_PIX_FMT_H264;
-                       strcpy(f->description, "H.264");
+                       strscpy(f->description, "H.264", sizeof(f->description));
                        break;
                }
                break;
        case 1:
                f->pixelformat = V4L2_PIX_FMT_MJPEG;
-               strcpy(f->description, "MJPEG");
+               strscpy(f->description, "MJPEG", sizeof(f->description));
                break;
        default:
                return -EINVAL;
@@ -1126,7 +1127,8 @@ static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
                                        solo_enc->md_thresholds->p_new.p_u16);
                break;
        case V4L2_CID_OSD_TEXT:
-               strcpy(solo_enc->osd_text, ctrl->p_new.p_char);
+               strscpy(solo_enc->osd_text, ctrl->p_new.p_char,
+                       sizeof(solo_enc->osd_text));
                return solo_osd_print(solo_enc);
        default:
                return -EINVAL;
index 99ffd1ed4a73a9b56920ceba645b6c2ff473a291..69fc939fd3d9870eeb77e140e4430a5eb41c4423 100644 (file)
@@ -383,8 +383,8 @@ static int solo_querycap(struct file *file, void  *priv,
 {
        struct solo_dev *solo_dev = video_drvdata(file);
 
-       strcpy(cap->driver, SOLO6X10_NAME);
-       strcpy(cap->card, "Softlogic 6x10");
+       strscpy(cap->driver, SOLO6X10_NAME, sizeof(cap->driver));
+       strscpy(cap->card, "Softlogic 6x10", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
                 pci_name(solo_dev->pdev));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
@@ -470,7 +470,7 @@ static int solo_enum_fmt_cap(struct file *file, void *priv,
                return -EINVAL;
 
        f->pixelformat = V4L2_PIX_FMT_UYVY;
-       strlcpy(f->description, "UYUV 4:2:2 Packed", sizeof(f->description));
+       strscpy(f->description, "UYUV 4:2:2 Packed", sizeof(f->description));
 
        return 0;
 }
index 1858efedaf1a42d84935b040086d53e8e5e0ad3b..411177ec4d723ead50634df7d94a5d570d5b46f4 100644 (file)
@@ -419,8 +419,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct sta2x11_vip *vip = video_drvdata(file);
 
-       strcpy(cap->driver, KBUILD_MODNAME);
-       strcpy(cap->card, KBUILD_MODNAME);
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
                 pci_name(vip->pdev));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
@@ -580,7 +580,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strcpy(f->description, "4:2:2, packed, UYVY");
+       strscpy(f->description, "4:2:2, packed, UYVY", sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_UYVY;
        f->flags = 0;
        return 0;
index d6816effb87866b80eae57d7c45004524d8cc031..409defc75c0569caf013976c4cc9ff0a3ec6b803 100644 (file)
@@ -2482,7 +2482,8 @@ static int av7110_attach(struct saa7146_dev* dev,
           get recognized before the main driver is fully loaded */
        saa7146_write(dev, GPIO_CTRL, 0x500000);
 
-       strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
+       strscpy(av7110->i2c_adap.name, pci_ext->ext_priv,
+               sizeof(av7110->i2c_adap.name));
 
        saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
 
index ef1bc17cdc4d37a8549b86d7085a8fdfd76abca3..1073e4671b68ed0eca82ea28a4a194693cb86bfd 100644 (file)
@@ -932,7 +932,6 @@ static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event
        return 0;
 }
 
-
 /******************************************************************************
  * DVB device file operations
  ******************************************************************************/
@@ -1095,6 +1094,42 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
                return 0;
 }
 
+#ifdef CONFIG_COMPAT
+struct compat_video_still_picture {
+       compat_uptr_t iFrame;
+       int32_t size;
+};
+#define VIDEO_STILLPICTURE32 _IOW('o', 30, struct compat_video_still_picture)
+
+struct compat_video_event {
+       __s32 type;
+       /* unused, make sure to use atomic time for y2038 if it ever gets used */
+       compat_long_t timestamp;
+       union {
+               video_size_t size;
+               unsigned int frame_rate;        /* in frames per 1000sec */
+               unsigned char vsync_field;      /* unknown/odd/even/progressive */
+       } u;
+};
+#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event)
+
+static int dvb_compat_video_get_event(struct av7110 *av7110,
+                                     struct compat_video_event *event, int flags)
+{
+       struct video_event ev;
+       int ret;
+
+       ret = dvb_video_get_event(av7110, &ev, flags);
+
+       *event = (struct compat_video_event) {
+               .type = ev.type,
+               .timestamp = ev.timestamp,
+               .u.size = ev.u.size,
+       };
+
+       return ret;
+}
+#endif
 
 static int dvb_video_ioctl(struct file *file,
                           unsigned int cmd, void *parg)
@@ -1184,6 +1219,12 @@ static int dvb_video_ioctl(struct file *file,
                memcpy(parg, &av7110->videostate, sizeof(struct video_status));
                break;
 
+#ifdef CONFIG_COMPAT
+       case VIDEO_GET_EVENT32:
+               ret = dvb_compat_video_get_event(av7110, parg, file->f_flags);
+               break;
+#endif
+
        case VIDEO_GET_EVENT:
                ret = dvb_video_get_event(av7110, parg, file->f_flags);
                break;
@@ -1226,6 +1267,19 @@ static int dvb_video_ioctl(struct file *file,
                                    1, (u16) arg);
                break;
 
+#ifdef CONFIG_COMPAT
+       case VIDEO_STILLPICTURE32:
+       {
+               struct compat_video_still_picture *pic =
+                       (struct compat_video_still_picture *) parg;
+               av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
+               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
+               ret = play_iframe(av7110, compat_ptr(pic->iFrame),
+                                 pic->size, file->f_flags & O_NONBLOCK);
+               break;
+       }
+#endif
+
        case VIDEO_STILLPICTURE:
        {
                struct video_still_picture *pic =
@@ -1533,6 +1587,7 @@ static const struct file_operations dvb_video_fops = {
        .owner          = THIS_MODULE,
        .write          = dvb_video_write,
        .unlocked_ioctl = dvb_generic_ioctl,
+       .compat_ioctl   = dvb_generic_ioctl,
        .open           = dvb_video_open,
        .release        = dvb_video_release,
        .poll           = dvb_video_poll,
@@ -1552,6 +1607,7 @@ static const struct file_operations dvb_audio_fops = {
        .owner          = THIS_MODULE,
        .write          = dvb_audio_write,
        .unlocked_ioctl = dvb_generic_ioctl,
+       .compat_ioctl   = dvb_generic_ioctl,
        .open           = dvb_audio_open,
        .release        = dvb_audio_release,
        .poll           = dvb_audio_poll,
index e4cf42c322840d7fb17e6bbb2e22ca11d141908a..d1fe15365f4a0f9b37d4431aa386dc5d1bda80a7 100644 (file)
@@ -332,7 +332,7 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
                return -EINVAL;
 
        memset(t, 0, sizeof(*t));
-       strcpy((char *)t->name, "Television");
+       strscpy((char *)t->name, "Television", sizeof(t->name));
 
        t->type = V4L2_TUNER_ANALOG_TV;
        t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
index b3dc45b91101ddb0861c41de1c083b70aabe1eb7..35b696bdb2df043468dd86a4881480925ee532e7 100644 (file)
@@ -504,10 +504,12 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
        if (bi->type != BUDGET_FS_ACTIVY)
                saa7146_write(dev, GPIO_CTRL, 0x500000);        /* GPIO 3 = 1 */
 
-       strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
+       strscpy(budget->i2c_adap.name, budget->card->name,
+               sizeof(budget->i2c_adap.name));
 
        saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
-       strcpy(budget->i2c_adap.name, budget->card->name);
+       strscpy(budget->i2c_adap.name, budget->card->name,
+               sizeof(budget->i2c_adap.name));
 
        if (i2c_add_adapter(&budget->i2c_adap) < 0) {
                ret = -ENOMEM;
index ff2b7da90c088694a83f7c908536aebfd5c8a8a1..5a1f3aa4101ae19f6626519b01d8310747514ccb 100644 (file)
@@ -610,7 +610,7 @@ static int tw5864_querycap(struct file *file, void *priv,
 {
        struct tw5864_input *input = video_drvdata(file);
 
-       strcpy(cap->driver, "tw5864");
+       strscpy(cap->driver, "tw5864", sizeof(cap->driver));
        snprintf(cap->card, sizeof(cap->card), "TW5864 Encoder %d",
                 input->nr);
        sprintf(cap->bus_info, "PCI:%s", pci_name(input->root->pci));
index 8c1f4a049764bda53cd98230c5577a640e037896..d3f727045ae8470e9b78f9364492cf79ee943dd6 100644 (file)
@@ -734,8 +734,8 @@ static int tw68_querycap(struct file *file, void  *priv,
 {
        struct tw68_dev *dev = video_drvdata(file);
 
-       strcpy(cap->driver, "tw68");
-       strlcpy(cap->card, "Techwell Capture Card",
+       strscpy(cap->driver, "tw68", sizeof(cap->driver));
+       strscpy(cap->card, "Techwell Capture Card",
                sizeof(cap->card));
        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
        cap->device_caps =
@@ -789,7 +789,7 @@ static int tw68_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index >= FORMATS)
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name,
+       strscpy(f->description, formats[f->index].name,
                sizeof(f->description));
 
        f->pixelformat = formats[f->index].fourcc;
index 77190768622a6262418a6e62c7bed5bf341760e1..a28329698e205a86720b519b8e92612abe9e99a3 100644 (file)
@@ -295,7 +295,7 @@ static int tw686x_snd_pcm_init(struct tw686x_dev *dev)
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &tw686x_pcm_ops);
        snd_pcm_chip(pcm) = dev;
        pcm->info_flags = 0;
-       strlcpy(pcm->name, "tw686x PCM", sizeof(pcm->name));
+       strscpy(pcm->name, "tw686x PCM", sizeof(pcm->name));
 
        for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
             ss; ss = ss->next, i++)
@@ -390,9 +390,9 @@ int tw686x_audio_init(struct tw686x_dev *dev)
                return err;
 
        dev->snd_card = card;
-       strlcpy(card->driver, "tw686x", sizeof(card->driver));
-       strlcpy(card->shortname, "tw686x", sizeof(card->shortname));
-       strlcpy(card->longname, pci_name(pci_dev), sizeof(card->longname));
+       strscpy(card->driver, "tw686x", sizeof(card->driver));
+       strscpy(card->shortname, "tw686x", sizeof(card->shortname));
+       strscpy(card->longname, pci_name(pci_dev), sizeof(card->longname));
        snd_card_set_dev(card, &pci_dev->dev);
 
        for (ch = 0; ch < max_channels(dev); ch++) {
index 3a06c000f97bbf629c8539002cddb7d869baa850..4890b7f1248b1f7cc1ab01b2967808c991142c29 100644 (file)
@@ -765,8 +765,8 @@ static int tw686x_querycap(struct file *file, void *priv,
        struct tw686x_video_channel *vc = video_drvdata(file);
        struct tw686x_dev *dev = vc->dev;
 
-       strlcpy(cap->driver, "tw686x", sizeof(cap->driver));
-       strlcpy(cap->card, dev->name, sizeof(cap->card));
+       strscpy(cap->driver, "tw686x", sizeof(cap->driver));
+       strscpy(cap->card, dev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "PCI:%s", pci_name(dev->pci_dev));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
index 54fe90acb5b2962432140949a17e1630361e08ca..70c4f6c54881cc097f8d90c8cea3bb61115a44ab 100644 (file)
@@ -58,6 +58,7 @@ config VIDEO_MUX
        select MULTIPLEXER
        depends on VIDEO_V4L2 && OF && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
        select REGMAP
+       select V4L2_FWNODE
        help
          This driver provides support for N:1 video bus multiplexers.
 
@@ -181,6 +182,15 @@ config VIDEO_CODA
 config VIDEO_IMX_VDOA
        def_tristate VIDEO_CODA if SOC_IMX6Q || COMPILE_TEST
 
+config VIDEO_IMX_PXP
+       tristate "i.MX Pixel Pipeline (PXP)"
+       depends on VIDEO_DEV && VIDEO_V4L2 && (ARCH_MXC || COMPILE_TEST)
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_MEM2MEM_DEV
+       help
+         The i.MX Pixel Pipeline is a memory-to-memory engine for scaling,
+         color space conversion, and rotation.
+
 config VIDEO_MEDIATEK_JPEG
        tristate "Mediatek JPEG Codec driver"
        depends on MTK_IOMMU_V1 || COMPILE_TEST
index 41322ab658027f1d7aa0c571d01ea34444319570..6ab6200dd9c999aac4b30992ac775a56d6e3c66b 100644 (file)
@@ -25,6 +25,8 @@ obj-$(CONFIG_VIDEO_TI_CAL)            += ti-vpe/
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP)                += mx2_emmaprp.o
 obj-$(CONFIG_VIDEO_CODA)               += coda/
 
+obj-$(CONFIG_VIDEO_IMX_PXP)            += imx-pxp.o
+
 obj-$(CONFIG_VIDEO_SH_VEU)             += sh_veu.o
 
 obj-$(CONFIG_CEC_GPIO)                 += cec-gpio/
index b05738a95e55e1dc77449e0780fa6a30b019009f..e13d2b3a7168ff3897f2561dc33415c86f0e86d8 100644 (file)
@@ -1408,8 +1408,8 @@ static int vpfe_querycap(struct file *file, void  *priv,
 
        vpfe_dbg(2, vpfe, "vpfe_querycap\n");
 
-       strlcpy(cap->driver, VPFE_MODULE_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, "TI AM437x VPFE", sizeof(cap->card));
+       strscpy(cap->driver, VPFE_MODULE_NAME, sizeof(cap->driver));
+       strscpy(cap->card, "TI AM437x VPFE", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                        "platform:%s", vpfe->v4l2_dev.name);
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
@@ -2386,7 +2386,7 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe)
        INIT_LIST_HEAD(&vpfe->dma_queue);
 
        vdev = &vpfe->video_dev;
-       strlcpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name));
+       strscpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name));
        vdev->release = video_device_release_empty;
        vdev->fops = &vpfe_fops;
        vdev->ioctl_ops = &vpfe_ioctl_ops;
@@ -2423,30 +2423,32 @@ static const struct v4l2_async_notifier_operations vpfe_async_ops = {
 };
 
 static struct vpfe_config *
-vpfe_get_pdata(struct platform_device *pdev)
+vpfe_get_pdata(struct vpfe_device *vpfe)
 {
        struct device_node *endpoint = NULL;
-       struct v4l2_fwnode_endpoint bus_cfg;
+       struct device *dev = vpfe->pdev;
        struct vpfe_subdev_info *sdinfo;
        struct vpfe_config *pdata;
        unsigned int flags;
        unsigned int i;
        int err;
 
-       dev_dbg(&pdev->dev, "vpfe_get_pdata\n");
+       dev_dbg(dev, "vpfe_get_pdata\n");
 
-       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
-               return pdev->dev.platform_data;
+       v4l2_async_notifier_init(&vpfe->notifier);
 
-       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
+               return dev->platform_data;
+
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return NULL;
 
        for (i = 0; ; i++) {
+               struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
                struct device_node *rem;
 
-               endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
-                                                     endpoint);
+               endpoint = of_graph_get_next_endpoint(dev->of_node, endpoint);
                if (!endpoint)
                        break;
 
@@ -2455,7 +2457,8 @@ vpfe_get_pdata(struct platform_device *pdev)
 
                /* we only support camera */
                sdinfo->inputs[0].index = i;
-               strcpy(sdinfo->inputs[0].name, "Camera");
+               strscpy(sdinfo->inputs[0].name, "Camera",
+                       sizeof(sdinfo->inputs[0].name));
                sdinfo->inputs[0].type = V4L2_INPUT_TYPE_CAMERA;
                sdinfo->inputs[0].std = V4L2_STD_ALL;
                sdinfo->inputs[0].capabilities = V4L2_IN_CAP_STD;
@@ -2473,16 +2476,16 @@ vpfe_get_pdata(struct platform_device *pdev)
                err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
                                                 &bus_cfg);
                if (err) {
-                       dev_err(&pdev->dev, "Could not parse the endpoint\n");
-                       goto done;
+                       dev_err(dev, "Could not parse the endpoint\n");
+                       goto cleanup;
                }
 
                sdinfo->vpfe_param.bus_width = bus_cfg.bus.parallel.bus_width;
 
                if (sdinfo->vpfe_param.bus_width < 8 ||
                        sdinfo->vpfe_param.bus_width > 16) {
-                       dev_err(&pdev->dev, "Invalid bus width.\n");
-                       goto done;
+                       dev_err(dev, "Invalid bus width.\n");
+                       goto cleanup;
                }
 
                flags = bus_cfg.bus.parallel.flags;
@@ -2495,29 +2498,25 @@ vpfe_get_pdata(struct platform_device *pdev)
 
                rem = of_graph_get_remote_port_parent(endpoint);
                if (!rem) {
-                       dev_err(&pdev->dev, "Remote device at %pOF not found\n",
+                       dev_err(dev, "Remote device at %pOF not found\n",
                                endpoint);
-                       goto done;
+                       goto cleanup;
                }
 
-               pdata->asd[i] = devm_kzalloc(&pdev->dev,
-                                            sizeof(struct v4l2_async_subdev),
-                                            GFP_KERNEL);
-               if (!pdata->asd[i]) {
+               pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
+                       &vpfe->notifier, of_fwnode_handle(rem),
+                       sizeof(struct v4l2_async_subdev));
+               if (IS_ERR(pdata->asd[i])) {
                        of_node_put(rem);
-                       pdata = NULL;
-                       goto done;
+                       goto cleanup;
                }
-
-               pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-               pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
-               of_node_put(rem);
        }
 
        of_node_put(endpoint);
        return pdata;
 
-done:
+cleanup:
+       v4l2_async_notifier_cleanup(&vpfe->notifier);
        of_node_put(endpoint);
        return NULL;
 }
@@ -2529,34 +2528,39 @@ done:
  */
 static int vpfe_probe(struct platform_device *pdev)
 {
-       struct vpfe_config *vpfe_cfg = vpfe_get_pdata(pdev);
+       struct vpfe_config *vpfe_cfg;
        struct vpfe_device *vpfe;
        struct vpfe_ccdc *ccdc;
        struct resource *res;
        int ret;
 
-       if (!vpfe_cfg) {
-               dev_err(&pdev->dev, "No platform data\n");
-               return -EINVAL;
-       }
-
        vpfe = devm_kzalloc(&pdev->dev, sizeof(*vpfe), GFP_KERNEL);
        if (!vpfe)
                return -ENOMEM;
 
        vpfe->pdev = &pdev->dev;
+
+       vpfe_cfg = vpfe_get_pdata(vpfe);
+       if (!vpfe_cfg) {
+               dev_err(&pdev->dev, "No platform data\n");
+               return -EINVAL;
+       }
+
        vpfe->cfg = vpfe_cfg;
        ccdc = &vpfe->ccdc;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        ccdc->ccdc_cfg.base_addr = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(ccdc->ccdc_cfg.base_addr))
-               return PTR_ERR(ccdc->ccdc_cfg.base_addr);
+       if (IS_ERR(ccdc->ccdc_cfg.base_addr)) {
+               ret = PTR_ERR(ccdc->ccdc_cfg.base_addr);
+               goto probe_out_cleanup;
+       }
 
        ret = platform_get_irq(pdev, 0);
        if (ret <= 0) {
                dev_err(&pdev->dev, "No IRQ resource\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto probe_out_cleanup;
        }
        vpfe->irq = ret;
 
@@ -2564,14 +2568,15 @@ static int vpfe_probe(struct platform_device *pdev)
                               "vpfe_capture0", vpfe);
        if (ret) {
                dev_err(&pdev->dev, "Unable to request interrupt\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto probe_out_cleanup;
        }
 
        ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev);
        if (ret) {
                vpfe_err(vpfe,
                        "Unable to register v4l2 device.\n");
-               return ret;
+               goto probe_out_cleanup;
        }
 
        /* set the driver data in platform device */
@@ -2595,11 +2600,8 @@ static int vpfe_probe(struct platform_device *pdev)
                goto probe_out_v4l2_unregister;
        }
 
-       vpfe->notifier.subdevs = vpfe->cfg->asd;
-       vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd);
        vpfe->notifier.ops = &vpfe_async_ops;
-       ret = v4l2_async_notifier_register(&vpfe->v4l2_dev,
-                                               &vpfe->notifier);
+       ret = v4l2_async_notifier_register(&vpfe->v4l2_dev, &vpfe->notifier);
        if (ret) {
                vpfe_err(vpfe, "Error registering async notifier\n");
                ret = -EINVAL;
@@ -2610,6 +2612,8 @@ static int vpfe_probe(struct platform_device *pdev)
 
 probe_out_v4l2_unregister:
        v4l2_device_unregister(&vpfe->v4l2_dev);
+probe_out_cleanup:
+       v4l2_async_notifier_cleanup(&vpfe->notifier);
        return ret;
 }
 
@@ -2625,6 +2629,7 @@ static int vpfe_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
 
        v4l2_async_notifier_unregister(&vpfe->notifier);
+       v4l2_async_notifier_cleanup(&vpfe->notifier);
        v4l2_device_unregister(&vpfe->v4l2_dev);
        video_unregister_device(&vpfe->video_dev);
 
index d89e14524d427faa94a04f2ae9402d621788270f..50178968b8a63cc8b34f02984bd4848e216f2034 100644 (file)
@@ -1238,8 +1238,8 @@ static int isc_querycap(struct file *file, void *priv,
 {
        struct isc_device *isc = video_drvdata(file);
 
-       strcpy(cap->driver, ATMEL_ISC_NAME);
-       strcpy(cap->card, "Atmel Image Sensor Controller");
+       strscpy(cap->driver, ATMEL_ISC_NAME, sizeof(cap->driver));
+       strscpy(cap->card, "Atmel Image Sensor Controller", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "platform:%s", isc->v4l2_dev.name);
 
@@ -1393,7 +1393,7 @@ static int isc_enum_input(struct file *file, void *priv,
 
        inp->type = V4L2_INPUT_TYPE_CAMERA;
        inp->std = 0;
-       strcpy(inp->name, "Camera");
+       strscpy(inp->name, "Camera", sizeof(inp->name));
 
        return 0;
 }
@@ -1951,7 +1951,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
        INIT_WORK(&isc->awb_work, isc_awb_work);
 
        /* Register video device */
-       strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
+       strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
        vdev->release           = video_device_release_empty;
        vdev->fops              = &isc_fops;
        vdev->ioctl_ops         = &isc_ioctl_ops;
@@ -1983,8 +1983,10 @@ static void isc_subdev_cleanup(struct isc_device *isc)
 {
        struct isc_subdev_entity *subdev_entity;
 
-       list_for_each_entry(subdev_entity, &isc->subdev_entities, list)
+       list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
                v4l2_async_notifier_unregister(&subdev_entity->notifier);
+               v4l2_async_notifier_cleanup(&subdev_entity->notifier);
+       }
 
        INIT_LIST_HEAD(&isc->subdev_entities);
 }
@@ -2026,7 +2028,6 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 {
        struct device_node *np = dev->of_node;
        struct device_node *epn = NULL, *rem;
-       struct v4l2_fwnode_endpoint v4l2_epn;
        struct isc_subdev_entity *subdev_entity;
        unsigned int flags;
        int ret;
@@ -2034,6 +2035,8 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
        INIT_LIST_HEAD(&isc->subdev_entities);
 
        while (1) {
+               struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 };
+
                epn = of_graph_get_next_endpoint(np, epn);
                if (!epn)
                        return 0;
@@ -2201,8 +2204,15 @@ static int atmel_isc_probe(struct platform_device *pdev)
        }
 
        list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
-               subdev_entity->notifier.subdevs = &subdev_entity->asd;
-               subdev_entity->notifier.num_subdevs = 1;
+               v4l2_async_notifier_init(&subdev_entity->notifier);
+
+               ret = v4l2_async_notifier_add_subdev(&subdev_entity->notifier,
+                                                    subdev_entity->asd);
+               if (ret) {
+                       fwnode_handle_put(subdev_entity->asd->match.fwnode);
+                       goto cleanup_subdev;
+               }
+
                subdev_entity->notifier.ops = &isc_async_ops;
 
                ret = v4l2_async_notifier_register(&isc->v4l2_dev,
index e8db4df1e7c41c96e0b9607b8f1506d9d803357e..fdb255e4a956d0332859a1e8baa6be733aebee2b 100644 (file)
@@ -655,9 +655,9 @@ static int isi_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int isi_querycap(struct file *file, void *priv,
                        struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, "atmel-isi", sizeof(cap->driver));
-       strlcpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
+       strscpy(cap->driver, "atmel-isi", sizeof(cap->driver));
+       strscpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
        return 0;
 }
 
@@ -668,7 +668,7 @@ static int isi_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
-       strlcpy(i->name, "Camera", sizeof(i->name));
+       strscpy(i->name, "Camera", sizeof(i->name));
        return 0;
 }
 
@@ -790,7 +790,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
                        struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
-       struct v4l2_fwnode_endpoint ep;
+       struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
        int err;
 
        /* Default settings for ISI */
@@ -1124,7 +1124,6 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 
 static int isi_graph_init(struct atmel_isi *isi)
 {
-       struct v4l2_async_subdev **subdevs = NULL;
        int ret;
 
        /* Parse the graph to extract a list of subdevice DT nodes. */
@@ -1134,23 +1133,20 @@ static int isi_graph_init(struct atmel_isi *isi)
                return ret;
        }
 
-       /* Register the subdevices notifier. */
-       subdevs = devm_kzalloc(isi->dev, sizeof(*subdevs), GFP_KERNEL);
-       if (!subdevs) {
+       v4l2_async_notifier_init(&isi->notifier);
+
+       ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd);
+       if (ret) {
                of_node_put(isi->entity.node);
-               return -ENOMEM;
+               return ret;
        }
 
-       subdevs[0] = &isi->entity.asd;
-
-       isi->notifier.subdevs = subdevs;
-       isi->notifier.num_subdevs = 1;
        isi->notifier.ops = &isi_graph_notify_ops;
 
        ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
        if (ret < 0) {
                dev_err(isi->dev, "Notifier registration failed\n");
-               of_node_put(isi->entity.node);
+               v4l2_async_notifier_cleanup(&isi->notifier);
                return ret;
        }
 
@@ -1202,7 +1198,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
        isi->vdev->fops = &isi_fops;
        isi->vdev->v4l2_dev = &isi->v4l2_dev;
        isi->vdev->queue = &isi->queue;
-       strlcpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
+       strscpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
        isi->vdev->release = video_device_release;
        isi->vdev->ioctl_ops = &isi_ioctl_ops;
        isi->vdev->lock = &isi->lock;
@@ -1303,6 +1299,7 @@ static int atmel_isi_remove(struct platform_device *pdev)
                        isi->fb_descriptors_phys);
        pm_runtime_disable(&pdev->dev);
        v4l2_async_notifier_unregister(&isi->notifier);
+       v4l2_async_notifier_cleanup(&isi->notifier);
        v4l2_device_unregister(&isi->v4l2_dev);
 
        return 0;
index 43e43c7b3e982324445d0d25c19ccf5964c468d7..31ace114eda14ea788350f07a94402473140bdce 100644 (file)
@@ -361,7 +361,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
 
 static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
 {
-       struct v4l2_fwnode_endpoint v4l2_ep;
+       struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
        struct fwnode_handle *fwh;
        struct device_node *ep;
        int ret;
@@ -378,7 +378,7 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
                return ret;
        }
 
-       if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) {
+       if (v4l2_ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(csi2rx->dev, "Unsupported media bus type: 0x%x\n",
                        v4l2_ep.bus_type);
                of_node_put(ep);
@@ -399,18 +399,22 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
        csi2rx->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
        of_node_put(ep);
 
-       csi2rx->notifier.subdevs = devm_kzalloc(csi2rx->dev,
-                                               sizeof(*csi2rx->notifier.subdevs),
-                                               GFP_KERNEL);
-       if (!csi2rx->notifier.subdevs)
-               return -ENOMEM;
+       v4l2_async_notifier_init(&csi2rx->notifier);
+
+       ret = v4l2_async_notifier_add_subdev(&csi2rx->notifier, &csi2rx->asd);
+       if (ret) {
+               fwnode_handle_put(csi2rx->asd.match.fwnode);
+               return ret;
+       }
 
-       csi2rx->notifier.subdevs[0] = &csi2rx->asd;
-       csi2rx->notifier.num_subdevs = 1;
        csi2rx->notifier.ops = &csi2rx_notifier_ops;
 
-       return v4l2_async_subdev_notifier_register(&csi2rx->subdev,
-                                                  &csi2rx->notifier);
+       ret = v4l2_async_subdev_notifier_register(&csi2rx->subdev,
+                                                 &csi2rx->notifier);
+       if (ret)
+               v4l2_async_notifier_cleanup(&csi2rx->notifier);
+
+       return ret;
 }
 
 static int csi2rx_probe(struct platform_device *pdev)
@@ -450,11 +454,11 @@ static int csi2rx_probe(struct platform_device *pdev)
        ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
                                     csi2rx->pads);
        if (ret)
-               goto err_free_priv;
+               goto err_cleanup;
 
        ret = v4l2_async_register_subdev(&csi2rx->subdev);
        if (ret < 0)
-               goto err_free_priv;
+               goto err_cleanup;
 
        dev_info(&pdev->dev,
                 "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n",
@@ -463,6 +467,8 @@ static int csi2rx_probe(struct platform_device *pdev)
 
        return 0;
 
+err_cleanup:
+       v4l2_async_notifier_cleanup(&csi2rx->notifier);
 err_free_priv:
        kfree(csi2rx);
        return ret;
index 40d0de690ff4ae7896131d13bff644ad59648ace..5042d053b94e21c1f02ddb31e034b6d19de62a6d 100644 (file)
@@ -432,7 +432,7 @@ static int csi2tx_get_resources(struct csi2tx_priv *csi2tx,
 
 static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx)
 {
-       struct v4l2_fwnode_endpoint v4l2_ep;
+       struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
        struct device_node *ep;
        int ret;
 
@@ -446,7 +446,7 @@ static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx)
                goto out;
        }
 
-       if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) {
+       if (v4l2_ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(csi2tx->dev, "Unsupported media bus type: 0x%x\n",
                        v4l2_ep.bus_type);
                ret = -EINVAL;
index 726b3b93a4863184bb84ee792784d69cdcc39333..2848ea5f464d97b746f64a2a43da6651a0e8dea0 100644 (file)
@@ -376,8 +376,7 @@ static struct vdoa_data *coda_get_vdoa_data(void)
                vdoa_data = ERR_PTR(-EPROBE_DEFER);
 
 out:
-       if (vdoa_node)
-               of_node_put(vdoa_node);
+       of_node_put(vdoa_node);
 
        return vdoa_data;
 }
@@ -390,10 +389,10 @@ static int coda_querycap(struct file *file, void *priv,
 {
        struct coda_ctx *ctx = fh_to_ctx(priv);
 
-       strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, coda_product_name(ctx->dev->devtype->product),
+       strscpy(cap->driver, CODA_NAME, sizeof(cap->driver));
+       strscpy(cap->card, coda_product_name(ctx->dev->devtype->product),
                sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
+       strscpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
@@ -1804,7 +1803,8 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
                break;
        case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
                /* TODO: switch between baseline and constrained baseline */
-               ctx->params.h264_profile_idc = 66;
+               if (ctx->inst_type == CODA_INST_ENCODER)
+                       ctx->params.h264_profile_idc = 66;
                break;
        case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
                /* nothing to do, this is set by the encoder */
@@ -2408,7 +2408,7 @@ static int coda_register_device(struct coda_dev *dev, int i)
        if (i >= dev->devtype->num_vdevs)
                return -EINVAL;
 
-       strlcpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name));
+       strscpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name));
        vfd->fops       = &coda_fops;
        vfd->ioctl_ops  = &coda_ioctl_ops;
        vfd->release    = video_device_release_empty,
index f924e76e2fbf869d859c6cea46c6f8945b368a02..340f8218f54d307cd582ecf645ca2228dc0cf067 100644 (file)
@@ -1100,7 +1100,8 @@ fail_nobase_res:
 
        while (i >= 0) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-               release_mem_region(res->start, resource_size(res));
+               if (res)
+                       release_mem_region(res->start, resource_size(res));
                i--;
        }
        vpfe_unregister_ccdc_device(&isif_hw_dev);
index b0eb3d899eb44bfcca33eac2b50194eeb2b70838..5c235898af7b29bcfd83249285a61db539273e8d 100644 (file)
@@ -521,7 +521,7 @@ vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
                else if (v_scale == 4)
                        layer_info->v_zoom = ZOOM_X4;
                if (v_exp)
-                       layer_info->h_exp = V_EXP_6_OVER_5;
+                       layer_info->v_exp = V_EXP_6_OVER_5;
        } else {
                /* no scaling, only cropping. Set display area to crop area */
                cfg->ysize = expected_ysize;
@@ -647,7 +647,7 @@ static int vpbe_display_querycap(struct file *file, void  *priv,
                dev_name(vpbe_dev->pdev));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(vpbe_dev->pdev));
-       strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
+       strscpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
 
        return 0;
 }
@@ -816,10 +816,12 @@ static int vpbe_display_enum_fmt(struct file *file, void  *priv,
        fmt->index = index;
        fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
        if (index == 0) {
-               strcpy(fmt->description, "YUV 4:2:2 - UYVY");
+               strscpy(fmt->description, "YUV 4:2:2 - UYVY",
+                       sizeof(fmt->description));
                fmt->pixelformat = V4L2_PIX_FMT_UYVY;
        } else {
-               strcpy(fmt->description, "Y/CbCr 4:2:0");
+               strscpy(fmt->description, "Y/CbCr 4:2:0",
+                       sizeof(fmt->description));
                fmt->pixelformat = V4L2_PIX_FMT_NV12;
        }
 
index ddcad7b3e76c21d07609a3938e401052940f853a..ca78eb29641af80ac17392221a7ec448d79e0899 100644 (file)
@@ -616,7 +616,7 @@ struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
 
        v4l2_subdev_init(&venc->sd, &venc_ops);
 
-       strcpy(venc->sd.name, venc_name);
+       strscpy(venc->sd.name, venc_name, sizeof(venc->sd.name));
        if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
                v4l2_err(v4l2_dev,
                        "vpbe unable to register venc sub device\n");
index 8613358ed245d75f05c6a528ce62396cc20a5003..ea3ddd5a42bd058e1c35fc6f314d1955eb34aed4 100644 (file)
@@ -889,9 +889,9 @@ static int vpfe_querycap(struct file *file, void  *priv,
 
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-       strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
-       strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
-       strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
+       strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
+       strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
        return 0;
 }
 
index a96f53ce808867f21b6a658532c4264b66704801..6216b7ac6875f753f67afaef464232d78c2e6641 100644 (file)
@@ -949,11 +949,13 @@ static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
        /* Fill in the information about format */
        if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
+               strscpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb",
+                       sizeof(fmt->description));
                fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
        } else {
                fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               strcpy(fmt->description, "YCbCr4:2:2 Semi-Planar");
+               strscpy(fmt->description, "YCbCr4:2:2 Semi-Planar",
+                       sizeof(fmt->description));
                fmt->pixelformat = V4L2_PIX_FMT_NV16;
        }
        return 0;
@@ -1094,10 +1096,10 @@ static int vpif_querycap(struct file *file, void  *priv,
 
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-       strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(vpif_dev));
-       strlcpy(cap->card, config->card_name, sizeof(cap->card));
+       strscpy(cap->card, config->card_name, sizeof(cap->card));
 
        return 0;
 }
@@ -1463,7 +1465,7 @@ static int vpif_probe_complete(void)
 
                /* Initialize the video_device structure */
                vdev = &ch->video_dev;
-               strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+               strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
                vdev->release = video_device_release_empty;
                vdev->fops = &vpif_fops;
                vdev->ioctl_ops = &vpif_ioctl_ops;
@@ -1509,12 +1511,13 @@ static struct vpif_capture_config *
 vpif_capture_get_pdata(struct platform_device *pdev)
 {
        struct device_node *endpoint = NULL;
-       struct v4l2_fwnode_endpoint bus_cfg;
        struct vpif_capture_config *pdata;
        struct vpif_subdev_info *sdinfo;
        struct vpif_capture_chan_config *chan;
        unsigned int i;
 
+       v4l2_async_notifier_init(&vpif_obj.notifier);
+
        /*
         * DT boot: OF node from parent device contains
         * video ports & endpoints data.
@@ -1537,6 +1540,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
                return NULL;
 
        for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) {
+               struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
                struct device_node *rem;
                unsigned int flags;
                int err;
@@ -1546,14 +1550,25 @@ vpif_capture_get_pdata(struct platform_device *pdev)
                if (!endpoint)
                        break;
 
+               rem = of_graph_get_remote_port_parent(endpoint);
+               if (!rem) {
+                       dev_dbg(&pdev->dev, "Remote device at %pOF not found\n",
+                               endpoint);
+                       of_node_put(endpoint);
+                       goto done;
+               }
+
                sdinfo = &pdata->subdev_info[i];
                chan = &pdata->chan_config[i];
                chan->inputs = devm_kcalloc(&pdev->dev,
                                            VPIF_CAPTURE_NUM_CHANNELS,
                                            sizeof(*chan->inputs),
                                            GFP_KERNEL);
-               if (!chan->inputs)
-                       return NULL;
+               if (!chan->inputs) {
+                       of_node_put(rem);
+                       of_node_put(endpoint);
+                       goto err_cleanup;
+               }
 
                chan->input_count++;
                chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
@@ -1562,12 +1577,16 @@ vpif_capture_get_pdata(struct platform_device *pdev)
 
                err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
                                                 &bus_cfg);
+               of_node_put(endpoint);
                if (err) {
                        dev_err(&pdev->dev, "Could not parse the endpoint\n");
+                       of_node_put(rem);
                        goto done;
                }
+
                dev_dbg(&pdev->dev, "Endpoint %pOF, bus_width = %d\n",
                        endpoint, bus_cfg.bus.parallel.bus_width);
+
                flags = bus_cfg.bus.parallel.flags;
 
                if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
@@ -1576,39 +1595,29 @@ vpif_capture_get_pdata(struct platform_device *pdev)
                if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
                        chan->vpif_if.vd_pol = 1;
 
-               rem = of_graph_get_remote_port_parent(endpoint);
-               if (!rem) {
-                       dev_dbg(&pdev->dev, "Remote device at %pOF not found\n",
-                               endpoint);
-                       goto done;
-               }
-
-               dev_dbg(&pdev->dev, "Remote device %s, %pOF found\n",
-                       rem->name, rem);
+               dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem);
                sdinfo->name = rem->full_name;
 
-               pdata->asd[i] = devm_kzalloc(&pdev->dev,
-                                            sizeof(struct v4l2_async_subdev),
-                                            GFP_KERNEL);
-               if (!pdata->asd[i]) {
+               pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
+                       &vpif_obj.notifier, of_fwnode_handle(rem),
+                       sizeof(struct v4l2_async_subdev));
+               if (IS_ERR(pdata->asd[i])) {
                        of_node_put(rem);
-                       pdata = NULL;
-                       goto done;
+                       goto err_cleanup;
                }
-
-               pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-               pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
-               of_node_put(rem);
        }
 
 done:
-       if (pdata) {
-               pdata->asd_sizes[0] = i;
-               pdata->subdev_count = i;
-               pdata->card_name = "DA850/OMAP-L138 Video Capture";
-       }
+       pdata->asd_sizes[0] = i;
+       pdata->subdev_count = i;
+       pdata->card_name = "DA850/OMAP-L138 Video Capture";
 
        return pdata;
+
+err_cleanup:
+       v4l2_async_notifier_cleanup(&vpif_obj.notifier);
+
+       return NULL;
 }
 
 /**
@@ -1633,23 +1642,18 @@ static __init int vpif_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       if (!pdev->dev.platform_data) {
-               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
-               return -EINVAL;
-       }
-
        vpif_dev = &pdev->dev;
 
        err = initialize_vpif();
        if (err) {
                v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
-               return err;
+               goto cleanup;
        }
 
        err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
        if (err) {
                v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
-               return err;
+               goto cleanup;
        }
 
        while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
@@ -1698,8 +1702,6 @@ static __init int vpif_probe(struct platform_device *pdev)
                }
                vpif_probe_complete();
        } else {
-               vpif_obj.notifier.subdevs = vpif_obj.config->asd;
-               vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
                vpif_obj.notifier.ops = &vpif_async_ops;
                err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
                                                   &vpif_obj.notifier);
@@ -1717,6 +1719,8 @@ probe_subdev_out:
        kfree(vpif_obj.sd);
 vpif_unregister:
        v4l2_device_unregister(&vpif_obj.v4l2_dev);
+cleanup:
+       v4l2_async_notifier_cleanup(&vpif_obj.notifier);
 
        return err;
 }
@@ -1732,6 +1736,8 @@ static int vpif_remove(struct platform_device *device)
        struct channel_obj *ch;
        int i;
 
+       v4l2_async_notifier_unregister(&vpif_obj.notifier);
+       v4l2_async_notifier_cleanup(&vpif_obj.notifier);
        v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
        kfree(vpif_obj.sd);
index 0f324055cc9ff21786848a30ab8adcc55dd95d66..3517487d9760bb546876fcd87bb8febf45c82b50 100644 (file)
@@ -586,10 +586,10 @@ static int vpif_querycap(struct file *file, void  *priv,
 
        cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-       strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(vpif_dev));
-       strlcpy(cap->card, config->card_name, sizeof(cap->card));
+       strscpy(cap->card, config->card_name, sizeof(cap->card));
 
        return 0;
 }
@@ -602,7 +602,8 @@ static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
 
        /* Fill in the information about format */
        fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-       strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
+       strscpy(fmt->description, "YCbCr4:2:2 YC Planar",
+               sizeof(fmt->description));
        fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
        fmt->flags = 0;
        return 0;
@@ -1209,7 +1210,7 @@ static int vpif_probe_complete(void)
 
                /* Initialize the video_device structure */
                vdev = &ch->video_dev;
-               strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+               strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
                vdev->release = video_device_release_empty;
                vdev->fops = &vpif_fops;
                vdev->ioctl_ops = &vpif_ioctl_ops;
@@ -1299,6 +1300,8 @@ static __init int vpif_probe(struct platform_device *pdev)
                goto vpif_unregister;
        }
 
+       v4l2_async_notifier_init(&vpif_obj.notifier);
+
        if (!vpif_obj.config->asd_sizes) {
                i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id);
                for (i = 0; i < subdev_count; i++) {
@@ -1322,20 +1325,27 @@ static __init int vpif_probe(struct platform_device *pdev)
                        goto probe_subdev_out;
                }
        } else {
-               vpif_obj.notifier.subdevs = vpif_obj.config->asd;
-               vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
+               for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
+                       err = v4l2_async_notifier_add_subdev(
+                               &vpif_obj.notifier, vpif_obj.config->asd[i]);
+                       if (err)
+                               goto probe_cleanup;
+               }
+
                vpif_obj.notifier.ops = &vpif_async_ops;
                err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
                                                   &vpif_obj.notifier);
                if (err) {
                        vpif_err("Error registering async notifier\n");
                        err = -EINVAL;
-                       goto probe_subdev_out;
+                       goto probe_cleanup;
                }
        }
 
        return 0;
 
+probe_cleanup:
+       v4l2_async_notifier_cleanup(&vpif_obj.notifier);
 probe_subdev_out:
        kfree(vpif_obj.sd);
 vpif_unregister:
@@ -1354,6 +1364,11 @@ static int vpif_remove(struct platform_device *device)
        struct channel_obj *ch;
        int i;
 
+       if (vpif_obj.config->asd_sizes) {
+               v4l2_async_notifier_unregister(&vpif_obj.notifier);
+               v4l2_async_notifier_cleanup(&vpif_obj.notifier);
+       }
+
        v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
        kfree(vpif_obj.sd);
index 17854a379243ce97fa65776320147b7e30749d6a..838c5c53de37d7e92e39926485587c11cb4f93b7 100644 (file)
@@ -339,7 +339,7 @@ int gsc_enum_fmt_mplane(struct v4l2_fmtdesc *f)
        if (!fmt)
                return -EINVAL;
 
-       strlcpy(f->description, fmt->name, sizeof(f->description));
+       strscpy(f->description, fmt->name, sizeof(f->description));
        f->pixelformat = fmt->pixelformat;
 
        return 0;
index c9d2f6c5311a73fd284fe7d7c32d71ba44c844b8..cc5d690818e17d87f901ce10da4e87b31bf4f5f3 100644 (file)
@@ -294,8 +294,8 @@ static int gsc_m2m_querycap(struct file *file, void *fh,
        struct gsc_ctx *ctx = fh_to_ctx(fh);
        struct gsc_dev *gsc = ctx->gsc_dev;
 
-       strlcpy(cap->driver, GSC_MODULE_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, GSC_MODULE_NAME " gscaler", sizeof(cap->card));
+       strscpy(cap->driver, GSC_MODULE_NAME, sizeof(cap->driver));
+       strscpy(cap->card, GSC_MODULE_NAME " gscaler", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(&gsc->pdev->dev));
        cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
index b90f5bb15517b10692890639c3823e7df512cd2e..76f557548dfcbf588ca654592314093f586ac7d3 100644 (file)
@@ -40,8 +40,8 @@ EXPORT_SYMBOL(fimc_find_remote_sensor);
 void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
                                                unsigned int caps)
 {
-       strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
-       strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
+       strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+       strscpy(cap->card, dev->driver->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                                "platform:%s", dev_name(dev));
        cap->device_caps = caps;
index a3cdac18819043df209f1b4df6ffaf34833eeef6..3e9fcf4f8a13d8d1ce5414e6b11e60f53130064f 100644 (file)
@@ -1087,7 +1087,7 @@ static int fimc_cap_enum_input(struct file *file, void *priv,
        fimc_md_graph_unlock(ve);
 
        if (sd)
-               strlcpy(i->name, sd->name, sizeof(i->name));
+               strscpy(i->name, sd->name, sizeof(i->name));
 
        return 0;
 }
@@ -1424,7 +1424,7 @@ static int fimc_link_setup(struct media_entity *entity,
                return 0;
 
        return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
-                                    sensor->ctrl_handler, NULL);
+                                    sensor->ctrl_handler, NULL, true);
 }
 
 static const struct media_entity_operations fimc_sd_media_ops = {
index 70dd4852b2b90ae648f47bb365280b0a9c22feb5..be937caf7645184c681de032b918300edf6fe9f0 100644 (file)
@@ -57,7 +57,7 @@ static int fimc_is_i2c_probe(struct platform_device *pdev)
        i2c_adap = &isp_i2c->adapter;
        i2c_adap->dev.of_node = node;
        i2c_adap->dev.parent = &pdev->dev;
-       strlcpy(i2c_adap->name, "exynos4x12-isp-i2c", sizeof(i2c_adap->name));
+       strscpy(i2c_adap->name, "exynos4x12-isp-i2c", sizeof(i2c_adap->name));
        i2c_adap->owner = THIS_MODULE;
        i2c_adap->algo = &fimc_is_i2c_algorithm;
        i2c_adap->class = I2C_CLASS_SPD;
index 5ddb2321e9e48f74d41c803453cf2e112fcba22a..f5fc54de19dabf91b5943fa0bd535679c8333628 100644 (file)
@@ -656,7 +656,7 @@ static int fimc_is_hw_open_sensor(struct fimc_is *is,
 
 int fimc_is_hw_initialize(struct fimc_is *is)
 {
-       const int config_ids[] = {
+       static const int config_ids[] = {
                IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO,
                IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO
        };
index a920164f53f1f0ab9de8a9947af72ac6cf653c95..de6bd28f7e313d20332bd3fa24f87c4b422cf189 100644 (file)
@@ -365,7 +365,7 @@ static int isp_video_enum_fmt_mplane(struct file *file, void *priv,
        if (WARN_ON(fmt == NULL))
                return -EINVAL;
 
-       strlcpy(f->description, fmt->name, sizeof(f->description));
+       strscpy(f->description, fmt->name, sizeof(f->description));
        f->pixelformat = fmt->fourcc;
 
        return 0;
index 70d5f5586a5d5ca615a8667d6e8946920d381d51..96f0a8a0dcae591f8a069b565a2ca3cf48976eef 100644 (file)
@@ -654,8 +654,8 @@ static int fimc_lite_querycap(struct file *file, void *priv,
 {
        struct fimc_lite *fimc = video_drvdata(file);
 
-       strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
+       strscpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                                        dev_name(&fimc->pdev->dev));
 
@@ -673,7 +673,7 @@ static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv,
                return -EINVAL;
 
        fmt = &fimc_lite_formats[f->index];
-       strlcpy(f->description, fmt->name, sizeof(f->description));
+       strscpy(f->description, fmt->name, sizeof(f->description));
        f->pixelformat = fmt->fourcc;
 
        return 0;
index deb499f76412a33f139aaedc467e038476f905aa..870501b0f351addb127f3b29c0dec9d5dee867d1 100644 (file)
@@ -390,7 +390,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 {
        struct fimc_source_info *pd = &fmd->sensor[index].pdata;
        struct device_node *rem, *ep, *np;
-       struct v4l2_fwnode_endpoint endpoint;
+       struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
        int ret;
 
        /* Assume here a port node can have only one endpoint node. */
@@ -457,11 +457,16 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 
        fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
        fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
-       fmd->async_subdevs[index] = &fmd->sensor[index].asd;
+
+       ret = v4l2_async_notifier_add_subdev(&fmd->subdev_notifier,
+                                            &fmd->sensor[index].asd);
+       if (ret) {
+               of_node_put(rem);
+               return ret;
+       }
 
        fmd->num_sensors++;
 
-       of_node_put(rem);
        return 0;
 }
 
@@ -500,7 +505,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
                ret = fimc_md_parse_port_node(fmd, port, index);
                if (ret < 0) {
                        of_node_put(node);
-                       goto rpm_put;
+                       goto cleanup;
                }
                index++;
        }
@@ -514,11 +519,17 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
                ret = fimc_md_parse_port_node(fmd, node, index);
                if (ret < 0) {
                        of_node_put(node);
-                       break;
+                       goto cleanup;
                }
                index++;
        }
+
 rpm_put:
+       pm_runtime_put(fmd->pmf);
+       return 0;
+
+cleanup:
+       v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
        pm_runtime_put(fmd->pmf);
        return ret;
 }
@@ -1204,9 +1215,9 @@ static ssize_t fimc_md_sysfs_show(struct device *dev,
        struct fimc_md *fmd = dev_get_drvdata(dev);
 
        if (fmd->user_subdev_api)
-               return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
+               return strscpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
 
-       return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
+       return strscpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
 }
 
 static ssize_t fimc_md_sysfs_store(struct device *dev,
@@ -1426,7 +1437,7 @@ static int fimc_md_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&fmd->pipelines);
        fmd->pdev = pdev;
 
-       strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
+       strscpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
                sizeof(fmd->media_dev.model));
        fmd->media_dev.ops = &fimc_md_ops;
        fmd->media_dev.dev = dev;
@@ -1434,7 +1445,7 @@ static int fimc_md_probe(struct platform_device *pdev)
        v4l2_dev = &fmd->v4l2_dev;
        v4l2_dev->mdev = &fmd->media_dev;
        v4l2_dev->notify = fimc_sensor_notify;
-       strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name));
 
        fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
        fmd->user_subdev_api = true;
@@ -1460,6 +1471,8 @@ static int fimc_md_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, fmd);
 
+       v4l2_async_notifier_init(&fmd->subdev_notifier);
+
        ret = fimc_md_register_platform_entities(fmd, dev->of_node);
        if (ret)
                goto err_clk;
@@ -1470,7 +1483,7 @@ static int fimc_md_probe(struct platform_device *pdev)
 
        ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
        if (ret)
-               goto err_m_ent;
+               goto err_cleanup;
        /*
         * FIMC platform devices need to be registered before the sclk_cam
         * clocks provider, as one of these devices needs to be activated
@@ -1483,8 +1496,6 @@ static int fimc_md_probe(struct platform_device *pdev)
        }
 
        if (fmd->num_sensors > 0) {
-               fmd->subdev_notifier.subdevs = fmd->async_subdevs;
-               fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
                fmd->subdev_notifier.ops = &subdev_notifier_ops;
                fmd->num_sensors = 0;
 
@@ -1500,10 +1511,12 @@ err_clk_p:
        fimc_md_unregister_clk_provider(fmd);
 err_attr:
        device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
-err_clk:
-       fimc_md_put_clocks(fmd);
+err_cleanup:
+       v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
 err_m_ent:
        fimc_md_unregister_entities(fmd);
+err_clk:
+       fimc_md_put_clocks(fmd);
 err_md:
        media_device_cleanup(&fmd->media_dev);
        v4l2_device_unregister(&fmd->v4l2_dev);
@@ -1519,6 +1532,7 @@ static int fimc_md_remove(struct platform_device *pdev)
 
        fimc_md_unregister_clk_provider(fmd);
        v4l2_async_notifier_unregister(&fmd->subdev_notifier);
+       v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
 
        v4l2_device_unregister(&fmd->v4l2_dev);
        device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
index 957787a2f48002379639ee362e0ba59935ab7062..9f527670395ab358df836105fa04c8ea6dee6e6e 100644 (file)
@@ -149,7 +149,6 @@ struct fimc_md {
        } clk_provider;
 
        struct v4l2_async_notifier subdev_notifier;
-       struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS];
 
        bool user_subdev_api;
        spinlock_t slock;
index b4e28a299e26e6b6dce99f5da0427f201cfab33b..35cb0162085b4d03bd12e9b6f099fa6759ca0e63 100644 (file)
@@ -718,7 +718,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
                            struct csis_state *state)
 {
        struct device_node *node = pdev->dev.of_node;
-       struct v4l2_fwnode_endpoint endpoint;
+       struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
        int ret;
 
        if (of_property_read_u32(node, "clock-frequency",
index 0273302aa7412f7c83a5b1cfe30ae3cd6050614e..ca6d0317ab4246a72a97a06a0653ce34340104a6 100644 (file)
@@ -565,9 +565,9 @@ static const struct videobuf_queue_ops viu_video_qops = {
 static int vidioc_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
-       strcpy(cap->driver, "viu");
-       strcpy(cap->card, "viu");
-       strcpy(cap->bus_info, "platform:viu");
+       strscpy(cap->driver, "viu", sizeof(cap->driver));
+       strscpy(cap->card, "viu", sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:viu", sizeof(cap->bus_info));
        cap->device_caps =      V4L2_CAP_VIDEO_CAPTURE |
                                V4L2_CAP_STREAMING     |
                                V4L2_CAP_VIDEO_OVERLAY |
@@ -941,7 +941,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 
        inp->type = V4L2_INPUT_TYPE_CAMERA;
        inp->std = fh->dev->vdev->tvnorms;
-       strcpy(inp->name, "Camera");
+       strscpy(inp->name, "Camera", sizeof(inp->name));
        return 0;
 }
 
diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c
new file mode 100644 (file)
index 0000000..b76cd0e
--- /dev/null
@@ -0,0 +1,1754 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * i.MX Pixel Pipeline (PXP) mem-to-mem scaler/CSC/rotator driver
+ *
+ * Copyright (c) 2018 Pengutronix, Philipp Zabel
+ *
+ * based on vim2m
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "imx-pxp.h"
+
+static unsigned int debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+#define MIN_W 8
+#define MIN_H 8
+#define MAX_W 4096
+#define MAX_H 4096
+#define ALIGN_W 3 /* 8x8 pixel blocks */
+#define ALIGN_H 3
+
+/* Flags that indicate a format can be used for capture/output */
+#define MEM2MEM_CAPTURE        (1 << 0)
+#define MEM2MEM_OUTPUT (1 << 1)
+
+#define MEM2MEM_NAME           "pxp"
+
+/* Flags that indicate processing mode */
+#define MEM2MEM_HFLIP  (1 << 0)
+#define MEM2MEM_VFLIP  (1 << 1)
+
+#define dprintk(dev, fmt, arg...) \
+       v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+struct pxp_fmt {
+       u32     fourcc;
+       int     depth;
+       /* Types the format can be used for */
+       u32     types;
+};
+
+static struct pxp_fmt formats[] = {
+       {
+               .fourcc = V4L2_PIX_FMT_XBGR32,
+               .depth  = 32,
+               /* Both capture and output format */
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_ABGR32,
+               .depth  = 32,
+               /* Capture-only format */
+               .types  = MEM2MEM_CAPTURE,
+       }, {
+               .fourcc = V4L2_PIX_FMT_BGR24,
+               .depth  = 24,
+               .types  = MEM2MEM_CAPTURE,
+       }, {
+               .fourcc = V4L2_PIX_FMT_RGB565,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_RGB555,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_RGB444,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV32,
+               .depth  = 32,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_UYVY,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .depth  = 16,
+               /* Output-only format */
+               .types  = MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_VYUY,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YVYU,
+               .depth  = 16,
+               .types  = MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_GREY,
+               .depth  = 8,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_Y4,
+               .depth  = 4,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV16,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV12,
+               .depth  = 12,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV21,
+               .depth  = 12,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_NV61,
+               .depth  = 16,
+               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV422P,
+               .depth  = 16,
+               .types  = MEM2MEM_OUTPUT,
+       }, {
+               .fourcc = V4L2_PIX_FMT_YUV420,
+               .depth  = 12,
+               .types  = MEM2MEM_OUTPUT,
+       },
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct pxp_q_data {
+       unsigned int            width;
+       unsigned int            height;
+       unsigned int            bytesperline;
+       unsigned int            sizeimage;
+       unsigned int            sequence;
+       struct pxp_fmt          *fmt;
+       enum v4l2_ycbcr_encoding ycbcr_enc;
+       enum v4l2_quantization  quant;
+};
+
+enum {
+       V4L2_M2M_SRC = 0,
+       V4L2_M2M_DST = 1,
+};
+
+static struct pxp_fmt *find_format(struct v4l2_format *f)
+{
+       struct pxp_fmt *fmt;
+       unsigned int k;
+
+       for (k = 0; k < NUM_FORMATS; k++) {
+               fmt = &formats[k];
+               if (fmt->fourcc == f->fmt.pix.pixelformat)
+                       break;
+       }
+
+       if (k == NUM_FORMATS)
+               return NULL;
+
+       return &formats[k];
+}
+
+struct pxp_dev {
+       struct v4l2_device      v4l2_dev;
+       struct video_device     vfd;
+
+       struct clk              *clk;
+       void __iomem            *mmio;
+
+       atomic_t                num_inst;
+       struct mutex            dev_mutex;
+       spinlock_t              irqlock;
+
+       struct v4l2_m2m_dev     *m2m_dev;
+};
+
+struct pxp_ctx {
+       struct v4l2_fh          fh;
+       struct pxp_dev  *dev;
+
+       struct v4l2_ctrl_handler hdl;
+
+       /* Abort requested by m2m */
+       int                     aborting;
+
+       /* Processing mode */
+       int                     mode;
+       u8                      alpha_component;
+
+       enum v4l2_colorspace    colorspace;
+       enum v4l2_xfer_func     xfer_func;
+
+       /* Source and destination queue data */
+       struct pxp_q_data   q_data[2];
+};
+
+static inline struct pxp_ctx *file2ctx(struct file *file)
+{
+       return container_of(file->private_data, struct pxp_ctx, fh);
+}
+
+static struct pxp_q_data *get_q_data(struct pxp_ctx *ctx,
+                                        enum v4l2_buf_type type)
+{
+       if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return &ctx->q_data[V4L2_M2M_SRC];
+       else
+               return &ctx->q_data[V4L2_M2M_DST];
+}
+
+static u32 pxp_v4l2_pix_fmt_to_ps_format(u32 v4l2_pix_fmt)
+{
+       switch (v4l2_pix_fmt) {
+       case V4L2_PIX_FMT_XBGR32:  return BV_PXP_PS_CTRL_FORMAT__RGB888;
+       case V4L2_PIX_FMT_RGB555:  return BV_PXP_PS_CTRL_FORMAT__RGB555;
+       case V4L2_PIX_FMT_RGB444:  return BV_PXP_PS_CTRL_FORMAT__RGB444;
+       case V4L2_PIX_FMT_RGB565:  return BV_PXP_PS_CTRL_FORMAT__RGB565;
+       case V4L2_PIX_FMT_YUV32:   return BV_PXP_PS_CTRL_FORMAT__YUV1P444;
+       case V4L2_PIX_FMT_UYVY:    return BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+       case V4L2_PIX_FMT_YUYV:    return BM_PXP_PS_CTRL_WB_SWAP |
+                                         BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+       case V4L2_PIX_FMT_VYUY:    return BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
+       case V4L2_PIX_FMT_YVYU:    return BM_PXP_PS_CTRL_WB_SWAP |
+                                         BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
+       case V4L2_PIX_FMT_GREY:    return BV_PXP_PS_CTRL_FORMAT__Y8;
+       default:
+       case V4L2_PIX_FMT_Y4:      return BV_PXP_PS_CTRL_FORMAT__Y4;
+       case V4L2_PIX_FMT_NV16:    return BV_PXP_PS_CTRL_FORMAT__YUV2P422;
+       case V4L2_PIX_FMT_NV12:    return BV_PXP_PS_CTRL_FORMAT__YUV2P420;
+       case V4L2_PIX_FMT_NV21:    return BV_PXP_PS_CTRL_FORMAT__YVU2P420;
+       case V4L2_PIX_FMT_NV61:    return BV_PXP_PS_CTRL_FORMAT__YVU2P422;
+       case V4L2_PIX_FMT_YUV422P: return BV_PXP_PS_CTRL_FORMAT__YUV422;
+       case V4L2_PIX_FMT_YUV420:  return BV_PXP_PS_CTRL_FORMAT__YUV420;
+       }
+}
+
+static u32 pxp_v4l2_pix_fmt_to_out_format(u32 v4l2_pix_fmt)
+{
+       switch (v4l2_pix_fmt) {
+       case V4L2_PIX_FMT_XBGR32:   return BV_PXP_OUT_CTRL_FORMAT__RGB888;
+       case V4L2_PIX_FMT_ABGR32:   return BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
+       case V4L2_PIX_FMT_BGR24:    return BV_PXP_OUT_CTRL_FORMAT__RGB888P;
+       /* Missing V4L2 pixel formats for ARGB1555 and ARGB4444 */
+       case V4L2_PIX_FMT_RGB555:   return BV_PXP_OUT_CTRL_FORMAT__RGB555;
+       case V4L2_PIX_FMT_RGB444:   return BV_PXP_OUT_CTRL_FORMAT__RGB444;
+       case V4L2_PIX_FMT_RGB565:   return BV_PXP_OUT_CTRL_FORMAT__RGB565;
+       case V4L2_PIX_FMT_YUV32:    return BV_PXP_OUT_CTRL_FORMAT__YUV1P444;
+       case V4L2_PIX_FMT_UYVY:     return BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
+       case V4L2_PIX_FMT_VYUY:     return BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
+       case V4L2_PIX_FMT_GREY:     return BV_PXP_OUT_CTRL_FORMAT__Y8;
+       default:
+       case V4L2_PIX_FMT_Y4:       return BV_PXP_OUT_CTRL_FORMAT__Y4;
+       case V4L2_PIX_FMT_NV16:     return BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
+       case V4L2_PIX_FMT_NV12:     return BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
+       case V4L2_PIX_FMT_NV61:     return BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
+       case V4L2_PIX_FMT_NV21:     return BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
+       }
+}
+
+static bool pxp_v4l2_pix_fmt_is_yuv(u32 v4l2_pix_fmt)
+{
+       switch (v4l2_pix_fmt) {
+       case V4L2_PIX_FMT_YUV32:
+       case V4L2_PIX_FMT_UYVY:
+       case V4L2_PIX_FMT_YUYV:
+       case V4L2_PIX_FMT_VYUY:
+       case V4L2_PIX_FMT_YVYU:
+       case V4L2_PIX_FMT_NV16:
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV61:
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_YUV422P:
+       case V4L2_PIX_FMT_GREY:
+       case V4L2_PIX_FMT_Y4:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static void pxp_setup_csc(struct pxp_ctx *ctx)
+{
+       struct pxp_dev *dev = ctx->dev;
+       enum v4l2_ycbcr_encoding ycbcr_enc;
+       enum v4l2_quantization quantization;
+
+       if (pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_SRC].fmt->fourcc) &&
+           !pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_DST].fmt->fourcc)) {
+               /*
+                * CSC1 YUV/YCbCr to RGB conversion is implemented as follows:
+                *
+                * |R|   |C0 0  C1|   |Y  + Yoffset |
+                * |G| = |C0 C3 C2| * |Cb + UVoffset|
+                * |B|   |C0 C4 0 |   |Cr + UVoffset|
+                *
+                * Results are clamped to 0..255.
+                *
+                * BT.601 limited range:
+                *
+                * |R|   |1.1644  0.0000  1.5960|   |Y  - 16 |
+                * |G| = |1.1644 -0.3917 -0.8129| * |Cb - 128|
+                * |B|   |1.1644  2.0172  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_bt601_lim[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x12a) |   /*  1.1641 (-0.03 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(-16),
+                       BF_PXP_CSC1_COEF1_C1(0x198) |   /*  1.5938 (-0.23 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x204),    /*  2.0156 (-0.16 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x730) |   /* -0.8125 (+0.04 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x79c),    /* -0.3906 (+0.11 %) */
+               };
+               /*
+                * BT.601 full range:
+                *
+                * |R|   |1.0000  0.0000  1.4020|   |Y  + 0  |
+                * |G| = |1.0000 -0.3441 -0.7141| * |Cb - 128|
+                * |B|   |1.0000  1.7720  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_bt601_full[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x100) |   /*  1.0000 (+0.00 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(0),
+                       BF_PXP_CSC1_COEF1_C1(0x166) |   /*  1.3984 (-0.36 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x1c5),    /*  1.7695 (-0.25 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x74a) |   /* -0.7109 (+0.32 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7a8),    /* -0.3438 (+0.04 %) */
+               };
+               /*
+                * Rec.709 limited range:
+                *
+                * |R|   |1.1644  0.0000  1.7927|   |Y  - 16 |
+                * |G| = |1.1644 -0.2132 -0.5329| * |Cb - 128|
+                * |B|   |1.1644  2.1124  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_rec709_lim[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x12a) |   /*  1.1641 (-0.03 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(-16),
+                       BF_PXP_CSC1_COEF1_C1(0x1ca) |   /*  1.7891 (-0.37 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x21c),    /*  2.1094 (-0.30 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x778) |   /* -0.5312 (+0.16 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7ca),    /* -0.2109 (+0.23 %) */
+               };
+               /*
+                * Rec.709 full range:
+                *
+                * |R|   |1.0000  0.0000  1.5748|   |Y  + 0  |
+                * |G| = |1.0000 -0.1873 -0.4681| * |Cb - 128|
+                * |B|   |1.0000  1.8556  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_rec709_full[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x100) |   /*  1.0000 (+0.00 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(0),
+                       BF_PXP_CSC1_COEF1_C1(0x193) |   /*  1.5742 (-0.06 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x1db),    /*  1.8555 (-0.01 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x789) |   /* -0.4648 (+0.33 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7d1),    /* -0.1836 (+0.37 %) */
+               };
+               /*
+                * BT.2020 limited range:
+                *
+                * |R|   |1.1644  0.0000  1.6787|   |Y  - 16 |
+                * |G| = |1.1644 -0.1874 -0.6505| * |Cb - 128|
+                * |B|   |1.1644  2.1418  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_bt2020_lim[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x12a) |   /*  1.1641 (-0.03 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(-16),
+                       BF_PXP_CSC1_COEF1_C1(0x1ad) |   /*  1.6758 (-0.29 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x224),    /*  2.1406 (-0.11 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x75a) |   /* -0.6484 (+0.20 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7d1),    /* -0.1836 (+0.38 %) */
+               };
+               /*
+                * BT.2020 full range:
+                *
+                * |R|   |1.0000  0.0000  1.4746|   |Y  + 0  |
+                * |G| = |1.0000 -0.1646 -0.5714| * |Cb - 128|
+                * |B|   |1.0000  1.8814  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_bt2020_full[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x100) |   /*  1.0000 (+0.00 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(0),
+                       BF_PXP_CSC1_COEF1_C1(0x179) |   /*  1.4727 (-0.19 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x1e1),    /*  1.8789 (-0.25 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x76e) |   /* -0.5703 (+0.11 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7d6),    /* -0.1641 (+0.05 %) */
+               };
+               /*
+                * SMPTE 240m limited range:
+                *
+                * |R|   |1.1644  0.0000  1.7937|   |Y  - 16 |
+                * |G| = |1.1644 -0.2565 -0.5427| * |Cb - 128|
+                * |B|   |1.1644  2.0798  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_smpte240m_lim[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x12a) |   /*  1.1641 (-0.03 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(-16),
+                       BF_PXP_CSC1_COEF1_C1(0x1cb) |   /*  1.7930 (-0.07 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x214),    /*  2.0781 (-0.17 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x776) |   /* -0.5391 (+0.36 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7bf),    /* -0.2539 (+0.26 %) */
+               };
+               /*
+                * SMPTE 240m full range:
+                *
+                * |R|   |1.0000  0.0000  1.5756|   |Y  + 0  |
+                * |G| = |1.0000 -0.2253 -0.4767| * |Cb - 128|
+                * |B|   |1.0000  1.8270  0.0000|   |Cr - 128|
+                */
+               static const u32 csc1_coef_smpte240m_full[3] = {
+                       BM_PXP_CSC1_COEF0_YCBCR_MODE |
+                       BF_PXP_CSC1_COEF0_C0(0x100) |   /*  1.0000 (+0.00 %) */
+                       BF_PXP_CSC1_COEF0_UV_OFFSET(-128) |
+                       BF_PXP_CSC1_COEF0_Y_OFFSET(0),
+                       BF_PXP_CSC1_COEF1_C1(0x193) |   /*  1.5742 (-0.14 %) */
+                       BF_PXP_CSC1_COEF1_C4(0x1d3),    /*  1.8242 (-0.28 %) */
+                       BF_PXP_CSC1_COEF2_C2(0x786) |   /* -0.4766 (+0.01 %) */
+                       BF_PXP_CSC1_COEF2_C3(0x7c7),    /* -0.2227 (+0.26 %) */
+               };
+               const u32 *csc1_coef;
+
+               ycbcr_enc = ctx->q_data[V4L2_M2M_SRC].ycbcr_enc;
+               quantization = ctx->q_data[V4L2_M2M_SRC].quant;
+
+               if (ycbcr_enc == V4L2_YCBCR_ENC_601) {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc1_coef = csc1_coef_bt601_full;
+                       else
+                               csc1_coef = csc1_coef_bt601_lim;
+               } else if (ycbcr_enc == V4L2_YCBCR_ENC_709) {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc1_coef = csc1_coef_rec709_full;
+                       else
+                               csc1_coef = csc1_coef_rec709_lim;
+               } else if (ycbcr_enc == V4L2_YCBCR_ENC_BT2020) {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc1_coef = csc1_coef_bt2020_full;
+                       else
+                               csc1_coef = csc1_coef_bt2020_lim;
+               } else {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc1_coef = csc1_coef_smpte240m_full;
+                       else
+                               csc1_coef = csc1_coef_smpte240m_lim;
+               }
+
+               writel(csc1_coef[0], dev->mmio + HW_PXP_CSC1_COEF0);
+               writel(csc1_coef[1], dev->mmio + HW_PXP_CSC1_COEF1);
+               writel(csc1_coef[2], dev->mmio + HW_PXP_CSC1_COEF2);
+       } else {
+               writel(BM_PXP_CSC1_COEF0_BYPASS, dev->mmio + HW_PXP_CSC1_COEF0);
+       }
+
+       if (!pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_SRC].fmt->fourcc) &&
+           pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_DST].fmt->fourcc)) {
+               /*
+                * CSC2 RGB to YUV/YCbCr conversion is implemented as follows:
+                *
+                * |Y |   |A1 A2 A3|   |R|   |D1|
+                * |Cb| = |B1 B2 B3| * |G| + |D2|
+                * |Cr|   |C1 C2 C3|   |B|   |D3|
+                *
+                * Results are clamped to 0..255.
+                *
+                * BT.601 limited range:
+                *
+                * |Y |   | 0.2568  0.5041  0.0979|   |R|   |16 |
+                * |Cb| = |-0.1482 -0.2910  0.4392| * |G| + |128|
+                * |Cr|   | 0.4392  0.4392 -0.3678|   |B|   |128|
+                */
+               static const u32 csc2_coef_bt601_lim[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x081) |   /*  0.5039 (-0.02 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x041),    /*  0.2539 (-0.29 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7db) |   /* -0.1445 (+0.37 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x019),    /*  0.0977 (-0.02 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x070) |   /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x7b6),    /* -0.2891 (+0.20 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x7a2) |   /* -0.3672 (+0.06 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x070),    /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF4_D1(16) |
+                       BF_PXP_CSC2_COEF4_C3(0x7ee),    /* -0.0703 (+0.11 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * BT.601 full range:
+                *
+                * |Y |   | 0.2990  0.5870  0.1140|   |R|   |0  |
+                * |Cb| = |-0.1687 -0.3313  0.5000| * |G| + |128|
+                * |Cr|   | 0.5000  0.5000 -0.4187|   |B|   |128|
+                */
+               static const u32 csc2_coef_bt601_full[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x096) |   /*  0.5859 (-0.11 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x04c),    /*  0.2969 (-0.21 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7d5) |   /* -0.1680 (+0.07 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x01d),    /*  0.1133 (-0.07 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x080) |   /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x7ac),    /* -0.3281 (+0.32 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x795) |   /* -0.4180 (+0.07 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x080),    /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF4_D1(0) |
+                       BF_PXP_CSC2_COEF4_C3(0x7ec),    /* -0.0781 (+0.32 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * Rec.709 limited range:
+                *
+                * |Y |   | 0.1826  0.6142  0.0620|   |R|   |16 |
+                * |Cb| = |-0.1007 -0.3385  0.4392| * |G| + |128|
+                * |Cr|   | 0.4392  0.4392 -0.3990|   |B|   |128|
+                */
+               static const u32 csc2_coef_rec709_lim[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x09d) |   /*  0.6133 (-0.09 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x02e),    /*  0.1797 (-0.29 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7e7) |   /* -0.0977 (+0.30 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x00f),    /*  0.0586 (-0.34 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x070) |   /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x7aa),    /* -0.3359 (+0.26 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x79a) |   /* -0.3984 (+0.05 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x070),    /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF4_D1(16) |
+                       BF_PXP_CSC2_COEF4_C3(0x7f6),    /* -0.0391 (+0.12 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * Rec.709 full range:
+                *
+                * |Y |   | 0.2126  0.7152  0.0722|   |R|   |0  |
+                * |Cb| = |-0.1146 -0.3854  0.5000| * |G| + |128|
+                * |Cr|   | 0.5000  0.5000 -0.4542|   |B|   |128|
+                */
+               static const u32 csc2_coef_rec709_full[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x0b7) |   /*  0.7148 (-0.04 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x036),    /*  0.2109 (-0.17 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7e3) |   /* -0.1133 (+0.13 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x012),    /*  0.0703 (-0.19 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x080) |   /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x79e),    /* -0.3828 (+0.26 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x78c) |   /* -0.4531 (+0.11 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x080),    /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF4_D1(0) |
+                       BF_PXP_CSC2_COEF4_C3(0x7f5),    /* -0.0430 (+0.28 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * BT.2020 limited range:
+                *
+                * |Y |   | 0.2256  0.5823  0.0509|   |R|   |16 |
+                * |Cb| = |-0.1226 -0.3166  0.4392| * |G| + |128|
+                * |Cr|   | 0.4392  0.4392 -0.4039|   |B|   |128|
+                */
+               static const u32 csc2_coef_bt2020_lim[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x095) |   /*  0.5820 (-0.03 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x039),    /*  0.2227 (-0.30 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7e1) |   /* -0.1211 (+0.15 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x00d),    /*  0.0508 (-0.01 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x070) |   /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x7af),    /* -0.3164 (+0.02 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x799) |   /* -0.4023 (+0.16 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x070),    /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF4_D1(16) |
+                       BF_PXP_CSC2_COEF4_C3(0x7f7),    /* -0.0352 (+0.02 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * BT.2020 full range:
+                *
+                * |Y |   | 0.2627  0.6780  0.0593|   |R|   |0  |
+                * |Cb| = |-0.1396 -0.3604  0.5000| * |G| + |128|
+                * |Cr|   | 0.5000  0.5000 -0.4598|   |B|   |128|
+                */
+               static const u32 csc2_coef_bt2020_full[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x0ad) |   /*  0.6758 (-0.22 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x043),    /*  0.2617 (-0.10 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7dd) |   /* -0.1367 (+0.29 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x00f),    /*  0.0586 (-0.07 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x080) |   /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x7a4),    /* -0.3594 (+0.10 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x78b) |   /* -0.4570 (+0.28 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x080),    /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF4_D1(0) |
+                       BF_PXP_CSC2_COEF4_C3(0x7f6),    /* -0.0391 (+0.11 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * SMPTE 240m limited range:
+                *
+                * |Y |   | 0.1821  0.6020  0.0747|   |R|   |16 |
+                * |Cb| = |-0.1019 -0.3373  0.4392| * |G| + |128|
+                * |Cr|   | 0.4392  0.4392 -0.3909|   |B|   |128|
+                */
+               static const u32 csc2_coef_smpte240m_lim[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x09a) |   /*  0.6016 (-0.05 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x02e),    /*  0.1797 (-0.24 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7e6) |   /* -0.1016 (+0.03 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x013),    /*  0.0742 (-0.05 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x070) |   /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x7aa),    /* -0.3359 (+0.14 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x79c) |   /* -0.3906 (+0.03 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x070),    /*  0.4375 (-0.17 %) */
+                       BF_PXP_CSC2_COEF4_D1(16) |
+                       BF_PXP_CSC2_COEF4_C3(0x7f4),    /* -0.0469 (+0.14 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               /*
+                * SMPTE 240m full range:
+                *
+                * |Y |   | 0.2120  0.7010  0.0870|   |R|   |0  |
+                * |Cb| = |-0.1160 -0.3840  0.5000| * |G| + |128|
+                * |Cr|   | 0.5000  0.5000 -0.4450|   |B|   |128|
+                */
+               static const u32 csc2_coef_smpte240m_full[6] = {
+                       BF_PXP_CSC2_COEF0_A2(0x0b3) |   /*  0.6992 (-0.18 %) */
+                       BF_PXP_CSC2_COEF0_A1(0x036),    /*  0.2109 (-0.11 %) */
+                       BF_PXP_CSC2_COEF1_B1(0x7e3) |   /* -0.1133 (+0.27 %) */
+                       BF_PXP_CSC2_COEF1_A3(0x016),    /*  0.0859 (-0.11 %) */
+                       BF_PXP_CSC2_COEF2_B3(0x080) |   /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF2_B2(0x79e),    /* -0.3828 (+0.12 %) */
+                       BF_PXP_CSC2_COEF3_C2(0x78f) |   /* -0.4414 (+0.36 %) */
+                       BF_PXP_CSC2_COEF3_C1(0x080),    /*  0.5000 (+0.00 %) */
+                       BF_PXP_CSC2_COEF4_D1(0) |
+                       BF_PXP_CSC2_COEF4_C3(0x7f2),    /* -0.0547 (+0.03 %) */
+                       BF_PXP_CSC2_COEF5_D3(128) |
+                       BF_PXP_CSC2_COEF5_D2(128),
+               };
+               const u32 *csc2_coef;
+               u32 csc2_ctrl;
+
+               ycbcr_enc = ctx->q_data[V4L2_M2M_DST].ycbcr_enc;
+               quantization = ctx->q_data[V4L2_M2M_DST].quant;
+
+               if (ycbcr_enc == V4L2_YCBCR_ENC_601) {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc2_coef = csc2_coef_bt601_full;
+                       else
+                               csc2_coef = csc2_coef_bt601_lim;
+               } else if (ycbcr_enc == V4L2_YCBCR_ENC_709) {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc2_coef = csc2_coef_rec709_full;
+                       else
+                               csc2_coef = csc2_coef_rec709_lim;
+               } else if (ycbcr_enc == V4L2_YCBCR_ENC_709) {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc2_coef = csc2_coef_bt2020_full;
+                       else
+                               csc2_coef = csc2_coef_bt2020_lim;
+               } else {
+                       if (quantization == V4L2_QUANTIZATION_FULL_RANGE)
+                               csc2_coef = csc2_coef_smpte240m_full;
+                       else
+                               csc2_coef = csc2_coef_smpte240m_lim;
+               }
+               if (quantization == V4L2_QUANTIZATION_FULL_RANGE) {
+                       csc2_ctrl = BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV <<
+                                   BP_PXP_CSC2_CTRL_CSC_MODE;
+               } else {
+                       csc2_ctrl = BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr <<
+                                   BP_PXP_CSC2_CTRL_CSC_MODE;
+               }
+
+               writel(csc2_ctrl, dev->mmio + HW_PXP_CSC2_CTRL);
+               writel(csc2_coef[0], dev->mmio + HW_PXP_CSC2_COEF0);
+               writel(csc2_coef[1], dev->mmio + HW_PXP_CSC2_COEF1);
+               writel(csc2_coef[2], dev->mmio + HW_PXP_CSC2_COEF2);
+               writel(csc2_coef[3], dev->mmio + HW_PXP_CSC2_COEF3);
+               writel(csc2_coef[4], dev->mmio + HW_PXP_CSC2_COEF4);
+               writel(csc2_coef[5], dev->mmio + HW_PXP_CSC2_COEF5);
+       } else {
+               writel(BM_PXP_CSC2_CTRL_BYPASS, dev->mmio + HW_PXP_CSC2_CTRL);
+       }
+}
+
+static int pxp_start(struct pxp_ctx *ctx, struct vb2_v4l2_buffer *in_vb,
+                    struct vb2_v4l2_buffer *out_vb)
+{
+       struct pxp_dev *dev = ctx->dev;
+       struct pxp_q_data *q_data;
+       u32 src_width, src_height, src_stride, src_fourcc;
+       u32 dst_width, dst_height, dst_stride, dst_fourcc;
+       dma_addr_t p_in, p_out;
+       u32 ctrl, out_ctrl, out_buf, out_buf2, out_pitch, out_lrc, out_ps_ulc;
+       u32 out_ps_lrc;
+       u32 ps_ctrl, ps_buf, ps_ubuf, ps_vbuf, ps_pitch, ps_scale, ps_offset;
+       u32 as_ulc, as_lrc;
+       u32 y_size;
+       u32 decx, decy, xscale, yscale;
+
+       q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+
+       src_width = ctx->q_data[V4L2_M2M_SRC].width;
+       dst_width = ctx->q_data[V4L2_M2M_DST].width;
+       src_height = ctx->q_data[V4L2_M2M_SRC].height;
+       dst_height = ctx->q_data[V4L2_M2M_DST].height;
+       src_stride = ctx->q_data[V4L2_M2M_SRC].bytesperline;
+       dst_stride = ctx->q_data[V4L2_M2M_DST].bytesperline;
+       src_fourcc = ctx->q_data[V4L2_M2M_SRC].fmt->fourcc;
+       dst_fourcc = ctx->q_data[V4L2_M2M_DST].fmt->fourcc;
+
+       p_in = vb2_dma_contig_plane_dma_addr(&in_vb->vb2_buf, 0);
+       p_out = vb2_dma_contig_plane_dma_addr(&out_vb->vb2_buf, 0);
+
+       if (!p_in || !p_out) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Acquiring DMA addresses of buffers failed\n");
+               return -EFAULT;
+       }
+
+       out_vb->sequence =
+               get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
+       in_vb->sequence = q_data->sequence++;
+       out_vb->vb2_buf.timestamp = in_vb->vb2_buf.timestamp;
+
+       if (in_vb->flags & V4L2_BUF_FLAG_TIMECODE)
+               out_vb->timecode = in_vb->timecode;
+       out_vb->field = in_vb->field;
+       out_vb->flags = in_vb->flags &
+               (V4L2_BUF_FLAG_TIMECODE |
+                V4L2_BUF_FLAG_KEYFRAME |
+                V4L2_BUF_FLAG_PFRAME |
+                V4L2_BUF_FLAG_BFRAME |
+                V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
+
+       /* Rotation disabled, 8x8 block size */
+       ctrl = BF_PXP_CTRL_VFLIP0(!!(ctx->mode & MEM2MEM_VFLIP)) |
+              BF_PXP_CTRL_HFLIP0(!!(ctx->mode & MEM2MEM_HFLIP));
+       /* Always write alpha value as V4L2_CID_ALPHA_COMPONENT */
+       out_ctrl = BF_PXP_OUT_CTRL_ALPHA(ctx->alpha_component) |
+                  BF_PXP_OUT_CTRL_ALPHA_OUTPUT(1) |
+                  pxp_v4l2_pix_fmt_to_out_format(dst_fourcc);
+       out_buf = p_out;
+       switch (dst_fourcc) {
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_NV16:
+       case V4L2_PIX_FMT_NV61:
+               out_buf2 = out_buf + dst_stride * dst_height;
+               break;
+       default:
+               out_buf2 = 0;
+       }
+
+       out_pitch = BF_PXP_OUT_PITCH_PITCH(dst_stride);
+       out_lrc = BF_PXP_OUT_LRC_X(dst_width - 1) |
+                 BF_PXP_OUT_LRC_Y(dst_height - 1);
+       /* PS covers whole output */
+       out_ps_ulc = BF_PXP_OUT_PS_ULC_X(0) | BF_PXP_OUT_PS_ULC_Y(0);
+       out_ps_lrc = BF_PXP_OUT_PS_LRC_X(dst_width - 1) |
+                    BF_PXP_OUT_PS_LRC_Y(dst_height - 1);
+       /* no AS */
+       as_ulc = BF_PXP_OUT_AS_ULC_X(1) | BF_PXP_OUT_AS_ULC_Y(1);
+       as_lrc = BF_PXP_OUT_AS_LRC_X(0) | BF_PXP_OUT_AS_LRC_Y(0);
+
+       decx = (src_width <= dst_width) ? 0 : ilog2(src_width / dst_width);
+       decy = (src_height <= dst_height) ? 0 : ilog2(src_height / dst_height);
+       ps_ctrl = BF_PXP_PS_CTRL_DECX(decx) | BF_PXP_PS_CTRL_DECY(decy) |
+                 pxp_v4l2_pix_fmt_to_ps_format(src_fourcc);
+       ps_buf = p_in;
+       y_size = src_stride * src_height;
+       switch (src_fourcc) {
+       case V4L2_PIX_FMT_YUV420:
+               ps_ubuf = ps_buf + y_size;
+               ps_vbuf = ps_ubuf + y_size / 4;
+               break;
+       case V4L2_PIX_FMT_YUV422P:
+               ps_ubuf = ps_buf + y_size;
+               ps_vbuf = ps_ubuf + y_size / 2;
+               break;
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_NV16:
+       case V4L2_PIX_FMT_NV61:
+               ps_ubuf = ps_buf + y_size;
+               ps_vbuf = 0;
+               break;
+       case V4L2_PIX_FMT_GREY:
+       case V4L2_PIX_FMT_Y4:
+               ps_ubuf = 0;
+               /* In grayscale mode, ps_vbuf contents are reused as CbCr */
+               ps_vbuf = 0x8080;
+               break;
+       default:
+               ps_ubuf = 0;
+               ps_vbuf = 0;
+               break;
+       }
+       ps_pitch = BF_PXP_PS_PITCH_PITCH(src_stride);
+       if (decx) {
+               xscale = (src_width >> decx) * 0x1000 / dst_width;
+       } else {
+               switch (src_fourcc) {
+               case V4L2_PIX_FMT_UYVY:
+               case V4L2_PIX_FMT_YUYV:
+               case V4L2_PIX_FMT_VYUY:
+               case V4L2_PIX_FMT_YVYU:
+               case V4L2_PIX_FMT_NV16:
+               case V4L2_PIX_FMT_NV12:
+               case V4L2_PIX_FMT_NV21:
+               case V4L2_PIX_FMT_NV61:
+               case V4L2_PIX_FMT_YUV422P:
+               case V4L2_PIX_FMT_YUV420:
+                       /*
+                        * This avoids sampling past the right edge for
+                        * horizontally chroma subsampled formats.
+                        */
+                       xscale = (src_width - 2) * 0x1000 / (dst_width - 1);
+                       break;
+               default:
+                       xscale = (src_width - 1) * 0x1000 / (dst_width - 1);
+                       break;
+               }
+       }
+       if (decy)
+               yscale = (src_height >> decy) * 0x1000 / dst_height;
+       else
+               yscale = (src_height - 1) * 0x1000 / (dst_height - 1);
+       ps_scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
+                  BF_PXP_PS_SCALE_XSCALE(xscale);
+       ps_offset = BF_PXP_PS_OFFSET_YOFFSET(0) | BF_PXP_PS_OFFSET_XOFFSET(0);
+
+       writel(ctrl, dev->mmio + HW_PXP_CTRL);
+       /* skip STAT */
+       writel(out_ctrl, dev->mmio + HW_PXP_OUT_CTRL);
+       writel(out_buf, dev->mmio + HW_PXP_OUT_BUF);
+       writel(out_buf2, dev->mmio + HW_PXP_OUT_BUF2);
+       writel(out_pitch, dev->mmio + HW_PXP_OUT_PITCH);
+       writel(out_lrc, dev->mmio + HW_PXP_OUT_LRC);
+       writel(out_ps_ulc, dev->mmio + HW_PXP_OUT_PS_ULC);
+       writel(out_ps_lrc, dev->mmio + HW_PXP_OUT_PS_LRC);
+       writel(as_ulc, dev->mmio + HW_PXP_OUT_AS_ULC);
+       writel(as_lrc, dev->mmio + HW_PXP_OUT_AS_LRC);
+       writel(ps_ctrl, dev->mmio + HW_PXP_PS_CTRL);
+       writel(ps_buf, dev->mmio + HW_PXP_PS_BUF);
+       writel(ps_ubuf, dev->mmio + HW_PXP_PS_UBUF);
+       writel(ps_vbuf, dev->mmio + HW_PXP_PS_VBUF);
+       writel(ps_pitch, dev->mmio + HW_PXP_PS_PITCH);
+       writel(0x00ffffff, dev->mmio + HW_PXP_PS_BACKGROUND_0);
+       writel(ps_scale, dev->mmio + HW_PXP_PS_SCALE);
+       writel(ps_offset, dev->mmio + HW_PXP_PS_OFFSET);
+       /* disable processed surface color keying */
+       writel(0x00ffffff, dev->mmio + HW_PXP_PS_CLRKEYLOW_0);
+       writel(0x00000000, dev->mmio + HW_PXP_PS_CLRKEYHIGH_0);
+
+       /* disable alpha surface color keying */
+       writel(0x00ffffff, dev->mmio + HW_PXP_AS_CLRKEYLOW_0);
+       writel(0x00000000, dev->mmio + HW_PXP_AS_CLRKEYHIGH_0);
+
+       /* setup CSC */
+       pxp_setup_csc(ctx);
+
+       /* bypass LUT */
+       writel(BM_PXP_LUT_CTRL_BYPASS, dev->mmio + HW_PXP_LUT_CTRL);
+
+       writel(BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(1)|
+              BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(1)|
+              BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(0)|
+              BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(0),
+              dev->mmio + HW_PXP_DATA_PATH_CTRL0);
+       writel(BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(1) |
+              BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(1),
+              dev->mmio + HW_PXP_DATA_PATH_CTRL1);
+
+       writel(0xffff, dev->mmio + HW_PXP_IRQ_MASK);
+
+       /* ungate, enable PS/AS/OUT and PXP operation */
+       writel(BM_PXP_CTRL_IRQ_ENABLE, dev->mmio + HW_PXP_CTRL_SET);
+       writel(BM_PXP_CTRL_ENABLE | BM_PXP_CTRL_ENABLE_CSC2 |
+              BM_PXP_CTRL_ENABLE_LUT | BM_PXP_CTRL_ENABLE_ROTATE0 |
+              BM_PXP_CTRL_ENABLE_PS_AS_OUT, dev->mmio + HW_PXP_CTRL_SET);
+
+       return 0;
+}
+
+static void pxp_job_finish(struct pxp_dev *dev)
+{
+       struct pxp_ctx *curr_ctx;
+       struct vb2_v4l2_buffer *src_vb, *dst_vb;
+       unsigned long flags;
+
+       curr_ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+
+       if (curr_ctx == NULL) {
+               pr_err("Instance released before the end of transaction\n");
+               return;
+       }
+
+       src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+       dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+
+       spin_lock_irqsave(&dev->irqlock, flags);
+       v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
+       v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
+       spin_unlock_irqrestore(&dev->irqlock, flags);
+
+       dprintk(curr_ctx->dev, "Finishing transaction\n");
+       v4l2_m2m_job_finish(dev->m2m_dev, curr_ctx->fh.m2m_ctx);
+}
+
+/*
+ * mem2mem callbacks
+ */
+static void pxp_device_run(void *priv)
+{
+       struct pxp_ctx *ctx = priv;
+       struct vb2_v4l2_buffer *src_buf, *dst_buf;
+
+       src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+       dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+       pxp_start(ctx, src_buf, dst_buf);
+}
+
+static int pxp_job_ready(void *priv)
+{
+       struct pxp_ctx *ctx = priv;
+
+       if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < 1 ||
+           v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < 1) {
+               dprintk(ctx->dev, "Not enough buffers available\n");
+               return 0;
+       }
+
+       return 1;
+}
+
+static void pxp_job_abort(void *priv)
+{
+       struct pxp_ctx *ctx = priv;
+
+       /* Will cancel the transaction in the next interrupt handler */
+       ctx->aborting = 1;
+}
+
+/*
+ * interrupt handler
+ */
+static irqreturn_t pxp_irq_handler(int irq, void *dev_id)
+{
+       struct pxp_dev *dev = dev_id;
+       u32 stat;
+
+       stat = readl(dev->mmio + HW_PXP_STAT);
+
+       if (stat & BM_PXP_STAT_IRQ0) {
+               /* we expect x = 0, y = height, irq0 = 1 */
+               if (stat & ~(BM_PXP_STAT_BLOCKX | BM_PXP_STAT_BLOCKY |
+                            BM_PXP_STAT_IRQ0))
+                       dprintk(dev, "%s: stat = 0x%08x\n", __func__, stat);
+               writel(BM_PXP_STAT_IRQ0, dev->mmio + HW_PXP_STAT_CLR);
+
+               pxp_job_finish(dev);
+       } else {
+               u32 irq = readl(dev->mmio + HW_PXP_IRQ);
+
+               dprintk(dev, "%s: stat = 0x%08x\n", __func__, stat);
+               dprintk(dev, "%s: irq = 0x%08x\n", __func__, irq);
+
+               writel(irq, dev->mmio + HW_PXP_IRQ_CLR);
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * video ioctls
+ */
+static int pxp_querycap(struct file *file, void *priv,
+                          struct v4l2_capability *cap)
+{
+       strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
+       strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
+       snprintf(cap->bus_info, sizeof(cap->bus_info),
+                       "platform:%s", MEM2MEM_NAME);
+       return 0;
+}
+
+static int pxp_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
+{
+       int i, num;
+       struct pxp_fmt *fmt;
+
+       num = 0;
+
+       for (i = 0; i < NUM_FORMATS; ++i) {
+               if (formats[i].types & type) {
+                       /* index-th format of type type found ? */
+                       if (num == f->index)
+                               break;
+                       /*
+                        * Correct type but haven't reached our index yet,
+                        * just increment per-type index
+                        */
+                       ++num;
+               }
+       }
+
+       if (i < NUM_FORMATS) {
+               /* Format found */
+               fmt = &formats[i];
+               f->pixelformat = fmt->fourcc;
+               return 0;
+       }
+
+       /* Format not found */
+       return -EINVAL;
+}
+
+static int pxp_enum_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_fmtdesc *f)
+{
+       return pxp_enum_fmt(f, MEM2MEM_CAPTURE);
+}
+
+static int pxp_enum_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_fmtdesc *f)
+{
+       return pxp_enum_fmt(f, MEM2MEM_OUTPUT);
+}
+
+static int pxp_g_fmt(struct pxp_ctx *ctx, struct v4l2_format *f)
+{
+       struct vb2_queue *vq;
+       struct pxp_q_data *q_data;
+
+       vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+       if (!vq)
+               return -EINVAL;
+
+       q_data = get_q_data(ctx, f->type);
+
+       f->fmt.pix.width        = q_data->width;
+       f->fmt.pix.height       = q_data->height;
+       f->fmt.pix.field        = V4L2_FIELD_NONE;
+       f->fmt.pix.pixelformat  = q_data->fmt->fourcc;
+       f->fmt.pix.bytesperline = q_data->bytesperline;
+       f->fmt.pix.sizeimage    = q_data->sizeimage;
+       f->fmt.pix.colorspace   = ctx->colorspace;
+       f->fmt.pix.xfer_func    = ctx->xfer_func;
+       f->fmt.pix.ycbcr_enc    = q_data->ycbcr_enc;
+       f->fmt.pix.quantization = q_data->quant;
+
+       return 0;
+}
+
+static int pxp_g_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       return pxp_g_fmt(file2ctx(file), f);
+}
+
+static int pxp_g_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       return pxp_g_fmt(file2ctx(file), f);
+}
+
+static inline u32 pxp_bytesperline(struct pxp_fmt *fmt, u32 width)
+{
+       switch (fmt->fourcc) {
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_YUV422P:
+       case V4L2_PIX_FMT_NV16:
+       case V4L2_PIX_FMT_NV61:
+               return width;
+       default:
+               return (width * fmt->depth) >> 3;
+       }
+}
+
+static inline u32 pxp_sizeimage(struct pxp_fmt *fmt, u32 width, u32 height)
+{
+       return (fmt->depth * width * height) >> 3;
+}
+
+static int pxp_try_fmt(struct v4l2_format *f, struct pxp_fmt *fmt)
+{
+       v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W, ALIGN_W,
+                             &f->fmt.pix.height, MIN_H, MAX_H, ALIGN_H, 0);
+
+       f->fmt.pix.bytesperline = pxp_bytesperline(fmt, f->fmt.pix.width);
+       f->fmt.pix.sizeimage = pxp_sizeimage(fmt, f->fmt.pix.width,
+                                            f->fmt.pix.height);
+       f->fmt.pix.field = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static void
+pxp_fixup_colorimetry_cap(struct pxp_ctx *ctx, u32 dst_fourcc,
+                         enum v4l2_ycbcr_encoding *ycbcr_enc,
+                         enum v4l2_quantization *quantization)
+{
+       bool dst_is_yuv = pxp_v4l2_pix_fmt_is_yuv(dst_fourcc);
+
+       if (pxp_v4l2_pix_fmt_is_yuv(ctx->q_data[V4L2_M2M_SRC].fmt->fourcc) ==
+           dst_is_yuv) {
+               /*
+                * There is no support for conversion between different YCbCr
+                * encodings or between RGB limited and full range.
+                */
+               *ycbcr_enc = ctx->q_data[V4L2_M2M_SRC].ycbcr_enc;
+               *quantization = ctx->q_data[V4L2_M2M_SRC].quant;
+       } else {
+               *ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(ctx->colorspace);
+               *quantization = V4L2_MAP_QUANTIZATION_DEFAULT(!dst_is_yuv,
+                                                             ctx->colorspace,
+                                                             *ycbcr_enc);
+       }
+}
+
+static int pxp_try_fmt_vid_cap(struct file *file, void *priv,
+                              struct v4l2_format *f)
+{
+       struct pxp_fmt *fmt;
+       struct pxp_ctx *ctx = file2ctx(file);
+
+       fmt = find_format(f);
+       if (!fmt) {
+               f->fmt.pix.pixelformat = formats[0].fourcc;
+               fmt = find_format(f);
+       }
+       if (!(fmt->types & MEM2MEM_CAPTURE)) {
+               v4l2_err(&ctx->dev->v4l2_dev,
+                        "Fourcc format (0x%08x) invalid.\n",
+                        f->fmt.pix.pixelformat);
+               return -EINVAL;
+       }
+
+       f->fmt.pix.colorspace = ctx->colorspace;
+       f->fmt.pix.xfer_func = ctx->xfer_func;
+
+       pxp_fixup_colorimetry_cap(ctx, fmt->fourcc,
+                                 &f->fmt.pix.ycbcr_enc,
+                                 &f->fmt.pix.quantization);
+
+       return pxp_try_fmt(f, fmt);
+}
+
+static int pxp_try_fmt_vid_out(struct file *file, void *priv,
+                              struct v4l2_format *f)
+{
+       struct pxp_fmt *fmt;
+       struct pxp_ctx *ctx = file2ctx(file);
+
+       fmt = find_format(f);
+       if (!fmt) {
+               f->fmt.pix.pixelformat = formats[0].fourcc;
+               fmt = find_format(f);
+       }
+       if (!(fmt->types & MEM2MEM_OUTPUT)) {
+               v4l2_err(&ctx->dev->v4l2_dev,
+                        "Fourcc format (0x%08x) invalid.\n",
+                        f->fmt.pix.pixelformat);
+               return -EINVAL;
+       }
+
+       if (!f->fmt.pix.colorspace)
+               f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+       return pxp_try_fmt(f, fmt);
+}
+
+static int pxp_s_fmt(struct pxp_ctx *ctx, struct v4l2_format *f)
+{
+       struct pxp_q_data *q_data;
+       struct vb2_queue *vq;
+
+       vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+       if (!vq)
+               return -EINVAL;
+
+       q_data = get_q_data(ctx, f->type);
+       if (!q_data)
+               return -EINVAL;
+
+       if (vb2_is_busy(vq)) {
+               v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
+               return -EBUSY;
+       }
+
+       q_data->fmt             = find_format(f);
+       q_data->width           = f->fmt.pix.width;
+       q_data->height          = f->fmt.pix.height;
+       q_data->bytesperline    = f->fmt.pix.bytesperline;
+       q_data->sizeimage       = f->fmt.pix.sizeimage;
+
+       dprintk(ctx->dev,
+               "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
+               f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
+
+       return 0;
+}
+
+static int pxp_s_fmt_vid_cap(struct file *file, void *priv,
+                            struct v4l2_format *f)
+{
+       struct pxp_ctx *ctx = file2ctx(file);
+       int ret;
+
+       ret = pxp_try_fmt_vid_cap(file, priv, f);
+       if (ret)
+               return ret;
+
+       ret = pxp_s_fmt(file2ctx(file), f);
+       if (ret)
+               return ret;
+
+       ctx->q_data[V4L2_M2M_DST].ycbcr_enc = f->fmt.pix.ycbcr_enc;
+       ctx->q_data[V4L2_M2M_DST].quant = f->fmt.pix.quantization;
+
+       return 0;
+}
+
+static int pxp_s_fmt_vid_out(struct file *file, void *priv,
+                            struct v4l2_format *f)
+{
+       struct pxp_ctx *ctx = file2ctx(file);
+       int ret;
+
+       ret = pxp_try_fmt_vid_out(file, priv, f);
+       if (ret)
+               return ret;
+
+       ret = pxp_s_fmt(file2ctx(file), f);
+       if (ret)
+               return ret;
+
+       ctx->colorspace = f->fmt.pix.colorspace;
+       ctx->xfer_func = f->fmt.pix.xfer_func;
+       ctx->q_data[V4L2_M2M_SRC].ycbcr_enc = f->fmt.pix.ycbcr_enc;
+       ctx->q_data[V4L2_M2M_SRC].quant = f->fmt.pix.quantization;
+
+       pxp_fixup_colorimetry_cap(ctx, ctx->q_data[V4L2_M2M_DST].fmt->fourcc,
+                                 &ctx->q_data[V4L2_M2M_DST].ycbcr_enc,
+                                 &ctx->q_data[V4L2_M2M_DST].quant);
+
+       return 0;
+}
+
+static int pxp_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct pxp_ctx *ctx =
+               container_of(ctrl->handler, struct pxp_ctx, hdl);
+
+       switch (ctrl->id) {
+       case V4L2_CID_HFLIP:
+               if (ctrl->val)
+                       ctx->mode |= MEM2MEM_HFLIP;
+               else
+                       ctx->mode &= ~MEM2MEM_HFLIP;
+               break;
+
+       case V4L2_CID_VFLIP:
+               if (ctrl->val)
+                       ctx->mode |= MEM2MEM_VFLIP;
+               else
+                       ctx->mode &= ~MEM2MEM_VFLIP;
+               break;
+
+       case V4L2_CID_ALPHA_COMPONENT:
+               ctx->alpha_component = ctrl->val;
+               break;
+
+       default:
+               v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops pxp_ctrl_ops = {
+       .s_ctrl = pxp_s_ctrl,
+};
+
+static const struct v4l2_ioctl_ops pxp_ioctl_ops = {
+       .vidioc_querycap        = pxp_querycap,
+
+       .vidioc_enum_fmt_vid_cap = pxp_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap   = pxp_g_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap = pxp_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap   = pxp_s_fmt_vid_cap,
+
+       .vidioc_enum_fmt_vid_out = pxp_enum_fmt_vid_out,
+       .vidioc_g_fmt_vid_out   = pxp_g_fmt_vid_out,
+       .vidioc_try_fmt_vid_out = pxp_try_fmt_vid_out,
+       .vidioc_s_fmt_vid_out   = pxp_s_fmt_vid_out,
+
+       .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
+       .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
+       .vidioc_qbuf            = v4l2_m2m_ioctl_qbuf,
+       .vidioc_dqbuf           = v4l2_m2m_ioctl_dqbuf,
+       .vidioc_prepare_buf     = v4l2_m2m_ioctl_prepare_buf,
+       .vidioc_create_bufs     = v4l2_m2m_ioctl_create_bufs,
+       .vidioc_expbuf          = v4l2_m2m_ioctl_expbuf,
+
+       .vidioc_streamon        = v4l2_m2m_ioctl_streamon,
+       .vidioc_streamoff       = v4l2_m2m_ioctl_streamoff,
+
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+/*
+ * Queue operations
+ */
+static int pxp_queue_setup(struct vb2_queue *vq,
+                          unsigned int *nbuffers, unsigned int *nplanes,
+                          unsigned int sizes[], struct device *alloc_devs[])
+{
+       struct pxp_ctx *ctx = vb2_get_drv_priv(vq);
+       struct pxp_q_data *q_data;
+       unsigned int size, count = *nbuffers;
+
+       q_data = get_q_data(ctx, vq->type);
+
+       size = q_data->sizeimage;
+
+       *nbuffers = count;
+
+       if (*nplanes)
+               return sizes[0] < size ? -EINVAL : 0;
+
+       *nplanes = 1;
+       sizes[0] = size;
+
+       dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
+
+       return 0;
+}
+
+static int pxp_buf_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct pxp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+       struct pxp_dev *dev = ctx->dev;
+       struct pxp_q_data *q_data;
+
+       dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
+
+       q_data = get_q_data(ctx, vb->vb2_queue->type);
+       if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+               if (vbuf->field == V4L2_FIELD_ANY)
+                       vbuf->field = V4L2_FIELD_NONE;
+               if (vbuf->field != V4L2_FIELD_NONE) {
+                       dprintk(dev, "%s field isn't supported\n", __func__);
+                       return -EINVAL;
+               }
+       }
+
+       if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
+               dprintk(dev, "%s data will not fit into plane (%lu < %lu)\n",
+                       __func__, vb2_plane_size(vb, 0),
+                       (long)q_data->sizeimage);
+               return -EINVAL;
+       }
+
+       vb2_set_plane_payload(vb, 0, q_data->sizeimage);
+
+       return 0;
+}
+
+static void pxp_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct pxp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static int pxp_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+       struct pxp_ctx *ctx = vb2_get_drv_priv(q);
+       struct pxp_q_data *q_data = get_q_data(ctx, q->type);
+
+       q_data->sequence = 0;
+       return 0;
+}
+
+static void pxp_stop_streaming(struct vb2_queue *q)
+{
+       struct pxp_ctx *ctx = vb2_get_drv_priv(q);
+       struct vb2_v4l2_buffer *vbuf;
+       unsigned long flags;
+
+       for (;;) {
+               if (V4L2_TYPE_IS_OUTPUT(q->type))
+                       vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+               else
+                       vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+               if (vbuf == NULL)
+                       return;
+               spin_lock_irqsave(&ctx->dev->irqlock, flags);
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+               spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+       }
+}
+
+static const struct vb2_ops pxp_qops = {
+       .queue_setup     = pxp_queue_setup,
+       .buf_prepare     = pxp_buf_prepare,
+       .buf_queue       = pxp_buf_queue,
+       .start_streaming = pxp_start_streaming,
+       .stop_streaming  = pxp_stop_streaming,
+       .wait_prepare    = vb2_ops_wait_prepare,
+       .wait_finish     = vb2_ops_wait_finish,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+                     struct vb2_queue *dst_vq)
+{
+       struct pxp_ctx *ctx = priv;
+       int ret;
+
+       src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+       src_vq->drv_priv = ctx;
+       src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+       src_vq->ops = &pxp_qops;
+       src_vq->mem_ops = &vb2_dma_contig_memops;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->lock = &ctx->dev->dev_mutex;
+       src_vq->dev = ctx->dev->v4l2_dev.dev;
+
+       ret = vb2_queue_init(src_vq);
+       if (ret)
+               return ret;
+
+       dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+       dst_vq->drv_priv = ctx;
+       dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+       dst_vq->ops = &pxp_qops;
+       dst_vq->mem_ops = &vb2_dma_contig_memops;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->lock = &ctx->dev->dev_mutex;
+       dst_vq->dev = ctx->dev->v4l2_dev.dev;
+
+       return vb2_queue_init(dst_vq);
+}
+
+/*
+ * File operations
+ */
+static int pxp_open(struct file *file)
+{
+       struct pxp_dev *dev = video_drvdata(file);
+       struct pxp_ctx *ctx = NULL;
+       struct v4l2_ctrl_handler *hdl;
+       int rc = 0;
+
+       if (mutex_lock_interruptible(&dev->dev_mutex))
+               return -ERESTARTSYS;
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx) {
+               rc = -ENOMEM;
+               goto open_unlock;
+       }
+
+       v4l2_fh_init(&ctx->fh, video_devdata(file));
+       file->private_data = &ctx->fh;
+       ctx->dev = dev;
+       hdl = &ctx->hdl;
+       v4l2_ctrl_handler_init(hdl, 4);
+       v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
+                         0, 255, 1, 255);
+       if (hdl->error) {
+               rc = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+               kfree(ctx);
+               goto open_unlock;
+       }
+       ctx->fh.ctrl_handler = hdl;
+       v4l2_ctrl_handler_setup(hdl);
+
+       ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
+       ctx->q_data[V4L2_M2M_SRC].width = 640;
+       ctx->q_data[V4L2_M2M_SRC].height = 480;
+       ctx->q_data[V4L2_M2M_SRC].bytesperline =
+               pxp_bytesperline(&formats[0], 640);
+       ctx->q_data[V4L2_M2M_SRC].sizeimage =
+               pxp_sizeimage(&formats[0], 640, 480);
+       ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
+       ctx->colorspace = V4L2_COLORSPACE_REC709;
+
+       ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
+
+       if (IS_ERR(ctx->fh.m2m_ctx)) {
+               rc = PTR_ERR(ctx->fh.m2m_ctx);
+
+               v4l2_ctrl_handler_free(hdl);
+               v4l2_fh_exit(&ctx->fh);
+               kfree(ctx);
+               goto open_unlock;
+       }
+
+       v4l2_fh_add(&ctx->fh);
+       atomic_inc(&dev->num_inst);
+
+       dprintk(dev, "Created instance: %p, m2m_ctx: %p\n",
+               ctx, ctx->fh.m2m_ctx);
+
+open_unlock:
+       mutex_unlock(&dev->dev_mutex);
+       return rc;
+}
+
+static int pxp_release(struct file *file)
+{
+       struct pxp_dev *dev = video_drvdata(file);
+       struct pxp_ctx *ctx = file2ctx(file);
+
+       dprintk(dev, "Releasing instance %p\n", ctx);
+
+       v4l2_fh_del(&ctx->fh);
+       v4l2_fh_exit(&ctx->fh);
+       v4l2_ctrl_handler_free(&ctx->hdl);
+       mutex_lock(&dev->dev_mutex);
+       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+       mutex_unlock(&dev->dev_mutex);
+       kfree(ctx);
+
+       atomic_dec(&dev->num_inst);
+
+       return 0;
+}
+
+static const struct v4l2_file_operations pxp_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pxp_open,
+       .release        = pxp_release,
+       .poll           = v4l2_m2m_fop_poll,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap           = v4l2_m2m_fop_mmap,
+};
+
+static const struct video_device pxp_videodev = {
+       .name           = MEM2MEM_NAME,
+       .vfl_dir        = VFL_DIR_M2M,
+       .fops           = &pxp_fops,
+       .device_caps    = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
+       .ioctl_ops      = &pxp_ioctl_ops,
+       .minor          = -1,
+       .release        = video_device_release_empty,
+};
+
+static const struct v4l2_m2m_ops m2m_ops = {
+       .device_run     = pxp_device_run,
+       .job_ready      = pxp_job_ready,
+       .job_abort      = pxp_job_abort,
+};
+
+static void pxp_soft_reset(struct pxp_dev *dev)
+{
+       int ret;
+       u32 val;
+
+       writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_CLR);
+       writel(BM_PXP_CTRL_CLKGATE, dev->mmio + HW_PXP_CTRL_CLR);
+
+       writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_SET);
+
+       ret = readl_poll_timeout(dev->mmio + HW_PXP_CTRL, val,
+                                val & BM_PXP_CTRL_CLKGATE, 0, 100);
+       if (ret < 0)
+               pr_err("PXP reset timeout\n");
+
+       writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_CLR);
+       writel(BM_PXP_CTRL_CLKGATE, dev->mmio + HW_PXP_CTRL_CLR);
+}
+
+static int pxp_probe(struct platform_device *pdev)
+{
+       struct pxp_dev *dev;
+       struct resource *res;
+       struct video_device *vfd;
+       int irq;
+       int ret;
+
+       dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->clk = devm_clk_get(&pdev->dev, "axi");
+       if (IS_ERR(dev->clk)) {
+               ret = PTR_ERR(dev->clk);
+               dev_err(&pdev->dev, "Failed to get clk: %d\n", ret);
+               return ret;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       dev->mmio = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(dev->mmio)) {
+               ret = PTR_ERR(dev->mmio);
+               dev_err(&pdev->dev, "Failed to map register space: %d\n", ret);
+               return ret;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "Failed to get irq resource: %d\n", irq);
+               return irq;
+       }
+
+       ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler,
+                       IRQF_ONESHOT, dev_name(&pdev->dev), dev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
+               return ret;
+       }
+
+       clk_prepare_enable(dev->clk);
+       pxp_soft_reset(dev);
+
+       spin_lock_init(&dev->irqlock);
+
+       ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+       if (ret)
+               goto err_clk;
+
+       atomic_set(&dev->num_inst, 0);
+       mutex_init(&dev->dev_mutex);
+
+       dev->vfd = pxp_videodev;
+       vfd = &dev->vfd;
+       vfd->lock = &dev->dev_mutex;
+       vfd->v4l2_dev = &dev->v4l2_dev;
+
+       video_set_drvdata(vfd, dev);
+       snprintf(vfd->name, sizeof(vfd->name), "%s", pxp_videodev.name);
+       v4l2_info(&dev->v4l2_dev,
+                       "Device registered as /dev/video%d\n", vfd->num);
+
+       platform_set_drvdata(pdev, dev);
+
+       dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
+       if (IS_ERR(dev->m2m_dev)) {
+               v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
+               ret = PTR_ERR(dev->m2m_dev);
+               goto err_v4l2;
+       }
+
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+               goto err_m2m;
+       }
+
+       return 0;
+
+err_m2m:
+       v4l2_m2m_release(dev->m2m_dev);
+err_v4l2:
+       v4l2_device_unregister(&dev->v4l2_dev);
+err_clk:
+       clk_disable_unprepare(dev->clk);
+
+       return ret;
+}
+
+static int pxp_remove(struct platform_device *pdev)
+{
+       struct pxp_dev *dev = platform_get_drvdata(pdev);
+
+       writel(BM_PXP_CTRL_CLKGATE, dev->mmio + HW_PXP_CTRL_SET);
+       writel(BM_PXP_CTRL_SFTRST, dev->mmio + HW_PXP_CTRL_SET);
+
+       clk_disable_unprepare(dev->clk);
+
+       v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME);
+       video_unregister_device(&dev->vfd);
+       v4l2_m2m_release(dev->m2m_dev);
+       v4l2_device_unregister(&dev->v4l2_dev);
+
+       return 0;
+}
+
+static const struct of_device_id pxp_dt_ids[] = {
+       { .compatible = "fsl,imx6ull-pxp", .data = NULL },
+       { },
+};
+MODULE_DEVICE_TABLE(of, pxp_dt_ids);
+
+static struct platform_driver pxp_driver = {
+       .probe          = pxp_probe,
+       .remove         = pxp_remove,
+       .driver         = {
+               .name   = MEM2MEM_NAME,
+               .of_match_table = of_match_ptr(pxp_dt_ids),
+       },
+};
+
+module_platform_driver(pxp_driver);
+
+MODULE_DESCRIPTION("i.MX PXP mem2mem scaler/CSC/rotator");
+MODULE_AUTHOR("Philipp Zabel <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/imx-pxp.h b/drivers/media/platform/imx-pxp.h
new file mode 100644 (file)
index 0000000..44f95c7
--- /dev/null
@@ -0,0 +1,1685 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Freescale PXP Register Definitions
+ *
+ * based on pxp_dma_v3.h, Xml Revision: 1.77, Template Revision: 1.3
+ *
+ * Copyright 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+#ifndef __IMX_PXP_H__
+#define __IMX_PXP_H__
+
+#define HW_PXP_CTRL    (0x00000000)
+#define HW_PXP_CTRL_SET        (0x00000004)
+#define HW_PXP_CTRL_CLR        (0x00000008)
+#define HW_PXP_CTRL_TOG        (0x0000000c)
+
+#define BM_PXP_CTRL_SFTRST 0x80000000
+#define BF_PXP_CTRL_SFTRST(v) \
+       (((v) << 31) & BM_PXP_CTRL_SFTRST)
+#define BM_PXP_CTRL_CLKGATE 0x40000000
+#define BF_PXP_CTRL_CLKGATE(v)  \
+       (((v) << 30) & BM_PXP_CTRL_CLKGATE)
+#define BM_PXP_CTRL_RSVD4 0x20000000
+#define BF_PXP_CTRL_RSVD4(v)  \
+       (((v) << 29) & BM_PXP_CTRL_RSVD4)
+#define BM_PXP_CTRL_EN_REPEAT 0x10000000
+#define BF_PXP_CTRL_EN_REPEAT(v)  \
+       (((v) << 28) & BM_PXP_CTRL_EN_REPEAT)
+#define BM_PXP_CTRL_ENABLE_ROTATE1 0x08000000
+#define BF_PXP_CTRL_ENABLE_ROTATE1(v)  \
+       (((v) << 27) & BM_PXP_CTRL_ENABLE_ROTATE1)
+#define BM_PXP_CTRL_ENABLE_ROTATE0 0x04000000
+#define BF_PXP_CTRL_ENABLE_ROTATE0(v)  \
+       (((v) << 26) & BM_PXP_CTRL_ENABLE_ROTATE0)
+#define BM_PXP_CTRL_ENABLE_LUT 0x02000000
+#define BF_PXP_CTRL_ENABLE_LUT(v)  \
+       (((v) << 25) & BM_PXP_CTRL_ENABLE_LUT)
+#define BM_PXP_CTRL_ENABLE_CSC2 0x01000000
+#define BF_PXP_CTRL_ENABLE_CSC2(v)  \
+       (((v) << 24) & BM_PXP_CTRL_ENABLE_CSC2)
+#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
+#define BF_PXP_CTRL_BLOCK_SIZE(v)  \
+       (((v) << 23) & BM_PXP_CTRL_BLOCK_SIZE)
+#define BV_PXP_CTRL_BLOCK_SIZE__8X8   0x0
+#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
+#define BM_PXP_CTRL_RSVD1 0x00400000
+#define BF_PXP_CTRL_RSVD1(v)  \
+       (((v) << 22) & BM_PXP_CTRL_RSVD1)
+#define BM_PXP_CTRL_ENABLE_ALPHA_B 0x00200000
+#define BF_PXP_CTRL_ENABLE_ALPHA_B(v)  \
+       (((v) << 21) & BM_PXP_CTRL_ENABLE_ALPHA_B)
+#define BM_PXP_CTRL_ENABLE_INPUT_FETCH_STORE 0x00100000
+#define BF_PXP_CTRL_ENABLE_INPUT_FETCH_STORE(v)  \
+       (((v) << 20) & BM_PXP_CTRL_ENABLE_INPUT_FETCH_STORE)
+#define BM_PXP_CTRL_ENABLE_WFE_B 0x00080000
+#define BF_PXP_CTRL_ENABLE_WFE_B(v)  \
+       (((v) << 19) & BM_PXP_CTRL_ENABLE_WFE_B)
+#define BM_PXP_CTRL_ENABLE_WFE_A 0x00040000
+#define BF_PXP_CTRL_ENABLE_WFE_A(v)  \
+       (((v) << 18) & BM_PXP_CTRL_ENABLE_WFE_A)
+#define BM_PXP_CTRL_ENABLE_DITHER 0x00020000
+#define BF_PXP_CTRL_ENABLE_DITHER(v)  \
+       (((v) << 17) & BM_PXP_CTRL_ENABLE_DITHER)
+#define BM_PXP_CTRL_ENABLE_PS_AS_OUT 0x00010000
+#define BF_PXP_CTRL_ENABLE_PS_AS_OUT(v)  \
+       (((v) << 16) & BM_PXP_CTRL_ENABLE_PS_AS_OUT)
+#define BM_PXP_CTRL_VFLIP1 0x00008000
+#define BF_PXP_CTRL_VFLIP1(v)  \
+       (((v) << 15) & BM_PXP_CTRL_VFLIP1)
+#define BM_PXP_CTRL_HFLIP1 0x00004000
+#define BF_PXP_CTRL_HFLIP1(v)  \
+       (((v) << 14) & BM_PXP_CTRL_HFLIP1)
+#define BP_PXP_CTRL_ROTATE1      12
+#define BM_PXP_CTRL_ROTATE1 0x00003000
+#define BF_PXP_CTRL_ROTATE1(v)  \
+       (((v) << 12) & BM_PXP_CTRL_ROTATE1)
+#define BV_PXP_CTRL_ROTATE1__ROT_0   0x0
+#define BV_PXP_CTRL_ROTATE1__ROT_90  0x1
+#define BV_PXP_CTRL_ROTATE1__ROT_180 0x2
+#define BV_PXP_CTRL_ROTATE1__ROT_270 0x3
+#define BM_PXP_CTRL_VFLIP0 0x00000800
+#define BF_PXP_CTRL_VFLIP0(v)  \
+       (((v) << 11) & BM_PXP_CTRL_VFLIP0)
+#define BM_PXP_CTRL_HFLIP0 0x00000400
+#define BF_PXP_CTRL_HFLIP0(v)  \
+       (((v) << 10) & BM_PXP_CTRL_HFLIP0)
+#define BP_PXP_CTRL_ROTATE0      8
+#define BM_PXP_CTRL_ROTATE0 0x00000300
+#define BF_PXP_CTRL_ROTATE0(v)  \
+       (((v) << 8) & BM_PXP_CTRL_ROTATE0)
+#define BV_PXP_CTRL_ROTATE0__ROT_0   0x0
+#define BV_PXP_CTRL_ROTATE0__ROT_90  0x1
+#define BV_PXP_CTRL_ROTATE0__ROT_180 0x2
+#define BV_PXP_CTRL_ROTATE0__ROT_270 0x3
+#define BP_PXP_CTRL_RSVD0      6
+#define BM_PXP_CTRL_RSVD0 0x000000C0
+#define BF_PXP_CTRL_RSVD0(v)  \
+       (((v) << 6) & BM_PXP_CTRL_RSVD0)
+#define BM_PXP_CTRL_HANDSHAKE_ABORT_SKIP 0x00000020
+#define BF_PXP_CTRL_HANDSHAKE_ABORT_SKIP(v)  \
+       (((v) << 5) & BM_PXP_CTRL_HANDSHAKE_ABORT_SKIP)
+#define BM_PXP_CTRL_ENABLE_LCD0_HANDSHAKE 0x00000010
+#define BF_PXP_CTRL_ENABLE_LCD0_HANDSHAKE(v)  \
+       (((v) << 4) & BM_PXP_CTRL_ENABLE_LCD0_HANDSHAKE)
+#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
+#define BF_PXP_CTRL_LUT_DMA_IRQ_ENABLE(v)  \
+       (((v) << 3) & BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE)
+#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
+#define BF_PXP_CTRL_NEXT_IRQ_ENABLE(v)  \
+       (((v) << 2) & BM_PXP_CTRL_NEXT_IRQ_ENABLE)
+#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
+#define BF_PXP_CTRL_IRQ_ENABLE(v)  \
+       (((v) << 1) & BM_PXP_CTRL_IRQ_ENABLE)
+#define BM_PXP_CTRL_ENABLE 0x00000001
+#define BF_PXP_CTRL_ENABLE(v)  \
+       (((v) << 0) & BM_PXP_CTRL_ENABLE)
+
+#define HW_PXP_STAT    (0x00000010)
+#define HW_PXP_STAT_SET        (0x00000014)
+#define HW_PXP_STAT_CLR        (0x00000018)
+#define HW_PXP_STAT_TOG        (0x0000001c)
+
+#define BP_PXP_STAT_BLOCKX      24
+#define BM_PXP_STAT_BLOCKX 0xFF000000
+#define BF_PXP_STAT_BLOCKX(v) \
+       (((v) << 24) & BM_PXP_STAT_BLOCKX)
+#define BP_PXP_STAT_BLOCKY      16
+#define BM_PXP_STAT_BLOCKY 0x00FF0000
+#define BF_PXP_STAT_BLOCKY(v)  \
+       (((v) << 16) & BM_PXP_STAT_BLOCKY)
+#define BP_PXP_STAT_AXI_ERROR_ID_1      12
+#define BM_PXP_STAT_AXI_ERROR_ID_1 0x0000F000
+#define BF_PXP_STAT_AXI_ERROR_ID_1(v)  \
+       (((v) << 12) & BM_PXP_STAT_AXI_ERROR_ID_1)
+#define BM_PXP_STAT_RSVD2 0x00000800
+#define BF_PXP_STAT_RSVD2(v)  \
+       (((v) << 11) & BM_PXP_STAT_RSVD2)
+#define BM_PXP_STAT_AXI_READ_ERROR_1 0x00000400
+#define BF_PXP_STAT_AXI_READ_ERROR_1(v)  \
+       (((v) << 10) & BM_PXP_STAT_AXI_READ_ERROR_1)
+#define BM_PXP_STAT_AXI_WRITE_ERROR_1 0x00000200
+#define BF_PXP_STAT_AXI_WRITE_ERROR_1(v)  \
+       (((v) << 9) & BM_PXP_STAT_AXI_WRITE_ERROR_1)
+#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
+#define BF_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ(v)  \
+       (((v) << 8) & BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ)
+#define BP_PXP_STAT_AXI_ERROR_ID_0      4
+#define BM_PXP_STAT_AXI_ERROR_ID_0 0x000000F0
+#define BF_PXP_STAT_AXI_ERROR_ID_0(v)  \
+       (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID_0)
+#define BM_PXP_STAT_NEXT_IRQ 0x00000008
+#define BF_PXP_STAT_NEXT_IRQ(v)  \
+       (((v) << 3) & BM_PXP_STAT_NEXT_IRQ)
+#define BM_PXP_STAT_AXI_READ_ERROR_0 0x00000004
+#define BF_PXP_STAT_AXI_READ_ERROR_0(v)  \
+       (((v) << 2) & BM_PXP_STAT_AXI_READ_ERROR_0)
+#define BM_PXP_STAT_AXI_WRITE_ERROR_0 0x00000002
+#define BF_PXP_STAT_AXI_WRITE_ERROR_0(v)  \
+       (((v) << 1) & BM_PXP_STAT_AXI_WRITE_ERROR_0)
+#define BM_PXP_STAT_IRQ0 0x00000001
+#define BF_PXP_STAT_IRQ0(v)  \
+       (((v) << 0) & BM_PXP_STAT_IRQ0)
+
+#define HW_PXP_OUT_CTRL        (0x00000020)
+#define HW_PXP_OUT_CTRL_SET    (0x00000024)
+#define HW_PXP_OUT_CTRL_CLR    (0x00000028)
+#define HW_PXP_OUT_CTRL_TOG    (0x0000002c)
+
+#define BP_PXP_OUT_CTRL_ALPHA      24
+#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
+#define BF_PXP_OUT_CTRL_ALPHA(v) \
+       (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
+#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
+#define BF_PXP_OUT_CTRL_ALPHA_OUTPUT(v)  \
+       (((v) << 23) & BM_PXP_OUT_CTRL_ALPHA_OUTPUT)
+#define BP_PXP_OUT_CTRL_RSVD1      10
+#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
+#define BF_PXP_OUT_CTRL_RSVD1(v)  \
+       (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
+#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT      8
+#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
+#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v)  \
+       (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0      0x1
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1      0x2
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED  0x3
+#define BP_PXP_OUT_CTRL_RSVD0      5
+#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
+#define BF_PXP_OUT_CTRL_RSVD0(v)  \
+       (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
+#define BP_PXP_OUT_CTRL_FORMAT      0
+#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
+#define BF_PXP_OUT_CTRL_FORMAT(v)  \
+       (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888  0x0
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888    0x4
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888P   0x5
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555  0x8
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444  0x9
+#define BV_PXP_OUT_CTRL_FORMAT__RGB555    0xC
+#define BV_PXP_OUT_CTRL_FORMAT__RGB444    0xD
+#define BV_PXP_OUT_CTRL_FORMAT__RGB565    0xE
+#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444  0x10
+#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_OUT_CTRL_FORMAT__Y8     0x14
+#define BV_PXP_OUT_CTRL_FORMAT__Y4     0x15
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422  0x18
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420  0x19
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422  0x1A
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420  0x1B
+
+#define HW_PXP_OUT_BUF (0x00000030)
+
+#define BP_PXP_OUT_BUF_ADDR      0
+#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF_ADDR(v)   (v)
+
+#define HW_PXP_OUT_BUF2        (0x00000040)
+
+#define BP_PXP_OUT_BUF2_ADDR      0
+#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF2_ADDR(v)   (v)
+
+#define HW_PXP_OUT_PITCH       (0x00000050)
+
+#define BP_PXP_OUT_PITCH_RSVD      16
+#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_OUT_PITCH_RSVD(v) \
+       (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
+#define BP_PXP_OUT_PITCH_PITCH      0
+#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_OUT_PITCH_PITCH(v)  \
+       (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
+
+#define HW_PXP_OUT_LRC (0x00000060)
+
+#define BP_PXP_OUT_LRC_RSVD1      30
+#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_LRC_RSVD1(v) \
+       (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
+#define BP_PXP_OUT_LRC_X      16
+#define BM_PXP_OUT_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_LRC_X(v)  \
+       (((v) << 16) & BM_PXP_OUT_LRC_X)
+#define BP_PXP_OUT_LRC_RSVD0      14
+#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_LRC_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
+#define BP_PXP_OUT_LRC_Y      0
+#define BM_PXP_OUT_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_LRC_Y(v)  \
+       (((v) << 0) & BM_PXP_OUT_LRC_Y)
+
+#define HW_PXP_OUT_PS_ULC      (0x00000070)
+
+#define BP_PXP_OUT_PS_ULC_RSVD1      30
+#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
+       (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
+#define BP_PXP_OUT_PS_ULC_X      16
+#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_ULC_X(v)  \
+       (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
+#define BP_PXP_OUT_PS_ULC_RSVD0      14
+#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_ULC_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
+#define BP_PXP_OUT_PS_ULC_Y      0
+#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_ULC_Y(v)  \
+       (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
+
+#define HW_PXP_OUT_PS_LRC      (0x00000080)
+
+#define BP_PXP_OUT_PS_LRC_RSVD1      30
+#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
+       (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
+#define BP_PXP_OUT_PS_LRC_X      16
+#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_LRC_X(v)  \
+       (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
+#define BP_PXP_OUT_PS_LRC_RSVD0      14
+#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_LRC_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
+#define BP_PXP_OUT_PS_LRC_Y      0
+#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_LRC_Y(v)  \
+       (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
+
+#define HW_PXP_OUT_AS_ULC      (0x00000090)
+
+#define BP_PXP_OUT_AS_ULC_RSVD1      30
+#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
+       (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
+#define BP_PXP_OUT_AS_ULC_X      16
+#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_ULC_X(v)  \
+       (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
+#define BP_PXP_OUT_AS_ULC_RSVD0      14
+#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_ULC_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
+#define BP_PXP_OUT_AS_ULC_Y      0
+#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_ULC_Y(v)  \
+       (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
+
+#define HW_PXP_OUT_AS_LRC      (0x000000a0)
+
+#define BP_PXP_OUT_AS_LRC_RSVD1      30
+#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
+       (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
+#define BP_PXP_OUT_AS_LRC_X      16
+#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_LRC_X(v)  \
+       (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
+#define BP_PXP_OUT_AS_LRC_RSVD0      14
+#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_LRC_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
+#define BP_PXP_OUT_AS_LRC_Y      0
+#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_LRC_Y(v)  \
+       (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
+
+#define HW_PXP_PS_CTRL (0x000000b0)
+#define HW_PXP_PS_CTRL_SET     (0x000000b4)
+#define HW_PXP_PS_CTRL_CLR     (0x000000b8)
+#define HW_PXP_PS_CTRL_TOG     (0x000000bc)
+
+#define BP_PXP_PS_CTRL_RSVD1      12
+#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
+#define BF_PXP_PS_CTRL_RSVD1(v) \
+       (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
+#define BP_PXP_PS_CTRL_DECX      10
+#define BM_PXP_PS_CTRL_DECX 0x00000C00
+#define BF_PXP_PS_CTRL_DECX(v)  \
+       (((v) << 10) & BM_PXP_PS_CTRL_DECX)
+#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECX__DECX2   0x1
+#define BV_PXP_PS_CTRL_DECX__DECX4   0x2
+#define BV_PXP_PS_CTRL_DECX__DECX8   0x3
+#define BP_PXP_PS_CTRL_DECY      8
+#define BM_PXP_PS_CTRL_DECY 0x00000300
+#define BF_PXP_PS_CTRL_DECY(v)  \
+       (((v) << 8) & BM_PXP_PS_CTRL_DECY)
+#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECY__DECY2   0x1
+#define BV_PXP_PS_CTRL_DECY__DECY4   0x2
+#define BV_PXP_PS_CTRL_DECY__DECY8   0x3
+#define BM_PXP_PS_CTRL_RSVD0 0x00000080
+#define BF_PXP_PS_CTRL_RSVD0(v)  \
+       (((v) << 7) & BM_PXP_PS_CTRL_RSVD0)
+#define BM_PXP_PS_CTRL_WB_SWAP 0x00000040
+#define BF_PXP_PS_CTRL_WB_SWAP(v)  \
+       (((v) << 6) & BM_PXP_PS_CTRL_WB_SWAP)
+#define BP_PXP_PS_CTRL_FORMAT      0
+#define BM_PXP_PS_CTRL_FORMAT 0x0000003F
+#define BF_PXP_PS_CTRL_FORMAT(v)  \
+       (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
+#define BV_PXP_PS_CTRL_FORMAT__RGB888    0x4
+#define BV_PXP_PS_CTRL_FORMAT__RGB555    0xC
+#define BV_PXP_PS_CTRL_FORMAT__RGB444    0xD
+#define BV_PXP_PS_CTRL_FORMAT__RGB565    0xE
+#define BV_PXP_PS_CTRL_FORMAT__YUV1P444  0x10
+#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_PS_CTRL_FORMAT__Y8      0x14
+#define BV_PXP_PS_CTRL_FORMAT__Y4      0x15
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P422  0x18
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P420  0x19
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P422  0x1A
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P420  0x1B
+#define BV_PXP_PS_CTRL_FORMAT__YUV422    0x1E
+#define BV_PXP_PS_CTRL_FORMAT__YUV420    0x1F
+
+#define HW_PXP_PS_BUF  (0x000000c0)
+
+#define BP_PXP_PS_BUF_ADDR      0
+#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_BUF_ADDR(v)   (v)
+
+#define HW_PXP_PS_UBUF (0x000000d0)
+
+#define BP_PXP_PS_UBUF_ADDR      0
+#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_UBUF_ADDR(v)   (v)
+
+#define HW_PXP_PS_VBUF (0x000000e0)
+
+#define BP_PXP_PS_VBUF_ADDR      0
+#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_VBUF_ADDR(v)   (v)
+
+#define HW_PXP_PS_PITCH        (0x000000f0)
+
+#define BP_PXP_PS_PITCH_RSVD      16
+#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_PS_PITCH_RSVD(v) \
+       (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
+#define BP_PXP_PS_PITCH_PITCH      0
+#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_PS_PITCH_PITCH(v)  \
+       (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
+
+#define HW_PXP_PS_BACKGROUND_0 (0x00000100)
+
+#define BP_PXP_PS_BACKGROUND_0_RSVD      24
+#define BM_PXP_PS_BACKGROUND_0_RSVD 0xFF000000
+#define BF_PXP_PS_BACKGROUND_0_RSVD(v) \
+       (((v) << 24) & BM_PXP_PS_BACKGROUND_0_RSVD)
+#define BP_PXP_PS_BACKGROUND_0_COLOR      0
+#define BM_PXP_PS_BACKGROUND_0_COLOR 0x00FFFFFF
+#define BF_PXP_PS_BACKGROUND_0_COLOR(v)  \
+       (((v) << 0) & BM_PXP_PS_BACKGROUND_0_COLOR)
+
+#define HW_PXP_PS_SCALE        (0x00000110)
+
+#define BM_PXP_PS_SCALE_RSVD2 0x80000000
+#define BF_PXP_PS_SCALE_RSVD2(v) \
+       (((v) << 31) & BM_PXP_PS_SCALE_RSVD2)
+#define BP_PXP_PS_SCALE_YSCALE      16
+#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
+#define BF_PXP_PS_SCALE_YSCALE(v)  \
+       (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
+#define BM_PXP_PS_SCALE_RSVD1 0x00008000
+#define BF_PXP_PS_SCALE_RSVD1(v)  \
+       (((v) << 15) & BM_PXP_PS_SCALE_RSVD1)
+#define BP_PXP_PS_SCALE_XSCALE      0
+#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
+#define BF_PXP_PS_SCALE_XSCALE(v)  \
+       (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
+
+#define HW_PXP_PS_OFFSET       (0x00000120)
+
+#define BP_PXP_PS_OFFSET_RSVD2      28
+#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
+#define BF_PXP_PS_OFFSET_RSVD2(v) \
+       (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
+#define BP_PXP_PS_OFFSET_YOFFSET      16
+#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
+#define BF_PXP_PS_OFFSET_YOFFSET(v)  \
+       (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
+#define BP_PXP_PS_OFFSET_RSVD1      12
+#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
+#define BF_PXP_PS_OFFSET_RSVD1(v)  \
+       (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
+#define BP_PXP_PS_OFFSET_XOFFSET      0
+#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
+#define BF_PXP_PS_OFFSET_XOFFSET(v)  \
+       (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
+
+#define HW_PXP_PS_CLRKEYLOW_0  (0x00000130)
+
+#define BP_PXP_PS_CLRKEYLOW_0_RSVD1      24
+#define BM_PXP_PS_CLRKEYLOW_0_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYLOW_0_RSVD1(v) \
+       (((v) << 24) & BM_PXP_PS_CLRKEYLOW_0_RSVD1)
+#define BP_PXP_PS_CLRKEYLOW_0_PIXEL      0
+#define BM_PXP_PS_CLRKEYLOW_0_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYLOW_0_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_PS_CLRKEYLOW_0_PIXEL)
+
+#define HW_PXP_PS_CLRKEYHIGH_0 (0x00000140)
+
+#define BP_PXP_PS_CLRKEYHIGH_0_RSVD1      24
+#define BM_PXP_PS_CLRKEYHIGH_0_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYHIGH_0_RSVD1(v) \
+       (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_0_RSVD1)
+#define BP_PXP_PS_CLRKEYHIGH_0_PIXEL      0
+#define BM_PXP_PS_CLRKEYHIGH_0_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYHIGH_0_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_0_PIXEL)
+
+#define HW_PXP_AS_CTRL (0x00000150)
+
+#define BP_PXP_AS_CTRL_RSVD1      22
+#define BM_PXP_AS_CTRL_RSVD1 0xFFC00000
+#define BF_PXP_AS_CTRL_RSVD1(v) \
+       (((v) << 22) & BM_PXP_AS_CTRL_RSVD1)
+#define BM_PXP_AS_CTRL_ALPHA1_INVERT 0x00200000
+#define BF_PXP_AS_CTRL_ALPHA1_INVERT(v)  \
+       (((v) << 21) & BM_PXP_AS_CTRL_ALPHA1_INVERT)
+#define BM_PXP_AS_CTRL_ALPHA0_INVERT 0x00100000
+#define BF_PXP_AS_CTRL_ALPHA0_INVERT(v)  \
+       (((v) << 20) & BM_PXP_AS_CTRL_ALPHA0_INVERT)
+#define BP_PXP_AS_CTRL_ROP      16
+#define BM_PXP_AS_CTRL_ROP 0x000F0000
+#define BF_PXP_AS_CTRL_ROP(v)  \
+       (((v) << 16) & BM_PXP_AS_CTRL_ROP)
+#define BV_PXP_AS_CTRL_ROP__MASKAS     0x0
+#define BV_PXP_AS_CTRL_ROP__MASKNOTAS  0x1
+#define BV_PXP_AS_CTRL_ROP__MASKASNOT  0x2
+#define BV_PXP_AS_CTRL_ROP__MERGEAS    0x3
+#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
+#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
+#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS  0x6
+#define BV_PXP_AS_CTRL_ROP__NOT        0x7
+#define BV_PXP_AS_CTRL_ROP__NOTMASKAS  0x8
+#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
+#define BV_PXP_AS_CTRL_ROP__XORAS      0xA
+#define BV_PXP_AS_CTRL_ROP__NOTXORAS   0xB
+#define BP_PXP_AS_CTRL_ALPHA      8
+#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
+#define BF_PXP_AS_CTRL_ALPHA(v)  \
+       (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
+#define BP_PXP_AS_CTRL_FORMAT      4
+#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
+#define BF_PXP_AS_CTRL_FORMAT(v)  \
+       (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
+#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_AS_CTRL_FORMAT__RGBA8888 0x1
+#define BV_PXP_AS_CTRL_FORMAT__RGB888   0x4
+#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_AS_CTRL_FORMAT__RGB555   0xC
+#define BV_PXP_AS_CTRL_FORMAT__RGB444   0xD
+#define BV_PXP_AS_CTRL_FORMAT__RGB565   0xE
+#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
+#define BF_PXP_AS_CTRL_ENABLE_COLORKEY(v)  \
+       (((v) << 3) & BM_PXP_AS_CTRL_ENABLE_COLORKEY)
+#define BP_PXP_AS_CTRL_ALPHA_CTRL      1
+#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
+#define BF_PXP_AS_CTRL_ALPHA_CTRL(v)  \
+       (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs     0x3
+#define BM_PXP_AS_CTRL_RSVD0 0x00000001
+#define BF_PXP_AS_CTRL_RSVD0(v)  \
+       (((v) << 0) & BM_PXP_AS_CTRL_RSVD0)
+
+#define HW_PXP_AS_BUF  (0x00000160)
+
+#define BP_PXP_AS_BUF_ADDR      0
+#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_AS_BUF_ADDR(v)   (v)
+
+#define HW_PXP_AS_PITCH        (0x00000170)
+
+#define BP_PXP_AS_PITCH_RSVD      16
+#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_AS_PITCH_RSVD(v) \
+       (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
+#define BP_PXP_AS_PITCH_PITCH      0
+#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_AS_PITCH_PITCH(v)  \
+       (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
+
+#define HW_PXP_AS_CLRKEYLOW_0  (0x00000180)
+
+#define BP_PXP_AS_CLRKEYLOW_0_RSVD1      24
+#define BM_PXP_AS_CLRKEYLOW_0_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYLOW_0_RSVD1(v) \
+       (((v) << 24) & BM_PXP_AS_CLRKEYLOW_0_RSVD1)
+#define BP_PXP_AS_CLRKEYLOW_0_PIXEL      0
+#define BM_PXP_AS_CLRKEYLOW_0_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYLOW_0_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_AS_CLRKEYLOW_0_PIXEL)
+
+#define HW_PXP_AS_CLRKEYHIGH_0 (0x00000190)
+
+#define BP_PXP_AS_CLRKEYHIGH_0_RSVD1      24
+#define BM_PXP_AS_CLRKEYHIGH_0_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYHIGH_0_RSVD1(v) \
+       (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_0_RSVD1)
+#define BP_PXP_AS_CLRKEYHIGH_0_PIXEL      0
+#define BM_PXP_AS_CLRKEYHIGH_0_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYHIGH_0_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_0_PIXEL)
+
+#define HW_PXP_CSC1_COEF0      (0x000001a0)
+
+#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
+#define BF_PXP_CSC1_COEF0_YCBCR_MODE(v) \
+       (((v) << 31) & BM_PXP_CSC1_COEF0_YCBCR_MODE)
+#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
+#define BF_PXP_CSC1_COEF0_BYPASS(v)  \
+       (((v) << 30) & BM_PXP_CSC1_COEF0_BYPASS)
+#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
+#define BF_PXP_CSC1_COEF0_RSVD1(v)  \
+       (((v) << 29) & BM_PXP_CSC1_COEF0_RSVD1)
+#define BP_PXP_CSC1_COEF0_C0      18
+#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
+#define BF_PXP_CSC1_COEF0_C0(v)  \
+       (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
+#define BP_PXP_CSC1_COEF0_UV_OFFSET      9
+#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
+#define BF_PXP_CSC1_COEF0_UV_OFFSET(v)  \
+       (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
+#define BP_PXP_CSC1_COEF0_Y_OFFSET      0
+#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
+#define BF_PXP_CSC1_COEF0_Y_OFFSET(v)  \
+       (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
+
+#define HW_PXP_CSC1_COEF1      (0x000001b0)
+
+#define BP_PXP_CSC1_COEF1_RSVD1      27
+#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF1_RSVD1(v) \
+       (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
+#define BP_PXP_CSC1_COEF1_C1      16
+#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
+#define BF_PXP_CSC1_COEF1_C1(v)  \
+       (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
+#define BP_PXP_CSC1_COEF1_RSVD0      11
+#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF1_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
+#define BP_PXP_CSC1_COEF1_C4      0
+#define BM_PXP_CSC1_COEF1_C4 0x000007FF
+#define BF_PXP_CSC1_COEF1_C4(v)  \
+       (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
+
+#define HW_PXP_CSC1_COEF2      (0x000001c0)
+
+#define BP_PXP_CSC1_COEF2_RSVD1      27
+#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF2_RSVD1(v) \
+       (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
+#define BP_PXP_CSC1_COEF2_C2      16
+#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
+#define BF_PXP_CSC1_COEF2_C2(v)  \
+       (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
+#define BP_PXP_CSC1_COEF2_RSVD0      11
+#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF2_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
+#define BP_PXP_CSC1_COEF2_C3      0
+#define BM_PXP_CSC1_COEF2_C3 0x000007FF
+#define BF_PXP_CSC1_COEF2_C3(v)  \
+       (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
+
+#define HW_PXP_CSC2_CTRL       (0x000001d0)
+
+#define BP_PXP_CSC2_CTRL_RSVD      3
+#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
+#define BF_PXP_CSC2_CTRL_RSVD(v) \
+       (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
+#define BP_PXP_CSC2_CTRL_CSC_MODE      1
+#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
+#define BF_PXP_CSC2_CTRL_CSC_MODE(v)  \
+       (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB   0x0
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV   0x2
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
+#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
+#define BF_PXP_CSC2_CTRL_BYPASS(v)  \
+       (((v) << 0) & BM_PXP_CSC2_CTRL_BYPASS)
+
+#define HW_PXP_CSC2_COEF0      (0x000001e0)
+
+#define BP_PXP_CSC2_COEF0_RSVD1      27
+#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF0_RSVD1(v) \
+       (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
+#define BP_PXP_CSC2_COEF0_A2      16
+#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
+#define BF_PXP_CSC2_COEF0_A2(v)  \
+       (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
+#define BP_PXP_CSC2_COEF0_RSVD0      11
+#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF0_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
+#define BP_PXP_CSC2_COEF0_A1      0
+#define BM_PXP_CSC2_COEF0_A1 0x000007FF
+#define BF_PXP_CSC2_COEF0_A1(v)  \
+       (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
+
+#define HW_PXP_CSC2_COEF1      (0x000001f0)
+
+#define BP_PXP_CSC2_COEF1_RSVD1      27
+#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF1_RSVD1(v) \
+       (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
+#define BP_PXP_CSC2_COEF1_B1      16
+#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
+#define BF_PXP_CSC2_COEF1_B1(v)  \
+       (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
+#define BP_PXP_CSC2_COEF1_RSVD0      11
+#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF1_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
+#define BP_PXP_CSC2_COEF1_A3      0
+#define BM_PXP_CSC2_COEF1_A3 0x000007FF
+#define BF_PXP_CSC2_COEF1_A3(v)  \
+       (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
+
+#define HW_PXP_CSC2_COEF2      (0x00000200)
+
+#define BP_PXP_CSC2_COEF2_RSVD1      27
+#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF2_RSVD1(v) \
+       (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
+#define BP_PXP_CSC2_COEF2_B3      16
+#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
+#define BF_PXP_CSC2_COEF2_B3(v)  \
+       (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
+#define BP_PXP_CSC2_COEF2_RSVD0      11
+#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF2_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
+#define BP_PXP_CSC2_COEF2_B2      0
+#define BM_PXP_CSC2_COEF2_B2 0x000007FF
+#define BF_PXP_CSC2_COEF2_B2(v)  \
+       (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
+
+#define HW_PXP_CSC2_COEF3      (0x00000210)
+
+#define BP_PXP_CSC2_COEF3_RSVD1      27
+#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF3_RSVD1(v) \
+       (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
+#define BP_PXP_CSC2_COEF3_C2      16
+#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
+#define BF_PXP_CSC2_COEF3_C2(v)  \
+       (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
+#define BP_PXP_CSC2_COEF3_RSVD0      11
+#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF3_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
+#define BP_PXP_CSC2_COEF3_C1      0
+#define BM_PXP_CSC2_COEF3_C1 0x000007FF
+#define BF_PXP_CSC2_COEF3_C1(v)  \
+       (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
+
+#define HW_PXP_CSC2_COEF4      (0x00000220)
+
+#define BP_PXP_CSC2_COEF4_RSVD1      25
+#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF4_RSVD1(v) \
+       (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
+#define BP_PXP_CSC2_COEF4_D1      16
+#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
+#define BF_PXP_CSC2_COEF4_D1(v)  \
+       (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
+#define BP_PXP_CSC2_COEF4_RSVD0      11
+#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF4_RSVD0(v)  \
+       (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
+#define BP_PXP_CSC2_COEF4_C3      0
+#define BM_PXP_CSC2_COEF4_C3 0x000007FF
+#define BF_PXP_CSC2_COEF4_C3(v)  \
+       (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
+
+#define HW_PXP_CSC2_COEF5      (0x00000230)
+
+#define BP_PXP_CSC2_COEF5_RSVD1      25
+#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF5_RSVD1(v) \
+       (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
+#define BP_PXP_CSC2_COEF5_D3      16
+#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
+#define BF_PXP_CSC2_COEF5_D3(v)  \
+       (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
+#define BP_PXP_CSC2_COEF5_RSVD0      9
+#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
+#define BF_PXP_CSC2_COEF5_RSVD0(v)  \
+       (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
+#define BP_PXP_CSC2_COEF5_D2      0
+#define BM_PXP_CSC2_COEF5_D2 0x000001FF
+#define BF_PXP_CSC2_COEF5_D2(v)  \
+       (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
+
+#define HW_PXP_LUT_CTRL        (0x00000240)
+
+#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
+#define BF_PXP_LUT_CTRL_BYPASS(v) \
+       (((v) << 31) & BM_PXP_LUT_CTRL_BYPASS)
+#define BP_PXP_LUT_CTRL_RSVD3      26
+#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
+#define BF_PXP_LUT_CTRL_RSVD3(v)  \
+       (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
+#define BP_PXP_LUT_CTRL_LOOKUP_MODE      24
+#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
+#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v)  \
+       (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565  0x0
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8     0x1
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
+#define BP_PXP_LUT_CTRL_RSVD2      18
+#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
+#define BF_PXP_LUT_CTRL_RSVD2(v)  \
+       (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
+#define BP_PXP_LUT_CTRL_OUT_MODE      16
+#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
+#define BF_PXP_LUT_CTRL_OUT_MODE(v)  \
+       (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
+#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED    0x0
+#define BV_PXP_LUT_CTRL_OUT_MODE__Y8     0x1
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888      0x3
+#define BP_PXP_LUT_CTRL_RSVD1      11
+#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
+#define BF_PXP_LUT_CTRL_RSVD1(v)  \
+       (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
+#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
+#define BF_PXP_LUT_CTRL_SEL_8KB(v)  \
+       (((v) << 10) & BM_PXP_LUT_CTRL_SEL_8KB)
+#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
+#define BF_PXP_LUT_CTRL_LRU_UPD(v)  \
+       (((v) << 9) & BM_PXP_LUT_CTRL_LRU_UPD)
+#define BM_PXP_LUT_CTRL_INVALID 0x00000100
+#define BF_PXP_LUT_CTRL_INVALID(v)  \
+       (((v) << 8) & BM_PXP_LUT_CTRL_INVALID)
+#define BP_PXP_LUT_CTRL_RSVD0      1
+#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
+#define BF_PXP_LUT_CTRL_RSVD0(v)  \
+       (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
+#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
+#define BF_PXP_LUT_CTRL_DMA_START(v)  \
+       (((v) << 0) & BM_PXP_LUT_CTRL_DMA_START)
+
+#define HW_PXP_LUT_ADDR        (0x00000250)
+
+#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
+#define BF_PXP_LUT_ADDR_RSVD2(v) \
+       (((v) << 31) & BM_PXP_LUT_ADDR_RSVD2)
+#define BP_PXP_LUT_ADDR_NUM_BYTES      16
+#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
+#define BF_PXP_LUT_ADDR_NUM_BYTES(v)  \
+       (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
+#define BP_PXP_LUT_ADDR_RSVD1      14
+#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
+#define BF_PXP_LUT_ADDR_RSVD1(v)  \
+       (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
+#define BP_PXP_LUT_ADDR_ADDR      0
+#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
+#define BF_PXP_LUT_ADDR_ADDR(v)  \
+       (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
+
+#define HW_PXP_LUT_DATA        (0x00000260)
+
+#define BP_PXP_LUT_DATA_DATA      0
+#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
+#define BF_PXP_LUT_DATA_DATA(v)   (v)
+
+#define HW_PXP_LUT_EXTMEM      (0x00000270)
+
+#define BP_PXP_LUT_EXTMEM_ADDR      0
+#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
+#define BF_PXP_LUT_EXTMEM_ADDR(v)   (v)
+
+#define HW_PXP_CFA     (0x00000280)
+
+#define BP_PXP_CFA_DATA      0
+#define BM_PXP_CFA_DATA 0xFFFFFFFF
+#define BF_PXP_CFA_DATA(v)   (v)
+
+#define HW_PXP_ALPHA_A_CTRL    (0x00000290)
+
+#define BP_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA      24
+#define BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA 0xFF000000
+#define BF_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA(v) \
+       (((v) << 24) & BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA      16
+#define BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA 0x00FF0000
+#define BF_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA(v)  \
+       (((v) << 16) & BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_A_CTRL_RSVD0      14
+#define BM_PXP_ALPHA_A_CTRL_RSVD0 0x0000C000
+#define BF_PXP_ALPHA_A_CTRL_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_ALPHA_A_CTRL_RSVD0)
+#define BM_PXP_ALPHA_A_CTRL_S1_COLOR_MODE 0x00002000
+#define BF_PXP_ALPHA_A_CTRL_S1_COLOR_MODE(v)  \
+       (((v) << 13) & BM_PXP_ALPHA_A_CTRL_S1_COLOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE 0x00001000
+#define BF_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE(v)  \
+       (((v) << 12) & BM_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE      10
+#define BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE 0x00000C00
+#define BF_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE(v)  \
+       (((v) << 10) & BM_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__1 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__2 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_GLOBAL_ALPHA_MODE__3 0x0
+#define BP_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE      8
+#define BM_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE 0x00000300
+#define BF_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE(v)  \
+       (((v) << 8) & BM_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_A_CTRL_S1_S0_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_A_CTRL_RSVD1 0x00000080
+#define BF_PXP_ALPHA_A_CTRL_RSVD1(v)  \
+       (((v) << 7) & BM_PXP_ALPHA_A_CTRL_RSVD1)
+#define BM_PXP_ALPHA_A_CTRL_S0_COLOR_MODE 0x00000040
+#define BF_PXP_ALPHA_A_CTRL_S0_COLOR_MODE(v)  \
+       (((v) << 6) & BM_PXP_ALPHA_A_CTRL_S0_COLOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE 0x00000020
+#define BF_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE(v)  \
+       (((v) << 5) & BM_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE      3
+#define BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE 0x00000018
+#define BF_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE(v)  \
+       (((v) << 3) & BM_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__1 0x1
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__2 0x2
+#define BV_PXP_ALPHA_A_CTRL_S0_GLOBAL_ALPHA_MODE__3 0x3
+#define BP_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE      1
+#define BM_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE 0x00000006
+#define BF_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE(v)  \
+       (((v) << 1) & BM_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE)
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_A_CTRL_S0_S1_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE 0x00000001
+#define BF_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE(v)  \
+       (((v) << 0) & BM_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE)
+#define BV_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE__0 0x0
+#define BV_PXP_ALPHA_A_CTRL_POTER_DUFF_ENABLE__1 0x1
+
+#define HW_PXP_ALPHA_B_CTRL    (0x000002a0)
+
+#define BP_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA      24
+#define BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA 0xFF000000
+#define BF_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA(v) \
+       (((v) << 24) & BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA      16
+#define BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA 0x00FF0000
+#define BF_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA(v)  \
+       (((v) << 16) & BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA)
+#define BP_PXP_ALPHA_B_CTRL_RSVD0      14
+#define BM_PXP_ALPHA_B_CTRL_RSVD0 0x0000C000
+#define BF_PXP_ALPHA_B_CTRL_RSVD0(v)  \
+       (((v) << 14) & BM_PXP_ALPHA_B_CTRL_RSVD0)
+#define BM_PXP_ALPHA_B_CTRL_S1_COLOR_MODE 0x00002000
+#define BF_PXP_ALPHA_B_CTRL_S1_COLOR_MODE(v)  \
+       (((v) << 13) & BM_PXP_ALPHA_B_CTRL_S1_COLOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE 0x00001000
+#define BF_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE(v)  \
+       (((v) << 12) & BM_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE      10
+#define BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE 0x00000C00
+#define BF_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE(v)  \
+       (((v) << 10) & BM_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S1_GLOBAL_ALPHA_MODE__3 0x3
+#define BP_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE      8
+#define BM_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE 0x00000300
+#define BF_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE(v)  \
+       (((v) << 8) & BM_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S1_S0_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_B_CTRL_RSVD1 0x00000080
+#define BF_PXP_ALPHA_B_CTRL_RSVD1(v)  \
+       (((v) << 7) & BM_PXP_ALPHA_B_CTRL_RSVD1)
+#define BM_PXP_ALPHA_B_CTRL_S0_COLOR_MODE 0x00000040
+#define BF_PXP_ALPHA_B_CTRL_S0_COLOR_MODE(v)  \
+       (((v) << 6) & BM_PXP_ALPHA_B_CTRL_S0_COLOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_COLOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_COLOR_MODE__1 0x1
+#define BM_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE 0x00000020
+#define BF_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE(v)  \
+       (((v) << 5) & BM_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_ALPHA_MODE__1 0x1
+#define BP_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE      3
+#define BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE 0x00000018
+#define BF_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE(v)  \
+       (((v) << 3) & BM_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S0_GLOBAL_ALPHA_MODE__3 0x3
+#define BP_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE      1
+#define BM_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE 0x00000006
+#define BF_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE(v)  \
+       (((v) << 1) & BM_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE)
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__1 0x1
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__2 0x2
+#define BV_PXP_ALPHA_B_CTRL_S0_S1_FACTOR_MODE__3 0x3
+#define BM_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE 0x00000001
+#define BF_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE(v)  \
+       (((v) << 0) & BM_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE)
+#define BV_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE__0 0x0
+#define BV_PXP_ALPHA_B_CTRL_POTER_DUFF_ENABLE__1 0x1
+
+#define HW_PXP_ALPHA_B_CTRL_1  (0x000002b0)
+
+#define BP_PXP_ALPHA_B_CTRL_1_RSVD0      8
+#define BM_PXP_ALPHA_B_CTRL_1_RSVD0 0xFFFFFF00
+#define BF_PXP_ALPHA_B_CTRL_1_RSVD0(v) \
+       (((v) << 8) & BM_PXP_ALPHA_B_CTRL_1_RSVD0)
+#define BP_PXP_ALPHA_B_CTRL_1_ROP      4
+#define BM_PXP_ALPHA_B_CTRL_1_ROP 0x000000F0
+#define BF_PXP_ALPHA_B_CTRL_1_ROP(v)  \
+       (((v) << 4) & BM_PXP_ALPHA_B_CTRL_1_ROP)
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKAS     0x0
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKNOTAS  0x1
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MASKASNOT  0x2
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGEAS    0x3
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGENOTAS 0x4
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__MERGEASNOT 0x5
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTCOPYAS  0x6
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOT 0x7
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTMASKAS  0x8
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTMERGEAS 0x9
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__XORAS      0xA
+#define BV_PXP_ALPHA_B_CTRL_1_ROP__NOTXORAS   0xB
+#define BP_PXP_ALPHA_B_CTRL_1_RSVD1      2
+#define BM_PXP_ALPHA_B_CTRL_1_RSVD1 0x0000000C
+#define BF_PXP_ALPHA_B_CTRL_1_RSVD1(v)  \
+       (((v) << 2) & BM_PXP_ALPHA_B_CTRL_1_RSVD1)
+#define BM_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE 0x00000002
+#define BF_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE(v)  \
+       (((v) << 1) & BM_PXP_ALPHA_B_CTRL_1_OL_CLRKEY_ENABLE)
+#define BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE 0x00000001
+#define BF_PXP_ALPHA_B_CTRL_1_ROP_ENABLE(v)  \
+       (((v) << 0) & BM_PXP_ALPHA_B_CTRL_1_ROP_ENABLE)
+
+#define HW_PXP_PS_BACKGROUND_1 (0x000002c0)
+
+#define BP_PXP_PS_BACKGROUND_1_RSVD      24
+#define BM_PXP_PS_BACKGROUND_1_RSVD 0xFF000000
+#define BF_PXP_PS_BACKGROUND_1_RSVD(v) \
+       (((v) << 24) & BM_PXP_PS_BACKGROUND_1_RSVD)
+#define BP_PXP_PS_BACKGROUND_1_COLOR      0
+#define BM_PXP_PS_BACKGROUND_1_COLOR 0x00FFFFFF
+#define BF_PXP_PS_BACKGROUND_1_COLOR(v)  \
+       (((v) << 0) & BM_PXP_PS_BACKGROUND_1_COLOR)
+
+#define HW_PXP_PS_CLRKEYLOW_1  (0x000002d0)
+
+#define BP_PXP_PS_CLRKEYLOW_1_RSVD1      24
+#define BM_PXP_PS_CLRKEYLOW_1_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYLOW_1_RSVD1(v) \
+       (((v) << 24) & BM_PXP_PS_CLRKEYLOW_1_RSVD1)
+#define BP_PXP_PS_CLRKEYLOW_1_PIXEL      0
+#define BM_PXP_PS_CLRKEYLOW_1_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYLOW_1_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_PS_CLRKEYLOW_1_PIXEL)
+
+#define HW_PXP_PS_CLRKEYHIGH_1 (0x000002e0)
+
+#define BP_PXP_PS_CLRKEYHIGH_1_RSVD1      24
+#define BM_PXP_PS_CLRKEYHIGH_1_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYHIGH_1_RSVD1(v) \
+       (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_1_RSVD1)
+#define BP_PXP_PS_CLRKEYHIGH_1_PIXEL      0
+#define BM_PXP_PS_CLRKEYHIGH_1_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYHIGH_1_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_1_PIXEL)
+
+#define HW_PXP_AS_CLRKEYLOW_1  (0x000002f0)
+
+#define BP_PXP_AS_CLRKEYLOW_1_RSVD1      24
+#define BM_PXP_AS_CLRKEYLOW_1_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYLOW_1_RSVD1(v) \
+       (((v) << 24) & BM_PXP_AS_CLRKEYLOW_1_RSVD1)
+#define BP_PXP_AS_CLRKEYLOW_1_PIXEL      0
+#define BM_PXP_AS_CLRKEYLOW_1_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYLOW_1_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_AS_CLRKEYLOW_1_PIXEL)
+
+#define HW_PXP_AS_CLRKEYHIGH_1 (0x00000300)
+
+#define BP_PXP_AS_CLRKEYHIGH_1_RSVD1      24
+#define BM_PXP_AS_CLRKEYHIGH_1_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYHIGH_1_RSVD1(v) \
+       (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_1_RSVD1)
+#define BP_PXP_AS_CLRKEYHIGH_1_PIXEL      0
+#define BM_PXP_AS_CLRKEYHIGH_1_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYHIGH_1_PIXEL(v)  \
+       (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_1_PIXEL)
+
+#define HW_PXP_CTRL2   (0x00000310)
+#define HW_PXP_CTRL2_SET       (0x00000314)
+#define HW_PXP_CTRL2_CLR       (0x00000318)
+#define HW_PXP_CTRL2_TOG       (0x0000031c)
+
+#define BP_PXP_CTRL2_RSVD3      28
+#define BM_PXP_CTRL2_RSVD3 0xF0000000
+#define BF_PXP_CTRL2_RSVD3(v) \
+       (((v) << 28) & BM_PXP_CTRL2_RSVD3)
+#define BM_PXP_CTRL2_ENABLE_ROTATE1 0x08000000
+#define BF_PXP_CTRL2_ENABLE_ROTATE1(v)  \
+       (((v) << 27) & BM_PXP_CTRL2_ENABLE_ROTATE1)
+#define BM_PXP_CTRL2_ENABLE_ROTATE0 0x04000000
+#define BF_PXP_CTRL2_ENABLE_ROTATE0(v)  \
+       (((v) << 26) & BM_PXP_CTRL2_ENABLE_ROTATE0)
+#define BM_PXP_CTRL2_ENABLE_LUT 0x02000000
+#define BF_PXP_CTRL2_ENABLE_LUT(v)  \
+       (((v) << 25) & BM_PXP_CTRL2_ENABLE_LUT)
+#define BM_PXP_CTRL2_ENABLE_CSC2 0x01000000
+#define BF_PXP_CTRL2_ENABLE_CSC2(v)  \
+       (((v) << 24) & BM_PXP_CTRL2_ENABLE_CSC2)
+#define BM_PXP_CTRL2_BLOCK_SIZE 0x00800000
+#define BF_PXP_CTRL2_BLOCK_SIZE(v)  \
+       (((v) << 23) & BM_PXP_CTRL2_BLOCK_SIZE)
+#define BV_PXP_CTRL2_BLOCK_SIZE__8X8   0x0
+#define BV_PXP_CTRL2_BLOCK_SIZE__16X16 0x1
+#define BM_PXP_CTRL2_RSVD2 0x00400000
+#define BF_PXP_CTRL2_RSVD2(v)  \
+       (((v) << 22) & BM_PXP_CTRL2_RSVD2)
+#define BM_PXP_CTRL2_ENABLE_ALPHA_B 0x00200000
+#define BF_PXP_CTRL2_ENABLE_ALPHA_B(v)  \
+       (((v) << 21) & BM_PXP_CTRL2_ENABLE_ALPHA_B)
+#define BM_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE 0x00100000
+#define BF_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE(v)  \
+       (((v) << 20) & BM_PXP_CTRL2_ENABLE_INPUT_FETCH_STORE)
+#define BM_PXP_CTRL2_ENABLE_WFE_B 0x00080000
+#define BF_PXP_CTRL2_ENABLE_WFE_B(v)  \
+       (((v) << 19) & BM_PXP_CTRL2_ENABLE_WFE_B)
+#define BM_PXP_CTRL2_ENABLE_WFE_A 0x00040000
+#define BF_PXP_CTRL2_ENABLE_WFE_A(v)  \
+       (((v) << 18) & BM_PXP_CTRL2_ENABLE_WFE_A)
+#define BM_PXP_CTRL2_ENABLE_DITHER 0x00020000
+#define BF_PXP_CTRL2_ENABLE_DITHER(v)  \
+       (((v) << 17) & BM_PXP_CTRL2_ENABLE_DITHER)
+#define BM_PXP_CTRL2_RSVD1 0x00010000
+#define BF_PXP_CTRL2_RSVD1(v)  \
+       (((v) << 16) & BM_PXP_CTRL2_RSVD1)
+#define BM_PXP_CTRL2_VFLIP1 0x00008000
+#define BF_PXP_CTRL2_VFLIP1(v)  \
+       (((v) << 15) & BM_PXP_CTRL2_VFLIP1)
+#define BM_PXP_CTRL2_HFLIP1 0x00004000
+#define BF_PXP_CTRL2_HFLIP1(v)  \
+       (((v) << 14) & BM_PXP_CTRL2_HFLIP1)
+#define BP_PXP_CTRL2_ROTATE1      12
+#define BM_PXP_CTRL2_ROTATE1 0x00003000
+#define BF_PXP_CTRL2_ROTATE1(v)  \
+       (((v) << 12) & BM_PXP_CTRL2_ROTATE1)
+#define BV_PXP_CTRL2_ROTATE1__ROT_0   0x0
+#define BV_PXP_CTRL2_ROTATE1__ROT_90  0x1
+#define BV_PXP_CTRL2_ROTATE1__ROT_180 0x2
+#define BV_PXP_CTRL2_ROTATE1__ROT_270 0x3
+#define BM_PXP_CTRL2_VFLIP0 0x00000800
+#define BF_PXP_CTRL2_VFLIP0(v)  \
+       (((v) << 11) & BM_PXP_CTRL2_VFLIP0)
+#define BM_PXP_CTRL2_HFLIP0 0x00000400
+#define BF_PXP_CTRL2_HFLIP0(v)  \
+       (((v) << 10) & BM_PXP_CTRL2_HFLIP0)
+#define BP_PXP_CTRL2_ROTATE0      8
+#define BM_PXP_CTRL2_ROTATE0 0x00000300
+#define BF_PXP_CTRL2_ROTATE0(v)  \
+       (((v) << 8) & BM_PXP_CTRL2_ROTATE0)
+#define BV_PXP_CTRL2_ROTATE0__ROT_0   0x0
+#define BV_PXP_CTRL2_ROTATE0__ROT_90  0x1
+#define BV_PXP_CTRL2_ROTATE0__ROT_180 0x2
+#define BV_PXP_CTRL2_ROTATE0__ROT_270 0x3
+#define BP_PXP_CTRL2_RSVD0      1
+#define BM_PXP_CTRL2_RSVD0 0x000000FE
+#define BF_PXP_CTRL2_RSVD0(v)  \
+       (((v) << 1) & BM_PXP_CTRL2_RSVD0)
+#define BM_PXP_CTRL2_ENABLE 0x00000001
+#define BF_PXP_CTRL2_ENABLE(v)  \
+       (((v) << 0) & BM_PXP_CTRL2_ENABLE)
+
+#define HW_PXP_POWER_REG0      (0x00000320)
+
+#define BP_PXP_POWER_REG0_CTRL      12
+#define BM_PXP_POWER_REG0_CTRL 0xFFFFF000
+#define BF_PXP_POWER_REG0_CTRL(v) \
+       (((v) << 12) & BM_PXP_POWER_REG0_CTRL)
+#define BP_PXP_POWER_REG0_ROT0_MEM_LP_STATE      9
+#define BM_PXP_POWER_REG0_ROT0_MEM_LP_STATE 0x00000E00
+#define BF_PXP_POWER_REG0_ROT0_MEM_LP_STATE(v)  \
+       (((v) << 9) & BM_PXP_POWER_REG0_ROT0_MEM_LP_STATE)
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG0_ROT0_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN      6
+#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN 0x000001C0
+#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN(v)  \
+       (((v) << 6) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN)
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__LS   0x1
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__DS   0x2
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY1_BANKN__SD   0x4
+#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN      3
+#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN 0x00000038
+#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN(v)  \
+       (((v) << 3) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN)
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__LS   0x1
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__DS   0x2
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANKN__SD   0x4
+#define BP_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0      0
+#define BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0 0x00000007
+#define BF_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0(v)  \
+       (((v) << 0) & BM_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0)
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__LS   0x1
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__DS   0x2
+#define BV_PXP_POWER_REG0_LUT_LP_STATE_WAY0_BANK0__SD   0x4
+
+#define HW_PXP_POWER_REG1      (0x00000330)
+
+#define BP_PXP_POWER_REG1_RSVD0      24
+#define BM_PXP_POWER_REG1_RSVD0 0xFF000000
+#define BF_PXP_POWER_REG1_RSVD0(v) \
+       (((v) << 24) & BM_PXP_POWER_REG1_RSVD0)
+#define BP_PXP_POWER_REG1_ALU_B_MEM_LP_STATE      21
+#define BM_PXP_POWER_REG1_ALU_B_MEM_LP_STATE 0x00E00000
+#define BF_PXP_POWER_REG1_ALU_B_MEM_LP_STATE(v)  \
+       (((v) << 21) & BM_PXP_POWER_REG1_ALU_B_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_ALU_B_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_ALU_A_MEM_LP_STATE      18
+#define BM_PXP_POWER_REG1_ALU_A_MEM_LP_STATE 0x001C0000
+#define BF_PXP_POWER_REG1_ALU_A_MEM_LP_STATE(v)  \
+       (((v) << 18) & BM_PXP_POWER_REG1_ALU_A_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_ALU_A_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE      15
+#define BM_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE 0x00038000
+#define BF_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE(v)  \
+       (((v) << 15) & BM_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_DITH2_LUT_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE      12
+#define BM_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE 0x00007000
+#define BF_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE(v)  \
+       (((v) << 12) & BM_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_DITH1_LUT_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE      9
+#define BM_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE 0x00000E00
+#define BF_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE(v)  \
+       (((v) << 9) & BM_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_DITH0_ERR1_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE      6
+#define BM_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE 0x000001C0
+#define BF_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE(v)  \
+       (((v) << 6) & BM_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_DITH0_ERR0_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE      3
+#define BM_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE 0x00000038
+#define BF_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE(v)  \
+       (((v) << 3) & BM_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_DITH0_LUT_MEM_LP_STATE__SD   0x4
+#define BP_PXP_POWER_REG1_ROT1_MEM_LP_STATE      0
+#define BM_PXP_POWER_REG1_ROT1_MEM_LP_STATE 0x00000007
+#define BF_PXP_POWER_REG1_ROT1_MEM_LP_STATE(v)  \
+       (((v) << 0) & BM_PXP_POWER_REG1_ROT1_MEM_LP_STATE)
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__LS   0x1
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__DS   0x2
+#define BV_PXP_POWER_REG1_ROT1_MEM_LP_STATE__SD   0x4
+
+#define HW_PXP_DATA_PATH_CTRL0 (0x00000340)
+#define HW_PXP_DATA_PATH_CTRL0_SET     (0x00000344)
+#define HW_PXP_DATA_PATH_CTRL0_CLR     (0x00000348)
+#define HW_PXP_DATA_PATH_CTRL0_TOG     (0x0000034c)
+
+#define BP_PXP_DATA_PATH_CTRL0_MUX15_SEL      30
+#define BM_PXP_DATA_PATH_CTRL0_MUX15_SEL 0xC0000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX15_SEL(v) \
+       (((v) << 30) & BM_PXP_DATA_PATH_CTRL0_MUX15_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX15_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX14_SEL      28
+#define BM_PXP_DATA_PATH_CTRL0_MUX14_SEL 0x30000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX14_SEL(v)  \
+       (((v) << 28) & BM_PXP_DATA_PATH_CTRL0_MUX14_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX14_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX13_SEL      26
+#define BM_PXP_DATA_PATH_CTRL0_MUX13_SEL 0x0C000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX13_SEL(v)  \
+       (((v) << 26) & BM_PXP_DATA_PATH_CTRL0_MUX13_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX13_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX12_SEL      24
+#define BM_PXP_DATA_PATH_CTRL0_MUX12_SEL 0x03000000
+#define BF_PXP_DATA_PATH_CTRL0_MUX12_SEL(v)  \
+       (((v) << 24) & BM_PXP_DATA_PATH_CTRL0_MUX12_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX12_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX11_SEL      22
+#define BM_PXP_DATA_PATH_CTRL0_MUX11_SEL 0x00C00000
+#define BF_PXP_DATA_PATH_CTRL0_MUX11_SEL(v)  \
+       (((v) << 22) & BM_PXP_DATA_PATH_CTRL0_MUX11_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX11_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX10_SEL      20
+#define BM_PXP_DATA_PATH_CTRL0_MUX10_SEL 0x00300000
+#define BF_PXP_DATA_PATH_CTRL0_MUX10_SEL(v)  \
+       (((v) << 20) & BM_PXP_DATA_PATH_CTRL0_MUX10_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX10_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX9_SEL      18
+#define BM_PXP_DATA_PATH_CTRL0_MUX9_SEL 0x000C0000
+#define BF_PXP_DATA_PATH_CTRL0_MUX9_SEL(v)  \
+       (((v) << 18) & BM_PXP_DATA_PATH_CTRL0_MUX9_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX9_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX8_SEL      16
+#define BM_PXP_DATA_PATH_CTRL0_MUX8_SEL 0x00030000
+#define BF_PXP_DATA_PATH_CTRL0_MUX8_SEL(v)  \
+       (((v) << 16) & BM_PXP_DATA_PATH_CTRL0_MUX8_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX8_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX7_SEL      14
+#define BM_PXP_DATA_PATH_CTRL0_MUX7_SEL 0x0000C000
+#define BF_PXP_DATA_PATH_CTRL0_MUX7_SEL(v)  \
+       (((v) << 14) & BM_PXP_DATA_PATH_CTRL0_MUX7_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX7_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX6_SEL      12
+#define BM_PXP_DATA_PATH_CTRL0_MUX6_SEL 0x00003000
+#define BF_PXP_DATA_PATH_CTRL0_MUX6_SEL(v)  \
+       (((v) << 12) & BM_PXP_DATA_PATH_CTRL0_MUX6_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX6_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX5_SEL      10
+#define BM_PXP_DATA_PATH_CTRL0_MUX5_SEL 0x00000C00
+#define BF_PXP_DATA_PATH_CTRL0_MUX5_SEL(v)  \
+       (((v) << 10) & BM_PXP_DATA_PATH_CTRL0_MUX5_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX5_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX4_SEL      8
+#define BM_PXP_DATA_PATH_CTRL0_MUX4_SEL 0x00000300
+#define BF_PXP_DATA_PATH_CTRL0_MUX4_SEL(v)  \
+       (((v) << 8) & BM_PXP_DATA_PATH_CTRL0_MUX4_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX4_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX3_SEL      6
+#define BM_PXP_DATA_PATH_CTRL0_MUX3_SEL 0x000000C0
+#define BF_PXP_DATA_PATH_CTRL0_MUX3_SEL(v)  \
+       (((v) << 6) & BM_PXP_DATA_PATH_CTRL0_MUX3_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX3_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX2_SEL      4
+#define BM_PXP_DATA_PATH_CTRL0_MUX2_SEL 0x00000030
+#define BF_PXP_DATA_PATH_CTRL0_MUX2_SEL(v)  \
+       (((v) << 4) & BM_PXP_DATA_PATH_CTRL0_MUX2_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX2_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX1_SEL      2
+#define BM_PXP_DATA_PATH_CTRL0_MUX1_SEL 0x0000000C
+#define BF_PXP_DATA_PATH_CTRL0_MUX1_SEL(v)  \
+       (((v) << 2) & BM_PXP_DATA_PATH_CTRL0_MUX1_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX1_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL0_MUX0_SEL      0
+#define BM_PXP_DATA_PATH_CTRL0_MUX0_SEL 0x00000003
+#define BF_PXP_DATA_PATH_CTRL0_MUX0_SEL(v)  \
+       (((v) << 0) & BM_PXP_DATA_PATH_CTRL0_MUX0_SEL)
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL0_MUX0_SEL__3 0x3
+
+#define HW_PXP_DATA_PATH_CTRL1 (0x00000350)
+#define HW_PXP_DATA_PATH_CTRL1_SET     (0x00000354)
+#define HW_PXP_DATA_PATH_CTRL1_CLR     (0x00000358)
+#define HW_PXP_DATA_PATH_CTRL1_TOG     (0x0000035c)
+
+#define BP_PXP_DATA_PATH_CTRL1_RSVD0      4
+#define BM_PXP_DATA_PATH_CTRL1_RSVD0 0xFFFFFFF0
+#define BF_PXP_DATA_PATH_CTRL1_RSVD0(v) \
+       (((v) << 4) & BM_PXP_DATA_PATH_CTRL1_RSVD0)
+#define BP_PXP_DATA_PATH_CTRL1_MUX17_SEL      2
+#define BM_PXP_DATA_PATH_CTRL1_MUX17_SEL 0x0000000C
+#define BF_PXP_DATA_PATH_CTRL1_MUX17_SEL(v)  \
+       (((v) << 2) & BM_PXP_DATA_PATH_CTRL1_MUX17_SEL)
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL1_MUX17_SEL__3 0x3
+#define BP_PXP_DATA_PATH_CTRL1_MUX16_SEL      0
+#define BM_PXP_DATA_PATH_CTRL1_MUX16_SEL 0x00000003
+#define BF_PXP_DATA_PATH_CTRL1_MUX16_SEL(v)  \
+       (((v) << 0) & BM_PXP_DATA_PATH_CTRL1_MUX16_SEL)
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__0 0x0
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__1 0x1
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__2 0x2
+#define BV_PXP_DATA_PATH_CTRL1_MUX16_SEL__3 0x3
+
+#define HW_PXP_INIT_MEM_CTRL   (0x00000360)
+#define HW_PXP_INIT_MEM_CTRL_SET       (0x00000364)
+#define HW_PXP_INIT_MEM_CTRL_CLR       (0x00000368)
+#define HW_PXP_INIT_MEM_CTRL_TOG       (0x0000036c)
+
+#define BM_PXP_INIT_MEM_CTRL_START 0x80000000
+#define BF_PXP_INIT_MEM_CTRL_START(v) \
+       (((v) << 31) & BM_PXP_INIT_MEM_CTRL_START)
+#define BP_PXP_INIT_MEM_CTRL_SELECT      27
+#define BM_PXP_INIT_MEM_CTRL_SELECT 0x78000000
+#define BF_PXP_INIT_MEM_CTRL_SELECT(v)  \
+       (((v) << 27) & BM_PXP_INIT_MEM_CTRL_SELECT)
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_LUT  0x0
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_ERR0 0x1
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER0_ERR1 0x2
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER1_LUT  0x3
+#define BV_PXP_INIT_MEM_CTRL_SELECT__DITHER2_LUT  0x4
+#define BV_PXP_INIT_MEM_CTRL_SELECT__ALU_A     0x5
+#define BV_PXP_INIT_MEM_CTRL_SELECT__ALU_B     0x6
+#define BV_PXP_INIT_MEM_CTRL_SELECT__WFE_A_FETCH  0x7
+#define BV_PXP_INIT_MEM_CTRL_SELECT__WFE_B_FETCH  0x8
+#define BV_PXP_INIT_MEM_CTRL_SELECT__RESERVED     0x15
+#define BP_PXP_INIT_MEM_CTRL_RSVD0      16
+#define BM_PXP_INIT_MEM_CTRL_RSVD0 0x07FF0000
+#define BF_PXP_INIT_MEM_CTRL_RSVD0(v)  \
+       (((v) << 16) & BM_PXP_INIT_MEM_CTRL_RSVD0)
+#define BP_PXP_INIT_MEM_CTRL_ADDR      0
+#define BM_PXP_INIT_MEM_CTRL_ADDR 0x0000FFFF
+#define BF_PXP_INIT_MEM_CTRL_ADDR(v)  \
+       (((v) << 0) & BM_PXP_INIT_MEM_CTRL_ADDR)
+
+#define HW_PXP_INIT_MEM_DATA   (0x00000370)
+
+#define BP_PXP_INIT_MEM_DATA_DATA      0
+#define BM_PXP_INIT_MEM_DATA_DATA 0xFFFFFFFF
+#define BF_PXP_INIT_MEM_DATA_DATA(v)   (v)
+
+#define HW_PXP_INIT_MEM_DATA_HIGH      (0x00000380)
+
+#define BP_PXP_INIT_MEM_DATA_HIGH_DATA      0
+#define BM_PXP_INIT_MEM_DATA_HIGH_DATA 0xFFFFFFFF
+#define BF_PXP_INIT_MEM_DATA_HIGH_DATA(v)   (v)
+
+#define HW_PXP_IRQ_MASK        (0x00000390)
+#define HW_PXP_IRQ_MASK_SET    (0x00000394)
+#define HW_PXP_IRQ_MASK_CLR    (0x00000398)
+#define HW_PXP_IRQ_MASK_TOG    (0x0000039c)
+
+#define BM_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN 0x80000000
+#define BF_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN(v) \
+       (((v) << 31) & BM_PXP_IRQ_MASK_COMPRESS_DONE_IRQ_EN)
+#define BP_PXP_IRQ_MASK_RSVD1      16
+#define BM_PXP_IRQ_MASK_RSVD1 0x7FFF0000
+#define BF_PXP_IRQ_MASK_RSVD1(v)  \
+       (((v) << 16) & BM_PXP_IRQ_MASK_RSVD1)
+#define BM_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN 0x00008000
+#define BF_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN(v)  \
+       (((v) << 15) & BM_PXP_IRQ_MASK_WFE_B_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN 0x00004000
+#define BF_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN(v)  \
+       (((v) << 14) & BM_PXP_IRQ_MASK_WFE_A_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN 0x00002000
+#define BF_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN(v)  \
+       (((v) << 13) & BM_PXP_IRQ_MASK_DITHER_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN 0x00001000
+#define BF_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN(v)  \
+       (((v) << 12) & BM_PXP_IRQ_MASK_FIRST_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN 0x00000800
+#define BF_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN(v)  \
+       (((v) << 11) & BM_PXP_IRQ_MASK_WFE_B_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN 0x00000400
+#define BF_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN(v)  \
+       (((v) << 10) & BM_PXP_IRQ_MASK_WFE_B_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN 0x00000200
+#define BF_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN(v)  \
+       (((v) << 9) & BM_PXP_IRQ_MASK_WFE_A_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN 0x00000100
+#define BF_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN(v)  \
+       (((v) << 8) & BM_PXP_IRQ_MASK_WFE_A_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN 0x00000080
+#define BF_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN(v)  \
+       (((v) << 7) & BM_PXP_IRQ_MASK_DITHER_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN 0x00000040
+#define BF_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN(v)  \
+       (((v) << 6) & BM_PXP_IRQ_MASK_DITHER_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN 0x00000020
+#define BF_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN(v)  \
+       (((v) << 5) & BM_PXP_IRQ_MASK_DITHER_CH1_PREFETCH_IRQ_EN)
+#define BM_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN 0x00000010
+#define BF_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN(v)  \
+       (((v) << 4) & BM_PXP_IRQ_MASK_DITHER_CH0_PREFETCH_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN 0x00000008
+#define BF_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN(v)  \
+       (((v) << 3) & BM_PXP_IRQ_MASK_FIRST_CH1_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN 0x00000004
+#define BF_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN(v)  \
+       (((v) << 2) & BM_PXP_IRQ_MASK_FIRST_CH0_STORE_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN 0x00000002
+#define BF_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN(v)  \
+       (((v) << 1) & BM_PXP_IRQ_MASK_FIRST_CH1_PREFETCH_IRQ_EN)
+#define BM_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN 0x00000001
+#define BF_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN(v)  \
+       (((v) << 0) & BM_PXP_IRQ_MASK_FIRST_CH0_PREFETCH_IRQ_EN)
+
+#define HW_PXP_IRQ     (0x000003a0)
+#define HW_PXP_IRQ_SET (0x000003a4)
+#define HW_PXP_IRQ_CLR (0x000003a8)
+#define HW_PXP_IRQ_TOG (0x000003ac)
+
+#define BM_PXP_IRQ_COMPRESS_DONE_IRQ 0x80000000
+#define BF_PXP_IRQ_COMPRESS_DONE_IRQ(v) \
+       (((v) << 31) & BM_PXP_IRQ_COMPRESS_DONE_IRQ)
+#define BP_PXP_IRQ_RSVD1      16
+#define BM_PXP_IRQ_RSVD1 0x7FFF0000
+#define BF_PXP_IRQ_RSVD1(v)  \
+       (((v) << 16) & BM_PXP_IRQ_RSVD1)
+#define BM_PXP_IRQ_WFE_B_STORE_IRQ 0x00008000
+#define BF_PXP_IRQ_WFE_B_STORE_IRQ(v)  \
+       (((v) << 15) & BM_PXP_IRQ_WFE_B_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_A_STORE_IRQ 0x00004000
+#define BF_PXP_IRQ_WFE_A_STORE_IRQ(v)  \
+       (((v) << 14) & BM_PXP_IRQ_WFE_A_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_STORE_IRQ 0x00002000
+#define BF_PXP_IRQ_DITHER_STORE_IRQ(v)  \
+       (((v) << 13) & BM_PXP_IRQ_DITHER_STORE_IRQ)
+#define BM_PXP_IRQ_FIRST_STORE_IRQ 0x00001000
+#define BF_PXP_IRQ_FIRST_STORE_IRQ(v)  \
+       (((v) << 12) & BM_PXP_IRQ_FIRST_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ 0x00000800
+#define BF_PXP_IRQ_WFE_B_CH1_STORE_IRQ(v)  \
+       (((v) << 11) & BM_PXP_IRQ_WFE_B_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ 0x00000400
+#define BF_PXP_IRQ_WFE_B_CH0_STORE_IRQ(v)  \
+       (((v) << 10) & BM_PXP_IRQ_WFE_B_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ 0x00000200
+#define BF_PXP_IRQ_WFE_A_CH1_STORE_IRQ(v)  \
+       (((v) << 9) & BM_PXP_IRQ_WFE_A_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ 0x00000100
+#define BF_PXP_IRQ_WFE_A_CH0_STORE_IRQ(v)  \
+       (((v) << 8) & BM_PXP_IRQ_WFE_A_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_CH1_STORE_IRQ 0x00000080
+#define BF_PXP_IRQ_DITHER_CH1_STORE_IRQ(v)  \
+       (((v) << 7) & BM_PXP_IRQ_DITHER_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_CH0_STORE_IRQ 0x00000040
+#define BF_PXP_IRQ_DITHER_CH0_STORE_IRQ(v)  \
+       (((v) << 6) & BM_PXP_IRQ_DITHER_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ 0x00000020
+#define BF_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ(v)  \
+       (((v) << 5) & BM_PXP_IRQ_DITHER_CH1_PREFETCH_IRQ)
+#define BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ 0x00000010
+#define BF_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ(v)  \
+       (((v) << 4) & BM_PXP_IRQ_DITHER_CH0_PREFETCH_IRQ)
+#define BM_PXP_IRQ_FIRST_CH1_STORE_IRQ 0x00000008
+#define BF_PXP_IRQ_FIRST_CH1_STORE_IRQ(v)  \
+       (((v) << 3) & BM_PXP_IRQ_FIRST_CH1_STORE_IRQ)
+#define BM_PXP_IRQ_FIRST_CH0_STORE_IRQ 0x00000004
+#define BF_PXP_IRQ_FIRST_CH0_STORE_IRQ(v)  \
+       (((v) << 2) & BM_PXP_IRQ_FIRST_CH0_STORE_IRQ)
+#define BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ 0x00000002
+#define BF_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ(v)  \
+       (((v) << 1) & BM_PXP_IRQ_FIRST_CH1_PREFETCH_IRQ)
+#define BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ 0x00000001
+#define BF_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ(v)  \
+       (((v) << 0) & BM_PXP_IRQ_FIRST_CH0_PREFETCH_IRQ)
+
+#define HW_PXP_NEXT    (0x00000400)
+
+#define BP_PXP_NEXT_POINTER      2
+#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
+#define BF_PXP_NEXT_POINTER(v) \
+       (((v) << 2) & BM_PXP_NEXT_POINTER)
+#define BM_PXP_NEXT_RSVD 0x00000002
+#define BF_PXP_NEXT_RSVD(v)  \
+       (((v) << 1) & BM_PXP_NEXT_RSVD)
+#define BM_PXP_NEXT_ENABLED 0x00000001
+#define BF_PXP_NEXT_ENABLED(v)  \
+       (((v) << 0) & BM_PXP_NEXT_ENABLED)
+
+#define HW_PXP_DEBUGCTRL       (0x00000410)
+
+#define BP_PXP_DEBUGCTRL_RSVD      12
+#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
+#define BF_PXP_DEBUGCTRL_RSVD(v) \
+       (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
+#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT      8
+#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
+#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v)  \
+       (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE     0x0
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT  0x2
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT  0x4
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT  0x8
+#define BP_PXP_DEBUGCTRL_SELECT      0
+#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
+#define BF_PXP_DEBUGCTRL_SELECT(v)  \
+       (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
+#define BV_PXP_DEBUGCTRL_SELECT__NONE  0x0
+#define BV_PXP_DEBUGCTRL_SELECT__CTRL  0x1
+#define BV_PXP_DEBUGCTRL_SELECT__PSBUF       0x2
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAX       0x3
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAY       0x4
+#define BV_PXP_DEBUGCTRL_SELECT__ASBUF       0x5
+#define BV_PXP_DEBUGCTRL_SELECT__ROTATION    0x6
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0     0x7
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1     0x8
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2     0x9
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT    0x10
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS    0x11
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT     0x12
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT     0x13
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
+
+#define HW_PXP_DEBUG   (0x00000420)
+
+#define BP_PXP_DEBUG_DATA      0
+#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
+#define BF_PXP_DEBUG_DATA(v)   (v)
+
+#define HW_PXP_VERSION (0x00000430)
+
+#define BP_PXP_VERSION_MAJOR      24
+#define BM_PXP_VERSION_MAJOR 0xFF000000
+#define BF_PXP_VERSION_MAJOR(v) \
+       (((v) << 24) & BM_PXP_VERSION_MAJOR)
+#define BP_PXP_VERSION_MINOR      16
+#define BM_PXP_VERSION_MINOR 0x00FF0000
+#define BF_PXP_VERSION_MINOR(v)  \
+       (((v) << 16) & BM_PXP_VERSION_MINOR)
+#define BP_PXP_VERSION_STEP      0
+#define BM_PXP_VERSION_STEP 0x0000FFFF
+#define BF_PXP_VERSION_STEP(v)  \
+       (((v) << 0) & BM_PXP_VERSION_STEP)
+
+#endif /* __IMX_PXP_H__ */
index 5f84d2aa47ab88e0d1de3a397f937fdc85d57dbc..c62e598ee7d022f3ae7375f2561ea8177182adb6 100644 (file)
@@ -438,9 +438,9 @@ static void deinterlace_device_run(void *priv)
 static int vidioc_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
-       strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card));
+       strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
+       strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
+       strscpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card));
        /*
         * This is only a mem-to-mem video device. The capture and output
         * device capability flags are left only for backward compatibility
@@ -474,7 +474,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
        if (i < NUM_FORMATS) {
                /* Format found */
                fmt = &formats[i];
-               strlcpy(f->description, fmt->name, sizeof(f->description));
+               strscpy(f->description, fmt->name, sizeof(f->description));
                f->pixelformat = fmt->fourcc;
                return 0;
        }
index 57d2c483ad0973f16db640ffd55e6702b8b4b971..2986cb4b88d0379cac9c5fd401cfa5561dfbe538 100644 (file)
@@ -341,7 +341,7 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
                return -ENOMEM;
        adap->owner = THIS_MODULE;
        adap->algo = &cafe_smbus_algo;
-       strcpy(adap->name, "cafe_ccic");
+       strscpy(adap->name, "cafe_ccic", sizeof(adap->name));
        adap->dev.parent = &cam->pdev->dev;
        i2c_set_adapdata(adap, cam);
        ret = i2c_add_adapter(adap);
index dfdbd4354b74cf700305c0b2c70a396938cd039a..f1b301810260a6fe602f276489c87e62e373b3d8 100644 (file)
@@ -794,7 +794,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
        /*
         * This field controls the generation of EOF(DVP only)
         */
-       if (cam->bus_type != V4L2_MBUS_CSI2)
+       if (cam->bus_type != V4L2_MBUS_CSI2_DPHY)
                mcam_reg_set_bit(cam, REG_CTRL0,
                                C0_EOF_VSYNC | C0_VEDGE_CTRL);
 }
@@ -1023,7 +1023,7 @@ static int mcam_read_setup(struct mcam_camera *cam)
                cam->calc_dphy(cam);
        cam_dbg(cam, "camera: DPHY sets: dphy3=0x%x, dphy5=0x%x, dphy6=0x%x\n",
                        cam->dphy[0], cam->dphy[1], cam->dphy[2]);
-       if (cam->bus_type == V4L2_MBUS_CSI2)
+       if (cam->bus_type == V4L2_MBUS_CSI2_DPHY)
                mcam_enable_mipi(cam);
        else
                mcam_disable_mipi(cam);
@@ -1303,9 +1303,9 @@ static int mcam_vidioc_querycap(struct file *file, void *priv,
 {
        struct mcam_camera *cam = video_drvdata(file);
 
-       strcpy(cap->driver, "marvell_ccic");
-       strcpy(cap->card, "marvell_ccic");
-       strlcpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info));
+       strscpy(cap->driver, "marvell_ccic", sizeof(cap->driver));
+       strscpy(cap->card, "marvell_ccic", sizeof(cap->card));
+       strscpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
                V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -1318,8 +1318,8 @@ static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp,
 {
        if (fmt->index >= N_MCAM_FMTS)
                return -EINVAL;
-       strlcpy(fmt->description, mcam_formats[fmt->index].desc,
-                       sizeof(fmt->description));
+       strscpy(fmt->description, mcam_formats[fmt->index].desc,
+               sizeof(fmt->description));
        fmt->pixelformat = mcam_formats[fmt->index].pixelformat;
        return 0;
 }
@@ -1421,7 +1421,7 @@ static int mcam_vidioc_enum_input(struct file *filp, void *priv,
                return -EINVAL;
 
        input->type = V4L2_INPUT_TYPE_CAMERA;
-       strcpy(input->name, "Camera");
+       strscpy(input->name, "Camera", sizeof(input->name));
        return 0;
 }
 
index 6d9f0abb26600534ad29ab83ac5c15686a650e6d..70a2833db0d146338d27bdcf04db04ceb62e5599 100644 (file)
@@ -362,7 +362,7 @@ static int mmpcam_probe(struct platform_device *pdev)
        mcam->mclk_div = pdata->mclk_div;
        mcam->bus_type = pdata->bus_type;
        mcam->dphy = pdata->dphy;
-       if (mcam->bus_type == V4L2_MBUS_CSI2) {
+       if (mcam->bus_type == V4L2_MBUS_CSI2_DPHY) {
                cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
                if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
                        return PTR_ERR(cam->mipi_clk);
@@ -371,7 +371,7 @@ static int mmpcam_probe(struct platform_device *pdev)
        mcam->lane = pdata->lane;
        mcam->chip_id = MCAM_ARMADA610;
        mcam->buffer_mode = B_DMA_sg;
-       strlcpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info));
+       strscpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info));
        spin_lock_init(&mcam->dev_lock);
        /*
         * Get our I/O memory.
index 4f24da8afecc4db93bbb482fd331daae084dff5b..2a5d5002c27ea8175d699ecb919f4ae2e513c9f3 100644 (file)
@@ -94,8 +94,8 @@ static int mtk_jpeg_querycap(struct file *file, void *priv,
 {
        struct mtk_jpeg_dev *jpeg = video_drvdata(file);
 
-       strlcpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver));
-       strlcpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card));
+       strscpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver));
+       strscpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(jpeg->dev));
 
index ceffc31cc6eb92f32db6e1ad0c0c4fb4b44191c6..51a13466261ef2d4ceaa45532797c36f25d1c4c3 100644 (file)
@@ -619,9 +619,9 @@ static int mtk_mdp_m2m_querycap(struct file *file, void *fh,
        struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
        struct mtk_mdp_dev *mdp = ctx->mdp_dev;
 
-       strlcpy(cap->driver, MTK_MDP_MODULE_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, mdp->pdev->name, sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:mt8173", sizeof(cap->bus_info));
+       strscpy(cap->driver, MTK_MDP_MODULE_NAME, sizeof(cap->driver));
+       strscpy(cap->card, mdp->pdev->name, sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:mt8173", sizeof(cap->bus_info));
 
        return 0;
 }
index 0c8a8b4c4e1cf1683cfeb81e732655a9961a3cdf..ba619647bc10e351467ac624f77b813ccf6757a0 100644 (file)
@@ -613,9 +613,9 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,
 static int vidioc_vdec_querycap(struct file *file, void *priv,
                                struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver));
-       strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
-       strlcpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
+       strscpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver));
+       strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
+       strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
 
        return 0;
 }
index 6ad408514a9984b999e0e0f99d9d439311716157..54631ad1c71eb760cc206322eb571203acd217f6 100644 (file)
@@ -222,9 +222,9 @@ static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
 static int vidioc_venc_querycap(struct file *file, void *priv,
                                struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver));
-       strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
-       strlcpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
+       strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver));
+       strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
+       strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
 
        return 0;
 }
index 0c28d0b995ccd7ff9a9679a3bd2726711fc6653c..e80123cba4062119b7c7aa2d0b99d470baacd39c 100644 (file)
@@ -49,16 +49,13 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
        struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data;
        struct device *dev = &ctx->dev->plat_dev->dev;
 
-       mem->va = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL);
-
+       mem->va = dma_zalloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL);
        if (!mem->va) {
                mtk_v4l2_err("%s dma_alloc size=%ld failed!", dev_name(dev),
                             size);
                return -ENOMEM;
        }
 
-       memset(mem->va, 0, size);
-
        mtk_v4l2_debug(3, "[%d]  - va      = %p", ctx->id, mem->va);
        mtk_v4l2_debug(3, "[%d]  - dma     = 0x%lx", ctx->id,
                       (unsigned long)mem->dma_addr);
index f8d35e3ac1dccce829238d6e030355dbb48c32bc..616f78b24a795ae1f555921b1220f159df692db3 100644 (file)
@@ -480,12 +480,12 @@ EXPORT_SYMBOL_GPL(vpu_get_plat_device);
 
 /* load vpu program/data memory */
 static int load_requested_vpu(struct mtk_vpu *vpu,
-                             const struct firmware *vpu_fw,
                              u8 fw_type)
 {
        size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE;
        size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE;
        char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW;
+       const struct firmware *vpu_fw;
        size_t dl_size = 0;
        size_t extra_fw_size = 0;
        void *dest;
@@ -539,7 +539,6 @@ int vpu_load_firmware(struct platform_device *pdev)
        struct mtk_vpu *vpu;
        struct device *dev = &pdev->dev;
        struct vpu_run *run;
-       const struct firmware *vpu_fw = NULL;
        int ret;
 
        if (!pdev) {
@@ -568,14 +567,14 @@ int vpu_load_firmware(struct platform_device *pdev)
        run->signaled = false;
        dev_dbg(vpu->dev, "firmware request\n");
        /* Downloading program firmware to device*/
-       ret = load_requested_vpu(vpu, vpu_fw, P_FW);
+       ret = load_requested_vpu(vpu, P_FW);
        if (ret < 0) {
                dev_err(dev, "Failed to request %s, %d\n", VPU_P_FW, ret);
                goto OUT_LOAD_FW;
        }
 
        /* Downloading data firmware to device */
-       ret = load_requested_vpu(vpu, vpu_fw, D_FW);
+       ret = load_requested_vpu(vpu, D_FW);
        if (ret < 0) {
                dev_err(dev, "Failed to request %s, %d\n", VPU_D_FW, ret);
                goto OUT_LOAD_FW;
index 64195c4ddeaf5d3b2f4c682cc4acc5dc3b744014..27b078cf98e35f737cc3f3f433c4627dd48c24e3 100644 (file)
@@ -413,7 +413,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
        if (i < NUM_FORMATS) {
                /* Format found */
                fmt = &formats[i];
-               strlcpy(f->description, fmt->name, sizeof(f->description) - 1);
+               strscpy(f->description, fmt->name, sizeof(f->description) - 1);
                f->pixelformat = fmt->fourcc;
                return 0;
        }
index 5700b7818621de4d91fa562e3515b2be09c8ba08..f447ae3bb465154922f7950a3f7fb9e2642f847d 100644 (file)
@@ -1041,8 +1041,8 @@ static int vidioc_querycap(struct file *file, void *fh,
 {
        struct omap_vout_device *vout = fh;
 
-       strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
+       strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
+       strscpy(cap->card, vout->vfd->name, sizeof(cap->card));
        cap->bus_info[0] = '\0';
        cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
                V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
@@ -1060,8 +1060,8 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
                return -EINVAL;
 
        fmt->flags = omap_formats[index].flags;
-       strlcpy(fmt->description, omap_formats[index].description,
-                       sizeof(fmt->description));
+       strscpy(fmt->description, omap_formats[index].description,
+               sizeof(fmt->description));
        fmt->pixelformat = omap_formats[index].pixelformat;
 
        return 0;
@@ -1868,7 +1868,7 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
        vfd->release = video_device_release;
        vfd->ioctl_ops = &vout_ioctl_ops;
 
-       strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
+       strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
 
        vfd->fops = &omap_vout_fops;
        vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
index 842e2235047d9c6327a65e1ab4fd9ea468fc015a..77fb7987b42f33cda57dc8b6627d4befc2d7a83e 100644 (file)
@@ -1677,7 +1677,7 @@ static int isp_register_entities(struct isp_device *isp)
        int ret;
 
        isp->media_dev.dev = isp->dev;
-       strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
+       strscpy(isp->media_dev.model, "TI OMAP3 ISP",
                sizeof(isp->media_dev.model));
        isp->media_dev.hw_revision = isp->revision;
        isp->media_dev.ops = &isp_media_ops;
@@ -2054,7 +2054,7 @@ static int isp_fwnode_parse(struct device *dev,
                        dev_dbg(dev, "CSI-1/CCP-2 configuration\n");
                        csi1 = true;
                        break;
-               case V4L2_MBUS_CSI2:
+               case V4L2_MBUS_CSI2_DPHY:
                        dev_dbg(dev, "CSI-2 configuration\n");
                        csi1 = false;
                        break;
@@ -2220,6 +2220,7 @@ static int isp_probe(struct platform_device *pdev)
 
        mutex_init(&isp->isp_mutex);
        spin_lock_init(&isp->stat_lock);
+       v4l2_async_notifier_init(&isp->notifier);
 
        ret = v4l2_async_notifier_parse_fwnode_endpoints(
                &pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev),
index 77b73e27a2746bf086d1bf86c7cb252582c94316..14a1c24037c4a7f12f2d859f8675b28dcdba876f 100644 (file)
@@ -2641,7 +2641,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 
        v4l2_subdev_init(sd, &ccdc_v4l2_ops);
        sd->internal_ops = &ccdc_v4l2_internal_ops;
-       strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
+       strscpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
        v4l2_set_subdevdata(sd, ccdc);
        sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
index e062939d0d054386b533ab8d3ab13afb3bdc1fbf..2dea423ffc0e365baf170185414755390bc78e12 100644 (file)
@@ -1070,7 +1070,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 
        v4l2_subdev_init(sd, &ccp2_sd_ops);
        sd->internal_ops = &ccp2_sd_internal_ops;
-       strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
+       strscpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
        v4l2_set_subdevdata(sd, ccp2);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index a4d3d030e81e20568b063d0544d18b64dd3a4d87..9c180f607bcb70ec9dd8c4f4a204fc69479b69a3 100644 (file)
@@ -1234,7 +1234,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 
        v4l2_subdev_init(sd, &csi2_ops);
        sd->internal_ops = &csi2_internal_ops;
-       strlcpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name));
+       strscpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name));
 
        sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
        v4l2_set_subdevdata(sd, csi2);
index 3195f7c8b8b7e43343af0908ad4a6ac8d0075a27..6ea6aeafd7513a42553d47a91f7c5a59ab8cc02f 100644 (file)
@@ -2267,7 +2267,7 @@ static int preview_init_entities(struct isp_prev_device *prev)
 
        v4l2_subdev_init(sd, &preview_v4l2_ops);
        sd->internal_ops = &preview_v4l2_internal_ops;
-       strlcpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name));
+       strscpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
        v4l2_set_subdevdata(sd, prev);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index 0b6a87508584f4eb5201f3f2b0bf284c1b7380f7..b281cae036b3d6dd75efd0b858450917364d7098 100644 (file)
@@ -1723,7 +1723,7 @@ static int resizer_init_entities(struct isp_res_device *res)
 
        v4l2_subdev_init(sd, &resizer_v4l2_ops);
        sd->internal_ops = &resizer_v4l2_internal_ops;
-       strlcpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name));
+       strscpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
        v4l2_set_subdevdata(sd, res);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index 9d228eac24ea538c45dac5dd15123193587f0bc4..078d64114b2410daca82f24f9afb07c45b38ab64 100644 (file)
@@ -654,9 +654,9 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
 {
        struct isp_video *video = video_drvdata(file);
 
-       strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, video->video.name, sizeof(cap->card));
-       strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
+       strscpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, video->video.name, sizeof(cap->card));
+       strscpy(cap->bus_info, "media", sizeof(cap->bus_info));
 
        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
                | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
@@ -940,7 +940,7 @@ isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
        int ret;
 
        mutex_lock(&video->queue_lock);
-       ret = vb2_qbuf(&vfh->queue, b);
+       ret = vb2_qbuf(&vfh->queue, video->video.v4l2_dev->mdev, b);
        mutex_unlock(&video->queue_lock);
 
        return ret;
@@ -1028,7 +1028,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
        ctrls.count = 1;
        ctrls.controls = &ctrl;
 
-       ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+       ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, NULL, &ctrls);
        if (ret < 0) {
                dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
                         pipe->external->name);
@@ -1251,7 +1251,7 @@ isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
        if (input->index > 0)
                return -EINVAL;
 
-       strlcpy(input->name, "camera", sizeof(input->name));
+       strscpy(input->name, "camera", sizeof(input->name));
        input->type = V4L2_INPUT_TYPE_CAMERA;
 
        return 0;
index b6e9e93bde7a8ad635a32eab35fc4658610d571a..5f930560eb30c799c01f1fa57c9324a46ce42739 100644 (file)
@@ -633,7 +633,7 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf
                mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
                return (!hsync || !vsync || !pclk || !data || !mode) ?
                        0 : common_flags;
-       case V4L2_MBUS_CSI2:
+       case V4L2_MBUS_CSI2_DPHY:
                mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
                mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
                                             V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
@@ -697,7 +697,6 @@ struct pxa_camera_dev {
        struct v4l2_pix_format  current_pix;
 
        struct v4l2_async_subdev asd;
-       struct v4l2_async_subdev *asds[1];
 
        /*
         * PXA27x is only supposed to handle one camera on its Quick Capture
@@ -1994,9 +1993,9 @@ static int pxac_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
 static int pxac_vidioc_querycap(struct file *file, void *priv,
                                struct v4l2_capability *cap)
 {
-       strlcpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info));
-       strlcpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info));
+       strscpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->card, pxa_cam_driver_description, sizeof(cap->card));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
@@ -2010,7 +2009,7 @@ static int pxac_vidioc_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
-       strlcpy(i->name, "Camera", sizeof(i->name));
+       strscpy(i->name, "Camera", sizeof(i->name));
 
        return 0;
 }
@@ -2299,7 +2298,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 {
        u32 mclk_rate;
        struct device_node *remote, *np = dev->of_node;
-       struct v4l2_fwnode_endpoint ep;
+       struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
        int err = of_property_read_u32(np, "clock-frequency",
                                       &mclk_rate);
        if (!err) {
@@ -2352,12 +2351,10 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 
        asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
        remote = of_graph_get_remote_port(np);
-       if (remote) {
+       if (remote)
                asd->match.fwnode = of_fwnode_handle(remote);
-               of_node_put(remote);
-       } else {
+       else
                dev_notice(dev, "no remote for %pOF\n", np);
-       }
 
 out:
        of_node_put(np);
@@ -2397,7 +2394,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
        pcdev->res = res;
 
        pcdev->pdata = pdev->dev.platform_data;
-       if (&pdev->dev.of_node && !pcdev->pdata) {
+       if (pdev->dev.of_node && !pcdev->pdata) {
                err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev, &pcdev->asd);
        } else {
                pcdev->platform_flags = pcdev->pdata->flags;
@@ -2495,9 +2492,14 @@ static int pxa_camera_probe(struct platform_device *pdev)
        if (err)
                goto exit_deactivate;
 
-       pcdev->asds[0] = &pcdev->asd;
-       pcdev->notifier.subdevs = pcdev->asds;
-       pcdev->notifier.num_subdevs = 1;
+       v4l2_async_notifier_init(&pcdev->notifier);
+
+       err = v4l2_async_notifier_add_subdev(&pcdev->notifier, &pcdev->asd);
+       if (err) {
+               fwnode_handle_put(pcdev->asd.match.fwnode);
+               goto exit_free_v4l2dev;
+       }
+
        pcdev->notifier.ops = &pxa_camera_sensor_ops;
 
        if (!of_have_populated_dt())
@@ -2505,7 +2507,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
 
        err = pxa_camera_init_videobuf2(pcdev);
        if (err)
-               goto exit_free_v4l2dev;
+               goto exit_notifier_cleanup;
 
        if (pcdev->mclk) {
                v4l2_clk_name_i2c(clk_name, sizeof(clk_name),
@@ -2516,7 +2518,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
                                                    clk_name, NULL);
                if (IS_ERR(pcdev->mclk_clk)) {
                        err = PTR_ERR(pcdev->mclk_clk);
-                       goto exit_free_v4l2dev;
+                       goto exit_notifier_cleanup;
                }
        }
 
@@ -2527,6 +2529,8 @@ static int pxa_camera_probe(struct platform_device *pdev)
        return 0;
 exit_free_clk:
        v4l2_clk_unregister(pcdev->mclk_clk);
+exit_notifier_cleanup:
+       v4l2_async_notifier_cleanup(&pcdev->notifier);
 exit_free_v4l2dev:
        v4l2_device_unregister(&pcdev->v4l2_dev);
 exit_deactivate:
@@ -2550,6 +2554,7 @@ static int pxa_camera_remove(struct platform_device *pdev)
        dma_release_channel(pcdev->dma_chans[2]);
 
        v4l2_async_notifier_unregister(&pcdev->notifier);
+       v4l2_async_notifier_cleanup(&pcdev->notifier);
 
        if (pcdev->mclk_clk) {
                v4l2_clk_unregister(pcdev->mclk_clk);
index c9bb0d023db480d1343b04ec953429996d9606a0..58aebe7114cd7dc5eb259cb4e9645be279c2765a 100644 (file)
@@ -521,8 +521,8 @@ static int video_querycap(struct file *file, void *fh,
 {
        struct camss_video *video = video_drvdata(file);
 
-       strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver));
-       strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
+       strscpy(cap->driver, "qcom-camss", sizeof(cap->driver));
+       strscpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(video->camss->dev));
 
@@ -683,7 +683,7 @@ static int video_enum_input(struct file *file, void *fh,
        if (input->index > 0)
                return -EINVAL;
 
-       strlcpy(input->name, "camera", sizeof(input->name));
+       strscpy(input->name, "camera", sizeof(input->name));
        input->type = V4L2_INPUT_TYPE_CAMERA;
 
        return 0;
@@ -919,7 +919,7 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
        vdev->vfl_dir = VFL_DIR_RX;
        vdev->queue = &video->vb2_q;
        vdev->lock = &video->lock;
-       strlcpy(vdev->name, name, sizeof(vdev->name));
+       strscpy(vdev->name, name, sizeof(vdev->name));
 
        ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
        if (ret < 0) {
index 669615fff6a0819dfa792a9be7253f92b39f79c5..45978db3b0bec8618efe61dce38bc08ff78f4ec3 100644 (file)
@@ -462,61 +462,51 @@ static int camss_of_parse_endpoint_node(struct device *dev,
  *
  * Return number of "port" nodes found in "ports" node
  */
-static int camss_of_parse_ports(struct device *dev,
-                               struct v4l2_async_notifier *notifier)
+static int camss_of_parse_ports(struct camss *camss)
 {
+       struct device *dev = camss->dev;
        struct device_node *node = NULL;
        struct device_node *remote = NULL;
-       unsigned int size, i;
-       int ret;
-
-       while ((node = of_graph_get_next_endpoint(dev->of_node, node)))
-               if (of_device_is_available(node))
-                       notifier->num_subdevs++;
-
-       of_node_put(node);
-       size = sizeof(*notifier->subdevs) * notifier->num_subdevs;
-       notifier->subdevs = devm_kzalloc(dev, size, GFP_KERNEL);
-       if (!notifier->subdevs) {
-               dev_err(dev, "Failed to allocate memory\n");
-               return -ENOMEM;
-       }
+       int ret, num_subdevs = 0;
 
-       i = 0;
-       while ((node = of_graph_get_next_endpoint(dev->of_node, node))) {
+       for_each_endpoint_of_node(dev->of_node, node) {
                struct camss_async_subdev *csd;
+               struct v4l2_async_subdev *asd;
 
                if (!of_device_is_available(node))
                        continue;
 
-               csd = devm_kzalloc(dev, sizeof(*csd), GFP_KERNEL);
-               if (!csd) {
-                       of_node_put(node);
-                       dev_err(dev, "Failed to allocate memory\n");
-                       return -ENOMEM;
-               }
-
-               notifier->subdevs[i++] = &csd->asd;
-
-               ret = camss_of_parse_endpoint_node(dev, node, csd);
-               if (ret < 0) {
-                       of_node_put(node);
-                       return ret;
-               }
-
                remote = of_graph_get_remote_port_parent(node);
                if (!remote) {
                        dev_err(dev, "Cannot get remote parent\n");
-                       of_node_put(node);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto err_cleanup;
                }
 
-               csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-               csd->asd.match.fwnode = of_fwnode_handle(remote);
+               asd = v4l2_async_notifier_add_fwnode_subdev(
+                       &camss->notifier, of_fwnode_handle(remote),
+                       sizeof(*csd));
+               if (IS_ERR(asd)) {
+                       ret = PTR_ERR(asd);
+                       of_node_put(remote);
+                       goto err_cleanup;
+               }
+
+               csd = container_of(asd, struct camss_async_subdev, asd);
+
+               ret = camss_of_parse_endpoint_node(dev, node, csd);
+               if (ret < 0)
+                       goto err_cleanup;
+
+               num_subdevs++;
        }
-       of_node_put(node);
 
-       return notifier->num_subdevs;
+       return num_subdevs;
+
+err_cleanup:
+       v4l2_async_notifier_cleanup(&camss->notifier);
+       of_node_put(node);
+       return ret;
 }
 
 /*
@@ -823,7 +813,7 @@ static int camss_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct camss *camss;
-       int ret;
+       int num_subdevs, ret;
 
        camss = kzalloc(sizeof(*camss), GFP_KERNEL);
        if (!camss)
@@ -863,20 +853,22 @@ static int camss_probe(struct platform_device *pdev)
        if (!camss->vfe)
                return -ENOMEM;
 
-       ret = camss_of_parse_ports(dev, &camss->notifier);
-       if (ret < 0)
-               return ret;
+       v4l2_async_notifier_init(&camss->notifier);
+
+       num_subdevs = camss_of_parse_ports(camss);
+       if (num_subdevs < 0)
+               return num_subdevs;
 
        ret = camss_init_subdevices(camss);
        if (ret < 0)
-               return ret;
+               goto err_cleanup;
 
        ret = dma_set_mask_and_coherent(dev, 0xffffffff);
        if (ret)
-               return ret;
+               goto err_cleanup;
 
        camss->media_dev.dev = camss->dev;
-       strlcpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
+       strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
                sizeof(camss->media_dev.model));
        camss->media_dev.ops = &camss_media_ops;
        media_device_init(&camss->media_dev);
@@ -885,14 +877,14 @@ static int camss_probe(struct platform_device *pdev)
        ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
        if (ret < 0) {
                dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
-               return ret;
+               goto err_cleanup;
        }
 
        ret = camss_register_entities(camss);
        if (ret < 0)
                goto err_register_entities;
 
-       if (camss->notifier.num_subdevs) {
+       if (num_subdevs) {
                camss->notifier.ops = &camss_subdev_notifier_ops;
 
                ret = v4l2_async_notifier_register(&camss->v4l2_dev,
@@ -942,6 +934,8 @@ err_register_subdevs:
        camss_unregister_entities(camss);
 err_register_entities:
        v4l2_device_unregister(&camss->v4l2_dev);
+err_cleanup:
+       v4l2_async_notifier_cleanup(&camss->notifier);
 
        return ret;
 }
@@ -978,6 +972,7 @@ static int camss_remove(struct platform_device *pdev)
                msm_vfe_stop_streaming(&camss->vfe[i]);
 
        v4l2_async_notifier_unregister(&camss->notifier);
+       v4l2_async_notifier_cleanup(&camss->notifier);
        camss_unregister_entities(camss);
 
        if (atomic_read(&camss->ref_count) == 0)
index 418996d8dad811443cd18b26813a90c833fa30c8..57b269ca93fd6ac29e81cfab21d35e024353937b 100644 (file)
@@ -17,7 +17,6 @@
 #include <media/v4l2-subdev.h>
 #include <media/media-device.h>
 #include <media/media-entity.h>
-#include <linux/device.h>
 
 #include "camss-csid.h"
 #include "camss-csiphy.h"
@@ -92,8 +91,8 @@ struct camss_camera_interface {
 };
 
 struct camss_async_subdev {
+       struct v4l2_async_subdev asd; /* must be first */
        struct camss_camera_interface interface;
-       struct v4l2_async_subdev asd;
 };
 
 struct camss_clock {
index cd3b96e6f24b2ff672a2f51fd52dc049ace604dc..e436385bc5ab5a11d506d02438c8852adb4c24f5 100644 (file)
@@ -472,7 +472,7 @@ static bool is_dynamic_bufmode(struct venus_inst *inst)
 
        caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
        if (!caps)
-               return 0;
+               return false;
 
        return caps->cap_bufs_mode_dynamic;
 }
index dfbbbf0f746f93e41d9bf39c69ddc066b8f7a4a1..189ec975c6bbdbe69f66558b609ced0c25e31c45 100644 (file)
@@ -341,9 +341,9 @@ vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
 static int
 vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver));
-       strlcpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
+       strscpy(cap->driver, "qcom-venus", sizeof(cap->driver));
+       strscpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
 
        return 0;
 }
@@ -888,8 +888,7 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
                unsigned int opb_sz = venus_helper_get_opb_size(inst);
 
                vb = &vbuf->vb2_buf;
-               vb->planes[0].bytesused =
-                       max_t(unsigned int, opb_sz, bytesused);
+               vb2_set_plane_payload(vb, 0, bytesused ? : opb_sz);
                vb->planes[0].data_offset = data_offset;
                vb->timestamp = timestamp_us * NSEC_PER_USEC;
                vbuf->sequence = inst->sequence_cap++;
@@ -1153,7 +1152,7 @@ static int vdec_probe(struct platform_device *pdev)
        if (!vdev)
                return -ENOMEM;
 
-       strlcpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name));
+       strscpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name));
        vdev->release = video_device_release;
        vdev->fops = &vdec_fops;
        vdev->ioctl_ops = &vdec_ioctl_ops;
index 41249d1443fa18dc1b1d4667ef81f36c3509fa86..ce85962b6adcc31597a6a95cda66d4b345fc8f85 100644 (file)
@@ -273,9 +273,9 @@ static int venc_v4l2_to_hfi(int id, int value)
 static int
 venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver));
-       strlcpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
+       strscpy(cap->driver, "qcom-venus", sizeof(cap->driver));
+       strscpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
 
        return 0;
 }
@@ -1257,7 +1257,7 @@ static int venc_probe(struct platform_device *pdev)
        if (!vdev)
                return -ENOMEM;
 
-       strlcpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name));
+       strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name));
        vdev->release = video_device_release;
        vdev->fops = &venc_fops;
        vdev->ioctl_ops = &venc_ioctl_ops;
index ce09799976efe1b506598123f9cf82997fb041ca..f476b2f1eb354781dc4dbd654b7ff549d3bc938d 100644 (file)
@@ -170,7 +170,6 @@ static int rvin_group_link_notify(struct media_link *link, u32 flags,
 
        if (csi_id == -ENODEV) {
                struct v4l2_subdev *sd;
-               unsigned int i;
 
                /*
                 * Make sure the source entity subdevice is registered as
@@ -268,8 +267,8 @@ static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
        match = of_match_node(vin->dev->driver->of_match_table,
                              vin->dev->of_node);
 
-       strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
-       strlcpy(mdev->model, match->compatible, sizeof(mdev->model));
+       strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
+       strscpy(mdev->model, match->compatible, sizeof(mdev->model));
        snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
                 dev_name(mdev->dev));
 
@@ -476,7 +475,7 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
                return ret;
 
        ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
-                                   NULL);
+                                   NULL, true);
        if (ret < 0) {
                v4l2_ctrl_handler_free(&vin->ctrl_handler);
                return ret;
@@ -611,6 +610,8 @@ static int rvin_parallel_init(struct rvin_dev *vin)
 {
        int ret;
 
+       v4l2_async_notifier_init(&vin->notifier);
+
        ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
                vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity),
                0, rvin_parallel_parse_v4l2);
@@ -803,6 +804,8 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
                return 0;
        }
 
+       v4l2_async_notifier_init(&vin->group->notifier);
+
        /*
         * Have all VIN's look for CSI-2 subdevices. Some subdevices will
         * overlap but the parser function can handle it, so each subdevice
@@ -824,7 +827,7 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
 
        mutex_unlock(&vin->group->lock);
 
-       if (!vin->group->notifier.num_subdevs)
+       if (list_empty(&vin->group->notifier.asd_list))
                return 0;
 
        vin->group->notifier.ops = &rvin_group_notify_ops;
index dc5ae8025832ab6e629557b1fa860731a5dfd796..b0044a08e71ed017a3c95c0a2d8d59234f22b865 100644 (file)
@@ -714,7 +714,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv,
        if (vep->base.port || vep->base.id)
                return -ENOTCONN;
 
-       if (vep->bus_type != V4L2_MBUS_CSI2) {
+       if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
                dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type);
                return -EINVAL;
        }
@@ -743,7 +743,7 @@ static int rcsi2_parse_v4l2(struct rcar_csi2 *priv,
 static int rcsi2_parse_dt(struct rcar_csi2 *priv)
 {
        struct device_node *ep;
-       struct v4l2_fwnode_endpoint v4l2_ep;
+       struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
        int ret;
 
        ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0);
@@ -771,21 +771,25 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv)
 
        of_node_put(ep);
 
-       priv->notifier.subdevs = devm_kzalloc(priv->dev,
-                                             sizeof(*priv->notifier.subdevs),
-                                             GFP_KERNEL);
-       if (!priv->notifier.subdevs)
-               return -ENOMEM;
+       v4l2_async_notifier_init(&priv->notifier);
+
+       ret = v4l2_async_notifier_add_subdev(&priv->notifier, &priv->asd);
+       if (ret) {
+               fwnode_handle_put(priv->asd.match.fwnode);
+               return ret;
+       }
 
-       priv->notifier.num_subdevs = 1;
-       priv->notifier.subdevs[0] = &priv->asd;
        priv->notifier.ops = &rcar_csi2_notify_ops;
 
        dev_dbg(priv->dev, "Found '%pOF'\n",
                to_of_node(priv->asd.match.fwnode));
 
-       return v4l2_async_subdev_notifier_register(&priv->subdev,
-                                                  &priv->notifier);
+       ret = v4l2_async_subdev_notifier_register(&priv->subdev,
+                                                 &priv->notifier);
+       if (ret)
+               v4l2_async_notifier_cleanup(&priv->notifier);
+
+       return ret;
 }
 
 /* -----------------------------------------------------------------------------
index 5a54779cfc27f65ddce716b2e784f3fcbd2ee431..dc77682b47857c97b820f17008dbe5f1b9115e26 100644 (file)
@@ -238,8 +238,8 @@ static int rvin_querycap(struct file *file, void *priv,
 {
        struct rvin_dev *vin = video_drvdata(file);
 
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, "R_Car_VIN", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(vin->dev));
        return 0;
@@ -440,7 +440,7 @@ static int rvin_enum_input(struct file *file, void *priv,
                i->std = vin->vdev.tvnorms;
        }
 
-       strlcpy(i->name, "Camera", sizeof(i->name));
+       strscpy(i->name, "Camera", sizeof(i->name));
 
        return 0;
 }
@@ -714,7 +714,7 @@ static int rvin_mc_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
-       strlcpy(i->name, "Camera", sizeof(i->name));
+       strscpy(i->name, "Camera", sizeof(i->name));
 
        return 0;
 }
index 81413ab52475d4132ef6c0c08f6c034f82395b25..c417ff8f6fe548f3d0c1e6682b8d0d4a4896045b 100644 (file)
@@ -870,8 +870,8 @@ static int rcar_drif_querycap(struct file *file, void *fh,
 {
        struct rcar_drif_sdr *sdr = video_drvdata(file);
 
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, sdr->vdev->name, sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, sdr->vdev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 sdr->vdev->name);
 
@@ -1164,7 +1164,7 @@ static int rcar_drif_notify_complete(struct v4l2_async_notifier *notifier)
        }
 
        ret = v4l2_ctrl_add_handler(&sdr->ctrl_hdl,
-                                   sdr->ep.subdev->ctrl_handler, NULL);
+                                   sdr->ep.subdev->ctrl_handler, NULL, true);
        if (ret) {
                rdrif_err(sdr, "failed: ctrl add hdlr ret %d\n", ret);
                goto error;
@@ -1213,18 +1213,15 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
 {
        struct v4l2_async_notifier *notifier = &sdr->notifier;
        struct fwnode_handle *fwnode, *ep;
+       int ret;
 
-       notifier->subdevs = devm_kzalloc(sdr->dev, sizeof(*notifier->subdevs),
-                                        GFP_KERNEL);
-       if (!notifier->subdevs)
-               return -ENOMEM;
+       v4l2_async_notifier_init(notifier);
 
        ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node),
                                            NULL);
        if (!ep)
                return 0;
 
-       notifier->subdevs[notifier->num_subdevs] = &sdr->ep.asd;
        fwnode = fwnode_graph_get_remote_port_parent(ep);
        if (!fwnode) {
                dev_warn(sdr->dev, "bad remote port parent\n");
@@ -1234,7 +1231,11 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
 
        sdr->ep.asd.match.fwnode = fwnode;
        sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-       notifier->num_subdevs++;
+       ret = v4l2_async_notifier_add_subdev(notifier, &sdr->ep.asd);
+       if (ret) {
+               fwnode_handle_put(fwnode);
+               return ret;
+       }
 
        /* Get the endpoint properties */
        rcar_drif_get_ep_properties(sdr, ep);
@@ -1356,11 +1357,13 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr)
        ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier);
        if (ret < 0) {
                dev_err(sdr->dev, "failed: notifier register ret %d\n", ret);
-               goto error;
+               goto cleanup;
        }
 
        return ret;
 
+cleanup:
+       v4l2_async_notifier_cleanup(&sdr->notifier);
 error:
        v4l2_device_unregister(&sdr->v4l2_dev);
 
@@ -1371,6 +1374,7 @@ error:
 static void rcar_drif_sdr_remove(struct rcar_drif_sdr *sdr)
 {
        v4l2_async_notifier_unregister(&sdr->notifier);
+       v4l2_async_notifier_cleanup(&sdr->notifier);
        v4l2_device_unregister(&sdr->v4l2_dev);
 }
 
index 2a15b7cca338fe6445ae11a8ec275c9e40ac1245..6bda1eee91702e5f767d584ce16d9bcf7c4be031 100644 (file)
@@ -1359,8 +1359,8 @@ static void device_frame_end(struct fdp1_dev *fdp1,
 static int fdp1_vidioc_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, DRIVER_NAME, sizeof(cap->card));
+       strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, DRIVER_NAME, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                        "platform:%s", DRIVER_NAME);
        return 0;
@@ -2339,7 +2339,7 @@ static int fdp1_probe(struct platform_device *pdev)
        vfd->lock = &fdp1->dev_mutex;
        vfd->v4l2_dev = &fdp1->v4l2_dev;
        video_set_drvdata(vfd, fdp1);
-       strlcpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));
+       strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));
 
        ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
        if (ret) {
index e5c882423f57482304ca52f92863687496fd4803..1dfd2eb65920012e346c30095c08af67740fcfb9 100644 (file)
@@ -664,11 +664,11 @@ static int jpu_querycap(struct file *file, void *priv,
        struct jpu_ctx *ctx = fh_to_ctx(priv);
 
        if (ctx->encoder)
-               strlcpy(cap->card, DRV_NAME " encoder", sizeof(cap->card));
+               strscpy(cap->card, DRV_NAME " encoder", sizeof(cap->card));
        else
-               strlcpy(cap->card, DRV_NAME " decoder", sizeof(cap->card));
+               strscpy(cap->card, DRV_NAME " decoder", sizeof(cap->card));
 
-       strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->driver, DRV_NAME, sizeof(cap->driver));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(ctx->jpu->dev));
        cap->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
@@ -1654,7 +1654,7 @@ static int jpu_probe(struct platform_device *pdev)
        for (i = 0; i < JPU_MAX_QUALITY; i++)
                jpu_generate_hdr(i, (unsigned char *)jpeg_hdrs[i]);
 
-       strlcpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name));
+       strscpy(jpu->vfd_encoder.name, DRV_NAME, sizeof(jpu->vfd_encoder.name));
        jpu->vfd_encoder.fops           = &jpu_fops;
        jpu->vfd_encoder.ioctl_ops      = &jpu_ioctl_ops;
        jpu->vfd_encoder.minor          = -1;
@@ -1671,7 +1671,7 @@ static int jpu_probe(struct platform_device *pdev)
 
        video_set_drvdata(&jpu->vfd_encoder, jpu);
 
-       strlcpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name));
+       strscpy(jpu->vfd_decoder.name, DRV_NAME, sizeof(jpu->vfd_decoder.name));
        jpu->vfd_decoder.fops           = &jpu_fops;
        jpu->vfd_decoder.ioctl_ops      = &jpu_ioctl_ops;
        jpu->vfd_decoder.minor          = -1;
index ad782901cd7a40594e0b7349c41c33691ba30019..150196f7cf96b16ee3d37e64839b235cebea607d 100644 (file)
@@ -189,8 +189,6 @@ struct ceu_device {
 
        /* async subdev notification helpers */
        struct v4l2_async_notifier notifier;
-       /* pointers to "struct ceu_subdevice -> asd" */
-       struct v4l2_async_subdev **asds;
 
        /* vb2 queue, capture buffer list and active buffer pointer */
        struct vb2_queue        vb2_vq;
@@ -1137,8 +1135,8 @@ static int ceu_querycap(struct file *file, void *priv,
 {
        struct ceu_device *ceudev = video_drvdata(file);
 
-       strlcpy(cap->card, "Renesas CEU", sizeof(cap->card));
-       strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, "Renesas CEU", sizeof(cap->card));
+       strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "platform:renesas-ceu-%s", dev_name(ceudev->dev));
 
@@ -1440,7 +1438,7 @@ static int ceu_notify_complete(struct v4l2_async_notifier *notifier)
                return ret;
 
        /* Register the video device. */
-       strlcpy(vdev->name, DRIVER_NAME, sizeof(vdev->name));
+       strscpy(vdev->name, DRIVER_NAME, sizeof(vdev->name));
        vdev->v4l2_dev          = v4l2_dev;
        vdev->lock              = &ceudev->mlock;
        vdev->queue             = &ceudev->vb2_vq;
@@ -1482,15 +1480,6 @@ static int ceu_init_async_subdevs(struct ceu_device *ceudev, unsigned int n_sd)
        if (!ceudev->subdevs)
                return -ENOMEM;
 
-       /*
-        * Reserve memory for 'n_sd' pointers to async_subdevices.
-        * ceudev->asds members will point to &ceu_subdev.asd
-        */
-       ceudev->asds = devm_kcalloc(ceudev->dev, n_sd,
-                                   sizeof(*ceudev->asds), GFP_KERNEL);
-       if (!ceudev->asds)
-               return -ENOMEM;
-
        ceudev->sd = NULL;
        ceudev->sd_index = 0;
        ceudev->num_sd = 0;
@@ -1518,6 +1507,7 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
                return ret;
 
        for (i = 0; i < pdata->num_subdevs; i++) {
+
                /* Setup the ceu subdevice and the async subdevice. */
                async_sd = &pdata->subdevs[i];
                ceu_sd = &ceudev->subdevs[i];
@@ -1529,7 +1519,12 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
                ceu_sd->asd.match.i2c.adapter_id = async_sd->i2c_adapter_id;
                ceu_sd->asd.match.i2c.address = async_sd->i2c_address;
 
-               ceudev->asds[i] = &ceu_sd->asd;
+               ret = v4l2_async_notifier_add_subdev(&ceudev->notifier,
+                                                    &ceu_sd->asd);
+               if (ret) {
+                       v4l2_async_notifier_cleanup(&ceudev->notifier);
+                       return ret;
+               }
        }
 
        return pdata->num_subdevs;
@@ -1541,9 +1536,8 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
 static int ceu_parse_dt(struct ceu_device *ceudev)
 {
        struct device_node *of = ceudev->dev->of_node;
-       struct v4l2_fwnode_endpoint fw_ep;
+       struct device_node *ep, *remote;
        struct ceu_subdev *ceu_sd;
-       struct device_node *ep;
        unsigned int i;
        int num_ep;
        int ret;
@@ -1557,45 +1551,55 @@ static int ceu_parse_dt(struct ceu_device *ceudev)
                return ret;
 
        for (i = 0; i < num_ep; i++) {
+               struct v4l2_fwnode_endpoint fw_ep = {
+                       .bus_type = V4L2_MBUS_PARALLEL,
+                       .bus = {
+                               .parallel = {
+                                       .flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+                                                V4L2_MBUS_VSYNC_ACTIVE_HIGH,
+                                       .bus_width = 8,
+                               },
+                       },
+               };
+
                ep = of_graph_get_endpoint_by_regs(of, 0, i);
                if (!ep) {
                        dev_err(ceudev->dev,
                                "No subdevice connected on endpoint %u.\n", i);
                        ret = -ENODEV;
-                       goto error_put_node;
+                       goto error_cleanup;
                }
 
                ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &fw_ep);
                if (ret) {
                        dev_err(ceudev->dev,
-                               "Unable to parse endpoint #%u.\n", i);
-                       goto error_put_node;
-               }
-
-               if (fw_ep.bus_type != V4L2_MBUS_PARALLEL) {
-                       dev_err(ceudev->dev,
-                               "Only parallel input supported.\n");
-                       ret = -EINVAL;
-                       goto error_put_node;
+                               "Unable to parse endpoint #%u: %d.\n", i, ret);
+                       goto error_cleanup;
                }
 
                /* Setup the ceu subdevice and the async subdevice. */
                ceu_sd = &ceudev->subdevs[i];
                INIT_LIST_HEAD(&ceu_sd->asd.list);
 
+               remote = of_graph_get_remote_port_parent(ep);
                ceu_sd->mbus_flags = fw_ep.bus.parallel.flags;
                ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-               ceu_sd->asd.match.fwnode =
-                       fwnode_graph_get_remote_port_parent(
-                                       of_fwnode_handle(ep));
+               ceu_sd->asd.match.fwnode = of_fwnode_handle(remote);
+
+               ret = v4l2_async_notifier_add_subdev(&ceudev->notifier,
+                                                    &ceu_sd->asd);
+               if (ret) {
+                       of_node_put(remote);
+                       goto error_cleanup;
+               }
 
-               ceudev->asds[i] = &ceu_sd->asd;
                of_node_put(ep);
        }
 
        return num_ep;
 
-error_put_node:
+error_cleanup:
+       v4l2_async_notifier_cleanup(&ceudev->notifier);
        of_node_put(ep);
        return ret;
 }
@@ -1674,6 +1678,8 @@ static int ceu_probe(struct platform_device *pdev)
        if (ret)
                goto error_pm_disable;
 
+       v4l2_async_notifier_init(&ceudev->notifier);
+
        if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
                ceu_data = of_match_device(ceu_of_match, dev)->data;
                num_subdevs = ceu_parse_dt(ceudev);
@@ -1693,18 +1699,18 @@ static int ceu_probe(struct platform_device *pdev)
        ceudev->irq_mask = ceu_data->irq_mask;
 
        ceudev->notifier.v4l2_dev       = &ceudev->v4l2_dev;
-       ceudev->notifier.subdevs        = ceudev->asds;
-       ceudev->notifier.num_subdevs    = num_subdevs;
        ceudev->notifier.ops            = &ceu_notify_ops;
        ret = v4l2_async_notifier_register(&ceudev->v4l2_dev,
                                           &ceudev->notifier);
        if (ret)
-               goto error_v4l2_unregister;
+               goto error_cleanup;
 
        dev_info(dev, "Renesas Capture Engine Unit %s\n", dev_name(dev));
 
        return 0;
 
+error_cleanup:
+       v4l2_async_notifier_cleanup(&ceudev->notifier);
 error_v4l2_unregister:
        v4l2_device_unregister(&ceudev->v4l2_dev);
 error_pm_disable:
@@ -1723,6 +1729,8 @@ static int ceu_remove(struct platform_device *pdev)
 
        v4l2_async_notifier_unregister(&ceudev->notifier);
 
+       v4l2_async_notifier_cleanup(&ceudev->notifier);
+
        v4l2_device_unregister(&ceudev->v4l2_dev);
 
        video_unregister_device(&ceudev->vdev);
index ab5a6f95044a2d0ab5a1b77a7a4e69708945ba73..9cc9db0838702f535cffc91269430e35002862b8 100644 (file)
@@ -447,9 +447,9 @@ static const struct v4l2_file_operations rga_fops = {
 static int
 vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, RGA_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, "rockchip-rga", sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info));
+       strscpy(cap->driver, RGA_NAME, sizeof(cap->driver));
+       strscpy(cap->card, "rockchip-rga", sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info));
 
        return 0;
 }
index c02dce8b4c6c788ba5dd025fc35b1378a9c466e9..c3fc94ef251e404a0281612761337660bdf233dd 100644 (file)
@@ -640,8 +640,8 @@ static int s3c_camif_vidioc_querycap(struct file *file, void *priv,
 {
        struct camif_vp *vp = video_drvdata(file);
 
-       strlcpy(cap->driver, S3C_CAMIF_DRIVER_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card));
+       strscpy(cap->driver, S3C_CAMIF_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d",
                 dev_name(vp->camif->dev), vp->id);
 
@@ -661,7 +661,7 @@ static int s3c_camif_vidioc_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        input->type = V4L2_INPUT_TYPE_CAMERA;
-       strlcpy(input->name, sensor->name, sizeof(input->name));
+       strscpy(input->name, sensor->name, sizeof(input->name));
        return 0;
 }
 
@@ -688,7 +688,7 @@ static int s3c_camif_vidioc_enum_fmt(struct file *file, void *priv,
        if (!fmt)
                return -EINVAL;
 
-       strlcpy(f->description, fmt->name, sizeof(f->description));
+       strscpy(f->description, fmt->name, sizeof(f->description));
        f->pixelformat = fmt->fourcc;
 
        pr_debug("fmt(%d): %s\n", f->index, f->description);
@@ -943,7 +943,7 @@ static int s3c_camif_qbuf(struct file *file, void *priv,
        if (vp->owner && vp->owner != priv)
                return -EBUSY;
 
-       return vb2_qbuf(&vp->vb_queue, buf);
+       return vb2_qbuf(&vp->vb_queue, vp->vdev.v4l2_dev->mdev, buf);
 }
 
 static int s3c_camif_dqbuf(struct file *file, void *priv,
@@ -981,7 +981,7 @@ static int s3c_camif_prepare_buf(struct file *file, void *priv,
                                 struct v4l2_buffer *b)
 {
        struct camif_vp *vp = video_drvdata(file);
-       return vb2_prepare_buf(&vp->vb_queue, b);
+       return vb2_prepare_buf(&vp->vb_queue, vp->vdev.v4l2_dev->mdev, b);
 }
 
 static int s3c_camif_g_selection(struct file *file, void *priv,
@@ -1555,7 +1555,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
 
        v4l2_subdev_init(sd, &s3c_camif_subdev_ops);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-       strlcpy(sd->name, "S3C-CAMIF", sizeof(sd->name));
+       strscpy(sd->name, "S3C-CAMIF", sizeof(sd->name));
 
        camif->pads[CAMIF_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
        camif->pads[CAMIF_SD_PAD_SOURCE_C].flags = MEDIA_PAD_FL_SOURCE;
index 79bc0ef6bb413d8cd15aaaea3662444d2b047635..31759f16458ed3acdc8de859c5af3585021344ba 100644 (file)
@@ -316,12 +316,12 @@ static int camif_media_dev_init(struct camif_dev *camif)
        memset(md, 0, sizeof(*md));
        snprintf(md->model, sizeof(md->model), "SAMSUNG S3C%s CAMIF",
                 ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X");
-       strlcpy(md->bus_info, "platform", sizeof(md->bus_info));
+       strscpy(md->bus_info, "platform", sizeof(md->bus_info));
        md->hw_revision = ip_rev;
 
        md->dev = camif->dev;
 
-       strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name));
        v4l2_dev->mdev = md;
 
        media_device_init(md);
index 04fd2e0493c0f9bc1da65603629d3f4645480e0f..3f9000b7038515170ef2e3dd9f9b35feb4a2cfa8 100644 (file)
@@ -1276,14 +1276,14 @@ static int s5p_jpeg_querycap(struct file *file, void *priv,
        struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
 
        if (ctx->mode == S5P_JPEG_ENCODE) {
-               strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
+               strscpy(cap->driver, S5P_JPEG_M2M_NAME,
                        sizeof(cap->driver));
-               strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
+               strscpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
                        sizeof(cap->card));
        } else {
-               strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
+               strscpy(cap->driver, S5P_JPEG_M2M_NAME,
                        sizeof(cap->driver));
-               strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
+               strscpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
                        sizeof(cap->card));
        }
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
@@ -1314,7 +1314,7 @@ static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
        if (i >= n)
                return -EINVAL;
 
-       strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
+       strscpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
        f->pixelformat = sjpeg_formats[i].fourcc;
 
        return 0;
index 6a3cc4f86c5df586b636dd81d4f81ef548cac4ac..ece59ce1b1499f3ee7e9bdca14f33d4f7ce430c8 100644 (file)
@@ -271,8 +271,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct s5p_mfc_dev *dev = video_drvdata(file);
 
-       strlcpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, dev->vfd_dec->name, sizeof(cap->card));
+       strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver));
+       strscpy(cap->card, dev->vfd_dec->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(&dev->plat_dev->dev));
        /*
@@ -308,7 +308,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
        if (i == ARRAY_SIZE(formats))
                return -EINVAL;
        fmt = &formats[i];
-       strlcpy(f->description, fmt->name, sizeof(f->description));
+       strscpy(f->description, fmt->name, sizeof(f->description));
        f->pixelformat = fmt->fourcc;
        return 0;
 }
@@ -632,9 +632,9 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
                return -EIO;
        }
        if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-               return vb2_qbuf(&ctx->vq_src, buf);
+               return vb2_qbuf(&ctx->vq_src, NULL, buf);
        else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-               return vb2_qbuf(&ctx->vq_dst, buf);
+               return vb2_qbuf(&ctx->vq_dst, NULL, buf);
        return -EINVAL;
 }
 
index 3ad4f5073002c90ae561f8e142a1d60c44b9badf..8fcf627dedfbdbeddae804a52634bb16bccfe591 100644 (file)
@@ -1313,8 +1313,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct s5p_mfc_dev *dev = video_drvdata(file);
 
-       strlcpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, dev->vfd_enc->name, sizeof(cap->card));
+       strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver));
+       strscpy(cap->card, dev->vfd_enc->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(&dev->plat_dev->dev));
        /*
@@ -1344,7 +1344,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
 
                if (j == f->index) {
                        fmt = &formats[i];
-                       strlcpy(f->description, fmt->name,
+                       strscpy(f->description, fmt->name,
                                sizeof(f->description));
                        f->pixelformat = fmt->fourcc;
                        return 0;
@@ -1621,9 +1621,9 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
                        mfc_err("Call on QBUF after EOS command\n");
                        return -EIO;
                }
-               return vb2_qbuf(&ctx->vq_src, buf);
+               return vb2_qbuf(&ctx->vq_src, NULL, buf);
        } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-               return vb2_qbuf(&ctx->vq_dst, buf);
+               return vb2_qbuf(&ctx->vq_dst, NULL, buf);
        }
        return -EINVAL;
 }
index 1d274c64de09e54ff01b0201b87bc3c791269f04..09ae64a0004c1fdceacedd5c8930476f50931ed2 100644 (file)
@@ -345,9 +345,9 @@ static int sh_veu_context_init(struct sh_veu_dev *veu)
 static int sh_veu_querycap(struct file *file, void *priv,
                           struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, "sh-veu", sizeof(cap->driver));
-       strlcpy(cap->card, "sh-mobile VEU", sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:sh-veu", sizeof(cap->bus_info));
+       strscpy(cap->driver, "sh-veu", sizeof(cap->driver));
+       strscpy(cap->card, "sh-mobile VEU", sizeof(cap->card));
+       strscpy(cap->bus_info, "platform:sh-veu", sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
@@ -359,7 +359,8 @@ static int sh_veu_enum_fmt(struct v4l2_fmtdesc *f, const int *fmt, int fmt_num)
        if (f->index >= fmt_num)
                return -EINVAL;
 
-       strlcpy(f->description, sh_veu_fmt[fmt[f->index]].name, sizeof(f->description));
+       strscpy(f->description, sh_veu_fmt[fmt[f->index]].name,
+               sizeof(f->description));
        f->pixelformat = sh_veu_fmt[fmt[f->index]].fourcc;
        return 0;
 }
index 6135e13e24d4879884775fc22d454be362e75064..cee58b125548aa6b5f151c760dd7bd17bbbe2599 100644 (file)
@@ -378,9 +378,9 @@ static int sh_vou_querycap(struct file *file, void  *priv,
 
        dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
-       strlcpy(cap->card, "SuperH VOU", sizeof(cap->card));
-       strlcpy(cap->driver, "sh-vou", sizeof(cap->driver));
-       strlcpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info));
+       strscpy(cap->card, "SuperH VOU", sizeof(cap->card));
+       strscpy(cap->driver, "sh-vou", sizeof(cap->driver));
+       strscpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE |
                           V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -399,7 +399,7 @@ static int sh_vou_enum_fmt_vid_out(struct file *file, void  *priv,
        dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
        fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-       strlcpy(fmt->description, vou_fmt[fmt->index].desc,
+       strscpy(fmt->description, vou_fmt[fmt->index].desc,
                sizeof(fmt->description));
        fmt->pixelformat = vou_fmt[fmt->index].pfmt;
 
@@ -790,7 +790,7 @@ static int sh_vou_enum_output(struct file *file, void *fh,
 
        if (a->index)
                return -EINVAL;
-       strlcpy(a->name, "Video Out", sizeof(a->name));
+       strscpy(a->name, "Video Out", sizeof(a->name));
        a->type = V4L2_OUTPUT_TYPE_ANALOG;
        a->std = vou_dev->vdev.tvnorms;
        return 0;
index 0a2c0daaffeffbabc547061023832c7b0951578a..6803f744e3077ccf9bcca0da48402d5dde196581 100644 (file)
@@ -1564,9 +1564,9 @@ static __poll_t sh_mobile_ceu_poll(struct file *file, poll_table *pt)
 static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
                                  struct v4l2_capability *cap)
 {
-       strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
-       strlcpy(cap->driver, "sh_mobile_ceu", sizeof(cap->driver));
-       strlcpy(cap->bus_info, "platform:sh_mobile_ceu", sizeof(cap->bus_info));
+       strscpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
+       strscpy(cap->driver, "sh_mobile_ceu", sizeof(cap->driver));
+       strscpy(cap->bus_info, "platform:sh_mobile_ceu", sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
index 66d6136291678cdec5add275d03a1d72213b8213..21034339cdcb0141f0781521770b3d04b37f9203 100644 (file)
@@ -312,7 +312,7 @@ static int soc_camera_enum_input(struct file *file, void *priv,
        /* default is camera */
        inp->type = V4L2_INPUT_TYPE_CAMERA;
        inp->std = icd->vdev->tvnorms;
-       strcpy(inp->name, "Camera");
+       strscpy(inp->name, "Camera", sizeof(inp->name));
 
        return 0;
 }
@@ -394,7 +394,7 @@ static int soc_camera_qbuf(struct file *file, void *priv,
        if (icd->streamer != file)
                return -EBUSY;
 
-       return vb2_qbuf(&icd->vb2_vidq, p);
+       return vb2_qbuf(&icd->vb2_vidq, NULL, p);
 }
 
 static int soc_camera_dqbuf(struct file *file, void *priv,
@@ -430,7 +430,7 @@ static int soc_camera_prepare_buf(struct file *file, void *priv,
 {
        struct soc_camera_device *icd = file->private_data;
 
-       return vb2_prepare_buf(&icd->vb2_vidq, b);
+       return vb2_prepare_buf(&icd->vb2_vidq, NULL, b);
 }
 
 static int soc_camera_expbuf(struct file *file, void *priv,
@@ -874,7 +874,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void  *priv,
        format = icd->user_formats[f->index].host_fmt;
 
        if (format->name)
-               strlcpy(f->description, format->name, sizeof(f->description));
+               strscpy(f->description, format->name, sizeof(f->description));
        f->pixelformat = format->fourcc;
        return 0;
 }
@@ -910,7 +910,7 @@ static int soc_camera_querycap(struct file *file, void  *priv,
 
        WARN_ON(priv != file->private_data);
 
-       strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver));
+       strscpy(cap->driver, ici->drv_name, sizeof(cap->driver));
        return ici->ops->querycap(ici, cap);
 }
 
@@ -1181,7 +1181,8 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd)
 
        v4l2_subdev_call(sd, video, g_tvnorms, &icd->vdev->tvnorms);
 
-       ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
+       ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler,
+                                   NULL, true);
        if (ret < 0)
                return ret;
 
@@ -1442,8 +1443,14 @@ static int scan_async_group(struct soc_camera_host *ici,
                goto eaddpdev;
        }
 
-       sasc->notifier.subdevs = asd;
-       sasc->notifier.num_subdevs = size;
+       v4l2_async_notifier_init(&sasc->notifier);
+
+       for (i = 0; i < size; i++) {
+               ret = v4l2_async_notifier_add_subdev(&sasc->notifier, asd[i]);
+               if (ret)
+                       goto eaddasd;
+       }
+
        sasc->notifier.ops = &soc_camera_async_ops;
 
        icd->sasc = sasc;
@@ -1466,6 +1473,8 @@ static int scan_async_group(struct soc_camera_host *ici,
        v4l2_clk_unregister(icd->clk);
 eclkreg:
        icd->clk = NULL;
+eaddasd:
+       v4l2_async_notifier_cleanup(&sasc->notifier);
        platform_device_del(sasc->pdev);
 eaddpdev:
        platform_device_put(sasc->pdev);
@@ -1540,8 +1549,14 @@ static int soc_of_bind(struct soc_camera_host *ici,
                goto eaddpdev;
        }
 
-       sasc->notifier.subdevs = &info->subdev;
-       sasc->notifier.num_subdevs = 1;
+       v4l2_async_notifier_init(&sasc->notifier);
+
+       ret = v4l2_async_notifier_add_subdev(&sasc->notifier, info->subdev);
+       if (ret) {
+               of_node_put(remote);
+               goto eaddasd;
+       }
+
        sasc->notifier.ops = &soc_camera_async_ops;
 
        icd->sasc = sasc;
@@ -1568,6 +1583,8 @@ static int soc_of_bind(struct soc_camera_host *ici,
        v4l2_clk_unregister(icd->clk);
 eclkreg:
        icd->clk = NULL;
+eaddasd:
+       v4l2_async_notifier_cleanup(&sasc->notifier);
        platform_device_del(sasc->pdev);
 eaddpdev:
        platform_device_put(sasc->pdev);
@@ -1582,7 +1599,7 @@ static void scan_of_host(struct soc_camera_host *ici)
 {
        struct device *dev = ici->v4l2_dev.dev;
        struct device_node *np = dev->of_node;
-       struct device_node *epn = NULL, *ren;
+       struct device_node *epn = NULL, *rem;
        unsigned int i;
 
        for (i = 0; ; i++) {
@@ -1590,17 +1607,15 @@ static void scan_of_host(struct soc_camera_host *ici)
                if (!epn)
                        break;
 
-               ren = of_graph_get_remote_port(epn);
-               if (!ren) {
+               rem = of_graph_get_remote_port_parent(epn);
+               if (!rem) {
                        dev_notice(dev, "no remote for %pOF\n", epn);
                        continue;
                }
 
                /* so we now have a remote node to connect */
                if (!i)
-                       soc_of_bind(ici, epn, ren->parent);
-
-               of_node_put(ren);
+                       soc_of_bind(ici, epn, rem);
 
                if (i) {
                        dev_err(dev, "multiple subdevices aren't supported yet!\n");
@@ -1926,6 +1941,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
        list_for_each_entry(sasc, &notifiers, list) {
                /* Must call unlocked to avoid AB-BA dead-lock */
                v4l2_async_notifier_unregister(&sasc->notifier);
+               v4l2_async_notifier_cleanup(&sasc->notifier);
                put_device(&sasc->pdev->dev);
        }
 
@@ -2026,7 +2042,7 @@ static int video_dev_create(struct soc_camera_device *icd)
        if (!vdev)
                return -ENOMEM;
 
-       strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
+       strscpy(vdev->name, ici->drv_name, sizeof(vdev->name));
 
        vdev->v4l2_dev          = &ici->v4l2_dev;
        vdev->fops              = &soc_camera_fops;
index 6745a6e3f464d57f5c0104570988fa05c79fada0..79fbe1fea95f53aca9daccd70451a59cb751693e 100644 (file)
@@ -156,7 +156,7 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
 
        v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
        v4l2_set_subdevdata(&priv->subdev, p);
-       strlcpy(priv->subdev.name, dev_name(&pdev->dev),
+       strscpy(priv->subdev.name, dev_name(&pdev->dev),
                sizeof(priv->subdev.name));
 
        return v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
index 0ad4b28266e4379f1a9a5932e809d100c84cede9..be74008ec0cae375b8fe0f9cd21f9d4ae2664958 100644 (file)
@@ -503,7 +503,7 @@ unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
                mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
                return (!hsync || !vsync || !pclk || !data || !mode) ?
                        0 : common_flags;
-       case V4L2_MBUS_CSI2:
+       case V4L2_MBUS_CSI2_DPHY:
                mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
                mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
                                             V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
index 6164102e6f9f9947533a416a7cd90bd3f8ed4715..8d25ca0490f742e9e4a45812d13e362943412eac 100644 (file)
@@ -52,7 +52,7 @@ int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
                return ret;
        }
 
-       sdsel.target = V4L2_SEL_TGT_CROP_DEFAULT;
+       sdsel.target = V4L2_SEL_TGT_CROP_BOUNDS;
        ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel);
        if (!ret)
                *rect = sdsel.r;
index 66b64096f5de0e8cc33306af98692d9b4e7b2691..79f7db1a9d1887dbcfa8d59fd30010611334eb5e 100644 (file)
@@ -688,8 +688,8 @@ static int bdisp_querycap(struct file *file, void *fh,
        struct bdisp_ctx *ctx = fh_to_ctx(fh);
        struct bdisp_dev *bdisp = ctx->bdisp_dev;
 
-       strlcpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver));
-       strlcpy(cap->card, bdisp->pdev->name, sizeof(cap->card));
+       strscpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver));
+       strscpy(cap->card, bdisp->pdev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d",
                 BDISP_NAME, bdisp->id);
 
index 0b42acd4e3a6e793650ffd1ec7ba6c05330a5a83..91369fb3ffaa41bf3bdd6822f9d8c86066c39efc 100644 (file)
@@ -385,8 +385,8 @@ static int delta_querycap(struct file *file, void *priv,
        struct delta_ctx *ctx = to_ctx(file->private_data);
        struct delta_dev *delta = ctx->dev;
 
-       strlcpy(cap->driver, DELTA_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, delta->vdev->name, sizeof(cap->card));
+       strscpy(cap->driver, DELTA_NAME, sizeof(cap->driver));
+       strscpy(cap->card, delta->vdev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 delta->pdev->name);
 
index 5a807c7c5e79195da386232d13d56e37015ce868..c42623dccfd60d2192e15da0081e799f3378ef52 100644 (file)
@@ -257,8 +257,8 @@ static int hva_querycap(struct file *file, void *priv,
        struct hva_ctx *ctx = fh_to_ctx(file->private_data);
        struct hva_dev *hva = ctx_to_hdev(ctx);
 
-       strlcpy(cap->driver, HVA_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, hva->vdev->name, sizeof(cap->card));
+       strscpy(cap->driver, HVA_NAME, sizeof(cap->driver));
+       strscpy(cap->card, hva->vdev->name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 hva->pdev->name);
 
index 721564176d8c07585d1803b35435f7ef8c52afcd..6732874114cf7882cf6dc518046a716e470e1bcb 100644 (file)
@@ -659,7 +659,10 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count)
        }
 
        /* Enable interruptions */
-       reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR);
+       if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG)
+               reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR);
+       else
+               reg_set(dcmi->regs, DCMI_IER, IT_OVR | IT_ERR);
 
        return 0;
 
@@ -1147,10 +1150,10 @@ static int dcmi_s_selection(struct file *file, void *priv,
 static int dcmi_querycap(struct file *file, void *priv,
                         struct v4l2_capability *cap)
 {
-       strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, "STM32 Camera Memory Interface",
+       strscpy(cap->driver, DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->card, "STM32 Camera Memory Interface",
                sizeof(cap->card));
-       strlcpy(cap->bus_info, "platform:dcmi", sizeof(cap->bus_info));
+       strscpy(cap->bus_info, "platform:dcmi", sizeof(cap->bus_info));
        return 0;
 }
 
@@ -1161,7 +1164,7 @@ static int dcmi_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
-       strlcpy(i->name, "Camera", sizeof(i->name));
+       strscpy(i->name, "Camera", sizeof(i->name));
        return 0;
 }
 
@@ -1587,7 +1590,6 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
 
 static int dcmi_graph_init(struct stm32_dcmi *dcmi)
 {
-       struct v4l2_async_subdev **subdevs = NULL;
        int ret;
 
        /* Parse the graph to extract a list of subdevice DT nodes. */
@@ -1597,23 +1599,21 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
                return ret;
        }
 
-       /* Register the subdevices notifier. */
-       subdevs = devm_kzalloc(dcmi->dev, sizeof(*subdevs), GFP_KERNEL);
-       if (!subdevs) {
+       v4l2_async_notifier_init(&dcmi->notifier);
+
+       ret = v4l2_async_notifier_add_subdev(&dcmi->notifier,
+                                            &dcmi->entity.asd);
+       if (ret) {
                of_node_put(dcmi->entity.node);
-               return -ENOMEM;
+               return ret;
        }
 
-       subdevs[0] = &dcmi->entity.asd;
-
-       dcmi->notifier.subdevs = subdevs;
-       dcmi->notifier.num_subdevs = 1;
        dcmi->notifier.ops = &dcmi_graph_notify_ops;
 
        ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier);
        if (ret < 0) {
                dev_err(dcmi->dev, "Notifier registration failed\n");
-               of_node_put(dcmi->entity.node);
+               v4l2_async_notifier_cleanup(&dcmi->notifier);
                return ret;
        }
 
@@ -1624,7 +1624,7 @@ static int dcmi_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *match = NULL;
-       struct v4l2_fwnode_endpoint ep;
+       struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
        struct stm32_dcmi *dcmi;
        struct vb2_queue *q;
        struct dma_chan *chan;
@@ -1663,7 +1663,7 @@ static int dcmi_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       if (ep.bus_type == V4L2_MBUS_CSI2) {
+       if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
                dev_err(&pdev->dev, "CSI bus not supported\n");
                return -ENODEV;
        }
@@ -1736,7 +1736,7 @@ static int dcmi_probe(struct platform_device *pdev)
        dcmi->vdev->fops = &dcmi_fops;
        dcmi->vdev->v4l2_dev = &dcmi->v4l2_dev;
        dcmi->vdev->queue = &dcmi->queue;
-       strlcpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name));
+       strscpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name));
        dcmi->vdev->release = video_device_release;
        dcmi->vdev->ioctl_ops = &dcmi_ioctl_ops;
        dcmi->vdev->lock = &dcmi->lock;
@@ -1770,7 +1770,7 @@ static int dcmi_probe(struct platform_device *pdev)
        ret = reset_control_assert(dcmi->rstc);
        if (ret) {
                dev_err(&pdev->dev, "Failed to assert the reset line\n");
-               goto err_device_release;
+               goto err_cleanup;
        }
 
        usleep_range(3000, 5000);
@@ -1778,7 +1778,7 @@ static int dcmi_probe(struct platform_device *pdev)
        ret = reset_control_deassert(dcmi->rstc);
        if (ret) {
                dev_err(&pdev->dev, "Failed to deassert the reset line\n");
-               goto err_device_release;
+               goto err_cleanup;
        }
 
        dev_info(&pdev->dev, "Probe done\n");
@@ -1789,6 +1789,8 @@ static int dcmi_probe(struct platform_device *pdev)
 
        return 0;
 
+err_cleanup:
+       v4l2_async_notifier_cleanup(&dcmi->notifier);
 err_device_release:
        video_device_release(dcmi->vdev);
 err_device_unregister:
@@ -1806,6 +1808,7 @@ static int dcmi_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
 
        v4l2_async_notifier_unregister(&dcmi->notifier);
+       v4l2_async_notifier_cleanup(&dcmi->notifier);
        v4l2_device_unregister(&dcmi->v4l2_dev);
 
        dma_release_channel(dcmi->dma_chan);
index d1febe5baa6dd9b45c2482e1e2d32c373bbd355f..95a093f41905d218f2fe746a637dfc0921d7559f 100644 (file)
@@ -270,7 +270,6 @@ struct cal_ctx {
        struct v4l2_fwnode_endpoint     endpoint;
 
        struct v4l2_async_subdev asd;
-       struct v4l2_async_subdev *asd_list[1];
 
        struct v4l2_fh          fh;
        struct cal_dev          *dev;
@@ -912,8 +911,8 @@ static int cal_querycap(struct file *file, void *priv,
 {
        struct cal_ctx *ctx = video_drvdata(file);
 
-       strlcpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));
+       strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));
+       strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));
 
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "platform:%s", ctx->v4l2_dev.name);
@@ -1711,9 +1710,9 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
        }
        v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint);
 
-       if (endpoint->bus_type != V4L2_MBUS_CSI2) {
-               ctx_err(ctx, "Port:%d sub-device %s is not a CSI2 device\n",
-                       inst, sensor_node->name);
+       if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) {
+               ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n",
+                       inst, sensor_node);
                goto cleanup_exit;
        }
 
@@ -1732,29 +1731,38 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
                        endpoint->bus.mipi_csi2.data_lanes[lane]);
        ctx_dbg(3, ctx, "\t>\n");
 
-       ctx_dbg(1, ctx, "Port: %d found sub-device %s\n",
-               inst, sensor_node->name);
+       ctx_dbg(1, ctx, "Port: %d found sub-device %pOFn\n",
+               inst, sensor_node);
+
+       v4l2_async_notifier_init(&ctx->notifier);
+
+       ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd);
+       if (ret) {
+               ctx_err(ctx, "Error adding asd\n");
+               goto cleanup_exit;
+       }
 
-       ctx->asd_list[0] = asd;
-       ctx->notifier.subdevs = ctx->asd_list;
-       ctx->notifier.num_subdevs = 1;
        ctx->notifier.ops = &cal_async_ops;
        ret = v4l2_async_notifier_register(&ctx->v4l2_dev,
                                           &ctx->notifier);
        if (ret) {
                ctx_err(ctx, "Error registering async notifier\n");
+               v4l2_async_notifier_cleanup(&ctx->notifier);
                ret = -EINVAL;
        }
 
+       /*
+        * On success we need to keep reference on sensor_node, or
+        * if notifier_cleanup was called above, sensor_node was
+        * already put.
+        */
+       sensor_node = NULL;
+
 cleanup_exit:
-       if (remote_ep)
-               of_node_put(remote_ep);
-       if (sensor_node)
-               of_node_put(sensor_node);
-       if (ep_node)
-               of_node_put(ep_node);
-       if (port)
-               of_node_put(port);
+       of_node_put(remote_ep);
+       of_node_put(sensor_node);
+       of_node_put(ep_node);
+       of_node_put(port);
 
        return ret;
 }
@@ -1810,15 +1818,17 @@ err_exit:
 static int cal_probe(struct platform_device *pdev)
 {
        struct cal_dev *dev;
+       struct cal_ctx *ctx;
        int ret;
        int irq;
+       int i;
 
        dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
        if (!dev)
                return -ENOMEM;
 
        /* set pseudo v4l2 device name so we can use v4l2_printk */
-       strlcpy(dev->v4l2_dev.name, CAL_MODULE_NAME,
+       strscpy(dev->v4l2_dev.name, CAL_MODULE_NAME,
                sizeof(dev->v4l2_dev.name));
 
        /* save pdev pointer */
@@ -1879,6 +1889,16 @@ static int cal_probe(struct platform_device *pdev)
 
 runtime_disable:
        pm_runtime_disable(&pdev->dev);
+       for (i = 0; i < CAL_NUM_CONTEXT; i++) {
+               ctx = dev->ctx[i];
+               if (ctx) {
+                       v4l2_async_notifier_unregister(&ctx->notifier);
+                       v4l2_async_notifier_cleanup(&ctx->notifier);
+                       v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+                       v4l2_device_unregister(&ctx->v4l2_dev);
+               }
+       }
+
        return ret;
 }
 
@@ -1900,6 +1920,7 @@ static int cal_remove(struct platform_device *pdev)
                                video_device_node_name(&ctx->vdev));
                        camerarx_phy_disable(ctx);
                        v4l2_async_notifier_unregister(&ctx->notifier);
+                       v4l2_async_notifier_cleanup(&ctx->notifier);
                        v4l2_ctrl_handler_free(&ctx->ctrl_handler);
                        v4l2_device_unregister(&ctx->v4l2_dev);
                        video_unregister_device(&ctx->vdev);
index c8bb82fe0b9df628ff11b086bb1e5d54fb582068..24d5759501a5603a26b55efa0ca1353f1cc43e8f 100644 (file)
@@ -812,7 +812,7 @@ static int viacam_enum_input(struct file *filp, void *priv,
 
        input->type = V4L2_INPUT_TYPE_CAMERA;
        input->std = V4L2_STD_ALL; /* Not sure what should go here */
-       strcpy(input->name, "Camera");
+       strscpy(input->name, "Camera", sizeof(input->name));
        return 0;
 }
 
@@ -860,8 +860,8 @@ static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv,
 {
        if (fmt->index >= N_VIA_FMTS)
                return -EINVAL;
-       strlcpy(fmt->description, via_formats[fmt->index].desc,
-                       sizeof(fmt->description));
+       strscpy(fmt->description, via_formats[fmt->index].desc,
+               sizeof(fmt->description));
        fmt->pixelformat = via_formats[fmt->index].pixelformat;
        return 0;
 }
@@ -990,8 +990,8 @@ out:
 static int viacam_querycap(struct file *filp, void *priv,
                struct v4l2_capability *cap)
 {
-       strcpy(cap->driver, "via-camera");
-       strcpy(cap->card, "via-camera");
+       strscpy(cap->driver, "via-camera", sizeof(cap->driver));
+       strscpy(cap->card, "via-camera", sizeof(cap->card));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
                V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
index 2503bcb1529fbd2b139032b80d0db660c85aa5ca..ad13329e3461299b87c4daa5a7d6249b75bb692a 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_VICODEC
        tristate "Virtual Codec Driver"
-       depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_DEV && VIDEO_V4L2
        select VIDEOBUF2_VMALLOC
        select V4L2_MEM2MEM_DEV
        default n
index 197229428953a861aa95484f39f31ee037061114..01bf7e9308a60fcbf8957d0ad7e4c5f066d31913 100644 (file)
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-vicodec-objs := vicodec-core.o vicodec-codec.o
+vicodec-objs := vicodec-core.o codec-fwht.o codec-v4l2-fwht.o
 
 obj-$(CONFIG_VIDEO_VICODEC) += vicodec.o
diff --git a/drivers/media/platform/vicodec/codec-fwht.c b/drivers/media/platform/vicodec/codec-fwht.c
new file mode 100644 (file)
index 0000000..3665603
--- /dev/null
@@ -0,0 +1,855 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright 2016 Tom aan de Wiel
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * 8x8 Fast Walsh Hadamard Transform in sequency order based on the paper:
+ *
+ * A Recursive Algorithm for Sequency-Ordered Fast Walsh Transforms,
+ * R.D. Brown, 1977
+ */
+
+#include <linux/string.h>
+#include "codec-fwht.h"
+
+/*
+ * Note: bit 0 of the header must always be 0. Otherwise it cannot
+ * be guaranteed that the magic 8 byte sequence (see below) can
+ * never occur in the rlc output.
+ */
+#define PFRAME_BIT BIT(15)
+#define DUPS_MASK 0x1ffe
+
+#define PBLOCK 0
+#define IBLOCK 1
+
+#define ALL_ZEROS 15
+
+static const uint8_t zigzag[64] = {
+       0,
+       1,  8,
+       2,  9, 16,
+       3, 10, 17, 24,
+       4, 11, 18, 25, 32,
+       5, 12, 19, 26, 33, 40,
+       6, 13, 20, 27, 34, 41, 48,
+       7, 14, 21, 28, 35, 42, 49, 56,
+       15, 22, 29, 36, 43, 50, 57,
+       23, 30, 37, 44, 51, 58,
+       31, 38, 45, 52, 59,
+       39, 46, 53, 60,
+       47, 54, 61,
+       55, 62,
+       63,
+};
+
+
+static int rlc(const s16 *in, __be16 *output, int blocktype)
+{
+       s16 block[8 * 8];
+       s16 *wp = block;
+       int i = 0;
+       int x, y;
+       int ret = 0;
+
+       /* read in block from framebuffer */
+       int lastzero_run = 0;
+       int to_encode;
+
+       for (y = 0; y < 8; y++) {
+               for (x = 0; x < 8; x++) {
+                       *wp = in[x + y * 8];
+                       wp++;
+               }
+       }
+
+       /* keep track of amount of trailing zeros */
+       for (i = 63; i >= 0 && !block[zigzag[i]]; i--)
+               lastzero_run++;
+
+       *output++ = (blocktype == PBLOCK ? htons(PFRAME_BIT) : 0);
+       ret++;
+
+       to_encode = 8 * 8 - (lastzero_run > 14 ? lastzero_run : 0);
+
+       i = 0;
+       while (i < to_encode) {
+               int cnt = 0;
+               int tmp;
+
+               /* count leading zeros */
+               while ((tmp = block[zigzag[i]]) == 0 && cnt < 14) {
+                       cnt++;
+                       i++;
+                       if (i == to_encode) {
+                               cnt--;
+                               break;
+                       }
+               }
+               /* 4 bits for run, 12 for coefficient (quantization by 4) */
+               *output++ = htons((cnt | tmp << 4));
+               i++;
+               ret++;
+       }
+       if (lastzero_run > 14) {
+               *output = htons(ALL_ZEROS | 0);
+               ret++;
+       }
+
+       return ret;
+}
+
+/*
+ * This function will worst-case increase rlc_in by 65*2 bytes:
+ * one s16 value for the header and 8 * 8 coefficients of type s16.
+ */
+static s16 derlc(const __be16 **rlc_in, s16 *dwht_out)
+{
+       /* header */
+       const __be16 *input = *rlc_in;
+       s16 ret = ntohs(*input++);
+       int dec_count = 0;
+       s16 block[8 * 8 + 16];
+       s16 *wp = block;
+       int i;
+
+       /*
+        * Now de-compress, it expands one byte to up to 15 bytes
+        * (or fills the remainder of the 64 bytes with zeroes if it
+        * is the last byte to expand).
+        *
+        * So block has to be 8 * 8 + 16 bytes, the '+ 16' is to
+        * allow for overflow if the incoming data was malformed.
+        */
+       while (dec_count < 8 * 8) {
+               s16 in = ntohs(*input++);
+               int length = in & 0xf;
+               int coeff = in >> 4;
+
+               /* fill remainder with zeros */
+               if (length == 15) {
+                       for (i = 0; i < 64 - dec_count; i++)
+                               *wp++ = 0;
+                       break;
+               }
+
+               for (i = 0; i < length; i++)
+                       *wp++ = 0;
+               *wp++ = coeff;
+               dec_count += length + 1;
+       }
+
+       wp = block;
+
+       for (i = 0; i < 64; i++) {
+               int pos = zigzag[i];
+               int y = pos / 8;
+               int x = pos % 8;
+
+               dwht_out[x + y * 8] = *wp++;
+       }
+       *rlc_in = input;
+       return ret;
+}
+
+static const int quant_table[] = {
+       2, 2, 2, 2, 2, 2,  2,  2,
+       2, 2, 2, 2, 2, 2,  2,  2,
+       2, 2, 2, 2, 2, 2,  2,  3,
+       2, 2, 2, 2, 2, 2,  3,  6,
+       2, 2, 2, 2, 2, 3,  6,  6,
+       2, 2, 2, 2, 3, 6,  6,  6,
+       2, 2, 2, 3, 6, 6,  6,  6,
+       2, 2, 3, 6, 6, 6,  6,  8,
+};
+
+static const int quant_table_p[] = {
+       3, 3, 3, 3, 3, 3,  3,  3,
+       3, 3, 3, 3, 3, 3,  3,  3,
+       3, 3, 3, 3, 3, 3,  3,  3,
+       3, 3, 3, 3, 3, 3,  3,  6,
+       3, 3, 3, 3, 3, 3,  6,  6,
+       3, 3, 3, 3, 3, 6,  6,  9,
+       3, 3, 3, 3, 6, 6,  9,  9,
+       3, 3, 3, 6, 6, 9,  9,  10,
+};
+
+static void quantize_intra(s16 *coeff, s16 *de_coeff, u16 qp)
+{
+       const int *quant = quant_table;
+       int i, j;
+
+       for (j = 0; j < 8; j++) {
+               for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
+                       *coeff >>= *quant;
+                       if (*coeff >= -qp && *coeff <= qp)
+                               *coeff = *de_coeff = 0;
+                       else
+                               *de_coeff = *coeff << *quant;
+               }
+       }
+}
+
+static void dequantize_intra(s16 *coeff)
+{
+       const int *quant = quant_table;
+       int i, j;
+
+       for (j = 0; j < 8; j++)
+               for (i = 0; i < 8; i++, quant++, coeff++)
+                       *coeff <<= *quant;
+}
+
+static void quantize_inter(s16 *coeff, s16 *de_coeff, u16 qp)
+{
+       const int *quant = quant_table_p;
+       int i, j;
+
+       for (j = 0; j < 8; j++) {
+               for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
+                       *coeff >>= *quant;
+                       if (*coeff >= -qp && *coeff <= qp)
+                               *coeff = *de_coeff = 0;
+                       else
+                               *de_coeff = *coeff << *quant;
+               }
+       }
+}
+
+static void dequantize_inter(s16 *coeff)
+{
+       const int *quant = quant_table_p;
+       int i, j;
+
+       for (j = 0; j < 8; j++)
+               for (i = 0; i < 8; i++, quant++, coeff++)
+                       *coeff <<= *quant;
+}
+
+static void fwht(const u8 *block, s16 *output_block, unsigned int stride,
+                unsigned int input_step, bool intra)
+{
+       /* we'll need more than 8 bits for the transformed coefficients */
+       s32 workspace1[8], workspace2[8];
+       const u8 *tmp = block;
+       s16 *out = output_block;
+       int add = intra ? 256 : 0;
+       unsigned int i;
+
+       /* stage 1 */
+       stride *= input_step;
+
+       for (i = 0; i < 8; i++, tmp += stride, out += 8) {
+               switch (input_step) {
+               case 1:
+                       workspace1[0]  = tmp[0] + tmp[1] - add;
+                       workspace1[1]  = tmp[0] - tmp[1];
+
+                       workspace1[2]  = tmp[2] + tmp[3] - add;
+                       workspace1[3]  = tmp[2] - tmp[3];
+
+                       workspace1[4]  = tmp[4] + tmp[5] - add;
+                       workspace1[5]  = tmp[4] - tmp[5];
+
+                       workspace1[6]  = tmp[6] + tmp[7] - add;
+                       workspace1[7]  = tmp[6] - tmp[7];
+                       break;
+               case 2:
+                       workspace1[0]  = tmp[0] + tmp[2] - add;
+                       workspace1[1]  = tmp[0] - tmp[2];
+
+                       workspace1[2]  = tmp[4] + tmp[6] - add;
+                       workspace1[3]  = tmp[4] - tmp[6];
+
+                       workspace1[4]  = tmp[8] + tmp[10] - add;
+                       workspace1[5]  = tmp[8] - tmp[10];
+
+                       workspace1[6]  = tmp[12] + tmp[14] - add;
+                       workspace1[7]  = tmp[12] - tmp[14];
+                       break;
+               case 3:
+                       workspace1[0]  = tmp[0] + tmp[3] - add;
+                       workspace1[1]  = tmp[0] - tmp[3];
+
+                       workspace1[2]  = tmp[6] + tmp[9] - add;
+                       workspace1[3]  = tmp[6] - tmp[9];
+
+                       workspace1[4]  = tmp[12] + tmp[15] - add;
+                       workspace1[5]  = tmp[12] - tmp[15];
+
+                       workspace1[6]  = tmp[18] + tmp[21] - add;
+                       workspace1[7]  = tmp[18] - tmp[21];
+                       break;
+               default:
+                       workspace1[0]  = tmp[0] + tmp[4] - add;
+                       workspace1[1]  = tmp[0] - tmp[4];
+
+                       workspace1[2]  = tmp[8] + tmp[12] - add;
+                       workspace1[3]  = tmp[8] - tmp[12];
+
+                       workspace1[4]  = tmp[16] + tmp[20] - add;
+                       workspace1[5]  = tmp[16] - tmp[20];
+
+                       workspace1[6]  = tmp[24] + tmp[28] - add;
+                       workspace1[7]  = tmp[24] - tmp[28];
+                       break;
+               }
+
+               /* stage 2 */
+               workspace2[0] = workspace1[0] + workspace1[2];
+               workspace2[1] = workspace1[0] - workspace1[2];
+               workspace2[2] = workspace1[1] - workspace1[3];
+               workspace2[3] = workspace1[1] + workspace1[3];
+
+               workspace2[4] = workspace1[4] + workspace1[6];
+               workspace2[5] = workspace1[4] - workspace1[6];
+               workspace2[6] = workspace1[5] - workspace1[7];
+               workspace2[7] = workspace1[5] + workspace1[7];
+
+               /* stage 3 */
+               out[0] = workspace2[0] + workspace2[4];
+               out[1] = workspace2[0] - workspace2[4];
+               out[2] = workspace2[1] - workspace2[5];
+               out[3] = workspace2[1] + workspace2[5];
+               out[4] = workspace2[2] + workspace2[6];
+               out[5] = workspace2[2] - workspace2[6];
+               out[6] = workspace2[3] - workspace2[7];
+               out[7] = workspace2[3] + workspace2[7];
+       }
+
+       out = output_block;
+
+       for (i = 0; i < 8; i++, out++) {
+               /* stage 1 */
+               workspace1[0]  = out[0] + out[1 * 8];
+               workspace1[1]  = out[0] - out[1 * 8];
+
+               workspace1[2]  = out[2 * 8] + out[3 * 8];
+               workspace1[3]  = out[2 * 8] - out[3 * 8];
+
+               workspace1[4]  = out[4 * 8] + out[5 * 8];
+               workspace1[5]  = out[4 * 8] - out[5 * 8];
+
+               workspace1[6]  = out[6 * 8] + out[7 * 8];
+               workspace1[7]  = out[6 * 8] - out[7 * 8];
+
+               /* stage 2 */
+               workspace2[0] = workspace1[0] + workspace1[2];
+               workspace2[1] = workspace1[0] - workspace1[2];
+               workspace2[2] = workspace1[1] - workspace1[3];
+               workspace2[3] = workspace1[1] + workspace1[3];
+
+               workspace2[4] = workspace1[4] + workspace1[6];
+               workspace2[5] = workspace1[4] - workspace1[6];
+               workspace2[6] = workspace1[5] - workspace1[7];
+               workspace2[7] = workspace1[5] + workspace1[7];
+               /* stage 3 */
+               out[0 * 8] = workspace2[0] + workspace2[4];
+               out[1 * 8] = workspace2[0] - workspace2[4];
+               out[2 * 8] = workspace2[1] - workspace2[5];
+               out[3 * 8] = workspace2[1] + workspace2[5];
+               out[4 * 8] = workspace2[2] + workspace2[6];
+               out[5 * 8] = workspace2[2] - workspace2[6];
+               out[6 * 8] = workspace2[3] - workspace2[7];
+               out[7 * 8] = workspace2[3] + workspace2[7];
+       }
+}
+
+/*
+ * Not the nicest way of doing it, but P-blocks get twice the range of
+ * that of the I-blocks. Therefore we need a type bigger than 8 bits.
+ * Furthermore values can be negative... This is just a version that
+ * works with 16 signed data
+ */
+static void fwht16(const s16 *block, s16 *output_block, int stride, int intra)
+{
+       /* we'll need more than 8 bits for the transformed coefficients */
+       s32 workspace1[8], workspace2[8];
+       const s16 *tmp = block;
+       s16 *out = output_block;
+       int i;
+
+       for (i = 0; i < 8; i++, tmp += stride, out += 8) {
+               /* stage 1 */
+               workspace1[0]  = tmp[0] + tmp[1];
+               workspace1[1]  = tmp[0] - tmp[1];
+
+               workspace1[2]  = tmp[2] + tmp[3];
+               workspace1[3]  = tmp[2] - tmp[3];
+
+               workspace1[4]  = tmp[4] + tmp[5];
+               workspace1[5]  = tmp[4] - tmp[5];
+
+               workspace1[6]  = tmp[6] + tmp[7];
+               workspace1[7]  = tmp[6] - tmp[7];
+
+               /* stage 2 */
+               workspace2[0] = workspace1[0] + workspace1[2];
+               workspace2[1] = workspace1[0] - workspace1[2];
+               workspace2[2] = workspace1[1] - workspace1[3];
+               workspace2[3] = workspace1[1] + workspace1[3];
+
+               workspace2[4] = workspace1[4] + workspace1[6];
+               workspace2[5] = workspace1[4] - workspace1[6];
+               workspace2[6] = workspace1[5] - workspace1[7];
+               workspace2[7] = workspace1[5] + workspace1[7];
+
+               /* stage 3 */
+               out[0] = workspace2[0] + workspace2[4];
+               out[1] = workspace2[0] - workspace2[4];
+               out[2] = workspace2[1] - workspace2[5];
+               out[3] = workspace2[1] + workspace2[5];
+               out[4] = workspace2[2] + workspace2[6];
+               out[5] = workspace2[2] - workspace2[6];
+               out[6] = workspace2[3] - workspace2[7];
+               out[7] = workspace2[3] + workspace2[7];
+       }
+
+       out = output_block;
+
+       for (i = 0; i < 8; i++, out++) {
+               /* stage 1 */
+               workspace1[0]  = out[0] + out[1*8];
+               workspace1[1]  = out[0] - out[1*8];
+
+               workspace1[2]  = out[2*8] + out[3*8];
+               workspace1[3]  = out[2*8] - out[3*8];
+
+               workspace1[4]  = out[4*8] + out[5*8];
+               workspace1[5]  = out[4*8] - out[5*8];
+
+               workspace1[6]  = out[6*8] + out[7*8];
+               workspace1[7]  = out[6*8] - out[7*8];
+
+               /* stage 2 */
+               workspace2[0] = workspace1[0] + workspace1[2];
+               workspace2[1] = workspace1[0] - workspace1[2];
+               workspace2[2] = workspace1[1] - workspace1[3];
+               workspace2[3] = workspace1[1] + workspace1[3];
+
+               workspace2[4] = workspace1[4] + workspace1[6];
+               workspace2[5] = workspace1[4] - workspace1[6];
+               workspace2[6] = workspace1[5] - workspace1[7];
+               workspace2[7] = workspace1[5] + workspace1[7];
+
+               /* stage 3 */
+               out[0*8] = workspace2[0] + workspace2[4];
+               out[1*8] = workspace2[0] - workspace2[4];
+               out[2*8] = workspace2[1] - workspace2[5];
+               out[3*8] = workspace2[1] + workspace2[5];
+               out[4*8] = workspace2[2] + workspace2[6];
+               out[5*8] = workspace2[2] - workspace2[6];
+               out[6*8] = workspace2[3] - workspace2[7];
+               out[7*8] = workspace2[3] + workspace2[7];
+       }
+}
+
+static void ifwht(const s16 *block, s16 *output_block, int intra)
+{
+       /*
+        * we'll need more than 8 bits for the transformed coefficients
+        * use native unit of cpu
+        */
+       int workspace1[8], workspace2[8];
+       int inter = intra ? 0 : 1;
+       const s16 *tmp = block;
+       s16 *out = output_block;
+       int i;
+
+       for (i = 0; i < 8; i++, tmp += 8, out += 8) {
+               /* stage 1 */
+               workspace1[0]  = tmp[0] + tmp[1];
+               workspace1[1]  = tmp[0] - tmp[1];
+
+               workspace1[2]  = tmp[2] + tmp[3];
+               workspace1[3]  = tmp[2] - tmp[3];
+
+               workspace1[4]  = tmp[4] + tmp[5];
+               workspace1[5]  = tmp[4] - tmp[5];
+
+               workspace1[6]  = tmp[6] + tmp[7];
+               workspace1[7]  = tmp[6] - tmp[7];
+
+               /* stage 2 */
+               workspace2[0] = workspace1[0] + workspace1[2];
+               workspace2[1] = workspace1[0] - workspace1[2];
+               workspace2[2] = workspace1[1] - workspace1[3];
+               workspace2[3] = workspace1[1] + workspace1[3];
+
+               workspace2[4] = workspace1[4] + workspace1[6];
+               workspace2[5] = workspace1[4] - workspace1[6];
+               workspace2[6] = workspace1[5] - workspace1[7];
+               workspace2[7] = workspace1[5] + workspace1[7];
+
+               /* stage 3 */
+               out[0] = workspace2[0] + workspace2[4];
+               out[1] = workspace2[0] - workspace2[4];
+               out[2] = workspace2[1] - workspace2[5];
+               out[3] = workspace2[1] + workspace2[5];
+               out[4] = workspace2[2] + workspace2[6];
+               out[5] = workspace2[2] - workspace2[6];
+               out[6] = workspace2[3] - workspace2[7];
+               out[7] = workspace2[3] + workspace2[7];
+       }
+
+       out = output_block;
+
+       for (i = 0; i < 8; i++, out++) {
+               /* stage 1 */
+               workspace1[0]  = out[0] + out[1 * 8];
+               workspace1[1]  = out[0] - out[1 * 8];
+
+               workspace1[2]  = out[2 * 8] + out[3 * 8];
+               workspace1[3]  = out[2 * 8] - out[3 * 8];
+
+               workspace1[4]  = out[4 * 8] + out[5 * 8];
+               workspace1[5]  = out[4 * 8] - out[5 * 8];
+
+               workspace1[6]  = out[6 * 8] + out[7 * 8];
+               workspace1[7]  = out[6 * 8] - out[7 * 8];
+
+               /* stage 2 */
+               workspace2[0] = workspace1[0] + workspace1[2];
+               workspace2[1] = workspace1[0] - workspace1[2];
+               workspace2[2] = workspace1[1] - workspace1[3];
+               workspace2[3] = workspace1[1] + workspace1[3];
+
+               workspace2[4] = workspace1[4] + workspace1[6];
+               workspace2[5] = workspace1[4] - workspace1[6];
+               workspace2[6] = workspace1[5] - workspace1[7];
+               workspace2[7] = workspace1[5] + workspace1[7];
+
+               /* stage 3 */
+               if (inter) {
+                       int d;
+
+                       out[0 * 8] = workspace2[0] + workspace2[4];
+                       out[1 * 8] = workspace2[0] - workspace2[4];
+                       out[2 * 8] = workspace2[1] - workspace2[5];
+                       out[3 * 8] = workspace2[1] + workspace2[5];
+                       out[4 * 8] = workspace2[2] + workspace2[6];
+                       out[5 * 8] = workspace2[2] - workspace2[6];
+                       out[6 * 8] = workspace2[3] - workspace2[7];
+                       out[7 * 8] = workspace2[3] + workspace2[7];
+
+                       for (d = 0; d < 8; d++)
+                               out[8 * d] >>= 6;
+               } else {
+                       int d;
+
+                       out[0 * 8] = workspace2[0] + workspace2[4];
+                       out[1 * 8] = workspace2[0] - workspace2[4];
+                       out[2 * 8] = workspace2[1] - workspace2[5];
+                       out[3 * 8] = workspace2[1] + workspace2[5];
+                       out[4 * 8] = workspace2[2] + workspace2[6];
+                       out[5 * 8] = workspace2[2] - workspace2[6];
+                       out[6 * 8] = workspace2[3] - workspace2[7];
+                       out[7 * 8] = workspace2[3] + workspace2[7];
+
+                       for (d = 0; d < 8; d++) {
+                               out[8 * d] >>= 6;
+                               out[8 * d] += 128;
+                       }
+               }
+       }
+}
+
+static void fill_encoder_block(const u8 *input, s16 *dst,
+                              unsigned int stride, unsigned int input_step)
+{
+       int i, j;
+
+       for (i = 0; i < 8; i++) {
+               for (j = 0; j < 8; j++, input += input_step)
+                       *dst++ = *input;
+               input += (stride - 8) * input_step;
+       }
+}
+
+static int var_intra(const s16 *input)
+{
+       int32_t mean = 0;
+       int32_t ret = 0;
+       const s16 *tmp = input;
+       int i;
+
+       for (i = 0; i < 8 * 8; i++, tmp++)
+               mean += *tmp;
+       mean /= 64;
+       tmp = input;
+       for (i = 0; i < 8 * 8; i++, tmp++)
+               ret += (*tmp - mean) < 0 ? -(*tmp - mean) : (*tmp - mean);
+       return ret;
+}
+
+static int var_inter(const s16 *old, const s16 *new)
+{
+       int32_t ret = 0;
+       int i;
+
+       for (i = 0; i < 8 * 8; i++, old++, new++)
+               ret += (*old - *new) < 0 ? -(*old - *new) : (*old - *new);
+       return ret;
+}
+
+static int decide_blocktype(const u8 *cur, const u8 *reference,
+                           s16 *deltablock, unsigned int stride,
+                           unsigned int input_step)
+{
+       s16 tmp[64];
+       s16 old[64];
+       s16 *work = tmp;
+       unsigned int k, l;
+       int vari;
+       int vard;
+
+       fill_encoder_block(cur, tmp, stride, input_step);
+       fill_encoder_block(reference, old, 8, 1);
+       vari = var_intra(tmp);
+
+       for (k = 0; k < 8; k++) {
+               for (l = 0; l < 8; l++) {
+                       *deltablock = *work - *reference;
+                       deltablock++;
+                       work++;
+                       reference++;
+               }
+       }
+       deltablock -= 64;
+       vard = var_inter(old, tmp);
+       return vari <= vard ? IBLOCK : PBLOCK;
+}
+
+static void fill_decoder_block(u8 *dst, const s16 *input, int stride)
+{
+       int i, j;
+
+       for (i = 0; i < 8; i++) {
+               for (j = 0; j < 8; j++, input++, dst++) {
+                       if (*input < 0)
+                               *dst = 0;
+                       else if (*input > 255)
+                               *dst = 255;
+                       else
+                               *dst = *input;
+               }
+               dst += stride - 8;
+       }
+}
+
+static void add_deltas(s16 *deltas, const u8 *ref, int stride)
+{
+       int k, l;
+
+       for (k = 0; k < 8; k++) {
+               for (l = 0; l < 8; l++) {
+                       *deltas += *ref++;
+                       /*
+                        * Due to quantizing, it might possible that the
+                        * decoded coefficients are slightly out of range
+                        */
+                       if (*deltas < 0)
+                               *deltas = 0;
+                       else if (*deltas > 255)
+                               *deltas = 255;
+                       deltas++;
+               }
+               ref += stride - 8;
+       }
+}
+
+static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,
+                       struct fwht_cframe *cf, u32 height, u32 width,
+                       unsigned int input_step,
+                       bool is_intra, bool next_is_intra)
+{
+       u8 *input_start = input;
+       __be16 *rlco_start = *rlco;
+       s16 deltablock[64];
+       __be16 pframe_bit = htons(PFRAME_BIT);
+       u32 encoding = 0;
+       unsigned int last_size = 0;
+       unsigned int i, j;
+
+       for (j = 0; j < height / 8; j++) {
+               for (i = 0; i < width / 8; i++) {
+                       /* intra code, first frame is always intra coded. */
+                       int blocktype = IBLOCK;
+                       unsigned int size;
+
+                       if (!is_intra)
+                               blocktype = decide_blocktype(input, refp,
+                                       deltablock, width, input_step);
+                       if (blocktype == IBLOCK) {
+                               fwht(input, cf->coeffs, width, input_step, 1);
+                               quantize_intra(cf->coeffs, cf->de_coeffs,
+                                              cf->i_frame_qp);
+                       } else {
+                               /* inter code */
+                               encoding |= FWHT_FRAME_PCODED;
+                               fwht16(deltablock, cf->coeffs, 8, 0);
+                               quantize_inter(cf->coeffs, cf->de_coeffs,
+                                              cf->p_frame_qp);
+                       }
+                       if (!next_is_intra) {
+                               ifwht(cf->de_coeffs, cf->de_fwht, blocktype);
+
+                               if (blocktype == PBLOCK)
+                                       add_deltas(cf->de_fwht, refp, 8);
+                               fill_decoder_block(refp, cf->de_fwht, 8);
+                       }
+
+                       input += 8 * input_step;
+                       refp += 8 * 8;
+
+                       size = rlc(cf->coeffs, *rlco, blocktype);
+                       if (last_size == size &&
+                           !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) {
+                               __be16 *last_rlco = *rlco - size;
+                               s16 hdr = ntohs(*last_rlco);
+
+                               if (!((*last_rlco ^ **rlco) & pframe_bit) &&
+                                   (hdr & DUPS_MASK) < DUPS_MASK)
+                                       *last_rlco = htons(hdr + 2);
+                               else
+                                       *rlco += size;
+                       } else {
+                               *rlco += size;
+                       }
+                       if (*rlco >= rlco_max) {
+                               encoding |= FWHT_FRAME_UNENCODED;
+                               goto exit_loop;
+                       }
+                       last_size = size;
+               }
+               input += width * 7 * input_step;
+       }
+
+exit_loop:
+       if (encoding & FWHT_FRAME_UNENCODED) {
+               u8 *out = (u8 *)rlco_start;
+
+               input = input_start;
+               /*
+                * The compressed stream should never contain the magic
+                * header, so when we copy the YUV data we replace 0xff
+                * by 0xfe. Since YUV is limited range such values
+                * shouldn't appear anyway.
+                */
+               for (i = 0; i < height * width; i++, input += input_step)
+                       *out++ = (*input == 0xff) ? 0xfe : *input;
+               *rlco = (__be16 *)out;
+               encoding &= ~FWHT_FRAME_PCODED;
+       }
+       return encoding;
+}
+
+u32 fwht_encode_frame(struct fwht_raw_frame *frm,
+                     struct fwht_raw_frame *ref_frm,
+                     struct fwht_cframe *cf,
+                     bool is_intra, bool next_is_intra)
+{
+       unsigned int size = frm->height * frm->width;
+       __be16 *rlco = cf->rlc_data;
+       __be16 *rlco_max;
+       u32 encoding;
+       u32 chroma_h = frm->height / frm->height_div;
+       u32 chroma_w = frm->width / frm->width_div;
+       unsigned int chroma_size = chroma_h * chroma_w;
+
+       rlco_max = rlco + size / 2 - 256;
+       encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf,
+                               frm->height, frm->width,
+                               frm->luma_step, is_intra, next_is_intra);
+       if (encoding & FWHT_FRAME_UNENCODED)
+               encoding |= FWHT_LUMA_UNENCODED;
+       encoding &= ~FWHT_FRAME_UNENCODED;
+       rlco_max = rlco + chroma_size / 2 - 256;
+       encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf,
+                                chroma_h, chroma_w,
+                                frm->chroma_step, is_intra, next_is_intra);
+       if (encoding & FWHT_FRAME_UNENCODED)
+               encoding |= FWHT_CB_UNENCODED;
+       encoding &= ~FWHT_FRAME_UNENCODED;
+       rlco_max = rlco + chroma_size / 2 - 256;
+       encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf,
+                                chroma_h, chroma_w,
+                                frm->chroma_step, is_intra, next_is_intra);
+       if (encoding & FWHT_FRAME_UNENCODED)
+               encoding |= FWHT_CR_UNENCODED;
+       encoding &= ~FWHT_FRAME_UNENCODED;
+       cf->size = (rlco - cf->rlc_data) * sizeof(*rlco);
+       return encoding;
+}
+
+static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref,
+                        u32 height, u32 width, bool uncompressed)
+{
+       unsigned int copies = 0;
+       s16 copy[8 * 8];
+       s16 stat;
+       unsigned int i, j;
+
+       if (uncompressed) {
+               memcpy(ref, *rlco, width * height);
+               *rlco += width * height / 2;
+               return;
+       }
+
+       /*
+        * When decoding each macroblock the rlco pointer will be increased
+        * by 65 * 2 bytes worst-case.
+        * To avoid overflow the buffer has to be 65/64th of the actual raw
+        * image size, just in case someone feeds it malicious data.
+        */
+       for (j = 0; j < height / 8; j++) {
+               for (i = 0; i < width / 8; i++) {
+                       u8 *refp = ref + j * 8 * width + i * 8;
+
+                       if (copies) {
+                               memcpy(cf->de_fwht, copy, sizeof(copy));
+                               if (stat & PFRAME_BIT)
+                                       add_deltas(cf->de_fwht, refp, width);
+                               fill_decoder_block(refp, cf->de_fwht, width);
+                               copies--;
+                               continue;
+                       }
+
+                       stat = derlc(rlco, cf->coeffs);
+
+                       if (stat & PFRAME_BIT)
+                               dequantize_inter(cf->coeffs);
+                       else
+                               dequantize_intra(cf->coeffs);
+
+                       ifwht(cf->coeffs, cf->de_fwht,
+                             (stat & PFRAME_BIT) ? 0 : 1);
+
+                       copies = (stat & DUPS_MASK) >> 1;
+                       if (copies)
+                               memcpy(copy, cf->de_fwht, sizeof(copy));
+                       if (stat & PFRAME_BIT)
+                               add_deltas(cf->de_fwht, refp, width);
+                       fill_decoder_block(refp, cf->de_fwht, width);
+               }
+       }
+}
+
+void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref,
+                      u32 hdr_flags)
+{
+       const __be16 *rlco = cf->rlc_data;
+       u32 h = cf->height / 2;
+       u32 w = cf->width / 2;
+
+       if (hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT)
+               h *= 2;
+       if (hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH)
+               w *= 2;
+       decode_plane(cf, &rlco, ref->luma, cf->height, cf->width,
+                    hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED);
+       decode_plane(cf, &rlco, ref->cb, h, w,
+                    hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED);
+       decode_plane(cf, &rlco, ref->cr, h, w,
+                    hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED);
+}
diff --git a/drivers/media/platform/vicodec/codec-fwht.h b/drivers/media/platform/vicodec/codec-fwht.h
new file mode 100644 (file)
index 0000000..3e9391f
--- /dev/null
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/*
+ * Copyright 2016 Tom aan de Wiel
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef CODEC_FWHT_H
+#define CODEC_FWHT_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <asm/byteorder.h>
+
+/*
+ * The compressed format consists of a fwht_cframe_hdr struct followed by the
+ * compressed frame data. The header contains the size of that data.
+ * Each Y, Cb and Cr plane is compressed separately. If the compressed
+ * size of each plane becomes larger than the uncompressed size, then
+ * that plane is stored uncompressed and the corresponding bit is set
+ * in the flags field of the header.
+ *
+ * Each compressed plane consists of macroblocks and each macroblock
+ * is run-length-encoded. Each macroblock starts with a 16 bit value.
+ * Bit 15 indicates if this is a P-coded macroblock (1) or not (0).
+ * P-coded macroblocks contain a delta against the previous frame.
+ *
+ * Bits 1-12 contain a number. If non-zero, then this same macroblock
+ * repeats that number of times. This results in a high degree of
+ * compression for generated images like colorbars.
+ *
+ * Following this macroblock header the MB coefficients are run-length
+ * encoded: the top 12 bits contain the coefficient, the bottom 4 bits
+ * tell how many times this coefficient occurs. The value 0xf indicates
+ * that the remainder of the macroblock should be filled with zeroes.
+ *
+ * All 16 and 32 bit values are stored in big-endian (network) order.
+ *
+ * Each fwht_cframe_hdr starts with an 8 byte magic header that is
+ * guaranteed not to occur in the compressed frame data. This header
+ * can be used to sync to the next frame.
+ *
+ * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel
+ * developed this as part of a university project, specifically for use
+ * with this driver. His project report can be found here:
+ *
+ * https://hverkuil.home.xs4all.nl/fwht.pdf
+ */
+
+/*
+ * This is a sequence of 8 bytes with the low 4 bits set to 0xf.
+ *
+ * This sequence cannot occur in the encoded data
+ *
+ * Note that these two magic values are symmetrical so endian issues here.
+ */
+#define FWHT_MAGIC1 0x4f4f4f4f
+#define FWHT_MAGIC2 0xffffffff
+
+#define FWHT_VERSION 1
+
+/* Set if this is an interlaced format */
+#define FWHT_FL_IS_INTERLACED          BIT(0)
+/* Set if this is a bottom-first (NTSC) interlaced format */
+#define FWHT_FL_IS_BOTTOM_FIRST                BIT(1)
+/* Set if each 'frame' contains just one field */
+#define FWHT_FL_IS_ALTERNATE           BIT(2)
+/*
+ * If FWHT_FL_IS_ALTERNATE was set, then this is set if this
+ * 'frame' is the bottom field, else it is the top field.
+ */
+#define FWHT_FL_IS_BOTTOM_FIELD                BIT(3)
+/* Set if this frame is uncompressed */
+#define FWHT_FL_LUMA_IS_UNCOMPRESSED   BIT(4)
+#define FWHT_FL_CB_IS_UNCOMPRESSED     BIT(5)
+#define FWHT_FL_CR_IS_UNCOMPRESSED     BIT(6)
+#define FWHT_FL_CHROMA_FULL_HEIGHT     BIT(7)
+#define FWHT_FL_CHROMA_FULL_WIDTH      BIT(8)
+
+struct fwht_cframe_hdr {
+       u32 magic1;
+       u32 magic2;
+       __be32 version;
+       __be32 width, height;
+       __be32 flags;
+       __be32 colorspace;
+       __be32 xfer_func;
+       __be32 ycbcr_enc;
+       __be32 quantization;
+       __be32 size;
+};
+
+struct fwht_cframe {
+       unsigned int width, height;
+       u16 i_frame_qp;
+       u16 p_frame_qp;
+       __be16 *rlc_data;
+       s16 coeffs[8 * 8];
+       s16 de_coeffs[8 * 8];
+       s16 de_fwht[8 * 8];
+       u32 size;
+};
+
+struct fwht_raw_frame {
+       unsigned int width, height;
+       unsigned int width_div;
+       unsigned int height_div;
+       unsigned int luma_step;
+       unsigned int chroma_step;
+       u8 *luma, *cb, *cr;
+};
+
+#define FWHT_FRAME_PCODED      BIT(0)
+#define FWHT_FRAME_UNENCODED   BIT(1)
+#define FWHT_LUMA_UNENCODED    BIT(2)
+#define FWHT_CB_UNENCODED      BIT(3)
+#define FWHT_CR_UNENCODED      BIT(4)
+
+u32 fwht_encode_frame(struct fwht_raw_frame *frm,
+                     struct fwht_raw_frame *ref_frm,
+                     struct fwht_cframe *cf,
+                     bool is_intra, bool next_is_intra);
+void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref,
+                      u32 hdr_flags);
+
+#endif
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c
new file mode 100644 (file)
index 0000000..e5b68fb
--- /dev/null
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * A V4L2 frontend for the FWHT codec
+ *
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+#include "codec-v4l2-fwht.h"
+
+static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = {
+       { V4L2_PIX_FMT_YUV420,  1, 3, 2, 1, 1, 2, 2 },
+       { V4L2_PIX_FMT_YVU420,  1, 3, 2, 1, 1, 2, 2 },
+       { V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1 },
+       { V4L2_PIX_FMT_NV12,    1, 3, 2, 1, 2, 2, 2 },
+       { V4L2_PIX_FMT_NV21,    1, 3, 2, 1, 2, 2, 2 },
+       { V4L2_PIX_FMT_NV16,    1, 2, 1, 1, 2, 2, 1 },
+       { V4L2_PIX_FMT_NV61,    1, 2, 1, 1, 2, 2, 1 },
+       { V4L2_PIX_FMT_NV24,    1, 3, 1, 1, 2, 1, 1 },
+       { V4L2_PIX_FMT_NV42,    1, 3, 1, 1, 2, 1, 1 },
+       { V4L2_PIX_FMT_YUYV,    2, 2, 1, 2, 4, 2, 1 },
+       { V4L2_PIX_FMT_YVYU,    2, 2, 1, 2, 4, 2, 1 },
+       { V4L2_PIX_FMT_UYVY,    2, 2, 1, 2, 4, 2, 1 },
+       { V4L2_PIX_FMT_VYUY,    2, 2, 1, 2, 4, 2, 1 },
+       { V4L2_PIX_FMT_BGR24,   3, 3, 1, 3, 3, 1, 1 },
+       { V4L2_PIX_FMT_RGB24,   3, 3, 1, 3, 3, 1, 1 },
+       { V4L2_PIX_FMT_HSV24,   3, 3, 1, 3, 3, 1, 1 },
+       { V4L2_PIX_FMT_BGR32,   4, 4, 1, 4, 4, 1, 1 },
+       { V4L2_PIX_FMT_XBGR32,  4, 4, 1, 4, 4, 1, 1 },
+       { V4L2_PIX_FMT_RGB32,   4, 4, 1, 4, 4, 1, 1 },
+       { V4L2_PIX_FMT_XRGB32,  4, 4, 1, 4, 4, 1, 1 },
+       { V4L2_PIX_FMT_HSV32,   4, 4, 1, 4, 4, 1, 1 },
+};
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++)
+               if (v4l2_fwht_pixfmts[i].id == pixelformat)
+                       return v4l2_fwht_pixfmts + i;
+       return NULL;
+}
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx)
+{
+       if (idx >= ARRAY_SIZE(v4l2_fwht_pixfmts))
+               return NULL;
+       return v4l2_fwht_pixfmts + idx;
+}
+
+int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
+{
+       unsigned int size = state->width * state->height;
+       const struct v4l2_fwht_pixfmt_info *info = state->info;
+       struct fwht_cframe_hdr *p_hdr;
+       struct fwht_cframe cf;
+       struct fwht_raw_frame rf;
+       u32 encoding;
+       u32 flags = 0;
+
+       if (!info)
+               return -EINVAL;
+       rf.width = state->width;
+       rf.height = state->height;
+       rf.luma = p_in;
+       rf.width_div = info->width_div;
+       rf.height_div = info->height_div;
+       rf.luma_step = info->luma_step;
+       rf.chroma_step = info->chroma_step;
+
+       switch (info->id) {
+       case V4L2_PIX_FMT_YUV420:
+               rf.cb = rf.luma + size;
+               rf.cr = rf.cb + size / 4;
+               break;
+       case V4L2_PIX_FMT_YVU420:
+               rf.cr = rf.luma + size;
+               rf.cb = rf.cr + size / 4;
+               break;
+       case V4L2_PIX_FMT_YUV422P:
+               rf.cb = rf.luma + size;
+               rf.cr = rf.cb + size / 2;
+               break;
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV16:
+       case V4L2_PIX_FMT_NV24:
+               rf.cb = rf.luma + size;
+               rf.cr = rf.cb + 1;
+               break;
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_NV61:
+       case V4L2_PIX_FMT_NV42:
+               rf.cr = rf.luma + size;
+               rf.cb = rf.cr + 1;
+               break;
+       case V4L2_PIX_FMT_YUYV:
+               rf.cb = rf.luma + 1;
+               rf.cr = rf.cb + 2;
+               break;
+       case V4L2_PIX_FMT_YVYU:
+               rf.cr = rf.luma + 1;
+               rf.cb = rf.cr + 2;
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               rf.cb = rf.luma;
+               rf.cr = rf.cb + 2;
+               rf.luma++;
+               break;
+       case V4L2_PIX_FMT_VYUY:
+               rf.cr = rf.luma;
+               rf.cb = rf.cr + 2;
+               rf.luma++;
+               break;
+       case V4L2_PIX_FMT_RGB24:
+       case V4L2_PIX_FMT_HSV24:
+               rf.cr = rf.luma;
+               rf.cb = rf.cr + 2;
+               rf.luma++;
+               break;
+       case V4L2_PIX_FMT_BGR24:
+               rf.cb = rf.luma;
+               rf.cr = rf.cb + 2;
+               rf.luma++;
+               break;
+       case V4L2_PIX_FMT_RGB32:
+       case V4L2_PIX_FMT_XRGB32:
+       case V4L2_PIX_FMT_HSV32:
+               rf.cr = rf.luma + 1;
+               rf.cb = rf.cr + 2;
+               rf.luma += 2;
+               break;
+       case V4L2_PIX_FMT_BGR32:
+       case V4L2_PIX_FMT_XBGR32:
+               rf.cb = rf.luma;
+               rf.cr = rf.cb + 2;
+               rf.luma++;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       cf.width = state->width;
+       cf.height = state->height;
+       cf.i_frame_qp = state->i_frame_qp;
+       cf.p_frame_qp = state->p_frame_qp;
+       cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr));
+
+       encoding = fwht_encode_frame(&rf, &state->ref_frame, &cf,
+                                    !state->gop_cnt,
+                                    state->gop_cnt == state->gop_size - 1);
+       if (!(encoding & FWHT_FRAME_PCODED))
+               state->gop_cnt = 0;
+       if (++state->gop_cnt >= state->gop_size)
+               state->gop_cnt = 0;
+
+       p_hdr = (struct fwht_cframe_hdr *)p_out;
+       p_hdr->magic1 = FWHT_MAGIC1;
+       p_hdr->magic2 = FWHT_MAGIC2;
+       p_hdr->version = htonl(FWHT_VERSION);
+       p_hdr->width = htonl(cf.width);
+       p_hdr->height = htonl(cf.height);
+       if (encoding & FWHT_LUMA_UNENCODED)
+               flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED;
+       if (encoding & FWHT_CB_UNENCODED)
+               flags |= FWHT_FL_CB_IS_UNCOMPRESSED;
+       if (encoding & FWHT_CR_UNENCODED)
+               flags |= FWHT_FL_CR_IS_UNCOMPRESSED;
+       if (rf.height_div == 1)
+               flags |= FWHT_FL_CHROMA_FULL_HEIGHT;
+       if (rf.width_div == 1)
+               flags |= FWHT_FL_CHROMA_FULL_WIDTH;
+       p_hdr->flags = htonl(flags);
+       p_hdr->colorspace = htonl(state->colorspace);
+       p_hdr->xfer_func = htonl(state->xfer_func);
+       p_hdr->ycbcr_enc = htonl(state->ycbcr_enc);
+       p_hdr->quantization = htonl(state->quantization);
+       p_hdr->size = htonl(cf.size);
+       state->ref_frame.width = cf.width;
+       state->ref_frame.height = cf.height;
+       return cf.size + sizeof(*p_hdr);
+}
+
+int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
+{
+       unsigned int size = state->width * state->height;
+       unsigned int chroma_size = size;
+       unsigned int i;
+       u32 flags;
+       struct fwht_cframe_hdr *p_hdr;
+       struct fwht_cframe cf;
+       u8 *p;
+
+       if (!state->info)
+               return -EINVAL;
+
+       p_hdr = (struct fwht_cframe_hdr *)p_in;
+       cf.width = ntohl(p_hdr->width);
+       cf.height = ntohl(p_hdr->height);
+       flags = ntohl(p_hdr->flags);
+       state->colorspace = ntohl(p_hdr->colorspace);
+       state->xfer_func = ntohl(p_hdr->xfer_func);
+       state->ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
+       state->quantization = ntohl(p_hdr->quantization);
+       cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr));
+
+       if (p_hdr->magic1 != FWHT_MAGIC1 ||
+           p_hdr->magic2 != FWHT_MAGIC2 ||
+           ntohl(p_hdr->version) != FWHT_VERSION ||
+           (cf.width & 7) || (cf.height & 7))
+               return -EINVAL;
+
+       /* TODO: support resolution changes */
+       if (cf.width != state->width || cf.height != state->height)
+               return -EINVAL;
+
+       if (!(flags & FWHT_FL_CHROMA_FULL_WIDTH))
+               chroma_size /= 2;
+       if (!(flags & FWHT_FL_CHROMA_FULL_HEIGHT))
+               chroma_size /= 2;
+
+       fwht_decode_frame(&cf, &state->ref_frame, flags);
+
+       switch (state->info->id) {
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_YUV422P:
+               memcpy(p_out, state->ref_frame.luma, size);
+               p_out += size;
+               memcpy(p_out, state->ref_frame.cb, chroma_size);
+               p_out += chroma_size;
+               memcpy(p_out, state->ref_frame.cr, chroma_size);
+               break;
+       case V4L2_PIX_FMT_YVU420:
+               memcpy(p_out, state->ref_frame.luma, size);
+               p_out += size;
+               memcpy(p_out, state->ref_frame.cr, chroma_size);
+               p_out += chroma_size;
+               memcpy(p_out, state->ref_frame.cb, chroma_size);
+               break;
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV16:
+       case V4L2_PIX_FMT_NV24:
+               memcpy(p_out, state->ref_frame.luma, size);
+               p_out += size;
+               for (i = 0, p = p_out; i < chroma_size; i++) {
+                       *p++ = state->ref_frame.cb[i];
+                       *p++ = state->ref_frame.cr[i];
+               }
+               break;
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_NV61:
+       case V4L2_PIX_FMT_NV42:
+               memcpy(p_out, state->ref_frame.luma, size);
+               p_out += size;
+               for (i = 0, p = p_out; i < chroma_size; i++) {
+                       *p++ = state->ref_frame.cr[i];
+                       *p++ = state->ref_frame.cb[i];
+               }
+               break;
+       case V4L2_PIX_FMT_YUYV:
+               for (i = 0, p = p_out; i < size; i += 2) {
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cb[i / 2];
+                       *p++ = state->ref_frame.luma[i + 1];
+                       *p++ = state->ref_frame.cr[i / 2];
+               }
+               break;
+       case V4L2_PIX_FMT_YVYU:
+               for (i = 0, p = p_out; i < size; i += 2) {
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cr[i / 2];
+                       *p++ = state->ref_frame.luma[i + 1];
+                       *p++ = state->ref_frame.cb[i / 2];
+               }
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               for (i = 0, p = p_out; i < size; i += 2) {
+                       *p++ = state->ref_frame.cb[i / 2];
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cr[i / 2];
+                       *p++ = state->ref_frame.luma[i + 1];
+               }
+               break;
+       case V4L2_PIX_FMT_VYUY:
+               for (i = 0, p = p_out; i < size; i += 2) {
+                       *p++ = state->ref_frame.cr[i / 2];
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cb[i / 2];
+                       *p++ = state->ref_frame.luma[i + 1];
+               }
+               break;
+       case V4L2_PIX_FMT_RGB24:
+       case V4L2_PIX_FMT_HSV24:
+               for (i = 0, p = p_out; i < size; i++) {
+                       *p++ = state->ref_frame.cr[i];
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cb[i];
+               }
+               break;
+       case V4L2_PIX_FMT_BGR24:
+               for (i = 0, p = p_out; i < size; i++) {
+                       *p++ = state->ref_frame.cb[i];
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cr[i];
+               }
+               break;
+       case V4L2_PIX_FMT_RGB32:
+       case V4L2_PIX_FMT_XRGB32:
+       case V4L2_PIX_FMT_HSV32:
+               for (i = 0, p = p_out; i < size; i++) {
+                       *p++ = 0;
+                       *p++ = state->ref_frame.cr[i];
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cb[i];
+               }
+               break;
+       case V4L2_PIX_FMT_BGR32:
+       case V4L2_PIX_FMT_XBGR32:
+               for (i = 0, p = p_out; i < size; i++) {
+                       *p++ = state->ref_frame.cb[i];
+                       *p++ = state->ref_frame.luma[i];
+                       *p++ = state->ref_frame.cr[i];
+                       *p++ = 0;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.h b/drivers/media/platform/vicodec/codec-v4l2-fwht.h
new file mode 100644 (file)
index 0000000..162465b
--- /dev/null
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/*
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef CODEC_V4L2_FWHT_H
+#define CODEC_V4L2_FWHT_H
+
+#include "codec-fwht.h"
+
+struct v4l2_fwht_pixfmt_info {
+       u32 id;
+       unsigned int bytesperline_mult;
+       unsigned int sizeimage_mult;
+       unsigned int sizeimage_div;
+       unsigned int luma_step;
+       unsigned int chroma_step;
+       /* Chroma plane subsampling */
+       unsigned int width_div;
+       unsigned int height_div;
+};
+
+struct v4l2_fwht_state {
+       const struct v4l2_fwht_pixfmt_info *info;
+       unsigned int width;
+       unsigned int height;
+       unsigned int gop_size;
+       unsigned int gop_cnt;
+       u16 i_frame_qp;
+       u16 p_frame_qp;
+
+       enum v4l2_colorspace colorspace;
+       enum v4l2_ycbcr_encoding ycbcr_enc;
+       enum v4l2_xfer_func xfer_func;
+       enum v4l2_quantization quantization;
+
+       struct fwht_raw_frame ref_frame;
+       u8 *compressed_frame;
+};
+
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat);
+const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx);
+
+int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out);
+int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out);
+
+#endif
diff --git a/drivers/media/platform/vicodec/vicodec-codec.c b/drivers/media/platform/vicodec/vicodec-codec.c
deleted file mode 100644 (file)
index 2d04764..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2016 Tom aan de Wiel
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- *
- * 8x8 Fast Walsh Hadamard Transform in sequency order based on the paper:
- *
- * A Recursive Algorithm for Sequency-Ordered Fast Walsh Transforms,
- * R.D. Brown, 1977
- */
-
-#include <linux/string.h>
-#include "vicodec-codec.h"
-
-#define ALL_ZEROS 15
-#define DEADZONE_WIDTH 20
-
-static const uint8_t zigzag[64] = {
-       0,
-       1,  8,
-       2,  9, 16,
-       3, 10, 17, 24,
-       4, 11, 18, 25, 32,
-       5, 12, 19, 26, 33, 40,
-       6, 13, 20, 27, 34, 41, 48,
-       7, 14, 21, 28, 35, 42, 49, 56,
-       15, 22, 29, 36, 43, 50, 57,
-       23, 30, 37, 44, 51, 58,
-       31, 38, 45, 52, 59,
-       39, 46, 53, 60,
-       47, 54, 61,
-       55, 62,
-       63,
-};
-
-
-static int rlc(const s16 *in, __be16 *output, int blocktype)
-{
-       s16 block[8 * 8];
-       s16 *wp = block;
-       int i = 0;
-       int x, y;
-       int ret = 0;
-
-       /* read in block from framebuffer */
-       int lastzero_run = 0;
-       int to_encode;
-
-       for (y = 0; y < 8; y++) {
-               for (x = 0; x < 8; x++) {
-                       *wp = in[x + y * 8];
-                       wp++;
-               }
-       }
-
-       /* keep track of amount of trailing zeros */
-       for (i = 63; i >= 0 && !block[zigzag[i]]; i--)
-               lastzero_run++;
-
-       *output++ = (blocktype == PBLOCK ? htons(PFRAME_BIT) : 0);
-       ret++;
-
-       to_encode = 8 * 8 - (lastzero_run > 14 ? lastzero_run : 0);
-
-       i = 0;
-       while (i < to_encode) {
-               int cnt = 0;
-               int tmp;
-
-               /* count leading zeros */
-               while ((tmp = block[zigzag[i]]) == 0 && cnt < 14) {
-                       cnt++;
-                       i++;
-                       if (i == to_encode) {
-                               cnt--;
-                               break;
-                       }
-               }
-               /* 4 bits for run, 12 for coefficient (quantization by 4) */
-               *output++ = htons((cnt | tmp << 4));
-               i++;
-               ret++;
-       }
-       if (lastzero_run > 14) {
-               *output = htons(ALL_ZEROS | 0);
-               ret++;
-       }
-
-       return ret;
-}
-
-/*
- * This function will worst-case increase rlc_in by 65*2 bytes:
- * one s16 value for the header and 8 * 8 coefficients of type s16.
- */
-static s16 derlc(const __be16 **rlc_in, s16 *dwht_out)
-{
-       /* header */
-       const __be16 *input = *rlc_in;
-       s16 ret = ntohs(*input++);
-       int dec_count = 0;
-       s16 block[8 * 8 + 16];
-       s16 *wp = block;
-       int i;
-
-       /*
-        * Now de-compress, it expands one byte to up to 15 bytes
-        * (or fills the remainder of the 64 bytes with zeroes if it
-        * is the last byte to expand).
-        *
-        * So block has to be 8 * 8 + 16 bytes, the '+ 16' is to
-        * allow for overflow if the incoming data was malformed.
-        */
-       while (dec_count < 8 * 8) {
-               s16 in = ntohs(*input++);
-               int length = in & 0xf;
-               int coeff = in >> 4;
-
-               /* fill remainder with zeros */
-               if (length == 15) {
-                       for (i = 0; i < 64 - dec_count; i++)
-                               *wp++ = 0;
-                       break;
-               }
-
-               for (i = 0; i < length; i++)
-                       *wp++ = 0;
-               *wp++ = coeff;
-               dec_count += length + 1;
-       }
-
-       wp = block;
-
-       for (i = 0; i < 64; i++) {
-               int pos = zigzag[i];
-               int y = pos / 8;
-               int x = pos % 8;
-
-               dwht_out[x + y * 8] = *wp++;
-       }
-       *rlc_in = input;
-       return ret;
-}
-
-static const int quant_table[] = {
-       2, 2, 2, 2, 2, 2,  2,  2,
-       2, 2, 2, 2, 2, 2,  2,  2,
-       2, 2, 2, 2, 2, 2,  2,  3,
-       2, 2, 2, 2, 2, 2,  3,  6,
-       2, 2, 2, 2, 2, 3,  6,  6,
-       2, 2, 2, 2, 3, 6,  6,  6,
-       2, 2, 2, 3, 6, 6,  6,  6,
-       2, 2, 3, 6, 6, 6,  6,  8,
-};
-
-static const int quant_table_p[] = {
-       3, 3, 3, 3, 3, 3,  3,  3,
-       3, 3, 3, 3, 3, 3,  3,  3,
-       3, 3, 3, 3, 3, 3,  3,  3,
-       3, 3, 3, 3, 3, 3,  3,  6,
-       3, 3, 3, 3, 3, 3,  6,  6,
-       3, 3, 3, 3, 3, 6,  6,  9,
-       3, 3, 3, 3, 6, 6,  9,  9,
-       3, 3, 3, 6, 6, 9,  9,  10,
-};
-
-static void quantize_intra(s16 *coeff, s16 *de_coeff)
-{
-       const int *quant = quant_table;
-       int i, j;
-
-       for (j = 0; j < 8; j++) {
-               for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
-                       *coeff >>= *quant;
-                       if (*coeff >= -DEADZONE_WIDTH &&
-                           *coeff <= DEADZONE_WIDTH)
-                               *coeff = *de_coeff = 0;
-                       else
-                               *de_coeff = *coeff << *quant;
-               }
-       }
-}
-
-static void dequantize_intra(s16 *coeff)
-{
-       const int *quant = quant_table;
-       int i, j;
-
-       for (j = 0; j < 8; j++)
-               for (i = 0; i < 8; i++, quant++, coeff++)
-                       *coeff <<= *quant;
-}
-
-static void quantize_inter(s16 *coeff, s16 *de_coeff)
-{
-       const int *quant = quant_table_p;
-       int i, j;
-
-       for (j = 0; j < 8; j++) {
-               for (i = 0; i < 8; i++, quant++, coeff++, de_coeff++) {
-                       *coeff >>= *quant;
-                       if (*coeff >= -DEADZONE_WIDTH &&
-                           *coeff <= DEADZONE_WIDTH)
-                               *coeff = *de_coeff = 0;
-                       else
-                               *de_coeff = *coeff << *quant;
-               }
-       }
-}
-
-static void dequantize_inter(s16 *coeff)
-{
-       const int *quant = quant_table_p;
-       int i, j;
-
-       for (j = 0; j < 8; j++)
-               for (i = 0; i < 8; i++, quant++, coeff++)
-                       *coeff <<= *quant;
-}
-
-static void fwht(const u8 *block, s16 *output_block, unsigned int stride,
-                unsigned int input_step, bool intra)
-{
-       /* we'll need more than 8 bits for the transformed coefficients */
-       s32 workspace1[8], workspace2[8];
-       const u8 *tmp = block;
-       s16 *out = output_block;
-       int add = intra ? 256 : 0;
-       unsigned int i;
-
-       /* stage 1 */
-       stride *= input_step;
-
-       for (i = 0; i < 8; i++, tmp += stride, out += 8) {
-               if (input_step == 1) {
-                       workspace1[0]  = tmp[0] + tmp[1] - add;
-                       workspace1[1]  = tmp[0] - tmp[1];
-
-                       workspace1[2]  = tmp[2] + tmp[3] - add;
-                       workspace1[3]  = tmp[2] - tmp[3];
-
-                       workspace1[4]  = tmp[4] + tmp[5] - add;
-                       workspace1[5]  = tmp[4] - tmp[5];
-
-                       workspace1[6]  = tmp[6] + tmp[7] - add;
-                       workspace1[7]  = tmp[6] - tmp[7];
-               } else {
-                       workspace1[0]  = tmp[0] + tmp[2] - add;
-                       workspace1[1]  = tmp[0] - tmp[2];
-
-                       workspace1[2]  = tmp[4] + tmp[6] - add;
-                       workspace1[3]  = tmp[4] - tmp[6];
-
-                       workspace1[4]  = tmp[8] + tmp[10] - add;
-                       workspace1[5]  = tmp[8] - tmp[10];
-
-                       workspace1[6]  = tmp[12] + tmp[14] - add;
-                       workspace1[7]  = tmp[12] - tmp[14];
-               }
-
-               /* stage 2 */
-               workspace2[0] = workspace1[0] + workspace1[2];
-               workspace2[1] = workspace1[0] - workspace1[2];
-               workspace2[2] = workspace1[1] - workspace1[3];
-               workspace2[3] = workspace1[1] + workspace1[3];
-
-               workspace2[4] = workspace1[4] + workspace1[6];
-               workspace2[5] = workspace1[4] - workspace1[6];
-               workspace2[6] = workspace1[5] - workspace1[7];
-               workspace2[7] = workspace1[5] + workspace1[7];
-
-               /* stage 3 */
-               out[0] = workspace2[0] + workspace2[4];
-               out[1] = workspace2[0] - workspace2[4];
-               out[2] = workspace2[1] - workspace2[5];
-               out[3] = workspace2[1] + workspace2[5];
-               out[4] = workspace2[2] + workspace2[6];
-               out[5] = workspace2[2] - workspace2[6];
-               out[6] = workspace2[3] - workspace2[7];
-               out[7] = workspace2[3] + workspace2[7];
-       }
-
-       out = output_block;
-
-       for (i = 0; i < 8; i++, out++) {
-               /* stage 1 */
-               workspace1[0]  = out[0] + out[1 * 8];
-               workspace1[1]  = out[0] - out[1 * 8];
-
-               workspace1[2]  = out[2 * 8] + out[3 * 8];
-               workspace1[3]  = out[2 * 8] - out[3 * 8];
-
-               workspace1[4]  = out[4 * 8] + out[5 * 8];
-               workspace1[5]  = out[4 * 8] - out[5 * 8];
-
-               workspace1[6]  = out[6 * 8] + out[7 * 8];
-               workspace1[7]  = out[6 * 8] - out[7 * 8];
-
-               /* stage 2 */
-               workspace2[0] = workspace1[0] + workspace1[2];
-               workspace2[1] = workspace1[0] - workspace1[2];
-               workspace2[2] = workspace1[1] - workspace1[3];
-               workspace2[3] = workspace1[1] + workspace1[3];
-
-               workspace2[4] = workspace1[4] + workspace1[6];
-               workspace2[5] = workspace1[4] - workspace1[6];
-               workspace2[6] = workspace1[5] - workspace1[7];
-               workspace2[7] = workspace1[5] + workspace1[7];
-               /* stage 3 */
-               out[0 * 8] = workspace2[0] + workspace2[4];
-               out[1 * 8] = workspace2[0] - workspace2[4];
-               out[2 * 8] = workspace2[1] - workspace2[5];
-               out[3 * 8] = workspace2[1] + workspace2[5];
-               out[4 * 8] = workspace2[2] + workspace2[6];
-               out[5 * 8] = workspace2[2] - workspace2[6];
-               out[6 * 8] = workspace2[3] - workspace2[7];
-               out[7 * 8] = workspace2[3] + workspace2[7];
-       }
-}
-
-/*
- * Not the nicest way of doing it, but P-blocks get twice the range of
- * that of the I-blocks. Therefore we need a type bigger than 8 bits.
- * Furthermore values can be negative... This is just a version that
- * works with 16 signed data
- */
-static void fwht16(const s16 *block, s16 *output_block, int stride, int intra)
-{
-       /* we'll need more than 8 bits for the transformed coefficients */
-       s32 workspace1[8], workspace2[8];
-       const s16 *tmp = block;
-       s16 *out = output_block;
-       int i;
-
-       for (i = 0; i < 8; i++, tmp += stride, out += 8) {
-               /* stage 1 */
-               workspace1[0]  = tmp[0] + tmp[1];
-               workspace1[1]  = tmp[0] - tmp[1];
-
-               workspace1[2]  = tmp[2] + tmp[3];
-               workspace1[3]  = tmp[2] - tmp[3];
-
-               workspace1[4]  = tmp[4] + tmp[5];
-               workspace1[5]  = tmp[4] - tmp[5];
-
-               workspace1[6]  = tmp[6] + tmp[7];
-               workspace1[7]  = tmp[6] - tmp[7];
-
-               /* stage 2 */
-               workspace2[0] = workspace1[0] + workspace1[2];
-               workspace2[1] = workspace1[0] - workspace1[2];
-               workspace2[2] = workspace1[1] - workspace1[3];
-               workspace2[3] = workspace1[1] + workspace1[3];
-
-               workspace2[4] = workspace1[4] + workspace1[6];
-               workspace2[5] = workspace1[4] - workspace1[6];
-               workspace2[6] = workspace1[5] - workspace1[7];
-               workspace2[7] = workspace1[5] + workspace1[7];
-
-               /* stage 3 */
-               out[0] = workspace2[0] + workspace2[4];
-               out[1] = workspace2[0] - workspace2[4];
-               out[2] = workspace2[1] - workspace2[5];
-               out[3] = workspace2[1] + workspace2[5];
-               out[4] = workspace2[2] + workspace2[6];
-               out[5] = workspace2[2] - workspace2[6];
-               out[6] = workspace2[3] - workspace2[7];
-               out[7] = workspace2[3] + workspace2[7];
-       }
-
-       out = output_block;
-
-       for (i = 0; i < 8; i++, out++) {
-               /* stage 1 */
-               workspace1[0]  = out[0] + out[1*8];
-               workspace1[1]  = out[0] - out[1*8];
-
-               workspace1[2]  = out[2*8] + out[3*8];
-               workspace1[3]  = out[2*8] - out[3*8];
-
-               workspace1[4]  = out[4*8] + out[5*8];
-               workspace1[5]  = out[4*8] - out[5*8];
-
-               workspace1[6]  = out[6*8] + out[7*8];
-               workspace1[7]  = out[6*8] - out[7*8];
-
-               /* stage 2 */
-               workspace2[0] = workspace1[0] + workspace1[2];
-               workspace2[1] = workspace1[0] - workspace1[2];
-               workspace2[2] = workspace1[1] - workspace1[3];
-               workspace2[3] = workspace1[1] + workspace1[3];
-
-               workspace2[4] = workspace1[4] + workspace1[6];
-               workspace2[5] = workspace1[4] - workspace1[6];
-               workspace2[6] = workspace1[5] - workspace1[7];
-               workspace2[7] = workspace1[5] + workspace1[7];
-
-               /* stage 3 */
-               out[0*8] = workspace2[0] + workspace2[4];
-               out[1*8] = workspace2[0] - workspace2[4];
-               out[2*8] = workspace2[1] - workspace2[5];
-               out[3*8] = workspace2[1] + workspace2[5];
-               out[4*8] = workspace2[2] + workspace2[6];
-               out[5*8] = workspace2[2] - workspace2[6];
-               out[6*8] = workspace2[3] - workspace2[7];
-               out[7*8] = workspace2[3] + workspace2[7];
-       }
-}
-
-static void ifwht(const s16 *block, s16 *output_block, int intra)
-{
-       /*
-        * we'll need more than 8 bits for the transformed coefficients
-        * use native unit of cpu
-        */
-       int workspace1[8], workspace2[8];
-       int inter = intra ? 0 : 1;
-       const s16 *tmp = block;
-       s16 *out = output_block;
-       int i;
-
-       for (i = 0; i < 8; i++, tmp += 8, out += 8) {
-               /* stage 1 */
-               workspace1[0]  = tmp[0] + tmp[1];
-               workspace1[1]  = tmp[0] - tmp[1];
-
-               workspace1[2]  = tmp[2] + tmp[3];
-               workspace1[3]  = tmp[2] - tmp[3];
-
-               workspace1[4]  = tmp[4] + tmp[5];
-               workspace1[5]  = tmp[4] - tmp[5];
-
-               workspace1[6]  = tmp[6] + tmp[7];
-               workspace1[7]  = tmp[6] - tmp[7];
-
-               /* stage 2 */
-               workspace2[0] = workspace1[0] + workspace1[2];
-               workspace2[1] = workspace1[0] - workspace1[2];
-               workspace2[2] = workspace1[1] - workspace1[3];
-               workspace2[3] = workspace1[1] + workspace1[3];
-
-               workspace2[4] = workspace1[4] + workspace1[6];
-               workspace2[5] = workspace1[4] - workspace1[6];
-               workspace2[6] = workspace1[5] - workspace1[7];
-               workspace2[7] = workspace1[5] + workspace1[7];
-
-               /* stage 3 */
-               out[0] = workspace2[0] + workspace2[4];
-               out[1] = workspace2[0] - workspace2[4];
-               out[2] = workspace2[1] - workspace2[5];
-               out[3] = workspace2[1] + workspace2[5];
-               out[4] = workspace2[2] + workspace2[6];
-               out[5] = workspace2[2] - workspace2[6];
-               out[6] = workspace2[3] - workspace2[7];
-               out[7] = workspace2[3] + workspace2[7];
-       }
-
-       out = output_block;
-
-       for (i = 0; i < 8; i++, out++) {
-               /* stage 1 */
-               workspace1[0]  = out[0] + out[1 * 8];
-               workspace1[1]  = out[0] - out[1 * 8];
-
-               workspace1[2]  = out[2 * 8] + out[3 * 8];
-               workspace1[3]  = out[2 * 8] - out[3 * 8];
-
-               workspace1[4]  = out[4 * 8] + out[5 * 8];
-               workspace1[5]  = out[4 * 8] - out[5 * 8];
-
-               workspace1[6]  = out[6 * 8] + out[7 * 8];
-               workspace1[7]  = out[6 * 8] - out[7 * 8];
-
-               /* stage 2 */
-               workspace2[0] = workspace1[0] + workspace1[2];
-               workspace2[1] = workspace1[0] - workspace1[2];
-               workspace2[2] = workspace1[1] - workspace1[3];
-               workspace2[3] = workspace1[1] + workspace1[3];
-
-               workspace2[4] = workspace1[4] + workspace1[6];
-               workspace2[5] = workspace1[4] - workspace1[6];
-               workspace2[6] = workspace1[5] - workspace1[7];
-               workspace2[7] = workspace1[5] + workspace1[7];
-
-               /* stage 3 */
-               if (inter) {
-                       int d;
-
-                       out[0 * 8] = workspace2[0] + workspace2[4];
-                       out[1 * 8] = workspace2[0] - workspace2[4];
-                       out[2 * 8] = workspace2[1] - workspace2[5];
-                       out[3 * 8] = workspace2[1] + workspace2[5];
-                       out[4 * 8] = workspace2[2] + workspace2[6];
-                       out[5 * 8] = workspace2[2] - workspace2[6];
-                       out[6 * 8] = workspace2[3] - workspace2[7];
-                       out[7 * 8] = workspace2[3] + workspace2[7];
-
-                       for (d = 0; d < 8; d++)
-                               out[8 * d] >>= 6;
-               } else {
-                       int d;
-
-                       out[0 * 8] = workspace2[0] + workspace2[4];
-                       out[1 * 8] = workspace2[0] - workspace2[4];
-                       out[2 * 8] = workspace2[1] - workspace2[5];
-                       out[3 * 8] = workspace2[1] + workspace2[5];
-                       out[4 * 8] = workspace2[2] + workspace2[6];
-                       out[5 * 8] = workspace2[2] - workspace2[6];
-                       out[6 * 8] = workspace2[3] - workspace2[7];
-                       out[7 * 8] = workspace2[3] + workspace2[7];
-
-                       for (d = 0; d < 8; d++) {
-                               out[8 * d] >>= 6;
-                               out[8 * d] += 128;
-                       }
-               }
-       }
-}
-
-static void fill_encoder_block(const u8 *input, s16 *dst,
-                              unsigned int stride, unsigned int input_step)
-{
-       int i, j;
-
-       for (i = 0; i < 8; i++) {
-               for (j = 0; j < 8; j++, input += input_step)
-                       *dst++ = *input;
-               input += (stride - 8) * input_step;
-       }
-}
-
-static int var_intra(const s16 *input)
-{
-       int32_t mean = 0;
-       int32_t ret = 0;
-       const s16 *tmp = input;
-       int i;
-
-       for (i = 0; i < 8 * 8; i++, tmp++)
-               mean += *tmp;
-       mean /= 64;
-       tmp = input;
-       for (i = 0; i < 8 * 8; i++, tmp++)
-               ret += (*tmp - mean) < 0 ? -(*tmp - mean) : (*tmp - mean);
-       return ret;
-}
-
-static int var_inter(const s16 *old, const s16 *new)
-{
-       int32_t ret = 0;
-       int i;
-
-       for (i = 0; i < 8 * 8; i++, old++, new++)
-               ret += (*old - *new) < 0 ? -(*old - *new) : (*old - *new);
-       return ret;
-}
-
-static int decide_blocktype(const u8 *cur, const u8 *reference,
-                           s16 *deltablock, unsigned int stride,
-                           unsigned int input_step)
-{
-       s16 tmp[64];
-       s16 old[64];
-       s16 *work = tmp;
-       unsigned int k, l;
-       int vari;
-       int vard;
-
-       fill_encoder_block(cur, tmp, stride, input_step);
-       fill_encoder_block(reference, old, 8, 1);
-       vari = var_intra(tmp);
-
-       for (k = 0; k < 8; k++) {
-               for (l = 0; l < 8; l++) {
-                       *deltablock = *work - *reference;
-                       deltablock++;
-                       work++;
-                       reference++;
-               }
-       }
-       deltablock -= 64;
-       vard = var_inter(old, tmp);
-       return vari <= vard ? IBLOCK : PBLOCK;
-}
-
-static void fill_decoder_block(u8 *dst, const s16 *input, int stride)
-{
-       int i, j;
-
-       for (i = 0; i < 8; i++) {
-               for (j = 0; j < 8; j++)
-                       *dst++ = *input++;
-               dst += stride - 8;
-       }
-}
-
-static void add_deltas(s16 *deltas, const u8 *ref, int stride)
-{
-       int k, l;
-
-       for (k = 0; k < 8; k++) {
-               for (l = 0; l < 8; l++) {
-                       *deltas += *ref++;
-                       /*
-                        * Due to quantizing, it might possible that the
-                        * decoded coefficients are slightly out of range
-                        */
-                       if (*deltas < 0)
-                               *deltas = 0;
-                       else if (*deltas > 255)
-                               *deltas = 255;
-                       deltas++;
-               }
-               ref += stride - 8;
-       }
-}
-
-static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,
-                       struct cframe *cf, u32 height, u32 width,
-                       unsigned int input_step,
-                       bool is_intra, bool next_is_intra)
-{
-       u8 *input_start = input;
-       __be16 *rlco_start = *rlco;
-       s16 deltablock[64];
-       __be16 pframe_bit = htons(PFRAME_BIT);
-       u32 encoding = 0;
-       unsigned int last_size = 0;
-       unsigned int i, j;
-
-       for (j = 0; j < height / 8; j++) {
-               for (i = 0; i < width / 8; i++) {
-                       /* intra code, first frame is always intra coded. */
-                       int blocktype = IBLOCK;
-                       unsigned int size;
-
-                       if (!is_intra)
-                               blocktype = decide_blocktype(input, refp,
-                                       deltablock, width, input_step);
-                       if (is_intra || blocktype == IBLOCK) {
-                               fwht(input, cf->coeffs, width, input_step, 1);
-                               quantize_intra(cf->coeffs, cf->de_coeffs);
-                               blocktype = IBLOCK;
-                       } else {
-                               /* inter code */
-                               encoding |= FRAME_PCODED;
-                               fwht16(deltablock, cf->coeffs, 8, 0);
-                               quantize_inter(cf->coeffs, cf->de_coeffs);
-                       }
-                       if (!next_is_intra) {
-                               ifwht(cf->de_coeffs, cf->de_fwht, blocktype);
-
-                               if (blocktype == PBLOCK)
-                                       add_deltas(cf->de_fwht, refp, 8);
-                               fill_decoder_block(refp, cf->de_fwht, 8);
-                       }
-
-                       input += 8 * input_step;
-                       refp += 8 * 8;
-
-                       if (encoding & FRAME_UNENCODED)
-                               continue;
-
-                       size = rlc(cf->coeffs, *rlco, blocktype);
-                       if (last_size == size &&
-                           !memcmp(*rlco + 1, *rlco - size + 1, 2 * size - 2)) {
-                               __be16 *last_rlco = *rlco - size;
-                               s16 hdr = ntohs(*last_rlco);
-
-                               if (!((*last_rlco ^ **rlco) & pframe_bit) &&
-                                   (hdr & DUPS_MASK) < DUPS_MASK)
-                                       *last_rlco = htons(hdr + 2);
-                               else
-                                       *rlco += size;
-                       } else {
-                               *rlco += size;
-                       }
-                       if (*rlco >= rlco_max)
-                               encoding |= FRAME_UNENCODED;
-                       last_size = size;
-               }
-               input += width * 7 * input_step;
-       }
-       if (encoding & FRAME_UNENCODED) {
-               u8 *out = (u8 *)rlco_start;
-
-               input = input_start;
-               /*
-                * The compressed stream should never contain the magic
-                * header, so when we copy the YUV data we replace 0xff
-                * by 0xfe. Since YUV is limited range such values
-                * shouldn't appear anyway.
-                */
-               for (i = 0; i < height * width; i++, input += input_step)
-                       *out++ = (*input == 0xff) ? 0xfe : *input;
-               *rlco = (__be16 *)out;
-       }
-       return encoding;
-}
-
-u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm,
-                struct cframe *cf, bool is_intra, bool next_is_intra)
-{
-       unsigned int size = frm->height * frm->width;
-       __be16 *rlco = cf->rlc_data;
-       __be16 *rlco_max;
-       u32 encoding;
-
-       rlco_max = rlco + size / 2 - 256;
-       encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf,
-                                 frm->height, frm->width,
-                                 1, is_intra, next_is_intra);
-       if (encoding & FRAME_UNENCODED)
-               encoding |= LUMA_UNENCODED;
-       encoding &= ~FRAME_UNENCODED;
-       rlco_max = rlco + size / 8 - 256;
-       encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf,
-                                  frm->height / 2, frm->width / 2,
-                                  frm->chroma_step, is_intra, next_is_intra);
-       if (encoding & FRAME_UNENCODED)
-               encoding |= CB_UNENCODED;
-       encoding &= ~FRAME_UNENCODED;
-       rlco_max = rlco + size / 8 - 256;
-       encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf,
-                                  frm->height / 2, frm->width / 2,
-                                  frm->chroma_step, is_intra, next_is_intra);
-       if (encoding & FRAME_UNENCODED)
-               encoding |= CR_UNENCODED;
-       encoding &= ~FRAME_UNENCODED;
-       cf->size = (rlco - cf->rlc_data) * sizeof(*rlco);
-       return encoding;
-}
-
-static void decode_plane(struct cframe *cf, const __be16 **rlco, u8 *ref,
-                        u32 height, u32 width, bool uncompressed)
-{
-       unsigned int copies = 0;
-       s16 copy[8 * 8];
-       s16 stat;
-       unsigned int i, j;
-
-       if (uncompressed) {
-               memcpy(ref, *rlco, width * height);
-               *rlco += width * height / 2;
-               return;
-       }
-
-       /*
-        * When decoding each macroblock the rlco pointer will be increased
-        * by 65 * 2 bytes worst-case.
-        * To avoid overflow the buffer has to be 65/64th of the actual raw
-        * image size, just in case someone feeds it malicious data.
-        */
-       for (j = 0; j < height / 8; j++) {
-               for (i = 0; i < width / 8; i++) {
-                       u8 *refp = ref + j * 8 * width + i * 8;
-
-                       if (copies) {
-                               memcpy(cf->de_fwht, copy, sizeof(copy));
-                               if (stat & PFRAME_BIT)
-                                       add_deltas(cf->de_fwht, refp, width);
-                               fill_decoder_block(refp, cf->de_fwht, width);
-                               copies--;
-                               continue;
-                       }
-
-                       stat = derlc(rlco, cf->coeffs);
-
-                       if (stat & PFRAME_BIT)
-                               dequantize_inter(cf->coeffs);
-                       else
-                               dequantize_intra(cf->coeffs);
-
-                       ifwht(cf->coeffs, cf->de_fwht,
-                             (stat & PFRAME_BIT) ? 0 : 1);
-
-                       copies = (stat & DUPS_MASK) >> 1;
-                       if (copies)
-                               memcpy(copy, cf->de_fwht, sizeof(copy));
-                       if (stat & PFRAME_BIT)
-                               add_deltas(cf->de_fwht, refp, width);
-                       fill_decoder_block(refp, cf->de_fwht, width);
-               }
-       }
-}
-
-void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags)
-{
-       const __be16 *rlco = cf->rlc_data;
-
-       decode_plane(cf, &rlco, ref->luma, cf->height, cf->width,
-                    hdr_flags & VICODEC_FL_LUMA_IS_UNCOMPRESSED);
-       decode_plane(cf, &rlco, ref->cb, cf->height / 2, cf->width / 2,
-                    hdr_flags & VICODEC_FL_CB_IS_UNCOMPRESSED);
-       decode_plane(cf, &rlco, ref->cr, cf->height / 2, cf->width / 2,
-                    hdr_flags & VICODEC_FL_CR_IS_UNCOMPRESSED);
-}
diff --git a/drivers/media/platform/vicodec/vicodec-codec.h b/drivers/media/platform/vicodec/vicodec-codec.h
deleted file mode 100644 (file)
index cdfad13..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright 2016 Tom aan de Wiel
- * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- */
-
-#ifndef VICODEC_RLC_H
-#define VICODEC_RLC_H
-
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-
-/*
- * The compressed format consists of a cframe_hdr struct followed by the
- * compressed frame data. The header contains the size of that data.
- * Each Y, Cb and Cr plane is compressed separately. If the compressed
- * size of each plane becomes larger than the uncompressed size, then
- * that plane is stored uncompressed and the corresponding bit is set
- * in the flags field of the header.
- *
- * Each compressed plane consists of macroblocks and each macroblock
- * is run-length-encoded. Each macroblock starts with a 16 bit value.
- * Bit 15 indicates if this is a P-coded macroblock (1) or not (0).
- * P-coded macroblocks contain a delta against the previous frame.
- *
- * Bits 1-12 contain a number. If non-zero, then this same macroblock
- * repeats that number of times. This results in a high degree of
- * compression for generated images like colorbars.
- *
- * Following this macroblock header the MB coefficients are run-length
- * encoded: the top 12 bits contain the coefficient, the bottom 4 bits
- * tell how many times this coefficient occurs. The value 0xf indicates
- * that the remainder of the macroblock should be filled with zeroes.
- *
- * All 16 and 32 bit values are stored in big-endian (network) order.
- *
- * Each cframe_hdr starts with an 8 byte magic header that is
- * guaranteed not to occur in the compressed frame data. This header
- * can be used to sync to the next frame.
- *
- * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel
- * developed this as part of a university project, specifically for use
- * with this driver. His project report can be found here:
- *
- * https://hverkuil.home.xs4all.nl/fwht.pdf
- */
-
-/*
- * Note: bit 0 of the header must always be 0. Otherwise it cannot
- * be guaranteed that the magic 8 byte sequence (see below) can
- * never occur in the rlc output.
- */
-#define PFRAME_BIT (1 << 15)
-#define DUPS_MASK 0x1ffe
-
-/*
- * This is a sequence of 8 bytes with the low 4 bits set to 0xf.
- *
- * This sequence cannot occur in the encoded data
- */
-#define VICODEC_MAGIC1 0x4f4f4f4f
-#define VICODEC_MAGIC2 0xffffffff
-
-#define VICODEC_VERSION 1
-
-#define VICODEC_MAX_WIDTH 3840
-#define VICODEC_MAX_HEIGHT 2160
-#define VICODEC_MIN_WIDTH 640
-#define VICODEC_MIN_HEIGHT 480
-
-#define PBLOCK 0
-#define IBLOCK 1
-
-/* Set if this is an interlaced format */
-#define VICODEC_FL_IS_INTERLACED       BIT(0)
-/* Set if this is a bottom-first (NTSC) interlaced format */
-#define VICODEC_FL_IS_BOTTOM_FIRST     BIT(1)
-/* Set if each 'frame' contains just one field */
-#define VICODEC_FL_IS_ALTERNATE                BIT(2)
-/*
- * If VICODEC_FL_IS_ALTERNATE was set, then this is set if this
- * 'frame' is the bottom field, else it is the top field.
- */
-#define VICODEC_FL_IS_BOTTOM_FIELD     BIT(3)
-/* Set if this frame is uncompressed */
-#define VICODEC_FL_LUMA_IS_UNCOMPRESSED        BIT(4)
-#define VICODEC_FL_CB_IS_UNCOMPRESSED  BIT(5)
-#define VICODEC_FL_CR_IS_UNCOMPRESSED  BIT(6)
-
-struct cframe_hdr {
-       u32 magic1;
-       u32 magic2;
-       __be32 version;
-       __be32 width, height;
-       __be32 flags;
-       __be32 colorspace;
-       __be32 xfer_func;
-       __be32 ycbcr_enc;
-       __be32 quantization;
-       __be32 size;
-};
-
-struct cframe {
-       unsigned int width, height;
-       __be16 *rlc_data;
-       s16 coeffs[8 * 8];
-       s16 de_coeffs[8 * 8];
-       s16 de_fwht[8 * 8];
-       u32 size;
-};
-
-struct raw_frame {
-       unsigned int width, height;
-       unsigned int chroma_step;
-       u8 *luma, *cb, *cr;
-};
-
-#define FRAME_PCODED   BIT(0)
-#define FRAME_UNENCODED        BIT(1)
-#define LUMA_UNENCODED BIT(2)
-#define CB_UNENCODED   BIT(3)
-#define CR_UNENCODED   BIT(4)
-
-u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm,
-                struct cframe *cf, bool is_intra, bool next_is_intra);
-void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags);
-
-#endif
index 408cd55d35801676265754c501ae4a2bd4b14dd5..1eb9132bfc85fdad1ab68d81442fb435be0ac0f0 100644 (file)
@@ -23,7 +23,7 @@
 #include <media/v4l2-event.h>
 #include <media/videobuf2-vmalloc.h>
 
-#include "vicodec-codec.h"
+#include "codec-v4l2-fwht.h"
 
 MODULE_DESCRIPTION("Virtual codec device");
 MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
@@ -48,6 +48,22 @@ MODULE_PARM_DESC(debug, " activates debug info");
        v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
 
 
+struct pixfmt_info {
+       u32 id;
+       unsigned int bytesperline_mult;
+       unsigned int sizeimage_mult;
+       unsigned int sizeimage_div;
+       unsigned int luma_step;
+       unsigned int chroma_step;
+       /* Chroma plane subsampling */
+       unsigned int width_div;
+       unsigned int height_div;
+};
+
+static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = {
+       V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1
+};
+
 static void vicodec_dev_release(struct device *dev)
 {
 }
@@ -61,10 +77,9 @@ static struct platform_device vicodec_pdev = {
 struct vicodec_q_data {
        unsigned int            width;
        unsigned int            height;
-       unsigned int            flags;
        unsigned int            sizeimage;
        unsigned int            sequence;
-       u32                     fourcc;
+       const struct v4l2_fwht_pixfmt_info *info;
 };
 
 enum {
@@ -96,24 +111,14 @@ struct vicodec_ctx {
        spinlock_t              *lock;
 
        struct v4l2_ctrl_handler hdl;
-       struct v4l2_ctrl        *ctrl_gop_size;
-       unsigned int            gop_size;
-       unsigned int            gop_cnt;
 
-       /* Abort requested by m2m */
-       int                     aborting;
        struct vb2_v4l2_buffer *last_src_buf;
        struct vb2_v4l2_buffer *last_dst_buf;
 
-       enum v4l2_colorspace    colorspace;
-       enum v4l2_ycbcr_encoding ycbcr_enc;
-       enum v4l2_xfer_func     xfer_func;
-       enum v4l2_quantization  quantization;
-
        /* Source and destination queue data */
        struct vicodec_q_data   q_data[2];
-       struct raw_frame        ref_frame;
-       u8                      *compressed_frame;
+       struct v4l2_fwht_state  state;
+
        u32                     cur_buf_offset;
        u32                     comp_max_size;
        u32                     comp_size;
@@ -123,13 +128,6 @@ struct vicodec_ctx {
        bool                    comp_has_next_frame;
 };
 
-static const u32 pixfmts_yuv[] = {
-       V4L2_PIX_FMT_YUV420,
-       V4L2_PIX_FMT_YVU420,
-       V4L2_PIX_FMT_NV12,
-       V4L2_PIX_FMT_NV21,
-};
-
 static inline struct vicodec_ctx *file2ctx(struct file *file)
 {
        return container_of(file->private_data, struct vicodec_ctx, fh);
@@ -152,156 +150,21 @@ static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx,
        return NULL;
 }
 
-static void encode(struct vicodec_ctx *ctx,
-                  struct vicodec_q_data *q_data,
-                  u8 *p_in, u8 *p_out)
-{
-       unsigned int size = q_data->width * q_data->height;
-       struct cframe_hdr *p_hdr;
-       struct cframe cf;
-       struct raw_frame rf;
-       u32 encoding;
-
-       rf.width = q_data->width;
-       rf.height = q_data->height;
-       rf.luma = p_in;
-
-       switch (q_data->fourcc) {
-       case V4L2_PIX_FMT_YUV420:
-               rf.cb = rf.luma + size;
-               rf.cr = rf.cb + size / 4;
-               rf.chroma_step = 1;
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               rf.cr = rf.luma + size;
-               rf.cb = rf.cr + size / 4;
-               rf.chroma_step = 1;
-               break;
-       case V4L2_PIX_FMT_NV12:
-               rf.cb = rf.luma + size;
-               rf.cr = rf.cb + 1;
-               rf.chroma_step = 2;
-               break;
-       case V4L2_PIX_FMT_NV21:
-               rf.cr = rf.luma + size;
-               rf.cb = rf.cr + 1;
-               rf.chroma_step = 2;
-               break;
-       }
-
-       cf.width = q_data->width;
-       cf.height = q_data->height;
-       cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr));
-
-       encoding = encode_frame(&rf, &ctx->ref_frame, &cf, !ctx->gop_cnt,
-                               ctx->gop_cnt == ctx->gop_size - 1);
-       if (encoding != FRAME_PCODED)
-               ctx->gop_cnt = 0;
-       if (++ctx->gop_cnt == ctx->gop_size)
-               ctx->gop_cnt = 0;
-
-       p_hdr = (struct cframe_hdr *)p_out;
-       p_hdr->magic1 = VICODEC_MAGIC1;
-       p_hdr->magic2 = VICODEC_MAGIC2;
-       p_hdr->version = htonl(VICODEC_VERSION);
-       p_hdr->width = htonl(cf.width);
-       p_hdr->height = htonl(cf.height);
-       p_hdr->flags = htonl(q_data->flags);
-       if (encoding & LUMA_UNENCODED)
-               p_hdr->flags |= htonl(VICODEC_FL_LUMA_IS_UNCOMPRESSED);
-       if (encoding & CB_UNENCODED)
-               p_hdr->flags |= htonl(VICODEC_FL_CB_IS_UNCOMPRESSED);
-       if (encoding & CR_UNENCODED)
-               p_hdr->flags |= htonl(VICODEC_FL_CR_IS_UNCOMPRESSED);
-       p_hdr->colorspace = htonl(ctx->colorspace);
-       p_hdr->xfer_func = htonl(ctx->xfer_func);
-       p_hdr->ycbcr_enc = htonl(ctx->ycbcr_enc);
-       p_hdr->quantization = htonl(ctx->quantization);
-       p_hdr->size = htonl(cf.size);
-       ctx->ref_frame.width = cf.width;
-       ctx->ref_frame.height = cf.height;
-}
-
-static int decode(struct vicodec_ctx *ctx,
-                 struct vicodec_q_data *q_data,
-                 u8 *p_in, u8 *p_out)
-{
-       unsigned int size = q_data->width * q_data->height;
-       unsigned int i;
-       struct cframe_hdr *p_hdr;
-       struct cframe cf;
-       u8 *p;
-
-       p_hdr = (struct cframe_hdr *)p_in;
-       cf.width = ntohl(p_hdr->width);
-       cf.height = ntohl(p_hdr->height);
-       q_data->flags = ntohl(p_hdr->flags);
-       ctx->colorspace = ntohl(p_hdr->colorspace);
-       ctx->xfer_func = ntohl(p_hdr->xfer_func);
-       ctx->ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
-       ctx->quantization = ntohl(p_hdr->quantization);
-       cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr));
-
-       if (p_hdr->magic1 != VICODEC_MAGIC1 ||
-           p_hdr->magic2 != VICODEC_MAGIC2 ||
-           ntohl(p_hdr->version) != VICODEC_VERSION ||
-           cf.width < VICODEC_MIN_WIDTH ||
-           cf.width > VICODEC_MAX_WIDTH ||
-           cf.height < VICODEC_MIN_HEIGHT ||
-           cf.height > VICODEC_MAX_HEIGHT ||
-           (cf.width & 7) || (cf.height & 7))
-               return -EINVAL;
-
-       /* TODO: support resolution changes */
-       if (cf.width != q_data->width || cf.height != q_data->height)
-               return -EINVAL;
-
-       decode_frame(&cf, &ctx->ref_frame, q_data->flags);
-       memcpy(p_out, ctx->ref_frame.luma, size);
-       p_out += size;
-
-       switch (q_data->fourcc) {
-       case V4L2_PIX_FMT_YUV420:
-               memcpy(p_out, ctx->ref_frame.cb, size / 4);
-               p_out += size / 4;
-               memcpy(p_out, ctx->ref_frame.cr, size / 4);
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               memcpy(p_out, ctx->ref_frame.cr, size / 4);
-               p_out += size / 4;
-               memcpy(p_out, ctx->ref_frame.cb, size / 4);
-               break;
-       case V4L2_PIX_FMT_NV12:
-               for (i = 0, p = p_out; i < size / 4; i++, p += 2)
-                       *p = ctx->ref_frame.cb[i];
-               for (i = 0, p = p_out + 1; i < size / 4; i++, p += 2)
-                       *p = ctx->ref_frame.cr[i];
-               break;
-       case V4L2_PIX_FMT_NV21:
-               for (i = 0, p = p_out; i < size / 4; i++, p += 2)
-                       *p = ctx->ref_frame.cr[i];
-               for (i = 0, p = p_out + 1; i < size / 4; i++, p += 2)
-                       *p = ctx->ref_frame.cb[i];
-               break;
-       }
-       return 0;
-}
-
 static int device_process(struct vicodec_ctx *ctx,
                          struct vb2_v4l2_buffer *in_vb,
                          struct vb2_v4l2_buffer *out_vb)
 {
        struct vicodec_dev *dev = ctx->dev;
-       struct vicodec_q_data *q_out, *q_cap;
+       struct vicodec_q_data *q_cap;
+       struct v4l2_fwht_state *state = &ctx->state;
        u8 *p_in, *p_out;
        int ret;
 
-       q_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
        q_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
        if (ctx->is_enc)
                p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0);
        else
-               p_in = ctx->compressed_frame;
+               p_in = state->compressed_frame;
        p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0);
        if (!p_in || !p_out) {
                v4l2_err(&dev->v4l2_dev,
@@ -310,17 +173,20 @@ static int device_process(struct vicodec_ctx *ctx,
        }
 
        if (ctx->is_enc) {
-               struct cframe_hdr *p_hdr = (struct cframe_hdr *)p_out;
+               struct vicodec_q_data *q_out;
 
-               encode(ctx, q_out, p_in, p_out);
-               vb2_set_plane_payload(&out_vb->vb2_buf, 0,
-                                     sizeof(*p_hdr) + ntohl(p_hdr->size));
+               q_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+               state->info = q_out->info;
+               ret = v4l2_fwht_encode(state, p_in, p_out);
+               if (ret < 0)
+                       return ret;
+               vb2_set_plane_payload(&out_vb->vb2_buf, 0, ret);
        } else {
-               ret = decode(ctx, q_cap, p_in, p_out);
-               if (ret)
+               state->info = q_cap->info;
+               ret = v4l2_fwht_decode(state, p_in, p_out);
+               if (ret < 0)
                        return ret;
-               vb2_set_plane_payload(&out_vb->vb2_buf, 0,
-                                     q_cap->width * q_cap->height * 3 / 2);
+               vb2_set_plane_payload(&out_vb->vb2_buf, 0, q_cap->sizeimage);
        }
 
        out_vb->sequence = q_cap->sequence++;
@@ -446,10 +312,11 @@ restart:
                        copy = sizeof(magic) - ctx->comp_magic_cnt;
                        if (p_out + sz - p < copy)
                                copy = p_out + sz - p;
-                       memcpy(ctx->compressed_frame + ctx->comp_magic_cnt,
+                       memcpy(ctx->state.compressed_frame + ctx->comp_magic_cnt,
                               p, copy);
                        ctx->comp_magic_cnt += copy;
-                       if (!memcmp(ctx->compressed_frame, magic, ctx->comp_magic_cnt)) {
+                       if (!memcmp(ctx->state.compressed_frame, magic,
+                                   ctx->comp_magic_cnt)) {
                                p += copy;
                                state = VB2_BUF_STATE_DONE;
                                break;
@@ -462,17 +329,18 @@ restart:
                }
                ctx->comp_size = sizeof(magic);
        }
-       if (ctx->comp_size < sizeof(struct cframe_hdr)) {
-               struct cframe_hdr *p_hdr = (struct cframe_hdr *)ctx->compressed_frame;
-               u32 copy = sizeof(struct cframe_hdr) - ctx->comp_size;
+       if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) {
+               struct fwht_cframe_hdr *p_hdr =
+                       (struct fwht_cframe_hdr *)ctx->state.compressed_frame;
+               u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->comp_size;
 
                if (copy > p_out + sz - p)
                        copy = p_out + sz - p;
-               memcpy(ctx->compressed_frame + ctx->comp_size,
+               memcpy(ctx->state.compressed_frame + ctx->comp_size,
                       p, copy);
                p += copy;
                ctx->comp_size += copy;
-               if (ctx->comp_size < sizeof(struct cframe_hdr)) {
+               if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) {
                        job_remove_out_buf(ctx, state);
                        goto restart;
                }
@@ -485,7 +353,7 @@ restart:
 
                if (copy > p_out + sz - p)
                        copy = p_out + sz - p;
-               memcpy(ctx->compressed_frame + ctx->comp_size,
+               memcpy(ctx->state.compressed_frame + ctx->comp_size,
                       p, copy);
                p += copy;
                ctx->comp_size += copy;
@@ -497,8 +365,8 @@ restart:
        ctx->cur_buf_offset = p - p_out;
        ctx->comp_has_frame = true;
        ctx->comp_has_next_frame = false;
-       if (sz - ctx->cur_buf_offset >= sizeof(struct cframe_hdr)) {
-               struct cframe_hdr *p_hdr = (struct cframe_hdr *)p;
+       if (sz - ctx->cur_buf_offset >= sizeof(struct fwht_cframe_hdr)) {
+               struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p;
                u32 frame_size = ntohl(p_hdr->size);
                u32 remaining = sz - ctx->cur_buf_offset - sizeof(*p_hdr);
 
@@ -508,26 +376,18 @@ restart:
        return 1;
 }
 
-static void job_abort(void *priv)
-{
-       struct vicodec_ctx *ctx = priv;
-
-       /* Will cancel the transaction in the next interrupt handler */
-       ctx->aborting = 1;
-}
-
 /*
  * video ioctls
  */
 
-static u32 find_fmt(u32 fmt)
+static const struct v4l2_fwht_pixfmt_info *find_fmt(u32 fmt)
 {
-       unsigned int i;
+       const struct v4l2_fwht_pixfmt_info *info =
+               v4l2_fwht_find_pixfmt(fmt);
 
-       for (i = 0; i < ARRAY_SIZE(pixfmts_yuv); i++)
-               if (pixfmts_yuv[i] == fmt)
-                       return fmt;
-       return pixfmts_yuv[0];
+       if (!info)
+               info = v4l2_fwht_get_pixfmt(0);
+       return info;
 }
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -547,19 +407,25 @@ static int vidioc_querycap(struct file *file, void *priv,
 
 static int enum_fmt(struct v4l2_fmtdesc *f, bool is_enc, bool is_out)
 {
-       bool is_yuv = (is_enc && is_out) || (!is_enc && !is_out);
+       bool is_uncomp = (is_enc && is_out) || (!is_enc && !is_out);
 
        if (V4L2_TYPE_IS_MULTIPLANAR(f->type) && !multiplanar)
                return -EINVAL;
        if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && multiplanar)
                return -EINVAL;
-       if (f->index >= (is_yuv ? ARRAY_SIZE(pixfmts_yuv) : 1))
-               return -EINVAL;
 
-       if (is_yuv)
-               f->pixelformat = pixfmts_yuv[f->index];
-       else
+       if (is_uncomp) {
+               const struct v4l2_fwht_pixfmt_info *info =
+                       v4l2_fwht_get_pixfmt(f->index);
+
+               if (!info)
+                       return -EINVAL;
+               f->pixelformat = info->id;
+       } else {
+               if (f->index)
+                       return -EINVAL;
                f->pixelformat = V4L2_PIX_FMT_FWHT;
+       }
        return 0;
 }
 
@@ -585,12 +451,14 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
        struct vicodec_q_data *q_data;
        struct v4l2_pix_format_mplane *pix_mp;
        struct v4l2_pix_format *pix;
+       const struct v4l2_fwht_pixfmt_info *info;
 
        vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
        if (!vq)
                return -EINVAL;
 
        q_data = get_q_data(ctx, f->type);
+       info = q_data->info;
 
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -601,16 +469,13 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
                pix->width = q_data->width;
                pix->height = q_data->height;
                pix->field = V4L2_FIELD_NONE;
-               pix->pixelformat = q_data->fourcc;
-               if (q_data->fourcc == V4L2_PIX_FMT_FWHT)
-                       pix->bytesperline = 0;
-               else
-                       pix->bytesperline = q_data->width;
+               pix->pixelformat = info->id;
+               pix->bytesperline = q_data->width * info->bytesperline_mult;
                pix->sizeimage = q_data->sizeimage;
-               pix->colorspace = ctx->colorspace;
-               pix->xfer_func = ctx->xfer_func;
-               pix->ycbcr_enc = ctx->ycbcr_enc;
-               pix->quantization = ctx->quantization;
+               pix->colorspace = ctx->state.colorspace;
+               pix->xfer_func = ctx->state.xfer_func;
+               pix->ycbcr_enc = ctx->state.ycbcr_enc;
+               pix->quantization = ctx->state.quantization;
                break;
 
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
@@ -621,17 +486,15 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
                pix_mp->width = q_data->width;
                pix_mp->height = q_data->height;
                pix_mp->field = V4L2_FIELD_NONE;
-               pix_mp->pixelformat = q_data->fourcc;
+               pix_mp->pixelformat = info->id;
                pix_mp->num_planes = 1;
-               if (q_data->fourcc == V4L2_PIX_FMT_FWHT)
-                       pix_mp->plane_fmt[0].bytesperline = 0;
-               else
-                       pix_mp->plane_fmt[0].bytesperline = q_data->width;
+               pix_mp->plane_fmt[0].bytesperline =
+                               q_data->width * info->bytesperline_mult;
                pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage;
-               pix_mp->colorspace = ctx->colorspace;
-               pix_mp->xfer_func = ctx->xfer_func;
-               pix_mp->ycbcr_enc = ctx->ycbcr_enc;
-               pix_mp->quantization = ctx->quantization;
+               pix_mp->colorspace = ctx->state.colorspace;
+               pix_mp->xfer_func = ctx->state.xfer_func;
+               pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
+               pix_mp->quantization = ctx->state.quantization;
                memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
                memset(pix_mp->plane_fmt[0].reserved, 0,
                       sizeof(pix_mp->plane_fmt[0].reserved));
@@ -658,40 +521,44 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
 {
        struct v4l2_pix_format_mplane *pix_mp;
        struct v4l2_pix_format *pix;
+       struct v4l2_plane_pix_format *plane;
+       const struct v4l2_fwht_pixfmt_info *info = &pixfmt_fwht;
 
        switch (f->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
                pix = &f->fmt.pix;
+               if (pix->pixelformat != V4L2_PIX_FMT_FWHT)
+                       info = find_fmt(pix->pixelformat);
                pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH) & ~7;
                pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT) & ~7;
-               pix->bytesperline = pix->width;
-               pix->sizeimage = pix->width * pix->height * 3 / 2;
                pix->field = V4L2_FIELD_NONE;
-               if (pix->pixelformat == V4L2_PIX_FMT_FWHT) {
-                       pix->bytesperline = 0;
-                       pix->sizeimage += sizeof(struct cframe_hdr);
-               }
+               pix->bytesperline =
+                       pix->width * info->bytesperline_mult;
+               pix->sizeimage = pix->width * pix->height *
+                       info->sizeimage_mult / info->sizeimage_div;
+               if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
+                       pix->sizeimage += sizeof(struct fwht_cframe_hdr);
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
                pix_mp = &f->fmt.pix_mp;
+               plane = pix_mp->plane_fmt;
+               if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT)
+                       info = find_fmt(pix_mp->pixelformat);
+               pix_mp->num_planes = 1;
                pix_mp->width = clamp(pix_mp->width, MIN_WIDTH, MAX_WIDTH) & ~7;
                pix_mp->height =
                        clamp(pix_mp->height, MIN_HEIGHT, MAX_HEIGHT) & ~7;
-               pix_mp->plane_fmt[0].bytesperline = pix_mp->width;
-               pix_mp->plane_fmt[0].sizeimage =
-                       pix_mp->width * pix_mp->height * 3 / 2;
                pix_mp->field = V4L2_FIELD_NONE;
-               pix_mp->num_planes = 1;
-               if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) {
-                       pix_mp->plane_fmt[0].bytesperline = 0;
-                       pix_mp->plane_fmt[0].sizeimage +=
-                                       sizeof(struct cframe_hdr);
-               }
+               plane->bytesperline =
+                       pix_mp->width * info->bytesperline_mult;
+               plane->sizeimage = pix_mp->width * pix_mp->height *
+                       info->sizeimage_mult / info->sizeimage_div;
+               if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
+                       plane->sizeimage += sizeof(struct fwht_cframe_hdr);
                memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
-               memset(pix_mp->plane_fmt[0].reserved, 0,
-                      sizeof(pix_mp->plane_fmt[0].reserved));
+               memset(plane->reserved, 0, sizeof(plane->reserved));
                break;
        default:
                return -EINVAL;
@@ -713,25 +580,22 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
                        return -EINVAL;
                pix = &f->fmt.pix;
                pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-                                  find_fmt(f->fmt.pix.pixelformat);
-               pix->colorspace = ctx->colorspace;
-               pix->xfer_func = ctx->xfer_func;
-               pix->ycbcr_enc = ctx->ycbcr_enc;
-               pix->quantization = ctx->quantization;
+                                  find_fmt(f->fmt.pix.pixelformat)->id;
+               pix->colorspace = ctx->state.colorspace;
+               pix->xfer_func = ctx->state.xfer_func;
+               pix->ycbcr_enc = ctx->state.ycbcr_enc;
+               pix->quantization = ctx->state.quantization;
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                if (!multiplanar)
                        return -EINVAL;
                pix_mp = &f->fmt.pix_mp;
                pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-                                     find_fmt(pix_mp->pixelformat);
-               pix_mp->colorspace = ctx->colorspace;
-               pix_mp->xfer_func = ctx->xfer_func;
-               pix_mp->ycbcr_enc = ctx->ycbcr_enc;
-               pix_mp->quantization = ctx->quantization;
-               memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
-               memset(pix_mp->plane_fmt[0].reserved, 0,
-                      sizeof(pix_mp->plane_fmt[0].reserved));
+                                     find_fmt(pix_mp->pixelformat)->id;
+               pix_mp->colorspace = ctx->state.colorspace;
+               pix_mp->xfer_func = ctx->state.xfer_func;
+               pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
+               pix_mp->quantization = ctx->state.quantization;
                break;
        default:
                return -EINVAL;
@@ -753,7 +617,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
                        return -EINVAL;
                pix = &f->fmt.pix;
                pix->pixelformat = !ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-                                  find_fmt(pix->pixelformat);
+                                  find_fmt(pix->pixelformat)->id;
                if (!pix->colorspace)
                        pix->colorspace = V4L2_COLORSPACE_REC709;
                break;
@@ -762,7 +626,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
                        return -EINVAL;
                pix_mp = &f->fmt.pix_mp;
                pix_mp->pixelformat = !ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-                                     find_fmt(pix_mp->pixelformat);
+                                     find_fmt(pix_mp->pixelformat)->id;
                if (!pix_mp->colorspace)
                        pix_mp->colorspace = V4L2_COLORSPACE_REC709;
                break;
@@ -795,14 +659,17 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
                pix = &f->fmt.pix;
                if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
                        fmt_changed =
-                               q_data->fourcc != pix->pixelformat ||
+                               q_data->info->id != pix->pixelformat ||
                                q_data->width != pix->width ||
                                q_data->height != pix->height;
 
                if (vb2_is_busy(vq) && fmt_changed)
                        return -EBUSY;
 
-               q_data->fourcc = pix->pixelformat;
+               if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
+                       q_data->info = &pixfmt_fwht;
+               else
+                       q_data->info = find_fmt(pix->pixelformat);
                q_data->width = pix->width;
                q_data->height = pix->height;
                q_data->sizeimage = pix->sizeimage;
@@ -812,14 +679,17 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
                pix_mp = &f->fmt.pix_mp;
                if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
                        fmt_changed =
-                               q_data->fourcc != pix_mp->pixelformat ||
+                               q_data->info->id != pix_mp->pixelformat ||
                                q_data->width != pix_mp->width ||
                                q_data->height != pix_mp->height;
 
                if (vb2_is_busy(vq) && fmt_changed)
                        return -EBUSY;
 
-               q_data->fourcc = pix_mp->pixelformat;
+               if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
+                       q_data->info = &pixfmt_fwht;
+               else
+                       q_data->info = find_fmt(pix_mp->pixelformat);
                q_data->width = pix_mp->width;
                q_data->height = pix_mp->height;
                q_data->sizeimage = pix_mp->plane_fmt[0].sizeimage;
@@ -830,7 +700,7 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
 
        dprintk(ctx->dev,
                "Setting format for type %d, wxh: %dx%d, fourcc: %08x\n",
-               f->type, q_data->width, q_data->height, q_data->fourcc);
+               f->type, q_data->width, q_data->height, q_data->info->id);
 
        return 0;
 }
@@ -865,18 +735,18 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                case V4L2_BUF_TYPE_VIDEO_OUTPUT:
                        pix = &f->fmt.pix;
-                       ctx->colorspace = pix->colorspace;
-                       ctx->xfer_func = pix->xfer_func;
-                       ctx->ycbcr_enc = pix->ycbcr_enc;
-                       ctx->quantization = pix->quantization;
+                       ctx->state.colorspace = pix->colorspace;
+                       ctx->state.xfer_func = pix->xfer_func;
+                       ctx->state.ycbcr_enc = pix->ycbcr_enc;
+                       ctx->state.quantization = pix->quantization;
                        break;
                case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
                        pix_mp = &f->fmt.pix_mp;
-                       ctx->colorspace = pix_mp->colorspace;
-                       ctx->xfer_func = pix_mp->xfer_func;
-                       ctx->ycbcr_enc = pix_mp->ycbcr_enc;
-                       ctx->quantization = pix_mp->quantization;
+                       ctx->state.colorspace = pix_mp->colorspace;
+                       ctx->state.xfer_func = pix_mp->xfer_func;
+                       ctx->state.ycbcr_enc = pix_mp->ycbcr_enc;
+                       ctx->state.quantization = pix_mp->quantization;
                        break;
                default:
                        break;
@@ -962,7 +832,7 @@ static int vicodec_enum_framesizes(struct file *file, void *fh,
        case V4L2_PIX_FMT_FWHT:
                break;
        default:
-               if (find_fmt(fsize->pixel_format) == fsize->pixel_format)
+               if (find_fmt(fsize->pixel_format)->id == fsize->pixel_format)
                        break;
                return -EINVAL;
        }
@@ -1119,30 +989,35 @@ static int vicodec_start_streaming(struct vb2_queue *q,
 {
        struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
        struct vicodec_q_data *q_data = get_q_data(ctx, q->type);
+       struct v4l2_fwht_state *state = &ctx->state;
        unsigned int size = q_data->width * q_data->height;
+       const struct v4l2_fwht_pixfmt_info *info = q_data->info;
+       unsigned int chroma_div = info->width_div * info->height_div;
 
        q_data->sequence = 0;
 
        if (!V4L2_TYPE_IS_OUTPUT(q->type))
                return 0;
 
-       ctx->ref_frame.width = ctx->ref_frame.height = 0;
-       ctx->ref_frame.luma = kvmalloc(size * 3 / 2, GFP_KERNEL);
-       ctx->comp_max_size = size * 3 / 2 + sizeof(struct cframe_hdr);
-       ctx->compressed_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
-       if (!ctx->ref_frame.luma || !ctx->compressed_frame) {
-               kvfree(ctx->ref_frame.luma);
-               kvfree(ctx->compressed_frame);
+       state->width = q_data->width;
+       state->height = q_data->height;
+       state->ref_frame.width = state->ref_frame.height = 0;
+       state->ref_frame.luma = kvmalloc(size + 2 * size / chroma_div,
+                                        GFP_KERNEL);
+       ctx->comp_max_size = size + 2 * size / chroma_div +
+                            sizeof(struct fwht_cframe_hdr);
+       state->compressed_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
+       if (!state->ref_frame.luma || !state->compressed_frame) {
+               kvfree(state->ref_frame.luma);
+               kvfree(state->compressed_frame);
                vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
                return -ENOMEM;
        }
-       ctx->ref_frame.cb = ctx->ref_frame.luma + size;
-       ctx->ref_frame.cr = ctx->ref_frame.cb + size / 4;
+       state->ref_frame.cb = state->ref_frame.luma + size;
+       state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
        ctx->last_src_buf = NULL;
        ctx->last_dst_buf = NULL;
-       v4l2_ctrl_grab(ctx->ctrl_gop_size, true);
-       ctx->gop_size = v4l2_ctrl_g_ctrl(ctx->ctrl_gop_size);
-       ctx->gop_cnt = 0;
+       state->gop_cnt = 0;
        ctx->cur_buf_offset = 0;
        ctx->comp_size = 0;
        ctx->comp_magic_cnt = 0;
@@ -1160,9 +1035,8 @@ static void vicodec_stop_streaming(struct vb2_queue *q)
        if (!V4L2_TYPE_IS_OUTPUT(q->type))
                return;
 
-       kvfree(ctx->ref_frame.luma);
-       kvfree(ctx->compressed_frame);
-       v4l2_ctrl_grab(ctx->ctrl_gop_size, false);
+       kvfree(ctx->state.ref_frame.luma);
+       kvfree(ctx->state.compressed_frame);
 }
 
 static const struct vb2_ops vicodec_qops = {
@@ -1211,6 +1085,55 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        return vb2_queue_init(dst_vq);
 }
 
+#define VICODEC_CID_CUSTOM_BASE                (V4L2_CID_MPEG_BASE | 0xf000)
+#define VICODEC_CID_I_FRAME_QP         (VICODEC_CID_CUSTOM_BASE + 0)
+#define VICODEC_CID_P_FRAME_QP         (VICODEC_CID_CUSTOM_BASE + 1)
+
+static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct vicodec_ctx *ctx = container_of(ctrl->handler,
+                                              struct vicodec_ctx, hdl);
+
+       switch (ctrl->id) {
+       case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+               ctx->state.gop_size = ctrl->val;
+               return 0;
+       case VICODEC_CID_I_FRAME_QP:
+               ctx->state.i_frame_qp = ctrl->val;
+               return 0;
+       case VICODEC_CID_P_FRAME_QP:
+               ctx->state.p_frame_qp = ctrl->val;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct v4l2_ctrl_ops vicodec_ctrl_ops = {
+       .s_ctrl = vicodec_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config vicodec_ctrl_i_frame = {
+       .ops = &vicodec_ctrl_ops,
+       .id = VICODEC_CID_I_FRAME_QP,
+       .name = "FWHT I-Frame QP Value",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .min = 1,
+       .max = 31,
+       .def = 20,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config vicodec_ctrl_p_frame = {
+       .ops = &vicodec_ctrl_ops,
+       .id = VICODEC_CID_P_FRAME_QP,
+       .name = "FWHT P-Frame QP Value",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .min = 1,
+       .max = 31,
+       .def = 20,
+       .step = 1,
+};
+
 /*
  * File operations
  */
@@ -1239,9 +1162,10 @@ static int vicodec_open(struct file *file)
        ctx->dev = dev;
        hdl = &ctx->hdl;
        v4l2_ctrl_handler_init(hdl, 4);
-       ctx->ctrl_gop_size = v4l2_ctrl_new_std(hdl, NULL,
-                                              V4L2_CID_MPEG_VIDEO_GOP_SIZE,
-                                              1, 16, 1, 10);
+       v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+                         1, 16, 1, 10);
+       v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_i_frame, NULL);
+       v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_p_frame, NULL);
        if (hdl->error) {
                rc = hdl->error;
                v4l2_ctrl_handler_free(hdl);
@@ -1251,25 +1175,34 @@ static int vicodec_open(struct file *file)
        ctx->fh.ctrl_handler = hdl;
        v4l2_ctrl_handler_setup(hdl);
 
-       ctx->q_data[V4L2_M2M_SRC].fourcc =
-               ctx->is_enc ? V4L2_PIX_FMT_YUV420 : V4L2_PIX_FMT_FWHT;
+       ctx->q_data[V4L2_M2M_SRC].info =
+               ctx->is_enc ? v4l2_fwht_get_pixfmt(0) : &pixfmt_fwht;
        ctx->q_data[V4L2_M2M_SRC].width = 1280;
        ctx->q_data[V4L2_M2M_SRC].height = 720;
-       size = 1280 * 720 * 3 / 2;
-       ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
+       size = 1280 * 720 * ctx->q_data[V4L2_M2M_SRC].info->sizeimage_mult /
+               ctx->q_data[V4L2_M2M_SRC].info->sizeimage_div;
+       if (ctx->is_enc)
+               ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
+       else
+               ctx->q_data[V4L2_M2M_SRC].sizeimage =
+                       size + sizeof(struct fwht_cframe_hdr);
        ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
-       ctx->q_data[V4L2_M2M_DST].fourcc =
-               ctx->is_enc ? V4L2_PIX_FMT_FWHT : V4L2_PIX_FMT_YUV420;
-       ctx->colorspace = V4L2_COLORSPACE_REC709;
+       ctx->q_data[V4L2_M2M_DST].info =
+               ctx->is_enc ? &pixfmt_fwht : v4l2_fwht_get_pixfmt(0);
+       size = 1280 * 720 * ctx->q_data[V4L2_M2M_DST].info->sizeimage_mult /
+               ctx->q_data[V4L2_M2M_DST].info->sizeimage_div;
+       if (ctx->is_enc)
+               ctx->q_data[V4L2_M2M_DST].sizeimage =
+                       size + sizeof(struct fwht_cframe_hdr);
+       else
+               ctx->q_data[V4L2_M2M_DST].sizeimage = size;
+       ctx->state.colorspace = V4L2_COLORSPACE_REC709;
 
-       size += sizeof(struct cframe_hdr);
        if (ctx->is_enc) {
-               ctx->q_data[V4L2_M2M_DST].sizeimage = size;
                ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->enc_dev, ctx,
                                                    &queue_init);
                ctx->lock = &dev->enc_lock;
        } else {
-               ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
                ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->dec_dev, ctx,
                                                    &queue_init);
                ctx->lock = &dev->dec_lock;
@@ -1327,7 +1260,6 @@ static const struct video_device vicodec_videodev = {
 
 static const struct v4l2_m2m_ops m2m_ops = {
        .device_run     = device_run,
-       .job_abort      = job_abort,
        .job_ready      = job_ready,
 };
 
@@ -1350,7 +1282,7 @@ static int vicodec_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
        dev->mdev.dev = &pdev->dev;
-       strlcpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model));
+       strscpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model));
        media_device_init(&dev->mdev);
        dev->v4l2_dev.mdev = &dev->mdev;
 #endif
@@ -1378,7 +1310,7 @@ static int vicodec_probe(struct platform_device *pdev)
        vfd = &dev->enc_vfd;
        vfd->lock = &dev->enc_mutex;
        vfd->v4l2_dev = &dev->v4l2_dev;
-       strlcpy(vfd->name, "vicodec-enc", sizeof(vfd->name));
+       strscpy(vfd->name, "vicodec-enc", sizeof(vfd->name));
        v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
        v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
        video_set_drvdata(vfd, dev);
@@ -1395,7 +1327,7 @@ static int vicodec_probe(struct platform_device *pdev)
        vfd = &dev->dec_vfd;
        vfd->lock = &dev->dec_mutex;
        vfd->v4l2_dev = &dev->v4l2_dev;
-       strlcpy(vfd->name, "vicodec-dec", sizeof(vfd->name));
+       strscpy(vfd->name, "vicodec-dec", sizeof(vfd->name));
        v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
        v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
        video_set_drvdata(vfd, dev);
index c01e1592ad0a8f7d52614bb81d4bc768b5459f2e..c33900e3c23ef4472374a0678eb175e6668d349a 100644 (file)
 #include <linux/of.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
 
 struct video_mux {
@@ -316,6 +318,38 @@ static const struct v4l2_subdev_ops video_mux_subdev_ops = {
        .video = &video_mux_subdev_video_ops,
 };
 
+static int video_mux_parse_endpoint(struct device *dev,
+                                   struct v4l2_fwnode_endpoint *vep,
+                                   struct v4l2_async_subdev *asd)
+{
+       /*
+        * it's not an error if remote is missing on a video-mux
+        * input port, return -ENOTCONN to skip this endpoint with
+        * no error.
+        */
+       return fwnode_device_is_available(asd->match.fwnode) ? 0 : -ENOTCONN;
+}
+
+static int video_mux_async_register(struct video_mux *vmux,
+                                   unsigned int num_input_pads)
+{
+       unsigned int i, *ports;
+       int ret;
+
+       ports = kcalloc(num_input_pads, sizeof(*ports), GFP_KERNEL);
+       if (!ports)
+               return -ENOMEM;
+       for (i = 0; i < num_input_pads; i++)
+               ports[i] = i;
+
+       ret = v4l2_async_register_fwnode_subdev(
+               &vmux->subdev, sizeof(struct v4l2_async_subdev),
+               ports, num_input_pads, video_mux_parse_endpoint);
+
+       kfree(ports);
+       return ret;
+}
+
 static int video_mux_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -333,7 +367,7 @@ static int video_mux_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, vmux);
 
        v4l2_subdev_init(&vmux->subdev, &video_mux_subdev_ops);
-       snprintf(vmux->subdev.name, sizeof(vmux->subdev.name), "%s", np->name);
+       snprintf(vmux->subdev.name, sizeof(vmux->subdev.name), "%pOFn", np);
        vmux->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
        vmux->subdev.dev = dev;
 
@@ -383,7 +417,7 @@ static int video_mux_probe(struct platform_device *pdev)
 
        vmux->subdev.entity.ops = &video_mux_ops;
 
-       return v4l2_async_register_subdev(&vmux->subdev);
+       return video_mux_async_register(vmux, num_pads - 1);
 }
 
 static int video_mux_remove(struct platform_device *pdev)
index 462099a141e4aaae2da52bedad20d94b5197d554..af150a0395dfb55ef55bf606df4825ec5b807912 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This is a virtual device driver for testing mem-to-mem videobuf framework.
  * It simulates a device that uses memory buffers for both source and
- * destination, processes the data and issues an "irq" (simulated by a timer).
+ * destination, processes the data and issues an "irq" (simulated by a delayed
+ * workqueue).
  * The device is capable of multi-instance, multi-buffer-per-transaction
  * operation (via the mem2mem framework).
  *
@@ -19,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
-#include <linux/timer.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 
@@ -148,7 +148,7 @@ struct vim2m_dev {
        struct mutex            dev_mutex;
        spinlock_t              irqlock;
 
-       struct timer_list       timer;
+       struct delayed_work     work_run;
 
        struct v4l2_m2m_dev     *m2m_dev;
 };
@@ -336,12 +336,6 @@ static int device_process(struct vim2m_ctx *ctx,
        return 0;
 }
 
-static void schedule_irq(struct vim2m_dev *dev, int msec_timeout)
-{
-       dprintk(dev, "Scheduling a simulated irq\n");
-       mod_timer(&dev->timer, jiffies + msecs_to_jiffies(msec_timeout));
-}
-
 /*
  * mem2mem callbacks
  */
@@ -385,15 +379,24 @@ static void device_run(void *priv)
        src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
        dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
+       /* Apply request controls if any */
+       v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
+                               &ctx->hdl);
+
        device_process(ctx, src_buf, dst_buf);
 
-       /* Run a timer, which simulates a hardware irq  */
-       schedule_irq(dev, ctx->transtime);
+       /* Complete request controls if any */
+       v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
+                                  &ctx->hdl);
+
+       /* Run delayed work, which simulates a hardware irq  */
+       schedule_delayed_work(&dev->work_run, msecs_to_jiffies(ctx->transtime));
 }
 
-static void device_isr(struct timer_list *t)
+static void device_work(struct work_struct *w)
 {
-       struct vim2m_dev *vim2m_dev = from_timer(vim2m_dev, t, timer);
+       struct vim2m_dev *vim2m_dev =
+               container_of(w, struct vim2m_dev, work_run.work);
        struct vim2m_ctx *curr_ctx;
        struct vb2_v4l2_buffer *src_vb, *dst_vb;
        unsigned long flags;
@@ -805,6 +808,7 @@ static void vim2m_stop_streaming(struct vb2_queue *q)
        struct vb2_v4l2_buffer *vbuf;
        unsigned long flags;
 
+       flush_scheduled_work();
        for (;;) {
                if (V4L2_TYPE_IS_OUTPUT(q->type))
                        vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
@@ -812,12 +816,21 @@ static void vim2m_stop_streaming(struct vb2_queue *q)
                        vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
                if (vbuf == NULL)
                        return;
+               v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
+                                          &ctx->hdl);
                spin_lock_irqsave(&ctx->dev->irqlock, flags);
                v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
                spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
        }
 }
 
+static void vim2m_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
+}
+
 static const struct vb2_ops vim2m_qops = {
        .queue_setup     = vim2m_queue_setup,
        .buf_prepare     = vim2m_buf_prepare,
@@ -826,6 +839,7 @@ static const struct vb2_ops vim2m_qops = {
        .stop_streaming  = vim2m_stop_streaming,
        .wait_prepare    = vb2_ops_wait_prepare,
        .wait_finish     = vb2_ops_wait_finish,
+       .buf_request_complete = vim2m_buf_request_complete,
 };
 
 static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
@@ -841,6 +855,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
        src_vq->mem_ops = &vb2_vmalloc_memops;
        src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
        src_vq->lock = &ctx->dev->dev_mutex;
+       src_vq->supports_requests = true;
 
        ret = vb2_queue_init(src_vq);
        if (ret)
@@ -992,6 +1007,11 @@ static const struct v4l2_m2m_ops m2m_ops = {
        .job_abort      = job_abort,
 };
 
+static const struct media_device_ops m2m_media_ops = {
+       .req_validate = vb2_request_validate,
+       .req_queue = vb2_m2m_request_queue,
+};
+
 static int vim2m_probe(struct platform_device *pdev)
 {
        struct vim2m_dev *dev;
@@ -1015,6 +1035,7 @@ static int vim2m_probe(struct platform_device *pdev)
        vfd = &dev->vfd;
        vfd->lock = &dev->dev_mutex;
        vfd->v4l2_dev = &dev->v4l2_dev;
+       INIT_DELAYED_WORK(&dev->work_run, device_work);
 
        ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
        if (ret) {
@@ -1026,7 +1047,6 @@ static int vim2m_probe(struct platform_device *pdev)
        v4l2_info(&dev->v4l2_dev,
                        "Device registered as /dev/video%d\n", vfd->num);
 
-       timer_setup(&dev->timer, device_isr, 0);
        platform_set_drvdata(pdev, dev);
 
        dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
@@ -1038,8 +1058,9 @@ static int vim2m_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
        dev->mdev.dev = &pdev->dev;
-       strlcpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+       strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
        media_device_init(&dev->mdev);
+       dev->mdev.ops = &m2m_media_ops;
        dev->v4l2_dev.mdev = &dev->mdev;
 
        ret = v4l2_m2m_register_media_controller(dev->m2m_dev,
@@ -1083,7 +1104,6 @@ static int vim2m_remove(struct platform_device *pdev)
        media_device_cleanup(&dev->mdev);
 #endif
        v4l2_m2m_release(dev->m2m_dev);
-       del_timer_sync(&dev->timer);
        video_unregister_device(&dev->vfd);
        v4l2_device_unregister(&dev->v4l2_dev);
 
index ec68feaac3784242aacae61852fdb0cf0c19cf17..3f7e9ed5663376dfeac8c767875f94ec8535b1f6 100644 (file)
@@ -71,8 +71,8 @@ static int vimc_cap_querycap(struct file *file, void *priv,
 {
        struct vimc_cap_device *vcap = video_drvdata(file);
 
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "platform:%s", vcap->vdev.v4l2_dev->name);
 
@@ -476,7 +476,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
        vdev->queue = q;
        vdev->v4l2_dev = v4l2_dev;
        vdev->vfl_dir = VFL_DIR_RX;
-       strlcpy(vdev->name, pdata->entity_name, sizeof(vdev->name));
+       strscpy(vdev->name, pdata->entity_name, sizeof(vdev->name));
        video_set_drvdata(vdev, &vcap->ved);
 
        /* Register the video_device with the v4l2 and the media framework */
index 617415c224fe4943fc1308d9bc3d0be55997f45e..dee1b9dfc4f64ba3a274c8775ad9531a3fa332b4 100644 (file)
@@ -430,7 +430,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
        sd->entity.function = function;
        sd->entity.ops = &vimc_ent_sd_mops;
        sd->owner = THIS_MODULE;
-       strlcpy(sd->name, name, sizeof(sd->name));
+       strscpy(sd->name, name, sizeof(sd->name));
        v4l2_set_subdevdata(sd, ved);
 
        /* Expose this subdev to user space */
index 9246f265de31b920f2181efe1f305c8b85c66cf4..ce809d2e3d5370e02dc6533f91f0dfb0df0f7370 100644 (file)
@@ -259,7 +259,7 @@ static struct component_match *vimc_add_subdevs(struct vimc_device *vimc)
                dev_dbg(&vimc->pdev.dev, "new pdev for %s\n",
                        vimc->pipe_cfg->ents[i].drv);
 
-               strlcpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name,
+               strscpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name,
                        sizeof(pdata.entity_name));
 
                vimc->subdevs[i] = platform_device_register_data(&vimc->pdev.dev,
@@ -317,7 +317,7 @@ static int vimc_probe(struct platform_device *pdev)
        vimc->v4l2_dev.mdev = &vimc->mdev;
 
        /* Initialize media device */
-       strlcpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
+       strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
                sizeof(vimc->mdev.model));
        vimc->mdev.dev = &pdev->dev;
        media_device_init(&vimc->mdev);
index b2b89315e7ba566fecf71f0811e1e30f0b3c6b51..edf4c85ae63db7875ab8808614bd01f10ba1794e 100644 (file)
@@ -317,6 +317,18 @@ static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
        case V4L2_CID_VFLIP:
                tpg_s_vflip(&vsen->tpg, ctrl->val);
                break;
+       case V4L2_CID_BRIGHTNESS:
+               tpg_s_brightness(&vsen->tpg, ctrl->val);
+               break;
+       case V4L2_CID_CONTRAST:
+               tpg_s_contrast(&vsen->tpg, ctrl->val);
+               break;
+       case V4L2_CID_HUE:
+               tpg_s_hue(&vsen->tpg, ctrl->val);
+               break;
+       case V4L2_CID_SATURATION:
+               tpg_s_saturation(&vsen->tpg, ctrl->val);
+               break;
        default:
                return -EINVAL;
        }
@@ -378,6 +390,14 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
                          V4L2_CID_VFLIP, 0, 1, 1, 0);
        v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
                          V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
+       v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+                         V4L2_CID_CONTRAST, 0, 255, 1, 128);
+       v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+                         V4L2_CID_HUE, -128, 127, 1, 0);
+       v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+                         V4L2_CID_SATURATION, 0, 255, 1, 128);
        vsen->sd.ctrl_handler = &vsen->hdl;
        if (vsen->hdl.error) {
                ret = vsen->hdl.error;
index 71105fa4c5f91a8cc2dfe97cc49af21c2152be84..4d822dbed97260f3e97309c7882f5bf77788f125 100644 (file)
@@ -241,11 +241,11 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
                cec_ops_set_osd_string(msg, &disp_ctl, osd);
                switch (disp_ctl) {
                case CEC_OP_DISP_CTL_DEFAULT:
-                       strcpy(dev->osd, osd);
+                       strscpy(dev->osd, osd, sizeof(dev->osd));
                        dev->osd_jiffies = jiffies;
                        break;
                case CEC_OP_DISP_CTL_UNTIL_CLEARED:
-                       strcpy(dev->osd, osd);
+                       strscpy(dev->osd, osd, sizeof(dev->osd));
                        dev->osd_jiffies = 0;
                        break;
                case CEC_OP_DISP_CTL_CLEAR:
index 31db363602e5313e88d253f1fb77b9b06652efd9..626e2b24a4033e224e09e195760f3cee9373a074 100644 (file)
@@ -197,8 +197,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
        struct vivid_dev *dev = video_drvdata(file);
 
-       strcpy(cap->driver, "vivid");
-       strcpy(cap->card, "vivid");
+       strscpy(cap->driver, "vivid", sizeof(cap->driver));
+       strscpy(cap->card, "vivid", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                        "platform:%s", dev->v4l2_dev.name);
 
@@ -627,6 +627,13 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev)
        kfree(dev);
 }
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+static const struct media_device_ops vivid_media_ops = {
+       .req_validate = vb2_request_validate,
+       .req_queue = vb2_request_queue,
+};
+#endif
+
 static int vivid_create_instance(struct platform_device *pdev, int inst)
 {
        static const struct v4l2_dv_timings def_dv_timings =
@@ -657,6 +664,16 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 
        dev->inst = inst;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+       dev->v4l2_dev.mdev = &dev->mdev;
+
+       /* Initialize media device */
+       strlcpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model));
+       dev->mdev.dev = &pdev->dev;
+       media_device_init(&dev->mdev);
+       dev->mdev.ops = &vivid_media_ops;
+#endif
+
        /* register v4l2_device */
        snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
                        "%s-%03d", VIVID_MODULE_NAME, inst);
@@ -1060,6 +1077,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
                q->dev = dev->v4l2_dev.dev;
+               q->supports_requests = true;
 
                ret = vb2_queue_init(q);
                if (ret)
@@ -1080,6 +1098,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
                q->dev = dev->v4l2_dev.dev;
+               q->supports_requests = true;
 
                ret = vb2_queue_init(q);
                if (ret)
@@ -1100,6 +1119,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
                q->dev = dev->v4l2_dev.dev;
+               q->supports_requests = true;
 
                ret = vb2_queue_init(q);
                if (ret)
@@ -1120,6 +1140,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                q->min_buffers_needed = 2;
                q->lock = &dev->mutex;
                q->dev = dev->v4l2_dev.dev;
+               q->supports_requests = true;
 
                ret = vb2_queue_init(q);
                if (ret)
@@ -1139,6 +1160,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                q->min_buffers_needed = 8;
                q->lock = &dev->mutex;
                q->dev = dev->v4l2_dev.dev;
+               q->supports_requests = true;
 
                ret = vb2_queue_init(q);
                if (ret)
@@ -1174,6 +1196,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                vfd->lock = &dev->mutex;
                video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+               dev->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
+               ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_cap_pad);
+               if (ret)
+                       goto unreg_dev;
+#endif
+
 #ifdef CONFIG_VIDEO_VIVID_CEC
                if (in_type_counter[HDMI]) {
                        struct cec_adapter *adap;
@@ -1226,6 +1255,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                vfd->lock = &dev->mutex;
                video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+               dev->vid_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+               ret = media_entity_pads_init(&vfd->entity, 1, &dev->vid_out_pad);
+               if (ret)
+                       goto unreg_dev;
+#endif
+
 #ifdef CONFIG_VIDEO_VIVID_CEC
                for (i = 0; i < dev->num_outputs; i++) {
                        struct cec_adapter *adap;
@@ -1275,6 +1311,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                vfd->tvnorms = tvnorms_cap;
                video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+               dev->vbi_cap_pad.flags = MEDIA_PAD_FL_SINK;
+               ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_cap_pad);
+               if (ret)
+                       goto unreg_dev;
+#endif
+
                ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_cap_nr[inst]);
                if (ret < 0)
                        goto unreg_dev;
@@ -1300,6 +1343,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                vfd->tvnorms = tvnorms_out;
                video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+               dev->vbi_out_pad.flags = MEDIA_PAD_FL_SOURCE;
+               ret = media_entity_pads_init(&vfd->entity, 1, &dev->vbi_out_pad);
+               if (ret)
+                       goto unreg_dev;
+#endif
+
                ret = video_register_device(vfd, VFL_TYPE_VBI, vbi_out_nr[inst]);
                if (ret < 0)
                        goto unreg_dev;
@@ -1323,6 +1373,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                vfd->lock = &dev->mutex;
                video_set_drvdata(vfd, dev);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+               dev->sdr_cap_pad.flags = MEDIA_PAD_FL_SINK;
+               ret = media_entity_pads_init(&vfd->entity, 1, &dev->sdr_cap_pad);
+               if (ret)
+                       goto unreg_dev;
+#endif
+
                ret = video_register_device(vfd, VFL_TYPE_SDR, sdr_cap_nr[inst]);
                if (ret < 0)
                        goto unreg_dev;
@@ -1369,12 +1426,25 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
                                          video_device_node_name(vfd));
        }
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+       /* Register the media device */
+       ret = media_device_register(&dev->mdev);
+       if (ret) {
+               dev_err(dev->mdev.dev,
+                       "media device register failed (err=%d)\n", ret);
+               goto unreg_dev;
+       }
+#endif
+
        /* Now that everything is fine, let's add it to device list */
        vivid_devs[inst] = dev;
 
        return 0;
 
 unreg_dev:
+#ifdef CONFIG_MEDIA_CONTROLLER
+       media_device_unregister(&dev->mdev);
+#endif
        video_unregister_device(&dev->radio_tx_dev);
        video_unregister_device(&dev->radio_rx_dev);
        video_unregister_device(&dev->sdr_cap_dev);
@@ -1445,6 +1515,10 @@ static int vivid_remove(struct platform_device *pdev)
                if (!dev)
                        continue;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+               media_device_unregister(&dev->mdev);
+#endif
+
                if (dev->has_vid_cap) {
                        v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
                                video_device_node_name(&dev->vid_cap_dev));
index 477c80a4d44c00ab105bd45ade343b2565d9e9f4..1891254c8f0b22dee4565a579ad32a4da62c00d7 100644 (file)
@@ -111,7 +111,7 @@ enum vivid_colorspace {
        VIVID_CS_170M,
        VIVID_CS_709,
        VIVID_CS_SRGB,
-       VIVID_CS_ADOBERGB,
+       VIVID_CS_OPRGB,
        VIVID_CS_2020,
        VIVID_CS_DCI_P3,
        VIVID_CS_240M,
@@ -136,6 +136,14 @@ struct vivid_cec_work {
 struct vivid_dev {
        unsigned                        inst;
        struct v4l2_device              v4l2_dev;
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_device             mdev;
+       struct media_pad                vid_cap_pad;
+       struct media_pad                vid_out_pad;
+       struct media_pad                vbi_cap_pad;
+       struct media_pad                vbi_out_pad;
+       struct media_pad                sdr_cap_pad;
+#endif
        struct v4l2_ctrl_handler        ctrl_hdl_user_gen;
        struct v4l2_ctrl_handler        ctrl_hdl_user_vid;
        struct v4l2_ctrl_handler        ctrl_hdl_user_aud;
index 5429193fbb91d09dfa158d7d69537a1bb02b24b2..bfffeda12f1410455892104cac9911ba4cb50b1e 100644 (file)
@@ -348,7 +348,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
                V4L2_COLORSPACE_SMPTE170M,
                V4L2_COLORSPACE_REC709,
                V4L2_COLORSPACE_SRGB,
-               V4L2_COLORSPACE_ADOBERGB,
+               V4L2_COLORSPACE_OPRGB,
                V4L2_COLORSPACE_BT2020,
                V4L2_COLORSPACE_DCI_P3,
                V4L2_COLORSPACE_SMPTE240M,
@@ -729,7 +729,7 @@ static const char * const vivid_ctrl_colorspace_strings[] = {
        "SMPTE 170M",
        "Rec. 709",
        "sRGB",
-       "AdobeRGB",
+       "opRGB",
        "BT.2020",
        "DCI-P3",
        "SMPTE 240M",
@@ -752,7 +752,7 @@ static const char * const vivid_ctrl_xfer_func_strings[] = {
        "Default",
        "Rec. 709",
        "sRGB",
-       "AdobeRGB",
+       "opRGB",
        "SMPTE 240M",
        "None",
        "DCI-P3",
@@ -1662,59 +1662,59 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
                v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
 
        if (dev->has_vid_cap) {
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
                if (hdl_vid_cap->error)
                        return hdl_vid_cap->error;
                dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
        }
        if (dev->has_vid_out) {
-               v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL);
-               v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL);
+               v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
                if (hdl_vid_out->error)
                        return hdl_vid_out->error;
                dev->vid_out_dev.ctrl_handler = hdl_vid_out;
        }
        if (dev->has_vbi_cap) {
-               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL);
-               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL);
-               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL);
+               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
                if (hdl_vbi_cap->error)
                        return hdl_vbi_cap->error;
                dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
        }
        if (dev->has_vbi_out) {
-               v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL);
+               v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
                if (hdl_vbi_out->error)
                        return hdl_vbi_out->error;
                dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
        }
        if (dev->has_radio_rx) {
-               v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL);
+               v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
                if (hdl_radio_rx->error)
                        return hdl_radio_rx->error;
                dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
        }
        if (dev->has_radio_tx) {
-               v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL);
+               v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
                if (hdl_radio_tx->error)
                        return hdl_radio_tx->error;
                dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
        }
        if (dev->has_sdr_cap) {
-               v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL);
-               v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL);
+               v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
+               v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
                if (hdl_sdr_cap->error)
                        return hdl_sdr_cap->error;
                dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
index f06003bb8e4239282404a4559eebf77afa93067a..eebfff2126be22f0f50664322a722cefa2616a44 100644 (file)
@@ -703,6 +703,8 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
                goto update_mv;
 
        if (vid_cap_buf) {
+               v4l2_ctrl_request_setup(vid_cap_buf->vb.vb2_buf.req_obj.req,
+                                       &dev->ctrl_hdl_vid_cap);
                /* Fill buffer */
                vivid_fillbuff(dev, vid_cap_buf);
                dprintk(dev, 1, "filled buffer %d\n",
@@ -713,6 +715,8 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
                        dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc)
                        vivid_overlay(dev, vid_cap_buf);
 
+               v4l2_ctrl_request_complete(vid_cap_buf->vb.vb2_buf.req_obj.req,
+                                          &dev->ctrl_hdl_vid_cap);
                vb2_buffer_done(&vid_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
                                VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
                dprintk(dev, 2, "vid_cap buffer %d done\n",
@@ -720,10 +724,14 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
        }
 
        if (vbi_cap_buf) {
+               v4l2_ctrl_request_setup(vbi_cap_buf->vb.vb2_buf.req_obj.req,
+                                       &dev->ctrl_hdl_vbi_cap);
                if (dev->stream_sliced_vbi_cap)
                        vivid_sliced_vbi_cap_process(dev, vbi_cap_buf);
                else
                        vivid_raw_vbi_cap_process(dev, vbi_cap_buf);
+               v4l2_ctrl_request_complete(vbi_cap_buf->vb.vb2_buf.req_obj.req,
+                                          &dev->ctrl_hdl_vbi_cap);
                vb2_buffer_done(&vbi_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
                                VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
                dprintk(dev, 2, "vbi_cap %d done\n",
@@ -891,6 +899,8 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
                        buf = list_entry(dev->vid_cap_active.next,
                                         struct vivid_buffer, list);
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vid_cap);
                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
                        dprintk(dev, 2, "vid_cap buffer %d done\n",
                                buf->vb.vb2_buf.index);
@@ -904,6 +914,8 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
                        buf = list_entry(dev->vbi_cap_active.next,
                                         struct vivid_buffer, list);
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vbi_cap);
                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
                        dprintk(dev, 2, "vbi_cap buffer %d done\n",
                                buf->vb.vb2_buf.index);
index 9981e7548019b3ba726e02b330d247929592a44e..5a14810eeb6910a6ff6766aae181494ea9fc2e35 100644 (file)
@@ -75,6 +75,10 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
                return;
 
        if (vid_out_buf) {
+               v4l2_ctrl_request_setup(vid_out_buf->vb.vb2_buf.req_obj.req,
+                                       &dev->ctrl_hdl_vid_out);
+               v4l2_ctrl_request_complete(vid_out_buf->vb.vb2_buf.req_obj.req,
+                                          &dev->ctrl_hdl_vid_out);
                vid_out_buf->vb.sequence = dev->vid_out_seq_count;
                if (dev->field_out == V4L2_FIELD_ALTERNATE) {
                        /*
@@ -92,6 +96,10 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
        }
 
        if (vbi_out_buf) {
+               v4l2_ctrl_request_setup(vbi_out_buf->vb.vb2_buf.req_obj.req,
+                                       &dev->ctrl_hdl_vbi_out);
+               v4l2_ctrl_request_complete(vbi_out_buf->vb.vb2_buf.req_obj.req,
+                                          &dev->ctrl_hdl_vbi_out);
                if (dev->stream_sliced_vbi_out)
                        vivid_sliced_vbi_out_process(dev, vbi_out_buf);
 
@@ -262,6 +270,8 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
                        buf = list_entry(dev->vid_out_active.next,
                                         struct vivid_buffer, list);
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vid_out);
                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
                        dprintk(dev, 2, "vid_out buffer %d done\n",
                                buf->vb.vb2_buf.index);
@@ -275,6 +285,8 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
                        buf = list_entry(dev->vbi_out_active.next,
                                         struct vivid_buffer, list);
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vbi_out);
                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
                        dprintk(dev, 2, "vbi_out buffer %d done\n",
                                buf->vb.vb2_buf.index);
index bbbc1b6938a56ba8fa91cb093bb46b70ffc5394f..1a89593b0c86ffe697e58560b7b4ad4b668af04c 100644 (file)
@@ -110,7 +110,7 @@ static int vivid_fb_get_fix(struct vivid_dev *dev, struct fb_fix_screeninfo *fix
 {
        dprintk(dev, 1, "vivid_fb_get_fix\n");
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-       strlcpy(fix->id, "vioverlay fb", sizeof(fix->id));
+       strscpy(fix->id, "vioverlay fb", sizeof(fix->id));
        fix->smem_start = dev->video_pbase;
        fix->smem_len = dev->video_buffer_size;
        fix->type = FB_TYPE_PACKED_PIXELS;
index 7c8efe38ff5b781e6346b7b09c59bd2e36338a02..138c7bce68b15c910e507b9d58f97b16cef672fe 100644 (file)
@@ -76,10 +76,10 @@ void vivid_radio_rds_init(struct vivid_dev *dev)
                rds->ta = dev->radio_tx_rds_ta->cur.val;
                rds->tp = dev->radio_tx_rds_tp->cur.val;
                rds->ms = dev->radio_tx_rds_ms->cur.val;
-               strlcpy(rds->psname,
+               strscpy(rds->psname,
                        dev->radio_tx_rds_psname->p_cur.p_char,
                        sizeof(rds->psname));
-               strlcpy(rds->radiotext,
+               strscpy(rds->radiotext,
                        dev->radio_tx_rds_radiotext->p_cur.p_char + alt * 64,
                        sizeof(rds->radiotext));
                v4l2_ctrl_unlock(dev->radio_tx_rds_pi);
index 1f86d7d4f72fa57f45ea6aa20c77aa584d84ec35..232cab508f48b0e9a02934dca6196933b73657a5 100644 (file)
@@ -223,7 +223,7 @@ int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        if (vt->index > 0)
                return -EINVAL;
 
-       strlcpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name));
+       strscpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name));
        vt->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                         V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS |
                         (dev->radio_rx_rds_controls ?
index 1a3749ba5e7e582b6dd9d9af0063d456cc6a18e4..049d40b948bb25276650d8ac6a83c8adf8221e51 100644 (file)
@@ -103,7 +103,7 @@ int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a)
        if (a->index > 0)
                return -EINVAL;
 
-       strlcpy(a->name, "AM/FM/SW Transmitter", sizeof(a->name));
+       strscpy(a->name, "AM/FM/SW Transmitter", sizeof(a->name));
        a->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                        V4L2_TUNER_CAP_FREQ_BANDS | V4L2_TUNER_CAP_RDS |
                        (dev->radio_tx_rds_controls ?
index 39ca9a56448c0e79bdaa54e0e5cf862687b7f62c..b5b104ee64c99f4ba31d07ecb96b62ed64d815cb 100644 (file)
@@ -147,11 +147,11 @@ void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq,
        snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d",
                 freq / 16, ((freq & 0xf) * 10) / 16);
        if (alt)
-               strlcpy(rds->radiotext,
+               strscpy(rds->radiotext,
                        " The Radio Data System can switch between different Radio Texts ",
                        sizeof(rds->radiotext));
        else
-               strlcpy(rds->radiotext,
+               strscpy(rds->radiotext,
                        "An example of Radio Text as transmitted by the Radio Data System",
                        sizeof(rds->radiotext));
 }
index cfb7cb4d37a875b0715d1b4020a662c0338625eb..dcdc80e272c209132a57826edb9b15e68fbaf4fe 100644 (file)
@@ -102,6 +102,10 @@ static void vivid_thread_sdr_cap_tick(struct vivid_dev *dev)
 
        if (sdr_cap_buf) {
                sdr_cap_buf->vb.sequence = dev->sdr_cap_seq_count;
+               v4l2_ctrl_request_setup(sdr_cap_buf->vb.vb2_buf.req_obj.req,
+                                       &dev->ctrl_hdl_sdr_cap);
+               v4l2_ctrl_request_complete(sdr_cap_buf->vb.vb2_buf.req_obj.req,
+                                          &dev->ctrl_hdl_sdr_cap);
                vivid_sdr_cap_process(dev, sdr_cap_buf);
                sdr_cap_buf->vb.vb2_buf.timestamp =
                        ktime_get_ns() + dev->time_wrap_offset;
@@ -272,6 +276,8 @@ static int sdr_cap_start_streaming(struct vb2_queue *vq, unsigned count)
 
                list_for_each_entry_safe(buf, tmp, &dev->sdr_cap_active, list) {
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_sdr_cap);
                        vb2_buffer_done(&buf->vb.vb2_buf,
                                        VB2_BUF_STATE_QUEUED);
                }
@@ -293,6 +299,8 @@ static void sdr_cap_stop_streaming(struct vb2_queue *vq)
                buf = list_entry(dev->sdr_cap_active.next,
                                struct vivid_buffer, list);
                list_del(&buf->list);
+               v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                          &dev->ctrl_hdl_sdr_cap);
                vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
        }
 
@@ -303,12 +311,20 @@ static void sdr_cap_stop_streaming(struct vb2_queue *vq)
        mutex_lock(&dev->mutex);
 }
 
+static void sdr_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_sdr_cap);
+}
+
 const struct vb2_ops vivid_sdr_cap_qops = {
        .queue_setup            = sdr_cap_queue_setup,
        .buf_prepare            = sdr_cap_buf_prepare,
        .buf_queue              = sdr_cap_buf_queue,
        .start_streaming        = sdr_cap_start_streaming,
        .stop_streaming         = sdr_cap_stop_streaming,
+       .buf_request_complete   = sdr_cap_buf_request_complete,
        .wait_prepare           = vb2_ops_wait_prepare,
        .wait_finish            = vb2_ops_wait_finish,
 };
@@ -396,7 +412,7 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
 {
        switch (vt->index) {
        case 0:
-               strlcpy(vt->name, "ADC", sizeof(vt->name));
+               strscpy(vt->name, "ADC", sizeof(vt->name));
                vt->type = V4L2_TUNER_ADC;
                vt->capability =
                        V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
@@ -404,7 +420,7 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
                vt->rangehigh = bands_adc[2].rangehigh;
                return 0;
        case 1:
-               strlcpy(vt->name, "RF", sizeof(vt->name));
+               strscpy(vt->name, "RF", sizeof(vt->name));
                vt->type = V4L2_TUNER_RF;
                vt->capability =
                        V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
index 92a852955173e73f4f570b1ac8baa3d563a2bec6..903cebeb5ce50c2b9d2cc8d76ee8a13895e8d556 100644 (file)
@@ -204,6 +204,8 @@ static int vbi_cap_start_streaming(struct vb2_queue *vq, unsigned count)
 
                list_for_each_entry_safe(buf, tmp, &dev->vbi_cap_active, list) {
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vbi_cap);
                        vb2_buffer_done(&buf->vb.vb2_buf,
                                        VB2_BUF_STATE_QUEUED);
                }
@@ -220,12 +222,20 @@ static void vbi_cap_stop_streaming(struct vb2_queue *vq)
        vivid_stop_generating_vid_cap(dev, &dev->vbi_cap_streaming);
 }
 
+static void vbi_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_cap);
+}
+
 const struct vb2_ops vivid_vbi_cap_qops = {
        .queue_setup            = vbi_cap_queue_setup,
        .buf_prepare            = vbi_cap_buf_prepare,
        .buf_queue              = vbi_cap_buf_queue,
        .start_streaming        = vbi_cap_start_streaming,
        .stop_streaming         = vbi_cap_stop_streaming,
+       .buf_request_complete   = vbi_cap_buf_request_complete,
        .wait_prepare           = vb2_ops_wait_prepare,
        .wait_finish            = vb2_ops_wait_finish,
 };
index 69486c130a7e4f4e945d2912d3a6ee27161ffb86..9357c07e30d645685657ccc0fc36d34cf2c45b8a 100644 (file)
@@ -96,6 +96,8 @@ static int vbi_out_start_streaming(struct vb2_queue *vq, unsigned count)
 
                list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vbi_out);
                        vb2_buffer_done(&buf->vb.vb2_buf,
                                        VB2_BUF_STATE_QUEUED);
                }
@@ -115,12 +117,20 @@ static void vbi_out_stop_streaming(struct vb2_queue *vq)
        dev->vbi_out_have_cc[1] = false;
 }
 
+static void vbi_out_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_out);
+}
+
 const struct vb2_ops vivid_vbi_out_qops = {
        .queue_setup            = vbi_out_queue_setup,
        .buf_prepare            = vbi_out_buf_prepare,
        .buf_queue              = vbi_out_buf_queue,
        .start_streaming        = vbi_out_start_streaming,
        .stop_streaming         = vbi_out_stop_streaming,
+       .buf_request_complete   = vbi_out_buf_request_complete,
        .wait_prepare           = vb2_ops_wait_prepare,
        .wait_finish            = vb2_ops_wait_finish,
 };
index 1599159f2574e5c1f9dbc9b075bdc05134bb2d5a..9c8e8be81ce34ccd2071d9bd52088ad940f7a98f 100644 (file)
@@ -51,7 +51,7 @@ static const struct vivid_fmt formats_ovl[] = {
 };
 
 /* The number of discrete webcam framesizes */
-#define VIVID_WEBCAM_SIZES 5
+#define VIVID_WEBCAM_SIZES 6
 /* The number of discrete webcam frameintervals */
 #define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2)
 
@@ -59,6 +59,7 @@ static const struct vivid_fmt formats_ovl[] = {
 static const struct v4l2_frmsize_discrete webcam_sizes[VIVID_WEBCAM_SIZES] = {
        {  320, 180 },
        {  640, 360 },
+       {  640, 480 },
        { 1280, 720 },
        { 1920, 1080 },
        { 3840, 2160 },
@@ -74,9 +75,11 @@ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
        {  1, 4 },
        {  1, 5 },
        {  1, 10 },
+       {  2, 25 },
        {  1, 15 },
        {  1, 25 },
        {  1, 30 },
+       {  1, 40 },
        {  1, 50 },
        {  1, 60 },
 };
@@ -240,6 +243,8 @@ static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)
 
                list_for_each_entry_safe(buf, tmp, &dev->vid_cap_active, list) {
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vid_cap);
                        vb2_buffer_done(&buf->vb.vb2_buf,
                                        VB2_BUF_STATE_QUEUED);
                }
@@ -257,6 +262,13 @@ static void vid_cap_stop_streaming(struct vb2_queue *vq)
        dev->can_loop_video = false;
 }
 
+static void vid_cap_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_cap);
+}
+
 const struct vb2_ops vivid_vid_cap_qops = {
        .queue_setup            = vid_cap_queue_setup,
        .buf_prepare            = vid_cap_buf_prepare,
@@ -264,6 +276,7 @@ const struct vb2_ops vivid_vid_cap_qops = {
        .buf_queue              = vid_cap_buf_queue,
        .start_streaming        = vid_cap_start_streaming,
        .stop_streaming         = vid_cap_stop_streaming,
+       .buf_request_complete   = vid_cap_buf_request_complete,
        .wait_prepare           = vb2_ops_wait_prepare,
        .wait_finish            = vb2_ops_wait_finish,
 };
@@ -1505,7 +1518,7 @@ int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
                        break;
                }
        }
-       strlcpy(vt->name, "TV Tuner", sizeof(vt->name));
+       strscpy(vt->name, "TV Tuner", sizeof(vt->name));
        return 0;
 }
 
@@ -1722,7 +1735,7 @@ int vidioc_s_edid(struct file *file, void *_fh,
                return -E2BIG;
        }
        phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL);
-       ret = cec_phys_addr_validate(phys_addr, &phys_addr, NULL);
+       ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL);
        if (ret)
                return ret;
 
@@ -1738,7 +1751,7 @@ set_phys_addr:
 
        for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++)
                cec_s_phys_addr(dev->cec_tx_adap[i],
-                               cec_phys_addr_for_input(phys_addr, i + 1),
+                               v4l2_phys_addr_for_input(phys_addr, i + 1),
                                false);
        return 0;
 }
index be531caa2cdf9e5f4d9f1213e7f8e4e524848b80..9645a91b8782592c1009e863f1aa444aa4f2b5d7 100644 (file)
@@ -449,6 +449,34 @@ struct vivid_fmt vivid_formats[] = {
                .planes   = 1,
                .buffers = 1,
        },
+       {
+               .fourcc   = V4L2_PIX_FMT_SBGGR16, /* Bayer BG/GR */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .fourcc   = V4L2_PIX_FMT_SGBRG16, /* Bayer GB/RG */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .fourcc   = V4L2_PIX_FMT_SGRBG16, /* Bayer GR/BG */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .fourcc   = V4L2_PIX_FMT_SRGGB16, /* Bayer RG/GB */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
        {
                .fourcc   = V4L2_PIX_FMT_HSV24, /* HSV 24bits */
                .color_enc = TGP_COLOR_ENC_HSV,
@@ -863,7 +891,7 @@ int vidioc_g_edid(struct file *file, void *_fh,
        if (edid->blocks > dev->edid_blocks - edid->start_block)
                edid->blocks = dev->edid_blocks - edid->start_block;
        if (adap)
-               cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
+               v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
        memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
        return 0;
 }
index 51fec66d8d455673139f12a5b5c826c988bf838b..aaf13f03d5d4347d42312324327e0f4fd3368d63 100644 (file)
@@ -162,6 +162,8 @@ static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count)
 
                list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) {
                        list_del(&buf->list);
+                       v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
+                                                  &dev->ctrl_hdl_vid_out);
                        vb2_buffer_done(&buf->vb.vb2_buf,
                                        VB2_BUF_STATE_QUEUED);
                }
@@ -179,12 +181,20 @@ static void vid_out_stop_streaming(struct vb2_queue *vq)
        dev->can_loop_video = false;
 }
 
+static void vid_out_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_out);
+}
+
 const struct vb2_ops vivid_vid_out_qops = {
        .queue_setup            = vid_out_queue_setup,
        .buf_prepare            = vid_out_buf_prepare,
        .buf_queue              = vid_out_buf_queue,
        .start_streaming        = vid_out_start_streaming,
        .stop_streaming         = vid_out_stop_streaming,
+       .buf_request_complete   = vid_out_buf_request_complete,
        .wait_prepare           = vb2_ops_wait_prepare,
        .wait_finish            = vb2_ops_wait_finish,
 };
@@ -413,7 +423,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
                mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
        } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M &&
                   mp->colorspace != V4L2_COLORSPACE_REC709 &&
-                  mp->colorspace != V4L2_COLORSPACE_ADOBERGB &&
+                  mp->colorspace != V4L2_COLORSPACE_OPRGB &&
                   mp->colorspace != V4L2_COLORSPACE_BT2020 &&
                   mp->colorspace != V4L2_COLORSPACE_SRGB) {
                mp->colorspace = V4L2_COLORSPACE_REC709;
index 359917b5d842d9bc49b0cf0bca42f532de49a944..5e50178b057dc7df5050afd26863077ffb2d6232 100644 (file)
@@ -153,7 +153,7 @@ static int brx_set_format(struct v4l2_subdev *subdev,
        format = vsp1_entity_get_pad_format(&brx->entity, config, fmt->pad);
        *format = fmt->format;
 
-       /* Reset the compose rectangle */
+       /* Reset the compose rectangle. */
        if (fmt->pad != brx->entity.source_pad) {
                struct v4l2_rect *compose;
 
@@ -164,7 +164,7 @@ static int brx_set_format(struct v4l2_subdev *subdev,
                compose->height = format->height;
        }
 
-       /* Propagate the format code to all pads */
+       /* Propagate the format code to all pads. */
        if (fmt->pad == BRX_PAD_SINK(0)) {
                unsigned int i;
 
index b9c0f695d002bdedbd6dbcc3a2df71367697f575..8d86f618ec776bb893c6b298e1d232b0cca076af 100644 (file)
@@ -770,6 +770,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
        struct vsp1_device *vsp1 = dev_get_drvdata(dev);
        struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
        const struct vsp1_format_info *fmtinfo;
+       unsigned int chroma_hsub;
        struct vsp1_rwpf *rpf;
 
        if (rpf_index >= vsp1->info->rpf_count)
@@ -810,10 +811,18 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
                return -EINVAL;
        }
 
+       /*
+        * Only formats with three planes can affect the chroma planes pitch.
+        * All formats with two planes have a horizontal subsampling value of 2,
+        * but combine U and V in a single chroma plane, which thus results in
+        * the luma plane and chroma plane having the same pitch.
+        */
+       chroma_hsub = (fmtinfo->planes == 3) ? fmtinfo->hsub : 1;
+
        rpf->fmtinfo = fmtinfo;
        rpf->format.num_planes = fmtinfo->planes;
        rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
-       rpf->format.plane_fmt[1].bytesperline = cfg->pitch;
+       rpf->format.plane_fmt[1].bytesperline = cfg->pitch / chroma_hsub;
        rpf->alpha = cfg->alpha;
 
        rpf->mem.addr[0] = cfg->mem[0];
index b6619c9c18bb4adb8416813b4b5a0aa476c095a1..c650e45bb0ad1d2f4bfd00b53302b6c35fd67fb2 100644 (file)
@@ -242,7 +242,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 
        mdev->dev = vsp1->dev;
        mdev->hw_revision = vsp1->version;
-       strlcpy(mdev->model, vsp1->info->model, sizeof(mdev->model));
+       strscpy(mdev->model, vsp1->info->model, sizeof(mdev->model));
        snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
                 dev_name(mdev->dev));
        media_device_init(mdev);
@@ -802,7 +802,7 @@ static int vsp1_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, vsp1);
 
-       /* I/O and IRQ resources (clock managed by the clock PM domain) */
+       /* I/O and IRQ resources (clock managed by the clock PM domain). */
        io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        vsp1->mmio = devm_ioremap_resource(&pdev->dev, io);
        if (IS_ERR(vsp1->mmio))
@@ -821,7 +821,7 @@ static int vsp1_probe(struct platform_device *pdev)
                return ret;
        }
 
-       /* FCP (optional) */
+       /* FCP (optional). */
        fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
        if (fcp_node) {
                vsp1->fcp = rcar_fcp_get(fcp_node);
@@ -869,7 +869,7 @@ static int vsp1_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version);
 
-       /* Instanciate entities */
+       /* Instantiate entities. */
        ret = vsp1_create_entities(vsp1);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to create entities\n");
index 36a29e13109ece5a0b0cf7d11d178b91b9334f2c..a54ab528b0603836845dcc13c943d1dbad9fb8a7 100644 (file)
@@ -404,7 +404,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
        format = vsp1_entity_get_pad_format(entity, config, entity->source_pad);
        *format = fmt->format;
 
-       /* Reset the crop and compose rectangles */
+       /* Reset the crop and compose rectangles. */
        selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
                                                  V4L2_SEL_TGT_CROP);
        selection->left = 0;
index 5e15c8ff88d9952486d36f4ea6ad78858de464fa..8b01e99acd20ac0c66aeecb6503e1b1879ef392b 100644 (file)
@@ -429,8 +429,8 @@ static int histo_v4l2_querycap(struct file *file, void *fh,
        cap->device_caps = V4L2_CAP_META_CAPTURE
                         | V4L2_CAP_STREAMING;
 
-       strlcpy(cap->driver, "vsp1", sizeof(cap->driver));
-       strlcpy(cap->card, histo->video.name, sizeof(cap->card));
+       strscpy(cap->driver, "vsp1", sizeof(cap->driver));
+       strscpy(cap->card, histo->video.name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(histo->entity.vsp1->dev));
 
index 0cb63244b21af8829375a66d86420368dac1e6ae..0b18f0bd74199885dcb19f9c0fd7ca801e2b39e8 100644 (file)
@@ -88,14 +88,35 @@ static void lif_configure_stream(struct vsp1_entity *entity,
 {
        const struct v4l2_mbus_framefmt *format;
        struct vsp1_lif *lif = to_lif(&entity->subdev);
-       unsigned int hbth = 1300;
-       unsigned int obth = 400;
-       unsigned int lbth = 200;
+       unsigned int hbth;
+       unsigned int obth;
+       unsigned int lbth;
 
        format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
                                            LIF_PAD_SOURCE);
 
-       obth = min(obth, (format->width + 1) / 2 * format->height - 4);
+       switch (entity->vsp1->version & VI6_IP_VERSION_SOC_MASK) {
+       case VI6_IP_VERSION_MODEL_VSPD_GEN2:
+       case VI6_IP_VERSION_MODEL_VSPD_V2H:
+               hbth = 1536;
+               obth = min(128U, (format->width + 1) / 2 * format->height - 4);
+               lbth = 1520;
+               break;
+
+       case VI6_IP_VERSION_MODEL_VSPDL_GEN3:
+       case VI6_IP_VERSION_MODEL_VSPD_V3:
+               hbth = 0;
+               obth = 1500;
+               lbth = 0;
+               break;
+
+       case VI6_IP_VERSION_MODEL_VSPD_GEN3:
+       default:
+               hbth = 0;
+               obth = 3000;
+               lbth = 0;
+               break;
+       }
 
        vsp1_lif_write(lif, dlb, VI6_LIF_CSBTH,
                        (hbth << VI6_LIF_CSBTH_HBTH_SHIFT) |
index 3738ff2f7b850052565d3b131d559fad048103d7..f6e4157095cc0081d013e20b238698c0c3183716 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1_regs.h  --  R-Car VSP1 Registers Definitions
  *
index f8005b60b9d239aa0fdd16a8b54bd1fc8903a5e9..616afa7e165f54597542719bb2fadd7f228a600f 100644 (file)
@@ -108,7 +108,7 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
        vsp1_rpf_write(rpf, dlb, VI6_RPF_INFMT, infmt);
        vsp1_rpf_write(rpf, dlb, VI6_RPF_DSWAP, fmtinfo->swap);
 
-       /* Output location */
+       /* Output location. */
        if (pipe->brx) {
                const struct v4l2_rect *compose;
 
@@ -309,7 +309,7 @@ static void rpf_configure_partition(struct vsp1_entity *entity,
 
        /*
         * Interlaced pipelines will use the extended pre-cmd to process
-        * SRCM_ADDR_{Y,C0,C1}
+        * SRCM_ADDR_{Y,C0,C1}.
         */
        if (pipe->interlaced) {
                vsp1_rpf_configure_autofld(rpf, dl);
index 04e4e05af6aedce90f46ad5fd8d934b1f0a33310..b1617cb1f2b9d9923538ae505cdae563aa32e3f4 100644 (file)
@@ -312,6 +312,11 @@ static unsigned int sru_max_width(struct vsp1_entity *entity,
        output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
                                            SRU_PAD_SOURCE);
 
+       /*
+        * The maximum input width of the SRU is 288 input pixels, but 32
+        * pixels are reserved to support overlapping partition windows when
+        * scaling.
+        */
        if (input->width != output->width)
                return 512;
        else
@@ -333,7 +338,7 @@ static void sru_partition(struct vsp1_entity *entity,
        output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
                                            SRU_PAD_SOURCE);
 
-       /* Adapt if SRUx2 is enabled */
+       /* Adapt if SRUx2 is enabled. */
        if (input->width != output->width) {
                window->width /= 2;
                window->left /= 2;
index c20c84b54936e365d06cc5baf4c13c1212cda13b..27012af973b24b78897f6766174a1def21812a0b 100644 (file)
@@ -314,13 +314,13 @@ static void uds_configure_partition(struct vsp1_entity *entity,
        output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
                                            UDS_PAD_SOURCE);
 
-       /* Input size clipping */
+       /* Input size clipping. */
        vsp1_uds_write(uds, dlb, VI6_UDS_HSZCLIP, VI6_UDS_HSZCLIP_HCEN |
                       (0 << VI6_UDS_HSZCLIP_HCL_OFST_SHIFT) |
                       (partition->uds_sink.width
                                << VI6_UDS_HSZCLIP_HCL_SIZE_SHIFT));
 
-       /* Output size clipping */
+       /* Output size clipping. */
        vsp1_uds_write(uds, dlb, VI6_UDS_CLIP_SIZE,
                       (partition->uds_source.width
                                << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) |
@@ -342,6 +342,14 @@ static unsigned int uds_max_width(struct vsp1_entity *entity,
                                            UDS_PAD_SOURCE);
        hscale = output->width / input->width;
 
+       /*
+        * The maximum width of the UDS is 304 pixels. These are input pixels
+        * in the event of up-scaling, and output pixels in the event of
+        * downscaling.
+        *
+        * To support overlapping partition windows we clamp at units of 256 and
+        * the remaining pixels are reserved.
+        */
        if (hscale <= 2)
                return 256;
        else if (hscale <= 4)
@@ -366,7 +374,7 @@ static void uds_partition(struct vsp1_entity *entity,
        const struct v4l2_mbus_framefmt *output;
        const struct v4l2_mbus_framefmt *input;
 
-       /* Initialise the partition state */
+       /* Initialise the partition state. */
        partition->uds_sink = *window;
        partition->uds_source = *window;
 
index 81d47a09d7bcc6b88fb58a166cbd447710d19fd5..771dfe1f7c20e526a5d9b44c6d76fac67a036165 100644 (file)
@@ -38,9 +38,7 @@
 #define VSP1_VIDEO_DEF_WIDTH           1024
 #define VSP1_VIDEO_DEF_HEIGHT          768
 
-#define VSP1_VIDEO_MIN_WIDTH           2U
 #define VSP1_VIDEO_MAX_WIDTH           8190U
-#define VSP1_VIDEO_MIN_HEIGHT          2U
 #define VSP1_VIDEO_MAX_HEIGHT          8190U
 
 /* -----------------------------------------------------------------------------
@@ -136,9 +134,8 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
        height = round_down(height, info->vsub);
 
        /* Clamp the width and height. */
-       pix->width = clamp(width, VSP1_VIDEO_MIN_WIDTH, VSP1_VIDEO_MAX_WIDTH);
-       pix->height = clamp(height, VSP1_VIDEO_MIN_HEIGHT,
-                           VSP1_VIDEO_MAX_HEIGHT);
+       pix->width = clamp(width, info->hsub, VSP1_VIDEO_MAX_WIDTH);
+       pix->height = clamp(height, info->vsub, VSP1_VIDEO_MAX_HEIGHT);
 
        /*
         * Compute and clamp the stride and image size. While not documented in
@@ -867,7 +864,7 @@ static void vsp1_video_cleanup_pipeline(struct vsp1_pipeline *pipe)
        pipe->stream_config = NULL;
        pipe->configured = false;
 
-       /* Release our partition table allocation */
+       /* Release our partition table allocation. */
        kfree(pipe->part_table);
        pipe->part_table = NULL;
 }
@@ -976,8 +973,8 @@ vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
                cap->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE
                                 | V4L2_CAP_STREAMING;
 
-       strlcpy(cap->driver, "vsp1", sizeof(cap->driver));
-       strlcpy(cap->card, video->video.name, sizeof(cap->card));
+       strscpy(cap->driver, "vsp1", sizeof(cap->driver));
+       strscpy(cap->card, video->video.name, sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
                 dev_name(video->vsp1->dev));
 
index c2a1a7f97e267ab35170c4776f21cb1d09d63dd5..32bb207b20072057baabd77f0e0752c347534d88 100644 (file)
@@ -317,7 +317,7 @@ static void wpf_configure_stream(struct vsp1_entity *entity,
 
        vsp1_wpf_write(wpf, dlb, VI6_WPF_SRCRPF, srcrpf);
 
-       /* Enable interrupts */
+       /* Enable interrupts. */
        vsp1_dl_body_write(dlb, VI6_WPF_IRQ_STA(wpf->entity.index), 0);
        vsp1_dl_body_write(dlb, VI6_WPF_IRQ_ENB(wpf->entity.index),
                           VI6_WFP_IRQ_ENB_DFEE);
index d041f94be832ae62888a1422e25dc70171375031..4ae9d38c94332fa4730fc8309191cc9126815e5a 100644 (file)
@@ -504,10 +504,10 @@ xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS
                          | dma->xdev->v4l2_caps;
 
-       strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
-       strlcpy(cap->card, dma->video.name, sizeof(cap->card));
-       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u",
-                dma->xdev->dev->of_node->name, dma->port);
+       strscpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
+       strscpy(cap->card, dma->video.name, sizeof(cap->card));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%pOFn:%u",
+                dma->xdev->dev->of_node, dma->port);
 
        return 0;
 }
@@ -527,7 +527,7 @@ xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
                return -EINVAL;
 
        f->pixelformat = dma->format.pixelformat;
-       strlcpy(f->description, dma->fmtinfo->description,
+       strscpy(f->description, dma->fmtinfo->description,
                sizeof(f->description));
 
        return 0;
@@ -693,8 +693,8 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
        dma->video.fops = &xvip_dma_fops;
        dma->video.v4l2_dev = &xdev->v4l2_dev;
        dma->video.queue = &dma->queue;
-       snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u",
-                xdev->dev->of_node->name,
+       snprintf(dma->video.name, sizeof(dma->video.name), "%pOFn %s %u",
+                xdev->dev->of_node,
                 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input",
                 port);
        dma->video.vfl_type = VFL_TYPE_GRABBER;
index 9c49d1d10bee572066e14d35151595a878f124d9..851d20dcd550757a0613d66e9988670ea69496d9 100644 (file)
@@ -833,7 +833,7 @@ static int xtpg_probe(struct platform_device *pdev)
        v4l2_subdev_init(subdev, &xtpg_ops);
        subdev->dev = &pdev->dev;
        subdev->internal_ops = &xtpg_internal_ops;
-       strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
+       strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
        v4l2_set_subdevdata(subdev, xtpg);
        subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
        subdev->entity.ops = &xtpg_media_ops;
index 6d95ec1e9a6b4b4450d4c60266c27ac72e807137..99e016d35d91d7e7e1b9ad6d7e89653d43ae8b2f 100644 (file)
 
 /**
  * struct xvip_graph_entity - Entity in the video graph
- * @list: list entry in a graph entities list
- * @node: the entity's DT node
- * @entity: media entity, from the corresponding V4L2 subdev
  * @asd: subdev asynchronous registration information
+ * @entity: media entity, from the corresponding V4L2 subdev
  * @subdev: V4L2 subdev
  */
 struct xvip_graph_entity {
-       struct list_head list;
-       struct device_node *node;
+       struct v4l2_async_subdev asd; /* must be first */
        struct media_entity *entity;
-
-       struct v4l2_async_subdev asd;
        struct v4l2_subdev *subdev;
 };
 
+static inline struct xvip_graph_entity *
+to_xvip_entity(struct v4l2_async_subdev *asd)
+{
+       return container_of(asd, struct xvip_graph_entity, asd);
+}
+
 /* -----------------------------------------------------------------------------
  * Graph Management
  */
 
 static struct xvip_graph_entity *
 xvip_graph_find_entity(struct xvip_composite_device *xdev,
-                      const struct device_node *node)
+                      const struct fwnode_handle *fwnode)
 {
        struct xvip_graph_entity *entity;
+       struct v4l2_async_subdev *asd;
 
-       list_for_each_entry(entity, &xdev->entities, list) {
-               if (entity->node == node)
+       list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) {
+               entity = to_xvip_entity(asd);
+               if (entity->asd.match.fwnode == fwnode)
                        return entity;
        }
 
@@ -75,22 +78,23 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
        struct media_pad *remote_pad;
        struct xvip_graph_entity *ent;
        struct v4l2_fwnode_link link;
-       struct device_node *ep = NULL;
+       struct fwnode_handle *ep = NULL;
        int ret = 0;
 
        dev_dbg(xdev->dev, "creating links for entity %s\n", local->name);
 
        while (1) {
                /* Get the next endpoint and parse its link. */
-               ep = of_graph_get_next_endpoint(entity->node, ep);
+               ep = fwnode_graph_get_next_endpoint(entity->asd.match.fwnode,
+                                                   ep);
                if (ep == NULL)
                        break;
 
-               dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep);
+               dev_dbg(xdev->dev, "processing endpoint %p\n", ep);
 
-               ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
+               ret = v4l2_fwnode_parse_link(ep, &link);
                if (ret < 0) {
-                       dev_err(xdev->dev, "failed to parse link for %pOF\n",
+                       dev_err(xdev->dev, "failed to parse link for %p\n",
                                ep);
                        continue;
                }
@@ -99,9 +103,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
                 * the link.
                 */
                if (link.local_port >= local->num_pads) {
-                       dev_err(xdev->dev, "invalid port number %u for %pOF\n",
-                               link.local_port,
-                               to_of_node(link.local_node));
+                       dev_err(xdev->dev, "invalid port number %u for %p\n",
+                               link.local_port, link.local_node);
                        v4l2_fwnode_put_link(&link);
                        ret = -EINVAL;
                        break;
@@ -110,28 +113,25 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
                local_pad = &local->pads[link.local_port];
 
                if (local_pad->flags & MEDIA_PAD_FL_SINK) {
-                       dev_dbg(xdev->dev, "skipping sink port %pOF:%u\n",
-                               to_of_node(link.local_node),
-                               link.local_port);
+                       dev_dbg(xdev->dev, "skipping sink port %p:%u\n",
+                               link.local_node, link.local_port);
                        v4l2_fwnode_put_link(&link);
                        continue;
                }
 
                /* Skip DMA engines, they will be processed separately. */
                if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) {
-                       dev_dbg(xdev->dev, "skipping DMA port %pOF:%u\n",
-                               to_of_node(link.local_node),
-                               link.local_port);
+                       dev_dbg(xdev->dev, "skipping DMA port %p:%u\n",
+                               link.local_node, link.local_port);
                        v4l2_fwnode_put_link(&link);
                        continue;
                }
 
                /* Find the remote entity. */
-               ent = xvip_graph_find_entity(xdev,
-                                            to_of_node(link.remote_node));
+               ent = xvip_graph_find_entity(xdev, link.remote_node);
                if (ent == NULL) {
-                       dev_err(xdev->dev, "no entity found for %pOF\n",
-                               to_of_node(link.remote_node));
+                       dev_err(xdev->dev, "no entity found for %p\n",
+                               link.remote_node);
                        v4l2_fwnode_put_link(&link);
                        ret = -ENODEV;
                        break;
@@ -140,8 +140,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
                remote = ent->entity;
 
                if (link.remote_port >= remote->num_pads) {
-                       dev_err(xdev->dev, "invalid port number %u on %pOF\n",
-                               link.remote_port, to_of_node(link.remote_node));
+                       dev_err(xdev->dev, "invalid port number %u on %p\n",
+                               link.remote_port, link.remote_node);
                        v4l2_fwnode_put_link(&link);
                        ret = -EINVAL;
                        break;
@@ -168,7 +168,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
                }
        }
 
-       of_node_put(ep);
+       fwnode_handle_put(ep);
        return ret;
 }
 
@@ -230,8 +230,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
                        dma->video.name);
 
                /* Find the remote entity. */
-               ent = xvip_graph_find_entity(xdev,
-                                            to_of_node(link.remote_node));
+               ent = xvip_graph_find_entity(xdev, link.remote_node);
                if (ent == NULL) {
                        dev_err(xdev->dev, "no entity found for %pOF\n",
                                to_of_node(link.remote_node));
@@ -289,12 +288,14 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier)
        struct xvip_composite_device *xdev =
                container_of(notifier, struct xvip_composite_device, notifier);
        struct xvip_graph_entity *entity;
+       struct v4l2_async_subdev *asd;
        int ret;
 
        dev_dbg(xdev->dev, "notify complete, all subdevs registered\n");
 
        /* Create links for every entity. */
-       list_for_each_entry(entity, &xdev->entities, list) {
+       list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) {
+               entity = to_xvip_entity(asd);
                ret = xvip_graph_build_one(xdev, entity);
                if (ret < 0)
                        return ret;
@@ -314,22 +315,25 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier)
 
 static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier,
                                   struct v4l2_subdev *subdev,
-                                  struct v4l2_async_subdev *asd)
+                                  struct v4l2_async_subdev *unused)
 {
        struct xvip_composite_device *xdev =
                container_of(notifier, struct xvip_composite_device, notifier);
        struct xvip_graph_entity *entity;
+       struct v4l2_async_subdev *asd;
 
        /* Locate the entity corresponding to the bound subdev and store the
         * subdev pointer.
         */
-       list_for_each_entry(entity, &xdev->entities, list) {
-               if (entity->node != subdev->dev->of_node)
+       list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) {
+               entity = to_xvip_entity(asd);
+
+               if (entity->asd.match.fwnode != subdev->fwnode)
                        continue;
 
                if (entity->subdev) {
-                       dev_err(xdev->dev, "duplicate subdev for node %pOF\n",
-                               entity->node);
+                       dev_err(xdev->dev, "duplicate subdev for node %p\n",
+                               entity->asd.match.fwnode);
                        return -EINVAL;
                }
 
@@ -349,56 +353,60 @@ static const struct v4l2_async_notifier_operations xvip_graph_notify_ops = {
 };
 
 static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
-                               struct device_node *node)
+                               struct fwnode_handle *fwnode)
 {
-       struct xvip_graph_entity *entity;
-       struct device_node *remote;
-       struct device_node *ep = NULL;
+       struct fwnode_handle *remote;
+       struct fwnode_handle *ep = NULL;
        int ret = 0;
 
-       dev_dbg(xdev->dev, "parsing node %pOF\n", node);
+       dev_dbg(xdev->dev, "parsing node %p\n", fwnode);
 
        while (1) {
-               ep = of_graph_get_next_endpoint(node, ep);
+               struct v4l2_async_subdev *asd;
+
+               ep = fwnode_graph_get_next_endpoint(fwnode, ep);
                if (ep == NULL)
                        break;
 
-               dev_dbg(xdev->dev, "handling endpoint %pOF\n", ep);
+               dev_dbg(xdev->dev, "handling endpoint %p\n", ep);
 
-               remote = of_graph_get_remote_port_parent(ep);
+               remote = fwnode_graph_get_remote_port_parent(ep);
                if (remote == NULL) {
                        ret = -EINVAL;
-                       break;
+                       goto err_notifier_cleanup;
                }
 
+               fwnode_handle_put(ep);
+
                /* Skip entities that we have already processed. */
-               if (remote == xdev->dev->of_node ||
+               if (remote == of_fwnode_handle(xdev->dev->of_node) ||
                    xvip_graph_find_entity(xdev, remote)) {
-                       of_node_put(remote);
+                       fwnode_handle_put(remote);
                        continue;
                }
 
-               entity = devm_kzalloc(xdev->dev, sizeof(*entity), GFP_KERNEL);
-               if (entity == NULL) {
-                       of_node_put(remote);
-                       ret = -ENOMEM;
-                       break;
+               asd = v4l2_async_notifier_add_fwnode_subdev(
+                       &xdev->notifier, remote,
+                       sizeof(struct xvip_graph_entity));
+               if (IS_ERR(asd)) {
+                       ret = PTR_ERR(asd);
+                       fwnode_handle_put(remote);
+                       goto err_notifier_cleanup;
                }
-
-               entity->node = remote;
-               entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-               entity->asd.match.fwnode = of_fwnode_handle(remote);
-               list_add_tail(&entity->list, &xdev->entities);
-               xdev->num_subdevs++;
        }
 
-       of_node_put(ep);
+       return 0;
+
+err_notifier_cleanup:
+       v4l2_async_notifier_cleanup(&xdev->notifier);
+       fwnode_handle_put(ep);
        return ret;
 }
 
 static int xvip_graph_parse(struct xvip_composite_device *xdev)
 {
        struct xvip_graph_entity *entity;
+       struct v4l2_async_subdev *asd;
        int ret;
 
        /*
@@ -407,14 +415,17 @@ static int xvip_graph_parse(struct xvip_composite_device *xdev)
         * loop will handle entities added at the end of the list while walking
         * the links.
         */
-       ret = xvip_graph_parse_one(xdev, xdev->dev->of_node);
+       ret = xvip_graph_parse_one(xdev, of_fwnode_handle(xdev->dev->of_node));
        if (ret < 0)
                return 0;
 
-       list_for_each_entry(entity, &xdev->entities, list) {
-               ret = xvip_graph_parse_one(xdev, entity->node);
-               if (ret < 0)
+       list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) {
+               entity = to_xvip_entity(asd);
+               ret = xvip_graph_parse_one(xdev, entity->asd.match.fwnode);
+               if (ret < 0) {
+                       v4l2_async_notifier_cleanup(&xdev->notifier);
                        break;
+               }
        }
 
        return ret;
@@ -485,17 +496,11 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
 
 static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
 {
-       struct xvip_graph_entity *entityp;
-       struct xvip_graph_entity *entity;
        struct xvip_dma *dmap;
        struct xvip_dma *dma;
 
        v4l2_async_notifier_unregister(&xdev->notifier);
-
-       list_for_each_entry_safe(entity, entityp, &xdev->entities, list) {
-               of_node_put(entity->node);
-               list_del(&entity->list);
-       }
+       v4l2_async_notifier_cleanup(&xdev->notifier);
 
        list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) {
                xvip_dma_cleanup(dma);
@@ -505,10 +510,6 @@ static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
 
 static int xvip_graph_init(struct xvip_composite_device *xdev)
 {
-       struct xvip_graph_entity *entity;
-       struct v4l2_async_subdev **subdevs = NULL;
-       unsigned int num_subdevs;
-       unsigned int i;
        int ret;
 
        /* Init the DMA channels. */
@@ -525,26 +526,12 @@ static int xvip_graph_init(struct xvip_composite_device *xdev)
                goto done;
        }
 
-       if (!xdev->num_subdevs) {
+       if (list_empty(&xdev->notifier.asd_list)) {
                dev_err(xdev->dev, "no subdev found in graph\n");
                goto done;
        }
 
        /* Register the subdevices notifier. */
-       num_subdevs = xdev->num_subdevs;
-       subdevs = devm_kcalloc(xdev->dev, num_subdevs, sizeof(*subdevs),
-                              GFP_KERNEL);
-       if (subdevs == NULL) {
-               ret = -ENOMEM;
-               goto done;
-       }
-
-       i = 0;
-       list_for_each_entry(entity, &xdev->entities, list)
-               subdevs[i++] = &entity->asd;
-
-       xdev->notifier.subdevs = subdevs;
-       xdev->notifier.num_subdevs = num_subdevs;
        xdev->notifier.ops = &xvip_graph_notify_ops;
 
        ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier);
@@ -578,7 +565,7 @@ static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev)
        int ret;
 
        xdev->media_dev.dev = xdev->dev;
-       strlcpy(xdev->media_dev.model, "Xilinx Video Composite Device",
+       strscpy(xdev->media_dev.model, "Xilinx Video Composite Device",
                sizeof(xdev->media_dev.model));
        xdev->media_dev.hw_revision = 0;
 
@@ -610,8 +597,8 @@ static int xvip_composite_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        xdev->dev = &pdev->dev;
-       INIT_LIST_HEAD(&xdev->entities);
        INIT_LIST_HEAD(&xdev->dmas);
+       v4l2_async_notifier_init(&xdev->notifier);
 
        ret = xvip_composite_v4l2_init(xdev);
        if (ret < 0)
index faf6b6e80b3ba9c6ede82cb7d6d4040f6cd8ecb4..7e9c4cff33b444e7d0e4454d94e012c82f50f3ee 100644 (file)
@@ -28,8 +28,6 @@
  * @media_dev: media device
  * @dev: (OF) device
  * @notifier: V4L2 asynchronous subdevs notifier
- * @entities: entities in the graph as a list of xvip_graph_entity
- * @num_subdevs: number of subdevs in the pipeline
  * @dmas: list of DMA channels at the pipeline output and input
  * @v4l2_caps: V4L2 capabilities of the whole device (see VIDIOC_QUERYCAP)
  */
@@ -39,8 +37,6 @@ struct xvip_composite_device {
        struct device *dev;
 
        struct v4l2_async_notifier notifier;
-       struct list_head entities;
-       unsigned int num_subdevs;
 
        struct list_head dmas;
        u32 v4l2_caps;
index 8521bb2825e8c639251ec2c842f339eb7efae556..c9d51a5f28389b21b6a7d3d8503d000612ce9cf6 100644 (file)
@@ -174,8 +174,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct dsbr100_device *radio = video_drvdata(file);
 
-       strlcpy(v->driver, "dsbr100", sizeof(v->driver));
-       strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
+       strscpy(v->driver, "dsbr100", sizeof(v->driver));
+       strscpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -191,7 +191,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
                return -EINVAL;
 
        dsbr100_getstat(radio);
-       strcpy(v->name, "FM");
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = FREQ_MIN * FREQ_MUL;
        v->rangehigh = FREQ_MAX * FREQ_MUL;
@@ -379,7 +379,8 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
                goto err_reg_ctrl;
        }
        mutex_init(&radio->v4l2_lock);
-       strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
+       strscpy(radio->videodev.name, v4l2_dev->name,
+               sizeof(radio->videodev.name));
        radio->videodev.v4l2_dev = v4l2_dev;
        radio->videodev.fops = &usb_dsbr100_fops;
        radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
index 5b82e63885cdd845a744451b0f2ed8f16056c0e2..d12e07e325462a23d70fa2202b9689fd349d249f 100644 (file)
@@ -353,9 +353,9 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
 static int vidioc_querycap(struct file *file, void *priv,
                                struct v4l2_capability *v)
 {
-       strlcpy(v->driver, "ADS Cadet", sizeof(v->driver));
-       strlcpy(v->card, "ADS Cadet", sizeof(v->card));
-       strlcpy(v->bus_info, "ISA:radio-cadet", sizeof(v->bus_info));
+       strscpy(v->driver, "ADS Cadet", sizeof(v->driver));
+       strscpy(v->card, "ADS Cadet", sizeof(v->card));
+       strscpy(v->bus_info, "ISA:radio-cadet", sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
                          V4L2_CAP_READWRITE | V4L2_CAP_RDS_CAPTURE;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -370,7 +370,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (v->index)
                return -EINVAL;
        v->type = V4L2_TUNER_RADIO;
-       strlcpy(v->name, "Radio", sizeof(v->name));
+       strscpy(v->name, "Radio", sizeof(v->name));
        v->capability = bands[0].capability | bands[1].capability;
        v->rangelow = bands[0].rangelow;           /* 520 kHz (start of AM band) */
        v->rangehigh = bands[1].rangehigh;    /* 108.0 MHz (end of FM band) */
@@ -595,7 +595,7 @@ static int __init cadet_init(void)
        struct v4l2_ctrl_handler *hdl;
        int res = -ENODEV;
 
-       strlcpy(v4l2_dev->name, "cadet", sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, "cadet", sizeof(v4l2_dev->name));
        mutex_init(&dev->lock);
 
        /* If a probe was requested then probe ISAPnP first (safest) */
@@ -639,7 +639,7 @@ static int __init cadet_init(void)
        dev->is_fm_band = true;
        dev->curfreq = bands[dev->is_fm_band].rangelow;
        cadet_setfreq(dev, dev->curfreq);
-       strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+       strscpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
        dev->vdev.v4l2_dev = v4l2_dev;
        dev->vdev.fops = &cadet_fops;
        dev->vdev.ioctl_ops = &cadet_ioctl_ops;
index 7312e469e850e8bbb0d3e54f02356de7a96d953e..551de8a45b95445fb78bea9e461649f1d595fee6 100644 (file)
@@ -42,8 +42,8 @@ static int radio_isa_querycap(struct file *file, void  *priv,
 {
        struct radio_isa_card *isa = video_drvdata(file);
 
-       strlcpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver));
-       strlcpy(v->card, isa->drv->card, sizeof(v->card));
+       strscpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver));
+       strscpy(v->card, isa->drv->card, sizeof(v->card));
        snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name);
 
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
@@ -60,7 +60,7 @@ static int radio_isa_g_tuner(struct file *file, void *priv,
        if (v->index > 0)
                return -EINVAL;
 
-       strlcpy(v->name, "FM", sizeof(v->name));
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = FREQ_LOW;
        v->rangehigh = FREQ_HIGH;
@@ -198,7 +198,7 @@ static struct radio_isa_card *radio_isa_alloc(struct radio_isa_driver *drv,
        dev_set_drvdata(pdev, isa);
        isa->drv = drv;
        v4l2_dev = &isa->v4l2_dev;
-       strlcpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name));
 
        return isa;
 }
@@ -243,7 +243,7 @@ static int radio_isa_common_probe(struct radio_isa_card *isa,
 
        mutex_init(&isa->lock);
        isa->vdev.lock = &isa->lock;
-       strlcpy(isa->vdev.name, v4l2_dev->name, sizeof(isa->vdev.name));
+       strscpy(isa->vdev.name, v4l2_dev->name, sizeof(isa->vdev.name));
        isa->vdev.v4l2_dev = v4l2_dev;
        isa->vdev.fops = &radio_isa_fops;
        isa->vdev.ioctl_ops = &radio_isa_ioctl_ops;
index f2ea8bc5f5eea11dbd266e881d3e3b8cfe2dd1e0..e9484b01307347feda1c36a817554024be204874 100644 (file)
@@ -174,8 +174,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct keene_device *radio = video_drvdata(file);
 
-       strlcpy(v->driver, "radio-keene", sizeof(v->driver));
-       strlcpy(v->card, "Keene FM Transmitter", sizeof(v->card));
+       strscpy(v->driver, "radio-keene", sizeof(v->driver));
+       strscpy(v->card, "Keene FM Transmitter", sizeof(v->card));
        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_MODULATOR;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -190,7 +190,7 @@ static int vidioc_g_modulator(struct file *file, void *priv,
        if (v->index > 0)
                return -EINVAL;
 
-       strlcpy(v->name, "FM", sizeof(v->name));
+       strscpy(v->name, "FM", sizeof(v->name));
        v->rangelow = FREQ_MIN * FREQ_MUL;
        v->rangehigh = FREQ_MAX * FREQ_MUL;
        v->txsubchans = radio->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
@@ -362,7 +362,7 @@ static int usb_keene_probe(struct usb_interface *intf,
 
        radio->v4l2_dev.ctrl_handler = hdl;
        radio->v4l2_dev.release = usb_keene_video_device_release;
-       strlcpy(radio->vdev.name, radio->v4l2_dev.name,
+       strscpy(radio->vdev.name, radio->v4l2_dev.name,
                sizeof(radio->vdev.name));
        radio->vdev.v4l2_dev = &radio->v4l2_dev;
        radio->vdev.fops = &usb_keene_fops;
index fdc481257efddbbf3d45a706b4b4a6d65e66e55c..5cb153727841b72e42f0bcc8c8e563b95b6e8bba 100644 (file)
@@ -197,8 +197,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct ma901radio_device *radio = video_drvdata(file);
 
-       strlcpy(v->driver, "radio-ma901", sizeof(v->driver));
-       strlcpy(v->card, "Masterkit MA901 USB FM Radio", sizeof(v->card));
+       strscpy(v->driver, "radio-ma901", sizeof(v->driver));
+       strscpy(v->card, "Masterkit MA901 USB FM Radio", sizeof(v->card));
        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -222,7 +222,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
         * retval = ma901radio_get_stat(radio, &is_stereo, &v->signal);
         */
 
-       strcpy(v->name, "FM");
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = FREQ_MIN * FREQ_MUL;
        v->rangehigh = FREQ_MAX * FREQ_MUL;
@@ -400,7 +400,7 @@ static int usb_ma901radio_probe(struct usb_interface *intf,
 
        radio->v4l2_dev.ctrl_handler = &radio->hdl;
        radio->v4l2_dev.release = usb_ma901radio_release;
-       strlcpy(radio->vdev.name, radio->v4l2_dev.name,
+       strscpy(radio->vdev.name, radio->v4l2_dev.name,
                sizeof(radio->vdev.name));
        radio->vdev.v4l2_dev = &radio->v4l2_dev;
        radio->vdev.fops = &usb_ma901radio_fops;
index e4e7587392469b840cd5c40c38926f7f741a009b..1b97ad2ce7d0a157328dad1c8c0b54ca8a62d7ac 100644 (file)
@@ -142,7 +142,7 @@ static int maxiradio_probe(struct pci_dev *pdev,
        dev->tea.cannot_read_data = true;
        dev->tea.v4l2_dev = v4l2_dev;
        dev->tea.radio_nr = radio_nr;
-       strlcpy(dev->tea.card, "Maxi Radio FM2000", sizeof(dev->tea.card));
+       strscpy(dev->tea.card, "Maxi Radio FM2000", sizeof(dev->tea.card));
        snprintf(dev->tea.bus_info, sizeof(dev->tea.bus_info),
                        "PCI:%s", pci_name(pdev));
 
index 7b35e633118d68952e22ddb60e4869055eb5a478..b626567b75c5a454557e1da7a2398b1bf441d996 100644 (file)
@@ -200,8 +200,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct pcm20 *dev = video_drvdata(file);
 
-       strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
-       strlcpy(v->card, "Miro PCM20", sizeof(v->card));
+       strscpy(v->driver, "Miro PCM20", sizeof(v->driver));
+       strscpy(v->card, "Miro PCM20", sizeof(v->card));
        snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", dev->v4l2_dev.name);
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -231,7 +231,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 
        if (v->index)
                return -EINVAL;
-       strlcpy(v->name, "FM", sizeof(v->name));
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = 87*16000;
        v->rangehigh = 108*16000;
@@ -443,7 +443,7 @@ static int __init pcm20_init(void)
                         "you must load the snd-miro driver first!\n");
                return -ENODEV;
        }
-       strlcpy(v4l2_dev->name, "radio-miropcm20", sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, "radio-miropcm20", sizeof(v4l2_dev->name));
        mutex_init(&dev->lock);
 
        res = v4l2_device_register(NULL, v4l2_dev);
@@ -474,7 +474,7 @@ static int __init pcm20_init(void)
                v4l2_err(v4l2_dev, "Could not register control\n");
                goto err_hdl;
        }
-       strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+       strscpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
        dev->vdev.v4l2_dev = v4l2_dev;
        dev->vdev.fops = &pcm20_fops;
        dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
index 0f292c6ba338f06e3a03f77bf869ef684d084b43..ab1324f681995663440e5e8453819175ef118064 100644 (file)
@@ -266,8 +266,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct amradio_device *radio = video_drvdata(file);
 
-       strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
-       strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
+       strscpy(v->driver, "radio-mr800", sizeof(v->driver));
+       strscpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER |
                                        V4L2_CAP_HW_FREQ_SEEK;
@@ -291,7 +291,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (retval)
                return retval;
 
-       strcpy(v->name, "FM");
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = FREQ_MIN * FREQ_MUL;
        v->rangehigh = FREQ_MAX * FREQ_MUL;
@@ -547,7 +547,7 @@ static int usb_amradio_probe(struct usb_interface *intf,
 
        radio->v4l2_dev.ctrl_handler = &radio->hdl;
        radio->v4l2_dev.release = usb_amradio_release;
-       strlcpy(radio->vdev.name, radio->v4l2_dev.name,
+       strscpy(radio->vdev.name, radio->v4l2_dev.name,
                sizeof(radio->vdev.name));
        radio->vdev.v4l2_dev = &radio->v4l2_dev;
        radio->vdev.fops = &usb_amradio_fops;
index 9a5079d64c4ab1fa96af7f0a22b0ebdb4793701b..5e782b3c2fa92a5658392652af56e1c6120d9d31 100644 (file)
@@ -181,8 +181,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct raremono_device *radio = video_drvdata(file);
 
-       strlcpy(v->driver, "radio-raremono", sizeof(v->driver));
-       strlcpy(v->card, "Thanko's Raremono", sizeof(v->card));
+       strscpy(v->driver, "radio-raremono", sizeof(v->driver));
+       strscpy(v->card, "Thanko's Raremono", sizeof(v->card));
        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -212,7 +212,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (v->index > 0)
                return -EINVAL;
 
-       strlcpy(v->name, "AM/FM/SW", sizeof(v->name));
+       strscpy(v->name, "AM/FM/SW", sizeof(v->name));
        v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                V4L2_TUNER_CAP_FREQ_BANDS;
        v->rangelow = AM_FREQ_RANGE_LOW * 16;
@@ -338,7 +338,7 @@ static int usb_raremono_probe(struct usb_interface *intf,
 
        mutex_init(&radio->lock);
 
-       strlcpy(radio->vdev.name, radio->v4l2_dev.name,
+       strscpy(radio->vdev.name, radio->v4l2_dev.name,
                sizeof(radio->vdev.name));
        radio->vdev.v4l2_dev = &radio->v4l2_dev;
        radio->vdev.fops = &usb_raremono_fops;
index 4f9b97edd9eb9f7514aae2964933c77afe2d5318..a8fedc96361443d475dcf45e46eec7eed06b9baf 100644 (file)
@@ -129,9 +129,9 @@ static void fmi_set_freq(struct fmi *fmi)
 static int vidioc_querycap(struct file *file, void  *priv,
                                        struct v4l2_capability *v)
 {
-       strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
-       strlcpy(v->card, "SF16-FMI/FMP/FMD radio", sizeof(v->card));
-       strlcpy(v->bus_info, "ISA:radio-sf16fmi", sizeof(v->bus_info));
+       strscpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
+       strscpy(v->card, "SF16-FMI/FMP/FMD radio", sizeof(v->card));
+       strscpy(v->bus_info, "ISA:radio-sf16fmi", sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
        return 0;
@@ -145,7 +145,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (v->index > 0)
                return -EINVAL;
 
-       strlcpy(v->name, "FM", sizeof(v->name));
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = RSF16_MINFREQ;
        v->rangehigh = RSF16_MAXFREQ;
@@ -315,7 +315,7 @@ static int __init fmi_init(void)
                return -ENODEV;
        }
 
-       strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
+       strscpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
        fmi->io = io;
 
        res = v4l2_device_register(NULL, v4l2_dev);
@@ -339,7 +339,7 @@ static int __init fmi_init(void)
                return res;
        }
 
-       strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
+       strscpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
        fmi->vdev.v4l2_dev = v4l2_dev;
        fmi->vdev.fops = &fmi_fops;
        fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
index 7b07d42a9909a7eb05bb2a298c8445745aa0796e..ca8a1c263eac1902e4b421d4aa1a12ab5f903c2d 100644 (file)
@@ -213,8 +213,8 @@ static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io)
                if (io == fmr2_cards[i]->io)
                        return -EBUSY;
 
-       strlcpy(fmr2->v4l2_dev.name, "radio-sf16fmr2",
-                       sizeof(fmr2->v4l2_dev.name)),
+       strscpy(fmr2->v4l2_dev.name, "radio-sf16fmr2",
+               sizeof(fmr2->v4l2_dev.name)),
        fmr2->io = io;
 
        if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) {
@@ -234,7 +234,7 @@ static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io)
        fmr2->tea.radio_nr = radio_nr[num_fmr2_cards];
        fmr2->tea.ops = &fmr2_tea_ops;
        fmr2->tea.ext_init = fmr2_tea_ext_init;
-       strlcpy(fmr2->tea.card, card_name, sizeof(fmr2->tea.card));
+       strscpy(fmr2->tea.card, card_name, sizeof(fmr2->tea.card));
        snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s",
                        fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev));
 
index 22f3466af2b187d1779c1bd81515ae5e85d3f9ad..8230da828d0ee677ec89498b569c6d6fd0c9c472 100644 (file)
@@ -345,7 +345,7 @@ static int usb_shark_probe(struct usb_interface *intf,
        shark->tea.ops = &shark_tea_ops;
        shark->tea.cannot_mute = true;
        shark->tea.has_am = true;
-       strlcpy(shark->tea.card, "Griffin radioSHARK",
+       strscpy(shark->tea.card, "Griffin radioSHARK",
                sizeof(shark->tea.card));
        usb_make_path(shark->usbdev, shark->tea.bus_info,
                sizeof(shark->tea.bus_info));
index 4d1a4b3d669cf5fcdcde0d2b3a882d059baa0acd..d150f12382c60e441e155c63a0ec21276b1d2482 100644 (file)
@@ -310,7 +310,7 @@ static int usb_shark_probe(struct usb_interface *intf,
        shark->tea.ops = &shark_tea_ops;
        shark->tea.has_am = true;
        shark->tea.write_before_read = true;
-       strlcpy(shark->tea.card, "Griffin radioSHARK2",
+       strscpy(shark->tea.card, "Griffin radioSHARK2",
                sizeof(shark->tea.card));
        usb_make_path(shark->usbdev, shark->tea.bus_info,
                sizeof(shark->tea.bus_info));
index b52e678c6901cfa8b115d7790be029cbd37cfc2f..269971145f88d5fd5df50f91bc207ce304c11287 100644 (file)
@@ -340,9 +340,9 @@ static int si476x_radio_querycap(struct file *file, void *priv,
 {
        struct si476x_radio *radio = video_drvdata(file);
 
-       strlcpy(capability->driver, radio->v4l2dev.name,
+       strscpy(capability->driver, radio->v4l2dev.name,
                sizeof(capability->driver));
-       strlcpy(capability->card,   DRIVER_CARD, sizeof(capability->card));
+       strscpy(capability->card,   DRIVER_CARD, sizeof(capability->card));
        snprintf(capability->bus_info, sizeof(capability->bus_info),
                 "platform:%s", radio->v4l2dev.name);
 
@@ -428,15 +428,15 @@ static int si476x_radio_g_tuner(struct file *file, void *priv,
        si476x_core_lock(radio->core);
 
        if (si476x_core_is_a_secondary_tuner(radio->core)) {
-               strlcpy(tuner->name, "FM (secondary)", sizeof(tuner->name));
+               strscpy(tuner->name, "FM (secondary)", sizeof(tuner->name));
                tuner->rxsubchans = 0;
                tuner->rangelow = si476x_bands[SI476X_BAND_FM].rangelow;
        } else if (si476x_core_has_am(radio->core)) {
                if (si476x_core_is_a_primary_tuner(radio->core))
-                       strlcpy(tuner->name, "AM/FM (primary)",
+                       strscpy(tuner->name, "AM/FM (primary)",
                                sizeof(tuner->name));
                else
-                       strlcpy(tuner->name, "AM/FM", sizeof(tuner->name));
+                       strscpy(tuner->name, "AM/FM", sizeof(tuner->name));
 
                tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO
                        | V4L2_TUNER_SUB_RDS;
@@ -446,7 +446,7 @@ static int si476x_radio_g_tuner(struct file *file, void *priv,
 
                tuner->rangelow = si476x_bands[SI476X_BAND_AM].rangelow;
        } else {
-               strlcpy(tuner->name, "FM", sizeof(tuner->name));
+               strscpy(tuner->name, "FM", sizeof(tuner->name));
                tuner->rxsubchans = V4L2_TUNER_SUB_RDS;
                tuner->capability |= V4L2_TUNER_CAP_RDS
                        | V4L2_TUNER_CAP_RDS_BLOCK_IO
index afb763256fd68a9a203f060c104707fe1699a29d..6632be648cea5e15264a9c5420326dec2b1e9920 100644 (file)
@@ -287,8 +287,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct tea5764_device *radio = video_drvdata(file);
        struct video_device *dev = &radio->vdev;
 
-       strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
-       strlcpy(v->card, dev->name, sizeof(v->card));
+       strscpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
+       strscpy(v->card, dev->name, sizeof(v->card));
        snprintf(v->bus_info, sizeof(v->bus_info),
                 "I2C:%s", dev_name(&dev->dev));
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
@@ -305,7 +305,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (v->index > 0)
                return -EINVAL;
 
-       strlcpy(v->name, "FM", sizeof(v->name));
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        tea5764_i2c_read(radio);
        v->rangelow   = FREQ_MIN * FREQ_MUL;
index 04ed1a5d117789bcc598e039144bf7168ed09d90..61f751cf1aa4cf575f132ed49f1f13bf9d687702 100644 (file)
@@ -266,10 +266,10 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
        struct radio_tea5777 *tea = video_drvdata(file);
 
-       strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
-       strlcpy(v->card, tea->card, sizeof(v->card));
+       strscpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
+       strscpy(v->card, tea->card, sizeof(v->card));
        strlcat(v->card, " TEA5777", sizeof(v->card));
-       strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
+       strscpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
        v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -304,9 +304,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 
        memset(v, 0, sizeof(*v));
        if (tea->has_am)
-               strlcpy(v->name, "AM/FM", sizeof(v->name));
+               strscpy(v->name, "AM/FM", sizeof(v->name));
        else
-               strlcpy(v->name, "FM", sizeof(v->name));
+               strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                        V4L2_TUNER_CAP_FREQ_BANDS |
@@ -560,7 +560,7 @@ int radio_tea5777_init(struct radio_tea5777 *tea, struct module *owner)
        tea->vd = tea575x_radio;
        video_set_drvdata(&tea->vd, tea);
        mutex_init(&tea->mutex);
-       strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
+       strscpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
        tea->vd.lock = &tea->mutex;
        tea->vd.v4l2_dev = tea->v4l2_dev;
        tea->fops = tea575x_fops;
index fc4d9a73ab17fc6ce41c466a43e761c2d2ea9576..0eda863124e9358bf594b12c897a824c6eed8b19 100644 (file)
@@ -39,8 +39,8 @@ struct timbradio {
 static int timbradio_vidioc_querycap(struct file *file, void  *priv,
        struct v4l2_capability *v)
 {
-       strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
-       strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
+       strscpy(v->driver, DRIVER_NAME, sizeof(v->driver));
+       strscpy(v->card, "Timberdale Radio", sizeof(v->card));
        snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -115,7 +115,7 @@ static int timbradio_probe(struct platform_device *pdev)
        tr->pdata = *pdata;
        mutex_init(&tr->lock);
 
-       strlcpy(tr->video_dev.name, "Timberdale Radio",
+       strscpy(tr->video_dev.name, "Timberdale Radio",
                sizeof(tr->video_dev.name));
        tr->video_dev.fops = &timbradio_fops;
        tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
@@ -123,7 +123,7 @@ static int timbradio_probe(struct platform_device *pdev)
        tr->video_dev.minor = -1;
        tr->video_dev.lock = &tr->lock;
 
-       strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
+       strscpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
        err = v4l2_device_register(NULL, &tr->v4l2_dev);
        if (err)
                goto err;
index 11aa94f189cb0f2fd2776e3dc23220942c549f9f..b95704f3cb8bb3e40fdb195c0b747dfdfe5a5e13 100644 (file)
@@ -1286,11 +1286,11 @@ static int wl1273_fm_vidioc_querycap(struct file *file, void *priv,
 
        dev_dbg(radio->dev, "%s\n", __func__);
 
-       strlcpy(capability->driver, WL1273_FM_DRIVER_NAME,
+       strscpy(capability->driver, WL1273_FM_DRIVER_NAME,
                sizeof(capability->driver));
-       strlcpy(capability->card, "Texas Instruments Wl1273 FM Radio",
+       strscpy(capability->card, "Texas Instruments Wl1273 FM Radio",
                sizeof(capability->card));
-       strlcpy(capability->bus_info, radio->bus_type,
+       strscpy(capability->bus_info, radio->bus_type,
                sizeof(capability->bus_info));
 
        capability->device_caps = V4L2_CAP_HW_FREQ_SEEK |
@@ -1488,7 +1488,7 @@ static int wl1273_fm_vidioc_g_audio(struct file *file, void *priv,
        if (audio->index > 1)
                return -EINVAL;
 
-       strlcpy(audio->name, "Radio", sizeof(audio->name));
+       strscpy(audio->name, "Radio", sizeof(audio->name));
        audio->capability = V4L2_AUDCAP_STEREO;
 
        return 0;
@@ -1523,7 +1523,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
        if (tuner->index > 0)
                return -EINVAL;
 
-       strlcpy(tuner->name, WL1273_FM_DRIVER_NAME, sizeof(tuner->name));
+       strscpy(tuner->name, WL1273_FM_DRIVER_NAME, sizeof(tuner->name));
        tuner->type = V4L2_TUNER_RADIO;
 
        tuner->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);
@@ -1781,7 +1781,7 @@ static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
 
        dev_dbg(radio->dev, "%s\n", __func__);
 
-       strlcpy(modulator->name, WL1273_FM_DRIVER_NAME,
+       strscpy(modulator->name, WL1273_FM_DRIVER_NAME,
                sizeof(modulator->name));
 
        modulator->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);
index c40e1753f34be9d1158ce215bc0aeca9f39618b1..1d7ab5462c77e47827d1df031c9e2d297c1c47cb 100644 (file)
@@ -622,7 +622,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
        }
 
        /* driver constants */
-       strcpy(tuner->name, "FM");
+       strscpy(tuner->name, "FM", sizeof(tuner->name));
        tuner->type = V4L2_TUNER_RADIO;
        tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
                            V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
index e3b3ecd14a4dd38803cec253a5eefc18ef723af4..9751ea1d80be558e11f7aecd00180fd1aeccc0a0 100644 (file)
@@ -229,8 +229,8 @@ static int si470x_fops_release(struct file *file)
 static int si470x_vidioc_querycap(struct file *file, void *priv,
                                  struct v4l2_capability *capability)
 {
-       strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
-       strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+       strscpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+       strscpy(capability->card, DRIVER_CARD, sizeof(capability->card));
        capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
                V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
        capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
index 313a95f195a27235bf2f1545e7bf2e25cde521e1..91d6ef5579f7950cee08d16eed0e075ecc97f422 100644 (file)
@@ -519,8 +519,8 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
 {
        struct si470x_device *radio = video_drvdata(file);
 
-       strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
-       strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+       strscpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+       strscpy(capability->card, DRIVER_CARD, sizeof(capability->card));
        usb_make_path(radio->usbdev, capability->bus_info,
                        sizeof(capability->bus_info));
        capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE |
index 27339ec495f603b87481cef5958b5c7c4c7e6ada..733fcf3933e44c60bdc452534989cbd8c8b525bb 100644 (file)
@@ -67,10 +67,10 @@ static const struct v4l2_file_operations radio_si4713_fops = {
 static int radio_si4713_querycap(struct file *file, void *priv,
                                        struct v4l2_capability *capability)
 {
-       strlcpy(capability->driver, "radio-si4713", sizeof(capability->driver));
-       strlcpy(capability->card, "Silicon Labs Si4713 Modulator",
+       strscpy(capability->driver, "radio-si4713", sizeof(capability->driver));
+       strscpy(capability->card, "Silicon Labs Si4713 Modulator",
                sizeof(capability->card));
-       strlcpy(capability->bus_info, "platform:radio-si4713",
+       strscpy(capability->bus_info, "platform:radio-si4713",
                sizeof(capability->bus_info));
        capability->device_caps = V4L2_CAP_MODULATOR | V4L2_CAP_RDS_OUTPUT;
        capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS;
index 1ebbf02171429010e8ee586b2292179edbb5a3de..23065ecce9796c2fe2f473c271e59a4d576d018c 100644 (file)
@@ -67,8 +67,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 {
        struct si4713_usb_device *radio = video_drvdata(file);
 
-       strlcpy(v->driver, "radio-usb-si4713", sizeof(v->driver));
-       strlcpy(v->card, "Si4713 FM Transmitter", sizeof(v->card));
+       strscpy(v->driver, "radio-usb-si4713", sizeof(v->driver));
+       strscpy(v->card, "Si4713 FM Transmitter", sizeof(v->card));
        usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_MODULATOR | V4L2_CAP_RDS_OUTPUT;
        v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -467,7 +467,7 @@ static int usb_si4713_probe(struct usb_interface *intf,
 
        radio->vdev.ctrl_handler = sd->ctrl_handler;
        radio->v4l2_dev.release = usb_si4713_video_device_release;
-       strlcpy(radio->vdev.name, radio->v4l2_dev.name,
+       strscpy(radio->vdev.name, radio->v4l2_dev.name,
                sizeof(radio->vdev.name));
        radio->vdev.v4l2_dev = &radio->v4l2_dev;
        radio->vdev.fops = &usb_si4713_fops;
index 7412fe1b10c6673336cae5bff37bfa522725e065..f89f83e047416e03387a502797200c2154f6b25b 100644 (file)
@@ -233,10 +233,10 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
        struct snd_tea575x *tea = video_drvdata(file);
 
-       strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
-       strlcpy(v->card, tea->card, sizeof(v->card));
+       strscpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver));
+       strscpy(v->card, tea->card, sizeof(v->card));
        strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card));
-       strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
+       strscpy(v->bus_info, tea->bus_info, sizeof(v->bus_info));
        v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
        if (!tea->cannot_read_data)
                v->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
@@ -296,7 +296,7 @@ int snd_tea575x_g_tuner(struct snd_tea575x *tea, struct v4l2_tuner *v)
        snd_tea575x_enum_freq_bands(tea, &band_fm);
 
        memset(v, 0, sizeof(*v));
-       strlcpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
+       strscpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->capability = band_fm.capability;
        v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow;
@@ -537,7 +537,7 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
        tea->vd = tea575x_radio;
        video_set_drvdata(&tea->vd, tea);
        mutex_init(&tea->mutex);
-       strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
+       strscpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
        tea->vd.lock = &tea->mutex;
        tea->vd.v4l2_dev = tea->v4l2_dev;
        tea->fops = tea575x_fops;
index ed210f4c476aa1ac3604e087e7fdb5d5c667d2ec..a76ff2978dfb8a101a8355e2f4e5107eb0b0db0f 100644 (file)
@@ -79,7 +79,7 @@ static int tef6862_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
                return -EINVAL;
 
        /* only support FM for now */
-       strlcpy(v->name, "FM", sizeof(v->name));
+       strscpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = TEF6862_LO_FREQ;
        v->rangehigh = TEF6862_HI_FREQ;
index dccdf6558e6ab7ce4e1e613453acdd5558badd3a..e25fd4d4d280c7c8f2efabf5bde33a5eb039bcc8 100644 (file)
@@ -190,9 +190,9 @@ release_unlock:
 static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
                struct v4l2_capability *capability)
 {
-       strlcpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
-       strlcpy(capability->card, FM_DRV_CARD_SHORT_NAME,
-                       sizeof(capability->card));
+       strscpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
+       strscpy(capability->card, FM_DRV_CARD_SHORT_NAME,
+               sizeof(capability->card));
        sprintf(capability->bus_info, "UART");
        capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
                V4L2_CAP_RADIO | V4L2_CAP_MODULATOR |
@@ -249,7 +249,7 @@ static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
                struct v4l2_audio *audio)
 {
        memset(audio, 0, sizeof(*audio));
-       strcpy(audio->name, "Radio");
+       strscpy(audio->name, "Radio", sizeof(audio->name));
        audio->capability = V4L2_AUDCAP_STEREO;
 
        return 0;
@@ -293,7 +293,7 @@ static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
        if (ret != 0)
                return ret;
 
-       strcpy(tuner->name, "FM");
+       strscpy(tuner->name, "FM", sizeof(tuner->name));
        tuner->type = V4L2_TUNER_RADIO;
        /* Store rangelow and rangehigh freq in unit of 62.5 Hz */
        tuner->rangelow = bottom_freq * 16;
@@ -531,7 +531,8 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
        struct v4l2_ctrl *ctrl;
        int ret;
 
-       strlcpy(fmdev->v4l2_dev.name, FM_DRV_NAME, sizeof(fmdev->v4l2_dev.name));
+       strscpy(fmdev->v4l2_dev.name, FM_DRV_NAME,
+               sizeof(fmdev->v4l2_dev.name));
        ret = v4l2_device_register(NULL, &fmdev->v4l2_dev);
        if (ret < 0)
                return ret;
index 8e82610ffaad51e26bfdfb852e27a4e44a782d60..265e91a2a70da146362302cbfcf121a0dbf2a06f 100644 (file)
@@ -862,7 +862,7 @@ static int ati_remote_probe(struct usb_interface *interface,
        ati_remote->interface = interface;
 
        usb_make_path(udev, ati_remote->rc_phys, sizeof(ati_remote->rc_phys));
-       strlcpy(ati_remote->mouse_phys, ati_remote->rc_phys,
+       strscpy(ati_remote->mouse_phys, ati_remote->rc_phys,
                sizeof(ati_remote->mouse_phys));
 
        strlcat(ati_remote->rc_phys, "/input0", sizeof(ati_remote->rc_phys));
index 71b8c9bbf6c409b954471d6e4cf20884fdea35ee..dd2fd307ef859e19811db97adcb3dbbf2e58cc6a 100644 (file)
@@ -326,8 +326,6 @@ static int ene_rx_get_sample_reg(struct ene_device *dev)
 /* Sense current received carrier */
 static void ene_rx_sense_carrier(struct ene_device *dev)
 {
-       DEFINE_IR_RAW_EVENT(ev);
-
        int carrier, duty_cycle;
        int period = ene_read_reg(dev, ENE_CIRCAR_PRD);
        int hperiod = ene_read_reg(dev, ENE_CIRCAR_HPRD);
@@ -348,9 +346,11 @@ static void ene_rx_sense_carrier(struct ene_device *dev)
        dbg("RX: sensed carrier = %d Hz, duty cycle %d%%",
                                                carrier, duty_cycle);
        if (dev->carrier_detect_enabled) {
-               ev.carrier_report = true;
-               ev.carrier = carrier;
-               ev.duty_cycle = duty_cycle;
+               struct ir_raw_event ev = {
+                       .carrier_report = true,
+                       .carrier = carrier,
+                       .duty_cycle = duty_cycle
+               };
                ir_raw_event_store(dev->rdev, &ev);
        }
 }
@@ -733,7 +733,7 @@ static irqreturn_t ene_isr(int irq, void *data)
        unsigned long flags;
        irqreturn_t retval = IRQ_NONE;
        struct ene_device *dev = (struct ene_device *)data;
-       DEFINE_IR_RAW_EVENT(ev);
+       struct ir_raw_event ev = {};
 
        spin_lock_irqsave(&dev->hw_lock, flags);
 
index f2639d0c2fca87478e51acbbb638f45cee53d878..601944666b71cdd09d558838f01e15a976a736d5 100644 (file)
@@ -282,7 +282,7 @@ static int fintek_cmdsize(u8 cmd, u8 subcmd)
 /* process ir data stored in driver buffer */
 static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        u8 sample;
        bool event = false;
        int i;
@@ -314,7 +314,6 @@ static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
                        break;
                case PARSE_IRDATA:
                        fintek->rem--;
-                       init_ir_raw_event(&rawir);
                        rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
                        rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK)
                                          * CIR_SAMPLE_PERIOD);
index f563ddd7f73922e35949fb05a3f313acf0075565..ba3f95a97f144f773467ddaddcef19327211adae 100644 (file)
@@ -56,7 +56,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd);
 
 static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        unsigned i, start, overflow;
 
        dev_dbg(ir->dev, "irdata: %*ph (len=%u)", len, ir->buf_in, len);
index 7daac8bab83b02d2db1f52f394ac701971cc6125..fbacb13b614b30a5cf5cf8d9a6908d9a44bf5b07 100644 (file)
@@ -129,12 +129,10 @@ static void process_ir_data(struct iguanair *ir, unsigned len)
                        break;
                }
        } else if (len >= 7) {
-               DEFINE_IR_RAW_EVENT(rawir);
+               struct ir_raw_event rawir = {};
                unsigned i;
                bool event = false;
 
-               init_ir_raw_event(&rawir);
-
                for (i = 0; i < 7; i++) {
                        if (ir->buf_in[i] == 0x80) {
                                rawir.pulse = false;
index 32709f96de14f78822897030fe683930dbd48222..7796098d9c307a54ed811db1e6c987fadfd2535f 100644 (file)
@@ -28,7 +28,7 @@ static inline int is_bit_set(const u8 *buf, int bit)
 
 static void imon_ir_data(struct imon *imon)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        int offset = 0, size = 5 * 8;
        int bit;
 
index 700ab4c563d0cf7cabee1129e77f79cc5fa9f0df..abc4d6c1b323eef0e306955675a32665bedbdd87 100644 (file)
@@ -175,7 +175,7 @@ static irqreturn_t hix5hd2_ir_rx_interrupt(int irq, void *data)
        }
 
        if ((irq_sr & INTMS_SYMBRCV) || (irq_sr & INTMS_TIMEOUT)) {
-               DEFINE_IR_RAW_EVENT(ev);
+               struct ir_raw_event ev = {};
 
                symb_num = readl_relaxed(priv->base + IR_DATAH);
                for (i = 0; i < symb_num; i++) {
index 67c1b0c15aae37f131609f71193e172d682b498b..a0efe260539383d5739c3042af8100e688fb35dc 100644 (file)
@@ -70,24 +70,13 @@ static void ir_imon_decode_scancode(struct rc_dev *dev)
                }
 
                if (!imon->stick_keyboard) {
-                       struct lirc_scancode lsc = {
-                               .scancode = imon->bits,
-                               .rc_proto = RC_PROTO_IMON,
-                       };
+                       input_report_rel(dev->input_dev, REL_X, rel_x);
+                       input_report_rel(dev->input_dev, REL_Y, rel_y);
 
-                       ir_lirc_scancode_event(dev, &lsc);
-
-                       input_event(imon->idev, EV_MSC, MSC_SCAN, imon->bits);
-
-                       input_report_rel(imon->idev, REL_X, rel_x);
-                       input_report_rel(imon->idev, REL_Y, rel_y);
-
-                       input_report_key(imon->idev, BTN_LEFT,
+                       input_report_key(dev->input_dev, BTN_LEFT,
                                         (imon->bits & 0x00010000) != 0);
-                       input_report_key(imon->idev, BTN_RIGHT,
+                       input_report_key(dev->input_dev, BTN_RIGHT,
                                         (imon->bits & 0x00040000) != 0);
-                       input_sync(imon->idev);
-                       return;
                }
        }
 
@@ -243,62 +232,19 @@ static int ir_imon_encode(enum rc_proto protocol, u32 scancode,
 
 static int ir_imon_register(struct rc_dev *dev)
 {
-       struct input_dev *idev;
        struct imon_dec *imon = &dev->raw->imon;
-       int ret;
-
-       idev = input_allocate_device();
-       if (!idev)
-               return -ENOMEM;
-
-       snprintf(imon->name, sizeof(imon->name),
-                "iMON PAD Stick (%s)", dev->device_name);
-       idev->name = imon->name;
-       idev->phys = dev->input_phys;
-
-       /* Mouse bits */
-       set_bit(EV_REL, idev->evbit);
-       set_bit(EV_KEY, idev->evbit);
-       set_bit(REL_X, idev->relbit);
-       set_bit(REL_Y, idev->relbit);
-       set_bit(BTN_LEFT, idev->keybit);
-       set_bit(BTN_RIGHT, idev->keybit);
-
-       /* Report scancodes too */
-       set_bit(EV_MSC, idev->evbit);
-       set_bit(MSC_SCAN, idev->mscbit);
-
-       input_set_drvdata(idev, imon);
-
-       ret = input_register_device(idev);
-       if (ret < 0) {
-               input_free_device(idev);
-               return -EIO;
-       }
 
-       imon->idev = idev;
        imon->stick_keyboard = false;
 
        return 0;
 }
 
-static int ir_imon_unregister(struct rc_dev *dev)
-{
-       struct imon_dec *imon = &dev->raw->imon;
-
-       input_unregister_device(imon->idev);
-       imon->idev = NULL;
-
-       return 0;
-}
-
 static struct ir_raw_handler imon_handler = {
        .protocols      = RC_PROTO_BIT_IMON,
        .decode         = ir_imon_decode,
        .encode         = ir_imon_encode,
        .carrier        = 38000,
        .raw_register   = ir_imon_register,
-       .raw_unregister = ir_imon_unregister,
        .min_timeout    = IMON_UNIT * IMON_BITS * 2,
 };
 
index 64ea429276693a43c2e5af7bcc9f3ab8afce955c..67f1c179c713dcede5b5a5809107e2a92199905c 100644 (file)
@@ -129,13 +129,14 @@ static void mce_kbd_rx_timeout(struct timer_list *t)
        if (time_is_before_eq_jiffies(raw->mce_kbd.rx_timeout.expires)) {
                for (i = 0; i < 7; i++) {
                        maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i];
-                       input_report_key(raw->mce_kbd.idev, maskcode, 0);
+                       input_report_key(raw->dev->input_dev, maskcode, 0);
                }
 
                for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
-                       input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0);
+                       input_report_key(raw->dev->input_dev, kbd_keycodes[i],
+                                        0);
 
-               input_sync(raw->mce_kbd.idev);
+               input_sync(raw->dev->input_dev);
        }
        spin_unlock_irqrestore(&raw->mce_kbd.keylock, flags);
 }
@@ -154,7 +155,6 @@ static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data)
 
 static void ir_mce_kbd_process_keyboard_data(struct rc_dev *dev, u32 scancode)
 {
-       struct mce_kbd_dec *data = &dev->raw->mce_kbd;
        u8 keydata1  = (scancode >> 8) & 0xff;
        u8 keydata2  = (scancode >> 16) & 0xff;
        u8 shiftmask = scancode & 0xff;
@@ -170,23 +170,22 @@ static void ir_mce_kbd_process_keyboard_data(struct rc_dev *dev, u32 scancode)
                        keystate = 1;
                else
                        keystate = 0;
-               input_report_key(data->idev, maskcode, keystate);
+               input_report_key(dev->input_dev, maskcode, keystate);
        }
 
        if (keydata1)
-               input_report_key(data->idev, kbd_keycodes[keydata1], 1);
+               input_report_key(dev->input_dev, kbd_keycodes[keydata1], 1);
        if (keydata2)
-               input_report_key(data->idev, kbd_keycodes[keydata2], 1);
+               input_report_key(dev->input_dev, kbd_keycodes[keydata2], 1);
 
        if (!keydata1 && !keydata2) {
                for (i = 0; i < MCIR2_MASK_KEYS_START; i++)
-                       input_report_key(data->idev, kbd_keycodes[i], 0);
+                       input_report_key(dev->input_dev, kbd_keycodes[i], 0);
        }
 }
 
 static void ir_mce_kbd_process_mouse_data(struct rc_dev *dev, u32 scancode)
 {
-       struct mce_kbd_dec *data = &dev->raw->mce_kbd;
        /* raw mouse coordinates */
        u8 xdata = (scancode >> 7) & 0x7f;
        u8 ydata = (scancode >> 14) & 0x7f;
@@ -208,11 +207,11 @@ static void ir_mce_kbd_process_mouse_data(struct rc_dev *dev, u32 scancode)
        dev_dbg(&dev->dev, "mouse: x = %d, y = %d, btns = %s%s\n",
                x, y, left ? "L" : "", right ? "R" : "");
 
-       input_report_rel(data->idev, REL_X, x);
-       input_report_rel(data->idev, REL_Y, y);
+       input_report_rel(dev->input_dev, REL_X, x);
+       input_report_rel(dev->input_dev, REL_Y, y);
 
-       input_report_key(data->idev, BTN_LEFT, left);
-       input_report_key(data->idev, BTN_RIGHT, right);
+       input_report_key(dev->input_dev, BTN_LEFT, left);
+       input_report_key(dev->input_dev, BTN_RIGHT, right);
 }
 
 /**
@@ -355,8 +354,8 @@ again:
                lsc.scancode = scancode;
                ir_lirc_scancode_event(dev, &lsc);
                data->state = STATE_INACTIVE;
-               input_event(data->idev, EV_MSC, MSC_SCAN, scancode);
-               input_sync(data->idev);
+               input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
+               input_sync(dev->input_dev);
                return 0;
        }
 
@@ -370,66 +369,18 @@ out:
 static int ir_mce_kbd_register(struct rc_dev *dev)
 {
        struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
-       struct input_dev *idev;
-       int i, ret;
-
-       idev = input_allocate_device();
-       if (!idev)
-               return -ENOMEM;
-
-       snprintf(mce_kbd->name, sizeof(mce_kbd->name),
-                "MCE IR Keyboard/Mouse (%s)", dev->driver_name);
-       strlcat(mce_kbd->phys, "/input0", sizeof(mce_kbd->phys));
-
-       idev->name = mce_kbd->name;
-       idev->phys = mce_kbd->phys;
-
-       /* Keyboard bits */
-       set_bit(EV_KEY, idev->evbit);
-       set_bit(EV_REP, idev->evbit);
-       for (i = 0; i < sizeof(kbd_keycodes); i++)
-               set_bit(kbd_keycodes[i], idev->keybit);
-
-       /* Mouse bits */
-       set_bit(EV_REL, idev->evbit);
-       set_bit(REL_X, idev->relbit);
-       set_bit(REL_Y, idev->relbit);
-       set_bit(BTN_LEFT, idev->keybit);
-       set_bit(BTN_RIGHT, idev->keybit);
-
-       /* Report scancodes too */
-       set_bit(EV_MSC, idev->evbit);
-       set_bit(MSC_SCAN, idev->mscbit);
 
        timer_setup(&mce_kbd->rx_timeout, mce_kbd_rx_timeout, 0);
        spin_lock_init(&mce_kbd->keylock);
 
-       input_set_drvdata(idev, mce_kbd);
-
-#if 0
-       /* Adding this reference means two input devices are associated with
-        * this rc-core device, which ir-keytable doesn't cope with yet */
-       idev->dev.parent = &dev->dev;
-#endif
-
-       ret = input_register_device(idev);
-       if (ret < 0) {
-               input_free_device(idev);
-               return -EIO;
-       }
-
-       mce_kbd->idev = idev;
-
        return 0;
 }
 
 static int ir_mce_kbd_unregister(struct rc_dev *dev)
 {
        struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
-       struct input_dev *idev = mce_kbd->idev;
 
        del_timer_sync(&mce_kbd->rx_timeout);
-       input_unregister_device(idev);
 
        return 0;
 }
index 68487ce9f79b618e213aaba9dcb0a5ae069baf15..d96aed1343e4208afef093e04383e549265657ab 100644 (file)
@@ -40,6 +40,7 @@
 #define RC6_6A_MCE_TOGGLE_MASK 0x8000  /* for the body bits */
 #define RC6_6A_LCC_MASK                0xffff0000 /* RC6-6A-32 long customer code mask */
 #define RC6_6A_MCE_CC          0x800f0000 /* MCE customer code */
+#define RC6_6A_KATHREIN_CC     0x80460000 /* Kathrein RCU-676 customer code */
 #ifndef CHAR_BIT
 #define CHAR_BIT 8     /* Normally in <limits.h> */
 #endif
@@ -242,13 +243,17 @@ again:
                                toggle = 0;
                                break;
                        case 32:
-                               if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
+                               switch (scancode & RC6_6A_LCC_MASK) {
+                               case RC6_6A_MCE_CC:
+                               case RC6_6A_KATHREIN_CC:
                                        protocol = RC_PROTO_RC6_MCE;
                                        toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
                                        scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
-                               } else {
+                                       break;
+                               default:
                                        protocol = RC_PROTO_RC6_6A_32;
                                        toggle = 0;
+                                       break;
                                }
                                break;
                        default:
index de77d22c30a708300a19332cfb8d21b4e72ed357..cd3c60ba8519ba92c247a0be319d5e09bb66f689 100644 (file)
@@ -173,7 +173,7 @@ static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int
        u32 sample_period;
        unsigned long *ldata;
        unsigned int next_one, next_zero, size;
-       DEFINE_IR_RAW_EVENT(ev);
+       struct ir_raw_event ev = {};
 
        if (length == 0)
                return;
@@ -1507,9 +1507,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
        /* initialize spinlocks */
        spin_lock_init(&itdev->lock);
 
-       /* initialize raw event */
-       init_ir_raw_event(&itdev->rawir);
-
        /* set driver data into the pnp device */
        pnp_set_drvdata(pdev, itdev);
        itdev->pdev = pdev;
index 9b1b57e3c875ea915f491a6535cc09eed56e94d2..e1b2c8e268834e20876a82fa43606c7191a898ef 100644 (file)
@@ -115,7 +115,7 @@ static struct rc_map_list behold_map = {
        .map = {
                .scan     = behold,
                .size     = ARRAY_SIZE(behold),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_BEHOLD,
        }
 };
index 62de69d78d92e394d0c60fc961f9f83730442c47..da21d6d6d79f0a2fac67eb71489e8f99edbfcf44 100644 (file)
@@ -60,7 +60,7 @@ static struct rc_map_list delock_61959_map = {
        .map = {
                .scan     = delock_61959,
                .size     = ARRAY_SIZE(delock_61959),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_DELOCK_61959,
        }
 };
index 83e4564aaa22fa7e6f1e07e146891eca6e502805..6f7ee485968251b8e8f28b6b87e959a94f38b54b 100644 (file)
@@ -59,7 +59,7 @@ static struct rc_map_list imon_rsc_map = {
        .map = {
                .scan     = imon_rsc,
                .size     = ARRAY_SIZE(imon_rsc),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_IMON_RSC,
        }
 };
index 908d14848ae8ae51ba61e86f8fca8f98c1b180b8..f1b5c52953ade22e827413eab0b616376bbf2113 100644 (file)
@@ -73,7 +73,7 @@ static struct rc_map_list it913x_v1_map = {
        .map = {
                .scan     = it913x_v1_rc,
                .size     = ARRAY_SIZE(it913x_v1_rc),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_IT913X_V1,
        }
 };
index 05ab7fa4f90b5cb91bc9618d96cc35a2833a57ac..be5dfb4fae4651d38e7b82738b2c36453a597761 100644 (file)
@@ -72,7 +72,7 @@ static struct rc_map_list it913x_v2_map = {
        .map = {
                .scan     = it913x_v2_rc,
                .size     = ARRAY_SIZE(it913x_v2_rc),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_IT913X_V2,
        }
 };
index 8fec0c1dcb126afa99a8d7fb703f8d1e5f5839a1..d50e741c73b7c64535e21d852b6699c40bf5f1b2 100644 (file)
@@ -64,7 +64,7 @@ static struct rc_map_list msi_digivox_iii_map = {
        .map = {
                .scan     = msi_digivox_iii,
                .size     = ARRAY_SIZE(msi_digivox_iii),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_MSI_DIGIVOX_III,
        }
 };
index 4ed85f61d0eef107a0428650353ee6e229315665..c0550e09f2555efe90fb0ef5d9a2d082e0e3cbdd 100644 (file)
@@ -51,7 +51,7 @@ static struct rc_map_list pixelview_map = {
        .map = {
                .scan     = pixelview_002t,
                .size     = ARRAY_SIZE(pixelview_002t),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_PIXELVIEW_002T,
        }
 };
index 6ded64b732a591ceb066bccbf9d7cec71c517279..864c8ea5d8e321203dd5a916825ec690ca54cc87 100644 (file)
@@ -57,7 +57,7 @@ static struct rc_map_list pixelview_map = {
        .map = {
                .scan     = pixelview_mk12,
                .size     = ARRAY_SIZE(pixelview_mk12),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_PIXELVIEW_MK12,
        }
 };
index 3b37acc7b144d5d2f7290b76895d05e86c2df886..b73223e8c238f5da7f38ff088e2e593c2dcee0c2 100644 (file)
@@ -64,7 +64,7 @@ static struct rc_map_list reddo_map = {
        .map = {
                .scan     = reddo,
                .size     = ARRAY_SIZE(reddo),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_REDDO,
        }
 };
index 628272c58d659f2c0f2107dfcd0c8aa72125a100..58a209811d1284968d4b39c6fae05c30e63dc6f3 100644 (file)
@@ -58,7 +58,7 @@ static struct rc_map_list terratec_slim_map = {
        .map = {
                .scan     = terratec_slim,
                .size     = ARRAY_SIZE(terratec_slim),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_TERRATEC_SLIM,
        }
 };
index 1962e33c8f4e472ed2fae8af2b3773b6094a6228..20268f8b18fddd01f684b2829f3627df74ebcdd9 100644 (file)
@@ -77,7 +77,7 @@ static struct rc_map_list tivo_map = {
        .map = {
                .scan     = tivo,
                .size     = ARRAY_SIZE(tivo),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NEC32,
                .name     = RC_MAP_TIVO,
        }
 };
index bc73bee309d8ee720bcc0d14ed2dbfa106c1eb4e..c34e8f5a88b6c35d5dd41e6fc6d6ae643d4bce23 100644 (file)
@@ -64,7 +64,7 @@ static struct rc_map_list total_media_in_hand_map = {
        .map = {
                .scan     = total_media_in_hand,
                .size     = ARRAY_SIZE(total_media_in_hand),
-               .rc_proto = RC_PROTO_NEC,
+               .rc_proto = RC_PROTO_NECX,
                .name     = RC_MAP_TOTAL_MEDIA_IN_HAND,
        }
 };
index 4c0c8008872aed48b4dac05063eb4c8831f2283b..c9293696dc2deee3a7a912f8a50ba73310e2425a 100644 (file)
@@ -1078,7 +1078,7 @@ static int mceusb_set_rx_carrier_report(struct rc_dev *dev, int enable)
  */
 static void mceusb_handle_command(struct mceusb_dev *ir, int index)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        u8 hi = ir->buf_in[index + 1] & 0xff;
        u8 lo = ir->buf_in[index + 2] & 0xff;
        u32 carrier_cycles;
@@ -1152,7 +1152,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
 
 static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        bool event = false;
        int i = 0;
 
@@ -1175,7 +1175,6 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                        break;
                case PARSE_IRDATA:
                        ir->rem--;
-                       init_ir_raw_event(&rawir);
                        rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
                        rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK);
                        if (unlikely(!rawir.duration)) {
@@ -1215,11 +1214,13 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                        if (ir->rem) {
                                ir->parser_state = PARSE_IRDATA;
                        } else {
-                               init_ir_raw_event(&rawir);
-                               rawir.timeout = 1;
-                               rawir.duration = ir->rc->timeout;
+                               struct ir_raw_event ev = {
+                                       .timeout = 1,
+                                       .duration = ir->rc->timeout
+                               };
+
                                if (ir_raw_event_store_with_filter(ir->rc,
-                                                                  &rawir))
+                                                                  &ev))
                                        event = true;
                                ir->pulse_tunit = 0;
                                ir->pulse_count = 0;
@@ -1603,7 +1604,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
        if (dev->descriptor.iManufacturer
            && usb_string(dev, dev->descriptor.iManufacturer,
                          buf, sizeof(buf)) > 0)
-               strlcpy(name, buf, sizeof(name));
+               strscpy(name, buf, sizeof(name));
        if (dev->descriptor.iProduct
            && usb_string(dev, dev->descriptor.iProduct,
                          buf, sizeof(buf)) > 0)
index f449b35d25e7378c034d6334393d64982187e731..9914c83fecb983d9be4cfe75efdd72d87ab943c7 100644 (file)
@@ -86,7 +86,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
 {
        struct meson_ir *ir = dev_id;
        u32 duration, status;
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        spin_lock(&ir->lock);
 
index e42efd9d382ec4290413e606b6f6040c28805cfe..31b7bb431497f44ff99c46e82fe289f9654d5033 100644 (file)
@@ -212,7 +212,7 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id)
        struct mtk_ir *ir = dev_id;
        u8  wid = 0;
        u32 i, j, val;
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        /*
         * Reset decoder state machine explicitly is required
index b8299c9a9744f50735760ecd3ed3161f52399206..5c2cd8d2d1555b610084fe486775047d3296e41d 100644 (file)
@@ -737,7 +737,7 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt)
  */
 static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        u8 sample;
        int i;
 
index e847bdad5c51ca3e65e8d7961f9a298a4c30f49c..c2cbe7f6266cc61a40999d452515f835a15e9c45 100644 (file)
@@ -110,12 +110,9 @@ struct ir_raw_event_ctrl {
                unsigned int pulse_len;
        } sharp;
        struct mce_kbd_dec {
-               struct input_dev *idev;
                /* locks key up timer */
                spinlock_t keylock;
                struct timer_list rx_timeout;
-               char name[64];
-               char phys[64];
                int state;
                u8 header;
                u32 body;
@@ -133,8 +130,6 @@ struct ir_raw_event_ctrl {
                int last_chk;
                unsigned int bits;
                bool stick_keyboard;
-               struct input_dev *idev;
-               char name[64];
        } imon;
 };
 
@@ -181,9 +176,10 @@ static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,
                                              unsigned int pulse,
                                              u32 duration)
 {
-       init_ir_raw_event(ev);
-       ev->duration = duration;
-       ev->pulse = pulse;
+       *ev = (struct ir_raw_event) {
+               .duration = duration,
+               .pulse = pulse
+       };
 }
 
 /**
index e7948908e78c80194cf40b194054afcfb13df46a..e10b4644a442d7c91ce9aa0eeb1174e8ba414b15 100644 (file)
@@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
 int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
 {
        ktime_t                 now;
-       DEFINE_IR_RAW_EVENT(ev);
+       struct ir_raw_event     ev = {};
 
        if (!dev->raw)
                return -EINVAL;
@@ -210,7 +210,7 @@ void ir_raw_event_set_idle(struct rc_dev *dev, bool idle)
        if (idle) {
                dev->raw->this_ev.timeout = true;
                ir_raw_event_store(dev, &dev->raw->this_ev);
-               init_ir_raw_event(&dev->raw->this_ev);
+               dev->raw->this_ev = (struct ir_raw_event) {};
        }
 
        if (dev->s_idle)
@@ -562,10 +562,10 @@ static void ir_raw_edge_handle(struct timer_list *t)
        spin_lock_irqsave(&dev->raw->edge_spinlock, flags);
        interval = ktime_sub(ktime_get(), dev->raw->last_event);
        if (ktime_to_ns(interval) >= dev->timeout) {
-               DEFINE_IR_RAW_EVENT(ev);
-
-               ev.timeout = true;
-               ev.duration = ktime_to_ns(interval);
+               struct ir_raw_event ev = {
+                       .timeout = true,
+                       .duration = ktime_to_ns(interval)
+               };
 
                ir_raw_event_store(dev, &ev);
        } else {
index 3822d9ebcb46cab913163420ababa9915ed928e8..b9f9325b8db1891b5018a5bcf5fdf519b17a6260 100644 (file)
@@ -103,7 +103,7 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
        struct loopback_dev *lodev = dev->priv;
        u32 rxmask;
        unsigned i;
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        if (lodev->txcarrier < lodev->rxcarriermin ||
            lodev->txcarrier > lodev->rxcarriermax) {
index ca68e1d2b2f989cf366bdecc999db5e388d50e11..552bbe82a160a80812cbcf456c798d818f7cdece 100644 (file)
@@ -274,7 +274,6 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
                                      unsigned int new_keycode)
 {
        int old_keycode = rc_map->scan[index].keycode;
-       int i;
 
        /* Did the user wish to remove the mapping? */
        if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
@@ -289,20 +288,9 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
                        old_keycode == KEY_RESERVED ? "New" : "Replacing",
                        rc_map->scan[index].scancode, new_keycode);
                rc_map->scan[index].keycode = new_keycode;
-               __set_bit(new_keycode, dev->input_dev->keybit);
        }
 
        if (old_keycode != KEY_RESERVED) {
-               /* A previous mapping was updated... */
-               __clear_bit(old_keycode, dev->input_dev->keybit);
-               /* ... but another scancode might use the same keycode */
-               for (i = 0; i < rc_map->len; i++) {
-                       if (rc_map->scan[i].keycode == old_keycode) {
-                               __set_bit(old_keycode, dev->input_dev->keybit);
-                               break;
-                       }
-               }
-
                /* Possibly shrink the keytable, failure is not a problem */
                ir_resize_table(dev, rc_map, GFP_ATOMIC);
        }
@@ -1755,10 +1743,18 @@ static int rc_prepare_rx_device(struct rc_dev *dev)
                dev->enabled_protocols = rc_proto;
        }
 
+       /* Keyboard events */
        set_bit(EV_KEY, dev->input_dev->evbit);
        set_bit(EV_REP, dev->input_dev->evbit);
        set_bit(EV_MSC, dev->input_dev->evbit);
        set_bit(MSC_SCAN, dev->input_dev->mscbit);
+       bitmap_fill(dev->input_dev->keybit, KEY_CNT);
+
+       /* Pointer/mouse events */
+       set_bit(EV_REL, dev->input_dev->evbit);
+       set_bit(REL_X, dev->input_dev->relbit);
+       set_bit(REL_Y, dev->input_dev->relbit);
+
        if (dev->open)
                dev->input_dev->open = ir_open;
        if (dev->close)
index 6bfc24885b5c4180776d87a042882a27cf777926..08c51ffd74a0e3f35ae14a090dadc78e5d57c161 100644 (file)
@@ -348,7 +348,7 @@ static u32 redrat3_us_to_len(u32 microsec)
 
 static void redrat3_process_ir_data(struct redrat3_dev *rr3)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        struct device *dev;
        unsigned int i, sig_size, single_len, offset, val;
        u32 mod_freq;
@@ -358,10 +358,10 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3)
        mod_freq = redrat3_val_to_mod_freq(&rr3->irdata);
        dev_dbg(dev, "Got mod_freq of %u\n", mod_freq);
        if (mod_freq && rr3->wideband) {
-               DEFINE_IR_RAW_EVENT(ev);
-
-               ev.carrier_report = 1;
-               ev.carrier = mod_freq;
+               struct ir_raw_event ev = {
+                       .carrier_report = 1,
+                       .carrier = mod_freq
+               };
 
                ir_raw_event_store(rr3->rc, &ev);
        }
index 8bf5637b3a69aca4a2fbf9ba4fe4f74c449fd233..ffe2c672d105c5dc7eb7c723b68ba5e2e8b84e1b 100644 (file)
@@ -273,7 +273,7 @@ static void frbwrite(unsigned int l, bool is_pulse)
 {
        /* simple noise filter */
        static unsigned int ptr, pulse, space;
-       DEFINE_IR_RAW_EVENT(ev);
+       struct ir_raw_event ev = {};
 
        if (ptr > 0 && is_pulse) {
                pulse += l;
@@ -472,10 +472,10 @@ static int hardware_init_port(void)
 
 static void serial_ir_timeout(struct timer_list *unused)
 {
-       DEFINE_IR_RAW_EVENT(ev);
-
-       ev.timeout = true;
-       ev.duration = serial_ir.rcdev->timeout;
+       struct ir_raw_event ev = {
+               .timeout = true,
+               .duration = serial_ir.rcdev->timeout
+       };
        ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
        ir_raw_event_handle(serial_ir.rcdev);
 }
index 9ee2c9196b4d81fd64c90937eccaac7a69252383..c8951650a36830aba8cc74a897896032e9f0a623 100644 (file)
@@ -96,7 +96,7 @@ static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf,
 
 static void add_read_queue(int flag, unsigned long val)
 {
-       DEFINE_IR_RAW_EVENT(ev);
+       struct ir_raw_event ev = {};
 
        pr_debug("add flag %d with val %lu\n", flag, val);
 
index c855b177103c85742c4adf9e33f81df74e6519e3..15de3ae166a2d96166c5716ecd66fed22763239e 100644 (file)
@@ -67,8 +67,7 @@ struct st_rc_device {
 
 static void st_rc_send_lirc_timeout(struct rc_dev *rdev)
 {
-       DEFINE_IR_RAW_EVENT(ev);
-       ev.timeout = true;
+       struct ir_raw_event ev = { .timeout = true, .duration = rdev->timeout };
        ir_raw_event_store(rdev, &ev);
 }
 
@@ -101,7 +100,7 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data)
        struct st_rc_device *dev = data;
        int last_symbol = 0;
        u32 status, int_status;
-       DEFINE_IR_RAW_EVENT(ev);
+       struct ir_raw_event ev = {};
 
        if (dev->irq_wake)
                pm_wakeup_event(dev->dev, 0);
index c9a70fda88a88bcd02b45137581896857c612bb9..a490d26bd1703866d02fa608a442ef87bf6bfe3f 100644 (file)
@@ -130,7 +130,7 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
 static void sz_push_full_pulse(struct streamzap_ir *sz,
                               unsigned char value)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        if (sz->idle) {
                int delta;
@@ -175,7 +175,7 @@ static void sz_push_half_pulse(struct streamzap_ir *sz,
 static void sz_push_full_space(struct streamzap_ir *sz,
                               unsigned char value)
 {
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        rawir.pulse = false;
        rawir.duration = ((int) value) * SZ_RESOLUTION;
@@ -249,10 +249,10 @@ static void streamzap_callback(struct urb *urb)
                        break;
                case FullSpace:
                        if (sz->buf_in[i] == SZ_TIMEOUT) {
-                               DEFINE_IR_RAW_EVENT(rawir);
-
-                               rawir.pulse = false;
-                               rawir.duration = sz->rdev->timeout;
+                               struct ir_raw_event rawir = {
+                                       .pulse = false,
+                                       .duration = sz->rdev->timeout
+                               };
                                sz->idle = true;
                                if (sz->timeout_enabled)
                                        sz_push(sz, rawir);
@@ -396,7 +396,7 @@ static int streamzap_probe(struct usb_interface *intf,
        if (usbdev->descriptor.iManufacturer
            && usb_string(usbdev, usbdev->descriptor.iManufacturer,
                          buf, sizeof(buf)) > 0)
-               strlcpy(name, buf, sizeof(name));
+               strscpy(name, buf, sizeof(name));
 
        if (usbdev->descriptor.iProduct
            && usb_string(usbdev, usbdev->descriptor.iProduct,
index f500cea228a95524dfaa959980c17212245210a5..307e44714ea048fbcde933100059dc58107f2e2b 100644 (file)
@@ -99,7 +99,7 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
        unsigned char dt;
        unsigned int cnt, rc;
        struct sunxi_ir *ir = dev_id;
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
 
        spin_lock(&ir->ir_lock);
 
index aafea3c5170b10d77168184f8c0f986067da82eb..8d4b56d057aeed76fcea50b7adfa6d4be441863c 100644 (file)
@@ -117,12 +117,10 @@ static void ttusbir_bulk_complete(struct urb *urb)
  */
 static void ttusbir_process_ir_data(struct ttusbir *tt, uint8_t *buf)
 {
-       struct ir_raw_event rawir;
+       struct ir_raw_event rawir = {};
        unsigned i, v, b;
        bool event = false;
 
-       init_ir_raw_event(&rawir);
-
        for (i = 0; i < 128; i++) {
                v = buf[i] & 0xfe;
                switch (v) {
index 851acba9b436c50d6498636891a2d7fc91bffb7b..0f07a2c384fafcbfe86774c4434f7655b13670d4 100644 (file)
@@ -322,11 +322,11 @@ wbcir_carrier_report(struct wbcir_data *data)
                        inb(data->ebase + WBCIR_REG_ECEIR_CNT_HI) << 8;
 
        if (counter > 0 && counter < 0xffff) {
-               DEFINE_IR_RAW_EVENT(ev);
-
-               ev.carrier_report = 1;
-               ev.carrier = DIV_ROUND_CLOSEST(counter * 1000000u,
-                                               data->pulse_duration);
+               struct ir_raw_event ev = {
+                       .carrier_report = 1,
+                       .carrier = DIV_ROUND_CLOSEST(counter * 1000000u,
+                                               data->pulse_duration)
+               };
 
                ir_raw_event_store(data->dev, &ev);
        }
@@ -362,7 +362,7 @@ static void
 wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
 {
        u8 irdata;
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        unsigned duration;
 
        /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
index fbec1a13dc6a542ab4d495a8ad469bf2d585540c..91956fb55b75051e4119d18240b1e1b043bb8de3 100644 (file)
@@ -312,7 +312,7 @@ static int e4000_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
 
        dev_dbg(&client->dev, "index=%d\n", v->index);
 
-       strlcpy(v->name, "Elonics E4000", sizeof(v->name));
+       strscpy(v->name, "Elonics E4000", sizeof(v->name));
        v->type = V4L2_TUNER_RF;
        v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
        v->rangelow  = bands[0].rangelow;
index db26892aac844be91a33c54c5a9c2f74e8d4be1e..dd88cf7148d0b738901ea4ca482ce8206cde2612 100644 (file)
@@ -405,7 +405,7 @@ static int fc2580_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
 
        dev_dbg(&client->dev, "index=%d\n", v->index);
 
-       strlcpy(v->name, "FCI FC2580", sizeof(v->name));
+       strscpy(v->name, "FCI FC2580", sizeof(v->name));
        v->type = V4L2_TUNER_RF;
        v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
        v->rangelow  = bands[0].rangelow;
index 5de6ed72870853bb39cc7e872621ab4199757f20..331c198c00bb4e904b37a7eb9cf09a495b07f219 100644 (file)
@@ -305,7 +305,7 @@ static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
 
        dev_dbg(&spi->dev, "index=%d\n", v->index);
 
-       strlcpy(v->name, "Mirics MSi001", sizeof(v->name));
+       strscpy(v->name, "Mirics MSi001", sizeof(v->name));
        v->type = V4L2_TUNER_RF;
        v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
        v->rangelow =    49000000;
index 129bf8e1aff8c1003ef97eb18ce1029472ddde46..8b4ce84b6914c3ec0a8fdfdb58ea4a00f9b5e94b 100644 (file)
@@ -636,7 +636,7 @@ struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
                return NULL;
        }
 
-       strlcpy(fe->ops.tuner_ops.info.name, name,
+       strscpy(fe->ops.tuner_ops.info.name, name,
                sizeof(fe->ops.tuner_ops.info.name));
        tuner_info("microtune %s found, OK\n",name);
        return fe;
index a08d8fe2bb1b035e40e8004602d4b4dbe42db037..d389f1fc237aac4a12652c59e8a8e6f579455ae7 100644 (file)
@@ -468,11 +468,14 @@ static int si2157_probe(struct i2c_client *client,
                dev->ent.name = KBUILD_MODNAME;
                dev->ent.function = MEDIA_ENT_F_TUNER;
 
-               dev->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
-               dev->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
-               dev->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE;
-
-               ret = media_entity_pads_init(&dev->ent, TUNER_NUM_PADS,
+               dev->pad[SI2157_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
+               dev->pad[SI2157_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
+               dev->pad[SI2157_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               dev->pad[SI2157_PAD_VID_OUT].sig_type = PAD_SIGNAL_ANALOG;
+               dev->pad[SI2157_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               dev->pad[SI2157_PAD_AUD_OUT].sig_type = PAD_SIGNAL_AUDIO;
+
+               ret = media_entity_pads_init(&dev->ent, SI2157_NUM_PADS,
                                             &dev->pad[0]);
 
                if (ret)
index e6436f74abaafb502f9ac0248a988ce5ec6b343e..50f86300d9651e8cf7059f8aabddb403869503e2 100644 (file)
 #include <media/v4l2-mc.h>
 #include "si2157.h"
 
+enum si2157_pads {
+       SI2157_PAD_RF_INPUT,
+       SI2157_PAD_VID_OUT,
+       SI2157_PAD_AUD_OUT,
+       SI2157_NUM_PADS
+};
+
 /* state struct */
 struct si2157_dev {
        struct mutex i2c_mutex;
@@ -35,7 +42,7 @@ struct si2157_dev {
 #if defined(CONFIG_MEDIA_CONTROLLER)
        struct media_device     *mdev;
        struct media_entity     ent;
-       struct media_pad        pad[TUNER_NUM_PADS];
+       struct media_pad        pad[SI2157_NUM_PADS];
 #endif
 
 };
index 29c1473f2e9f6448890a451aea9b02112a7a8ca8..d2169bb3111a2817e9f643171cdc61722c9128d2 100644 (file)
@@ -1130,7 +1130,7 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
                                   priv->nr, dtv_input[priv->nr]);
        }
 
-       strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name,
+       strscpy(fe->ops.tuner_ops.info.name, priv->tun->name,
                sizeof(fe->ops.tuner_ops.info.name));
 
        return fe;
index e70c9e2f3798de12a3f75b2bef86dc007e5170ad..41fa0f93143d45c81eb3c70a4e028a4efc191cc4 100644 (file)
@@ -619,8 +619,8 @@ static int airspy_querycap(struct file *file, void *fh,
 {
        struct airspy *s = video_drvdata(file);
 
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, s->vdev.name, sizeof(cap->card));
        usb_make_path(s->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
                        V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
@@ -635,7 +635,7 @@ static int airspy_enum_fmt_sdr_cap(struct file *file, void *priv,
        if (f->index >= NUM_FORMATS)
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       strscpy(f->description, formats[f->index].name, sizeof(f->description));
        f->pixelformat = formats[f->index].pixelformat;
 
        return 0;
@@ -720,14 +720,14 @@ static int airspy_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
        int ret;
 
        if (v->index == 0) {
-               strlcpy(v->name, "AirSpy ADC", sizeof(v->name));
+               strscpy(v->name, "AirSpy ADC", sizeof(v->name));
                v->type = V4L2_TUNER_ADC;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow  = bands[0].rangelow;
                v->rangehigh = bands[0].rangehigh;
                ret = 0;
        } else if (v->index == 1) {
-               strlcpy(v->name, "AirSpy RF", sizeof(v->name));
+               strscpy(v->name, "AirSpy RF", sizeof(v->name));
                v->type = V4L2_TUNER_RF;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow  = bands_rf[0].rangelow;
index cd363a2100d453c6b5be15b35430907acd44cdde..1fdb1601dc653e64cb2b7f044eca36b33da9c8c1 100644 (file)
@@ -266,11 +266,13 @@ static void au0828_media_graph_notify(struct media_entity *new,
 
 create_link:
        if (decoder && mixer) {
-               ret = media_create_pad_link(decoder,
-                                           DEMOD_PAD_AUDIO_OUT,
-                                           mixer, 0,
-                                           MEDIA_LNK_FL_ENABLED);
-               if (ret)
+               ret = media_get_pad_index(decoder, false,
+                                         PAD_SIGNAL_AUDIO);
+               if (ret >= 0)
+                       ret = media_create_pad_link(decoder, ret,
+                                                   mixer, 0,
+                                                   MEDIA_LNK_FL_ENABLED);
+               if (ret < 0)
                        dev_err(&dev->usbdev->dev,
                                "Mixer Pad Link Create Error: %d\n", ret);
        }
@@ -626,17 +628,16 @@ static int au0828_usb_probe(struct usb_interface *interface,
        /* Analog TV */
        retval = au0828_analog_register(dev, interface);
        if (retval) {
-               pr_err("%s() au0282_dev_register failed to register on V4L2\n",
+               pr_err("%s() au0828_analog_register failed to register on V4L2\n",
                        __func__);
                mutex_unlock(&dev->lock);
-               kfree(dev);
                goto done;
        }
 
        /* Digital TV */
        retval = au0828_dvb_register(dev);
        if (retval)
-               pr_err("%s() au0282_dev_register failed\n",
+               pr_err("%s() au0828_dvb_register failed\n",
                       __func__);
 
        /* Remote controller */
index 1b8ec5d9e7ab8aca9f9dff2cdbe25fdf7fdee130..92df5b5463aff2845d6eab0b980fc414ca22d66b 100644 (file)
@@ -378,7 +378,7 @@ int au0828_i2c_register(struct au0828_dev *dev)
 
        dev->i2c_adap.dev.parent = &dev->usbdev->dev;
 
-       strlcpy(dev->i2c_adap.name, KBUILD_MODNAME,
+       strscpy(dev->i2c_adap.name, KBUILD_MODNAME,
                sizeof(dev->i2c_adap.name));
 
        dev->i2c_adap.algo = &dev->i2c_algo;
index 832ed9f25784512e3b544f50ee228043b4a702dd..4befa920246ca43db4853bdc9a8d87d000bb7b29 100644 (file)
@@ -113,7 +113,7 @@ static int au8522_rc_andor(struct au0828_rc *ir, u16 reg, u8 mask, u8 value)
 static int au0828_get_key_au8522(struct au0828_rc *ir)
 {
        unsigned char buf[40];
-       DEFINE_IR_RAW_EVENT(rawir);
+       struct ir_raw_event rawir = {};
        int i, j, rc;
        int prv_bit, bit, width;
        bool first = true;
@@ -167,7 +167,6 @@ static int au0828_get_key_au8522(struct au0828_rc *ir)
                        if (first) {
                                first = false;
 
-                               init_ir_raw_event(&rawir);
                                rawir.pulse = true;
                                if (width > NEC_START_SPACE - 2 &&
                                    width < NEC_START_SPACE + 2) {
@@ -186,7 +185,6 @@ static int au0828_get_key_au8522(struct au0828_rc *ir)
                                ir_raw_event_store(ir->rc, &rawir);
                        }
 
-                       init_ir_raw_event(&rawir);
                        rawir.pulse = prv_bit ? false : true;
                        rawir.duration = AU8522_UNIT * width;
                        dprintk(16, "Storing %s with duration %d",
@@ -199,7 +197,6 @@ static int au0828_get_key_au8522(struct au0828_rc *ir)
                }
        }
 
-       init_ir_raw_event(&rawir);
        rawir.pulse = prv_bit ? false : true;
        rawir.duration = AU8522_UNIT * width;
        dprintk(16, "Storing end %s with duration %d",
index 62b45062b1e685ebdc3dd271c439c57d78a90812..efbf210147c73a289b443cc938c6d2c32798b436 100644 (file)
@@ -1191,8 +1191,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
-       strlcpy(cap->driver, "au0828", sizeof(cap->driver));
-       strlcpy(cap->card, dev->board.name, sizeof(cap->card));
+       strscpy(cap->driver, "au0828", sizeof(cap->driver));
+       strscpy(cap->card, dev->board.name, sizeof(cap->card));
        usb_make_path(dev->usbdev, cap->bus_info, sizeof(cap->bus_info));
 
        /* set the device capabilities */
@@ -1218,7 +1218,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        dprintk(1, "%s called\n", __func__);
 
        f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       strcpy(f->description, "Packed YUV2");
+       strscpy(f->description, "Packed YUV2", sizeof(f->description));
 
        f->flags = 0;
        f->pixelformat = V4L2_PIX_FMT_UYVY;
@@ -1349,7 +1349,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        input->index = tmp;
-       strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
+       strscpy(input->name, inames[AUVI_INPUT(tmp).type], sizeof(input->name));
        if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
            (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) {
                input->type |= V4L2_INPUT_TYPE_TUNER;
@@ -1465,9 +1465,9 @@ static int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *a)
        dprintk(1, "%s called\n", __func__);
 
        if (a->index == 0)
-               strcpy(a->name, "Television");
+               strscpy(a->name, "Television", sizeof(a->name));
        else
-               strcpy(a->name, "Line in");
+               strscpy(a->name, "Line in", sizeof(a->name));
 
        a->capability = V4L2_AUDCAP_STEREO;
        return 0;
@@ -1482,9 +1482,9 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
 
        a->index = dev->ctrl_ainput;
        if (a->index == 0)
-               strcpy(a->name, "Television");
+               strscpy(a->name, "Television", sizeof(a->name));
        else
-               strcpy(a->name, "Line in");
+               strscpy(a->name, "Line in", sizeof(a->name));
 
        a->capability = V4L2_AUDCAP_STEREO;
        return 0;
@@ -1518,7 +1518,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
        dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
-       strcpy(t->name, "Auvitek tuner");
+       strscpy(t->name, "Auvitek tuner", sizeof(t->name));
 
        au0828_init_tuner(dev);
        i2c_gate_ctrl(dev, 1);
@@ -1978,7 +1978,7 @@ int au0828_analog_register(struct au0828_dev *dev,
        dev->vdev.lock = &dev->lock;
        dev->vdev.queue = &dev->vb_vidq;
        dev->vdev.queue->lock = &dev->vb_queue_lock;
-       strcpy(dev->vdev.name, "au0828a video");
+       strscpy(dev->vdev.name, "au0828a video", sizeof(dev->vdev.name));
 
        /* Setup the VBI device */
        dev->vbi_dev = au0828_video_template;
@@ -1986,7 +1986,7 @@ int au0828_analog_register(struct au0828_dev *dev,
        dev->vbi_dev.lock = &dev->lock;
        dev->vbi_dev.queue = &dev->vb_vbiq;
        dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock;
-       strcpy(dev->vbi_dev.name, "au0828a vbi");
+       strscpy(dev->vbi_dev.name, "au0828a vbi", sizeof(dev->vbi_dev.name));
 
        /* Init entities at the Media Controller */
        au0828_analog_create_entities(dev);
index 99f106b13280f1f6d16685f69b8b8c7d1d316d11..3f401fbd0ecc675391bd16e6421df43ddd660468 100644 (file)
@@ -219,12 +219,12 @@ static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *v
 {
        struct camera_data *cam = video_drvdata(file);
 
-       strcpy(vc->driver, "cpia2");
+       strscpy(vc->driver, "cpia2", sizeof(vc->driver));
 
        if (cam->params.pnp_id.product == 0x151)
-               strcpy(vc->card, "QX5 Microscope");
+               strscpy(vc->card, "QX5 Microscope", sizeof(vc->card));
        else
-               strcpy(vc->card, "CPiA2 Camera");
+               strscpy(vc->card, "CPiA2 Camera", sizeof(vc->card));
        switch (cam->params.pnp_id.device_type) {
        case DEVICE_STV_672:
                strcat(vc->card, " (672/");
@@ -281,7 +281,7 @@ static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 {
        if (i->index)
                return -EINVAL;
-       strcpy(i->name, "Camera");
+       strscpy(i->name, "Camera", sizeof(i->name));
        i->type = V4L2_INPUT_TYPE_CAMERA;
        return 0;
 }
@@ -319,11 +319,11 @@ static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
        f->flags = V4L2_FMT_FLAG_COMPRESSED;
        switch(index) {
        case 0:
-               strcpy(f->description, "MJPEG");
+               strscpy(f->description, "MJPEG", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_MJPEG;
                break;
        case 1:
-               strcpy(f->description, "JPEG");
+               strscpy(f->description, "JPEG", sizeof(f->description));
                f->pixelformat = V4L2_PIX_FMT_JPEG;
                break;
        default:
@@ -949,7 +949,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
        buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
        buf->length = cam->frame_size;
        buf->reserved2 = 0;
-       buf->reserved = 0;
+       buf->request_fd = 0;
        memset(&buf->timecode, 0, sizeof(buf->timecode));
 
        DBG("DQBUF #%d status:%d seq:%d length:%d\n", buf->index,
index 2f3b0564d676d3d4927e8d9aa8573cdd13b1a486..2641e23d946b649a0adeeb31cc86c8578722f457 100644 (file)
@@ -1583,7 +1583,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strlcpy(f->description, "MPEG", sizeof(f->description));
+       strscpy(f->description, "MPEG", sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_MPEG;
 
        return 0;
@@ -1992,7 +1992,7 @@ int cx231xx_417_register(struct cx231xx *dev)
        dev->mpeg_ctrl_handler.ops = &cx231xx_ops;
        if (dev->sd_cx25840)
                v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl,
-                               dev->sd_cx25840->ctrl_handler, NULL);
+                               dev->sd_cx25840->ctrl_handler, NULL, false);
        if (dev->mpeg_ctrl_handler.hdl.error) {
                err = dev->mpeg_ctrl_handler.hdl.error;
                dprintk(3, "%s: can't add cx25840 controls\n", dev->name);
index 32ee7b3f21c9b5cecc00d5b7fd4445be7d69dea3..77f2c65eb79a9489963bb7dca29b3bf4e5134cb3 100644 (file)
@@ -679,10 +679,10 @@ static int cx231xx_audio_init(struct cx231xx *dev)
                        &snd_cx231xx_pcm_capture);
        pcm->info_flags = 0;
        pcm->private_data = dev;
-       strcpy(pcm->name, "Conexant cx231xx Capture");
-       strcpy(card->driver, "Cx231xx-Audio");
-       strcpy(card->shortname, "Cx231xx Audio");
-       strcpy(card->longname, "Conexant cx231xx Audio");
+       strscpy(pcm->name, "Conexant cx231xx Capture", sizeof(pcm->name));
+       strscpy(card->driver, "Cx231xx-Audio", sizeof(card->driver));
+       strscpy(card->shortname, "Cx231xx Audio", sizeof(card->shortname));
+       strscpy(card->longname, "Conexant cx231xx Audio", sizeof(card->longname));
 
        INIT_WORK(&dev->wq_trigger, audio_trigger);
 
index 3e9b73a6b7c93f72dbf78e3f799423d1dcac0d90..9f88c640ec2b34a416e16caa982f7072410f5baa 100644 (file)
@@ -67,7 +67,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
 
        dev->init_data.name = cx231xx_boards[dev->model].name;
 
-       strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+       strscpy(info.type, "ir_video", I2C_NAME_SIZE);
        info.platform_data = &dev->init_data;
 
        /*
index f7fcd733a2ca8de24360a30fc5e08a6d80902589..c990f70c0ea646453d9b3bf058df201f442a83fe 100644 (file)
@@ -1169,7 +1169,7 @@ int cx231xx_enum_input(struct file *file, void *priv,
        i->index = n;
        i->type = V4L2_INPUT_TYPE_CAMERA;
 
-       strcpy(i->name, iname[INPUT(n)->type]);
+       strscpy(i->name, iname[INPUT(n)->type], sizeof(i->name));
 
        if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) ||
            (CX231XX_VMUX_CABLE == INPUT(n)->type))
@@ -1244,7 +1244,7 @@ int cx231xx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
        if (0 != t->index)
                return -EINVAL;
 
-       strcpy(t->name, "Tuner");
+       strscpy(t->name, "Tuner", sizeof(t->name));
 
        t->type = V4L2_TUNER_ANALOG_TV;
        t->capability = V4L2_TUNER_CAP_NORM;
@@ -1354,22 +1354,22 @@ int cx231xx_g_chip_info(struct file *file, void *fh,
        case 0: /* Cx231xx - internal registers */
                return 0;
        case 1: /* AFE - read byte */
-               strlcpy(chip->name, "AFE (byte)", sizeof(chip->name));
+               strscpy(chip->name, "AFE (byte)", sizeof(chip->name));
                return 0;
        case 2: /* Video Block - read byte */
-               strlcpy(chip->name, "Video (byte)", sizeof(chip->name));
+               strscpy(chip->name, "Video (byte)", sizeof(chip->name));
                return 0;
        case 3: /* I2S block - read byte */
-               strlcpy(chip->name, "I2S (byte)", sizeof(chip->name));
+               strscpy(chip->name, "I2S (byte)", sizeof(chip->name));
                return 0;
        case 4: /* AFE - read dword */
-               strlcpy(chip->name, "AFE (dword)", sizeof(chip->name));
+               strscpy(chip->name, "AFE (dword)", sizeof(chip->name));
                return 0;
        case 5: /* Video Block - read dword */
-               strlcpy(chip->name, "Video (dword)", sizeof(chip->name));
+               strscpy(chip->name, "Video (dword)", sizeof(chip->name));
                return 0;
        case 6: /* I2S Block - read dword */
-               strlcpy(chip->name, "I2S (dword)", sizeof(chip->name));
+               strscpy(chip->name, "I2S (dword)", sizeof(chip->name));
                return 0;
        }
        return -EINVAL;
@@ -1389,7 +1389,7 @@ int cx231xx_g_register(struct file *file, void *priv,
                ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
                                (u16)reg->reg, value, 4);
                reg->val = value[0] | value[1] << 8 |
-                       value[2] << 16 | value[3] << 24;
+                       value[2] << 16 | (u32)value[3] << 24;
                reg->size = 4;
                break;
        case 1: /* AFE - read byte */
@@ -1553,8 +1553,8 @@ int cx231xx_querycap(struct file *file, void *priv,
        struct cx231xx_fh *fh = priv;
        struct cx231xx *dev = fh->dev;
 
-       strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
-       strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
+       strscpy(cap->driver, "cx231xx", sizeof(cap->driver));
+       strscpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
        if (vdev->vfl_type == VFL_TYPE_RADIO)
@@ -1583,7 +1583,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
        if (unlikely(f->index >= ARRAY_SIZE(format)))
                return -EINVAL;
 
-       strlcpy(f->description, format[f->index].name, sizeof(f->description));
+       strscpy(f->description, format[f->index].name, sizeof(f->description));
        f->pixelformat = format[f->index].fourcc;
 
        return 0;
@@ -1716,7 +1716,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
        if (t->index)
                return -EINVAL;
 
-       strcpy(t->name, "Radio");
+       strscpy(t->name, "Radio", sizeof(t->name));
 
        call_all(dev, tuner, g_tuner, t);
 
@@ -2204,10 +2204,10 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 
        if (dev->sd_cx25840) {
                v4l2_ctrl_add_handler(&dev->ctrl_handler,
-                               dev->sd_cx25840->ctrl_handler, NULL);
+                               dev->sd_cx25840->ctrl_handler, NULL, true);
                v4l2_ctrl_add_handler(&dev->radio_ctrl_handler,
                                dev->sd_cx25840->ctrl_handler,
-                               v4l2_ctrl_radio_filter);
+                               v4l2_ctrl_radio_filter, true);
        }
 
        if (dev->ctrl_handler.error)
@@ -2242,7 +2242,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 
        /* Initialize VBI template */
        cx231xx_vbi_template = cx231xx_video_template;
-       strcpy(cx231xx_vbi_template.name, "cx231xx-vbi");
+       strscpy(cx231xx_vbi_template.name, "cx231xx-vbi",
+               sizeof(cx231xx_vbi_template.name));
 
        /* Allocate and fill vbi video_device struct */
        cx231xx_vdev_init(dev, &dev->vbi_dev, &cx231xx_vbi_template, "vbi");
index 1f6c1eefe38920c9f1e08d1f99158db7e715c838..80d3bd3a0f245786b69800dcbfaabf7f6d430c1e 100644 (file)
@@ -204,7 +204,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
                .platform_data = platform_data,
        };
 
-       strlcpy(board_info.type, type, I2C_NAME_SIZE);
+       strscpy(board_info.type, type, I2C_NAME_SIZE);
 
        /* find first free client */
        for (num = 0; num < AF9035_I2C_CLIENT_MAX; num++) {
index 20ee7eea2a91ef238d19d73fc622addf1529005b..0df7ad69e6c782e1160a984adcc93a79754dcef5 100644 (file)
@@ -638,7 +638,7 @@ static int anysee_add_i2c_dev(struct dvb_usb_device *d, const char *type,
                .platform_data = platform_data,
        };
 
-       strlcpy(board_info.type, type, I2C_NAME_SIZE);
+       strscpy(board_info.type, type, I2C_NAME_SIZE);
 
        /* find first free client */
        for (num = 0; num < ANYSEE_I2C_CLIENT_MAX; num++) {
index 955318ab7f5e31c65b698a68b0a1f3581686966e..3b8f7931b7306178f5854b5a2ea2608f8faeb25e 100644 (file)
@@ -74,7 +74,7 @@ static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
        if (!d->props->i2c_algo)
                return 0;
 
-       strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
+       strscpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
        d->i2c_adap.algo = d->props->i2c_algo;
        d->i2c_adap.dev.parent = &d->udev->dev;
        i2c_set_adapdata(&d->i2c_adap, d);
index 1aa88d94e57f5e54c96c097c86d1f9c91e82608b..e28bd8836751e46e9ee4a1209d953b374dc2bde2 100644 (file)
@@ -31,6 +31,7 @@ MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver.");
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 struct dvbsky_state {
+       struct mutex stream_mutex;
        u8 ibuf[DVBSKY_BUF_LEN];
        u8 obuf[DVBSKY_BUF_LEN];
        u8 last_lock;
@@ -67,17 +68,18 @@ static int dvbsky_usb_generic_rw(struct dvb_usb_device *d,
 
 static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
 {
+       struct dvbsky_state *state = d_to_priv(d);
        int ret;
-       static u8 obuf_pre[3] = { 0x37, 0, 0 };
-       static u8 obuf_post[3] = { 0x36, 3, 0 };
+       u8 obuf_pre[3] = { 0x37, 0, 0 };
+       u8 obuf_post[3] = { 0x36, 3, 0 };
 
-       mutex_lock(&d->usb_mutex);
-       ret = dvb_usbv2_generic_rw_locked(d, obuf_pre, 3, NULL, 0);
+       mutex_lock(&state->stream_mutex);
+       ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0);
        if (!ret && onoff) {
                msleep(20);
-               ret = dvb_usbv2_generic_rw_locked(d, obuf_post, 3, NULL, 0);
+               ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0);
        }
-       mutex_unlock(&d->usb_mutex);
+       mutex_unlock(&state->stream_mutex);
        return ret;
 }
 
@@ -606,6 +608,8 @@ static int dvbsky_init(struct dvb_usb_device *d)
        if (ret)
                return ret;
        */
+       mutex_init(&state->stream_mutex);
+
        state->last_lock = 0;
 
        return 0;
index 3338b21d8b25ca0fcb438f4d1eedce6c80c99f1a..0559417c8af48830e614aecb3d206cf1e71cef90 100644 (file)
@@ -507,7 +507,7 @@ static int friio_frontend_attach(struct dvb_usb_adapter *adap)
        priv->i2c_client_demod = cl;
        priv->tuner_adap.algo = &friio_tuner_i2c_algo;
        priv->tuner_adap.dev.parent = &d->udev->dev;
-       strlcpy(priv->tuner_adap.name, d->name, sizeof(priv->tuner_adap.name));
+       strscpy(priv->tuner_adap.name, d->name, sizeof(priv->tuner_adap.name));
        strlcat(priv->tuner_adap.name, "-tuner", sizeof(priv->tuner_adap.name));
        priv->demod_sub_i2c = &priv->tuner_adap;
        i2c_set_adapdata(&priv->tuner_adap, d);
index 0750a975bcb899a4744ebf5229c0ced0dcd00fe9..f109c04f05ae2e879ec00301e8838d263b12edb0 100644 (file)
@@ -1004,7 +1004,7 @@ static int lme_name(struct dvb_usb_adapter *adap)
                " SHARP:BS2F7HZ0194", " RS2000"};
        char *name = adap->fe[0]->ops.info.name;
 
-       strlcpy(name, desc, 128);
+       strscpy(name, desc, 128);
        strlcat(name, fe_name[st->tuner_config], 128);
 
        return 0;
index 4713ba65e1c228b71c1a4c51ecc015cb58a610ad..85cdf593a9ad4a1c4cc43d63f20a959cd3f5b9c0 100644 (file)
@@ -892,11 +892,13 @@ static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
        state->tuner.function = MEDIA_ENT_F_TUNER;
        state->tuner.name = "mxl111sf tuner";
-       state->tuner_pads[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       state->tuner_pads[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->tuner_pads[MXL111SF_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       state->tuner_pads[MXL111SF_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
+       state->tuner_pads[MXL111SF_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->tuner_pads[MXL111SF_PAD_OUTPUT].sig_type = PAD_SIGNAL_ANALOG;
 
        ret = media_entity_pads_init(&state->tuner,
-                                    TUNER_NUM_PADS, state->tuner_pads);
+                                    MXL111SF_NUM_PADS, state->tuner_pads);
        if (ret)
                return ret;
 
index 22253d4908eb48c8b8c69341abbe46c4ac867c73..ed98654ba7fdec4658e1580c8c5c8e30e6ebacca 100644 (file)
@@ -52,6 +52,12 @@ struct mxl111sf_adap_state {
        int (*fe_sleep)(struct dvb_frontend *);
 };
 
+enum mxl111sf_pads {
+       MXL111SF_PAD_RF_INPUT,
+       MXL111SF_PAD_OUTPUT,
+       MXL111SF_NUM_PADS
+};
+
 struct mxl111sf_state {
        struct dvb_usb_device *d;
 
@@ -94,7 +100,7 @@ struct mxl111sf_state {
        struct mutex msg_lock;
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
        struct media_entity tuner;
-       struct media_pad tuner_pads[2];
+       struct media_pad tuner_pads[MXL111SF_NUM_PADS];
 #endif
 };
 
index a970224a94bdd34b1b37ad3979156f26fec13443..8a83b10e50e08a87409cce4ca79279c918654836 100644 (file)
@@ -687,7 +687,7 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
 
        /* attach demodulator */
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "rtl2830", I2C_NAME_SIZE);
+       strscpy(board_info.type, "rtl2830", I2C_NAME_SIZE);
        board_info.addr = 0x10;
        board_info.platform_data = pdata;
        request_module("%s", board_info.type);
@@ -908,7 +908,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
 
        /* attach demodulator */
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "rtl2832", I2C_NAME_SIZE);
+       strscpy(board_info.type, "rtl2832", I2C_NAME_SIZE);
        board_info.addr = 0x10;
        board_info.platform_data = pdata;
        request_module("%s", board_info.type);
@@ -947,7 +947,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
 
                        mn88472_config.fe = &adap->fe[1];
                        mn88472_config.i2c_wr_max = 22,
-                       strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
+                       strscpy(info.type, "mn88472", I2C_NAME_SIZE);
                        mn88472_config.xtal = 20500000;
                        mn88472_config.ts_mode = SERIAL_TS_MODE;
                        mn88472_config.ts_clock = VARIABLE_TS_CLOCK;
@@ -972,7 +972,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
 
                        mn88473_config.fe = &adap->fe[1];
                        mn88473_config.i2c_wr_max = 22,
-                       strlcpy(info.type, "mn88473", I2C_NAME_SIZE);
+                       strscpy(info.type, "mn88473", I2C_NAME_SIZE);
                        info.addr = 0x18;
                        info.platform_data = &mn88473_config;
                        request_module(info.type);
@@ -998,7 +998,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
                        si2168_config.ts_mode = SI2168_TS_SERIAL;
                        si2168_config.ts_clock_inv = false;
                        si2168_config.ts_clock_gapped = true;
-                       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2168", I2C_NAME_SIZE);
                        info.addr = 0x64;
                        info.platform_data = &si2168_config;
                        request_module(info.type);
@@ -1189,7 +1189,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                                .clock = 28800000,
                        };
 
-                       strlcpy(info.type, "e4000", I2C_NAME_SIZE);
+                       strscpy(info.type, "e4000", I2C_NAME_SIZE);
                        info.addr = 0x64;
                        info.platform_data = &e4000_config;
 
@@ -1213,7 +1213,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                        };
                        struct i2c_board_info board_info = {};
 
-                       strlcpy(board_info.type, "fc2580", I2C_NAME_SIZE);
+                       strscpy(board_info.type, "fc2580", I2C_NAME_SIZE);
                        board_info.addr = 0x56;
                        board_info.platform_data = &fc2580_pdata;
                        request_module("fc2580");
@@ -1244,7 +1244,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                if (ret)
                        goto err;
 
-               strlcpy(board_info.type, "tua9001", I2C_NAME_SIZE);
+               strscpy(board_info.type, "tua9001", I2C_NAME_SIZE);
                board_info.addr = 0x60;
                board_info.platform_data = &tua9001_pdata;
                request_module("tua9001");
@@ -1289,7 +1289,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
                                .inversion = false,
                        };
 
-                       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+                       strscpy(info.type, "si2157", I2C_NAME_SIZE);
                        info.addr = 0x60;
                        info.platform_data = &si2157_config;
                        request_module(info.type);
@@ -1685,7 +1685,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
 {
        int ret, i, len;
        struct rtl28xxu_dev *dev = d->priv;
-       struct ir_raw_event ev;
+       struct ir_raw_event ev = {};
        u8 buf[128];
        static const struct rtl28xxu_reg_val_mask refresh_tab[] = {
                {IR_RX_IF,               0x03, 0xff},
@@ -1751,8 +1751,6 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
        }
 
        /* pass data to Kernel IR decoder */
-       init_ir_raw_event(&ev);
-
        for (i = 0; i < len; i++) {
                ev.pulse = buf[i] >> 7;
                ev.duration = 50800 * (buf[i] & 0x7f);
index d1eb4b7bc0519c4103ca401da7cf7478cef7affd..7a41d744ff5800d25d8e4d42873572a63f309f1a 100644 (file)
@@ -177,7 +177,7 @@ static int zd1301_frontend_attach(struct dvb_usb_adapter *adap)
        dev->mt2060_pdata.i2c_write_max = 9;
        dev->mt2060_pdata.dvb_frontend = frontend;
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "mt2060", I2C_NAME_SIZE);
+       strscpy(board_info.type, "mt2060", I2C_NAME_SIZE);
        board_info.addr = 0x60;
        board_info.platform_data = &dev->mt2060_pdata;
        request_module("%s", "mt2060");
index 5b51ed7d6243fe8572b126e45fba6cee83587f3e..a51a45c6023315264a5add9fa1d9223de8e2a8fe 100644 (file)
@@ -1196,7 +1196,7 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
        si2168_config.ts_mode = SI2168_TS_PARALLEL;
        si2168_config.ts_clock_inv = 1;
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+       strscpy(info.type, "si2168", I2C_NAME_SIZE);
        info.addr = 0x64;
        info.platform_data = &si2168_config;
        request_module(info.type);
@@ -1216,7 +1216,7 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
        si2157_config.fe = adap->fe_adap[0].fe;
        si2157_config.if_port = 1;
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+       strscpy(info.type, "si2157", I2C_NAME_SIZE);
        info.addr = 0x60;
        info.platform_data = &si2157_config;
        request_module(info.type);
index 091389fdf89ee62f6e15f8c02f025cfd8ffe6c66..7551dce96f648a3b9e610f51db52ccf7ca020f90 100644 (file)
@@ -3763,7 +3763,7 @@ static int xbox_one_attach(struct dvb_usb_adapter *adap)
        mn88472_config.ts_mode = PARALLEL_TS_MODE;
        mn88472_config.ts_clock = FIXED_TS_CLOCK;
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
+       strscpy(info.type, "mn88472", I2C_NAME_SIZE);
        info.addr = 0x18;
        info.platform_data = &mn88472_config;
        request_module(info.type);
@@ -3790,7 +3790,7 @@ static int xbox_one_attach(struct dvb_usb_adapter *adap)
        tda18250_config.fe = adap->fe_adap[0].fe;
 
        memset(&info, 0, sizeof(struct i2c_board_info));
-       strlcpy(info.type, "tda18250", I2C_NAME_SIZE);
+       strscpy(info.type, "tda18250", I2C_NAME_SIZE);
        info.addr = 0x60;
        info.platform_data = &tda18250_config;
 
index ca0b734e009b16c7732420984f08eee20224b25b..2e07106f46803c7cb0d82a27f5e02f9e5eb1a2b7 100644 (file)
@@ -20,7 +20,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
                return -EINVAL;
        }
 
-       strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
+       strscpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
        d->i2c_adap.algo      = d->props.i2c_algo;
        d->i2c_adap.algo_data = NULL;
        d->i2c_adap.dev.parent = &d->udev->dev;
index 9ce8b4d79d1fa47ffdd9c027a68a428823c3e4ef..eefe2867815c3aca21637e027e15c9ea1304d643 100644 (file)
@@ -1589,7 +1589,7 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
        m88ds3103_pdata.lnb_hv_pol = 1;
        m88ds3103_pdata.lnb_en_pol = 0;
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
+       strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
        board_info.addr = 0x68;
        board_info.platform_data = &m88ds3103_pdata;
        request_module("m88ds3103");
@@ -1608,7 +1608,7 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
        /* attach tuner */
        ts2020_config.fe = adap->fe_adap[0].fe;
        memset(&board_info, 0, sizeof(board_info));
-       strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
+       strscpy(board_info.type, "ts2022", I2C_NAME_SIZE);
        board_info.addr = 0x60;
        board_info.platform_data = &ts2020_config;
        request_module("ts2020");
index 18d0f8f5283fa6cb96af7702229a3dc196950a24..c659e18b358b88db8b7ce31836bab9e784a4dfa4 100644 (file)
@@ -566,8 +566,9 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
                        a->fe_adap[0].fe->ops.set_voltage = technisat_usb2_set_voltage;
 
                        /* if everything was successful assign a nice name to the frontend */
-                       strlcpy(a->fe_adap[0].fe->ops.info.name, a->dev->desc->name,
-                                       sizeof(a->fe_adap[0].fe->ops.info.name));
+                       strscpy(a->fe_adap[0].fe->ops.info.name,
+                               a->dev->desc->name,
+                               sizeof(a->fe_adap[0].fe->ops.info.name));
                } else {
                        dvb_frontend_detach(a->fe_adap[0].fe);
                        a->fe_adap[0].fe = NULL;
index 67481fc8244587772dfddf9764b377d52d496b4d..49c9b70b632b26202e5032413a0103042c6112b3 100644 (file)
@@ -843,11 +843,11 @@ static int em28xx_audio_urb_init(struct em28xx *dev)
 
        dev->adev.transfer_buffer = kcalloc(num_urb,
                                            sizeof(*dev->adev.transfer_buffer),
-                                           GFP_ATOMIC);
+                                           GFP_KERNEL);
        if (!dev->adev.transfer_buffer)
                return -ENOMEM;
 
-       dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC);
+       dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_KERNEL);
        if (!dev->adev.urb) {
                kfree(dev->adev.transfer_buffer);
                return -ENOMEM;
@@ -860,14 +860,14 @@ static int em28xx_audio_urb_init(struct em28xx *dev)
                int j, k;
                void *buf;
 
-               urb = usb_alloc_urb(npackets, GFP_ATOMIC);
+               urb = usb_alloc_urb(npackets, GFP_KERNEL);
                if (!urb) {
                        em28xx_audio_free_urb(dev);
                        return -ENOMEM;
                }
                dev->adev.urb[i] = urb;
 
-               buf = usb_alloc_coherent(udev, npackets * ep_size, GFP_ATOMIC,
+               buf = usb_alloc_coherent(udev, npackets * ep_size, GFP_KERNEL,
                                         &urb->transfer_dma);
                if (!buf) {
                        dev_err(&dev->intf->dev,
@@ -939,11 +939,11 @@ static int em28xx_audio_init(struct em28xx *dev)
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
        pcm->info_flags = 0;
        pcm->private_data = dev;
-       strcpy(pcm->name, "Empia 28xx Capture");
+       strscpy(pcm->name, "Empia 28xx Capture", sizeof(pcm->name));
 
-       strcpy(card->driver, "Em28xx-Audio");
-       strcpy(card->shortname, "Em28xx Audio");
-       strcpy(card->longname, "Empia Em28xx Audio");
+       strscpy(card->driver, "Em28xx-Audio", sizeof(card->driver));
+       strscpy(card->shortname, "Em28xx Audio", sizeof(card->shortname));
+       strscpy(card->longname, "Empia Em28xx Audio", sizeof(card->longname));
 
        INIT_WORK(&adev->wq_trigger, audio_trigger);
 
index 71c829f31d3bb3b86f0e9469ab0135966d54e71d..87b887b7604ef31716faccaa12812897e9b20641 100644 (file)
@@ -2141,13 +2141,13 @@ const struct em28xx_board em28xx_boards[] = {
                .input           = { {
                        .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
-                       .amux     = EM28XX_AUDIO_SRC_LINE,
+                       .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = terratec_av350_unmute_gpio,
 
                }, {
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = TVP5150_SVIDEO,
-                       .amux     = EM28XX_AUDIO_SRC_LINE,
+                       .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = terratec_av350_unmute_gpio,
                } },
        },
@@ -3039,6 +3039,9 @@ static int em28xx_hint_board(struct em28xx *dev)
 
 static void em28xx_card_setup(struct em28xx *dev)
 {
+       int i, j, idx;
+       bool duplicate_entry;
+
        /*
         * If the device can be a webcam, seek for a sensor.
         * If sensor is not found, then it isn't a webcam.
@@ -3195,6 +3198,32 @@ static void em28xx_card_setup(struct em28xx *dev)
        /* Allow override tuner type by a module parameter */
        if (tuner >= 0)
                dev->tuner_type = tuner;
+
+       /*
+        * Dynamically generate a list of valid audio inputs for this
+        * specific board, mapping them via enum em28xx_amux.
+        */
+
+       idx = 0;
+       for (i = 0; i < MAX_EM28XX_INPUT; i++) {
+               if (!INPUT(i)->type)
+                       continue;
+
+               /* Skip already mapped audio inputs */
+               duplicate_entry = false;
+               for (j = 0; j < idx; j++) {
+                       if (INPUT(i)->amux == dev->amux_map[j]) {
+                               duplicate_entry = true;
+                               break;
+                       }
+               }
+               if (duplicate_entry)
+                       continue;
+
+               dev->amux_map[idx++] = INPUT(i)->amux;
+       }
+       for (; idx < MAX_EM28XX_INPUT; idx++)
+               dev->amux_map[idx] = EM28XX_AMUX_UNUSED;
 }
 
 void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
index e19d6342e0d0af74311dc7943c0a56969b80d1ac..02c13d71e6c1a17b1a66c856d948f7de34e0068a 100644 (file)
@@ -985,7 +985,8 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned int bus,
 
        dev->i2c_adap[bus] = em28xx_adap_template;
        dev->i2c_adap[bus].dev.parent = &dev->intf->dev;
-       strcpy(dev->i2c_adap[bus].name, dev_name(&dev->intf->dev));
+       strscpy(dev->i2c_adap[bus].name, dev_name(&dev->intf->dev),
+               sizeof(dev->i2c_adap[bus].name));
 
        dev->i2c_bus[bus].bus = bus;
        dev->i2c_bus[bus].algo_type = algo_type;
index 68571bf36d28623cad6be5908f4f6075dd947df5..f43717ea831db9cb20c2511f588d942cd66d7b2d 100644 (file)
@@ -1093,6 +1093,8 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
 
        em28xx_videodbg("%s\n", __func__);
 
+       dev->v4l2->field_count = 0;
+
        /*
         * Make sure streaming is not already in progress for this type
         * of filehandle (e.g. video, vbi)
@@ -1471,9 +1473,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 
        fmt = format_by_fourcc(f->fmt.pix.pixelformat);
        if (!fmt) {
-               em28xx_videodbg("Fourcc format (%08x) invalid.\n",
-                               f->fmt.pix.pixelformat);
-               return -EINVAL;
+               fmt = &format[0];
+               em28xx_videodbg("Fourcc format (%08x) invalid. Using default (%08x).\n",
+                               f->fmt.pix.pixelformat, fmt->fourcc);
        }
 
        if (dev->board.is_em2800) {
@@ -1666,6 +1668,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 {
        struct em28xx *dev = video_drvdata(file);
        unsigned int       n;
+       int j;
 
        n = i->index;
        if (n >= MAX_EM28XX_INPUT)
@@ -1675,7 +1678,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 
        i->type = V4L2_INPUT_TYPE_CAMERA;
 
-       strcpy(i->name, iname[INPUT(n)->type]);
+       strscpy(i->name, iname[INPUT(n)->type], sizeof(i->name));
 
        if (INPUT(n)->type == EM28XX_VMUX_TELEVISION)
                i->type = V4L2_INPUT_TYPE_TUNER;
@@ -1685,6 +1688,12 @@ static int vidioc_enum_input(struct file *file, void *priv,
        if (dev->is_webcam)
                i->capabilities = 0;
 
+       /* Dynamically generates an audioset bitmask */
+       i->audioset = 0;
+       for (j = 0; j < MAX_EM28XX_INPUT; j++)
+               if (dev->amux_map[j] != EM28XX_AMUX_UNUSED)
+                       i->audioset |= 1 << j;
+
        return 0;
 }
 
@@ -1710,61 +1719,121 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
        return 0;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+static int em28xx_fill_audio_input(struct em28xx *dev,
+                                  const char *s,
+                                  struct v4l2_audio *a,
+                                  unsigned int index)
 {
-       struct em28xx *dev = video_drvdata(file);
+       unsigned int idx = dev->amux_map[index];
+
+       /*
+        * With msp3400, almost all mappings use the default (amux = 0).
+        * The only one may use a different value is WinTV USB2, where it
+        * can also be SCART1 input.
+        * As it is very doubtful that we would see new boards with msp3400,
+        * let's just reuse the existing switch.
+        */
+       if (dev->has_msp34xx && idx != EM28XX_AMUX_UNUSED)
+               idx = EM28XX_AMUX_LINE_IN;
 
-       switch (a->index) {
+       switch (idx) {
        case EM28XX_AMUX_VIDEO:
-               strcpy(a->name, "Television");
+               strscpy(a->name, "Television", sizeof(a->name));
                break;
        case EM28XX_AMUX_LINE_IN:
-               strcpy(a->name, "Line In");
+               strscpy(a->name, "Line In", sizeof(a->name));
                break;
        case EM28XX_AMUX_VIDEO2:
-               strcpy(a->name, "Television alt");
+               strscpy(a->name, "Television alt", sizeof(a->name));
                break;
        case EM28XX_AMUX_PHONE:
-               strcpy(a->name, "Phone");
+               strscpy(a->name, "Phone", sizeof(a->name));
                break;
        case EM28XX_AMUX_MIC:
-               strcpy(a->name, "Mic");
+               strscpy(a->name, "Mic", sizeof(a->name));
                break;
        case EM28XX_AMUX_CD:
-               strcpy(a->name, "CD");
+               strscpy(a->name, "CD", sizeof(a->name));
                break;
        case EM28XX_AMUX_AUX:
-               strcpy(a->name, "Aux");
+               strscpy(a->name, "Aux", sizeof(a->name));
                break;
        case EM28XX_AMUX_PCM_OUT:
-               strcpy(a->name, "PCM");
+               strscpy(a->name, "PCM", sizeof(a->name));
                break;
+       case EM28XX_AMUX_UNUSED:
        default:
                return -EINVAL;
        }
-
-       a->index = dev->ctl_ainput;
+       a->index = index;
        a->capability = V4L2_AUDCAP_STEREO;
 
+       em28xx_videodbg("%s: audio input index %d is '%s'\n",
+                       s, a->index, a->name);
+
        return 0;
 }
 
+static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+       struct em28xx *dev = video_drvdata(file);
+
+       if (a->index >= MAX_EM28XX_INPUT)
+               return -EINVAL;
+
+       return em28xx_fill_audio_input(dev, __func__, a, a->index);
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+       struct em28xx *dev = video_drvdata(file);
+       int i;
+
+       for (i = 0; i < MAX_EM28XX_INPUT; i++)
+               if (dev->ctl_ainput == dev->amux_map[i])
+                       return em28xx_fill_audio_input(dev, __func__, a, i);
+
+       /* Should never happen! */
+       return -EINVAL;
+}
+
 static int vidioc_s_audio(struct file *file, void *priv,
                          const struct v4l2_audio *a)
 {
        struct em28xx *dev = video_drvdata(file);
+       int idx, i;
 
        if (a->index >= MAX_EM28XX_INPUT)
                return -EINVAL;
-       if (!INPUT(a->index)->type)
+
+       idx = dev->amux_map[a->index];
+
+       if (idx == EM28XX_AMUX_UNUSED)
                return -EINVAL;
 
-       dev->ctl_ainput = INPUT(a->index)->amux;
-       dev->ctl_aoutput = INPUT(a->index)->aout;
+       dev->ctl_ainput = idx;
+
+       /*
+        * FIXME: This is wrong, as different inputs at em28xx_cards
+        * may have different audio outputs. So, the right thing
+        * to do is to implement VIDIOC_G_AUDOUT/VIDIOC_S_AUDOUT.
+        * With the current board definitions, this would work fine,
+        * as, currently, all boards fit.
+        */
+       for (i = 0; i < MAX_EM28XX_INPUT; i++)
+               if (idx == dev->amux_map[i])
+                       break;
+       if (i == MAX_EM28XX_INPUT)
+               return -EINVAL;
+
+       dev->ctl_aoutput = INPUT(i)->aout;
 
        if (!dev->ctl_aoutput)
                dev->ctl_aoutput = EM28XX_AOUT_MASTER;
 
+       em28xx_videodbg("%s: set audio input to %d\n", __func__,
+                       dev->ctl_ainput);
+
        return 0;
 }
 
@@ -1776,7 +1845,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (t->index != 0)
                return -EINVAL;
 
-       strcpy(t->name, "Tuner");
+       strscpy(t->name, "Tuner", sizeof(t->name));
 
        v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t);
        return 0;
@@ -1833,9 +1902,9 @@ static int vidioc_g_chip_info(struct file *file, void *priv,
        if (chip->match.addr > 1)
                return -EINVAL;
        if (chip->match.addr == 1)
-               strlcpy(chip->name, "ac97", sizeof(chip->name));
+               strscpy(chip->name, "ac97", sizeof(chip->name));
        else
-               strlcpy(chip->name,
+               strscpy(chip->name,
                        dev->v4l2->v4l2_dev.name, sizeof(chip->name));
        return 0;
 }
@@ -1920,8 +1989,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct em28xx_v4l2    *v4l2 = dev->v4l2;
        struct usb_device *udev = interface_to_usbdev(dev->intf);
 
-       strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
-       strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
+       strscpy(cap->driver, "em28xx", sizeof(cap->driver));
+       strscpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
        usb_make_path(udev, cap->bus_info, sizeof(cap->bus_info));
 
        if (vdev->vfl_type == VFL_TYPE_GRABBER)
@@ -1954,7 +2023,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (unlikely(f->index >= ARRAY_SIZE(format)))
                return -EINVAL;
 
-       strlcpy(f->description, format[f->index].name, sizeof(f->description));
+       strscpy(f->description, format[f->index].name, sizeof(f->description));
        f->pixelformat = format[f->index].fourcc;
 
        return 0;
@@ -2045,7 +2114,7 @@ static int radio_g_tuner(struct file *file, void *priv,
        if (unlikely(t->index > 0))
                return -EINVAL;
 
-       strcpy(t->name, "Radio");
+       strscpy(t->name, "Radio", sizeof(t->name));
 
        v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t);
 
@@ -2302,6 +2371,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
        .vidioc_try_fmt_vbi_cap     = vidioc_g_fmt_vbi_cap,
        .vidioc_s_fmt_vbi_cap       = vidioc_g_fmt_vbi_cap,
        .vidioc_enum_framesizes     = vidioc_enum_framesizes,
+       .vidioc_enumaudio           = vidioc_enumaudio,
        .vidioc_g_audio             = vidioc_g_audio,
        .vidioc_s_audio             = vidioc_s_audio,
 
index 953caac025f22a4acc2fc8b15beb85ba456fd58d..a551072e62ed1fb9a03293b389b8d4c6e27d9b30 100644 (file)
@@ -335,6 +335,9 @@ enum em28xx_usb_audio_type {
 /**
  * em28xx_amux - describes the type of audio input used by em28xx
  *
+ * @EM28XX_AMUX_UNUSED:
+ *     Used only on em28xx dev->map field, in order to mark an entry
+ *     as unused.
  * @EM28XX_AMUX_VIDEO:
  *     On devices without AC97, this is the only value that it is currently
  *     allowed.
@@ -369,7 +372,8 @@ enum em28xx_usb_audio_type {
  * same time, via the alsa mux.
  */
 enum em28xx_amux {
-       EM28XX_AMUX_VIDEO,
+       EM28XX_AMUX_UNUSED = -1,
+       EM28XX_AMUX_VIDEO = 0,
        EM28XX_AMUX_LINE_IN,
 
        /* Some less-common mixer setups */
@@ -692,6 +696,8 @@ struct em28xx {
        unsigned int ctl_input; // selected input
        unsigned int ctl_ainput;// selected audio input
        unsigned int ctl_aoutput;// selected audio output
+       enum em28xx_amux amux_map[MAX_EM28XX_INPUT];
+
        int mute;
        int volume;
 
index 62aeebcdd7f71bede5f47a654d9163e33df3e82d..59cf50355b4e441631d0fa0a9814bd04ee79b16a 100644 (file)
@@ -208,7 +208,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con
        struct i2c_board_info info;
 
        memset(&info, 0, sizeof(info));
-       strlcpy(info.type, i2c->type, sizeof(info.type));
+       strscpy(info.type, i2c->type, sizeof(info.type));
        info.addr = i2c->addr;
        info.flags = i2c->flags;
 
index c55c82f70e541b2b6483ae2c840a3f08f35d5f22..7a2781fa83e71bd1603852c4513faf2082081c87 100644 (file)
@@ -284,9 +284,9 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
        struct go7007 *go = video_drvdata(file);
 
-       strlcpy(cap->driver, "go7007", sizeof(cap->driver));
-       strlcpy(cap->card, go->name, sizeof(cap->card));
-       strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
+       strscpy(cap->driver, "go7007", sizeof(cap->driver));
+       strscpy(cap->card, go->name, sizeof(cap->card));
+       strscpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
 
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
                                V4L2_CAP_STREAMING;
@@ -634,8 +634,8 @@ static int vidioc_enum_input(struct file *file, void *priv,
        if (inp->index >= go->board_info->num_inputs)
                return -EINVAL;
 
-       strlcpy(inp->name, go->board_info->inputs[inp->index].name,
-                       sizeof(inp->name));
+       strscpy(inp->name, go->board_info->inputs[inp->index].name,
+               sizeof(inp->name));
 
        /* If this board has a tuner, it will be the first input */
        if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
@@ -673,7 +673,7 @@ static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
 
        if (a->index >= go->board_info->num_aud_inputs)
                return -EINVAL;
-       strlcpy(a->name, go->board_info->aud_inputs[a->index].name,
+       strscpy(a->name, go->board_info->aud_inputs[a->index].name,
                sizeof(a->name));
        a->capability = V4L2_AUDCAP_STEREO;
        return 0;
@@ -684,7 +684,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
        struct go7007 *go = video_drvdata(file);
 
        a->index = go->aud_input;
-       strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
+       strscpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
                sizeof(a->name));
        a->capability = V4L2_AUDCAP_STEREO;
        return 0;
@@ -742,7 +742,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (t->index != 0)
                return -EINVAL;
 
-       strlcpy(t->name, "Tuner", sizeof(t->name));
+       strscpy(t->name, "Tuner", sizeof(t->name));
        return call_all(&go->v4l2_dev, tuner, g_tuner, t);
 }
 
index 137fc253b1228495e230b8466a8531230da1e6e5..fc84b37d5587858af9b47562ef8d01c1bff479ce 100644 (file)
@@ -260,10 +260,10 @@ int go7007_snd_init(struct go7007 *go)
                kfree(gosnd);
                return ret;
        }
-       strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
-       strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
-       strlcpy(gosnd->card->longname, gosnd->card->shortname,
-                       sizeof(gosnd->card->longname));
+       strscpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
+       strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
+       strscpy(gosnd->card->longname, gosnd->card->shortname,
+               sizeof(gosnd->card->longname));
 
        gosnd->pcm->private_data = go;
        snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
index 57aa521e16b159005bea6206dee791873f4cf402..fce9d6f4b7c924c6b95dea6c59f792ac701b7031 100644 (file)
@@ -1193,11 +1193,11 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
        struct gspca_dev *gspca_dev = video_drvdata(file);
 
-       strlcpy((char *) cap->driver, gspca_dev->sd_desc->name,
-                       sizeof cap->driver);
+       strscpy((char *)cap->driver, gspca_dev->sd_desc->name,
+               sizeof(cap->driver));
        if (gspca_dev->dev->product != NULL) {
-               strlcpy((char *) cap->card, gspca_dev->dev->product,
-                       sizeof cap->card);
+               strscpy((char *)cap->card, gspca_dev->dev->product,
+                       sizeof(cap->card));
        } else {
                snprintf((char *) cap->card, sizeof cap->card,
                        "USB Camera (%04x:%04x)",
@@ -1222,7 +1222,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
                return -EINVAL;
        input->type = V4L2_INPUT_TYPE_CAMERA;
        input->status = gspca_dev->cam.input_flags;
-       strlcpy(input->name, gspca_dev->sd_desc->name,
+       strscpy(input->name, gspca_dev->sd_desc->name,
                sizeof input->name);
        return 0;
 }
index cfa2a04d9f3f6a90cb4c34fd32f32c6f15ba3583..5984bb12bcff2ffe9fcc5d6a814fb6f0a84fa2ba 100644 (file)
@@ -1601,7 +1601,7 @@ static int sd_chip_info(struct gspca_dev *gspca_dev,
        if (chip->match.addr > 1)
                return -EINVAL;
        if (chip->match.addr == 1)
-               strlcpy(chip->name, "sensor", sizeof(chip->name));
+               strscpy(chip->name, "sensor", sizeof(chip->name));
        return 0;
 }
 #endif
index d7cbcf2b394794ac8d51529da921c2c51eb14065..e15b45f022e1b028ddad4a09599e6a90aaad75b7 100644 (file)
@@ -1044,7 +1044,7 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev)
                        v4l2_ctrl_g_ctrl(sd->gain));
 
        gspca_dev->cam.bulk_nurbs = 1;
-       ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC);
+       ret = usb_submit_urb(gspca_dev->urb[0], GFP_KERNEL);
        if (ret < 0)
                pr_err("sd_dq_callback() err %d\n", ret);
 
index 34085a0b15a1a5ec09bd2d892dcc0c2762c61951..d437852066224c4ca7936aa0610333f98f1b0720 100644 (file)
@@ -918,8 +918,8 @@ static int hackrf_querycap(struct file *file, void *fh,
        cap->capabilities = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER |
                            V4L2_CAP_SDR_OUTPUT | V4L2_CAP_MODULATOR |
                            V4L2_CAP_DEVICE_CAPS | cap->device_caps;
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, dev->rx_vdev.name, sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, dev->rx_vdev.name, sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
        return 0;
@@ -1041,14 +1041,14 @@ static int hackrf_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
        dev_dbg(dev->dev, "index=%d\n", v->index);
 
        if (v->index == 0) {
-               strlcpy(v->name, "HackRF ADC", sizeof(v->name));
+               strscpy(v->name, "HackRF ADC", sizeof(v->name));
                v->type = V4L2_TUNER_SDR;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow  = bands_adc_dac[0].rangelow;
                v->rangehigh = bands_adc_dac[0].rangehigh;
                ret = 0;
        } else if (v->index == 1) {
-               strlcpy(v->name, "HackRF RF", sizeof(v->name));
+               strscpy(v->name, "HackRF RF", sizeof(v->name));
                v->type = V4L2_TUNER_RF;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow  = bands_rx_tx[0].rangelow;
@@ -1080,14 +1080,14 @@ static int hackrf_g_modulator(struct file *file, void *fh,
        dev_dbg(dev->dev, "index=%d\n", a->index);
 
        if (a->index == 0) {
-               strlcpy(a->name, "HackRF DAC", sizeof(a->name));
+               strscpy(a->name, "HackRF DAC", sizeof(a->name));
                a->type = V4L2_TUNER_SDR;
                a->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                a->rangelow  = bands_adc_dac[0].rangelow;
                a->rangehigh = bands_adc_dac[0].rangehigh;
                ret = 0;
        } else if (a->index == 1) {
-               strlcpy(a->name, "HackRF RF", sizeof(a->name));
+               strscpy(a->name, "HackRF RF", sizeof(a->name));
                a->type = V4L2_TUNER_RF;
                a->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                a->rangelow  = bands_rx_tx[0].rangelow;
index 1b89c77bad6673d03600f2961f4c8fc96667b5dc..e082086428a43a23c25c6a2b2dcf9a566903c612 100644 (file)
@@ -578,8 +578,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
        struct hdpvr_device *dev = video_drvdata(file);
 
-       strcpy(cap->driver, "hdpvr");
-       strcpy(cap->card, "Hauppauge HD PVR");
+       strscpy(cap->driver, "hdpvr", sizeof(cap->driver));
+       strscpy(cap->card, "Hauppauge HD PVR", sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO |
                            V4L2_CAP_READWRITE;
@@ -873,7 +873,7 @@ static int vidioc_g_audio(struct file *file, void *private_data,
 
        audio->index = dev->options.audio_input;
        audio->capability = V4L2_AUDCAP_STEREO;
-       strlcpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
+       strscpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
        audio->name[sizeof(audio->name) - 1] = '\0';
        return 0;
 }
@@ -1238,7 +1238,8 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
 
        /* setup and register video device */
        dev->video_dev = hdpvr_video_template;
-       strcpy(dev->video_dev.name, "Hauppauge HD PVR");
+       strscpy(dev->video_dev.name, "Hauppauge HD PVR",
+               sizeof(dev->video_dev.name));
        dev->video_dev.v4l2_dev = &dev->v4l2_dev;
        video_set_drvdata(&dev->video_dev, dev);
 
index 65ef755adfdc1ee51828c3b044b26751c1f76b05..10b5b95bee34d22dd0c516e9aba219257c6f2daf 100644 (file)
@@ -604,8 +604,8 @@ static int msi2500_querycap(struct file *file, void *fh,
 
        dev_dbg(dev->dev, "\n");
 
-       strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
-       strlcpy(cap->card, dev->vdev.name, sizeof(cap->card));
+       strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+       strscpy(cap->card, dev->vdev.name, sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
                        V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
@@ -916,7 +916,7 @@ static int msi2500_enum_fmt_sdr_cap(struct file *file, void *priv,
        if (f->index >= dev->num_formats)
                return -EINVAL;
 
-       strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+       strscpy(f->description, formats[f->index].name, sizeof(f->description));
        f->pixelformat = formats[f->index].pixelformat;
 
        return 0;
@@ -1017,7 +1017,7 @@ static int msi2500_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
        dev_dbg(dev->dev, "index=%d\n", v->index);
 
        if (v->index == 0) {
-               strlcpy(v->name, "Mirics MSi2500", sizeof(v->name));
+               strscpy(v->name, "Mirics MSi2500", sizeof(v->name));
                v->type = V4L2_TUNER_ADC;
                v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
                v->rangelow =   1200000;
@@ -1278,7 +1278,7 @@ static int msi2500_probe(struct usb_interface *intf,
        }
 
        /* currently all controls are from subdev */
-       v4l2_ctrl_add_handler(&dev->hdl, sd->ctrl_handler, NULL);
+       v4l2_ctrl_add_handler(&dev->hdl, sd->ctrl_handler, NULL, true);
 
        dev->v4l2_dev.ctrl_handler = &dev->hdl;
        dev->vdev.v4l2_dev = &dev->v4l2_dev;
index 350635826aaed39898519ba4844327ab9d4695eb..365c78b748dd5cb1e5b739a462a7e4df656738b7 100644 (file)
@@ -571,7 +571,8 @@ static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
                        memset(osd_str + osd_len, ' ', 4 - osd_len);
                        osd_len = 4;
                        osd_str[osd_len] = '\0';
-                       strcpy(adap->log_addrs.osd_name, osd_str);
+                       strscpy(adap->log_addrs.osd_name, osd_str,
+                               sizeof(adap->log_addrs.osd_name));
                }
                err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len,
                                           MSGCODE_COMMAND_ACCEPTED, 0);
index 5cd16292e2fa1ae2de78c6586d24a6c5678f1122..1323f949f4545d7bffd1717245418003c4784580 100644 (file)
@@ -17,7 +17,7 @@
 
 extern int pvrusb2_debug;
 
-#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0)
+#define pvr2_trace(msk, fmt, arg...) do {if (msk & pvrusb2_debug) pr_info("pvrusb2: " fmt "\n", ##arg); } while (0)
 
 /* These are listed in *rough* order of decreasing usefulness and
    increasing noise level. */
index a8519da0020bf82e9e15cfd5295cd9b6c02b5405..7702285c15193f144f5cf9e3305a1685b185ecd4 100644 (file)
@@ -3293,12 +3293,12 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
        int nr = pvr2_hdw_get_unit_number(hdw);
        LOCK_TAKE(hdw->big_lock);
        do {
-               printk(KERN_INFO "pvrusb2: =================  START STATUS CARD #%d  =================\n", nr);
+               pr_info("pvrusb2: =================  START STATUS CARD #%d  =================\n", nr);
                v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
                pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
                cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
                pvr2_hdw_state_log_state(hdw);
-               printk(KERN_INFO "pvrusb2: ==================  END STATUS CARD #%d  ==================\n", nr);
+               pr_info("pvrusb2: ==================  END STATUS CARD #%d  ==================\n", nr);
        } while (0);
        LOCK_GIVE(hdw->big_lock);
 }
@@ -4851,7 +4851,7 @@ static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
        for (idx = 0; ; idx++) {
                ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
                if (!ccnt) break;
-               printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
+               pr_info("%s %.*s\n", hdw->name, ccnt, buf);
        }
        ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
        if (ccnt >= sizeof(buf))
@@ -4863,7 +4863,7 @@ static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
                while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
                        lcnt++;
                }
-               printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
+               pr_info("%s %.*s\n", hdw->name, lcnt, buf + ucnt);
                ucnt += lcnt + 1;
        }
 }
index f3003ca05f4ba370d3ccbc647b269ca5bd817c9c..8f023085c2d928401c8025f1ca8cb49beb6306eb 100644 (file)
@@ -478,8 +478,7 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
                unsigned int idx,offs,cnt;
                for (idx = 0; idx < num; idx++) {
                        cnt = msgs[idx].len;
-                       printk(KERN_INFO
-                              "pvrusb2 i2c xfer %u/%u: addr=0x%x len=%d %s",
+                       pr_info("pvrusb2 i2c xfer %u/%u: addr=0x%x len=%d %s",
                               idx+1,num,
                               msgs[idx].addr,
                               cnt,
@@ -487,22 +486,21 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
                                "read" : "write"));
                        if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
                                if (cnt > 8) cnt = 8;
-                               printk(KERN_CONT " [");
+                               pr_cont(" [");
                                for (offs = 0; offs < cnt; offs++) {
-                                       if (offs) printk(KERN_CONT " ");
-                                       printk(KERN_CONT "%02x",msgs[idx].buf[offs]);
+                                       if (offs) pr_cont(" ");
+                                       pr_cont("%02x", msgs[idx].buf[offs]);
                                }
-                               if (offs < cnt) printk(KERN_CONT " ...");
-                               printk(KERN_CONT "]");
+                               if (offs < cnt) pr_cont(" ...");
+                               pr_cont("]");
                        }
                        if (idx+1 == num) {
-                               printk(KERN_CONT " result=%d",ret);
+                               pr_cont(" result=%d", ret);
                        }
-                       printk(KERN_CONT "\n");
+                       pr_cont("\n");
                }
                if (!num) {
-                       printk(KERN_INFO
-                              "pvrusb2 i2c xfer null transfer result=%d\n",
+                       pr_info("pvrusb2 i2c xfer null transfer result=%d\n",
                               ret);
                }
        }
@@ -542,14 +540,14 @@ static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
 static void do_i2c_scan(struct pvr2_hdw *hdw)
 {
        int i;
-       printk(KERN_INFO "%s: i2c scan beginning\n", hdw->name);
+       pr_info("%s: i2c scan beginning\n", hdw->name);
        for (i = 0; i < 128; i++) {
                if (do_i2c_probe(hdw, i)) {
-                       printk(KERN_INFO "%s: i2c scan: found device @ 0x%x\n",
+                       pr_info("%s: i2c scan: found device @ 0x%x\n",
                               hdw->name, i);
                }
        }
-       printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
+       pr_info("%s: i2c scan done.\n", hdw->name);
 }
 
 static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
@@ -573,7 +571,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
                /* IR Receiver */
                info.addr          = 0x18;
                info.platform_data = init_data;
-               strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+               strscpy(info.type, "ir_video", I2C_NAME_SIZE);
                pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
                           info.type, info.addr);
                i2c_new_device(&hdw->i2c_adap, &info);
@@ -588,7 +586,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
                /* IR Transceiver */
                info.addr = 0x71;
                info.platform_data = init_data;
-               strlcpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
+               strscpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
                pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
                           info.type, info.addr);
                i2c_new_device(&hdw->i2c_adap, &info);
@@ -612,7 +610,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
 
        /* However, deal with various special cases for 24xxx hardware. */
        if (ir_mode[hdw->unit_number] == 0) {
-               printk(KERN_INFO "%s: IR disabled\n",hdw->name);
+               pr_info("%s: IR disabled\n", hdw->name);
                hdw->i2c_func[0x18] = i2c_black_hole;
        } else if (ir_mode[hdw->unit_number] == 1) {
                if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
@@ -631,7 +629,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
        // Configure the adapter and set up everything else related to it.
        hdw->i2c_adap = pvr2_i2c_adap_template;
        hdw->i2c_algo = pvr2_i2c_algo_template;
-       strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
+       strscpy(hdw->i2c_adap.name, hdw->name, sizeof(hdw->i2c_adap.name));
        hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
        hdw->i2c_adap.algo = &hdw->i2c_algo;
        hdw->i2c_adap.algo_data = hdw;
index cbe2c3a2245839005aa05f3bd56eedcc9a853270..23672dd352f5918c15a8d9d7432d291db937b5ab 100644 (file)
@@ -132,10 +132,10 @@ static int __init pvr_init(void)
        ret = usb_register(&pvr_driver);
 
        if (ret == 0)
-               printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
+               pr_info("pvrusb2: " DRIVER_VERSION ":"
                       DRIVER_DESC "\n");
        if (pvrusb2_debug)
-               printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
+               pr_info("pvrusb2: Debug mask is %d (0x%x)\n",
                       pvrusb2_debug,pvrusb2_debug);
 
        pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
index e53a80b589a15b3e5f7c2dd05aed728b65c2ffe5..97a93ed4bcda74a5923734aacfcbb198597fba85 100644 (file)
@@ -121,10 +121,10 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *
        struct pvr2_v4l2_fh *fh = file->private_data;
        struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 
-       strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver));
-       strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
-                       sizeof(cap->bus_info));
-       strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
+       strscpy(cap->driver, "pvrusb2", sizeof(cap->driver));
+       strscpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
+               sizeof(cap->bus_info));
+       strscpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
                            V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
                            V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS;
@@ -545,7 +545,7 @@ static int pvr2_queryctrl(struct file *file, void *priv,
                        "QUERYCTRL id=0x%x mapping name=%s (%s)",
                        vc->id, pvr2_ctrl_get_name(cptr),
                        pvr2_ctrl_get_desc(cptr));
-       strlcpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
+       strscpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
        vc->flags = pvr2_ctrl_get_v4lflags(cptr);
        pvr2_ctrl_get_def(cptr, &val);
        vc->default_value = val;
@@ -869,7 +869,7 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
           are gone. */
        video_unregister_device(&dip->devbase);
 
-       printk(KERN_INFO "%s\n", msg);
+       pr_info("%s\n", msg);
 
 }
 
@@ -1260,7 +1260,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
                        ": Failed to register pvrusb2 v4l device\n");
        }
 
-       printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
+       pr_info("pvrusb2: registered device %s [%s]\n",
               video_device_node_name(&dip->devbase),
               pvr2_config_get_name(dip->config));
 
index 54b036d39c5b973eaec5c8be428050023109fdb9..72704f4d5330b9bbb0cb9d602dd1d59e6981dd85 100644 (file)
@@ -1027,7 +1027,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 
        /* Init video_device structure */
        pdev->vdev = pwc_template;
-       strcpy(pdev->vdev.name, name);
+       strscpy(pdev->vdev.name, name, sizeof(pdev->vdev.name));
        pdev->vdev.queue = &pdev->vb_queue;
        pdev->vdev.queue->lock = &pdev->vb_queue_lock;
        video_set_drvdata(&pdev->vdev, pdev);
index 043b2b97cee6795c9eaa5f52797480f852b3cc95..bef6e4ef8a7e14812f064d566e37e9af497fc14c 100644 (file)
@@ -492,8 +492,8 @@ static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap
 {
        struct pwc_device *pdev = video_drvdata(file);
 
-       strcpy(cap->driver, PWC_NAME);
-       strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
+       strscpy(cap->driver, PWC_NAME, sizeof(cap->driver));
+       strscpy(cap->card, pdev->vdev.name, sizeof(cap->card));
        usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
                                        V4L2_CAP_READWRITE;
@@ -506,7 +506,7 @@ static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
        if (i->index)   /* Only one INPUT is supported */
                return -EINVAL;
 
-       strlcpy(i->name, "Camera", sizeof(i->name));
+       strscpy(i->name, "Camera", sizeof(i->name));
        i->type = V4L2_INPUT_TYPE_CAMERA;
        return 0;
 }
@@ -889,11 +889,13 @@ static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc
                /* RAW format */
                f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
                f->flags = V4L2_FMT_FLAG_COMPRESSED;
-               strlcpy(f->description, "Raw Philips Webcam", sizeof(f->description));
+               strscpy(f->description, "Raw Philips Webcam",
+                       sizeof(f->description));
                break;
        case 1:
                f->pixelformat = V4L2_PIX_FMT_YUV420;
-               strlcpy(f->description, "4:2:0, planar, Y-Cb-Cr", sizeof(f->description));
+               strscpy(f->description, "4:2:0, planar, Y-Cb-Cr",
+                       sizeof(f->description));
                break;
        default:
                return -EINVAL;
index cecdcbcd400c5f6c1a6c1f841d7582b9bf0f83b4..d9964da05976b5bc925fd12626137d0e08162782 100644 (file)
@@ -141,7 +141,8 @@ static void rain_irq_work_handler(struct work_struct *work)
                            !memcmp(rain->cmd, "STA", 3)) {
                                rain_process_msg(rain);
                        } else {
-                               strcpy(rain->cmd_reply, rain->cmd);
+                               strscpy(rain->cmd_reply, rain->cmd,
+                                       sizeof(rain->cmd_reply));
                                complete(&rain->cmd_done);
                        }
                        rain->cmd_idx = 0;
index 82927eb334c48d07be8b8ec6cd121de37edf643f..5b3e54b76e9a522b2b69f3d55612b04c120426d9 100644 (file)
@@ -730,8 +730,8 @@ static int vidioc_querycap(struct file *file, void *priv,
        struct s2255_vc *vc = video_drvdata(file);
        struct s2255_dev *dev = vc->dev;
 
-       strlcpy(cap->driver, "s2255", sizeof(cap->driver));
-       strlcpy(cap->card, "s2255", sizeof(cap->card));
+       strscpy(cap->driver, "s2255", sizeof(cap->driver));
+       strscpy(cap->card, "s2255", sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
                V4L2_CAP_READWRITE;
@@ -749,7 +749,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
        if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
                        (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
                return -EINVAL;
-       strlcpy(f->description, formats[index].name, sizeof(f->description));
+       strscpy(f->description, formats[index].name, sizeof(f->description));
        f->pixelformat = formats[index].fourcc;
        return 0;
 }
@@ -1195,10 +1195,10 @@ static int vidioc_enum_input(struct file *file, void *priv,
        switch (dev->pid) {
        case 0x2255:
        default:
-               strlcpy(inp->name, "Composite", sizeof(inp->name));
+               strscpy(inp->name, "Composite", sizeof(inp->name));
                break;
        case 0x2257:
-               strlcpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
+               strscpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
                        sizeof(inp->name));
                break;
        }
index 62a12d5356ad2a4e8052a4997ec059f17005a10f..c3a15564e5cb58aaf7639ba444fea54a84d24dfe 100644 (file)
@@ -260,7 +260,7 @@ int stk1160_i2c_register(struct stk1160 *dev)
 
        dev->i2c_adap = adap_template;
        dev->i2c_adap.dev.parent = dev->dev;
-       strcpy(dev->i2c_adap.name, "stk1160");
+       strscpy(dev->i2c_adap.name, "stk1160", sizeof(dev->i2c_adap.name));
        dev->i2c_adap.algo_data = dev;
 
        i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
index 504e413edcd25a49bce6232cebf2c0937b8716ad..701ed3d4afe64a493dc225198dff2164bd365a3f 100644 (file)
@@ -344,8 +344,8 @@ static int vidioc_querycap(struct file *file,
 {
        struct stk1160 *dev = video_drvdata(file);
 
-       strcpy(cap->driver, "stk1160");
-       strcpy(cap->card, "stk1160");
+       strscpy(cap->driver, "stk1160", sizeof(cap->driver));
+       strscpy(cap->card, "stk1160", sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps =
                V4L2_CAP_VIDEO_CAPTURE |
@@ -361,7 +361,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index != 0)
                return -EINVAL;
 
-       strlcpy(f->description, format[f->index].name, sizeof(f->description));
+       strscpy(f->description, format[f->index].name, sizeof(f->description));
        f->pixelformat = format[f->index].fourcc;
        return 0;
 }
index 5accb52410720196b24181e18ee0620e68dbc223..e11d5d5b7c263e9a00be1e2334b108f2f14111ee 100644 (file)
@@ -793,8 +793,8 @@ static int stk_vidioc_querycap(struct file *filp,
 {
        struct stk_camera *dev = video_drvdata(filp);
 
-       strcpy(cap->driver, "stk");
-       strcpy(cap->card, "stk");
+       strscpy(cap->driver, "stk", sizeof(cap->driver));
+       strscpy(cap->card, "stk", sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
@@ -809,7 +809,7 @@ static int stk_vidioc_enum_input(struct file *filp,
        if (input->index != 0)
                return -EINVAL;
 
-       strcpy(input->name, "Syntek USB Camera");
+       strscpy(input->name, "Syntek USB Camera", sizeof(input->name));
        input->type = V4L2_INPUT_TYPE_CAMERA;
        return 0;
 }
@@ -859,23 +859,23 @@ static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
        switch (fmtd->index) {
        case 0:
                fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
-               strcpy(fmtd->description, "r5g6b5");
+               strscpy(fmtd->description, "r5g6b5", sizeof(fmtd->description));
                break;
        case 1:
                fmtd->pixelformat = V4L2_PIX_FMT_RGB565X;
-               strcpy(fmtd->description, "r5g6b5BE");
+               strscpy(fmtd->description, "r5g6b5BE", sizeof(fmtd->description));
                break;
        case 2:
                fmtd->pixelformat = V4L2_PIX_FMT_UYVY;
-               strcpy(fmtd->description, "yuv4:2:2");
+               strscpy(fmtd->description, "yuv4:2:2", sizeof(fmtd->description));
                break;
        case 3:
                fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
-               strcpy(fmtd->description, "Raw bayer");
+               strscpy(fmtd->description, "Raw bayer", sizeof(fmtd->description));
                break;
        case 4:
                fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
-               strcpy(fmtd->description, "yuv4:2:2");
+               strscpy(fmtd->description, "yuv4:2:2", sizeof(fmtd->description));
                break;
        default:
                return -EINVAL;
index f18cffae4c85a15bbaf38a170de44fa0e6c637a3..b965931793b57acf7edd67d67a68e0e71fa99035 100644 (file)
@@ -429,8 +429,8 @@ static int tm6000_audio_init(struct tm6000_core *dev)
                snd_printk(KERN_ERR "cannot create card instance %d\n", devnr);
                return rc;
        }
-       strcpy(card->driver, "tm6000-alsa");
-       strcpy(card->shortname, "TM5600/60x0");
+       strscpy(card->driver, "tm6000-alsa", sizeof(card->driver));
+       strscpy(card->shortname, "TM5600/60x0", sizeof(card->shortname));
        sprintf(card->longname, "TM5600/60x0 Audio at bus %d device %d",
                dev->udev->bus->busnum, dev->udev->devnum);
 
@@ -456,7 +456,7 @@ static int tm6000_audio_init(struct tm6000_core *dev)
 
        pcm->info_flags = 0;
        pcm->private_data = chip;
-       strcpy(pcm->name, "Trident TM5600/60x0");
+       strscpy(pcm->name, "Trident TM5600/60x0", sizeof(pcm->name));
 
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
 
index ccd1adf862b14cbd4246e07c50430b366dd7f3cb..8c0476dfe54f6f1833a91bedab5e0b374d96744b 100644 (file)
@@ -292,7 +292,7 @@ int tm6000_i2c_register(struct tm6000_core *dev)
        dev->i2c_adap.owner = THIS_MODULE;
        dev->i2c_adap.algo = &tm6000_algo;
        dev->i2c_adap.dev.parent = &dev->udev->dev;
-       strlcpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
+       strscpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name));
        dev->i2c_adap.algo_data = dev;
        i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
        rc = i2c_add_adapter(&dev->i2c_adap);
@@ -300,7 +300,7 @@ int tm6000_i2c_register(struct tm6000_core *dev)
                return rc;
 
        dev->i2c_client.adapter = &dev->i2c_adap;
-       strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
+       strscpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
        tm6000_i2c_eeprom(dev);
 
        return 0;
index 7d268f2404e1921ea6187fb2246e9233ad7ba6dc..ee7b5318b3518b35f7da2ef6a20cbf8970527a7c 100644 (file)
@@ -856,8 +856,9 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
        struct video_device *vdev = video_devdata(file);
 
-       strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
-       strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
+       strscpy(cap->driver, "tm6000", sizeof(cap->driver));
+       strscpy(cap->card, "Trident TVMaster TM5600/6000/6010",
+               sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        if (dev->tuner_type != TUNER_ABSENT)
                cap->device_caps |= V4L2_CAP_TUNER;
@@ -879,7 +880,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index >= ARRAY_SIZE(format))
                return -EINVAL;
 
-       strlcpy(f->description, format[f->index].name, sizeof(f->description));
+       strscpy(f->description, format[f->index].name, sizeof(f->description));
        f->pixelformat = format[f->index].fourcc;
        return 0;
 }
@@ -1091,7 +1092,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
        else
                i->type = V4L2_INPUT_TYPE_CAMERA;
 
-       strcpy(i->name, iname[dev->vinput[n].type]);
+       strscpy(i->name, iname[dev->vinput[n].type], sizeof(i->name));
 
        i->std = TM6000_STD;
 
@@ -1188,7 +1189,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (0 != t->index)
                return -EINVAL;
 
-       strcpy(t->name, "Television");
+       strscpy(t->name, "Television", sizeof(t->name));
        t->type       = V4L2_TUNER_ANALOG_TV;
        t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
        t->rangehigh  = 0xffffffffUL;
@@ -1268,7 +1269,7 @@ static int radio_g_tuner(struct file *file, void *priv,
                return -EINVAL;
 
        memset(t, 0, sizeof(*t));
-       strcpy(t->name, "Radio");
+       strscpy(t->name, "Radio", sizeof(t->name));
        t->type = V4L2_TUNER_RADIO;
        t->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
        t->rxsubchans = V4L2_TUNER_SUB_STEREO;
@@ -1626,7 +1627,7 @@ int tm6000_v4l2_register(struct tm6000_core *dev)
        v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops,
                        V4L2_CID_HUE, -128, 127, 1, 0);
        v4l2_ctrl_add_handler(&dev->ctrl_handler,
-                       &dev->radio_ctrl_handler, NULL);
+                       &dev->radio_ctrl_handler, NULL, false);
 
        if (dev->radio_ctrl_handler.error)
                ret = dev->radio_ctrl_handler.error;
index eed56895c2b99052295614f742441f94d923a836..6eb84cf007b4ca62f640324b226619810205cb48 100644 (file)
@@ -1686,7 +1686,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        /* i2c */
        memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
-       strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
+       strscpy(ttusb->i2c_adap.name, "TTUSB DEC", sizeof(ttusb->i2c_adap.name));
 
        i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
 
index 4ce38246ed6415f312de88f04649f36a4d59daeb..6f108996142d742b4c8ec3ba99368c97ce8f1373 100644 (file)
@@ -358,8 +358,8 @@ int usbtv_audio_init(struct usbtv *usbtv)
        if (rv < 0)
                return rv;
 
-       strlcpy(card->driver, usbtv->dev->driver->name, sizeof(card->driver));
-       strlcpy(card->shortname, "usbtv", sizeof(card->shortname));
+       strscpy(card->driver, usbtv->dev->driver->name, sizeof(card->driver));
+       strscpy(card->shortname, "usbtv", sizeof(card->shortname));
        snprintf(card->longname, sizeof(card->longname),
                "USBTV Audio at bus %d device %d", usbtv->udev->bus->busnum,
                usbtv->udev->devnum);
@@ -372,7 +372,7 @@ int usbtv_audio_init(struct usbtv *usbtv)
        if (rv < 0)
                goto err;
 
-       strlcpy(pcm->name, "USBTV Audio Input", sizeof(pcm->name));
+       strscpy(pcm->name, "USBTV Audio Input", sizeof(pcm->name));
        pcm->info_flags = 0;
        pcm->private_data = usbtv;
 
index 36a9a401718574fc7c8809934e035cc30b4eb546..4a1eab711bdc632da2a3ea80ad5c2a5384cadd93 100644 (file)
@@ -600,8 +600,8 @@ static int usbtv_querycap(struct file *file, void *priv,
 {
        struct usbtv *dev = video_drvdata(file);
 
-       strlcpy(cap->driver, "usbtv", sizeof(cap->driver));
-       strlcpy(cap->card, "usbtv", sizeof(cap->card));
+       strscpy(cap->driver, "usbtv", sizeof(cap->driver));
+       strscpy(cap->card, "usbtv", sizeof(cap->card));
        usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE;
        cap->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
@@ -616,10 +616,10 @@ static int usbtv_enum_input(struct file *file, void *priv,
 
        switch (i->index) {
        case USBTV_COMPOSITE_INPUT:
-               strlcpy(i->name, "Composite", sizeof(i->name));
+               strscpy(i->name, "Composite", sizeof(i->name));
                break;
        case USBTV_SVIDEO_INPUT:
-               strlcpy(i->name, "S-Video", sizeof(i->name));
+               strscpy(i->name, "S-Video", sizeof(i->name));
                break;
        default:
                return -EINVAL;
@@ -636,8 +636,8 @@ static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
        if (f->index > 0)
                return -EINVAL;
 
-       strlcpy(f->description, "16 bpp YUY2, 4:2:2, packed",
-                                       sizeof(f->description));
+       strscpy(f->description, "16 bpp YUY2, 4:2:2, packed",
+               sizeof(f->description));
        f->pixelformat = V4L2_PIX_FMT_YUYV;
        return 0;
 }
@@ -934,7 +934,7 @@ int usbtv_video_init(struct usbtv *usbtv)
        }
 
        /* Video structure */
-       strlcpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name));
+       strscpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name));
        usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev;
        usbtv->vdev.release = video_device_release_empty;
        usbtv->vdev.fops = &usbtv_fops;
index 7138c2b606cce92e1e2c450ed09e42d672025c41..31e0e98d6dafe429d87c92e1d669174f96b26e21 100644 (file)
@@ -1272,7 +1272,6 @@ static void usbvision_isoc_irq(struct urb *urb)
        int len;
        struct usb_usbvision *usbvision = urb->context;
        int i;
-       unsigned long start_time = jiffies;
        struct usbvision_frame **f;
 
        /* We don't want to do anything if we are about to be removed! */
@@ -1324,8 +1323,6 @@ static void usbvision_isoc_irq(struct urb *urb)
                scratch_reset(usbvision);
        }
 
-       usbvision->time_in_irq += jiffies - start_time;
-
        for (i = 0; i < USBVISION_URB_FRAMES; i++) {
                urb->iso_frame_desc[i].status = 0;
                urb->iso_frame_desc[i].actual_length = 0;
index f29d1bef029367f241dbbb1125199ee2d99f2525..dd2ff8ed6c6a2b34949e99105853d251cf38295c 100644 (file)
@@ -467,8 +467,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct usb_usbvision *usbvision = video_drvdata(file);
        struct video_device *vdev = video_devdata(file);
 
-       strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
-       strlcpy(vc->card,
+       strscpy(vc->driver, "USBVision", sizeof(vc->driver));
+       strscpy(vc->card,
                usbvision_device_data[usbvision->dev_model].model_string,
                sizeof(vc->card));
        usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
@@ -504,9 +504,9 @@ static int vidioc_enum_input(struct file *file, void *priv,
        switch (chan) {
        case 0:
                if (usbvision_device_data[usbvision->dev_model].video_channels == 4) {
-                       strcpy(vi->name, "White Video Input");
+                       strscpy(vi->name, "White Video Input", sizeof(vi->name));
                } else {
-                       strcpy(vi->name, "Television");
+                       strscpy(vi->name, "Television", sizeof(vi->name));
                        vi->type = V4L2_INPUT_TYPE_TUNER;
                        vi->tuner = chan;
                        vi->std = USBVISION_NORMS;
@@ -515,22 +515,23 @@ static int vidioc_enum_input(struct file *file, void *priv,
        case 1:
                vi->type = V4L2_INPUT_TYPE_CAMERA;
                if (usbvision_device_data[usbvision->dev_model].video_channels == 4)
-                       strcpy(vi->name, "Green Video Input");
+                       strscpy(vi->name, "Green Video Input", sizeof(vi->name));
                else
-                       strcpy(vi->name, "Composite Video Input");
+                       strscpy(vi->name, "Composite Video Input",
+                               sizeof(vi->name));
                vi->std = USBVISION_NORMS;
                break;
        case 2:
                vi->type = V4L2_INPUT_TYPE_CAMERA;
                if (usbvision_device_data[usbvision->dev_model].video_channels == 4)
-                       strcpy(vi->name, "Yellow Video Input");
+                       strscpy(vi->name, "Yellow Video Input", sizeof(vi->name));
                else
-                       strcpy(vi->name, "S-Video Input");
+                       strscpy(vi->name, "S-Video Input", sizeof(vi->name));
                vi->std = USBVISION_NORMS;
                break;
        case 3:
                vi->type = V4L2_INPUT_TYPE_CAMERA;
-               strcpy(vi->name, "Red Video Input");
+               strscpy(vi->name, "Red Video Input", sizeof(vi->name));
                vi->std = USBVISION_NORMS;
                break;
        }
@@ -589,9 +590,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
        if (vt->index)  /* Only tuner 0 */
                return -EINVAL;
        if (vt->type == V4L2_TUNER_RADIO)
-               strcpy(vt->name, "Radio");
+               strscpy(vt->name, "Radio", sizeof(vt->name));
        else
-               strcpy(vt->name, "Television");
+               strscpy(vt->name, "Television", sizeof(vt->name));
 
        /* Let clients fill in the remainder of this struct */
        call_all(usbvision, tuner, g_tuner, vt);
@@ -814,7 +815,8 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 {
        if (vfd->index >= USBVISION_SUPPORTED_PALETTES - 1)
                return -EINVAL;
-       strcpy(vfd->description, usbvision_v4l2_format[vfd->index].desc);
+       strscpy(vfd->description, usbvision_v4l2_format[vfd->index].desc,
+               sizeof(vfd->description));
        vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
        return 0;
 }
index 6ecdcd58248f195cd4a2c7e43b62f93d8857170a..017e7baf57473b3ae5514314d36a254533669e58 100644 (file)
@@ -447,7 +447,6 @@ struct usb_usbvision {
        unsigned long isoc_skip_count;                  /* How many empty ISO packets received */
        unsigned long isoc_err_count;                   /* How many bad ISO packets received */
        unsigned long isoc_packet_count;                /* How many packets we totally got */
-       unsigned long time_in_irq;                      /* How long do we need for interrupt */
        int isoc_measure_bandwidth_count;
        int frame_num;                                  /* How many video frames we send to user */
        int max_strip_len;                              /* How big is the biggest strip */
index c2ad102bd693d219846c400bf09b328ee92825e5..d45415cbe6e7af9bb07ddb23530b44c4779761b5 100644 (file)
@@ -38,7 +38,7 @@
  * Controls
  */
 
-static struct uvc_control_info uvc_ctrls[] = {
+static const struct uvc_control_info uvc_ctrls[] = {
        {
                .entity         = UVC_GUID_UVC_PROCESSING,
                .selector       = UVC_PU_BRIGHTNESS_CONTROL,
@@ -354,13 +354,13 @@ static struct uvc_control_info uvc_ctrls[] = {
        },
 };
 
-static struct uvc_menu_info power_line_frequency_controls[] = {
+static const struct uvc_menu_info power_line_frequency_controls[] = {
        { 0, "Disabled" },
        { 1, "50 Hz" },
        { 2, "60 Hz" },
 };
 
-static struct uvc_menu_info exposure_auto_controls[] = {
+static const struct uvc_menu_info exposure_auto_controls[] = {
        { 2, "Auto Mode" },
        { 1, "Manual Mode" },
        { 4, "Shutter Priority Mode" },
@@ -421,7 +421,7 @@ static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping,
        data[first+1] = min_t(int, abs(value), 0xff);
 }
 
-static struct uvc_control_mapping uvc_ctrl_mappings[] = {
+static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
        {
                .id             = V4L2_CID_BRIGHTNESS,
                .name           = "Brightness",
@@ -978,7 +978,7 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
        s32 value = mapping->get(mapping, UVC_GET_CUR, data);
 
        if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
-               struct uvc_menu_info *menu = mapping->menu_info;
+               const struct uvc_menu_info *menu = mapping->menu_info;
                unsigned int i;
 
                for (i = 0; i < mapping->menu_count; ++i, ++menu) {
@@ -1025,13 +1025,13 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
 {
        struct uvc_control_mapping *master_map = NULL;
        struct uvc_control *master_ctrl = NULL;
-       struct uvc_menu_info *menu;
+       const struct uvc_menu_info *menu;
        unsigned int i;
 
        memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
        v4l2_ctrl->id = mapping->id;
        v4l2_ctrl->type = mapping->v4l2_type;
-       strlcpy(v4l2_ctrl->name, mapping->name, sizeof(v4l2_ctrl->name));
+       strscpy(v4l2_ctrl->name, mapping->name, sizeof(v4l2_ctrl->name));
        v4l2_ctrl->flags = 0;
 
        if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
@@ -1145,7 +1145,7 @@ done:
 int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
        struct v4l2_querymenu *query_menu)
 {
-       struct uvc_menu_info *menu_info;
+       const struct uvc_menu_info *menu_info;
        struct uvc_control_mapping *mapping;
        struct uvc_control *ctrl;
        u32 index = query_menu->index;
@@ -1191,7 +1191,7 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
                }
        }
 
-       strlcpy(query_menu->name, menu_info->name, sizeof(query_menu->name));
+       strscpy(query_menu->name, menu_info->name, sizeof(query_menu->name));
 
 done:
        mutex_unlock(&chain->ctrl_mutex);
index 368f8f8dfcb5c5917e63fbf1cf25bb80f1d4ed50..77e7c2419b9bc59735a993fbd7e85ebd2c160288 100644 (file)
@@ -106,9 +106,6 @@ void uvc_debugfs_init_stream(struct uvc_streaming *stream)
 
 void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream)
 {
-       if (stream->debugfs_dir == NULL)
-               return;
-
        debugfs_remove_recursive(stream->debugfs_dir);
        stream->debugfs_dir = NULL;
 }
@@ -128,6 +125,5 @@ void uvc_debugfs_init(void)
 
 void uvc_debugfs_cleanup(void)
 {
-       if (uvc_debugfs_root_dir != NULL)
-               debugfs_remove_recursive(uvc_debugfs_root_dir);
+       debugfs_remove_recursive(uvc_debugfs_root_dir);
 }
index d46dc432456c4fc4a1fe72bab319b9bc3eb1fdd8..bc369a0934a36258d99b5d6dde0b02dc51fe6d8b 100644 (file)
@@ -427,7 +427,7 @@ static int uvc_parse_format(struct uvc_device *dev,
                fmtdesc = uvc_format_by_guid(&buffer[5]);
 
                if (fmtdesc != NULL) {
-                       strlcpy(format->name, fmtdesc->name,
+                       strscpy(format->name, fmtdesc->name,
                                sizeof(format->name));
                        format->fcc = fmtdesc->fcc;
                } else {
@@ -445,7 +445,7 @@ static int uvc_parse_format(struct uvc_device *dev,
                 */
                if (dev->quirks & UVC_QUIRK_FORCE_Y8) {
                        if (format->fcc == V4L2_PIX_FMT_YUYV) {
-                               strlcpy(format->name, "Greyscale 8-bit (Y8  )",
+                               strscpy(format->name, "Greyscale 8-bit (Y8  )",
                                        sizeof(format->name));
                                format->fcc = V4L2_PIX_FMT_GREY;
                                format->bpp = 8;
@@ -471,7 +471,7 @@ static int uvc_parse_format(struct uvc_device *dev,
                        return -EINVAL;
                }
 
-               strlcpy(format->name, "MJPEG", sizeof(format->name));
+               strscpy(format->name, "MJPEG", sizeof(format->name));
                format->fcc = V4L2_PIX_FMT_MJPEG;
                format->flags = UVC_FMT_FLAG_COMPRESSED;
                format->bpp = 0;
@@ -489,13 +489,13 @@ static int uvc_parse_format(struct uvc_device *dev,
 
                switch (buffer[8] & 0x7f) {
                case 0:
-                       strlcpy(format->name, "SD-DV", sizeof(format->name));
+                       strscpy(format->name, "SD-DV", sizeof(format->name));
                        break;
                case 1:
-                       strlcpy(format->name, "SDL-DV", sizeof(format->name));
+                       strscpy(format->name, "SDL-DV", sizeof(format->name));
                        break;
                case 2:
-                       strlcpy(format->name, "HD-DV", sizeof(format->name));
+                       strscpy(format->name, "HD-DV", sizeof(format->name));
                        break;
                default:
                        uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
@@ -914,7 +914,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
        unsigned int size;
        unsigned int i;
 
-       extra_size = ALIGN(extra_size, sizeof(*entity->pads));
+       extra_size = roundup(extra_size, sizeof(*entity->pads));
        num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
        size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
             + num_inputs;
@@ -1932,7 +1932,7 @@ int uvc_register_video_device(struct uvc_device *dev,
                break;
        }
 
-       strlcpy(vdev->name, dev->name, sizeof(vdev->name));
+       strscpy(vdev->name, dev->name, sizeof(vdev->name));
 
        /*
         * Set the driver data before calling video_register_device, otherwise
@@ -2027,10 +2027,9 @@ static int uvc_register_chains(struct uvc_device *dev)
 
 #ifdef CONFIG_MEDIA_CONTROLLER
                ret = uvc_mc_register_entities(chain);
-               if (ret < 0) {
-                       uvc_printk(KERN_INFO, "Failed to register entites "
-                               "(%d).\n", ret);
-               }
+               if (ret < 0)
+                       uvc_printk(KERN_INFO,
+                                  "Failed to register entities (%d).\n", ret);
 #endif
        }
 
@@ -2041,10 +2040,7 @@ static int uvc_register_chains(struct uvc_device *dev)
  * USB probe, disconnect, suspend and resume
  */
 
-struct uvc_device_info {
-       u32     quirks;
-       u32     meta_format;
-};
+static const struct uvc_device_info uvc_quirk_none = { 0 };
 
 static int uvc_probe(struct usb_interface *intf,
                     const struct usb_device_id *id)
@@ -2053,7 +2049,6 @@ static int uvc_probe(struct usb_interface *intf,
        struct uvc_device *dev;
        const struct uvc_device_info *info =
                (const struct uvc_device_info *)id->driver_info;
-       u32 quirks = info ? info->quirks : 0;
        int function;
        int ret;
 
@@ -2080,13 +2075,12 @@ static int uvc_probe(struct usb_interface *intf,
        dev->udev = usb_get_dev(udev);
        dev->intf = usb_get_intf(intf);
        dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
-       dev->quirks = (uvc_quirks_param == -1)
-                   ? quirks : uvc_quirks_param;
-       if (info)
-               dev->meta_format = info->meta_format;
+       dev->info = info ? info : &uvc_quirk_none;
+       dev->quirks = uvc_quirks_param == -1
+                   ? dev->info->quirks : uvc_quirks_param;
 
        if (udev->product != NULL)
-               strlcpy(dev->name, udev->product, sizeof(dev->name));
+               strscpy(dev->name, udev->product, sizeof(dev->name));
        else
                snprintf(dev->name, sizeof(dev->name),
                         "UVC Camera (%04x:%04x)",
@@ -2124,7 +2118,7 @@ static int uvc_probe(struct usb_interface *intf,
                le16_to_cpu(udev->descriptor.idVendor),
                le16_to_cpu(udev->descriptor.idProduct));
 
-       if (dev->quirks != quirks) {
+       if (dev->quirks != dev->info->quirks) {
                uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
                        "parameter for testing purpose.\n", dev->quirks);
                uvc_printk(KERN_INFO, "Please report required quirks to the "
@@ -2134,11 +2128,11 @@ static int uvc_probe(struct usb_interface *intf,
        /* Initialize the media device and register the V4L2 device. */
 #ifdef CONFIG_MEDIA_CONTROLLER
        dev->mdev.dev = &intf->dev;
-       strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
+       strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
        if (udev->serial)
-               strlcpy(dev->mdev.serial, udev->serial,
+               strscpy(dev->mdev.serial, udev->serial,
                        sizeof(dev->mdev.serial));
-       strcpy(dev->mdev.bus_info, udev->devpath);
+       strscpy(dev->mdev.bus_info, udev->devpath, sizeof(dev->mdev.bus_info));
        dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
        media_device_init(&dev->mdev);
 
@@ -2344,7 +2338,9 @@ static const struct uvc_device_info uvc_quirk_force_y8 = {
        .quirks = UVC_QUIRK_FORCE_Y8,
 };
 
-#define UVC_QUIRK_INFO(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
+#define UVC_INFO_QUIRK(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
+#define UVC_INFO_META(m) (kernel_ulong_t)&(struct uvc_device_info) \
+       {.meta_format = m}
 
 /*
  * The Logitech cameras listed below have their interface class set to
@@ -2453,7 +2449,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
        /* Chicony CNF7129 (Asus EEE 100HE) */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2462,7 +2458,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_RESTRICT_FRAME_RATE) },
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_RESTRICT_FRAME_RATE) },
        /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2525,7 +2521,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
                                        | UVC_QUIRK_BUILTIN_ISIGHT) },
        /* Apple Built-In iSight via iBridge */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
@@ -2607,7 +2603,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
                                        | UVC_QUIRK_PROBE_DEF) },
        /* IMC Networks (Medion Akoya) */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
@@ -2707,7 +2703,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
                                        | UVC_QUIRK_PROBE_EXTRAFIELDS) },
        /* Aveo Technology USB 2.0 Camera (Tasco USB Microscope) */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
@@ -2725,7 +2721,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_EXTRAFIELDS) },
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_EXTRAFIELDS) },
        /* Manta MM-353 Plako */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2771,7 +2767,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_STATUS_INTERVAL) },
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_STATUS_INTERVAL) },
        /* MSI StarCam 370i */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2798,7 +2794,7 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
-         .driver_info          = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+         .driver_info          = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
                                        | UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
        /* Oculus VR Positional Tracker DK2 */
        { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
@@ -2818,6 +2814,15 @@ static const struct usb_device_id uvc_ids[] = {
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
          .driver_info          = (kernel_ulong_t)&uvc_quirk_force_y8 },
+       /* Intel RealSense D4M */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x8086,
+         .idProduct            = 0x0b03,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_INFO_META(V4L2_META_FMT_D4XX) },
        /* Generic USB Video Class */
        { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
        { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
index 554063c07d7a2c4ebb876e2dfa42051f7b20e385..06bffdf8828b5075ccec275b2274ee219a689303 100644 (file)
@@ -79,7 +79,7 @@ static int uvc_mc_init_entity(struct uvc_video_chain *chain,
 
        if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) {
                v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops);
-               strlcpy(entity->subdev.name, entity->name,
+               strscpy(entity->subdev.name, entity->name,
                        sizeof(entity->subdev.name));
 
                ret = media_entity_pads_init(&entity->subdev.entity,
index cd1aec19cc5b583fabd9770f735e9bd3f8804686..5f535b515c23a7bedddc4bebc12ed9021e8a3d2c 100644 (file)
@@ -33,8 +33,8 @@ static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
        struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
        struct uvc_video_chain *chain = stream->chain;
 
-       strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver));
-       strlcpy(cap->card, vfh->vdev->name, sizeof(cap->card));
+       strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
+       strscpy(cap->card, vfh->vdev->name, sizeof(cap->card));
        usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
                          | chain->caps;
@@ -74,7 +74,8 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
 
        memset(fmt, 0, sizeof(*fmt));
 
-       fmt->dataformat = fmeta == dev->meta_format ? fmeta : V4L2_META_FMT_UVC;
+       fmt->dataformat = fmeta == dev->info->meta_format
+                       ? fmeta : V4L2_META_FMT_UVC;
        fmt->buffersize = UVC_METATADA_BUF_SIZE;
 
        return 0;
@@ -118,14 +119,14 @@ static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh,
        u32 index = fdesc->index;
 
        if (fdesc->type != vfh->vdev->queue->type ||
-           index > 1U || (index && !dev->meta_format))
+           index > 1U || (index && !dev->info->meta_format))
                return -EINVAL;
 
        memset(fdesc, 0, sizeof(*fdesc));
 
        fdesc->type = vfh->vdev->queue->type;
        fdesc->index = index;
-       fdesc->pixelformat = index ? dev->meta_format : V4L2_META_FMT_UVC;
+       fdesc->pixelformat = index ? dev->info->meta_format : V4L2_META_FMT_UVC;
 
        return 0;
 }
index fecccb5e76282139d07f227cd2239d71a44e1a6c..8964e16f2b22d4ae3388dfaabfdec378c29ad65e 100644 (file)
@@ -300,12 +300,13 @@ int uvc_create_buffers(struct uvc_video_queue *queue,
        return ret;
 }
 
-int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
+int uvc_queue_buffer(struct uvc_video_queue *queue,
+                    struct media_device *mdev, struct v4l2_buffer *buf)
 {
        int ret;
 
        mutex_lock(&queue->mutex);
-       ret = vb2_qbuf(&queue->queue, buf);
+       ret = vb2_qbuf(&queue->queue, mdev, buf);
        mutex_unlock(&queue->mutex);
 
        return ret;
index 18a7384b50ee9706674ba6db4f4fb0b732b31981..84be596d326996795ca0e4589e3f51ed4e71d8be 100644 (file)
@@ -591,8 +591,8 @@ static int uvc_ioctl_querycap(struct file *file, void *fh,
        struct uvc_video_chain *chain = handle->chain;
        struct uvc_streaming *stream = handle->stream;
 
-       strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver));
-       strlcpy(cap->card, vdev->name, sizeof(cap->card));
+       strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
+       strscpy(cap->card, vdev->name, sizeof(cap->card));
        usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
        cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
                          | chain->caps;
@@ -618,7 +618,7 @@ static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream,
        fmt->flags = 0;
        if (format->flags & UVC_FMT_FLAG_COMPRESSED)
                fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
-       strlcpy(fmt->description, format->name, sizeof(fmt->description));
+       strscpy(fmt->description, format->name, sizeof(fmt->description));
        fmt->description[sizeof(fmt->description) - 1] = 0;
        fmt->pixelformat = format->fcc;
        return 0;
@@ -751,7 +751,8 @@ static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
        if (!uvc_has_privileges(handle))
                return -EBUSY;
 
-       return uvc_queue_buffer(&stream->queue, buf);
+       return uvc_queue_buffer(&stream->queue,
+                               stream->vdev.v4l2_dev->mdev, buf);
 }
 
 static int uvc_ioctl_expbuf(struct file *file, void *fh,
@@ -859,7 +860,7 @@ static int uvc_ioctl_enum_input(struct file *file, void *fh,
 
        memset(input, 0, sizeof(*input));
        input->index = index;
-       strlcpy(input->name, iterm->name, sizeof(input->name));
+       strscpy(input->name, iterm->name, sizeof(input->name));
        if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
                input->type = V4L2_INPUT_TYPE_CAMERA;
 
@@ -939,7 +940,7 @@ static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
 
        qec->id = qc.id;
        qec->type = qc.type;
-       strlcpy(qec->name, qc.name, sizeof(qec->name));
+       strscpy(qec->name, qc.name, sizeof(qec->name));
        qec->minimum = qc.minimum;
        qec->maximum = qc.maximum;
        qec->step = qc.step;
index e5f5d84f1d1d5821e8ce5a8b1d30e69d9d730735..c0cbd833d0a4c460954255ba9afd2ba8b285ba62 100644 (file)
@@ -234,7 +234,7 @@ struct uvc_control_mapping {
        enum v4l2_ctrl_type v4l2_type;
        u32 data_type;
 
-       struct uvc_menu_info *menu_info;
+       const struct uvc_menu_info *menu_info;
        u32 menu_count;
 
        u32 master_id;
@@ -572,15 +572,21 @@ struct uvc_streaming {
        } clock;
 };
 
+struct uvc_device_info {
+       u32     quirks;
+       u32     meta_format;
+};
+
 struct uvc_device {
        struct usb_device *udev;
        struct usb_interface *intf;
        unsigned long warnings;
        u32 quirks;
-       u32 meta_format;
        int intfnum;
        char name[32];
 
+       const struct uvc_device_info *info;
+
        struct mutex lock;              /* Protects users */
        unsigned int users;
        atomic_t nmappings;
@@ -694,6 +700,7 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
 int uvc_create_buffers(struct uvc_video_queue *queue,
                       struct v4l2_create_buffers *v4l2_cb);
 int uvc_queue_buffer(struct uvc_video_queue *queue,
+                    struct media_device *mdev,
                     struct v4l2_buffer *v4l2_buf);
 int uvc_export_buffer(struct uvc_video_queue *queue,
                      struct v4l2_exportbuffer *exp);
index b8886102c5ed6325b6ef36eddc34bca80e1a5859..ab35554cbffab3cc63d9a5ad74be721fb510944c 100644 (file)
@@ -702,9 +702,9 @@ static int zr364xx_vidioc_querycap(struct file *file, void *priv,
 {
        struct zr364xx_camera *cam = video_drvdata(file);
 
-       strlcpy(cap->driver, DRIVER_DESC, sizeof(cap->driver));
-       strlcpy(cap->card, cam->udev->product, sizeof(cap->card));
-       strlcpy(cap->bus_info, dev_name(&cam->udev->dev),
+       strscpy(cap->driver, DRIVER_DESC, sizeof(cap->driver));
+       strscpy(cap->card, cam->udev->product, sizeof(cap->card));
+       strscpy(cap->bus_info, dev_name(&cam->udev->dev),
                sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
                            V4L2_CAP_READWRITE |
@@ -719,7 +719,7 @@ static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
 {
        if (i->index != 0)
                return -EINVAL;
-       strcpy(i->name, DRIVER_DESC " Camera");
+       strscpy(i->name, DRIVER_DESC " Camera", sizeof(i->name));
        i->type = V4L2_INPUT_TYPE_CAMERA;
        return 0;
 }
@@ -765,7 +765,7 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
        if (f->index > 0)
                return -EINVAL;
        f->flags = V4L2_FMT_FLAG_COMPRESSED;
-       strcpy(f->description, formats[0].name);
+       strscpy(f->description, formats[0].name, sizeof(f->description));
        f->pixelformat = formats[0].fourcc;
        return 0;
 }
index 7f858c39753c1f1aaacbe0cd70cdcb07b1cd6f21..03a340cb5a9be93a462bf5631e900ffa7961ad31 100644 (file)
@@ -94,9 +94,56 @@ static const struct v4l2_subdev_ops tuner_ops;
 } while (0)
 
 /*
- * Internal struct used inside the driver
+ * Internal enums/struct used inside the driver
  */
 
+/**
+ * enum tuner_pad_index - tuner pad index for MEDIA_ENT_F_TUNER
+ *
+ * @TUNER_PAD_RF_INPUT:
+ *     Radiofrequency (RF) sink pad, usually linked to a RF connector entity.
+ * @TUNER_PAD_OUTPUT:
+ *     tuner video output source pad. Contains the video chrominance
+ *     and luminance or the hole bandwidth of the signal converted to
+ *     an Intermediate Frequency (IF) or to baseband (on zero-IF tuners).
+ * @TUNER_PAD_AUD_OUT:
+ *     Tuner audio output source pad. Tuners used to decode analog TV
+ *     signals have an extra pad for audio output. Old tuners use an
+ *     analog stage with a saw filter for the audio IF frequency. The
+ *     output of the pad is, in this case, the audio IF, with should be
+ *     decoded either by the bridge chipset (that's the case of cx2388x
+ *     chipsets) or may require an external IF sound processor, like
+ *     msp34xx. On modern silicon tuners, the audio IF decoder is usually
+ *     incorporated at the tuner. On such case, the output of this pad
+ *     is an audio sampled data.
+ * @TUNER_NUM_PADS:
+ *     Number of pads of the tuner.
+ */
+enum tuner_pad_index {
+       TUNER_PAD_RF_INPUT,
+       TUNER_PAD_OUTPUT,
+       TUNER_PAD_AUD_OUT,
+       TUNER_NUM_PADS
+};
+
+/**
+ * enum if_vid_dec_pad_index - video IF-PLL pad index
+ *     for MEDIA_ENT_F_IF_VID_DECODER
+ *
+ * @IF_VID_DEC_PAD_IF_INPUT:
+ *     video Intermediate Frequency (IF) sink pad
+ * @IF_VID_DEC_PAD_OUT:
+ *     IF-PLL video output source pad. Contains the video chrominance
+ *     and luminance IF signals.
+ * @IF_VID_DEC_PAD_NUM_PADS:
+ *     Number of pads of the video IF-PLL.
+ */
+enum if_vid_dec_pad_index {
+       IF_VID_DEC_PAD_IF_INPUT,
+       IF_VID_DEC_PAD_OUT,
+       IF_VID_DEC_PAD_NUM_PADS
+};
+
 struct tuner {
        /* device */
        struct dvb_frontend fe;
@@ -685,15 +732,20 @@ register_client:
         */
        if (t->type == TUNER_TDA9887) {
                t->pad[IF_VID_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+               t->pad[IF_VID_DEC_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
                t->pad[IF_VID_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               t->pad[IF_VID_DEC_PAD_OUT].sig_type = PAD_SIGNAL_ANALOG;
                ret = media_entity_pads_init(&t->sd.entity,
                                             IF_VID_DEC_PAD_NUM_PADS,
                                             &t->pad[0]);
                t->sd.entity.function = MEDIA_ENT_F_IF_VID_DECODER;
        } else {
                t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
+               t->pad[TUNER_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
                t->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
+               t->pad[TUNER_PAD_OUTPUT].sig_type = PAD_SIGNAL_ANALOG;
                t->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               t->pad[TUNER_PAD_AUD_OUT].sig_type = PAD_SIGNAL_AUDIO;
                ret = media_entity_pads_init(&t->sd.entity, TUNER_NUM_PADS,
                                             &t->pad[0]);
                t->sd.entity.function = MEDIA_ENT_F_TUNER;
index 2b08d03b251d6053aa9db3ccae0c5b8c2cbbdf90..a6d91370838d934295d812051e8d7c55f35adc2d 100644 (file)
@@ -57,6 +57,7 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
 #if IS_ENABLED(CONFIG_I2C)
        struct i2c_client *client = i2c_verify_client(sd->dev);
+
        return client &&
                asd->match.i2c.adapter_id == client->adapter->nr &&
                asd->match.i2c.address == client->addr;
@@ -89,10 +90,11 @@ static LIST_HEAD(subdev_list);
 static LIST_HEAD(notifier_list);
 static DEFINE_MUTEX(list_lock);
 
-static struct v4l2_async_subdev *v4l2_async_find_match(
-       struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd)
+static struct v4l2_async_subdev *
+v4l2_async_find_match(struct v4l2_async_notifier *notifier,
+                     struct v4l2_subdev *sd)
 {
-       bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *);
+       bool (*match)(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd);
        struct v4l2_async_subdev *asd;
 
        list_for_each_entry(asd, &notifier->waiting, list) {
@@ -124,9 +126,34 @@ static struct v4l2_async_subdev *v4l2_async_find_match(
        return NULL;
 }
 
+/* Compare two async sub-device descriptors for equivalence */
+static bool asd_equal(struct v4l2_async_subdev *asd_x,
+                     struct v4l2_async_subdev *asd_y)
+{
+       if (asd_x->match_type != asd_y->match_type)
+               return false;
+
+       switch (asd_x->match_type) {
+       case V4L2_ASYNC_MATCH_DEVNAME:
+               return strcmp(asd_x->match.device_name,
+                             asd_y->match.device_name) == 0;
+       case V4L2_ASYNC_MATCH_I2C:
+               return asd_x->match.i2c.adapter_id ==
+                       asd_y->match.i2c.adapter_id &&
+                       asd_x->match.i2c.address ==
+                       asd_y->match.i2c.address;
+       case V4L2_ASYNC_MATCH_FWNODE:
+               return asd_x->match.fwnode == asd_y->match.fwnode;
+       default:
+               break;
+       }
+
+       return false;
+}
+
 /* Find the sub-device notifier registered by a sub-device driver. */
-static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
-       struct v4l2_subdev *sd)
+static struct v4l2_async_notifier *
+v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd)
 {
        struct v4l2_async_notifier *n;
 
@@ -138,8 +165,8 @@ static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
 }
 
 /* Get v4l2_device related to the notifier if one can be found. */
-static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
-       struct v4l2_async_notifier *notifier)
+static struct v4l2_device *
+v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier)
 {
        while (notifier->parent)
                notifier = notifier->parent;
@@ -150,8 +177,8 @@ static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
 /*
  * Return true if all child sub-device notifiers are complete, false otherwise.
  */
-static bool v4l2_async_notifier_can_complete(
-       struct v4l2_async_notifier *notifier)
+static bool
+v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
 {
        struct v4l2_subdev *sd;
 
@@ -174,8 +201,8 @@ static bool v4l2_async_notifier_can_complete(
  * Complete the master notifier if possible. This is done when all async
  * sub-devices have been bound; v4l2_device is also available then.
  */
-static int v4l2_async_notifier_try_complete(
-       struct v4l2_async_notifier *notifier)
+static int
+v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier)
 {
        /* Quick check whether there are still more sub-devices here. */
        if (!list_empty(&notifier->waiting))
@@ -196,8 +223,8 @@ static int v4l2_async_notifier_try_complete(
        return v4l2_async_notifier_call_complete(notifier);
 }
 
-static int v4l2_async_notifier_try_all_subdevs(
-       struct v4l2_async_notifier *notifier);
+static int
+v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier);
 
 static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
                                   struct v4l2_device *v4l2_dev,
@@ -243,8 +270,8 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
 }
 
 /* Test all async sub-devices in a notifier for a match. */
-static int v4l2_async_notifier_try_all_subdevs(
-       struct v4l2_async_notifier *notifier)
+static int
+v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier)
 {
        struct v4l2_device *v4l2_dev =
                v4l2_async_notifier_find_v4l2_dev(notifier);
@@ -281,14 +308,17 @@ again:
 static void v4l2_async_cleanup(struct v4l2_subdev *sd)
 {
        v4l2_device_unregister_subdev(sd);
-       /* Subdevice driver will reprobe and put the subdev back onto the list */
+       /*
+        * Subdevice driver will reprobe and put the subdev back
+        * onto the list
+        */
        list_del_init(&sd->async_list);
        sd->asd = NULL;
 }
 
 /* Unbind all sub-devices in the notifier tree. */
-static void v4l2_async_notifier_unbind_all_subdevs(
-       struct v4l2_async_notifier *notifier)
+static void
+v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
 {
        struct v4l2_subdev *sd, *tmp;
 
@@ -308,29 +338,23 @@ static void v4l2_async_notifier_unbind_all_subdevs(
        notifier->parent = NULL;
 }
 
-/* See if an fwnode can be found in a notifier's lists. */
-static bool __v4l2_async_notifier_fwnode_has_async_subdev(
-       struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode)
+/* See if an async sub-device can be found in a notifier's lists. */
+static bool
+__v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+                                      struct v4l2_async_subdev *asd)
 {
-       struct v4l2_async_subdev *asd;
+       struct v4l2_async_subdev *asd_y;
        struct v4l2_subdev *sd;
 
-       list_for_each_entry(asd, &notifier->waiting, list) {
-               if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
-                       continue;
-
-               if (asd->match.fwnode == fwnode)
+       list_for_each_entry(asd_y, &notifier->waiting, list)
+               if (asd_equal(asd, asd_y))
                        return true;
-       }
 
        list_for_each_entry(sd, &notifier->done, async_list) {
                if (WARN_ON(!sd->asd))
                        continue;
 
-               if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
-                       continue;
-
-               if (sd->asd->match.fwnode == fwnode)
+               if (asd_equal(asd, sd->asd))
                        return true;
        }
 
@@ -338,76 +362,91 @@ static bool __v4l2_async_notifier_fwnode_has_async_subdev(
 }
 
 /*
- * Find out whether an async sub-device was set up for an fwnode already or
+ * Find out whether an async sub-device was set up already or
  * whether it exists in a given notifier before @this_index.
+ * If @this_index < 0, search the notifier's entire @asd_list.
  */
-static bool v4l2_async_notifier_fwnode_has_async_subdev(
-       struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode,
-       unsigned int this_index)
+static bool
+v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+                                    struct v4l2_async_subdev *asd,
+                                    int this_index)
 {
-       unsigned int j;
+       struct v4l2_async_subdev *asd_y;
+       int j = 0;
 
        lockdep_assert_held(&list_lock);
 
-       /* Check that an fwnode is not being added more than once. */
-       for (j = 0; j < this_index; j++) {
-               struct v4l2_async_subdev *asd = notifier->subdevs[this_index];
-               struct v4l2_async_subdev *other_asd = notifier->subdevs[j];
-
-               if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&
-                   asd->match.fwnode ==
-                   other_asd->match.fwnode)
+       /* Check that an asd is not being added more than once. */
+       list_for_each_entry(asd_y, &notifier->asd_list, asd_list) {
+               if (this_index >= 0 && j++ >= this_index)
+                       break;
+               if (asd_equal(asd, asd_y))
                        return true;
        }
 
-       /* Check than an fwnode did not exist in other notifiers. */
+       /* Check that an asd does not exist in other notifiers. */
        list_for_each_entry(notifier, &notifier_list, list)
-               if (__v4l2_async_notifier_fwnode_has_async_subdev(
-                           notifier, fwnode))
+               if (__v4l2_async_notifier_has_async_subdev(notifier, asd))
                        return true;
 
        return false;
 }
 
-static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
+                                        struct v4l2_async_subdev *asd,
+                                        int this_index)
 {
        struct device *dev =
                notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
-       struct v4l2_async_subdev *asd;
-       int ret;
-       int i;
 
-       if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+       if (!asd)
+               return -EINVAL;
+
+       switch (asd->match_type) {
+       case V4L2_ASYNC_MATCH_CUSTOM:
+       case V4L2_ASYNC_MATCH_DEVNAME:
+       case V4L2_ASYNC_MATCH_I2C:
+       case V4L2_ASYNC_MATCH_FWNODE:
+               if (v4l2_async_notifier_has_async_subdev(notifier, asd,
+                                                        this_index)) {
+                       dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n");
+                       return -EEXIST;
+               }
+               break;
+       default:
+               dev_err(dev, "Invalid match type %u on %p\n",
+                       asd->match_type, asd);
                return -EINVAL;
+       }
+
+       return 0;
+}
+
+void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier)
+{
+       mutex_lock(&list_lock);
+
+       INIT_LIST_HEAD(&notifier->asd_list);
+
+       mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_notifier_init);
+
+static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+{
+       struct v4l2_async_subdev *asd;
+       int ret, i = 0;
 
        INIT_LIST_HEAD(&notifier->waiting);
        INIT_LIST_HEAD(&notifier->done);
 
        mutex_lock(&list_lock);
 
-       for (i = 0; i < notifier->num_subdevs; i++) {
-               asd = notifier->subdevs[i];
-
-               switch (asd->match_type) {
-               case V4L2_ASYNC_MATCH_CUSTOM:
-               case V4L2_ASYNC_MATCH_DEVNAME:
-               case V4L2_ASYNC_MATCH_I2C:
-                       break;
-               case V4L2_ASYNC_MATCH_FWNODE:
-                       if (v4l2_async_notifier_fwnode_has_async_subdev(
-                                   notifier, asd->match.fwnode, i)) {
-                               dev_err(dev,
-                                       "fwnode has already been registered or in notifier's subdev list\n");
-                               ret = -EEXIST;
-                               goto err_unlock;
-                       }
-                       break;
-               default:
-                       dev_err(dev, "Invalid match type %u on %p\n",
-                               asd->match_type, asd);
-                       ret = -EINVAL;
+       list_for_each_entry(asd, &notifier->asd_list, asd_list) {
+               ret = v4l2_async_notifier_asd_valid(notifier, asd, i++);
+               if (ret)
                        goto err_unlock;
-               }
+
                list_add_tail(&asd->list, &notifier->waiting);
        }
 
@@ -474,8 +513,8 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
 }
 EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
 
-static void __v4l2_async_notifier_unregister(
-       struct v4l2_async_notifier *notifier)
+static void
+__v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 {
        if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
                return;
@@ -498,36 +537,132 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 }
 EXPORT_SYMBOL(v4l2_async_notifier_unregister);
 
-void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
+static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
 {
-       unsigned int i;
+       struct v4l2_async_subdev *asd, *tmp;
 
-       if (!notifier || !notifier->max_subdevs)
+       if (!notifier)
                return;
 
-       for (i = 0; i < notifier->num_subdevs; i++) {
-               struct v4l2_async_subdev *asd = notifier->subdevs[i];
-
+       list_for_each_entry_safe(asd, tmp, &notifier->asd_list, asd_list) {
                switch (asd->match_type) {
                case V4L2_ASYNC_MATCH_FWNODE:
                        fwnode_handle_put(asd->match.fwnode);
                        break;
                default:
-                       WARN_ON_ONCE(true);
                        break;
                }
 
+               list_del(&asd->asd_list);
                kfree(asd);
        }
+}
 
-       notifier->max_subdevs = 0;
-       notifier->num_subdevs = 0;
+void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
+{
+       mutex_lock(&list_lock);
+
+       __v4l2_async_notifier_cleanup(notifier);
 
-       kvfree(notifier->subdevs);
-       notifier->subdevs = NULL;
+       mutex_unlock(&list_lock);
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
 
+int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+                                  struct v4l2_async_subdev *asd)
+{
+       int ret;
+
+       mutex_lock(&list_lock);
+
+       ret = v4l2_async_notifier_asd_valid(notifier, asd, -1);
+       if (ret)
+               goto unlock;
+
+       list_add_tail(&asd->asd_list, &notifier->asd_list);
+
+unlock:
+       mutex_unlock(&list_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_subdev);
+
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+                                     struct fwnode_handle *fwnode,
+                                     unsigned int asd_struct_size)
+{
+       struct v4l2_async_subdev *asd;
+       int ret;
+
+       asd = kzalloc(asd_struct_size, GFP_KERNEL);
+       if (!asd)
+               return ERR_PTR(-ENOMEM);
+
+       asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+       asd->match.fwnode = fwnode;
+
+       ret = v4l2_async_notifier_add_subdev(notifier, asd);
+       if (ret) {
+               kfree(asd);
+               return ERR_PTR(ret);
+       }
+
+       return asd;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev);
+
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+                                  int adapter_id, unsigned short address,
+                                  unsigned int asd_struct_size)
+{
+       struct v4l2_async_subdev *asd;
+       int ret;
+
+       asd = kzalloc(asd_struct_size, GFP_KERNEL);
+       if (!asd)
+               return ERR_PTR(-ENOMEM);
+
+       asd->match_type = V4L2_ASYNC_MATCH_I2C;
+       asd->match.i2c.adapter_id = adapter_id;
+       asd->match.i2c.address = address;
+
+       ret = v4l2_async_notifier_add_subdev(notifier, asd);
+       if (ret) {
+               kfree(asd);
+               return ERR_PTR(ret);
+       }
+
+       return asd;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_i2c_subdev);
+
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier,
+                                      const char *device_name,
+                                      unsigned int asd_struct_size)
+{
+       struct v4l2_async_subdev *asd;
+       int ret;
+
+       asd = kzalloc(asd_struct_size, GFP_KERNEL);
+       if (!asd)
+               return ERR_PTR(-ENOMEM);
+
+       asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
+       asd->match.device_name = device_name;
+
+       ret = v4l2_async_notifier_add_subdev(notifier, asd);
+       if (ret) {
+               kfree(asd);
+               return ERR_PTR(ret);
+       }
+
+       return asd;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_devname_subdev);
+
 int v4l2_async_register_subdev(struct v4l2_subdev *sd)
 {
        struct v4l2_async_notifier *subdev_notifier;
@@ -601,7 +736,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
        mutex_lock(&list_lock);
 
        __v4l2_async_notifier_unregister(sd->subdev_notifier);
-       v4l2_async_notifier_cleanup(sd->subdev_notifier);
+       __v4l2_async_notifier_cleanup(sd->subdev_notifier);
        kfree(sd->subdev_notifier);
        sd->subdev_notifier = NULL;
 
index b518b92d6d96e5cc3bd3047bded18d54a52f979b..50763fb42a1b8c0b31a7170c816d1c220e96073c 100644 (file)
@@ -100,7 +100,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _
        qctrl->step = step;
        qctrl->default_value = def;
        qctrl->reserved[0] = qctrl->reserved[1] = 0;
-       strlcpy(qctrl->name, name, sizeof(qctrl->name));
+       strscpy(qctrl->name, name, sizeof(qctrl->name));
        return 0;
 }
 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
@@ -109,6 +109,19 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 
 #if IS_ENABLED(CONFIG_I2C)
 
+void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
+                             const char *devname, const char *postfix)
+{
+       if (!devname)
+               devname = client->dev.driver->name;
+       if (!postfix)
+               postfix = "";
+
+       snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
+                i2c_adapter_id(client->adapter), client->addr);
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);
+
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
                const struct v4l2_subdev_ops *ops)
 {
@@ -120,10 +133,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
        /* i2c_client and v4l2_subdev point to one another */
        v4l2_set_subdevdata(sd, client);
        i2c_set_clientdata(client, sd);
-       /* initialize name */
-       snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
-               client->dev.driver->name, i2c_adapter_id(client->adapter),
-               client->addr);
+       v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
@@ -186,7 +196,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
        /* Setup the i2c board info with the device type and
           the device address. */
        memset(&info, 0, sizeof(info));
-       strlcpy(info.type, client_type, sizeof(info.type));
+       strscpy(info.type, client_type, sizeof(info.type));
        info.addr = addr;
 
        return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
@@ -255,7 +265,8 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
        v4l2_set_subdevdata(sd, spi);
        spi_set_drvdata(spi, sd);
        /* initialize name */
-       strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name));
+       snprintf(sd->name, sizeof(sd->name), "%s %s",
+               spi->dev.driver->name, dev_name(&spi->dev));
 }
 EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
 
index 6481212fda772c734e0c2222dde8611932cbdaf1..f4325329fbd6f32f558ef1b798da75a2a208199d 100644 (file)
@@ -244,6 +244,7 @@ struct v4l2_format32 {
  *             return: number of created buffers
  * @memory:    buffer memory type
  * @format:    frame format, for which buffers are requested
+ * @capabilities: capabilities of this buffer type.
  * @reserved:  future extensions
  */
 struct v4l2_create_buffers32 {
@@ -251,7 +252,8 @@ struct v4l2_create_buffers32 {
        __u32                   count;
        __u32                   memory; /* enum v4l2_memory */
        struct v4l2_format32    format;
-       __u32                   reserved[8];
+       __u32                   capabilities;
+       __u32                   reserved[7];
 };
 
 static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
@@ -411,6 +413,7 @@ static int put_v4l2_create32(struct v4l2_create_buffers __user *p64,
        if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
            copy_in_user(p32, p64,
                         offsetof(struct v4l2_create_buffers32, format)) ||
+           assign_in_user(&p32->capabilities, &p64->capabilities) ||
            copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
                return -EFAULT;
        return __put_v4l2_format32(&p64->format, &p32->format);
@@ -482,7 +485,7 @@ struct v4l2_buffer32 {
        } m;
        __u32                   length;
        __u32                   reserved2;
-       __u32                   reserved;
+       __s32                   request_fd;
 };
 
 static int get_v4l2_plane32(struct v4l2_plane __user *p64,
@@ -581,6 +584,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer __user *p64,
 {
        u32 type;
        u32 length;
+       s32 request_fd;
        enum v4l2_memory memory;
        struct v4l2_plane32 __user *uplane32;
        struct v4l2_plane __user *uplane;
@@ -595,7 +599,9 @@ static int get_v4l2_buffer32(struct v4l2_buffer __user *p64,
            get_user(memory, &p32->memory) ||
            put_user(memory, &p64->memory) ||
            get_user(length, &p32->length) ||
-           put_user(length, &p64->length))
+           put_user(length, &p64->length) ||
+           get_user(request_fd, &p32->request_fd) ||
+           put_user(request_fd, &p64->request_fd))
                return -EFAULT;
 
        if (V4L2_TYPE_IS_OUTPUT(type))
@@ -699,7 +705,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer __user *p64,
            copy_in_user(&p32->timecode, &p64->timecode, sizeof(p64->timecode)) ||
            assign_in_user(&p32->sequence, &p64->sequence) ||
            assign_in_user(&p32->reserved2, &p64->reserved2) ||
-           assign_in_user(&p32->reserved, &p64->reserved) ||
+           assign_in_user(&p32->request_fd, &p64->request_fd) ||
            get_user(length, &p64->length) ||
            put_user(length, &p32->length))
                return -EFAULT;
@@ -834,7 +840,8 @@ struct v4l2_ext_controls32 {
        __u32 which;
        __u32 count;
        __u32 error_idx;
-       __u32 reserved[2];
+       __s32 request_fd;
+       __u32 reserved[1];
        compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
 };
 
@@ -909,6 +916,7 @@ static int get_v4l2_ext_controls32(struct file *file,
            get_user(count, &p32->count) ||
            put_user(count, &p64->count) ||
            assign_in_user(&p64->error_idx, &p32->error_idx) ||
+           assign_in_user(&p64->request_fd, &p32->request_fd) ||
            copy_in_user(p64->reserved, p32->reserved, sizeof(p64->reserved)))
                return -EFAULT;
 
@@ -974,6 +982,7 @@ static int put_v4l2_ext_controls32(struct file *file,
            get_user(count, &p64->count) ||
            put_user(count, &p32->count) ||
            assign_in_user(&p32->error_idx, &p64->error_idx) ||
+           assign_in_user(&p32->request_fd, &p64->request_fd) ||
            copy_in_user(p32->reserved, p64->reserved, sizeof(p32->reserved)) ||
            get_user(kcontrols, &p64->controls))
                return -EFAULT;
index 599c1cbff3b9e9e4cc584b3a4b395d11094ec995..6e37950292cd9b832d589e1728fba7d28d469794 100644 (file)
@@ -37,8 +37,8 @@
 struct v4l2_ctrl_helper {
        /* Pointer to the control reference of the master control */
        struct v4l2_ctrl_ref *mref;
-       /* The control corresponding to the v4l2_ext_control ID field. */
-       struct v4l2_ctrl *ctrl;
+       /* The control ref corresponding to the v4l2_ext_control ID field. */
+       struct v4l2_ctrl_ref *ref;
        /* v4l2_ext_control index of the next control belonging to the
           same cluster, or 0 if there isn't any. */
        u32 next;
@@ -844,6 +844,8 @@ const char *v4l2_ctrl_get_name(u32 id)
        case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:             return "Vertical MV Search Range";
        case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:             return "Repeat Sequence Header";
        case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:               return "Force Key Frame";
+       case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:            return "MPEG-2 Slice Parameters";
+       case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION:            return "MPEG-2 Quantization Matrices";
 
        /* VPX controls */
        case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:            return "VPX Number of Partitions";
@@ -1292,6 +1294,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
        case V4L2_CID_RDS_TX_ALT_FREQS:
                *type = V4L2_CTRL_TYPE_U32;
                break;
+       case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS:
+               *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS;
+               break;
+       case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION:
+               *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION;
+               break;
        default:
                *type = V4L2_CTRL_TYPE_INTEGER;
                break;
@@ -1550,6 +1558,7 @@ static void std_log(const struct v4l2_ctrl *ctrl)
 static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
                        union v4l2_ctrl_ptr ptr)
 {
+       struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
        size_t len;
        u64 offset;
        s64 val;
@@ -1612,6 +1621,54 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
                        return -ERANGE;
                return 0;
 
+       case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
+               p_mpeg2_slice_params = ptr.p;
+
+               switch (p_mpeg2_slice_params->sequence.chroma_format) {
+               case 1: /* 4:2:0 */
+               case 2: /* 4:2:2 */
+               case 3: /* 4:4:4 */
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
+               case 0: /* 8 bits */
+               case 1: /* 9 bits */
+               case 11: /* 11 bits */
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               switch (p_mpeg2_slice_params->picture.picture_structure) {
+               case 1: /* interlaced top field */
+               case 2: /* interlaced bottom field */
+               case 3: /* progressive */
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               switch (p_mpeg2_slice_params->picture.picture_coding_type) {
+               case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
+               case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
+               case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               if (p_mpeg2_slice_params->backward_ref_index >= VIDEO_MAX_FRAME ||
+                   p_mpeg2_slice_params->forward_ref_index >= VIDEO_MAX_FRAME)
+                       return -EINVAL;
+
+               return 0;
+
+       case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
+               return 0;
+
        default:
                return -EINVAL;
        }
@@ -1668,6 +1725,13 @@ static int new_to_user(struct v4l2_ext_control *c,
        return ptr_to_user(c, ctrl, ctrl->p_new);
 }
 
+/* Helper function: copy the request value back to the caller */
+static int req_to_user(struct v4l2_ext_control *c,
+                      struct v4l2_ctrl_ref *ref)
+{
+       return ptr_to_user(c, ref->ctrl, ref->p_req);
+}
+
 /* Helper function: copy the initial control value back to the caller */
 static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
 {
@@ -1787,6 +1851,26 @@ static void cur_to_new(struct v4l2_ctrl *ctrl)
        ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
 }
 
+/* Copy the new value to the request value */
+static void new_to_req(struct v4l2_ctrl_ref *ref)
+{
+       if (!ref)
+               return;
+       ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req);
+       ref->req = ref;
+}
+
+/* Copy the request value to the new value */
+static void req_to_new(struct v4l2_ctrl_ref *ref)
+{
+       if (!ref)
+               return;
+       if (ref->req)
+               ptr_to_ptr(ref->ctrl, ref->req->p_req, ref->ctrl->p_new);
+       else
+               ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new);
+}
+
 /* Return non-zero if one or more of the controls in the cluster has a new
    value that differs from the current value. */
 static int cluster_changed(struct v4l2_ctrl *master)
@@ -1896,11 +1980,15 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
        lockdep_set_class_and_name(hdl->lock, key, name);
        INIT_LIST_HEAD(&hdl->ctrls);
        INIT_LIST_HEAD(&hdl->ctrl_refs);
+       INIT_LIST_HEAD(&hdl->requests);
+       INIT_LIST_HEAD(&hdl->requests_queued);
+       hdl->request_is_queued = false;
        hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
        hdl->buckets = kvmalloc_array(hdl->nr_of_buckets,
                                      sizeof(hdl->buckets[0]),
                                      GFP_KERNEL | __GFP_ZERO);
        hdl->error = hdl->buckets ? 0 : -ENOMEM;
+       media_request_object_init(&hdl->req_obj);
        return hdl->error;
 }
 EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
@@ -1915,6 +2003,14 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
        if (hdl == NULL || hdl->buckets == NULL)
                return;
 
+       if (!hdl->req_obj.req && !list_empty(&hdl->requests)) {
+               struct v4l2_ctrl_handler *req, *next_req;
+
+               list_for_each_entry_safe(req, next_req, &hdl->requests, requests) {
+                       media_request_object_unbind(&req->req_obj);
+                       media_request_object_put(&req->req_obj);
+               }
+       }
        mutex_lock(hdl->lock);
        /* Free all nodes */
        list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
@@ -2016,13 +2112,19 @@ EXPORT_SYMBOL(v4l2_ctrl_find);
 
 /* Allocate a new v4l2_ctrl_ref and hook it into the handler. */
 static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
-                          struct v4l2_ctrl *ctrl)
+                          struct v4l2_ctrl *ctrl,
+                          struct v4l2_ctrl_ref **ctrl_ref,
+                          bool from_other_dev, bool allocate_req)
 {
        struct v4l2_ctrl_ref *ref;
        struct v4l2_ctrl_ref *new_ref;
        u32 id = ctrl->id;
        u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1;
        int bucket = id % hdl->nr_of_buckets;   /* which bucket to use */
+       unsigned int size_extra_req = 0;
+
+       if (ctrl_ref)
+               *ctrl_ref = NULL;
 
        /*
         * Automatically add the control class if it is not yet present and
@@ -2036,10 +2138,16 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
        if (hdl->error)
                return hdl->error;
 
-       new_ref = kzalloc(sizeof(*new_ref), GFP_KERNEL);
+       if (allocate_req)
+               size_extra_req = ctrl->elems * ctrl->elem_size;
+       new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL);
        if (!new_ref)
                return handler_set_err(hdl, -ENOMEM);
        new_ref->ctrl = ctrl;
+       new_ref->from_other_dev = from_other_dev;
+       if (size_extra_req)
+               new_ref->p_req.p = &new_ref[1];
+
        if (ctrl->handler == hdl) {
                /* By default each control starts in a cluster of its own.
                   new_ref->ctrl is basically a cluster array with one
@@ -2079,6 +2187,8 @@ insert_in_hash:
        /* Insert the control node in the hash */
        new_ref->next = hdl->buckets[bucket];
        hdl->buckets[bucket] = new_ref;
+       if (ctrl_ref)
+               *ctrl_ref = new_ref;
 
 unlock:
        mutex_unlock(hdl->lock);
@@ -2133,6 +2243,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
        case V4L2_CTRL_TYPE_U32:
                elem_size = sizeof(u32);
                break;
+       case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
+               elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params);
+               break;
+       case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
+               elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization);
+               break;
        default:
                if (type < V4L2_CTRL_COMPOUND_TYPES)
                        elem_size = sizeof(s32);
@@ -2220,7 +2336,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
                ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
        }
 
-       if (handler_new_ref(hdl, ctrl)) {
+       if (handler_new_ref(hdl, ctrl, NULL, false, false)) {
                kvfree(ctrl);
                return NULL;
        }
@@ -2389,7 +2505,8 @@ EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
 /* Add the controls from another handler to our own. */
 int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
                          struct v4l2_ctrl_handler *add,
-                         bool (*filter)(const struct v4l2_ctrl *ctrl))
+                         bool (*filter)(const struct v4l2_ctrl *ctrl),
+                         bool from_other_dev)
 {
        struct v4l2_ctrl_ref *ref;
        int ret = 0;
@@ -2412,7 +2529,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
                /* Filter any unwanted controls */
                if (filter && !filter(ctrl))
                        continue;
-               ret = handler_new_ref(hdl, ctrl);
+               ret = handler_new_ref(hdl, ctrl, NULL, from_other_dev, false);
                if (ret)
                        break;
        }
@@ -2511,20 +2628,15 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active)
 }
 EXPORT_SYMBOL(v4l2_ctrl_activate);
 
-/* Grab/ungrab a control.
-   Typically used when streaming starts and you want to grab controls,
-   preventing the user from changing them.
-
-   Just call this and the framework will block any attempts to change
-   these controls. */
-void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
+void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
 {
        bool old;
 
        if (ctrl == NULL)
                return;
 
-       v4l2_ctrl_lock(ctrl);
+       lockdep_assert_held(ctrl->handler->lock);
+
        if (grabbed)
                /* set V4L2_CTRL_FLAG_GRABBED */
                old = test_and_set_bit(1, &ctrl->flags);
@@ -2533,9 +2645,8 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
                old = test_and_clear_bit(1, &ctrl->flags);
        if (old != grabbed)
                send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
-       v4l2_ctrl_unlock(ctrl);
 }
-EXPORT_SYMBOL(v4l2_ctrl_grab);
+EXPORT_SYMBOL(__v4l2_ctrl_grab);
 
 /* Log the control name and value */
 static void log_ctrl(const struct v4l2_ctrl *ctrl,
@@ -2722,7 +2833,7 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr
                qc->id = id;
        else
                qc->id = ctrl->id;
-       strlcpy(qc->name, ctrl->name, sizeof(qc->name));
+       strscpy(qc->name, ctrl->name, sizeof(qc->name));
        qc->flags = user_flags(ctrl);
        qc->type = ctrl->type;
        qc->elem_size = ctrl->elem_size;
@@ -2754,7 +2865,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
        qc->id = qec.id;
        qc->type = qec.type;
        qc->flags = qec.flags;
-       strlcpy(qc->name, qec.name, sizeof(qc->name));
+       strscpy(qc->name, qec.name, sizeof(qc->name));
        switch (qc->type) {
        case V4L2_CTRL_TYPE_INTEGER:
        case V4L2_CTRL_TYPE_BOOLEAN:
@@ -2813,7 +2924,7 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
        if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
                if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
                        return -EINVAL;
-               strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+               strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
        } else {
                qm->value = ctrl->qmenu_int[i];
        }
@@ -2821,6 +2932,148 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
 }
 EXPORT_SYMBOL(v4l2_querymenu);
 
+static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
+                                  const struct v4l2_ctrl_handler *from)
+{
+       struct v4l2_ctrl_ref *ref;
+       int err = 0;
+
+       if (WARN_ON(!hdl || hdl == from))
+               return -EINVAL;
+
+       if (hdl->error)
+               return hdl->error;
+
+       WARN_ON(hdl->lock != &hdl->_lock);
+
+       mutex_lock(from->lock);
+       list_for_each_entry(ref, &from->ctrl_refs, node) {
+               struct v4l2_ctrl *ctrl = ref->ctrl;
+               struct v4l2_ctrl_ref *new_ref;
+
+               /* Skip refs inherited from other devices */
+               if (ref->from_other_dev)
+                       continue;
+               /* And buttons */
+               if (ctrl->type == V4L2_CTRL_TYPE_BUTTON)
+                       continue;
+               err = handler_new_ref(hdl, ctrl, &new_ref, false, true);
+               if (err)
+                       break;
+       }
+       mutex_unlock(from->lock);
+       return err;
+}
+
+static void v4l2_ctrl_request_queue(struct media_request_object *obj)
+{
+       struct v4l2_ctrl_handler *hdl =
+               container_of(obj, struct v4l2_ctrl_handler, req_obj);
+       struct v4l2_ctrl_handler *main_hdl = obj->priv;
+       struct v4l2_ctrl_handler *prev_hdl = NULL;
+       struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL;
+
+       if (list_empty(&main_hdl->requests_queued))
+               goto queue;
+
+       prev_hdl = list_last_entry(&main_hdl->requests_queued,
+                                  struct v4l2_ctrl_handler, requests_queued);
+       /*
+        * Note: prev_hdl and hdl must contain the same list of control
+        * references, so if any differences are detected then that is a
+        * driver bug and the WARN_ON is triggered.
+        */
+       mutex_lock(prev_hdl->lock);
+       ref_ctrl_prev = list_first_entry(&prev_hdl->ctrl_refs,
+                                        struct v4l2_ctrl_ref, node);
+       list_for_each_entry(ref_ctrl, &hdl->ctrl_refs, node) {
+               if (ref_ctrl->req)
+                       continue;
+               while (ref_ctrl_prev->ctrl->id < ref_ctrl->ctrl->id) {
+                       /* Should never happen, but just in case... */
+                       if (list_is_last(&ref_ctrl_prev->node,
+                                        &prev_hdl->ctrl_refs))
+                               break;
+                       ref_ctrl_prev = list_next_entry(ref_ctrl_prev, node);
+               }
+               if (WARN_ON(ref_ctrl_prev->ctrl->id != ref_ctrl->ctrl->id))
+                       break;
+               ref_ctrl->req = ref_ctrl_prev->req;
+       }
+       mutex_unlock(prev_hdl->lock);
+queue:
+       list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued);
+       hdl->request_is_queued = true;
+}
+
+static void v4l2_ctrl_request_unbind(struct media_request_object *obj)
+{
+       struct v4l2_ctrl_handler *hdl =
+               container_of(obj, struct v4l2_ctrl_handler, req_obj);
+
+       list_del_init(&hdl->requests);
+       if (hdl->request_is_queued) {
+               list_del_init(&hdl->requests_queued);
+               hdl->request_is_queued = false;
+       }
+}
+
+static void v4l2_ctrl_request_release(struct media_request_object *obj)
+{
+       struct v4l2_ctrl_handler *hdl =
+               container_of(obj, struct v4l2_ctrl_handler, req_obj);
+
+       v4l2_ctrl_handler_free(hdl);
+       kfree(hdl);
+}
+
+static const struct media_request_object_ops req_ops = {
+       .queue = v4l2_ctrl_request_queue,
+       .unbind = v4l2_ctrl_request_unbind,
+       .release = v4l2_ctrl_request_release,
+};
+
+struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req,
+                                       struct v4l2_ctrl_handler *parent)
+{
+       struct media_request_object *obj;
+
+       if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING &&
+                   req->state != MEDIA_REQUEST_STATE_QUEUED))
+               return NULL;
+
+       obj = media_request_object_find(req, &req_ops, parent);
+       if (obj)
+               return container_of(obj, struct v4l2_ctrl_handler, req_obj);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find);
+
+struct v4l2_ctrl *
+v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
+{
+       struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
+
+       return (ref && ref->req == ref) ? ref->ctrl : NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find);
+
+static int v4l2_ctrl_request_bind(struct media_request *req,
+                          struct v4l2_ctrl_handler *hdl,
+                          struct v4l2_ctrl_handler *from)
+{
+       int ret;
+
+       ret = v4l2_ctrl_request_clone(hdl, from);
+
+       if (!ret) {
+               ret = media_request_object_bind(req, &req_ops,
+                                               from, false, &hdl->req_obj);
+               if (!ret)
+                       list_add_tail(&hdl->requests, &from->requests);
+       }
+       return ret;
+}
 
 /* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:
 
@@ -2882,6 +3135,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
 
                if (cs->which &&
                    cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
+                   cs->which != V4L2_CTRL_WHICH_REQUEST_VAL &&
                    V4L2_CTRL_ID2WHICH(id) != cs->which)
                        return -EINVAL;
 
@@ -2892,6 +3146,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
                ref = find_ref_lock(hdl, id);
                if (ref == NULL)
                        return -EINVAL;
+               h->ref = ref;
                ctrl = ref->ctrl;
                if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED)
                        return -EINVAL;
@@ -2914,7 +3169,6 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
                }
                /* Store the ref to the master control of the cluster */
                h->mref = ref;
-               h->ctrl = ctrl;
                /* Initially set next to 0, meaning that there is no other
                   control in this helper array belonging to the same
                   cluster */
@@ -2961,15 +3215,15 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
    whether there are any controls at all. */
 static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
 {
-       if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL)
+       if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL ||
+           which == V4L2_CTRL_WHICH_REQUEST_VAL)
                return 0;
        return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
 }
 
-
-
 /* Get extended controls. Allocates the helpers array if needed. */
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
+static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
+                                  struct v4l2_ext_controls *cs)
 {
        struct v4l2_ctrl_helper helper[4];
        struct v4l2_ctrl_helper *helpers = helper;
@@ -2999,7 +3253,7 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
        cs->error_idx = cs->count;
 
        for (i = 0; !ret && i < cs->count; i++)
-               if (helpers[i].ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
+               if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
                        ret = -EACCES;
 
        for (i = 0; !ret && i < cs->count; i++) {
@@ -3033,8 +3287,12 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
                        u32 idx = i;
 
                        do {
-                               ret = ctrl_to_user(cs->controls + idx,
-                                                  helpers[idx].ctrl);
+                               if (helpers[idx].ref->req)
+                                       ret = req_to_user(cs->controls + idx,
+                                               helpers[idx].ref->req);
+                               else
+                                       ret = ctrl_to_user(cs->controls + idx,
+                                               helpers[idx].ref->ctrl);
                                idx = helpers[idx].next;
                        } while (!ret && idx);
                }
@@ -3045,6 +3303,91 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
                kvfree(helpers);
        return ret;
 }
+
+static struct media_request_object *
+v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl,
+                       struct media_request *req, bool set)
+{
+       struct media_request_object *obj;
+       struct v4l2_ctrl_handler *new_hdl;
+       int ret;
+
+       if (IS_ERR(req))
+               return ERR_CAST(req);
+
+       if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING))
+               return ERR_PTR(-EBUSY);
+
+       obj = media_request_object_find(req, &req_ops, hdl);
+       if (obj)
+               return obj;
+       if (!set)
+               return ERR_PTR(-ENOENT);
+
+       new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL);
+       if (!new_hdl)
+               return ERR_PTR(-ENOMEM);
+
+       obj = &new_hdl->req_obj;
+       ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8);
+       if (!ret)
+               ret = v4l2_ctrl_request_bind(req, new_hdl, hdl);
+       if (ret) {
+               kfree(new_hdl);
+
+               return ERR_PTR(ret);
+       }
+
+       media_request_object_get(obj);
+       return obj;
+}
+
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
+                    struct v4l2_ext_controls *cs)
+{
+       struct media_request_object *obj = NULL;
+       struct media_request *req = NULL;
+       int ret;
+
+       if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) {
+               if (!mdev || cs->request_fd < 0)
+                       return -EINVAL;
+
+               req = media_request_get_by_fd(mdev, cs->request_fd);
+               if (IS_ERR(req))
+                       return PTR_ERR(req);
+
+               if (req->state != MEDIA_REQUEST_STATE_COMPLETE) {
+                       media_request_put(req);
+                       return -EACCES;
+               }
+
+               ret = media_request_lock_for_access(req);
+               if (ret) {
+                       media_request_put(req);
+                       return ret;
+               }
+
+               obj = v4l2_ctrls_find_req_obj(hdl, req, false);
+               if (IS_ERR(obj)) {
+                       media_request_unlock_for_access(req);
+                       media_request_put(req);
+                       return PTR_ERR(obj);
+               }
+
+               hdl = container_of(obj, struct v4l2_ctrl_handler,
+                                  req_obj);
+       }
+
+       ret = v4l2_g_ext_ctrls_common(hdl, cs);
+
+       if (obj) {
+               media_request_unlock_for_access(req);
+               media_request_object_put(obj);
+               media_request_put(req);
+       }
+       return ret;
+}
 EXPORT_SYMBOL(v4l2_g_ext_ctrls);
 
 /* Helper function to get a single control */
@@ -3186,7 +3529,7 @@ static int validate_ctrls(struct v4l2_ext_controls *cs,
 
        cs->error_idx = cs->count;
        for (i = 0; i < cs->count; i++) {
-               struct v4l2_ctrl *ctrl = helpers[i].ctrl;
+               struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl;
                union v4l2_ctrl_ptr p_new;
 
                cs->error_idx = i;
@@ -3233,9 +3576,9 @@ static void update_from_auto_cluster(struct v4l2_ctrl *master)
 }
 
 /* Try or try-and-set controls */
-static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
-                            struct v4l2_ext_controls *cs,
-                            bool set)
+static int try_set_ext_ctrls_common(struct v4l2_fh *fh,
+                                   struct v4l2_ctrl_handler *hdl,
+                                   struct v4l2_ext_controls *cs, bool set)
 {
        struct v4l2_ctrl_helper helper[4];
        struct v4l2_ctrl_helper *helpers = helper;
@@ -3298,7 +3641,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
                        do {
                                /* Check if the auto control is part of the
                                   list, and remember the new value. */
-                               if (helpers[tmp_idx].ctrl == master)
+                               if (helpers[tmp_idx].ref->ctrl == master)
                                        new_auto_val = cs->controls[tmp_idx].value;
                                tmp_idx = helpers[tmp_idx].next;
                        } while (tmp_idx);
@@ -3311,7 +3654,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
                /* Copy the new caller-supplied control values.
                   user_to_new() sets 'is_new' to 1. */
                do {
-                       struct v4l2_ctrl *ctrl = helpers[idx].ctrl;
+                       struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl;
 
                        ret = user_to_new(cs->controls + idx, ctrl);
                        if (!ret && ctrl->is_ptr)
@@ -3320,14 +3663,23 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
                } while (!ret && idx);
 
                if (!ret)
-                       ret = try_or_set_cluster(fh, master, set, 0);
+                       ret = try_or_set_cluster(fh, master,
+                                                !hdl->req_obj.req && set, 0);
+               if (!ret && hdl->req_obj.req && set) {
+                       for (j = 0; j < master->ncontrols; j++) {
+                               struct v4l2_ctrl_ref *ref =
+                                       find_ref(hdl, master->cluster[j]->id);
+
+                               new_to_req(ref);
+                       }
+               }
 
                /* Copy the new values back to userspace. */
                if (!ret) {
                        idx = i;
                        do {
                                ret = new_to_user(cs->controls + idx,
-                                               helpers[idx].ctrl);
+                                               helpers[idx].ref->ctrl);
                                idx = helpers[idx].next;
                        } while (!ret && idx);
                }
@@ -3339,16 +3691,60 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
        return ret;
 }
 
-int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
+static int try_set_ext_ctrls(struct v4l2_fh *fh,
+                            struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
+                            struct v4l2_ext_controls *cs, bool set)
 {
-       return try_set_ext_ctrls(NULL, hdl, cs, false);
+       struct media_request_object *obj = NULL;
+       struct media_request *req = NULL;
+       int ret;
+
+       if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) {
+               if (!mdev || cs->request_fd < 0)
+                       return -EINVAL;
+
+               req = media_request_get_by_fd(mdev, cs->request_fd);
+               if (IS_ERR(req))
+                       return PTR_ERR(req);
+
+               ret = media_request_lock_for_update(req);
+               if (ret) {
+                       media_request_put(req);
+                       return ret;
+               }
+
+               obj = v4l2_ctrls_find_req_obj(hdl, req, set);
+               if (IS_ERR(obj)) {
+                       media_request_unlock_for_update(req);
+                       media_request_put(req);
+                       return PTR_ERR(obj);
+               }
+               hdl = container_of(obj, struct v4l2_ctrl_handler,
+                                  req_obj);
+       }
+
+       ret = try_set_ext_ctrls_common(fh, hdl, cs, set);
+
+       if (obj) {
+               media_request_unlock_for_update(req);
+               media_request_object_put(obj);
+               media_request_put(req);
+       }
+
+       return ret;
+}
+
+int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
+                      struct v4l2_ext_controls *cs)
+{
+       return try_set_ext_ctrls(NULL, hdl, mdev, cs, false);
 }
 EXPORT_SYMBOL(v4l2_try_ext_ctrls);
 
 int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
-                                       struct v4l2_ext_controls *cs)
+                    struct media_device *mdev, struct v4l2_ext_controls *cs)
 {
-       return try_set_ext_ctrls(fh, hdl, cs, true);
+       return try_set_ext_ctrls(fh, hdl, mdev, cs, true);
 }
 EXPORT_SYMBOL(v4l2_s_ext_ctrls);
 
@@ -3442,11 +3838,167 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
 
        /* It's a driver bug if this happens. */
        WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING);
-       strlcpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
+       strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
        return set_ctrl(NULL, ctrl, 0);
 }
 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
 
+void v4l2_ctrl_request_complete(struct media_request *req,
+                               struct v4l2_ctrl_handler *main_hdl)
+{
+       struct media_request_object *obj;
+       struct v4l2_ctrl_handler *hdl;
+       struct v4l2_ctrl_ref *ref;
+
+       if (!req || !main_hdl)
+               return;
+
+       /*
+        * Note that it is valid if nothing was found. It means
+        * that this request doesn't have any controls and so just
+        * wants to leave the controls unchanged.
+        */
+       obj = media_request_object_find(req, &req_ops, main_hdl);
+       if (!obj)
+               return;
+       hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);
+
+       list_for_each_entry(ref, &hdl->ctrl_refs, node) {
+               struct v4l2_ctrl *ctrl = ref->ctrl;
+               struct v4l2_ctrl *master = ctrl->cluster[0];
+               unsigned int i;
+
+               if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
+                       ref->req = ref;
+
+                       v4l2_ctrl_lock(master);
+                       /* g_volatile_ctrl will update the current control values */
+                       for (i = 0; i < master->ncontrols; i++)
+                               cur_to_new(master->cluster[i]);
+                       call_op(master, g_volatile_ctrl);
+                       new_to_req(ref);
+                       v4l2_ctrl_unlock(master);
+                       continue;
+               }
+               if (ref->req == ref)
+                       continue;
+
+               v4l2_ctrl_lock(ctrl);
+               if (ref->req)
+                       ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req);
+               else
+                       ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req);
+               v4l2_ctrl_unlock(ctrl);
+       }
+
+       WARN_ON(!hdl->request_is_queued);
+       list_del_init(&hdl->requests_queued);
+       hdl->request_is_queued = false;
+       media_request_object_complete(obj);
+       media_request_object_put(obj);
+}
+EXPORT_SYMBOL(v4l2_ctrl_request_complete);
+
+void v4l2_ctrl_request_setup(struct media_request *req,
+                            struct v4l2_ctrl_handler *main_hdl)
+{
+       struct media_request_object *obj;
+       struct v4l2_ctrl_handler *hdl;
+       struct v4l2_ctrl_ref *ref;
+
+       if (!req || !main_hdl)
+               return;
+
+       if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
+               return;
+
+       /*
+        * Note that it is valid if nothing was found. It means
+        * that this request doesn't have any controls and so just
+        * wants to leave the controls unchanged.
+        */
+       obj = media_request_object_find(req, &req_ops, main_hdl);
+       if (!obj)
+               return;
+       if (obj->completed) {
+               media_request_object_put(obj);
+               return;
+       }
+       hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);
+
+       list_for_each_entry(ref, &hdl->ctrl_refs, node)
+               ref->req_done = false;
+
+       list_for_each_entry(ref, &hdl->ctrl_refs, node) {
+               struct v4l2_ctrl *ctrl = ref->ctrl;
+               struct v4l2_ctrl *master = ctrl->cluster[0];
+               bool have_new_data = false;
+               int i;
+
+               /*
+                * Skip if this control was already handled by a cluster.
+                * Skip button controls and read-only controls.
+                */
+               if (ref->req_done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
+                   (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
+                       continue;
+
+               v4l2_ctrl_lock(master);
+               for (i = 0; i < master->ncontrols; i++) {
+                       if (master->cluster[i]) {
+                               struct v4l2_ctrl_ref *r =
+                                       find_ref(hdl, master->cluster[i]->id);
+
+                               if (r->req && r == r->req) {
+                                       have_new_data = true;
+                                       break;
+                               }
+                       }
+               }
+               if (!have_new_data) {
+                       v4l2_ctrl_unlock(master);
+                       continue;
+               }
+
+               for (i = 0; i < master->ncontrols; i++) {
+                       if (master->cluster[i]) {
+                               struct v4l2_ctrl_ref *r =
+                                       find_ref(hdl, master->cluster[i]->id);
+
+                               req_to_new(r);
+                               master->cluster[i]->is_new = 1;
+                               r->req_done = true;
+                       }
+               }
+               /*
+                * For volatile autoclusters that are currently in auto mode
+                * we need to discover if it will be set to manual mode.
+                * If so, then we have to copy the current volatile values
+                * first since those will become the new manual values (which
+                * may be overwritten by explicit new values from this set
+                * of controls).
+                */
+               if (master->is_auto && master->has_volatiles &&
+                   !is_cur_manual(master)) {
+                       s32 new_auto_val = *master->p_new.p_s32;
+
+                       /*
+                        * If the new value == the manual value, then copy
+                        * the current volatile values.
+                        */
+                       if (new_auto_val == master->manual_mode_value)
+                               update_from_auto_cluster(master);
+               }
+
+               try_or_set_cluster(NULL, master, true, 0);
+
+               v4l2_ctrl_unlock(master);
+       }
+
+       media_request_object_put(obj);
+}
+EXPORT_SYMBOL(v4l2_ctrl_request_setup);
+
 void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
 {
        if (ctrl == NULL)
index 69e775930fc4df85a5dab10e5608aee6848a29d8..feb749aaaa42f4c801febc1c1db158dce66f09d4 100644 (file)
@@ -444,8 +444,22 @@ static int v4l2_release(struct inode *inode, struct file *filp)
        struct video_device *vdev = video_devdata(filp);
        int ret = 0;
 
-       if (vdev->fops->release)
-               ret = vdev->fops->release(filp);
+       /*
+        * We need to serialize the release() with queueing new requests.
+        * The release() may trigger the cancellation of a streaming
+        * operation, and that should not be mixed with queueing a new
+        * request at the same time.
+        */
+       if (vdev->fops->release) {
+               if (v4l2_device_supports_requests(vdev->v4l2_dev)) {
+                       mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex);
+                       ret = vdev->fops->release(filp);
+                       mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex);
+               } else {
+                       ret = vdev->fops->release(filp);
+               }
+       }
+
        if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP)
                dprintk("%s: release\n",
                        video_device_node_name(vdev));
index 3940e55c72f1f7754bc04a44b295f66432537d46..df0ac38c40500fa68999bb93b946878b708da36c 100644 (file)
@@ -178,7 +178,8 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 
        sd->v4l2_dev = v4l2_dev;
        /* This just returns 0 if either of the two args is NULL */
-       err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
+       err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler,
+                                   NULL, true);
        if (err)
                goto error_module;
 
@@ -245,7 +246,7 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
                }
 
                video_set_drvdata(vdev, sd);
-               strlcpy(vdev->name, sd->name, sizeof(vdev->name));
+               strscpy(vdev->name, sd->name, sizeof(vdev->name));
                vdev->v4l2_dev = v4l2_dev;
                vdev->fops = &v4l2_subdev_fops;
                vdev->release = v4l2_device_release_subdev_node;
index c81faea96fbabf51f519648211fd636313fe28f0..4f23e939ead0b39712d16194026cf03a8b9242b7 100644 (file)
@@ -15,6 +15,7 @@
 #include <media/v4l2-dv-timings.h>
 #include <linux/math64.h>
 #include <linux/hdmi.h>
+#include <media/cec.h>
 
 MODULE_AUTHOR("Hans Verkuil");
 MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
@@ -373,6 +374,45 @@ struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t)
 }
 EXPORT_SYMBOL_GPL(v4l2_dv_timings_aspect_ratio);
 
+/** v4l2_calc_timeperframe - helper function to calculate timeperframe based
+ *     v4l2_dv_timings fields.
+ * @t - Timings for the video mode.
+ *
+ * Calculates the expected timeperframe using the pixel clock value and
+ * horizontal/vertical measures. This means that v4l2_dv_timings structure
+ * must be correctly and fully filled.
+ */
+struct v4l2_fract v4l2_calc_timeperframe(const struct v4l2_dv_timings *t)
+{
+       const struct v4l2_bt_timings *bt = &t->bt;
+       struct v4l2_fract fps_fract = { 1, 1 };
+       unsigned long n, d;
+       u32 htot, vtot, fps;
+       u64 pclk;
+
+       if (t->type != V4L2_DV_BT_656_1120)
+               return fps_fract;
+
+       htot = V4L2_DV_BT_FRAME_WIDTH(bt);
+       vtot = V4L2_DV_BT_FRAME_HEIGHT(bt);
+       pclk = bt->pixelclock;
+
+       if ((bt->flags & V4L2_DV_FL_CAN_DETECT_REDUCED_FPS) &&
+           (bt->flags & V4L2_DV_FL_REDUCED_FPS))
+               pclk = div_u64(pclk * 1000ULL, 1001);
+
+       fps = (htot * vtot) > 0 ? div_u64((100 * pclk), (htot * vtot)) : 0;
+       if (!fps)
+               return fps_fract;
+
+       rational_best_approximation(fps, 100, fps, 100, &n, &d);
+
+       fps_fract.numerator = d;
+       fps_fract.denominator = n;
+       return fps_fract;
+}
+EXPORT_SYMBOL_GPL(v4l2_calc_timeperframe);
+
 /*
  * CVT defines
  * Based on Coordinated Video Timings Standard
@@ -837,9 +877,9 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
                switch (avi->colorimetry) {
                case HDMI_COLORIMETRY_EXTENDED:
                        switch (avi->extended_colorimetry) {
-                       case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB:
-                               c.colorspace = V4L2_COLORSPACE_ADOBERGB;
-                               c.xfer_func = V4L2_XFER_FUNC_ADOBERGB;
+                       case HDMI_EXTENDED_COLORIMETRY_OPRGB:
+                               c.colorspace = V4L2_COLORSPACE_OPRGB;
+                               c.xfer_func = V4L2_XFER_FUNC_OPRGB;
                                break;
                        case HDMI_EXTENDED_COLORIMETRY_BT2020:
                                c.colorspace = V4L2_COLORSPACE_BT2020;
@@ -908,10 +948,10 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
                                c.ycbcr_enc = V4L2_YCBCR_ENC_601;
                                c.xfer_func = V4L2_XFER_FUNC_SRGB;
                                break;
-                       case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601:
-                               c.colorspace = V4L2_COLORSPACE_ADOBERGB;
+                       case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
+                               c.colorspace = V4L2_COLORSPACE_OPRGB;
                                c.ycbcr_enc = V4L2_YCBCR_ENC_601;
-                               c.xfer_func = V4L2_XFER_FUNC_ADOBERGB;
+                               c.xfer_func = V4L2_XFER_FUNC_OPRGB;
                                break;
                        case HDMI_EXTENDED_COLORIMETRY_BT2020:
                                c.colorspace = V4L2_COLORSPACE_BT2020;
@@ -942,3 +982,153 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
        return c;
 }
 EXPORT_SYMBOL_GPL(v4l2_hdmi_rx_colorimetry);
+
+/**
+ * v4l2_get_edid_phys_addr() - find and return the physical address
+ *
+ * @edid:      pointer to the EDID data
+ * @size:      size in bytes of the EDID data
+ * @offset:    If not %NULL then the location of the physical address
+ *             bytes in the EDID will be returned here. This is set to 0
+ *             if there is no physical address found.
+ *
+ * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none.
+ */
+u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size,
+                           unsigned int *offset)
+{
+       unsigned int loc = cec_get_edid_spa_location(edid, size);
+
+       if (offset)
+               *offset = loc;
+       if (loc == 0)
+               return CEC_PHYS_ADDR_INVALID;
+       return (edid[loc] << 8) | edid[loc + 1];
+}
+EXPORT_SYMBOL_GPL(v4l2_get_edid_phys_addr);
+
+/**
+ * v4l2_set_edid_phys_addr() - find and set the physical address
+ *
+ * @edid:      pointer to the EDID data
+ * @size:      size in bytes of the EDID data
+ * @phys_addr: the new physical address
+ *
+ * This function finds the location of the physical address in the EDID
+ * and fills in the given physical address and updates the checksum
+ * at the end of the EDID block. It does nothing if the EDID doesn't
+ * contain a physical address.
+ */
+void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr)
+{
+       unsigned int loc = cec_get_edid_spa_location(edid, size);
+       u8 sum = 0;
+       unsigned int i;
+
+       if (loc == 0)
+               return;
+       edid[loc] = phys_addr >> 8;
+       edid[loc + 1] = phys_addr & 0xff;
+       loc &= ~0x7f;
+
+       /* update the checksum */
+       for (i = loc; i < loc + 127; i++)
+               sum += edid[i];
+       edid[i] = 256 - sum;
+}
+EXPORT_SYMBOL_GPL(v4l2_set_edid_phys_addr);
+
+/**
+ * v4l2_phys_addr_for_input() - calculate the PA for an input
+ *
+ * @phys_addr: the physical address of the parent
+ * @input:     the number of the input port, must be between 1 and 15
+ *
+ * This function calculates a new physical address based on the input
+ * port number. For example:
+ *
+ * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0
+ *
+ * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0
+ *
+ * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5
+ *
+ * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth.
+ *
+ * Return: the new physical address or CEC_PHYS_ADDR_INVALID.
+ */
+u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input)
+{
+       /* Check if input is sane */
+       if (WARN_ON(input == 0 || input > 0xf))
+               return CEC_PHYS_ADDR_INVALID;
+
+       if (phys_addr == 0)
+               return input << 12;
+
+       if ((phys_addr & 0x0fff) == 0)
+               return phys_addr | (input << 8);
+
+       if ((phys_addr & 0x00ff) == 0)
+               return phys_addr | (input << 4);
+
+       if ((phys_addr & 0x000f) == 0)
+               return phys_addr | input;
+
+       /*
+        * All nibbles are used so no valid physical addresses can be assigned
+        * to the input.
+        */
+       return CEC_PHYS_ADDR_INVALID;
+}
+EXPORT_SYMBOL_GPL(v4l2_phys_addr_for_input);
+
+/**
+ * v4l2_phys_addr_validate() - validate a physical address from an EDID
+ *
+ * @phys_addr: the physical address to validate
+ * @parent:    if not %NULL, then this is filled with the parents PA.
+ * @port:      if not %NULL, then this is filled with the input port.
+ *
+ * This validates a physical address as read from an EDID. If the
+ * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end),
+ * then it will return -EINVAL.
+ *
+ * The parent PA is passed into %parent and the input port is passed into
+ * %port. For example:
+ *
+ * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0.
+ *
+ * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1.
+ *
+ * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2.
+ *
+ * PA = f.f.f.f: has parent f.f.f.f and input port 0.
+ *
+ * Return: 0 if the PA is valid, -EINVAL if not.
+ */
+int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
+{
+       int i;
+
+       if (parent)
+               *parent = phys_addr;
+       if (port)
+               *port = 0;
+       if (phys_addr == CEC_PHYS_ADDR_INVALID)
+               return 0;
+       for (i = 0; i < 16; i += 4)
+               if (phys_addr & (0xf << i))
+                       break;
+       if (i == 16)
+               return 0;
+       if (parent)
+               *parent = phys_addr & (0xfff0 << i);
+       if (port)
+               *port = (phys_addr >> i) & 0xf;
+       for (i += 4; i < 16; i += 4)
+               if ((phys_addr & (0xf << i)) == 0)
+                       return -EINVAL;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_phys_addr_validate);
index 215b4804ada29a5d8b037c96ad6bc1ebfd968eaa..1697932af5ea19bb8af5a1c906b8fa615ccf1560 100644 (file)
@@ -640,7 +640,7 @@ static struct v4l2_flash *__v4l2_flash_init(
        v4l2_subdev_init(sd, &v4l2_flash_subdev_ops);
        sd->internal_ops = &v4l2_flash_subdev_internal_ops;
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-       strlcpy(sd->name, config->dev_name, sizeof(sd->name));
+       strscpy(sd->name, config->dev_name, sizeof(sd->name));
 
        ret = media_entity_pads_init(&sd->entity, 0, NULL);
        if (ret < 0)
index 169bdbb1f61a51305257a04882dfc87db4b19117..218f0da0ce7690673f797cd5dce0aea2ce0b8f53 100644 (file)
@@ -36,194 +36,469 @@ enum v4l2_fwnode_bus_type {
        V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
        V4L2_FWNODE_BUS_TYPE_CSI1,
        V4L2_FWNODE_BUS_TYPE_CCP2,
+       V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
+       V4L2_FWNODE_BUS_TYPE_PARALLEL,
+       V4L2_FWNODE_BUS_TYPE_BT656,
        NR_OF_V4L2_FWNODE_BUS_TYPE,
 };
 
+static const struct v4l2_fwnode_bus_conv {
+       enum v4l2_fwnode_bus_type fwnode_bus_type;
+       enum v4l2_mbus_type mbus_type;
+       const char *name;
+} busses[] = {
+       {
+               V4L2_FWNODE_BUS_TYPE_GUESS,
+               V4L2_MBUS_UNKNOWN,
+               "not specified",
+       }, {
+               V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
+               V4L2_MBUS_CSI2_CPHY,
+               "MIPI CSI-2 C-PHY",
+       }, {
+               V4L2_FWNODE_BUS_TYPE_CSI1,
+               V4L2_MBUS_CSI1,
+               "MIPI CSI-1",
+       }, {
+               V4L2_FWNODE_BUS_TYPE_CCP2,
+               V4L2_MBUS_CCP2,
+               "compact camera port 2",
+       }, {
+               V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
+               V4L2_MBUS_CSI2_DPHY,
+               "MIPI CSI-2 D-PHY",
+       }, {
+               V4L2_FWNODE_BUS_TYPE_PARALLEL,
+               V4L2_MBUS_PARALLEL,
+               "parallel",
+       }, {
+               V4L2_FWNODE_BUS_TYPE_BT656,
+               V4L2_MBUS_BT656,
+               "Bt.656",
+       }
+};
+
+static const struct v4l2_fwnode_bus_conv *
+get_v4l2_fwnode_bus_conv_by_fwnode_bus(enum v4l2_fwnode_bus_type type)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(busses); i++)
+               if (busses[i].fwnode_bus_type == type)
+                       return &busses[i];
+
+       return NULL;
+}
+
+static enum v4l2_mbus_type
+v4l2_fwnode_bus_type_to_mbus(enum v4l2_fwnode_bus_type type)
+{
+       const struct v4l2_fwnode_bus_conv *conv =
+               get_v4l2_fwnode_bus_conv_by_fwnode_bus(type);
+
+       return conv ? conv->mbus_type : V4L2_MBUS_UNKNOWN;
+}
+
+static const char *
+v4l2_fwnode_bus_type_to_string(enum v4l2_fwnode_bus_type type)
+{
+       const struct v4l2_fwnode_bus_conv *conv =
+               get_v4l2_fwnode_bus_conv_by_fwnode_bus(type);
+
+       return conv ? conv->name : "not found";
+}
+
+static const struct v4l2_fwnode_bus_conv *
+get_v4l2_fwnode_bus_conv_by_mbus(enum v4l2_mbus_type type)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(busses); i++)
+               if (busses[i].mbus_type == type)
+                       return &busses[i];
+
+       return NULL;
+}
+
+static const char *
+v4l2_fwnode_mbus_type_to_string(enum v4l2_mbus_type type)
+{
+       const struct v4l2_fwnode_bus_conv *conv =
+               get_v4l2_fwnode_bus_conv_by_mbus(type);
+
+       return conv ? conv->name : "not found";
+}
+
 static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
-                                              struct v4l2_fwnode_endpoint *vep)
+                                              struct v4l2_fwnode_endpoint *vep,
+                                              enum v4l2_mbus_type bus_type)
 {
        struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2;
-       bool have_clk_lane = false;
+       bool have_clk_lane = false, have_data_lanes = false,
+               have_lane_polarities = false;
        unsigned int flags = 0, lanes_used = 0;
+       u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
+       u32 clock_lane = 0;
+       unsigned int num_data_lanes = 0;
+       bool use_default_lane_mapping = false;
        unsigned int i;
        u32 v;
        int rval;
 
+       if (bus_type == V4L2_MBUS_CSI2_DPHY ||
+           bus_type == V4L2_MBUS_CSI2_CPHY) {
+               use_default_lane_mapping = true;
+
+               num_data_lanes = min_t(u32, bus->num_data_lanes,
+                                      V4L2_FWNODE_CSI2_MAX_DATA_LANES);
+
+               clock_lane = bus->clock_lane;
+               if (clock_lane)
+                       use_default_lane_mapping = false;
+
+               for (i = 0; i < num_data_lanes; i++) {
+                       array[i] = bus->data_lanes[i];
+                       if (array[i])
+                               use_default_lane_mapping = false;
+               }
+
+               if (use_default_lane_mapping)
+                       pr_debug("using default lane mapping\n");
+       }
+
        rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
        if (rval > 0) {
-               u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
-
-               bus->num_data_lanes =
+               num_data_lanes =
                        min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval);
 
                fwnode_property_read_u32_array(fwnode, "data-lanes", array,
-                                              bus->num_data_lanes);
+                                              num_data_lanes);
 
-               for (i = 0; i < bus->num_data_lanes; i++) {
-                       if (lanes_used & BIT(array[i]))
-                               pr_warn("duplicated lane %u in data-lanes\n",
-                                       array[i]);
-                       lanes_used |= BIT(array[i]);
+               have_data_lanes = true;
+       }
 
-                       bus->data_lanes[i] = array[i];
+       for (i = 0; i < num_data_lanes; i++) {
+               if (lanes_used & BIT(array[i])) {
+                       if (have_data_lanes || !use_default_lane_mapping)
+                               pr_warn("duplicated lane %u in data-lanes, using defaults\n",
+                                       array[i]);
+                       use_default_lane_mapping = true;
                }
+               lanes_used |= BIT(array[i]);
 
-               rval = fwnode_property_read_u32_array(fwnode,
-                                                     "lane-polarities", NULL,
-                                                     0);
-               if (rval > 0) {
-                       if (rval != 1 + bus->num_data_lanes /* clock+data */) {
-                               pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
-                                       1 + bus->num_data_lanes, rval);
-                               return -EINVAL;
-                       }
-
-                       fwnode_property_read_u32_array(fwnode,
-                                                      "lane-polarities", array,
-                                                      1 + bus->num_data_lanes);
+               if (have_data_lanes)
+                       pr_debug("lane %u position %u\n", i, array[i]);
+       }
 
-                       for (i = 0; i < 1 + bus->num_data_lanes; i++)
-                               bus->lane_polarities[i] = array[i];
+       rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
+                                             0);
+       if (rval > 0) {
+               if (rval != 1 + num_data_lanes /* clock+data */) {
+                       pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
+                               1 + num_data_lanes, rval);
+                       return -EINVAL;
                }
 
+               have_lane_polarities = true;
        }
 
        if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
-               if (lanes_used & BIT(v))
-                       pr_warn("duplicated lane %u in clock-lanes\n", v);
-               lanes_used |= BIT(v);
-
-               bus->clock_lane = v;
+               clock_lane = v;
+               pr_debug("clock lane position %u\n", v);
                have_clk_lane = true;
        }
 
-       if (fwnode_property_present(fwnode, "clock-noncontinuous"))
+       if (lanes_used & BIT(clock_lane)) {
+               if (have_clk_lane || !use_default_lane_mapping)
+                       pr_warn("duplicated lane %u in clock-lanes, using defaults\n",
+                               v);
+               use_default_lane_mapping = true;
+       }
+
+       if (fwnode_property_present(fwnode, "clock-noncontinuous")) {
                flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
-       else if (have_clk_lane || bus->num_data_lanes > 0)
+               pr_debug("non-continuous clock\n");
+       } else {
                flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+       }
 
-       bus->flags = flags;
-       vep->bus_type = V4L2_MBUS_CSI2;
+       if (bus_type == V4L2_MBUS_CSI2_DPHY ||
+           bus_type == V4L2_MBUS_CSI2_CPHY || lanes_used ||
+           have_clk_lane || (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) {
+               bus->flags = flags;
+               if (bus_type == V4L2_MBUS_UNKNOWN)
+                       vep->bus_type = V4L2_MBUS_CSI2_DPHY;
+               bus->num_data_lanes = num_data_lanes;
+
+               if (use_default_lane_mapping) {
+                       bus->clock_lane = 0;
+                       for (i = 0; i < num_data_lanes; i++)
+                               bus->data_lanes[i] = 1 + i;
+               } else {
+                       bus->clock_lane = clock_lane;
+                       for (i = 0; i < num_data_lanes; i++)
+                               bus->data_lanes[i] = array[i];
+               }
+
+               if (have_lane_polarities) {
+                       fwnode_property_read_u32_array(fwnode,
+                                                      "lane-polarities", array,
+                                                      1 + num_data_lanes);
+
+                       for (i = 0; i < 1 + num_data_lanes; i++) {
+                               bus->lane_polarities[i] = array[i];
+                               pr_debug("lane %u polarity %sinverted",
+                                        i, array[i] ? "" : "not ");
+                       }
+               } else {
+                       pr_debug("no lane polarities defined, assuming not inverted\n");
+               }
+       }
 
        return 0;
 }
 
-static void v4l2_fwnode_endpoint_parse_parallel_bus(
-       struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep)
+#define PARALLEL_MBUS_FLAGS (V4L2_MBUS_HSYNC_ACTIVE_HIGH |     \
+                            V4L2_MBUS_HSYNC_ACTIVE_LOW |       \
+                            V4L2_MBUS_VSYNC_ACTIVE_HIGH |      \
+                            V4L2_MBUS_VSYNC_ACTIVE_LOW |       \
+                            V4L2_MBUS_FIELD_EVEN_HIGH |        \
+                            V4L2_MBUS_FIELD_EVEN_LOW)
+
+static void
+v4l2_fwnode_endpoint_parse_parallel_bus(struct fwnode_handle *fwnode,
+                                       struct v4l2_fwnode_endpoint *vep,
+                                       enum v4l2_mbus_type bus_type)
 {
        struct v4l2_fwnode_bus_parallel *bus = &vep->bus.parallel;
        unsigned int flags = 0;
        u32 v;
 
-       if (!fwnode_property_read_u32(fwnode, "hsync-active", &v))
+       if (bus_type == V4L2_MBUS_PARALLEL || bus_type == V4L2_MBUS_BT656)
+               flags = bus->flags;
+
+       if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) {
+               flags &= ~(V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+                          V4L2_MBUS_HSYNC_ACTIVE_LOW);
                flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
                        V4L2_MBUS_HSYNC_ACTIVE_LOW;
+               pr_debug("hsync-active %s\n", v ? "high" : "low");
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "vsync-active", &v))
+       if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) {
+               flags &= ~(V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+                          V4L2_MBUS_VSYNC_ACTIVE_LOW);
                flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
                        V4L2_MBUS_VSYNC_ACTIVE_LOW;
+               pr_debug("vsync-active %s\n", v ? "high" : "low");
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "field-even-active", &v))
+       if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) {
+               flags &= ~(V4L2_MBUS_FIELD_EVEN_HIGH |
+                          V4L2_MBUS_FIELD_EVEN_LOW);
                flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
                        V4L2_MBUS_FIELD_EVEN_LOW;
-       if (flags)
-               vep->bus_type = V4L2_MBUS_PARALLEL;
-       else
-               vep->bus_type = V4L2_MBUS_BT656;
+               pr_debug("field-even-active %s\n", v ? "high" : "low");
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v))
+       if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) {
+               flags &= ~(V4L2_MBUS_PCLK_SAMPLE_RISING |
+                          V4L2_MBUS_PCLK_SAMPLE_FALLING);
                flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
                        V4L2_MBUS_PCLK_SAMPLE_FALLING;
+               pr_debug("pclk-sample %s\n", v ? "high" : "low");
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "data-active", &v))
+       if (!fwnode_property_read_u32(fwnode, "data-active", &v)) {
+               flags &= ~(V4L2_MBUS_PCLK_SAMPLE_RISING |
+                          V4L2_MBUS_PCLK_SAMPLE_FALLING);
                flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
                        V4L2_MBUS_DATA_ACTIVE_LOW;
+               pr_debug("data-active %s\n", v ? "high" : "low");
+       }
 
-       if (fwnode_property_present(fwnode, "slave-mode"))
+       if (fwnode_property_present(fwnode, "slave-mode")) {
+               pr_debug("slave mode\n");
+               flags &= ~V4L2_MBUS_MASTER;
                flags |= V4L2_MBUS_SLAVE;
-       else
+       } else {
+               flags &= ~V4L2_MBUS_SLAVE;
                flags |= V4L2_MBUS_MASTER;
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "bus-width", &v))
+       if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) {
                bus->bus_width = v;
+               pr_debug("bus-width %u\n", v);
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "data-shift", &v))
+       if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) {
                bus->data_shift = v;
+               pr_debug("data-shift %u\n", v);
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v))
+       if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) {
+               flags &= ~(V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH |
+                          V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW);
                flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
                        V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
+               pr_debug("sync-on-green-active %s\n", v ? "high" : "low");
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v))
+       if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) {
+               flags &= ~(V4L2_MBUS_DATA_ENABLE_HIGH |
+                          V4L2_MBUS_DATA_ENABLE_LOW);
                flags |= v ? V4L2_MBUS_DATA_ENABLE_HIGH :
                        V4L2_MBUS_DATA_ENABLE_LOW;
+               pr_debug("data-enable-active %s\n", v ? "high" : "low");
+       }
 
-       bus->flags = flags;
-
+       switch (bus_type) {
+       default:
+               bus->flags = flags;
+               if (flags & PARALLEL_MBUS_FLAGS)
+                       vep->bus_type = V4L2_MBUS_PARALLEL;
+               else
+                       vep->bus_type = V4L2_MBUS_BT656;
+               break;
+       case V4L2_MBUS_PARALLEL:
+               vep->bus_type = V4L2_MBUS_PARALLEL;
+               bus->flags = flags;
+               break;
+       case V4L2_MBUS_BT656:
+               vep->bus_type = V4L2_MBUS_BT656;
+               bus->flags = flags & ~PARALLEL_MBUS_FLAGS;
+               break;
+       }
 }
 
 static void
 v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode,
                                    struct v4l2_fwnode_endpoint *vep,
-                                   u32 bus_type)
+                                   enum v4l2_mbus_type bus_type)
 {
        struct v4l2_fwnode_bus_mipi_csi1 *bus = &vep->bus.mipi_csi1;
        u32 v;
 
-       if (!fwnode_property_read_u32(fwnode, "clock-inv", &v))
+       if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) {
                bus->clock_inv = v;
+               pr_debug("clock-inv %u\n", v);
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "strobe", &v))
+       if (!fwnode_property_read_u32(fwnode, "strobe", &v)) {
                bus->strobe = v;
+               pr_debug("strobe %u\n", v);
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "data-lanes", &v))
+       if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) {
                bus->data_lane = v;
+               pr_debug("data-lanes %u\n", v);
+       }
 
-       if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v))
+       if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
                bus->clock_lane = v;
+               pr_debug("clock-lanes %u\n", v);
+       }
 
-       if (bus_type == V4L2_FWNODE_BUS_TYPE_CCP2)
+       if (bus_type == V4L2_MBUS_CCP2)
                vep->bus_type = V4L2_MBUS_CCP2;
        else
                vep->bus_type = V4L2_MBUS_CSI1;
 }
 
-int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
-                              struct v4l2_fwnode_endpoint *vep)
+static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
+                                       struct v4l2_fwnode_endpoint *vep)
 {
-       u32 bus_type = 0;
+       u32 bus_type = V4L2_FWNODE_BUS_TYPE_GUESS;
+       enum v4l2_mbus_type mbus_type;
        int rval;
 
-       fwnode_graph_parse_endpoint(fwnode, &vep->base);
+       if (vep->bus_type == V4L2_MBUS_UNKNOWN) {
+               /* Zero fields from bus union to until the end */
+               memset(&vep->bus, 0,
+                      sizeof(*vep) - offsetof(typeof(*vep), bus));
+       }
 
-       /* Zero fields from bus_type to until the end */
-       memset(&vep->bus_type, 0, sizeof(*vep) -
-              offsetof(typeof(*vep), bus_type));
+       pr_debug("===== begin V4L2 endpoint properties\n");
+
+       /*
+        * Zero the fwnode graph endpoint memory in case we don't end up parsing
+        * the endpoint.
+        */
+       memset(&vep->base, 0, sizeof(vep->base));
 
        fwnode_property_read_u32(fwnode, "bus-type", &bus_type);
+       pr_debug("fwnode video bus type %s (%u), mbus type %s (%u)\n",
+                v4l2_fwnode_bus_type_to_string(bus_type), bus_type,
+                v4l2_fwnode_mbus_type_to_string(vep->bus_type),
+                vep->bus_type);
+       mbus_type = v4l2_fwnode_bus_type_to_mbus(bus_type);
+
+       if (vep->bus_type != V4L2_MBUS_UNKNOWN) {
+               if (mbus_type != V4L2_MBUS_UNKNOWN &&
+                   vep->bus_type != mbus_type) {
+                       pr_debug("expecting bus type %s\n",
+                                v4l2_fwnode_mbus_type_to_string(vep->bus_type));
+                       return -ENXIO;
+               }
+       } else {
+               vep->bus_type = mbus_type;
+       }
 
-       switch (bus_type) {
-       case V4L2_FWNODE_BUS_TYPE_GUESS:
-               rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep);
+       switch (vep->bus_type) {
+       case V4L2_MBUS_UNKNOWN:
+               rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
+                                                          V4L2_MBUS_UNKNOWN);
                if (rval)
                        return rval;
-               /*
-                * Parse the parallel video bus properties only if none
-                * of the MIPI CSI-2 specific properties were found.
-                */
-               if (vep->bus.mipi_csi2.flags == 0)
-                       v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep);
-
-               return 0;
-       case V4L2_FWNODE_BUS_TYPE_CCP2:
-       case V4L2_FWNODE_BUS_TYPE_CSI1:
-               v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, bus_type);
-
-               return 0;
+
+               if (vep->bus_type == V4L2_MBUS_UNKNOWN)
+                       v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep,
+                                                               V4L2_MBUS_UNKNOWN);
+
+               pr_debug("assuming media bus type %s (%u)\n",
+                        v4l2_fwnode_mbus_type_to_string(vep->bus_type),
+                        vep->bus_type);
+
+               break;
+       case V4L2_MBUS_CCP2:
+       case V4L2_MBUS_CSI1:
+               v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, vep->bus_type);
+
+               break;
+       case V4L2_MBUS_CSI2_DPHY:
+       case V4L2_MBUS_CSI2_CPHY:
+               rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
+                                                          vep->bus_type);
+               if (rval)
+                       return rval;
+
+               break;
+       case V4L2_MBUS_PARALLEL:
+       case V4L2_MBUS_BT656:
+               v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep,
+                                                       vep->bus_type);
+
+               break;
        default:
-               pr_warn("unsupported bus type %u\n", bus_type);
+               pr_warn("unsupported bus type %u\n", mbus_type);
                return -EINVAL;
        }
+
+       fwnode_graph_parse_endpoint(fwnode, &vep->base);
+
+       return 0;
+}
+
+int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
+                              struct v4l2_fwnode_endpoint *vep)
+{
+       int ret;
+
+       ret = __v4l2_fwnode_endpoint_parse(fwnode, vep);
+
+       pr_debug("===== end V4L2 endpoint properties\n");
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse);
 
@@ -233,49 +508,48 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
                return;
 
        kfree(vep->link_frequencies);
-       kfree(vep);
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);
 
-struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
-       struct fwnode_handle *fwnode)
+int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode,
+                                    struct v4l2_fwnode_endpoint *vep)
 {
-       struct v4l2_fwnode_endpoint *vep;
        int rval;
 
-       vep = kzalloc(sizeof(*vep), GFP_KERNEL);
-       if (!vep)
-               return ERR_PTR(-ENOMEM);
-
-       rval = v4l2_fwnode_endpoint_parse(fwnode, vep);
+       rval = __v4l2_fwnode_endpoint_parse(fwnode, vep);
        if (rval < 0)
-               goto out_err;
+               return rval;
 
        rval = fwnode_property_read_u64_array(fwnode, "link-frequencies",
                                              NULL, 0);
        if (rval > 0) {
+               unsigned int i;
+
                vep->link_frequencies =
                        kmalloc_array(rval, sizeof(*vep->link_frequencies),
                                      GFP_KERNEL);
-               if (!vep->link_frequencies) {
-                       rval = -ENOMEM;
-                       goto out_err;
-               }
+               if (!vep->link_frequencies)
+                       return -ENOMEM;
 
                vep->nr_of_link_frequencies = rval;
 
-               rval = fwnode_property_read_u64_array(
-                       fwnode, "link-frequencies", vep->link_frequencies,
-                       vep->nr_of_link_frequencies);
-               if (rval < 0)
-                       goto out_err;
+               rval = fwnode_property_read_u64_array(fwnode,
+                                                     "link-frequencies",
+                                                     vep->link_frequencies,
+                                                     vep->nr_of_link_frequencies);
+               if (rval < 0) {
+                       v4l2_fwnode_endpoint_free(vep);
+                       return rval;
+               }
+
+               for (i = 0; i < vep->nr_of_link_frequencies; i++)
+                       pr_info("link-frequencies %u value %llu\n", i,
+                               vep->link_frequencies[i]);
        }
 
-       return vep;
+       pr_debug("===== end V4L2 endpoint properties\n");
 
-out_err:
-       v4l2_fwnode_endpoint_free(vep);
-       return ERR_PTR(rval);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
 
@@ -320,43 +594,16 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
 }
 EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
 
-static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,
-                                      unsigned int max_subdevs)
-{
-       struct v4l2_async_subdev **subdevs;
-
-       if (max_subdevs <= notifier->max_subdevs)
-               return 0;
-
-       subdevs = kvmalloc_array(
-               max_subdevs, sizeof(*notifier->subdevs),
-               GFP_KERNEL | __GFP_ZERO);
-       if (!subdevs)
-               return -ENOMEM;
-
-       if (notifier->subdevs) {
-               memcpy(subdevs, notifier->subdevs,
-                      sizeof(*subdevs) * notifier->num_subdevs);
-
-               kvfree(notifier->subdevs);
-       }
-
-       notifier->subdevs = subdevs;
-       notifier->max_subdevs = max_subdevs;
-
-       return 0;
-}
-
-static int v4l2_async_notifier_fwnode_parse_endpoint(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       struct fwnode_handle *endpoint, unsigned int asd_struct_size,
-       int (*parse_endpoint)(struct device *dev,
-                           struct v4l2_fwnode_endpoint *vep,
-                           struct v4l2_async_subdev *asd))
+static int
+v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
+                                         struct v4l2_async_notifier *notifier,
+                                         struct fwnode_handle *endpoint,
+                                         unsigned int asd_struct_size,
+                                         parse_endpoint_func parse_endpoint)
 {
+       struct v4l2_fwnode_endpoint vep = { .bus_type = 0 };
        struct v4l2_async_subdev *asd;
-       struct v4l2_fwnode_endpoint *vep;
-       int ret = 0;
+       int ret;
 
        asd = kzalloc(asd_struct_size, GFP_KERNEL);
        if (!asd)
@@ -367,32 +614,36 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
                fwnode_graph_get_remote_port_parent(endpoint);
        if (!asd->match.fwnode) {
                dev_warn(dev, "bad remote port parent\n");
-               ret = -EINVAL;
+               ret = -ENOTCONN;
                goto out_err;
        }
 
-       vep = v4l2_fwnode_endpoint_alloc_parse(endpoint);
-       if (IS_ERR(vep)) {
-               ret = PTR_ERR(vep);
+       ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &vep);
+       if (ret) {
                dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n",
                         ret);
                goto out_err;
        }
 
-       ret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;
+       ret = parse_endpoint ? parse_endpoint(dev, &vep, asd) : 0;
        if (ret == -ENOTCONN)
-               dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep->base.port,
-                       vep->base.id);
+               dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep.base.port,
+                       vep.base.id);
        else if (ret < 0)
                dev_warn(dev,
                         "driver could not parse port@%u/endpoint@%u (%d)\n",
-                        vep->base.port, vep->base.id, ret);
-       v4l2_fwnode_endpoint_free(vep);
+                        vep.base.port, vep.base.id, ret);
+       v4l2_fwnode_endpoint_free(&vep);
        if (ret < 0)
                goto out_err;
 
-       notifier->subdevs[notifier->num_subdevs] = asd;
-       notifier->num_subdevs++;
+       ret = v4l2_async_notifier_add_subdev(notifier, asd);
+       if (ret < 0) {
+               /* not an error if asd already exists */
+               if (ret == -EEXIST)
+                       ret = 0;
+               goto out_err;
+       }
 
        return 0;
 
@@ -403,56 +654,21 @@ out_err:
        return ret == -ENOTCONN ? 0 : ret;
 }
 
-static int __v4l2_async_notifier_parse_fwnode_endpoints(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       size_t asd_struct_size, unsigned int port, bool has_port,
-       int (*parse_endpoint)(struct device *dev,
-                           struct v4l2_fwnode_endpoint *vep,
-                           struct v4l2_async_subdev *asd))
+static int
+__v4l2_async_notifier_parse_fwnode_ep(struct device *dev,
+                                     struct v4l2_async_notifier *notifier,
+                                     size_t asd_struct_size,
+                                     unsigned int port,
+                                     bool has_port,
+                                     parse_endpoint_func parse_endpoint)
 {
        struct fwnode_handle *fwnode;
-       unsigned int max_subdevs = notifier->max_subdevs;
-       int ret;
+       int ret = 0;
 
        if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))
                return -EINVAL;
 
-       for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(
-                                    dev_fwnode(dev), fwnode)); ) {
-               struct fwnode_handle *dev_fwnode;
-               bool is_available;
-
-               dev_fwnode = fwnode_graph_get_port_parent(fwnode);
-               is_available = fwnode_device_is_available(dev_fwnode);
-               fwnode_handle_put(dev_fwnode);
-               if (!is_available)
-                       continue;
-
-               if (has_port) {
-                       struct fwnode_endpoint ep;
-
-                       ret = fwnode_graph_parse_endpoint(fwnode, &ep);
-                       if (ret) {
-                               fwnode_handle_put(fwnode);
-                               return ret;
-                       }
-
-                       if (ep.port != port)
-                               continue;
-               }
-               max_subdevs++;
-       }
-
-       /* No subdevs to add? Return here. */
-       if (max_subdevs == notifier->max_subdevs)
-               return 0;
-
-       ret = v4l2_async_notifier_realloc(notifier, max_subdevs);
-       if (ret)
-               return ret;
-
-       for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(
-                                    dev_fwnode(dev), fwnode)); ) {
+       fwnode_graph_for_each_endpoint(dev_fwnode(dev), fwnode) {
                struct fwnode_handle *dev_fwnode;
                bool is_available;
 
@@ -473,13 +689,11 @@ static int __v4l2_async_notifier_parse_fwnode_endpoints(
                                continue;
                }
 
-               if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
-                       ret = -EINVAL;
-                       break;
-               }
-
-               ret = v4l2_async_notifier_fwnode_parse_endpoint(
-                       dev, notifier, fwnode, asd_struct_size, parse_endpoint);
+               ret = v4l2_async_notifier_fwnode_parse_endpoint(dev,
+                                                               notifier,
+                                                               fwnode,
+                                                               asd_struct_size,
+                                                               parse_endpoint);
                if (ret < 0)
                        break;
        }
@@ -489,27 +703,29 @@ static int __v4l2_async_notifier_parse_fwnode_endpoints(
        return ret;
 }
 
-int v4l2_async_notifier_parse_fwnode_endpoints(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       size_t asd_struct_size,
-       int (*parse_endpoint)(struct device *dev,
-                           struct v4l2_fwnode_endpoint *vep,
-                           struct v4l2_async_subdev *asd))
+int
+v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev,
+                                          struct v4l2_async_notifier *notifier,
+                                          size_t asd_struct_size,
+                                          parse_endpoint_func parse_endpoint)
 {
-       return __v4l2_async_notifier_parse_fwnode_endpoints(
-               dev, notifier, asd_struct_size, 0, false, parse_endpoint);
+       return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier,
+                                                    asd_struct_size, 0,
+                                                    false, parse_endpoint);
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
 
-int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       size_t asd_struct_size, unsigned int port,
-       int (*parse_endpoint)(struct device *dev,
-                           struct v4l2_fwnode_endpoint *vep,
-                           struct v4l2_async_subdev *asd))
+int
+v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev,
+                                                  struct v4l2_async_notifier *notifier,
+                                                  size_t asd_struct_size,
+                                                  unsigned int port,
+                                                  parse_endpoint_func parse_endpoint)
 {
-       return __v4l2_async_notifier_parse_fwnode_endpoints(
-               dev, notifier, asd_struct_size, port, true, parse_endpoint);
+       return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier,
+                                                    asd_struct_size,
+                                                    port, true,
+                                                    parse_endpoint);
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
 
@@ -524,17 +740,18 @@ EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
  *        -ENOMEM if memory allocation failed
  *        -EINVAL if property parsing failed
  */
-static int v4l2_fwnode_reference_parse(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       const char *prop)
+static int v4l2_fwnode_reference_parse(struct device *dev,
+                                      struct v4l2_async_notifier *notifier,
+                                      const char *prop)
 {
        struct fwnode_reference_args args;
        unsigned int index;
        int ret;
 
        for (index = 0;
-            !(ret = fwnode_property_get_reference_args(
-                      dev_fwnode(dev), prop, NULL, 0, index, &args));
+            !(ret = fwnode_property_get_reference_args(dev_fwnode(dev),
+                                                       prop, NULL, 0,
+                                                       index, &args));
             index++)
                fwnode_handle_put(args.fwnode);
 
@@ -548,31 +765,25 @@ static int v4l2_fwnode_reference_parse(
        if (ret != -ENOENT && ret != -ENODATA)
                return ret;
 
-       ret = v4l2_async_notifier_realloc(notifier,
-                                         notifier->num_subdevs + index);
-       if (ret)
-               return ret;
-
-       for (index = 0; !fwnode_property_get_reference_args(
-                    dev_fwnode(dev), prop, NULL, 0, index, &args);
+       for (index = 0;
+            !fwnode_property_get_reference_args(dev_fwnode(dev), prop, NULL,
+                                                0, index, &args);
             index++) {
                struct v4l2_async_subdev *asd;
 
-               if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
-                       ret = -EINVAL;
-                       goto error;
-               }
+               asd = v4l2_async_notifier_add_fwnode_subdev(notifier,
+                                                           args.fwnode,
+                                                           sizeof(*asd));
+               if (IS_ERR(asd)) {
+                       ret = PTR_ERR(asd);
+                       /* not an error if asd already exists */
+                       if (ret == -EEXIST) {
+                               fwnode_handle_put(args.fwnode);
+                               continue;
+                       }
 
-               asd = kzalloc(sizeof(*asd), GFP_KERNEL);
-               if (!asd) {
-                       ret = -ENOMEM;
                        goto error;
                }
-
-               notifier->subdevs[notifier->num_subdevs] = asd;
-               asd->match.fwnode = args.fwnode;
-               asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-               notifier->num_subdevs++;
        }
 
        return 0;
@@ -738,9 +949,12 @@ error:
  *        -EINVAL if property parsing otherwise failed
  *        -ENOMEM if memory allocation failed
  */
-static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
-       struct fwnode_handle *fwnode, const char *prop, unsigned int index,
-       const char * const *props, unsigned int nprops)
+static struct fwnode_handle *
+v4l2_fwnode_reference_get_int_prop(struct fwnode_handle *fwnode,
+                                  const char *prop,
+                                  unsigned int index,
+                                  const char * const *props,
+                                  unsigned int nprops)
 {
        struct fwnode_reference_args fwnode_args;
        u64 *args = fwnode_args.args;
@@ -792,6 +1006,12 @@ static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
        return fwnode;
 }
 
+struct v4l2_fwnode_int_props {
+       const char *name;
+       const char * const *props;
+       unsigned int nprops;
+};
+
 /*
  * v4l2_fwnode_reference_parse_int_props - parse references for async
  *                                        sub-devices
@@ -815,13 +1035,17 @@ static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
  *        -EINVAL if property parsing otherwisefailed
  *        -ENOMEM if memory allocation failed
  */
-static int v4l2_fwnode_reference_parse_int_props(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       const char *prop, const char * const *props, unsigned int nprops)
+static int
+v4l2_fwnode_reference_parse_int_props(struct device *dev,
+                                     struct v4l2_async_notifier *notifier,
+                                     const struct v4l2_fwnode_int_props *p)
 {
        struct fwnode_handle *fwnode;
        unsigned int index;
        int ret;
+       const char *prop = p->name;
+       const char * const *props = p->props;
+       unsigned int nprops = p->nprops;
 
        index = 0;
        do {
@@ -843,31 +1067,26 @@ static int v4l2_fwnode_reference_parse_int_props(
                index++;
        } while (1);
 
-       ret = v4l2_async_notifier_realloc(notifier,
-                                         notifier->num_subdevs + index);
-       if (ret)
-               return -ENOMEM;
-
-       for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
-                                        dev_fwnode(dev), prop, index, props,
-                                        nprops))); index++) {
+       for (index = 0;
+            !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev),
+                                                                 prop, index,
+                                                                 props,
+                                                                 nprops)));
+            index++) {
                struct v4l2_async_subdev *asd;
 
-               if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
-                       ret = -EINVAL;
-                       goto error;
-               }
+               asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
+                                                           sizeof(*asd));
+               if (IS_ERR(asd)) {
+                       ret = PTR_ERR(asd);
+                       /* not an error if asd already exists */
+                       if (ret == -EEXIST) {
+                               fwnode_handle_put(fwnode);
+                               continue;
+                       }
 
-               asd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL);
-               if (!asd) {
-                       ret = -ENOMEM;
                        goto error;
                }
-
-               notifier->subdevs[notifier->num_subdevs] = asd;
-               asd->match.fwnode = fwnode;
-               asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-               notifier->num_subdevs++;
        }
 
        return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
@@ -877,15 +1096,11 @@ error:
        return ret;
 }
 
-int v4l2_async_notifier_parse_fwnode_sensor_common(
-       struct device *dev, struct v4l2_async_notifier *notifier)
+int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
+                                                  struct v4l2_async_notifier *notifier)
 {
        static const char * const led_props[] = { "led" };
-       static const struct {
-               const char *name;
-               const char * const *props;
-               unsigned int nprops;
-       } props[] = {
+       static const struct v4l2_fwnode_int_props props[] = {
                { "flash-leds", led_props, ARRAY_SIZE(led_props) },
                { "lens-focus", NULL, 0 },
        };
@@ -895,12 +1110,12 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(
                int ret;
 
                if (props[i].props && is_acpi_node(dev_fwnode(dev)))
-                       ret = v4l2_fwnode_reference_parse_int_props(
-                               dev, notifier, props[i].name,
-                               props[i].props, props[i].nprops);
+                       ret = v4l2_fwnode_reference_parse_int_props(dev,
+                                                                   notifier,
+                                                                   &props[i]);
                else
-                       ret = v4l2_fwnode_reference_parse(
-                               dev, notifier, props[i].name);
+                       ret = v4l2_fwnode_reference_parse(dev, notifier,
+                                                         props[i].name);
                if (ret && ret != -ENOENT) {
                        dev_warn(dev, "parsing property \"%s\" failed (%d)\n",
                                 props[i].name, ret);
@@ -924,6 +1139,8 @@ int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
        if (!notifier)
                return -ENOMEM;
 
+       v4l2_async_notifier_init(notifier);
+
        ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,
                                                             notifier);
        if (ret < 0)
@@ -952,6 +1169,68 @@ out_cleanup:
 }
 EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
 
+int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
+                                     size_t asd_struct_size,
+                                     unsigned int *ports,
+                                     unsigned int num_ports,
+                                     parse_endpoint_func parse_endpoint)
+{
+       struct v4l2_async_notifier *notifier;
+       struct device *dev = sd->dev;
+       struct fwnode_handle *fwnode;
+       int ret;
+
+       if (WARN_ON(!dev))
+               return -ENODEV;
+
+       fwnode = dev_fwnode(dev);
+       if (!fwnode_device_is_available(fwnode))
+               return -ENODEV;
+
+       notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
+       if (!notifier)
+               return -ENOMEM;
+
+       v4l2_async_notifier_init(notifier);
+
+       if (!ports) {
+               ret = v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier,
+                                                                asd_struct_size,
+                                                                parse_endpoint);
+               if (ret < 0)
+                       goto out_cleanup;
+       } else {
+               unsigned int i;
+
+               for (i = 0; i < num_ports; i++) {
+                       ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(dev, notifier, asd_struct_size, ports[i], parse_endpoint);
+                       if (ret < 0)
+                               goto out_cleanup;
+               }
+       }
+
+       ret = v4l2_async_subdev_notifier_register(sd, notifier);
+       if (ret < 0)
+               goto out_cleanup;
+
+       ret = v4l2_async_register_subdev(sd);
+       if (ret < 0)
+               goto out_unregister;
+
+       sd->subdev_notifier = notifier;
+
+       return 0;
+
+out_unregister:
+       v4l2_async_notifier_unregister(notifier);
+out_cleanup:
+       v4l2_async_notifier_cleanup(notifier);
+       kfree(notifier);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_register_fwnode_subdev);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
index 54afc9c7ee6ea162b96a83f44389ae98dc9293d1..c63746968fa3d714fcd6eaecd2f34d021503f08b 100644 (file)
@@ -121,7 +121,7 @@ int v4l2_video_std_construct(struct v4l2_standard *vs,
        vs->id = id;
        v4l2_video_std_frame_period(id, &vs->frameperiod);
        vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
-       strlcpy(vs->name, name, sizeof(vs->name));
+       strscpy(vs->name, name, sizeof(vs->name));
        return 0;
 }
 EXPORT_SYMBOL(v4l2_video_std_construct);
@@ -474,13 +474,13 @@ static void v4l_print_buffer(const void *arg, bool write_only)
        const struct v4l2_plane *plane;
        int i;
 
-       pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, field=%s, sequence=%d, memory=%s",
+       pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
                        p->timestamp.tv_sec / 3600,
                        (int)(p->timestamp.tv_sec / 60) % 60,
                        (int)(p->timestamp.tv_sec % 60),
                        (long)p->timestamp.tv_usec,
                        p->index,
-                       prt_names(p->type, v4l2_type_names),
+                       prt_names(p->type, v4l2_type_names), p->request_fd,
                        p->flags, prt_names(p->field, v4l2_field_names),
                        p->sequence, prt_names(p->memory, v4l2_memory_names));
 
@@ -590,8 +590,8 @@ static void v4l_print_ext_controls(const void *arg, bool write_only)
        const struct v4l2_ext_controls *p = arg;
        int i;
 
-       pr_cont("which=0x%x, count=%d, error_idx=%d",
-                       p->which, p->count, p->error_idx);
+       pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
+                       p->which, p->count, p->error_idx, p->request_fd);
        for (i = 0; i < p->count; i++) {
                if (!p->controls[i].size)
                        pr_cont(", id/val=0x%x/0x%x",
@@ -907,7 +907,7 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
        __u32 i;
 
        /* zero the reserved fields */
-       c->reserved[0] = c->reserved[1] = 0;
+       c->reserved[0] = 0;
        for (i = 0; i < c->count; i++)
                c->controls[i].reserved2[0] = 0;
 
@@ -1309,6 +1309,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
                case V4L2_PIX_FMT_H263:         descr = "H.263"; break;
                case V4L2_PIX_FMT_MPEG1:        descr = "MPEG-1 ES"; break;
                case V4L2_PIX_FMT_MPEG2:        descr = "MPEG-2 ES"; break;
+               case V4L2_PIX_FMT_MPEG2_SLICE:  descr = "MPEG-2 Parsed Slice Data"; break;
                case V4L2_PIX_FMT_MPEG4:        descr = "MPEG-4 part 2 ES"; break;
                case V4L2_PIX_FMT_XVID:         descr = "Xvid"; break;
                case V4L2_PIX_FMT_VC1_ANNEX_G:  descr = "VC-1 (SMPTE 412M Annex G)"; break;
@@ -1336,6 +1337,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
                case V4L2_PIX_FMT_SE401:        descr = "GSPCA SE401"; break;
                case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
                case V4L2_PIX_FMT_MT21C:        descr = "Mediatek Compressed Format"; break;
+               case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
                default:
                        WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
                        if (fmt->description[0])
@@ -1352,7 +1354,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
        }
 
        if (descr)
-               WARN_ON(strlcpy(fmt->description, descr, sz) >= sz);
+               WARN_ON(strscpy(fmt->description, descr, sz) >= sz);
        fmt->flags = flags;
 }
 
@@ -1877,7 +1879,7 @@ static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
        if (ret)
                return ret;
 
-       CLEAR_AFTER_FIELD(p, memory);
+       CLEAR_AFTER_FIELD(p, capabilities);
 
        return ops->vidioc_reqbufs(file, fh, p);
 }
@@ -1918,7 +1920,7 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
        if (ret)
                return ret;
 
-       CLEAR_AFTER_FIELD(create, format);
+       CLEAR_AFTER_FIELD(create, capabilities);
 
        v4l_sanitize_format(&create->format);
 
@@ -2109,9 +2111,9 @@ static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
 
        p->error_idx = p->count;
        if (vfh && vfh->ctrl_handler)
-               return v4l2_g_ext_ctrls(vfh->ctrl_handler, p);
+               return v4l2_g_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
        if (vfd->ctrl_handler)
-               return v4l2_g_ext_ctrls(vfd->ctrl_handler, p);
+               return v4l2_g_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
        if (ops->vidioc_g_ext_ctrls == NULL)
                return -ENOTTY;
        return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
@@ -2128,9 +2130,9 @@ static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
 
        p->error_idx = p->count;
        if (vfh && vfh->ctrl_handler)
-               return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p);
+               return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
        if (vfd->ctrl_handler)
-               return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p);
+               return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
        if (ops->vidioc_s_ext_ctrls == NULL)
                return -ENOTTY;
        return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
@@ -2147,9 +2149,9 @@ static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
 
        p->error_idx = p->count;
        if (vfh && vfh->ctrl_handler)
-               return v4l2_try_ext_ctrls(vfh->ctrl_handler, p);
+               return v4l2_try_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
        if (vfd->ctrl_handler)
-               return v4l2_try_ext_ctrls(vfd->ctrl_handler, p);
+               return v4l2_try_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
        if (ops->vidioc_try_ext_ctrls == NULL)
                return -ENOTTY;
        return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
@@ -2391,7 +2393,7 @@ static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
                        p->flags |= V4L2_CHIP_FL_WRITABLE;
                if (ops->vidioc_g_register)
                        p->flags |= V4L2_CHIP_FL_READABLE;
-               strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
+               strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
                if (ops->vidioc_g_chip_info)
                        return ops->vidioc_g_chip_info(file, fh, arg);
                if (p->match.addr)
@@ -2408,7 +2410,7 @@ static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
                                p->flags |= V4L2_CHIP_FL_WRITABLE;
                        if (sd->ops->core && sd->ops->core->g_register)
                                p->flags |= V4L2_CHIP_FL_READABLE;
-                       strlcpy(p->name, sd->name, sizeof(p->name));
+                       strscpy(p->name, sd->name, sizeof(p->name));
                        return 0;
                }
                break;
@@ -2780,6 +2782,7 @@ static long __video_do_ioctl(struct file *file,
                unsigned int cmd, void *arg)
 {
        struct video_device *vfd = video_devdata(file);
+       struct mutex *req_queue_lock = NULL;
        struct mutex *lock; /* ioctl serialization mutex */
        const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
        bool write_only = false;
@@ -2799,10 +2802,27 @@ static long __video_do_ioctl(struct file *file,
        if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
                vfh = file->private_data;
 
+       /*
+        * We need to serialize streamon/off with queueing new requests.
+        * These ioctls may trigger the cancellation of a streaming
+        * operation, and that should not be mixed with queueing a new
+        * request at the same time.
+        */
+       if (v4l2_device_supports_requests(vfd->v4l2_dev) &&
+           (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) {
+               req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex;
+
+               if (mutex_lock_interruptible(req_queue_lock))
+                       return -ERESTARTSYS;
+       }
+
        lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
 
-       if (lock && mutex_lock_interruptible(lock))
+       if (lock && mutex_lock_interruptible(lock)) {
+               if (req_queue_lock)
+                       mutex_unlock(req_queue_lock);
                return -ERESTARTSYS;
+       }
 
        if (!video_is_registered(vfd)) {
                ret = -ENODEV;
@@ -2861,6 +2881,8 @@ done:
 unlock:
        if (lock)
                mutex_unlock(lock);
+       if (req_queue_lock)
+               mutex_unlock(req_queue_lock);
        return ret;
 }
 
index 0fc185a2ce90e80acb8906aa248afbe50163fecf..014a2a97cadd87065247e0eeb678d086b3270104 100644 (file)
@@ -28,7 +28,7 @@ int v4l2_mc_create_media_graph(struct media_device *mdev)
        struct media_entity *io_v4l = NULL, *io_vbi = NULL, *io_swradio = NULL;
        bool is_webcam = false;
        u32 flags;
-       int ret;
+       int ret, pad_sink, pad_source;
 
        if (!mdev)
                return 0;
@@ -63,8 +63,10 @@ int v4l2_mc_create_media_graph(struct media_device *mdev)
        }
 
        /* It should have at least one I/O entity */
-       if (!io_v4l && !io_vbi && !io_swradio)
+       if (!io_v4l && !io_vbi && !io_swradio) {
+               dev_warn(mdev->dev, "Didn't find any I/O entity\n");
                return -EINVAL;
+       }
 
        /*
         * Here, webcams are modelled on a very simple way: the sensor is
@@ -74,8 +76,10 @@ int v4l2_mc_create_media_graph(struct media_device *mdev)
         * PC-consumer's hardware.
         */
        if (is_webcam) {
-               if (!io_v4l)
+               if (!io_v4l) {
+                       dev_warn(mdev->dev, "Didn't find a MEDIA_ENT_F_IO_V4L\n");
                        return -EINVAL;
+               }
 
                media_device_for_each_entity(entity, mdev) {
                        if (entity->function != MEDIA_ENT_F_CAM_SENSOR)
@@ -83,46 +87,91 @@ int v4l2_mc_create_media_graph(struct media_device *mdev)
                        ret = media_create_pad_link(entity, 0,
                                                    io_v4l, 0,
                                                    MEDIA_LNK_FL_ENABLED);
-                       if (ret)
+                       if (ret) {
+                               dev_warn(mdev->dev, "Failed to create a sensor link\n");
                                return ret;
+                       }
                }
                if (!decoder)
                        return 0;
        }
 
        /* The device isn't a webcam. So, it should have a decoder */
-       if (!decoder)
+       if (!decoder) {
+               dev_warn(mdev->dev, "Decoder not found\n");
                return -EINVAL;
+       }
 
        /* Link the tuner and IF video output pads */
        if (tuner) {
                if (if_vid) {
-                       ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT,
-                                                   if_vid,
-                                                   IF_VID_DEC_PAD_IF_INPUT,
+                       pad_source = media_get_pad_index(tuner, false,
+                                                        PAD_SIGNAL_ANALOG);
+                       pad_sink = media_get_pad_index(if_vid, true,
+                                                      PAD_SIGNAL_ANALOG);
+                       if (pad_source < 0 || pad_sink < 0) {
+                               dev_warn(mdev->dev, "Couldn't get tuner and/or PLL pad(s): (%d, %d)\n",
+                                        pad_source, pad_sink);
+                               return -EINVAL;
+                       }
+                       ret = media_create_pad_link(tuner, pad_source,
+                                                   if_vid, pad_sink,
                                                    MEDIA_LNK_FL_ENABLED);
-                       if (ret)
+                       if (ret) {
+                               dev_warn(mdev->dev, "Couldn't create tuner->PLL link)\n");
                                return ret;
-                       ret = media_create_pad_link(if_vid, IF_VID_DEC_PAD_OUT,
-                                               decoder, DEMOD_PAD_IF_INPUT,
-                                               MEDIA_LNK_FL_ENABLED);
-                       if (ret)
+                       }
+
+                       pad_source = media_get_pad_index(if_vid, false,
+                                                        PAD_SIGNAL_ANALOG);
+                       pad_sink = media_get_pad_index(decoder, true,
+                                                      PAD_SIGNAL_ANALOG);
+                       if (pad_source < 0 || pad_sink < 0) {
+                               dev_warn(mdev->dev, "get decoder and/or PLL pad(s): (%d, %d)\n",
+                                        pad_source, pad_sink);
+                               return -EINVAL;
+                       }
+                       ret = media_create_pad_link(if_vid, pad_source,
+                                                   decoder, pad_sink,
+                                                   MEDIA_LNK_FL_ENABLED);
+                       if (ret) {
+                               dev_warn(mdev->dev, "couldn't link PLL to decoder\n");
                                return ret;
+                       }
                } else {
-                       ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT,
-                                               decoder, DEMOD_PAD_IF_INPUT,
-                                               MEDIA_LNK_FL_ENABLED);
+                       pad_source = media_get_pad_index(tuner, false,
+                                                        PAD_SIGNAL_ANALOG);
+                       pad_sink = media_get_pad_index(decoder, true,
+                                                      PAD_SIGNAL_ANALOG);
+                       if (pad_source < 0 || pad_sink < 0) {
+                               dev_warn(mdev->dev, "couldn't get tuner and/or decoder pad(s): (%d, %d)\n",
+                                        pad_source, pad_sink);
+                               return -EINVAL;
+                       }
+                       ret = media_create_pad_link(tuner, pad_source,
+                                                   decoder, pad_sink,
+                                                   MEDIA_LNK_FL_ENABLED);
                        if (ret)
                                return ret;
                }
 
                if (if_aud) {
-                       ret = media_create_pad_link(tuner, TUNER_PAD_AUD_OUT,
-                                                   if_aud,
-                                                   IF_AUD_DEC_PAD_IF_INPUT,
+                       pad_source = media_get_pad_index(tuner, false,
+                                                        PAD_SIGNAL_AUDIO);
+                       pad_sink = media_get_pad_index(if_aud, true,
+                                                      PAD_SIGNAL_AUDIO);
+                       if (pad_source < 0 || pad_sink < 0) {
+                               dev_warn(mdev->dev, "couldn't get tuner and/or decoder pad(s) for audio: (%d, %d)\n",
+                                        pad_source, pad_sink);
+                               return -EINVAL;
+                       }
+                       ret = media_create_pad_link(tuner, pad_source,
+                                                   if_aud, pad_sink,
                                                    MEDIA_LNK_FL_ENABLED);
-                       if (ret)
+                       if (ret) {
+                               dev_warn(mdev->dev, "couldn't link tuner->audio PLL\n");
                                return ret;
+                       }
                } else {
                        if_aud = tuner;
                }
@@ -131,27 +180,48 @@ int v4l2_mc_create_media_graph(struct media_device *mdev)
 
        /* Create demod to V4L, VBI and SDR radio links */
        if (io_v4l) {
-               ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT,
-                                       io_v4l, 0,
-                                       MEDIA_LNK_FL_ENABLED);
-               if (ret)
+               pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV);
+               if (pad_source < 0) {
+                       dev_warn(mdev->dev, "couldn't get decoder output pad for V4L I/O\n");
+                       return -EINVAL;
+               }
+               ret = media_create_pad_link(decoder, pad_source,
+                                           io_v4l, 0,
+                                           MEDIA_LNK_FL_ENABLED);
+               if (ret) {
+                       dev_warn(mdev->dev, "couldn't link decoder output to V4L I/O\n");
                        return ret;
+               }
        }
 
        if (io_swradio) {
-               ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT,
-                                       io_swradio, 0,
-                                       MEDIA_LNK_FL_ENABLED);
-               if (ret)
+               pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV);
+               if (pad_source < 0) {
+                       dev_warn(mdev->dev, "couldn't get decoder output pad for SDR\n");
+                       return -EINVAL;
+               }
+               ret = media_create_pad_link(decoder, pad_source,
+                                           io_swradio, 0,
+                                           MEDIA_LNK_FL_ENABLED);
+               if (ret) {
+                       dev_warn(mdev->dev, "couldn't link decoder output to SDR\n");
                        return ret;
+               }
        }
 
        if (io_vbi) {
-               ret = media_create_pad_link(decoder, DEMOD_PAD_VBI_OUT,
+               pad_source = media_get_pad_index(decoder, false, PAD_SIGNAL_DV);
+               if (pad_source < 0) {
+                       dev_warn(mdev->dev, "couldn't get decoder output pad for VBI\n");
+                       return -EINVAL;
+               }
+               ret = media_create_pad_link(decoder, pad_source,
                                            io_vbi, 0,
                                            MEDIA_LNK_FL_ENABLED);
-               if (ret)
+               if (ret) {
+                       dev_warn(mdev->dev, "couldn't link decoder output to VBI\n");
                        return ret;
+               }
        }
 
        /* Create links for the media connectors */
@@ -161,15 +231,26 @@ int v4l2_mc_create_media_graph(struct media_device *mdev)
                case MEDIA_ENT_F_CONN_RF:
                        if (!tuner)
                                continue;
-
+                       pad_sink = media_get_pad_index(tuner, true,
+                                                      PAD_SIGNAL_ANALOG);
+                       if (pad_sink < 0) {
+                               dev_warn(mdev->dev, "couldn't get tuner analog pad sink\n");
+                               return -EINVAL;
+                       }
                        ret = media_create_pad_link(entity, 0, tuner,
-                                                   TUNER_PAD_RF_INPUT,
+                                                   pad_sink,
                                                    flags);
                        break;
                case MEDIA_ENT_F_CONN_SVIDEO:
                case MEDIA_ENT_F_CONN_COMPOSITE:
+                       pad_sink = media_get_pad_index(decoder, true,
+                                                      PAD_SIGNAL_ANALOG);
+                       if (pad_sink < 0) {
+                               dev_warn(mdev->dev, "couldn't get tuner analog pad sink\n");
+                               return -EINVAL;
+                       }
                        ret = media_create_pad_link(entity, 0, decoder,
-                                                   DEMOD_PAD_IF_INPUT,
+                                                   pad_sink,
                                                    flags);
                        break;
                default:
index ce9bd1b912102aeb1b89840872f2ea5f1add6a1a..d7806db222d83b87f39175fb53c06178d98b363e 100644 (file)
@@ -387,7 +387,7 @@ static void v4l2_m2m_cancel_job(struct v4l2_m2m_ctx *m2m_ctx)
                spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
                if (m2m_dev->m2m_ops->job_abort)
                        m2m_dev->m2m_ops->job_abort(m2m_ctx->priv);
-               dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx);
+               dprintk("m2m_ctx %p running, will wait to complete\n", m2m_ctx);
                wait_event(m2m_ctx->finished,
                                !(m2m_ctx->job_flags & TRANS_RUNNING));
        } else if (m2m_ctx->job_flags & TRANS_QUEUED) {
@@ -473,12 +473,19 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
 int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                  struct v4l2_buffer *buf)
 {
+       struct video_device *vdev = video_devdata(file);
        struct vb2_queue *vq;
        int ret;
 
        vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
-       ret = vb2_qbuf(vq, buf);
-       if (!ret)
+       if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&
+           (buf->flags & V4L2_BUF_FLAG_REQUEST_FD)) {
+               dprintk("%s: requests cannot be used with capture buffers\n",
+                       __func__);
+               return -EPERM;
+       }
+       ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf);
+       if (!ret && !(buf->flags & V4L2_BUF_FLAG_IN_REQUEST))
                v4l2_m2m_try_schedule(m2m_ctx);
 
        return ret;
@@ -498,15 +505,11 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
 int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                         struct v4l2_buffer *buf)
 {
+       struct video_device *vdev = video_devdata(file);
        struct vb2_queue *vq;
-       int ret;
 
        vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
-       ret = vb2_prepare_buf(vq, buf);
-       if (!ret)
-               v4l2_m2m_try_schedule(m2m_ctx);
-
-       return ret;
+       return vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf);
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf);
 
@@ -950,6 +953,52 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
 
+void vb2_m2m_request_queue(struct media_request *req)
+{
+       struct media_request_object *obj, *obj_safe;
+       struct v4l2_m2m_ctx *m2m_ctx = NULL;
+
+       /*
+        * Queue all objects. Note that buffer objects are at the end of the
+        * objects list, after all other object types. Once buffer objects
+        * are queued, the driver might delete them immediately (if the driver
+        * processes the buffer at once), so we have to use
+        * list_for_each_entry_safe() to handle the case where the object we
+        * queue is deleted.
+        */
+       list_for_each_entry_safe(obj, obj_safe, &req->objects, list) {
+               struct v4l2_m2m_ctx *m2m_ctx_obj;
+               struct vb2_buffer *vb;
+
+               if (!obj->ops->queue)
+                       continue;
+
+               if (vb2_request_object_is_buffer(obj)) {
+                       /* Sanity checks */
+                       vb = container_of(obj, struct vb2_buffer, req_obj);
+                       WARN_ON(!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type));
+                       m2m_ctx_obj = container_of(vb->vb2_queue,
+                                                  struct v4l2_m2m_ctx,
+                                                  out_q_ctx.q);
+                       WARN_ON(m2m_ctx && m2m_ctx_obj != m2m_ctx);
+                       m2m_ctx = m2m_ctx_obj;
+               }
+
+               /*
+                * The buffer we queue here can in theory be immediately
+                * unbound, hence the use of list_for_each_entry_safe()
+                * above and why we call the queue op last.
+                */
+               obj->ops->queue(obj);
+       }
+
+       WARN_ON(!m2m_ctx);
+
+       if (m2m_ctx)
+               v4l2_m2m_try_schedule(m2m_ctx);
+}
+EXPORT_SYMBOL_GPL(vb2_m2m_request_queue);
+
 /* Videobuf2 ioctl helpers */
 
 int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
index 2b63fa6b6fc9a7391b2c80846298b6282563e25e..f5f0d71ec74540323429d530fc3676404b43c009 100644 (file)
@@ -222,17 +222,20 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        case VIDIOC_G_EXT_CTRLS:
                if (!vfh->ctrl_handler)
                        return -ENOTTY;
-               return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg);
+               return v4l2_g_ext_ctrls(vfh->ctrl_handler,
+                                       sd->v4l2_dev->mdev, arg);
 
        case VIDIOC_S_EXT_CTRLS:
                if (!vfh->ctrl_handler)
                        return -ENOTTY;
-               return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg);
+               return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
+                                       sd->v4l2_dev->mdev, arg);
 
        case VIDIOC_TRY_EXT_CTRLS:
                if (!vfh->ctrl_handler)
                        return -ENOTTY;
-               return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg);
+               return v4l2_try_ext_ctrls(vfh->ctrl_handler,
+                                         sd->v4l2_dev->mdev, arg);
 
        case VIDIOC_DQEVENT:
                if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
@@ -273,7 +276,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                        p->flags |= V4L2_CHIP_FL_WRITABLE;
                if (sd->ops->core && sd->ops->core->g_register)
                        p->flags |= V4L2_CHIP_FL_READABLE;
-               strlcpy(p->name, sd->name, sizeof(p->name));
+               strscpy(p->name, sd->name, sizeof(p->name));
                return 0;
        }
 #endif
index b907865d4664db167a4931edb3479cf11069de70..c3748b414c27911e643d813b1d32281d3ef00a47 100644 (file)
@@ -327,8 +327,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
                return -EINVAL;
        }
 
-       ebid = devm_kzalloc(ebi->dev,
-                           sizeof(*ebid) + (numcs * sizeof(*ebid->configs)),
+       ebid = devm_kzalloc(ebi->dev, struct_size(ebid, configs, numcs),
                            GFP_KERNEL);
        if (!ebid)
                return -ENOMEM;
index 45e9453608c58dcf311dde45c55491f23d1e6c7d..978d836a02481fc12f8644a28f1067fca046b99c 100644 (file)
 
 #define CROS_EC_DEV_VERSION "1.0.0"
 
-/*
- * @offset: within EC_LPC_ADDR_MEMMAP region
- * @bytes: number of bytes to read. zero means "read a string" (including '\0')
- *         (at most only EC_MEMMAP_SIZE bytes can be read)
- * @buffer: where to store the result
- * ioctl returns the number of bytes read, negative on error
+/**
+ * struct cros_ec_readmem - Struct used to read mapped memory.
+ * @offset: Within EC_LPC_ADDR_MEMMAP region.
+ * @bytes: Number of bytes to read. Zero means "read a string" (including '\0')
+ *         At most only EC_MEMMAP_SIZE bytes can be read.
+ * @buffer: Where to store the result. The ioctl returns the number of bytes
+ *         read or negative on error.
  */
 struct cros_ec_readmem {
        uint32_t offset;
index 7e50e1d6f58c22b914f39ae7f5e419a53d689b37..636ed7149793b5c4eeac354a4415cb945a570c4a 100644 (file)
@@ -106,23 +106,6 @@ static unsigned int at24_write_timeout = 25;
 module_param_named(write_timeout, at24_write_timeout, uint, 0);
 MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
 
-/*
- * Both reads and writes fail if the previous write didn't complete yet. This
- * macro loops a few times waiting at least long enough for one entire page
- * write to work while making sure that at least one iteration is run before
- * checking the break condition.
- *
- * It takes two parameters: a variable in which the future timeout in jiffies
- * will be stored and a temporary variable holding the time of the last
- * iteration of processing the request. Both should be unsigned integers
- * holding at least 32 bits.
- */
-#define at24_loop_until_timeout(tout, op_time)                         \
-       for (tout = jiffies + msecs_to_jiffies(at24_write_timeout),     \
-            op_time = 0;                                               \
-            op_time ? time_before(op_time, tout) : true;               \
-            usleep_range(1000, 1500), op_time = jiffies)
-
 struct at24_chip_data {
        /*
         * these fields mirror their equivalents in
@@ -308,13 +291,22 @@ static ssize_t at24_regmap_read(struct at24_data *at24, char *buf,
        /* adjust offset for mac and serial read ops */
        offset += at24->offset_adj;
 
-       at24_loop_until_timeout(timeout, read_time) {
+       timeout = jiffies + msecs_to_jiffies(at24_write_timeout);
+       do {
+               /*
+                * The timestamp shall be taken before the actual operation
+                * to avoid a premature timeout in case of high CPU load.
+                */
+               read_time = jiffies;
+
                ret = regmap_bulk_read(regmap, offset, buf, count);
                dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
                        count, offset, ret, jiffies);
                if (!ret)
                        return count;
-       }
+
+               usleep_range(1000, 1500);
+       } while (time_before(read_time, timeout));
 
        return -ETIMEDOUT;
 }
@@ -358,14 +350,23 @@ static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf,
        regmap = at24_client->regmap;
        client = at24_client->client;
        count = at24_adjust_write_count(at24, offset, count);
+       timeout = jiffies + msecs_to_jiffies(at24_write_timeout);
+
+       do {
+               /*
+                * The timestamp shall be taken before the actual operation
+                * to avoid a premature timeout in case of high CPU load.
+                */
+               write_time = jiffies;
 
-       at24_loop_until_timeout(timeout, write_time) {
                ret = regmap_bulk_write(regmap, offset, buf, count);
                dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n",
                        count, offset, ret, jiffies);
                if (!ret)
                        return count;
-       }
+
+               usleep_range(1000, 1500);
+       } while (time_before(write_time, timeout));
 
        return -ETIMEDOUT;
 }
index fc15ec58230a0d8fdfa6a0ad8d34206ee2c95ec3..0d33cf0842add6c8dbb05022dc44b8563b762377 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/module.h>
 
 #include <uapi/linux/magic.h>
index a07e24970be4216f16df473c80dab72b516ab11c..11c5bad95226698ab2888f2ad971220a2c5df8e4 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
index 38fa60ddaf2ea0d2c8d3d0db15640c94035ae54b..28510e33924fbd7099f232a869c7715656eccc4e 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/netdevice.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/io.h>
 
 #include "arcdevice.h"
index 4e56aaf2b9843cb633a10cf93c0a4242b270ce8f..2c546013a98014b4c83b759d293ed24f91b3c940 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
index 13ebb16be64e7bfe16669b0a9701f9e424914af3..d023cf303d56c3a557881a55818b9ee424e74162 100644 (file)
@@ -16,6 +16,7 @@
 
 #define pr_fmt(fmt)    "OF: " fmt
 
+#include <linux/bitmap.h>
 #include <linux/console.h>
 #include <linux/ctype.h>
 #include <linux/cpu.h>
@@ -1985,6 +1986,59 @@ int of_alias_get_id(struct device_node *np, const char *stem)
 }
 EXPORT_SYMBOL_GPL(of_alias_get_id);
 
+/**
+ * of_alias_get_alias_list - Get alias list for the given device driver
+ * @matches:   Array of OF device match structures to search in
+ * @stem:      Alias stem of the given device_node
+ * @bitmap:    Bitmap field pointer
+ * @nbits:     Maximum number of alias IDs which can be recorded in bitmap
+ *
+ * The function travels the lookup table to record alias ids for the given
+ * device match structures and alias stem.
+ *
+ * Return:     0 or -ENOSYS when !CONFIG_OF or
+ *             -EOVERFLOW if alias ID is greater then allocated nbits
+ */
+int of_alias_get_alias_list(const struct of_device_id *matches,
+                            const char *stem, unsigned long *bitmap,
+                            unsigned int nbits)
+{
+       struct alias_prop *app;
+       int ret = 0;
+
+       /* Zero bitmap field to make sure that all the time it is clean */
+       bitmap_zero(bitmap, nbits);
+
+       mutex_lock(&of_mutex);
+       pr_debug("%s: Looking for stem: %s\n", __func__, stem);
+       list_for_each_entry(app, &aliases_lookup, link) {
+               pr_debug("%s: stem: %s, id: %d\n",
+                        __func__, app->stem, app->id);
+
+               if (strcmp(app->stem, stem) != 0) {
+                       pr_debug("%s: stem comparison didn't pass %s\n",
+                                __func__, app->stem);
+                       continue;
+               }
+
+               if (of_match_node(matches, app->np)) {
+                       pr_debug("%s: Allocated ID %d\n", __func__, app->id);
+
+                       if (app->id >= nbits) {
+                               pr_warn("%s: ID %d >= than bitmap field %d\n",
+                                       __func__, app->id, nbits);
+                               ret = -EOVERFLOW;
+                       } else {
+                               set_bit(app->id, bitmap);
+                       }
+               }
+       }
+       mutex_unlock(&of_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(of_alias_get_alias_list);
+
 /**
  * of_alias_get_highest_id - Get highest alias id for the given stem
  * @stem:      Alias stem to be examined
index 76c83c1ffeda9368c4d464e486d3a1d529fbf15b..bb532aae0d92a080a0b9e9eb4369267b34af4710 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/crc32.h>
 #include <linux/kernel.h>
 #include <linux/initrd.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
@@ -1115,7 +1114,6 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
        return 1;
 }
 
-#ifdef CONFIG_HAVE_MEMBLOCK
 #ifndef MIN_MEMBLOCK_ADDR
 #define MIN_MEMBLOCK_ADDR      __pa(PAGE_OFFSET)
 #endif
@@ -1178,29 +1176,9 @@ int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
        return memblock_reserve(base, size);
 }
 
-#else
-void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
-{
-       WARN_ON(1);
-}
-
-int __init __weak early_init_dt_mark_hotplug_memory_arch(u64 base, u64 size)
-{
-       return -ENOSYS;
-}
-
-int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
-                                       phys_addr_t size, bool nomap)
-{
-       pr_err("Reserved memory not supported, ignoring range %pa - %pa%s\n",
-                 &base, &size, nomap ? " (nomap)" : "");
-       return -ENOSYS;
-}
-#endif
-
 static void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
 {
-       return memblock_virt_alloc(size, align);
+       return memblock_alloc(size, align);
 }
 
 bool __init early_init_dt_verify(void *params)
index 895c83e0c7b6c4c816b1aad72c67e2a1a5235a88..1977ee0adcb1b46b730d26e8a82fad93ce25beb8 100644 (file)
 #include <linux/of_reserved_mem.h>
 #include <linux/sort.h>
 #include <linux/slab.h>
+#include <linux/memblock.h>
 
 #define MAX_RESERVED_REGIONS   32
 static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
 static int reserved_mem_count;
 
-#if defined(CONFIG_HAVE_MEMBLOCK)
-#include <linux/memblock.h>
 int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
        phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
        phys_addr_t *res_base)
@@ -37,6 +36,7 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
         * panic()s on allocation failure.
         */
        end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
+       align = !align ? SMP_CACHE_BYTES : align;
        base = __memblock_alloc_base(size, align, end);
        if (!base)
                return -ENOMEM;
@@ -54,16 +54,6 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
                return memblock_remove(base, size);
        return 0;
 }
-#else
-int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
-       phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
-       phys_addr_t *res_base)
-{
-       pr_err("Reserved memory not supported, ignoring region 0x%llx%s\n",
-                 size, nomap ? " (nomap)" : "");
-       return -ENOSYS;
-}
-#endif
 
 /**
  * res_mem_save_node() - save fdt node for second pass initialization
index a3a6866765f25a00a97efb4ec6db25e0483b16fc..49ae2aa744d62207d57442d1d099e05c8869362b 100644 (file)
@@ -5,7 +5,7 @@
 
 #define pr_fmt(fmt) "### dt-test ### " fmt
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/errno.h>
@@ -2192,7 +2192,7 @@ static struct device_node *overlay_base_root;
 
 static void * __init dt_alloc_memory(u64 size, u64 align)
 {
-       return memblock_virt_alloc(size, align);
+       return memblock_alloc(size, align);
 }
 
 /*
index 1e81f8144c0d6f2e36027863df7e3dab2ec0d2f6..ce259ec9f990078302041523f654c4f638c754bf 100644 (file)
@@ -99,7 +99,7 @@ static const struct acpi_device_id chromeos_tbmc_acpi_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, chromeos_tbmc_acpi_device_ids);
 
-static const SIMPLE_DEV_PM_OPS(chromeos_tbmc_pm_ops, NULL,
+static SIMPLE_DEV_PM_OPS(chromeos_tbmc_pm_ops, NULL,
                chromeos_tbmc_resume);
 
 static struct acpi_driver chromeos_tbmc_driver = {
index 31c8b8c49e458f5be62b9aec0dbedd436785f84c..e1b75775cd4a12867b1b3b4566140605564c7085 100644 (file)
 #include <linux/dmi.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
 #include <linux/mfd/cros_ec.h>
 #include <linux/mfd/cros_ec_commands.h>
-#include <linux/mfd/cros_ec_lpc_reg.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/printk.h>
 #include <linux/suspend.h>
 
+#include "cros_ec_lpc_reg.h"
+
 #define DRV_NAME "cros_ec_lpcs"
 #define ACPI_DRV_NAME "GOOG0004"
 
@@ -248,7 +250,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
        acpi_status status;
        struct cros_ec_device *ec_dev;
        u8 buf[2];
-       int ret;
+       int irq, ret;
 
        if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE,
                                 dev_name(dev))) {
@@ -287,6 +289,18 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
                           sizeof(struct ec_response_get_protocol_info);
        ec_dev->dout_size = sizeof(struct ec_host_request);
 
+       /*
+        * Some boards do not have an IRQ allotted for cros_ec_lpc,
+        * which makes ENXIO an expected (and safe) scenario.
+        */
+       irq = platform_get_irq(pdev, 0);
+       if (irq > 0)
+               ec_dev->irq = irq;
+       else if (irq != -ENXIO) {
+               dev_err(dev, "couldn't retrieve IRQ number (%d)\n", irq);
+               return irq;
+       }
+
        ret = cros_ec_register(ec_dev);
        if (ret) {
                dev_err(dev, "couldn't register ec_dev (%d)\n", ret);
index 2eda2c2fc210fb3dc95d147b75012fb7a013b4bf..c4edfa83e493062fcd65363e4733387562211ef5 100644 (file)
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/mfd/cros_ec_commands.h>
-#include <linux/mfd/cros_ec_lpc_mec.h>
 #include <linux/mutex.h>
 #include <linux/types.h>
 
+#include "cros_ec_lpc_mec.h"
+
 /*
  * This mutex must be held while accessing the EMI unit. We can't rely on the
  * EC mutex because memmap data may be accessed without it being held.
diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.h b/drivers/platform/chrome/cros_ec_lpc_mec.h
new file mode 100644 (file)
index 0000000..105068c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * cros_ec_lpc_mec - LPC variant I/O for Microchip EC
+ *
+ * Copyright (C) 2016 Google, Inc
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This driver uses the Chrome OS EC byte-level message-based protocol for
+ * communicating the keyboard state (which keys are pressed) from a keyboard EC
+ * to the AP over some bus (such as i2c, lpc, spi).  The EC does debouncing,
+ * but everything else (including deghosting) is done here.  The main
+ * motivation for this is to keep the EC firmware as simple as possible, since
+ * it cannot be easily upgraded and EC flash/IRAM space is relatively
+ * expensive.
+ */
+
+#ifndef __CROS_EC_LPC_MEC_H
+#define __CROS_EC_LPC_MEC_H
+
+#include <linux/mfd/cros_ec_commands.h>
+
+enum cros_ec_lpc_mec_emi_access_mode {
+       /* 8-bit access */
+       ACCESS_TYPE_BYTE = 0x0,
+       /* 16-bit access */
+       ACCESS_TYPE_WORD = 0x1,
+       /* 32-bit access */
+       ACCESS_TYPE_LONG = 0x2,
+       /*
+        * 32-bit access, read or write of MEC_EMI_EC_DATA_B3 causes the
+        * EC data register to be incremented.
+        */
+       ACCESS_TYPE_LONG_AUTO_INCREMENT = 0x3,
+};
+
+enum cros_ec_lpc_mec_io_type {
+       MEC_IO_READ,
+       MEC_IO_WRITE,
+};
+
+/* Access IO ranges 0x800 thru 0x9ff using EMI interface instead of LPC */
+#define MEC_EMI_RANGE_START EC_HOST_CMD_REGION0
+#define MEC_EMI_RANGE_END   (EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE)
+
+/* EMI registers are relative to base */
+#define MEC_EMI_BASE 0x800
+#define MEC_EMI_HOST_TO_EC (MEC_EMI_BASE + 0)
+#define MEC_EMI_EC_TO_HOST (MEC_EMI_BASE + 1)
+#define MEC_EMI_EC_ADDRESS_B0 (MEC_EMI_BASE + 2)
+#define MEC_EMI_EC_ADDRESS_B1 (MEC_EMI_BASE + 3)
+#define MEC_EMI_EC_DATA_B0 (MEC_EMI_BASE + 4)
+#define MEC_EMI_EC_DATA_B1 (MEC_EMI_BASE + 5)
+#define MEC_EMI_EC_DATA_B2 (MEC_EMI_BASE + 6)
+#define MEC_EMI_EC_DATA_B3 (MEC_EMI_BASE + 7)
+
+/*
+ * cros_ec_lpc_mec_init
+ *
+ * Initialize MEC I/O.
+ */
+void cros_ec_lpc_mec_init(void);
+
+/*
+ * cros_ec_lpc_mec_destroy
+ *
+ * Cleanup MEC I/O.
+ */
+void cros_ec_lpc_mec_destroy(void);
+
+/**
+ * cros_ec_lpc_io_bytes_mec - Read / write bytes to MEC EMI port
+ *
+ * @io_type: MEC_IO_READ or MEC_IO_WRITE, depending on request
+ * @offset:  Base read / write address
+ * @length:  Number of bytes to read / write
+ * @buf:     Destination / source buffer
+ *
+ * @return 8-bit checksum of all bytes read / written
+ */
+u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
+                           unsigned int offset, unsigned int length, u8 *buf);
+
+#endif /* __CROS_EC_LPC_MEC_H */
index dcc7a3e30604bb60ffc3a550efa7877e01998921..fc23d535c404e32c773faf0e61a854d0fa4eeaaa 100644 (file)
@@ -24,7 +24,8 @@
 #include <linux/io.h>
 #include <linux/mfd/cros_ec.h>
 #include <linux/mfd/cros_ec_commands.h>
-#include <linux/mfd/cros_ec_lpc_mec.h>
+
+#include "cros_ec_lpc_mec.h"
 
 static u8 lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest)
 {
diff --git a/drivers/platform/chrome/cros_ec_lpc_reg.h b/drivers/platform/chrome/cros_ec_lpc_reg.h
new file mode 100644 (file)
index 0000000..1c12c38
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * cros_ec_lpc_reg - LPC access to the Chrome OS Embedded Controller
+ *
+ * Copyright (C) 2016 Google, Inc
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This driver uses the Chrome OS EC byte-level message-based protocol for
+ * communicating the keyboard state (which keys are pressed) from a keyboard EC
+ * to the AP over some bus (such as i2c, lpc, spi).  The EC does debouncing,
+ * but everything else (including deghosting) is done here.  The main
+ * motivation for this is to keep the EC firmware as simple as possible, since
+ * it cannot be easily upgraded and EC flash/IRAM space is relatively
+ * expensive.
+ */
+
+#ifndef __CROS_EC_LPC_REG_H
+#define __CROS_EC_LPC_REG_H
+
+/**
+ * cros_ec_lpc_read_bytes - Read bytes from a given LPC-mapped address.
+ * Returns 8-bit checksum of all bytes read.
+ *
+ * @offset: Base read address
+ * @length: Number of bytes to read
+ * @dest: Destination buffer
+ */
+u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest);
+
+/**
+ * cros_ec_lpc_write_bytes - Write bytes to a given LPC-mapped address.
+ * Returns 8-bit checksum of all bytes written.
+ *
+ * @offset: Base write address
+ * @length: Number of bytes to write
+ * @msg: Write data buffer
+ */
+u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, u8 *msg);
+
+/**
+ * cros_ec_lpc_reg_init
+ *
+ * Initialize register I/O.
+ */
+void cros_ec_lpc_reg_init(void);
+
+/**
+ * cros_ec_lpc_reg_destroy
+ *
+ * Cleanup reg I/O.
+ */
+void cros_ec_lpc_reg_destroy(void);
+
+#endif /* __CROS_EC_LPC_REG_H */
index bdac939de223c9242385bfd77c23a343258fc687..54f6a40c75c69c667ac3d4591dde89fd99bac3be 100644 (file)
@@ -60,7 +60,10 @@ config ACERHDF
 
          After loading this driver the BIOS is still in control of the fan.
          To let the kernel handle the fan, do:
-         echo -n enabled > /sys/class/thermal/thermal_zone0/mode
+         echo -n enabled > /sys/class/thermal/thermal_zoneN/mode
+         where N=0,1,2... depending on the number of thermal nodes and the
+         detection order of your particular system.  The "type" parameter
+         in the same node directory will tell you if it is "acerhdf".
 
          For more information about this driver see
          <http://piie.net/files/acerhdf_README.txt>
@@ -105,6 +108,22 @@ config ASUS_LAPTOP
 
          If you have an ACPI-compatible ASUS laptop, say Y or M here.
 
+config DCDBAS
+       tristate "Dell Systems Management Base Driver"
+       depends on X86
+       help
+         The Dell Systems Management Base Driver provides a sysfs interface
+         for systems management software to perform System Management
+         Interrupts (SMIs) and Host Control Actions (system power cycle or
+         power off after OS shutdown) on certain Dell systems.
+
+         See <file:Documentation/dcdbas.txt> for more details on the driver
+         and the Dell systems on which Dell systems management software makes
+         use of this driver.
+
+         Say Y or M here to enable the driver for use by Dell systems
+         management software such as Dell OpenManage.
+
 #
 # The DELL_SMBIOS driver depends on ACPI_WMI and/or DCDBAS if those
 # backends are selected. The "depends" line prevents a configuration
@@ -227,6 +246,18 @@ config DELL_RBTN
          To compile this driver as a module, choose M here: the module will
          be called dell-rbtn.
 
+config DELL_RBU
+       tristate "BIOS update support for DELL systems via sysfs"
+       depends on X86
+       select FW_LOADER
+       select FW_LOADER_USER_HELPER
+       help
+        Say m if you want to have the option of updating the BIOS for your
+        DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
+        supporting application to communicate with the BIOS regarding the new
+        image for the image update to take effect.
+        See <file:Documentation/dell_rbu.txt> for more details on the driver.
+
 
 config FUJITSU_LAPTOP
        tristate "Fujitsu Laptop Extras"
@@ -336,6 +367,20 @@ config HP_WMI
         To compile this driver as a module, choose M here: the module will
         be called hp-wmi.
 
+config LG_LAPTOP
+       tristate "LG Laptop Extras"
+       depends on ACPI
+       depends on ACPI_WMI
+       depends on INPUT
+       select INPUT_SPARSEKMAP
+       select LEDS_CLASS
+       help
+        This driver adds support for hotkeys as well as control of keyboard
+        backlight, battery maximum charge level and various other ACPI
+        features.
+
+        If you have an LG Gram laptop, say Y or M here.
+
 config MSI_LAPTOP
        tristate "MSI Laptop Extras"
        depends on ACPI
@@ -1231,6 +1276,18 @@ config I2C_MULTI_INSTANTIATE
          To compile this driver as a module, choose M here: the module
          will be called i2c-multi-instantiate.
 
+config INTEL_ATOMISP2_PM
+       tristate "Intel AtomISP2 dummy / power-management driver"
+       depends on PCI && IOSF_MBI && PM
+       help
+         Power-management driver for Intel's Image Signal Processor found on
+         Bay and Cherry Trail devices. This dummy driver's sole purpose is to
+         turn the ISP off (put it in D3) to save power and to allow entering
+         of S0ix modes.
+
+         To compile this driver as a module, choose M here: the module
+         will be called intel_atomisp2_pm.
+
 endif # X86_PLATFORM_DEVICES
 
 config PMC_ATOM
index e6d1becf81ce8c6bd526e196b8c167576d0f5c6f..39ae94135406b69bb7cef9bcb8d24242382afe35 100644 (file)
@@ -9,9 +9,11 @@ obj-$(CONFIG_ASUS_NB_WMI)      += asus-nb-wmi.o
 obj-$(CONFIG_ASUS_WIRELESS)    += asus-wireless.o
 obj-$(CONFIG_EEEPC_LAPTOP)     += eeepc-laptop.o
 obj-$(CONFIG_EEEPC_WMI)                += eeepc-wmi.o
+obj-$(CONFIG_LG_LAPTOP)                += lg-laptop.o
 obj-$(CONFIG_MSI_LAPTOP)       += msi-laptop.o
 obj-$(CONFIG_ACPI_CMPC)                += classmate-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)    += compal-laptop.o
+obj-$(CONFIG_DCDBAS)           += dcdbas.o
 obj-$(CONFIG_DELL_SMBIOS)      += dell-smbios.o
 dell-smbios-objs               := dell-smbios-base.o
 dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)  += dell-smbios-wmi.o
@@ -23,6 +25,7 @@ obj-$(CONFIG_DELL_WMI_AIO)    += dell-wmi-aio.o
 obj-$(CONFIG_DELL_WMI_LED)     += dell-wmi-led.o
 obj-$(CONFIG_DELL_SMO8800)     += dell-smo8800.o
 obj-$(CONFIG_DELL_RBTN)                += dell-rbtn.o
+obj-$(CONFIG_DELL_RBU)          += dell_rbu.o
 obj-$(CONFIG_ACER_WMI)         += acer-wmi.o
 obj-$(CONFIG_ACER_WIRELESS)    += acer-wireless.o
 obj-$(CONFIG_ACERHDF)          += acerhdf.o
@@ -92,3 +95,4 @@ obj-$(CONFIG_MLX_PLATFORM)    += mlx-platform.o
 obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
 obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN)    += intel_chtdc_ti_pwrbtn.o
 obj-$(CONFIG_I2C_MULTI_INSTANTIATE)    += i2c-multi-instantiate.o
+obj-$(CONFIG_INTEL_ATOMISP2_PM)        += intel_atomisp2_pm.o
index ea22591ee66feb9c08d8a831cbb822d8b9ab7591..50522422537886c26c849af01b18694be049387b 100644 (file)
@@ -86,6 +86,7 @@ static unsigned int interval = 10;
 static unsigned int fanon = 60000;
 static unsigned int fanoff = 53000;
 static unsigned int verbose;
+static unsigned int list_supported;
 static unsigned int fanstate = ACERHDF_FAN_AUTO;
 static char force_bios[16];
 static char force_product[16];
@@ -104,10 +105,12 @@ module_param(fanoff, uint, 0600);
 MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature");
 module_param(verbose, uint, 0600);
 MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
+module_param(list_supported, uint, 0600);
+MODULE_PARM_DESC(list_supported, "List supported models and BIOS versions");
 module_param_string(force_bios, force_bios, 16, 0);
-MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check");
+MODULE_PARM_DESC(force_bios, "Pretend system has this known supported BIOS version");
 module_param_string(force_product, force_product, 16, 0);
-MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check");
+MODULE_PARM_DESC(force_product, "Pretend system is this known supported model");
 
 /*
  * cmd_off: to switch the fan completely off and check if the fan is off
@@ -130,7 +133,7 @@ static const struct manualcmd mcmd = {
        .moff = 0xff,
 };
 
-/* BIOS settings */
+/* BIOS settings - only used during probe */
 struct bios_settings {
        const char *vendor;
        const char *product;
@@ -141,8 +144,18 @@ struct bios_settings {
        int mcmd_enable;
 };
 
+/* This could be a daughter struct in the above, but not worth the redirect */
+struct ctrl_settings {
+       u8 fanreg;
+       u8 tempreg;
+       struct fancmd cmd;
+       int mcmd_enable;
+};
+
+static struct ctrl_settings ctrl_cfg __read_mostly;
+
 /* Register addresses and values for different BIOS versions */
-static const struct bios_settings bios_tbl[] = {
+static const struct bios_settings bios_tbl[] __initconst = {
        /* AOA110 */
        {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0},
        {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0},
@@ -233,6 +246,7 @@ static const struct bios_settings bios_tbl[] = {
        {"Gateway", "LT31",   "v1.3201",  0x55, 0x58, {0x9e, 0x00}, 0},
        {"Gateway", "LT31",   "v1.3302",  0x55, 0x58, {0x9e, 0x00}, 0},
        {"Gateway", "LT31",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0},
+       {"Gateway", "LT31",   "v1.3307",  0x55, 0x58, {0x9e, 0x00}, 0},
        /* Packard Bell */
        {"Packard Bell", "DOA150",  "v0.3104",  0x55, 0x58, {0x21, 0x00}, 0},
        {"Packard Bell", "DOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00}, 0},
@@ -256,8 +270,6 @@ static const struct bios_settings bios_tbl[] = {
        {"", "", "", 0, 0, {0, 0}, 0}
 };
 
-static const struct bios_settings *bios_cfg __read_mostly;
-
 /*
  * this struct is used to instruct thermal layer to use bang_bang instead of
  * default governor for acerhdf
@@ -270,7 +282,7 @@ static int acerhdf_get_temp(int *temp)
 {
        u8 read_temp;
 
-       if (ec_read(bios_cfg->tempreg, &read_temp))
+       if (ec_read(ctrl_cfg.tempreg, &read_temp))
                return -EINVAL;
 
        *temp = read_temp * 1000;
@@ -282,10 +294,10 @@ static int acerhdf_get_fanstate(int *state)
 {
        u8 fan;
 
-       if (ec_read(bios_cfg->fanreg, &fan))
+       if (ec_read(ctrl_cfg.fanreg, &fan))
                return -EINVAL;
 
-       if (fan != bios_cfg->cmd.cmd_off)
+       if (fan != ctrl_cfg.cmd.cmd_off)
                *state = ACERHDF_FAN_AUTO;
        else
                *state = ACERHDF_FAN_OFF;
@@ -306,13 +318,13 @@ static void acerhdf_change_fanstate(int state)
                state = ACERHDF_FAN_AUTO;
        }
 
-       cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off
-                                        : bios_cfg->cmd.cmd_auto;
+       cmd = (state == ACERHDF_FAN_OFF) ? ctrl_cfg.cmd.cmd_off
+                                        : ctrl_cfg.cmd.cmd_auto;
        fanstate = state;
 
-       ec_write(bios_cfg->fanreg, cmd);
+       ec_write(ctrl_cfg.fanreg, cmd);
 
-       if (bios_cfg->mcmd_enable && state == ACERHDF_FAN_OFF) {
+       if (ctrl_cfg.mcmd_enable && state == ACERHDF_FAN_OFF) {
                if (verbose)
                        pr_notice("turning off fan manually\n");
                ec_write(mcmd.mreg, mcmd.moff);
@@ -615,10 +627,11 @@ static int str_starts_with(const char *str, const char *start)
 }
 
 /* check hardware */
-static int acerhdf_check_hardware(void)
+static int __init acerhdf_check_hardware(void)
 {
        char const *vendor, *version, *product;
        const struct bios_settings *bt = NULL;
+       int found = 0;
 
        /* get BIOS data */
        vendor  = dmi_get_system_info(DMI_SYS_VENDOR);
@@ -632,6 +645,17 @@ static int acerhdf_check_hardware(void)
 
        pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER);
 
+       if (list_supported) {
+               pr_info("List of supported Manufacturer/Model/BIOS:\n");
+               pr_info("---------------------------------------------------\n");
+               for (bt = bios_tbl; bt->vendor[0]; bt++) {
+                       pr_info("%-13s | %-17s | %-10s\n", bt->vendor,
+                               bt->product, bt->version);
+               }
+               pr_info("---------------------------------------------------\n");
+               return -ECANCELED;
+       }
+
        if (force_bios[0]) {
                version = force_bios;
                pr_info("forcing BIOS version: %s\n", version);
@@ -657,30 +681,36 @@ static int acerhdf_check_hardware(void)
                if (str_starts_with(vendor, bt->vendor) &&
                                str_starts_with(product, bt->product) &&
                                str_starts_with(version, bt->version)) {
-                       bios_cfg = bt;
+                       found = 1;
                        break;
                }
        }
 
-       if (!bios_cfg) {
+       if (!found) {
                pr_err("unknown (unsupported) BIOS version %s/%s/%s, please report, aborting!\n",
                       vendor, product, version);
                return -EINVAL;
        }
 
+       /* Copy control settings from BIOS table before we free it. */
+       ctrl_cfg.fanreg = bt->fanreg;
+       ctrl_cfg.tempreg = bt->tempreg;
+       memcpy(&ctrl_cfg.cmd, &bt->cmd, sizeof(struct fancmd));
+       ctrl_cfg.mcmd_enable = bt->mcmd_enable;
+
        /*
         * if started with kernel mode off, prevent the kernel from switching
         * off the fan
         */
        if (!kernelmode) {
                pr_notice("Fan control off, to enable do:\n");
-               pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zone0/mode\n");
+               pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zoneN/mode # N=0,1,2...\n");
        }
 
        return 0;
 }
 
-static int acerhdf_register_platform(void)
+static int __init acerhdf_register_platform(void)
 {
        int err = 0;
 
@@ -712,7 +742,7 @@ static void acerhdf_unregister_platform(void)
        platform_driver_unregister(&acerhdf_driver);
 }
 
-static int acerhdf_register_thermal(void)
+static int __init acerhdf_register_thermal(void)
 {
        cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL,
                                                 &acerhdf_cooling_ops);
index 93ee2d5466f8092978f57bf74ca84ee9c3cc1cc8..c285a16675ee7d912280028bf5f94c552fad6371 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/platform_data/x86/asus-wmi.h>
 #include <linux/platform_device.h>
 #include <linux/thermal.h>
 #include <linux/acpi.h>
@@ -69,89 +70,6 @@ MODULE_LICENSE("GPL");
 #define NOTIFY_KBD_BRTDWN              0xc5
 #define NOTIFY_KBD_BRTTOGGLE           0xc7
 
-/* WMI Methods */
-#define ASUS_WMI_METHODID_SPEC         0x43455053 /* BIOS SPECification */
-#define ASUS_WMI_METHODID_SFBD         0x44424653 /* Set First Boot Device */
-#define ASUS_WMI_METHODID_GLCD         0x44434C47 /* Get LCD status */
-#define ASUS_WMI_METHODID_GPID         0x44495047 /* Get Panel ID?? (Resol) */
-#define ASUS_WMI_METHODID_QMOD         0x444F4D51 /* Quiet MODe */
-#define ASUS_WMI_METHODID_SPLV         0x4C425053 /* Set Panel Light Value */
-#define ASUS_WMI_METHODID_AGFN         0x4E464741 /* FaN? */
-#define ASUS_WMI_METHODID_SFUN         0x4E554653 /* FUNCtionalities */
-#define ASUS_WMI_METHODID_SDSP         0x50534453 /* Set DiSPlay output */
-#define ASUS_WMI_METHODID_GDSP         0x50534447 /* Get DiSPlay output */
-#define ASUS_WMI_METHODID_DEVP         0x50564544 /* DEVice Policy */
-#define ASUS_WMI_METHODID_OSVR         0x5256534F /* OS VeRsion */
-#define ASUS_WMI_METHODID_DSTS         0x53544344 /* Device STatuS */
-#define ASUS_WMI_METHODID_DSTS2                0x53545344 /* Device STatuS #2*/
-#define ASUS_WMI_METHODID_BSTS         0x53545342 /* Bios STatuS ? */
-#define ASUS_WMI_METHODID_DEVS         0x53564544 /* DEVice Set */
-#define ASUS_WMI_METHODID_CFVS         0x53564643 /* CPU Frequency Volt Set */
-#define ASUS_WMI_METHODID_KBFT         0x5446424B /* KeyBoard FilTer */
-#define ASUS_WMI_METHODID_INIT         0x54494E49 /* INITialize */
-#define ASUS_WMI_METHODID_HKEY         0x59454B48 /* Hot KEY ?? */
-
-#define ASUS_WMI_UNSUPPORTED_METHOD    0xFFFFFFFE
-
-/* Wireless */
-#define ASUS_WMI_DEVID_HW_SWITCH       0x00010001
-#define ASUS_WMI_DEVID_WIRELESS_LED    0x00010002
-#define ASUS_WMI_DEVID_CWAP            0x00010003
-#define ASUS_WMI_DEVID_WLAN            0x00010011
-#define ASUS_WMI_DEVID_WLAN_LED                0x00010012
-#define ASUS_WMI_DEVID_BLUETOOTH       0x00010013
-#define ASUS_WMI_DEVID_GPS             0x00010015
-#define ASUS_WMI_DEVID_WIMAX           0x00010017
-#define ASUS_WMI_DEVID_WWAN3G          0x00010019
-#define ASUS_WMI_DEVID_UWB             0x00010021
-
-/* Leds */
-/* 0x000200XX and 0x000400XX */
-#define ASUS_WMI_DEVID_LED1            0x00020011
-#define ASUS_WMI_DEVID_LED2            0x00020012
-#define ASUS_WMI_DEVID_LED3            0x00020013
-#define ASUS_WMI_DEVID_LED4            0x00020014
-#define ASUS_WMI_DEVID_LED5            0x00020015
-#define ASUS_WMI_DEVID_LED6            0x00020016
-
-/* Backlight and Brightness */
-#define ASUS_WMI_DEVID_ALS_ENABLE      0x00050001 /* Ambient Light Sensor */
-#define ASUS_WMI_DEVID_BACKLIGHT       0x00050011
-#define ASUS_WMI_DEVID_BRIGHTNESS      0x00050012
-#define ASUS_WMI_DEVID_KBD_BACKLIGHT   0x00050021
-#define ASUS_WMI_DEVID_LIGHT_SENSOR    0x00050022 /* ?? */
-#define ASUS_WMI_DEVID_LIGHTBAR                0x00050025
-
-/* Misc */
-#define ASUS_WMI_DEVID_CAMERA          0x00060013
-
-/* Storage */
-#define ASUS_WMI_DEVID_CARDREADER      0x00080013
-
-/* Input */
-#define ASUS_WMI_DEVID_TOUCHPAD                0x00100011
-#define ASUS_WMI_DEVID_TOUCHPAD_LED    0x00100012
-
-/* Fan, Thermal */
-#define ASUS_WMI_DEVID_THERMAL_CTRL    0x00110011
-#define ASUS_WMI_DEVID_FAN_CTRL                0x00110012
-
-/* Power */
-#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
-
-/* Deep S3 / Resume on LID open */
-#define ASUS_WMI_DEVID_LID_RESUME      0x00120031
-
-/* DSTS masks */
-#define ASUS_WMI_DSTS_STATUS_BIT       0x00000001
-#define ASUS_WMI_DSTS_UNKNOWN_BIT      0x00000002
-#define ASUS_WMI_DSTS_PRESENCE_BIT     0x00010000
-#define ASUS_WMI_DSTS_USER_BIT         0x00020000
-#define ASUS_WMI_DSTS_BIOS_BIT         0x00040000
-#define ASUS_WMI_DSTS_BRIGHTNESS_MASK  0x000000FF
-#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK  0x0000FF00
-#define ASUS_WMI_DSTS_LIGHTBAR_MASK    0x0000000F
-
 #define ASUS_FAN_DESC                  "cpu_fan"
 #define ASUS_FAN_MFUN                  0x13
 #define ASUS_FAN_SFUN_READ             0x06
@@ -239,7 +157,6 @@ struct asus_wmi {
        int lightbar_led_wk;
        struct workqueue_struct *led_workqueue;
        struct work_struct tpd_led_work;
-       struct work_struct kbd_led_work;
        struct work_struct wlan_led_work;
        struct work_struct lightbar_led_work;
 
@@ -302,8 +219,7 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
        asus->inputdev = NULL;
 }
 
-static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
-                                   u32 *retval)
+int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
 {
        struct bios_args args = {
                .arg0 = arg0,
@@ -339,6 +255,7 @@ exit:
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
 
 static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
 {
@@ -456,12 +373,9 @@ static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
        return read_tpd_led_state(asus);
 }
 
-static void kbd_led_update(struct work_struct *work)
+static void kbd_led_update(struct asus_wmi *asus)
 {
        int ctrl_param = 0;
-       struct asus_wmi *asus;
-
-       asus = container_of(work, struct asus_wmi, kbd_led_work);
 
        /*
         * bits 0-2: level
@@ -471,7 +385,6 @@ static void kbd_led_update(struct work_struct *work)
                ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
 
        asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
-       led_classdev_notify_brightness_hw_changed(&asus->kbd_led, asus->kbd_led_wk);
 }
 
 static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
@@ -516,7 +429,7 @@ static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
                value = 0;
 
        asus->kbd_led_wk = value;
-       queue_work(asus->led_workqueue, &asus->kbd_led_work);
+       kbd_led_update(asus);
 }
 
 static void kbd_led_set(struct led_classdev *led_cdev,
@@ -525,6 +438,14 @@ static void kbd_led_set(struct led_classdev *led_cdev,
        do_kbd_led_set(led_cdev, value);
 }
 
+static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value)
+{
+       struct led_classdev *led_cdev = &asus->kbd_led;
+
+       do_kbd_led_set(led_cdev, value);
+       led_classdev_notify_brightness_hw_changed(led_cdev, asus->kbd_led_wk);
+}
+
 static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
 {
        struct asus_wmi *asus;
@@ -671,8 +592,6 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
 
        led_val = kbd_led_read(asus, NULL, NULL);
        if (led_val >= 0) {
-               INIT_WORK(&asus->kbd_led_work, kbd_led_update);
-
                asus->kbd_led_wk = led_val;
                asus->kbd_led.name = "asus::kbd_backlight";
                asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
@@ -1746,18 +1665,18 @@ static void asus_wmi_notify(u32 value, void *context)
        }
 
        if (code == NOTIFY_KBD_BRTUP) {
-               do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
+               kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
                goto exit;
        }
        if (code == NOTIFY_KBD_BRTDWN) {
-               do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk - 1);
+               kbd_led_set_by_kbd(asus, asus->kbd_led_wk - 1);
                goto exit;
        }
        if (code == NOTIFY_KBD_BRTTOGGLE) {
                if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
-                       do_kbd_led_set(&asus->kbd_led, 0);
+                       kbd_led_set_by_kbd(asus, 0);
                else
-                       do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
+                       kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
                goto exit;
        }
 
@@ -2291,7 +2210,7 @@ static int asus_hotk_resume(struct device *device)
        struct asus_wmi *asus = dev_get_drvdata(device);
 
        if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
-               queue_work(asus->led_workqueue, &asus->kbd_led_work);
+               kbd_led_update(asus);
 
        return 0;
 }
@@ -2327,7 +2246,7 @@ static int asus_hotk_restore(struct device *device)
                rfkill_set_sw_state(asus->uwb.rfkill, bl);
        }
        if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
-               queue_work(asus->led_workqueue, &asus->kbd_led_work);
+               kbd_led_update(asus);
 
        return 0;
 }
diff --git a/drivers/platform/x86/dcdbas.c b/drivers/platform/x86/dcdbas.c
new file mode 100644 (file)
index 0000000..88bd7ef
--- /dev/null
@@ -0,0 +1,761 @@
+/*
+ *  dcdbas.c: Dell Systems Management Base Driver
+ *
+ *  The Dell Systems Management Base Driver provides a sysfs interface for
+ *  systems management software to perform System Management Interrupts (SMIs)
+ *  and Host Control Actions (power cycle or power off after OS shutdown) on
+ *  Dell systems.
+ *
+ *  See Documentation/dcdbas.txt for more information.
+ *
+ *  Copyright (C) 1995-2006 Dell Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License v2.0 as published by
+ *  the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/cpu.h>
+#include <linux/gfp.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+
+#include "dcdbas.h"
+
+#define DRIVER_NAME            "dcdbas"
+#define DRIVER_VERSION         "5.6.0-3.3"
+#define DRIVER_DESCRIPTION     "Dell Systems Management Base Driver"
+
+static struct platform_device *dcdbas_pdev;
+
+static u8 *smi_data_buf;
+static dma_addr_t smi_data_buf_handle;
+static unsigned long smi_data_buf_size;
+static unsigned long max_smi_data_buf_size = MAX_SMI_DATA_BUF_SIZE;
+static u32 smi_data_buf_phys_addr;
+static DEFINE_MUTEX(smi_data_lock);
+static u8 *eps_buffer;
+
+static unsigned int host_control_action;
+static unsigned int host_control_smi_type;
+static unsigned int host_control_on_shutdown;
+
+static bool wsmt_enabled;
+
+/**
+ * smi_data_buf_free: free SMI data buffer
+ */
+static void smi_data_buf_free(void)
+{
+       if (!smi_data_buf || wsmt_enabled)
+               return;
+
+       dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
+               __func__, smi_data_buf_phys_addr, smi_data_buf_size);
+
+       dma_free_coherent(&dcdbas_pdev->dev, smi_data_buf_size, smi_data_buf,
+                         smi_data_buf_handle);
+       smi_data_buf = NULL;
+       smi_data_buf_handle = 0;
+       smi_data_buf_phys_addr = 0;
+       smi_data_buf_size = 0;
+}
+
+/**
+ * smi_data_buf_realloc: grow SMI data buffer if needed
+ */
+static int smi_data_buf_realloc(unsigned long size)
+{
+       void *buf;
+       dma_addr_t handle;
+
+       if (smi_data_buf_size >= size)
+               return 0;
+
+       if (size > max_smi_data_buf_size)
+               return -EINVAL;
+
+       /* new buffer is needed */
+       buf = dma_alloc_coherent(&dcdbas_pdev->dev, size, &handle, GFP_KERNEL);
+       if (!buf) {
+               dev_dbg(&dcdbas_pdev->dev,
+                       "%s: failed to allocate memory size %lu\n",
+                       __func__, size);
+               return -ENOMEM;
+       }
+       /* memory zeroed by dma_alloc_coherent */
+
+       if (smi_data_buf)
+               memcpy(buf, smi_data_buf, smi_data_buf_size);
+
+       /* free any existing buffer */
+       smi_data_buf_free();
+
+       /* set up new buffer for use */
+       smi_data_buf = buf;
+       smi_data_buf_handle = handle;
+       smi_data_buf_phys_addr = (u32) virt_to_phys(buf);
+       smi_data_buf_size = size;
+
+       dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
+               __func__, smi_data_buf_phys_addr, smi_data_buf_size);
+
+       return 0;
+}
+
+static ssize_t smi_data_buf_phys_addr_show(struct device *dev,
+                                          struct device_attribute *attr,
+                                          char *buf)
+{
+       return sprintf(buf, "%x\n", smi_data_buf_phys_addr);
+}
+
+static ssize_t smi_data_buf_size_show(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       return sprintf(buf, "%lu\n", smi_data_buf_size);
+}
+
+static ssize_t smi_data_buf_size_store(struct device *dev,
+                                      struct device_attribute *attr,
+                                      const char *buf, size_t count)
+{
+       unsigned long buf_size;
+       ssize_t ret;
+
+       buf_size = simple_strtoul(buf, NULL, 10);
+
+       /* make sure SMI data buffer is at least buf_size */
+       mutex_lock(&smi_data_lock);
+       ret = smi_data_buf_realloc(buf_size);
+       mutex_unlock(&smi_data_lock);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static ssize_t smi_data_read(struct file *filp, struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buf, loff_t pos, size_t count)
+{
+       ssize_t ret;
+
+       mutex_lock(&smi_data_lock);
+       ret = memory_read_from_buffer(buf, count, &pos, smi_data_buf,
+                                       smi_data_buf_size);
+       mutex_unlock(&smi_data_lock);
+       return ret;
+}
+
+static ssize_t smi_data_write(struct file *filp, struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buf, loff_t pos, size_t count)
+{
+       ssize_t ret;
+
+       if ((pos + count) > max_smi_data_buf_size)
+               return -EINVAL;
+
+       mutex_lock(&smi_data_lock);
+
+       ret = smi_data_buf_realloc(pos + count);
+       if (ret)
+               goto out;
+
+       memcpy(smi_data_buf + pos, buf, count);
+       ret = count;
+out:
+       mutex_unlock(&smi_data_lock);
+       return ret;
+}
+
+static ssize_t host_control_action_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       return sprintf(buf, "%u\n", host_control_action);
+}
+
+static ssize_t host_control_action_store(struct device *dev,
+                                        struct device_attribute *attr,
+                                        const char *buf, size_t count)
+{
+       ssize_t ret;
+
+       /* make sure buffer is available for host control command */
+       mutex_lock(&smi_data_lock);
+       ret = smi_data_buf_realloc(sizeof(struct apm_cmd));
+       mutex_unlock(&smi_data_lock);
+       if (ret)
+               return ret;
+
+       host_control_action = simple_strtoul(buf, NULL, 10);
+       return count;
+}
+
+static ssize_t host_control_smi_type_show(struct device *dev,
+                                         struct device_attribute *attr,
+                                         char *buf)
+{
+       return sprintf(buf, "%u\n", host_control_smi_type);
+}
+
+static ssize_t host_control_smi_type_store(struct device *dev,
+                                          struct device_attribute *attr,
+                                          const char *buf, size_t count)
+{
+       host_control_smi_type = simple_strtoul(buf, NULL, 10);
+       return count;
+}
+
+static ssize_t host_control_on_shutdown_show(struct device *dev,
+                                            struct device_attribute *attr,
+                                            char *buf)
+{
+       return sprintf(buf, "%u\n", host_control_on_shutdown);
+}
+
+static ssize_t host_control_on_shutdown_store(struct device *dev,
+                                             struct device_attribute *attr,
+                                             const char *buf, size_t count)
+{
+       host_control_on_shutdown = simple_strtoul(buf, NULL, 10);
+       return count;
+}
+
+static int raise_smi(void *par)
+{
+       struct smi_cmd *smi_cmd = par;
+
+       if (smp_processor_id() != 0) {
+               dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
+                       __func__);
+               return -EBUSY;
+       }
+
+       /* generate SMI */
+       /* inb to force posted write through and make SMI happen now */
+       asm volatile (
+               "outb %b0,%w1\n"
+               "inb %w1"
+               : /* no output args */
+               : "a" (smi_cmd->command_code),
+                 "d" (smi_cmd->command_address),
+                 "b" (smi_cmd->ebx),
+                 "c" (smi_cmd->ecx)
+               : "memory"
+       );
+
+       return 0;
+}
+/**
+ * dcdbas_smi_request: generate SMI request
+ *
+ * Called with smi_data_lock.
+ */
+int dcdbas_smi_request(struct smi_cmd *smi_cmd)
+{
+       int ret;
+
+       if (smi_cmd->magic != SMI_CMD_MAGIC) {
+               dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n",
+                        __func__);
+               return -EBADR;
+       }
+
+       /* SMI requires CPU 0 */
+       get_online_cpus();
+       ret = smp_call_on_cpu(0, raise_smi, smi_cmd, true);
+       put_online_cpus();
+
+       return ret;
+}
+
+/**
+ * smi_request_store:
+ *
+ * The valid values are:
+ * 0: zero SMI data buffer
+ * 1: generate calling interface SMI
+ * 2: generate raw SMI
+ *
+ * User application writes smi_cmd to smi_data before telling driver
+ * to generate SMI.
+ */
+static ssize_t smi_request_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t count)
+{
+       struct smi_cmd *smi_cmd;
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+       ssize_t ret;
+
+       mutex_lock(&smi_data_lock);
+
+       if (smi_data_buf_size < sizeof(struct smi_cmd)) {
+               ret = -ENODEV;
+               goto out;
+       }
+       smi_cmd = (struct smi_cmd *)smi_data_buf;
+
+       switch (val) {
+       case 2:
+               /* Raw SMI */
+               ret = dcdbas_smi_request(smi_cmd);
+               if (!ret)
+                       ret = count;
+               break;
+       case 1:
+               /*
+                * Calling Interface SMI
+                *
+                * Provide physical address of command buffer field within
+                * the struct smi_cmd to BIOS.
+                *
+                * Because the address that smi_cmd (smi_data_buf) points to
+                * will be from memremap() of a non-memory address if WSMT
+                * is present, we can't use virt_to_phys() on smi_cmd, so
+                * we have to use the physical address that was saved when
+                * the virtual address for smi_cmd was received.
+                */
+               smi_cmd->ebx = smi_data_buf_phys_addr +
+                               offsetof(struct smi_cmd, command_buffer);
+               ret = dcdbas_smi_request(smi_cmd);
+               if (!ret)
+                       ret = count;
+               break;
+       case 0:
+               memset(smi_data_buf, 0, smi_data_buf_size);
+               ret = count;
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+out:
+       mutex_unlock(&smi_data_lock);
+       return ret;
+}
+EXPORT_SYMBOL(dcdbas_smi_request);
+
+/**
+ * host_control_smi: generate host control SMI
+ *
+ * Caller must set up the host control command in smi_data_buf.
+ */
+static int host_control_smi(void)
+{
+       struct apm_cmd *apm_cmd;
+       u8 *data;
+       unsigned long flags;
+       u32 num_ticks;
+       s8 cmd_status;
+       u8 index;
+
+       apm_cmd = (struct apm_cmd *)smi_data_buf;
+       apm_cmd->status = ESM_STATUS_CMD_UNSUCCESSFUL;
+
+       switch (host_control_smi_type) {
+       case HC_SMITYPE_TYPE1:
+               spin_lock_irqsave(&rtc_lock, flags);
+               /* write SMI data buffer physical address */
+               data = (u8 *)&smi_data_buf_phys_addr;
+               for (index = PE1300_CMOS_CMD_STRUCT_PTR;
+                    index < (PE1300_CMOS_CMD_STRUCT_PTR + 4);
+                    index++, data++) {
+                       outb(index,
+                            (CMOS_BASE_PORT + CMOS_PAGE2_INDEX_PORT_PIIX4));
+                       outb(*data,
+                            (CMOS_BASE_PORT + CMOS_PAGE2_DATA_PORT_PIIX4));
+               }
+
+               /* first set status to -1 as called by spec */
+               cmd_status = ESM_STATUS_CMD_UNSUCCESSFUL;
+               outb((u8) cmd_status, PCAT_APM_STATUS_PORT);
+
+               /* generate SMM call */
+               outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
+               spin_unlock_irqrestore(&rtc_lock, flags);
+
+               /* wait a few to see if it executed */
+               num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
+               while ((cmd_status = inb(PCAT_APM_STATUS_PORT))
+                      == ESM_STATUS_CMD_UNSUCCESSFUL) {
+                       num_ticks--;
+                       if (num_ticks == EXPIRED_TIMER)
+                               return -ETIME;
+               }
+               break;
+
+       case HC_SMITYPE_TYPE2:
+       case HC_SMITYPE_TYPE3:
+               spin_lock_irqsave(&rtc_lock, flags);
+               /* write SMI data buffer physical address */
+               data = (u8 *)&smi_data_buf_phys_addr;
+               for (index = PE1400_CMOS_CMD_STRUCT_PTR;
+                    index < (PE1400_CMOS_CMD_STRUCT_PTR + 4);
+                    index++, data++) {
+                       outb(index, (CMOS_BASE_PORT + CMOS_PAGE1_INDEX_PORT));
+                       outb(*data, (CMOS_BASE_PORT + CMOS_PAGE1_DATA_PORT));
+               }
+
+               /* generate SMM call */
+               if (host_control_smi_type == HC_SMITYPE_TYPE3)
+                       outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
+               else
+                       outb(ESM_APM_CMD, PE1400_APM_CONTROL_PORT);
+
+               /* restore RTC index pointer since it was written to above */
+               CMOS_READ(RTC_REG_C);
+               spin_unlock_irqrestore(&rtc_lock, flags);
+
+               /* read control port back to serialize write */
+               cmd_status = inb(PE1400_APM_CONTROL_PORT);
+
+               /* wait a few to see if it executed */
+               num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
+               while (apm_cmd->status == ESM_STATUS_CMD_UNSUCCESSFUL) {
+                       num_ticks--;
+                       if (num_ticks == EXPIRED_TIMER)
+                               return -ETIME;
+               }
+               break;
+
+       default:
+               dev_dbg(&dcdbas_pdev->dev, "%s: invalid SMI type %u\n",
+                       __func__, host_control_smi_type);
+               return -ENOSYS;
+       }
+
+       return 0;
+}
+
+/**
+ * dcdbas_host_control: initiate host control
+ *
+ * This function is called by the driver after the system has
+ * finished shutting down if the user application specified a
+ * host control action to perform on shutdown.  It is safe to
+ * use smi_data_buf at this point because the system has finished
+ * shutting down and no userspace apps are running.
+ */
+static void dcdbas_host_control(void)
+{
+       struct apm_cmd *apm_cmd;
+       u8 action;
+
+       if (host_control_action == HC_ACTION_NONE)
+               return;
+
+       action = host_control_action;
+       host_control_action = HC_ACTION_NONE;
+
+       if (!smi_data_buf) {
+               dev_dbg(&dcdbas_pdev->dev, "%s: no SMI buffer\n", __func__);
+               return;
+       }
+
+       if (smi_data_buf_size < sizeof(struct apm_cmd)) {
+               dev_dbg(&dcdbas_pdev->dev, "%s: SMI buffer too small\n",
+                       __func__);
+               return;
+       }
+
+       apm_cmd = (struct apm_cmd *)smi_data_buf;
+
+       /* power off takes precedence */
+       if (action & HC_ACTION_HOST_CONTROL_POWEROFF) {
+               apm_cmd->command = ESM_APM_POWER_CYCLE;
+               apm_cmd->reserved = 0;
+               *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 0;
+               host_control_smi();
+       } else if (action & HC_ACTION_HOST_CONTROL_POWERCYCLE) {
+               apm_cmd->command = ESM_APM_POWER_CYCLE;
+               apm_cmd->reserved = 0;
+               *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 20;
+               host_control_smi();
+       }
+}
+
+/* WSMT */
+
+static u8 checksum(u8 *buffer, u8 length)
+{
+       u8 sum = 0;
+       u8 *end = buffer + length;
+
+       while (buffer < end)
+               sum += *buffer++;
+       return sum;
+}
+
+static inline struct smm_eps_table *check_eps_table(u8 *addr)
+{
+       struct smm_eps_table *eps = (struct smm_eps_table *)addr;
+
+       if (strncmp(eps->smm_comm_buff_anchor, SMM_EPS_SIG, 4) != 0)
+               return NULL;
+
+       if (checksum(addr, eps->length) != 0)
+               return NULL;
+
+       return eps;
+}
+
+static int dcdbas_check_wsmt(void)
+{
+       struct acpi_table_wsmt *wsmt = NULL;
+       struct smm_eps_table *eps = NULL;
+       u64 remap_size;
+       u8 *addr;
+
+       acpi_get_table(ACPI_SIG_WSMT, 0, (struct acpi_table_header **)&wsmt);
+       if (!wsmt)
+               return 0;
+
+       /* Check if WSMT ACPI table shows that protection is enabled */
+       if (!(wsmt->protection_flags & ACPI_WSMT_FIXED_COMM_BUFFERS) ||
+           !(wsmt->protection_flags & ACPI_WSMT_COMM_BUFFER_NESTED_PTR_PROTECTION))
+               return 0;
+
+       /* Scan for EPS (entry point structure) */
+       for (addr = (u8 *)__va(0xf0000);
+            addr < (u8 *)__va(0x100000 - sizeof(struct smm_eps_table));
+            addr += 16) {
+               eps = check_eps_table(addr);
+               if (eps)
+                       break;
+       }
+
+       if (!eps) {
+               dev_dbg(&dcdbas_pdev->dev, "found WSMT, but no EPS found\n");
+               return -ENODEV;
+       }
+
+       /*
+        * Get physical address of buffer and map to virtual address.
+        * Table gives size in 4K pages, regardless of actual system page size.
+        */
+       if (upper_32_bits(eps->smm_comm_buff_addr + 8)) {
+               dev_warn(&dcdbas_pdev->dev, "found WSMT, but EPS buffer address is above 4GB\n");
+               return -EINVAL;
+       }
+       /*
+        * Limit remap size to MAX_SMI_DATA_BUF_SIZE + 8 (since the first 8
+        * bytes are used for a semaphore, not the data buffer itself).
+        */
+       remap_size = eps->num_of_4k_pages * PAGE_SIZE;
+       if (remap_size > MAX_SMI_DATA_BUF_SIZE + 8)
+               remap_size = MAX_SMI_DATA_BUF_SIZE + 8;
+       eps_buffer = memremap(eps->smm_comm_buff_addr, remap_size, MEMREMAP_WB);
+       if (!eps_buffer) {
+               dev_warn(&dcdbas_pdev->dev, "found WSMT, but failed to map EPS buffer\n");
+               return -ENOMEM;
+       }
+
+       /* First 8 bytes is for a semaphore, not part of the smi_data_buf */
+       smi_data_buf_phys_addr = eps->smm_comm_buff_addr + 8;
+       smi_data_buf = eps_buffer + 8;
+       smi_data_buf_size = remap_size - 8;
+       max_smi_data_buf_size = smi_data_buf_size;
+       wsmt_enabled = true;
+       dev_info(&dcdbas_pdev->dev,
+                "WSMT found, using firmware-provided SMI buffer.\n");
+       return 1;
+}
+
+/**
+ * dcdbas_reboot_notify: handle reboot notification for host control
+ */
+static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code,
+                               void *unused)
+{
+       switch (code) {
+       case SYS_DOWN:
+       case SYS_HALT:
+       case SYS_POWER_OFF:
+               if (host_control_on_shutdown) {
+                       /* firmware is going to perform host control action */
+                       printk(KERN_WARNING "Please wait for shutdown "
+                              "action to complete...\n");
+                       dcdbas_host_control();
+               }
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block dcdbas_reboot_nb = {
+       .notifier_call = dcdbas_reboot_notify,
+       .next = NULL,
+       .priority = INT_MIN
+};
+
+static DCDBAS_BIN_ATTR_RW(smi_data);
+
+static struct bin_attribute *dcdbas_bin_attrs[] = {
+       &bin_attr_smi_data,
+       NULL
+};
+
+static DCDBAS_DEV_ATTR_RW(smi_data_buf_size);
+static DCDBAS_DEV_ATTR_RO(smi_data_buf_phys_addr);
+static DCDBAS_DEV_ATTR_WO(smi_request);
+static DCDBAS_DEV_ATTR_RW(host_control_action);
+static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
+static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);
+
+static struct attribute *dcdbas_dev_attrs[] = {
+       &dev_attr_smi_data_buf_size.attr,
+       &dev_attr_smi_data_buf_phys_addr.attr,
+       &dev_attr_smi_request.attr,
+       &dev_attr_host_control_action.attr,
+       &dev_attr_host_control_smi_type.attr,
+       &dev_attr_host_control_on_shutdown.attr,
+       NULL
+};
+
+static const struct attribute_group dcdbas_attr_group = {
+       .attrs = dcdbas_dev_attrs,
+       .bin_attrs = dcdbas_bin_attrs,
+};
+
+static int dcdbas_probe(struct platform_device *dev)
+{
+       int error;
+
+       host_control_action = HC_ACTION_NONE;
+       host_control_smi_type = HC_SMITYPE_NONE;
+
+       dcdbas_pdev = dev;
+
+       /* Check if ACPI WSMT table specifies protected SMI buffer address */
+       error = dcdbas_check_wsmt();
+       if (error < 0)
+               return error;
+
+       /*
+        * BIOS SMI calls require buffer addresses be in 32-bit address space.
+        * This is done by setting the DMA mask below.
+        */
+       error = dma_set_coherent_mask(&dcdbas_pdev->dev, DMA_BIT_MASK(32));
+       if (error)
+               return error;
+
+       error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
+       if (error)
+               return error;
+
+       register_reboot_notifier(&dcdbas_reboot_nb);
+
+       dev_info(&dev->dev, "%s (version %s)\n",
+                DRIVER_DESCRIPTION, DRIVER_VERSION);
+
+       return 0;
+}
+
+static int dcdbas_remove(struct platform_device *dev)
+{
+       unregister_reboot_notifier(&dcdbas_reboot_nb);
+       sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
+
+       return 0;
+}
+
+static struct platform_driver dcdbas_driver = {
+       .driver         = {
+               .name   = DRIVER_NAME,
+       },
+       .probe          = dcdbas_probe,
+       .remove         = dcdbas_remove,
+};
+
+static const struct platform_device_info dcdbas_dev_info __initconst = {
+       .name           = DRIVER_NAME,
+       .id             = -1,
+       .dma_mask       = DMA_BIT_MASK(32),
+};
+
+static struct platform_device *dcdbas_pdev_reg;
+
+/**
+ * dcdbas_init: initialize driver
+ */
+static int __init dcdbas_init(void)
+{
+       int error;
+
+       error = platform_driver_register(&dcdbas_driver);
+       if (error)
+               return error;
+
+       dcdbas_pdev_reg = platform_device_register_full(&dcdbas_dev_info);
+       if (IS_ERR(dcdbas_pdev_reg)) {
+               error = PTR_ERR(dcdbas_pdev_reg);
+               goto err_unregister_driver;
+       }
+
+       return 0;
+
+ err_unregister_driver:
+       platform_driver_unregister(&dcdbas_driver);
+       return error;
+}
+
+/**
+ * dcdbas_exit: perform driver cleanup
+ */
+static void __exit dcdbas_exit(void)
+{
+       /*
+        * make sure functions that use dcdbas_pdev are called
+        * before platform_device_unregister
+        */
+       unregister_reboot_notifier(&dcdbas_reboot_nb);
+
+       /*
+        * We have to free the buffer here instead of dcdbas_remove
+        * because only in module exit function we can be sure that
+        * all sysfs attributes belonging to this module have been
+        * released.
+        */
+       if (dcdbas_pdev)
+               smi_data_buf_free();
+       if (eps_buffer)
+               memunmap(eps_buffer);
+       platform_device_unregister(dcdbas_pdev_reg);
+       platform_driver_unregister(&dcdbas_driver);
+}
+
+subsys_initcall_sync(dcdbas_init);
+module_exit(dcdbas_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR("Dell Inc.");
+MODULE_LICENSE("GPL");
+/* Any System or BIOS claiming to be by Dell */
+MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*");
diff --git a/drivers/platform/x86/dcdbas.h b/drivers/platform/x86/dcdbas.h
new file mode 100644 (file)
index 0000000..52729a4
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  dcdbas.h: Definitions for Dell Systems Management Base driver
+ *
+ *  Copyright (C) 1995-2005 Dell Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License v2.0 as published by
+ *  the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _DCDBAS_H_
+#define _DCDBAS_H_
+
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#define MAX_SMI_DATA_BUF_SIZE                  (256 * 1024)
+
+#define HC_ACTION_NONE                         (0)
+#define HC_ACTION_HOST_CONTROL_POWEROFF                BIT(1)
+#define HC_ACTION_HOST_CONTROL_POWERCYCLE      BIT(2)
+
+#define HC_SMITYPE_NONE                                (0)
+#define HC_SMITYPE_TYPE1                       (1)
+#define HC_SMITYPE_TYPE2                       (2)
+#define HC_SMITYPE_TYPE3                       (3)
+
+#define ESM_APM_CMD                            (0x0A0)
+#define ESM_APM_POWER_CYCLE                    (0x10)
+#define ESM_STATUS_CMD_UNSUCCESSFUL            (-1)
+
+#define CMOS_BASE_PORT                         (0x070)
+#define CMOS_PAGE1_INDEX_PORT                  (0)
+#define CMOS_PAGE1_DATA_PORT                   (1)
+#define CMOS_PAGE2_INDEX_PORT_PIIX4            (2)
+#define CMOS_PAGE2_DATA_PORT_PIIX4             (3)
+#define PE1400_APM_CONTROL_PORT                        (0x0B0)
+#define PCAT_APM_CONTROL_PORT                  (0x0B2)
+#define PCAT_APM_STATUS_PORT                   (0x0B3)
+#define PE1300_CMOS_CMD_STRUCT_PTR             (0x38)
+#define PE1400_CMOS_CMD_STRUCT_PTR             (0x70)
+
+#define MAX_SYSMGMT_SHORTCMD_PARMBUF_LEN       (14)
+#define MAX_SYSMGMT_LONGCMD_SGENTRY_NUM                (16)
+
+#define TIMEOUT_USEC_SHORT_SEMA_BLOCKING       (10000)
+#define EXPIRED_TIMER                          (0)
+
+#define SMI_CMD_MAGIC                          (0x534D4931)
+#define SMM_EPS_SIG                            "$SCB"
+
+#define DCDBAS_DEV_ATTR_RW(_name) \
+       DEVICE_ATTR(_name,0600,_name##_show,_name##_store);
+
+#define DCDBAS_DEV_ATTR_RO(_name) \
+       DEVICE_ATTR(_name,0400,_name##_show,NULL);
+
+#define DCDBAS_DEV_ATTR_WO(_name) \
+       DEVICE_ATTR(_name,0200,NULL,_name##_store);
+
+#define DCDBAS_BIN_ATTR_RW(_name) \
+struct bin_attribute bin_attr_##_name = { \
+       .attr =  { .name = __stringify(_name), \
+                  .mode = 0600 }, \
+       .read =  _name##_read, \
+       .write = _name##_write, \
+}
+
+struct smi_cmd {
+       __u32 magic;
+       __u32 ebx;
+       __u32 ecx;
+       __u16 command_address;
+       __u8 command_code;
+       __u8 reserved;
+       __u8 command_buffer[1];
+} __attribute__ ((packed));
+
+struct apm_cmd {
+       __u8 command;
+       __s8 status;
+       __u16 reserved;
+       union {
+               struct {
+                       __u8 parm[MAX_SYSMGMT_SHORTCMD_PARMBUF_LEN];
+               } __attribute__ ((packed)) shortreq;
+
+               struct {
+                       __u16 num_sg_entries;
+                       struct {
+                               __u32 size;
+                               __u64 addr;
+                       } __attribute__ ((packed))
+                           sglist[MAX_SYSMGMT_LONGCMD_SGENTRY_NUM];
+               } __attribute__ ((packed)) longreq;
+       } __attribute__ ((packed)) parameters;
+} __attribute__ ((packed));
+
+int dcdbas_smi_request(struct smi_cmd *smi_cmd);
+
+struct smm_eps_table {
+       char smm_comm_buff_anchor[4];
+       u8 length;
+       u8 checksum;
+       u8 version;
+       u64 smm_comm_buff_addr;
+       u64 num_of_4k_pages;
+} __packed;
+
+#endif /* _DCDBAS_H_ */
+
index 97a90bebc36079f5ff716b8d739bd27928aa442a..ab9b822a6dfe6df42a0ba237f7aa50fb984d39db 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
-#include "../../firmware/dcdbas.h"
+#include "dcdbas.h"
 #include "dell-smbios.h"
 
 static int da_command_address;
diff --git a/drivers/platform/x86/dell_rbu.c b/drivers/platform/x86/dell_rbu.c
new file mode 100644 (file)
index 0000000..ccefa84
--- /dev/null
@@ -0,0 +1,753 @@
+/*
+ * dell_rbu.c
+ * Bios Update driver for Dell systems
+ * Author: Dell Inc
+ *         Abhay Salunke <abhay_salunke@dell.com>
+ *
+ * Copyright (C) 2005 Dell Inc.
+ *
+ * Remote BIOS Update (rbu) driver is used for updating DELL BIOS by
+ * creating entries in the /sys file systems on Linux 2.6 and higher
+ * kernels. The driver supports two mechanism to update the BIOS namely
+ * contiguous and packetized. Both these methods still require having some
+ * application to set the CMOS bit indicating the BIOS to update itself
+ * after a reboot.
+ *
+ * Contiguous method:
+ * This driver writes the incoming data in a monolithic image by allocating
+ * contiguous physical pages large enough to accommodate the incoming BIOS
+ * image size.
+ *
+ * Packetized method:
+ * The driver writes the incoming packet image by allocating a new packet
+ * on every time the packet data is written. This driver requires an
+ * application to break the BIOS image in to fixed sized packet chunks.
+ *
+ * See Documentation/dell_rbu.txt for more info.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/blkdev.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/dma-mapping.h>
+#include <asm/set_memory.h>
+
+MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
+MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("3.2");
+
+#define BIOS_SCAN_LIMIT 0xffffffff
+#define MAX_IMAGE_LENGTH 16
+static struct _rbu_data {
+       void *image_update_buffer;
+       unsigned long image_update_buffer_size;
+       unsigned long bios_image_size;
+       int image_update_ordernum;
+       int dma_alloc;
+       spinlock_t lock;
+       unsigned long packet_read_count;
+       unsigned long num_packets;
+       unsigned long packetsize;
+       unsigned long imagesize;
+       int entry_created;
+} rbu_data;
+
+static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
+module_param_string(image_type, image_type, sizeof (image_type), 0);
+MODULE_PARM_DESC(image_type,
+       "BIOS image type. choose- mono or packet or init");
+
+static unsigned long allocation_floor = 0x100000;
+module_param(allocation_floor, ulong, 0644);
+MODULE_PARM_DESC(allocation_floor,
+    "Minimum address for allocations when using Packet mode");
+
+struct packet_data {
+       struct list_head list;
+       size_t length;
+       void *data;
+       int ordernum;
+};
+
+static struct packet_data packet_data_head;
+
+static struct platform_device *rbu_device;
+static int context;
+static dma_addr_t dell_rbu_dmaaddr;
+
+static void init_packet_head(void)
+{
+       INIT_LIST_HEAD(&packet_data_head.list);
+       rbu_data.packet_read_count = 0;
+       rbu_data.num_packets = 0;
+       rbu_data.packetsize = 0;
+       rbu_data.imagesize = 0;
+}
+
+static int create_packet(void *data, size_t length)
+{
+       struct packet_data *newpacket;
+       int ordernum = 0;
+       int retval = 0;
+       unsigned int packet_array_size = 0;
+       void **invalid_addr_packet_array = NULL;
+       void *packet_data_temp_buf = NULL;
+       unsigned int idx = 0;
+
+       pr_debug("create_packet: entry \n");
+
+       if (!rbu_data.packetsize) {
+               pr_debug("create_packet: packetsize not specified\n");
+               retval = -EINVAL;
+               goto out_noalloc;
+       }
+
+       spin_unlock(&rbu_data.lock);
+
+       newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
+
+       if (!newpacket) {
+               printk(KERN_WARNING
+                       "dell_rbu:%s: failed to allocate new "
+                       "packet\n", __func__);
+               retval = -ENOMEM;
+               spin_lock(&rbu_data.lock);
+               goto out_noalloc;
+       }
+
+       ordernum = get_order(length);
+
+       /*
+        * BIOS errata mean we cannot allocate packets below 1MB or they will
+        * be overwritten by BIOS.
+        *
+        * array to temporarily hold packets
+        * that are below the allocation floor
+        *
+        * NOTE: very simplistic because we only need the floor to be at 1MB
+        *       due to BIOS errata. This shouldn't be used for higher floors
+        *       or you will run out of mem trying to allocate the array.
+        */
+       packet_array_size = max(
+                       (unsigned int)(allocation_floor / rbu_data.packetsize),
+                       (unsigned int)1);
+       invalid_addr_packet_array = kcalloc(packet_array_size, sizeof(void *),
+                                               GFP_KERNEL);
+
+       if (!invalid_addr_packet_array) {
+               printk(KERN_WARNING
+                       "dell_rbu:%s: failed to allocate "
+                       "invalid_addr_packet_array \n",
+                       __func__);
+               retval = -ENOMEM;
+               spin_lock(&rbu_data.lock);
+               goto out_alloc_packet;
+       }
+
+       while (!packet_data_temp_buf) {
+               packet_data_temp_buf = (unsigned char *)
+                       __get_free_pages(GFP_KERNEL, ordernum);
+               if (!packet_data_temp_buf) {
+                       printk(KERN_WARNING
+                               "dell_rbu:%s: failed to allocate new "
+                               "packet\n", __func__);
+                       retval = -ENOMEM;
+                       spin_lock(&rbu_data.lock);
+                       goto out_alloc_packet_array;
+               }
+
+               if ((unsigned long)virt_to_phys(packet_data_temp_buf)
+                               < allocation_floor) {
+                       pr_debug("packet 0x%lx below floor at 0x%lx.\n",
+                                       (unsigned long)virt_to_phys(
+                                               packet_data_temp_buf),
+                                       allocation_floor);
+                       invalid_addr_packet_array[idx++] = packet_data_temp_buf;
+                       packet_data_temp_buf = NULL;
+               }
+       }
+       /*
+        * set to uncachable or it may never get written back before reboot
+        */
+       set_memory_uc((unsigned long)packet_data_temp_buf, 1 << ordernum);
+
+       spin_lock(&rbu_data.lock);
+
+       newpacket->data = packet_data_temp_buf;
+
+       pr_debug("create_packet: newpacket at physical addr %lx\n",
+               (unsigned long)virt_to_phys(newpacket->data));
+
+       /* packets may not have fixed size */
+       newpacket->length = length;
+       newpacket->ordernum = ordernum;
+       ++rbu_data.num_packets;
+
+       /* initialize the newly created packet headers */
+       INIT_LIST_HEAD(&newpacket->list);
+       list_add_tail(&newpacket->list, &packet_data_head.list);
+
+       memcpy(newpacket->data, data, length);
+
+       pr_debug("create_packet: exit \n");
+
+out_alloc_packet_array:
+       /* always free packet array */
+       for (;idx>0;idx--) {
+               pr_debug("freeing unused packet below floor 0x%lx.\n",
+                       (unsigned long)virt_to_phys(
+                               invalid_addr_packet_array[idx-1]));
+               free_pages((unsigned long)invalid_addr_packet_array[idx-1],
+                       ordernum);
+       }
+       kfree(invalid_addr_packet_array);
+
+out_alloc_packet:
+       /* if error, free data */
+       if (retval)
+               kfree(newpacket);
+
+out_noalloc:
+       return retval;
+}
+
+static int packetize_data(const u8 *data, size_t length)
+{
+       int rc = 0;
+       int done = 0;
+       int packet_length;
+       u8 *temp;
+       u8 *end = (u8 *) data + length;
+       pr_debug("packetize_data: data length %zd\n", length);
+       if (!rbu_data.packetsize) {
+               printk(KERN_WARNING
+                       "dell_rbu: packetsize not specified\n");
+               return -EIO;
+       }
+
+       temp = (u8 *) data;
+
+       /* packetize the hunk */
+       while (!done) {
+               if ((temp + rbu_data.packetsize) < end)
+                       packet_length = rbu_data.packetsize;
+               else {
+                       /* this is the last packet */
+                       packet_length = end - temp;
+                       done = 1;
+               }
+
+               if ((rc = create_packet(temp, packet_length)))
+                       return rc;
+
+               pr_debug("%p:%td\n", temp, (end - temp));
+               temp += packet_length;
+       }
+
+       rbu_data.imagesize = length;
+
+       return rc;
+}
+
+static int do_packet_read(char *data, struct list_head *ptemp_list,
+       int length, int bytes_read, int *list_read_count)
+{
+       void *ptemp_buf;
+       struct packet_data *newpacket = NULL;
+       int bytes_copied = 0;
+       int j = 0;
+
+       newpacket = list_entry(ptemp_list, struct packet_data, list);
+       *list_read_count += newpacket->length;
+
+       if (*list_read_count > bytes_read) {
+               /* point to the start of unread data */
+               j = newpacket->length - (*list_read_count - bytes_read);
+               /* point to the offset in the packet buffer */
+               ptemp_buf = (u8 *) newpacket->data + j;
+               /*
+                * check if there is enough room in
+                * * the incoming buffer
+                */
+               if (length > (*list_read_count - bytes_read))
+                       /*
+                        * copy what ever is there in this
+                        * packet and move on
+                        */
+                       bytes_copied = (*list_read_count - bytes_read);
+               else
+                       /* copy the remaining */
+                       bytes_copied = length;
+               memcpy(data, ptemp_buf, bytes_copied);
+       }
+       return bytes_copied;
+}
+
+static int packet_read_list(char *data, size_t * pread_length)
+{
+       struct list_head *ptemp_list;
+       int temp_count = 0;
+       int bytes_copied = 0;
+       int bytes_read = 0;
+       int remaining_bytes = 0;
+       char *pdest = data;
+
+       /* check if we have any packets */
+       if (0 == rbu_data.num_packets)
+               return -ENOMEM;
+
+       remaining_bytes = *pread_length;
+       bytes_read = rbu_data.packet_read_count;
+
+       ptemp_list = (&packet_data_head.list)->next;
+       while (!list_empty(ptemp_list)) {
+               bytes_copied = do_packet_read(pdest, ptemp_list,
+                       remaining_bytes, bytes_read, &temp_count);
+               remaining_bytes -= bytes_copied;
+               bytes_read += bytes_copied;
+               pdest += bytes_copied;
+               /*
+                * check if we reached end of buffer before reaching the
+                * last packet
+                */
+               if (remaining_bytes == 0)
+                       break;
+
+               ptemp_list = ptemp_list->next;
+       }
+       /*finally set the bytes read */
+       *pread_length = bytes_read - rbu_data.packet_read_count;
+       rbu_data.packet_read_count = bytes_read;
+       return 0;
+}
+
+static void packet_empty_list(void)
+{
+       struct list_head *ptemp_list;
+       struct list_head *pnext_list;
+       struct packet_data *newpacket;
+
+       ptemp_list = (&packet_data_head.list)->next;
+       while (!list_empty(ptemp_list)) {
+               newpacket =
+                       list_entry(ptemp_list, struct packet_data, list);
+               pnext_list = ptemp_list->next;
+               list_del(ptemp_list);
+               ptemp_list = pnext_list;
+               /*
+                * zero out the RBU packet memory before freeing
+                * to make sure there are no stale RBU packets left in memory
+                */
+               memset(newpacket->data, 0, rbu_data.packetsize);
+               set_memory_wb((unsigned long)newpacket->data,
+                       1 << newpacket->ordernum);
+               free_pages((unsigned long) newpacket->data,
+                       newpacket->ordernum);
+               kfree(newpacket);
+       }
+       rbu_data.packet_read_count = 0;
+       rbu_data.num_packets = 0;
+       rbu_data.imagesize = 0;
+}
+
+/*
+ * img_update_free: Frees the buffer allocated for storing BIOS image
+ * Always called with lock held and returned with lock held
+ */
+static void img_update_free(void)
+{
+       if (!rbu_data.image_update_buffer)
+               return;
+       /*
+        * zero out this buffer before freeing it to get rid of any stale
+        * BIOS image copied in memory.
+        */
+       memset(rbu_data.image_update_buffer, 0,
+               rbu_data.image_update_buffer_size);
+       if (rbu_data.dma_alloc == 1)
+               dma_free_coherent(NULL, rbu_data.bios_image_size,
+                       rbu_data.image_update_buffer, dell_rbu_dmaaddr);
+       else
+               free_pages((unsigned long) rbu_data.image_update_buffer,
+                       rbu_data.image_update_ordernum);
+
+       /*
+        * Re-initialize the rbu_data variables after a free
+        */
+       rbu_data.image_update_ordernum = -1;
+       rbu_data.image_update_buffer = NULL;
+       rbu_data.image_update_buffer_size = 0;
+       rbu_data.bios_image_size = 0;
+       rbu_data.dma_alloc = 0;
+}
+
+/*
+ * img_update_realloc: This function allocates the contiguous pages to
+ * accommodate the requested size of data. The memory address and size
+ * values are stored globally and on every call to this function the new
+ * size is checked to see if more data is required than the existing size.
+ * If true the previous memory is freed and new allocation is done to
+ * accommodate the new size. If the incoming size is less then than the
+ * already allocated size, then that memory is reused. This function is
+ * called with lock held and returns with lock held.
+ */
+static int img_update_realloc(unsigned long size)
+{
+       unsigned char *image_update_buffer = NULL;
+       unsigned long rc;
+       unsigned long img_buf_phys_addr;
+       int ordernum;
+       int dma_alloc = 0;
+
+       /*
+        * check if the buffer of sufficient size has been
+        * already allocated
+        */
+       if (rbu_data.image_update_buffer_size >= size) {
+               /*
+                * check for corruption
+                */
+               if ((size != 0) && (rbu_data.image_update_buffer == NULL)) {
+                       printk(KERN_ERR "dell_rbu:%s: corruption "
+                               "check failed\n", __func__);
+                       return -EINVAL;
+               }
+               /*
+                * we have a valid pre-allocated buffer with
+                * sufficient size
+                */
+               return 0;
+       }
+
+       /*
+        * free any previously allocated buffer
+        */
+       img_update_free();
+
+       spin_unlock(&rbu_data.lock);
+
+       ordernum = get_order(size);
+       image_update_buffer =
+               (unsigned char *) __get_free_pages(GFP_KERNEL, ordernum);
+
+       img_buf_phys_addr =
+               (unsigned long) virt_to_phys(image_update_buffer);
+
+       if (img_buf_phys_addr > BIOS_SCAN_LIMIT) {
+               free_pages((unsigned long) image_update_buffer, ordernum);
+               ordernum = -1;
+               image_update_buffer = dma_alloc_coherent(NULL, size,
+                       &dell_rbu_dmaaddr, GFP_KERNEL);
+               dma_alloc = 1;
+       }
+
+       spin_lock(&rbu_data.lock);
+
+       if (image_update_buffer != NULL) {
+               rbu_data.image_update_buffer = image_update_buffer;
+               rbu_data.image_update_buffer_size = size;
+               rbu_data.bios_image_size =
+                       rbu_data.image_update_buffer_size;
+               rbu_data.image_update_ordernum = ordernum;
+               rbu_data.dma_alloc = dma_alloc;
+               rc = 0;
+       } else {
+               pr_debug("Not enough memory for image update:"
+                       "size = %ld\n", size);
+               rc = -ENOMEM;
+       }
+
+       return rc;
+}
+
+static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
+{
+       int retval;
+       size_t bytes_left;
+       size_t data_length;
+       char *ptempBuf = buffer;
+
+       /* check to see if we have something to return */
+       if (rbu_data.num_packets == 0) {
+               pr_debug("read_packet_data: no packets written\n");
+               retval = -ENOMEM;
+               goto read_rbu_data_exit;
+       }
+
+       if (pos > rbu_data.imagesize) {
+               retval = 0;
+               printk(KERN_WARNING "dell_rbu:read_packet_data: "
+                       "data underrun\n");
+               goto read_rbu_data_exit;
+       }
+
+       bytes_left = rbu_data.imagesize - pos;
+       data_length = min(bytes_left, count);
+
+       if ((retval = packet_read_list(ptempBuf, &data_length)) < 0)
+               goto read_rbu_data_exit;
+
+       if ((pos + count) > rbu_data.imagesize) {
+               rbu_data.packet_read_count = 0;
+               /* this was the last copy */
+               retval = bytes_left;
+       } else
+               retval = count;
+
+      read_rbu_data_exit:
+       return retval;
+}
+
+static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
+{
+       /* check to see if we have something to return */
+       if ((rbu_data.image_update_buffer == NULL) ||
+               (rbu_data.bios_image_size == 0)) {
+               pr_debug("read_rbu_data_mono: image_update_buffer %p ,"
+                       "bios_image_size %lu\n",
+                       rbu_data.image_update_buffer,
+                       rbu_data.bios_image_size);
+               return -ENOMEM;
+       }
+
+       return memory_read_from_buffer(buffer, count, &pos,
+                       rbu_data.image_update_buffer, rbu_data.bios_image_size);
+}
+
+static ssize_t read_rbu_data(struct file *filp, struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buffer, loff_t pos, size_t count)
+{
+       ssize_t ret_count = 0;
+
+       spin_lock(&rbu_data.lock);
+
+       if (!strcmp(image_type, "mono"))
+               ret_count = read_rbu_mono_data(buffer, pos, count);
+       else if (!strcmp(image_type, "packet"))
+               ret_count = read_packet_data(buffer, pos, count);
+       else
+               pr_debug("read_rbu_data: invalid image type specified\n");
+
+       spin_unlock(&rbu_data.lock);
+       return ret_count;
+}
+
+static void callbackfn_rbu(const struct firmware *fw, void *context)
+{
+       rbu_data.entry_created = 0;
+
+       if (!fw)
+               return;
+
+       if (!fw->size)
+               goto out;
+
+       spin_lock(&rbu_data.lock);
+       if (!strcmp(image_type, "mono")) {
+               if (!img_update_realloc(fw->size))
+                       memcpy(rbu_data.image_update_buffer,
+                               fw->data, fw->size);
+       } else if (!strcmp(image_type, "packet")) {
+               /*
+                * we need to free previous packets if a
+                * new hunk of packets needs to be downloaded
+                */
+               packet_empty_list();
+               if (packetize_data(fw->data, fw->size))
+                       /* Incase something goes wrong when we are
+                        * in middle of packetizing the data, we
+                        * need to free up whatever packets might
+                        * have been created before we quit.
+                        */
+                       packet_empty_list();
+       } else
+               pr_debug("invalid image type specified.\n");
+       spin_unlock(&rbu_data.lock);
+ out:
+       release_firmware(fw);
+}
+
+static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
+                                  struct bin_attribute *bin_attr,
+                                  char *buffer, loff_t pos, size_t count)
+{
+       int size = 0;
+       if (!pos)
+               size = scnprintf(buffer, count, "%s\n", image_type);
+       return size;
+}
+
+static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buffer, loff_t pos, size_t count)
+{
+       int rc = count;
+       int req_firm_rc = 0;
+       int i;
+       spin_lock(&rbu_data.lock);
+       /*
+        * Find the first newline or space
+        */
+       for (i = 0; i < count; ++i)
+               if (buffer[i] == '\n' || buffer[i] == ' ') {
+                       buffer[i] = '\0';
+                       break;
+               }
+       if (i == count)
+               buffer[count] = '\0';
+
+       if (strstr(buffer, "mono"))
+               strcpy(image_type, "mono");
+       else if (strstr(buffer, "packet"))
+               strcpy(image_type, "packet");
+       else if (strstr(buffer, "init")) {
+               /*
+                * If due to the user error the driver gets in a bad
+                * state where even though it is loaded , the
+                * /sys/class/firmware/dell_rbu entries are missing.
+                * to cover this situation the user can recreate entries
+                * by writing init to image_type.
+                */
+               if (!rbu_data.entry_created) {
+                       spin_unlock(&rbu_data.lock);
+                       req_firm_rc = request_firmware_nowait(THIS_MODULE,
+                               FW_ACTION_NOHOTPLUG, "dell_rbu",
+                               &rbu_device->dev, GFP_KERNEL, &context,
+                               callbackfn_rbu);
+                       if (req_firm_rc) {
+                               printk(KERN_ERR
+                                       "dell_rbu:%s request_firmware_nowait"
+                                       " failed %d\n", __func__, rc);
+                               rc = -EIO;
+                       } else
+                               rbu_data.entry_created = 1;
+
+                       spin_lock(&rbu_data.lock);
+               }
+       } else {
+               printk(KERN_WARNING "dell_rbu: image_type is invalid\n");
+               spin_unlock(&rbu_data.lock);
+               return -EINVAL;
+       }
+
+       /* we must free all previous allocations */
+       packet_empty_list();
+       img_update_free();
+       spin_unlock(&rbu_data.lock);
+
+       return rc;
+}
+
+static ssize_t read_rbu_packet_size(struct file *filp, struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buffer, loff_t pos, size_t count)
+{
+       int size = 0;
+       if (!pos) {
+               spin_lock(&rbu_data.lock);
+               size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize);
+               spin_unlock(&rbu_data.lock);
+       }
+       return size;
+}
+
+static ssize_t write_rbu_packet_size(struct file *filp, struct kobject *kobj,
+                                    struct bin_attribute *bin_attr,
+                                    char *buffer, loff_t pos, size_t count)
+{
+       unsigned long temp;
+       spin_lock(&rbu_data.lock);
+       packet_empty_list();
+       sscanf(buffer, "%lu", &temp);
+       if (temp < 0xffffffff)
+               rbu_data.packetsize = temp;
+
+       spin_unlock(&rbu_data.lock);
+       return count;
+}
+
+static struct bin_attribute rbu_data_attr = {
+       .attr = {.name = "data", .mode = 0444},
+       .read = read_rbu_data,
+};
+
+static struct bin_attribute rbu_image_type_attr = {
+       .attr = {.name = "image_type", .mode = 0644},
+       .read = read_rbu_image_type,
+       .write = write_rbu_image_type,
+};
+
+static struct bin_attribute rbu_packet_size_attr = {
+       .attr = {.name = "packet_size", .mode = 0644},
+       .read = read_rbu_packet_size,
+       .write = write_rbu_packet_size,
+};
+
+static int __init dcdrbu_init(void)
+{
+       int rc;
+       spin_lock_init(&rbu_data.lock);
+
+       init_packet_head();
+       rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0);
+       if (IS_ERR(rbu_device)) {
+               printk(KERN_ERR
+                       "dell_rbu:%s:platform_device_register_simple "
+                       "failed\n", __func__);
+               return PTR_ERR(rbu_device);
+       }
+
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
+       if (rc)
+               goto out_devreg;
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+       if (rc)
+               goto out_data;
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj,
+               &rbu_packet_size_attr);
+       if (rc)
+               goto out_imtype;
+
+       rbu_data.entry_created = 0;
+       return 0;
+
+out_imtype:
+       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+out_data:
+       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
+out_devreg:
+       platform_device_unregister(rbu_device);
+       return rc;
+}
+
+static __exit void dcdrbu_exit(void)
+{
+       spin_lock(&rbu_data.lock);
+       packet_empty_list();
+       img_update_free();
+       spin_unlock(&rbu_data.lock);
+       platform_device_unregister(rbu_device);
+}
+
+module_exit(dcdrbu_exit);
+module_init(dcdrbu_init);
+
+/* vim:noet:ts=8:sw=8
+*/
index d4f1259ff5a233bc22bb0700ddb354ace4b40e58..b6489cba29853e1919cd21c36e7fd19f3c720748 100644 (file)
@@ -212,7 +212,7 @@ static int read_ec_data(acpi_handle handle, int cmd, unsigned long *data)
                        return 0;
                }
        }
-       pr_err("timeout in read_ec_cmd\n");
+       pr_err("timeout in %s\n", __func__);
        return -1;
 }
 
@@ -1146,6 +1146,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBM"),
                },
        },
+       {
+               .ident = "Lenovo Legion Y530-15ICH",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion Y530-15ICH"),
+               },
+       },
        {
                .ident = "Lenovo Legion Y720-15IKB",
                .matches = {
index 6cf9b7fa5bf0486fcf7e9d0b3ed805cfe07ca19d..e28bcf61b12698c6bf88668fe542e49cca463d32 100644 (file)
@@ -1,19 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Intel HID event & 5 button array driver
  *
  *  Copyright (C) 2015 Alex Hung <alex.hung@canonical.com>
  *  Copyright (C) 2015 Andrew Lutomirski <luto@kernel.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
  */
 
 #include <linux/acpi.h>
index 7344d841f4d98d17810b5f6bdbee8965415af6e5..3b81cb896fedff37c231ed62de5c9d859a2df3ac 100644 (file)
@@ -1,26 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-
-#include <linux/init.h>
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/acpi.h>
 
 MODULE_LICENSE("GPL");
 
@@ -53,12 +38,10 @@ static ssize_t irst_store_wakeup_events(struct device *dev,
        acpi = to_acpi_device(dev);
 
        error = kstrtoul(buf, 0, &value);
-
        if (error)
                return error;
 
        status = acpi_execute_simple_method(acpi->handle, "SFFS", value);
-
        if (ACPI_FAILURE(status))
                return -EINVAL;
 
@@ -99,12 +82,10 @@ static ssize_t irst_store_wakeup_time(struct device *dev,
        acpi = to_acpi_device(dev);
 
        error = kstrtoul(buf, 0, &value);
-
        if (error)
                return error;
 
        status = acpi_execute_simple_method(acpi->handle, "SFTV", value);
-
        if (ACPI_FAILURE(status))
                return -EINVAL;
 
index bbe4c06c769f66eabf8ed956cbb3361ef8407220..64c2dc93472f474869b98e418ac1a67bb74d5559 100644 (file)
@@ -1,25 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-
-#include <linux/init.h>
-#include <linux/module.h>
 #include <linux/acpi.h>
+#include <linux/module.h>
 
 MODULE_LICENSE("GPL");
 
@@ -44,6 +29,7 @@ static const struct acpi_device_id smartconnect_ids[] = {
        {"INT33A0", 0},
        {"", 0}
 };
+MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
 
 static struct acpi_driver smartconnect_driver = {
        .owner = THIS_MODULE,
@@ -56,5 +42,3 @@ static struct acpi_driver smartconnect_driver = {
 };
 
 module_acpi_driver(smartconnect_driver);
-
-MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
index c2257bd06f1863d848fc384b2ac5577294bef8f5..9ded8e2af312f23293a5a6a8a56a3c7b8d499c3e 100644 (file)
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * WMI Thunderbolt driver
  *
  * Copyright (C) 2017 Dell Inc. All Rights Reserved.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License version 2 as published
- *  by the Free Software Foundation.
- *
- *  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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -38,12 +30,16 @@ static ssize_t force_power_store(struct device *dev,
        input.length = sizeof(u8);
        input.pointer = &mode;
        mode = hex_to_bin(buf[0]);
+       dev_dbg(dev, "force_power: storing %#x\n", mode);
        if (mode == 0 || mode == 1) {
                status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1,
                                             &input, NULL);
-               if (ACPI_FAILURE(status))
+               if (ACPI_FAILURE(status)) {
+                       dev_dbg(dev, "force_power: failed to evaluate ACPI method\n");
                        return -ENODEV;
+               }
        } else {
+               dev_dbg(dev, "force_power: unsupported mode\n");
                return -EINVAL;
        }
        return count;
@@ -95,4 +91,4 @@ module_wmi_driver(intel_wmi_thunderbolt_driver);
 MODULE_ALIAS("wmi:" INTEL_WMI_THUNDERBOLT_GUID);
 MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
 MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel_atomisp2_pm.c b/drivers/platform/x86/intel_atomisp2_pm.c
new file mode 100644 (file)
index 0000000..9371603
--- /dev/null
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Dummy driver for Intel's Image Signal Processor found on Bay and Cherry
+ * Trail devices. The sole purpose of this driver is to allow the ISP to
+ * be put in D3.
+ *
+ * Copyright (C) 2018 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Based on various non upstream patches for ISP support:
+ * Copyright (C) 2010-2017 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <asm/iosf_mbi.h>
+
+/* PCI configuration regs */
+#define PCI_INTERRUPT_CTRL             0x9c
+
+#define PCI_CSI_CONTROL                        0xe8
+#define PCI_CSI_CONTROL_PORTS_OFF_MASK 0x7
+
+/* IOSF BT_MBI_UNIT_PMC regs */
+#define ISPSSPM0                       0x39
+#define ISPSSPM0_ISPSSC_OFFSET         0
+#define ISPSSPM0_ISPSSC_MASK           0x00000003
+#define ISPSSPM0_ISPSSS_OFFSET         24
+#define ISPSSPM0_ISPSSS_MASK           0x03000000
+#define ISPSSPM0_IUNIT_POWER_ON                0x0
+#define ISPSSPM0_IUNIT_POWER_OFF       0x3
+
+static int isp_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+       unsigned long timeout;
+       u32 val;
+
+       pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, 0);
+
+       /*
+        * MRFLD IUNIT DPHY is located in an always-power-on island
+        * MRFLD HW design need all CSI ports are disabled before
+        * powering down the IUNIT.
+        */
+       pci_read_config_dword(dev, PCI_CSI_CONTROL, &val);
+       val |= PCI_CSI_CONTROL_PORTS_OFF_MASK;
+       pci_write_config_dword(dev, PCI_CSI_CONTROL, val);
+
+       /* Write 0x3 to ISPSSPM0 bit[1:0] to power off the IUNIT */
+       iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0,
+                       ISPSSPM0_IUNIT_POWER_OFF, ISPSSPM0_ISPSSC_MASK);
+
+       /*
+        * There should be no IUNIT access while power-down is
+        * in progress HW sighting: 4567865
+        * Wait up to 50 ms for the IUNIT to shut down.
+        */
+       timeout = jiffies + msecs_to_jiffies(50);
+       while (1) {
+               /* Wait until ISPSSPM0 bit[25:24] shows 0x3 */
+               iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0, &val);
+               val = (val & ISPSSPM0_ISPSSS_MASK) >> ISPSSPM0_ISPSSS_OFFSET;
+               if (val == ISPSSPM0_IUNIT_POWER_OFF)
+                       break;
+
+               if (time_after(jiffies, timeout)) {
+                       dev_err(&dev->dev, "IUNIT power-off timeout.\n");
+                       return -EBUSY;
+               }
+               usleep_range(1000, 2000);
+       }
+
+       pm_runtime_allow(&dev->dev);
+       pm_runtime_put_sync_suspend(&dev->dev);
+
+       return 0;
+}
+
+static void isp_remove(struct pci_dev *dev)
+{
+       pm_runtime_get_sync(&dev->dev);
+       pm_runtime_forbid(&dev->dev);
+}
+
+static int isp_pci_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int isp_pci_resume(struct device *dev)
+{
+       return 0;
+}
+
+static UNIVERSAL_DEV_PM_OPS(isp_pm_ops, isp_pci_suspend,
+                           isp_pci_resume, NULL);
+
+static const struct pci_device_id isp_id_table[] = {
+       { PCI_VDEVICE(INTEL, 0x22b8), },
+       { 0, }
+};
+MODULE_DEVICE_TABLE(pci, isp_id_table);
+
+static struct pci_driver isp_pci_driver = {
+       .name = "intel_atomisp2_pm",
+       .id_table = isp_id_table,
+       .probe = isp_probe,
+       .remove = isp_remove,
+       .driver.pm = &isp_pm_ops,
+};
+
+module_pci_driver(isp_pci_driver);
+
+MODULE_DESCRIPTION("Intel AtomISP2 dummy / power-management drv (for suspend)");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_LICENSE("GPL v2");
index 227943a20212cca12188cc18730bc42d6807da4e..951c105bafc1b8b1fc276ee04274690fd5f15f30 100644 (file)
@@ -1,21 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * intel_bxtwc_tmu.c - Intel BXT Whiskey Cove PMIC TMU driver
+ * Intel BXT Whiskey Cove PMIC TMU driver
  *
  * Copyright (C) 2016 Intel Corporation. All rights reserved.
  *
  * This driver adds TMU (Time Management Unit) support for Intel BXT platform.
  * It enables the alarm wake-up functionality in the TMU unit of Whiskey Cove
  * PMIC.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 
 #include <linux/module.h>
index f40b1c1921064b734614705c72dc212700f979fc..464fe93657b53e03268eabb2f41f5cdd0583d96e 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel Cherry Trail ACPI INT33FE pseudo device driver
  *
  * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Some Intel Cherry Trail based device which ship with Windows 10, have
  * this weird INT33FE ACPI device with a CRS table with 4 I2cSerialBusV2
  * resources, for 4 different chips attached to various i2c busses:
@@ -257,4 +254,4 @@ module_platform_driver(cht_int33fe_driver);
 
 MODULE_DESCRIPTION("Intel Cherry Trail ACPI INT33FE pseudo device driver");
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 38b8e7cfe88c06a68fa351b7048247324fc89e31..0df2e82dd24924bd6d92ff74f2434b4eb1f30d64 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Power-button driver for Dollar Cove TI PMIC
  * Copyright (C) 2014 Intel Corp
index e89ad4964dc139daec390560bfcecb145cdd5505..4b8f7305fc8a773b8a0e06291b69672ef559a7ab 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel INT0002 "Virtual GPIO" driver
  *
@@ -9,10 +10,6 @@
  *
  * Author: Dyut Kumar Sil <dyut.k.sil@intel.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Some peripherals on Bay Trail and Cherry Trail platforms signal a Power
  * Management Event (PME) to the Power Management Controller (PMC) to wakeup
  * the system. When this happens software needs to clear the PME bus 0 status
 #define ICPU(model)    { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }
 
 static const struct x86_cpu_id int0002_cpu_ids[] = {
-/*
- * Limit ourselves to Cherry Trail for now, until testing shows we
- * need to handle the INT0002 device on Baytrail too.
- *     ICPU(INTEL_FAM6_ATOM_SILVERMONT),        * Valleyview, Bay Trail *
- */
+       ICPU(INTEL_FAM6_ATOM_SILVERMONT),       /* Valleyview, Bay Trail  */
        ICPU(INTEL_FAM6_ATOM_AIRMONT),          /* Braswell, Cherry Trail */
        {}
 };
@@ -110,6 +103,21 @@ static void int0002_irq_mask(struct irq_data *data)
        outl(gpe_en_reg, GPE0A_EN_PORT);
 }
 
+static int int0002_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+       struct platform_device *pdev = to_platform_device(chip->parent);
+       int irq = platform_get_irq(pdev, 0);
+
+       /* Propagate to parent irq */
+       if (on)
+               enable_irq_wake(irq);
+       else
+               disable_irq_wake(irq);
+
+       return 0;
+}
+
 static irqreturn_t int0002_irq(int irq, void *data)
 {
        struct gpio_chip *chip = data;
@@ -132,6 +140,7 @@ static struct irq_chip int0002_irqchip = {
        .irq_ack                = int0002_irq_ack,
        .irq_mask               = int0002_irq_mask,
        .irq_unmask             = int0002_irq_unmask,
+       .irq_set_wake           = int0002_irq_set_wake,
 };
 
 static int int0002_probe(struct platform_device *pdev)
@@ -216,4 +225,4 @@ module_platform_driver(int0002_driver);
 
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_DESCRIPTION("Intel INT0002 Virtual GPIO driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index c5ece7ef08c6df36b2d1ccff788f99c3cb408abe..225638a1b09e45d762668615cc9de93a0db100ba 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2009-2010 Intel Corporation
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
- *
  * Authors:
  *     Jesse Barnes <jbarnes@virtuousgeek.org>
  */
@@ -1697,6 +1686,6 @@ static struct pci_driver ips_pci_driver = {
 
 module_pci_driver(ips_pci_driver);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
 MODULE_DESCRIPTION("Intelligent Power Sharing Driver");
index 60f4e3ddbe9f5b3f84e02030a57b98793141e615..512ad234ad0d67fccdb05d241d37fd887da164d5 100644 (file)
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2010 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * The full GNU General Public License is included in this distribution in
- * the file called "COPYING".
  */
 
 void ips_link_to_i915_driver(void);
index ef9b0af8cdd36a6adc68fb2f3b835993bfa46ebe..77eb8709c931c03dbeda565b71c65e8d6f1d564e 100644 (file)
@@ -1,25 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- *  intel_menlow.c - Intel menlow Driver for thermal management extension
+ *  Intel menlow Driver for thermal management extension
  *
  *  Copyright (C) 2008 Intel Corp
  *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
  *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  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.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  *  This driver creates the sys I/F for programming the sensors.
  *  It also implements the driver for intel menlow memory controller (hardware
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/acpi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/thermal.h>
-#include <linux/acpi.h>
+#include <linux/types.h>
 
 MODULE_AUTHOR("Thomas Sujith");
 MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Intel Menlow platform specific driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 /*
  * Memory controller device control
index 5ad44204a9c3c997bf237aacfb1bbb99ab292ef7..292bace83f1e3d95a8dae813370b1fc6610bc0df 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Power button driver for Intel MID platforms.
  *
@@ -5,18 +6,8 @@
  *
  * Author: Hong Liu <hong.liu@intel.com>
  * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
  */
 
-#include <linux/init.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/intel_msic.h>
@@ -121,12 +112,9 @@ static const struct mid_pb_ddata mrfld_ddata = {
        .setup  = mrfld_setup,
 };
 
-#define ICPU(model, ddata)     \
-       { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata }
-
 static const struct x86_cpu_id mid_pb_cpu_ids[] = {
-       ICPU(INTEL_FAM6_ATOM_SALTWELL_MID,              mfld_ddata),
-       ICPU(INTEL_FAM6_ATOM_SILVERMONT_MID,    mrfld_ddata),
+       INTEL_CPU_FAM6(ATOM_SALTWELL_MID,       mfld_ddata),
+       INTEL_CPU_FAM6(ATOM_SILVERMONT_MID,     mrfld_ddata),
        {}
 };
 
index 008a76903cbfb62221ac4fd4bb8aaa7b46c56fb1..f402e2e74a38392e9abf1eae8debc3630dcc828c 100644 (file)
@@ -1,39 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * intel_mid_thermal.c - Intel MID platform thermal driver
+ * Intel MID platform thermal driver
  *
  * Copyright (C) 2011 Intel Corporation
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the GNU
- * General Public License for more details.
- *
- * 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.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  * Author: Durgadoss R <durgadoss.r@intel.com>
  */
 
 #define pr_fmt(fmt) "intel_mid_thermal: " fmt
 
-#include <linux/module.h>
-#include <linux/init.h>
+#include <linux/device.h>
 #include <linux/err.h>
+#include <linux/mfd/intel_msic.h>
+#include <linux/module.h>
 #include <linux/param.h>
-#include <linux/device.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/pm.h>
+#include <linux/slab.h>
 #include <linux/thermal.h>
-#include <linux/mfd/intel_msic.h>
 
 /* Number of thermal sensors */
 #define MSIC_THERMAL_SENSORS   4
@@ -567,4 +551,4 @@ module_platform_driver(mid_thermal_driver);
 
 MODULE_AUTHOR("Durgadoss R <durgadoss.r@intel.com>");
 MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 5747f63c8d9f490c51edb31f5fc836ee89dab33f..3c0438ba385ee8494c14a4d24147201e04dcaee6 100644 (file)
@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * intel_oaktrail.c - Intel OakTrail Platform support.
+ * Intel OakTrail Platform support
  *
  * Copyright (C) 2010-2011 Intel Corporation
  * Author: Yin Kangkai (kangkai.yin@intel.com)
@@ -8,21 +9,6 @@
  * <cezary.jackiewicz (at) gmail.com>, based on MSI driver
  * Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
- *
  * This driver does below things:
  * 1. registers itself in the Linux backlight control in
  *    /sys/class/backlight/intel_oaktrail/
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/acpi.h>
-#include <linux/fb.h>
-#include <linux/mutex.h>
+#include <linux/backlight.h>
+#include <linux/dmi.h>
 #include <linux/err.h>
+#include <linux/fb.h>
 #include <linux/i2c.h>
-#include <linux/backlight.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
-#include <linux/dmi.h>
 #include <linux/rfkill.h>
+
 #include <acpi/video.h>
 
 #define DRIVER_NAME    "intel_oaktrail"
index 2d272a3e017621365de7d38dfbfa68bef7d73ab2..6b31d410cb09abeb57aec266a7896c4dbbec1dc3 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel Core SoC Power Management Controller Driver
  *
@@ -6,16 +7,6 @@
  *
  * Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
  *          Vishwanath Somayaji <vishwanath.somayaji@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 93a7e99e1f8b8a0a8d241416c1540cc66c779f20..be045348ad86b2674c3b08b3c1af54b3844ea339 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel Core SoC Power Management Controller Header File
  *
@@ -6,16 +7,6 @@
  *
  * Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
  *          Vishwanath Somayaji <vishwanath.somayaji@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  */
 
 #ifndef PMC_CORE_H
index e7edc8c6393674dfdcfcf53cccb80da50fd255f2..7964ba22ef8d997d31e3cd83af9a56feb90dd088 100644 (file)
@@ -1,39 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * intel_pmc_ipc.c: Driver for the Intel PMC IPC mechanism
+ * Driver for the Intel PMC IPC mechanism
  *
  * (C) Copyright 2014-2015 Intel Corporation
  *
- * This driver is based on Intel SCU IPC driver(intel_scu_opc.c) by
+ * This driver is based on Intel SCU IPC driver(intel_scu_ipc.c) by
  *     Sreedhara DS <sreedhara.ds@intel.com>
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- *
  * PMC running in ARC processor communicates with other entity running in IA
  * core through IPC mechanism which in turn messaging between IA core ad PMC.
  */
 
-#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/atomic.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
 #include <linux/device.h>
-#include <linux/pm.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
-#include <linux/interrupt.h>
+#include <linux/pm.h>
 #include <linux/pm_qos.h>
-#include <linux/kernel.h>
-#include <linux/bitops.h>
 #include <linux/sched.h>
-#include <linux/atomic.h>
-#include <linux/notifier.h>
-#include <linux/suspend.h>
-#include <linux/acpi.h>
-#include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/spinlock.h>
+#include <linux/suspend.h>
 
 #include <asm/intel_pmc_ipc.h>
 
@@ -1029,7 +1024,7 @@ static void __exit intel_pmc_ipc_exit(void)
 
 MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
 MODULE_DESCRIPTION("Intel PMC IPC driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 /* Some modules are dependent on this, so init earlier */
 fs_initcall(intel_pmc_ipc_init);
index 2efeab650345c044371aa7c56624e4d650ea7c93..79671927f4ef6ada5833419c58a8aeb23fd1621f 100644 (file)
@@ -1,25 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for the Intel P-Unit Mailbox IPC mechanism
  *
  * (C) Copyright 2015 Intel Corporation
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * The heart of the P-Unit is the Foxton microcontroller and its firmware,
  * which provide mailbox interface for power management usage.
  */
 
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
 #include <linux/acpi.h>
-#include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
+
 #include <asm/intel_punit_ipc.h>
 
 /* IPC Mailbox registers */
index 75c8fef7a482c41717c69aa8ef98b21ef4dd1043..cdab916fbf92775320400d1879e112dfdc8e4034 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism
+ * Driver for the Intel SCU IPC mechanism
  *
  * (C) Copyright 2008-2010,2015 Intel Corporation
  * Author: Sreedhara DS (sreedhara.ds@intel.com)
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- *
  * SCU running in ARC processor communicates with other entity running in IA
  * core through IPC mechanism which in turn messaging between IA core ad SCU.
  * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and
  * IPC-1 Driver provides an API for power control unit registers (e.g. MSIC)
  * along with other APIs.
  */
+
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/device.h>
-#include <linux/pm.h>
-#include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
 #include <linux/sfi.h>
+
 #include <asm/intel-mid.h>
 #include <asm/intel_scu_ipc.h>
 
index aa454241489c9f541864f34828e19318514d3560..8afe6fa06d7b8d45a1f9f68e5483f1e191f62e91 100644 (file)
@@ -1,32 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism
+ * Driver for the Intel SCU IPC mechanism
  *
  * (C) Copyright 2008-2010 Intel Corporation
  * Author: Sreedhara DS (sreedhara.ds@intel.com)
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- *
- * This driver provides ioctl interfaces to call intel scu ipc driver api
+ * This driver provides IOCTL interfaces to call Intel SCU IPC driver API.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/fs.h>
 #include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/uaccess.h>
 #include <linux/slab.h>
-#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+
 #include <asm/intel_scu_ipc.h>
 
 static int major;
 
-/* ioctl commnds */
+/* IOCTL commands */
 #define        INTE_SCU_IPC_REGISTER_READ      0
 #define INTE_SCU_IPC_REGISTER_WRITE    1
 #define INTE_SCU_IPC_REGISTER_UPDATE   2
index f378621b5fe9d86632a853a33599b1efff88b05a..d4040bb222b485ead8c8caa8a1b3c4463e72dffa 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel SoC Core Telemetry Driver
  * Copyright (C) 2015, Intel Corporation.
  * All Rights Reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  * Telemetry Framework provides platform related PM and performance statistics.
  * This file provides the core telemetry API implementation.
  */
@@ -460,4 +452,4 @@ module_exit(telemetry_module_exit);
 
 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
 MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index cee08f23629245803783734af6229ac18c69e3e6..40bce560eb30d9cf2ca1a348d7b1eece30d00616 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel SOC Telemetry debugfs Driver: Currently supports APL
  * Copyright (c) 2015, Intel Corporation.
  * All Rights Reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  * This file provides the debugfs interfaces for telemetry.
  * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
  * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
@@ -72,9 +64,6 @@
 #define TELEM_IOSS_DX_D0IX_EVTS                25
 #define TELEM_IOSS_PG_EVTS             30
 
-#define TELEM_DEBUGFS_CPU(model, data) \
-       { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data}
-
 #define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
        if (evtlog[index].telem_evtid == (EVTID)) { \
                for (idx = 0; idx < (EVTNUM); idx++) \
@@ -319,8 +308,8 @@ static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
 };
 
 static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
-       TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf),
-       TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT_PLUS, telem_apl_debugfs_conf),
+       INTEL_CPU_FAM6(ATOM_GOLDMONT, telem_apl_debugfs_conf),
+       INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, telem_apl_debugfs_conf),
        {}
 };
 
@@ -951,12 +940,16 @@ static int __init telemetry_debugfs_init(void)
        debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
 
        err = telemetry_pltconfig_valid();
-       if (err < 0)
+       if (err < 0) {
+               pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
                return -ENODEV;
+       }
 
        err = telemetry_debugfs_check_evts();
-       if (err < 0)
+       if (err < 0) {
+               pr_info("telemetry_debugfs_check_evts failed\n");
                return -EINVAL;
+       }
 
        register_pm_notifier(&pm_notifier);
 
@@ -1037,4 +1030,4 @@ module_exit(telemetry_debugfs_exit);
 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
 MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
 MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index fcc6bee51a422a1c95e205f0d2874fc746ed09e2..df8565bad595c72ba7b889a7d50afe2e0e75d9c6 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel SOC Telemetry Platform Driver: Currently supports APL
  * Copyright (c) 2015, Intel Corporation.
  * All Rights Reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  * This file provides the platform specific telemetry implementation for APL.
  * It used the PUNIT and PMC IPC interfaces for configuring the counters.
  * The accumulated results are fetched from SRAM.
@@ -1242,4 +1234,4 @@ module_exit(telemetry_module_exit);
 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
 MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
 MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index a6d5aa0c3c479dbd7f345a3f5666ae0ef72e456d..7b9cc841ab6557157a71691cf131cd43cc7ecb9c 100644 (file)
@@ -1,28 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel Turbo Boost Max Technology 3.0 legacy (non HWP) enumeration driver
  * Copyright (c) 2017, Intel Corporation.
  * All rights reserved.
  *
  * Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/kernel.h>
+#include <linux/cpufeature.h>
+#include <linux/cpuhotplug.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/topology.h>
 #include <linux/workqueue.h>
-#include <linux/cpuhotplug.h>
-#include <linux/cpufeature.h>
+
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 
diff --git a/drivers/platform/x86/lg-laptop.c b/drivers/platform/x86/lg-laptop.c
new file mode 100644 (file)
index 0000000..c0bb1f8
--- /dev/null
@@ -0,0 +1,700 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * lg-laptop.c - LG Gram ACPI features and hotkeys Driver
+ *
+ * Copyright (C) 2018 Matan Ziv-Av <matan@svgalib.org>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#define LED_DEVICE(_name, max) struct led_classdev _name = { \
+       .name           = __stringify(_name),   \
+       .max_brightness = max,                  \
+       .brightness_set = _name##_set,          \
+       .brightness_get = _name##_get,          \
+}
+
+MODULE_AUTHOR("Matan Ziv-Av");
+MODULE_DESCRIPTION("LG WMI Hotkey Driver");
+MODULE_LICENSE("GPL");
+
+#define WMI_EVENT_GUID0        "E4FB94F9-7F2B-4173-AD1A-CD1D95086248"
+#define WMI_EVENT_GUID1        "023B133E-49D1-4E10-B313-698220140DC2"
+#define WMI_EVENT_GUID2        "37BE1AC0-C3F2-4B1F-BFBE-8FDEAF2814D6"
+#define WMI_EVENT_GUID3        "911BAD44-7DF8-4FBB-9319-BABA1C4B293B"
+#define WMI_METHOD_WMAB "C3A72B38-D3EF-42D3-8CBB-D5A57049F66D"
+#define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210"
+#define WMI_EVENT_GUID  WMI_EVENT_GUID0
+
+#define WMAB_METHOD     "\\XINI.WMAB"
+#define WMBB_METHOD     "\\XINI.WMBB"
+#define SB_GGOV_METHOD  "\\_SB.GGOV"
+#define GOV_TLED        0x2020008
+#define WM_GET          1
+#define WM_SET          2
+#define WM_KEY_LIGHT    0x400
+#define WM_TLED         0x404
+#define WM_FN_LOCK      0x407
+#define WM_BATT_LIMIT   0x61
+#define WM_READER_MODE  0xBF
+#define WM_FAN_MODE    0x33
+#define WMBB_USB_CHARGE 0x10B
+#define WMBB_BATT_LIMIT 0x10C
+
+#define PLATFORM_NAME   "lg-laptop"
+
+MODULE_ALIAS("wmi:" WMI_EVENT_GUID0);
+MODULE_ALIAS("wmi:" WMI_EVENT_GUID1);
+MODULE_ALIAS("wmi:" WMI_EVENT_GUID2);
+MODULE_ALIAS("wmi:" WMI_EVENT_GUID3);
+MODULE_ALIAS("wmi:" WMI_METHOD_WMAB);
+MODULE_ALIAS("wmi:" WMI_METHOD_WMBB);
+MODULE_ALIAS("acpi*:LGEX0815:*");
+
+static struct platform_device *pf_device;
+static struct input_dev *wmi_input_dev;
+
+static u32 inited;
+#define INIT_INPUT_WMI_0        0x01
+#define INIT_INPUT_WMI_2        0x02
+#define INIT_INPUT_ACPI         0x04
+#define INIT_TPAD_LED           0x08
+#define INIT_KBD_LED            0x10
+#define INIT_SPARSE_KEYMAP        0x80
+
+static const struct key_entry wmi_keymap[] = {
+       {KE_KEY, 0x70, {KEY_F15} },      /* LG control panel (F1) */
+       {KE_KEY, 0x74, {KEY_F13} },      /* Touchpad toggle (F5) */
+       {KE_KEY, 0xf020000, {KEY_F14} }, /* Read mode (F9) */
+       {KE_KEY, 0x10000000, {KEY_F16} },/* Keyboard backlight (F8) - pressing
+                                         * this key both sends an event and
+                                         * changes backlight level.
+                                         */
+       {KE_KEY, 0x80, {KEY_RFKILL} },
+       {KE_END, 0}
+};
+
+static int ggov(u32 arg0)
+{
+       union acpi_object args[1];
+       union acpi_object *r;
+       acpi_status status;
+       acpi_handle handle;
+       struct acpi_object_list arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       int res;
+
+       args[0].type = ACPI_TYPE_INTEGER;
+       args[0].integer.value = arg0;
+
+       status = acpi_get_handle(NULL, (acpi_string) SB_GGOV_METHOD, &handle);
+       if (ACPI_FAILURE(status)) {
+               pr_err("Cannot get handle");
+               return -ENODEV;
+       }
+
+       arg.count = 1;
+       arg.pointer = args;
+
+       status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
+       if (ACPI_FAILURE(status)) {
+               acpi_handle_err(handle, "GGOV: call failed.\n");
+               return -EINVAL;
+       }
+
+       r = buffer.pointer;
+       if (r->type != ACPI_TYPE_INTEGER) {
+               kfree(r);
+               return -EINVAL;
+       }
+
+       res = r->integer.value;
+       kfree(r);
+
+       return res;
+}
+
+static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2)
+{
+       union acpi_object args[3];
+       acpi_status status;
+       acpi_handle handle;
+       struct acpi_object_list arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+       args[0].type = ACPI_TYPE_INTEGER;
+       args[0].integer.value = method;
+       args[1].type = ACPI_TYPE_INTEGER;
+       args[1].integer.value = arg1;
+       args[2].type = ACPI_TYPE_INTEGER;
+       args[2].integer.value = arg2;
+
+       status = acpi_get_handle(NULL, (acpi_string) WMAB_METHOD, &handle);
+       if (ACPI_FAILURE(status)) {
+               pr_err("Cannot get handle");
+               return NULL;
+       }
+
+       arg.count = 3;
+       arg.pointer = args;
+
+       status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
+       if (ACPI_FAILURE(status)) {
+               acpi_handle_err(handle, "WMAB: call failed.\n");
+               return NULL;
+       }
+
+       return buffer.pointer;
+}
+
+static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2)
+{
+       union acpi_object args[3];
+       acpi_status status;
+       acpi_handle handle;
+       struct acpi_object_list arg;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       u8 buf[32];
+
+       *(u32 *)buf = method_id;
+       *(u32 *)(buf + 4) = arg1;
+       *(u32 *)(buf + 16) = arg2;
+       args[0].type = ACPI_TYPE_INTEGER;
+       args[0].integer.value = 0; /* ignored */
+       args[1].type = ACPI_TYPE_INTEGER;
+       args[1].integer.value = 1; /* Must be 1 or 2. Does not matter which */
+       args[2].type = ACPI_TYPE_BUFFER;
+       args[2].buffer.length = 32;
+       args[2].buffer.pointer = buf;
+
+       status = acpi_get_handle(NULL, (acpi_string)WMBB_METHOD, &handle);
+       if (ACPI_FAILURE(status)) {
+               pr_err("Cannot get handle");
+               return NULL;
+       }
+
+       arg.count = 3;
+       arg.pointer = args;
+
+       status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
+       if (ACPI_FAILURE(status)) {
+               acpi_handle_err(handle, "WMAB: call failed.\n");
+               return NULL;
+       }
+
+       return (union acpi_object *)buffer.pointer;
+}
+
+static void wmi_notify(u32 value, void *context)
+{
+       struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *obj;
+       acpi_status status;
+       long data = (long)context;
+
+       pr_debug("event guid %li\n", data);
+       status = wmi_get_event_data(value, &response);
+       if (ACPI_FAILURE(status)) {
+               pr_err("Bad event status 0x%x\n", status);
+               return;
+       }
+
+       obj = (union acpi_object *)response.pointer;
+       if (!obj)
+               return;
+
+       if (obj->type == ACPI_TYPE_INTEGER) {
+               int eventcode = obj->integer.value;
+               struct key_entry *key;
+
+               key =
+                   sparse_keymap_entry_from_scancode(wmi_input_dev, eventcode);
+               if (key && key->type == KE_KEY)
+                       sparse_keymap_report_entry(wmi_input_dev, key, 1, true);
+       }
+
+       pr_debug("Type: %i    Eventcode: 0x%llx\n", obj->type,
+                obj->integer.value);
+       kfree(response.pointer);
+}
+
+static void wmi_input_setup(void)
+{
+       acpi_status status;
+
+       wmi_input_dev = input_allocate_device();
+       if (wmi_input_dev) {
+               wmi_input_dev->name = "LG WMI hotkeys";
+               wmi_input_dev->phys = "wmi/input0";
+               wmi_input_dev->id.bustype = BUS_HOST;
+
+               if (sparse_keymap_setup(wmi_input_dev, wmi_keymap, NULL) ||
+                   input_register_device(wmi_input_dev)) {
+                       pr_info("Cannot initialize input device");
+                       input_free_device(wmi_input_dev);
+                       return;
+               }
+
+               inited |= INIT_SPARSE_KEYMAP;
+               status = wmi_install_notify_handler(WMI_EVENT_GUID0, wmi_notify,
+                                                   (void *)0);
+               if (ACPI_SUCCESS(status))
+                       inited |= INIT_INPUT_WMI_0;
+
+               status = wmi_install_notify_handler(WMI_EVENT_GUID2, wmi_notify,
+                                                   (void *)2);
+               if (ACPI_SUCCESS(status))
+                       inited |= INIT_INPUT_WMI_2;
+       } else {
+               pr_info("Cannot allocate input device");
+       }
+}
+
+static void acpi_notify(struct acpi_device *device, u32 event)
+{
+       struct key_entry *key;
+
+       acpi_handle_debug(device->handle, "notify: %d\n", event);
+       if (inited & INIT_SPARSE_KEYMAP) {
+               key = sparse_keymap_entry_from_scancode(wmi_input_dev, 0x80);
+               if (key && key->type == KE_KEY)
+                       sparse_keymap_report_entry(wmi_input_dev, key, 1, true);
+       }
+}
+
+static ssize_t fan_mode_store(struct device *dev,
+                             struct device_attribute *attr,
+                             const char *buffer, size_t count)
+{
+       bool value;
+       union acpi_object *r;
+       u32 m;
+       int ret;
+
+       ret = kstrtobool(buffer, &value);
+       if (ret)
+               return ret;
+
+       r = lg_wmab(WM_FAN_MODE, WM_GET, 0);
+       if (!r)
+               return -EIO;
+
+       if (r->type != ACPI_TYPE_INTEGER) {
+               kfree(r);
+               return -EIO;
+       }
+
+       m = r->integer.value;
+       kfree(r);
+       r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4));
+       kfree(r);
+       r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value);
+       kfree(r);
+
+       return count;
+}
+
+static ssize_t fan_mode_show(struct device *dev,
+                            struct device_attribute *attr, char *buffer)
+{
+       unsigned int status;
+       union acpi_object *r;
+
+       r = lg_wmab(WM_FAN_MODE, WM_GET, 0);
+       if (!r)
+               return -EIO;
+
+       if (r->type != ACPI_TYPE_INTEGER) {
+               kfree(r);
+               return -EIO;
+       }
+
+       status = r->integer.value & 0x01;
+       kfree(r);
+
+       return snprintf(buffer, PAGE_SIZE, "%d\n", status);
+}
+
+static ssize_t usb_charge_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buffer, size_t count)
+{
+       bool value;
+       union acpi_object *r;
+       int ret;
+
+       ret = kstrtobool(buffer, &value);
+       if (ret)
+               return ret;
+
+       r = lg_wmbb(WMBB_USB_CHARGE, WM_SET, value);
+       if (!r)
+               return -EIO;
+
+       kfree(r);
+       return count;
+}
+
+static ssize_t usb_charge_show(struct device *dev,
+                              struct device_attribute *attr, char *buffer)
+{
+       unsigned int status;
+       union acpi_object *r;
+
+       r = lg_wmbb(WMBB_USB_CHARGE, WM_GET, 0);
+       if (!r)
+               return -EIO;
+
+       if (r->type != ACPI_TYPE_BUFFER) {
+               kfree(r);
+               return -EIO;
+       }
+
+       status = !!r->buffer.pointer[0x10];
+
+       kfree(r);
+
+       return snprintf(buffer, PAGE_SIZE, "%d\n", status);
+}
+
+static ssize_t reader_mode_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buffer, size_t count)
+{
+       bool value;
+       union acpi_object *r;
+       int ret;
+
+       ret = kstrtobool(buffer, &value);
+       if (ret)
+               return ret;
+
+       r = lg_wmab(WM_READER_MODE, WM_SET, value);
+       if (!r)
+               return -EIO;
+
+       kfree(r);
+       return count;
+}
+
+static ssize_t reader_mode_show(struct device *dev,
+                               struct device_attribute *attr, char *buffer)
+{
+       unsigned int status;
+       union acpi_object *r;
+
+       r = lg_wmab(WM_READER_MODE, WM_GET, 0);
+       if (!r)
+               return -EIO;
+
+       if (r->type != ACPI_TYPE_INTEGER) {
+               kfree(r);
+               return -EIO;
+       }
+
+       status = !!r->integer.value;
+
+       kfree(r);
+
+       return snprintf(buffer, PAGE_SIZE, "%d\n", status);
+}
+
+static ssize_t fn_lock_store(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buffer, size_t count)
+{
+       bool value;
+       union acpi_object *r;
+       int ret;
+
+       ret = kstrtobool(buffer, &value);
+       if (ret)
+               return ret;
+
+       r = lg_wmab(WM_FN_LOCK, WM_SET, value);
+       if (!r)
+               return -EIO;
+
+       kfree(r);
+       return count;
+}
+
+static ssize_t fn_lock_show(struct device *dev,
+                           struct device_attribute *attr, char *buffer)
+{
+       unsigned int status;
+       union acpi_object *r;
+
+       r = lg_wmab(WM_FN_LOCK, WM_GET, 0);
+       if (!r)
+               return -EIO;
+
+       if (r->type != ACPI_TYPE_BUFFER) {
+               kfree(r);
+               return -EIO;
+       }
+
+       status = !!r->buffer.pointer[0];
+       kfree(r);
+
+       return snprintf(buffer, PAGE_SIZE, "%d\n", status);
+}
+
+static ssize_t battery_care_limit_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buffer, size_t count)
+{
+       unsigned long value;
+       int ret;
+
+       ret = kstrtoul(buffer, 10, &value);
+       if (ret)
+               return ret;
+
+       if (value == 100 || value == 80) {
+               union acpi_object *r;
+
+               r = lg_wmab(WM_BATT_LIMIT, WM_SET, value);
+               if (!r)
+                       return -EIO;
+
+               kfree(r);
+               return count;
+       }
+
+       return -EINVAL;
+}
+
+static ssize_t battery_care_limit_show(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buffer)
+{
+       unsigned int status;
+       union acpi_object *r;
+
+       r = lg_wmab(WM_BATT_LIMIT, WM_GET, 0);
+       if (!r)
+               return -EIO;
+
+       if (r->type != ACPI_TYPE_INTEGER) {
+               kfree(r);
+               return -EIO;
+       }
+
+       status = r->integer.value;
+       kfree(r);
+       if (status != 80 && status != 100)
+               status = 0;
+
+       return snprintf(buffer, PAGE_SIZE, "%d\n", status);
+}
+
+static DEVICE_ATTR_RW(fan_mode);
+static DEVICE_ATTR_RW(usb_charge);
+static DEVICE_ATTR_RW(reader_mode);
+static DEVICE_ATTR_RW(fn_lock);
+static DEVICE_ATTR_RW(battery_care_limit);
+
+static struct attribute *dev_attributes[] = {
+       &dev_attr_fan_mode.attr,
+       &dev_attr_usb_charge.attr,
+       &dev_attr_reader_mode.attr,
+       &dev_attr_fn_lock.attr,
+       &dev_attr_battery_care_limit.attr,
+       NULL
+};
+
+static const struct attribute_group dev_attribute_group = {
+       .attrs = dev_attributes,
+};
+
+static void tpad_led_set(struct led_classdev *cdev,
+                        enum led_brightness brightness)
+{
+       union acpi_object *r;
+
+       r = lg_wmab(WM_TLED, WM_SET, brightness > LED_OFF);
+       kfree(r);
+}
+
+static enum led_brightness tpad_led_get(struct led_classdev *cdev)
+{
+       return ggov(GOV_TLED) > 0 ? LED_ON : LED_OFF;
+}
+
+static LED_DEVICE(tpad_led, 1);
+
+static void kbd_backlight_set(struct led_classdev *cdev,
+                             enum led_brightness brightness)
+{
+       u32 val;
+       union acpi_object *r;
+
+       val = 0x22;
+       if (brightness <= LED_OFF)
+               val = 0;
+       if (brightness >= LED_FULL)
+               val = 0x24;
+       r = lg_wmab(WM_KEY_LIGHT, WM_SET, val);
+       kfree(r);
+}
+
+static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
+{
+       union acpi_object *r;
+       int val;
+
+       r = lg_wmab(WM_KEY_LIGHT, WM_GET, 0);
+
+       if (!r)
+               return LED_OFF;
+
+       if (r->type != ACPI_TYPE_BUFFER || r->buffer.pointer[1] != 0x05) {
+               kfree(r);
+               return LED_OFF;
+       }
+
+       switch (r->buffer.pointer[0] & 0x27) {
+       case 0x24:
+               val = LED_FULL;
+               break;
+       case 0x22:
+               val = LED_HALF;
+               break;
+       default:
+               val = LED_OFF;
+       }
+
+       kfree(r);
+
+       return val;
+}
+
+static LED_DEVICE(kbd_backlight, 255);
+
+static void wmi_input_destroy(void)
+{
+       if (inited & INIT_INPUT_WMI_2)
+               wmi_remove_notify_handler(WMI_EVENT_GUID2);
+
+       if (inited & INIT_INPUT_WMI_0)
+               wmi_remove_notify_handler(WMI_EVENT_GUID0);
+
+       if (inited & INIT_SPARSE_KEYMAP)
+               input_unregister_device(wmi_input_dev);
+
+       inited &= ~(INIT_INPUT_WMI_0 | INIT_INPUT_WMI_2 | INIT_SPARSE_KEYMAP);
+}
+
+static struct platform_driver pf_driver = {
+       .driver = {
+                  .name = PLATFORM_NAME,
+       }
+};
+
+static int acpi_add(struct acpi_device *device)
+{
+       int ret;
+
+       if (pf_device)
+               return 0;
+
+       ret = platform_driver_register(&pf_driver);
+       if (ret)
+               return ret;
+
+       pf_device = platform_device_register_simple(PLATFORM_NAME,
+                                                   PLATFORM_DEVID_NONE,
+                                                   NULL, 0);
+       if (IS_ERR(pf_device)) {
+               ret = PTR_ERR(pf_device);
+               pf_device = NULL;
+               pr_err("unable to register platform device\n");
+               goto out_platform_registered;
+       }
+
+       ret = sysfs_create_group(&pf_device->dev.kobj, &dev_attribute_group);
+       if (ret)
+               goto out_platform_device;
+
+       if (!led_classdev_register(&pf_device->dev, &kbd_backlight))
+               inited |= INIT_KBD_LED;
+
+       if (!led_classdev_register(&pf_device->dev, &tpad_led))
+               inited |= INIT_TPAD_LED;
+
+       wmi_input_setup();
+
+       return 0;
+
+out_platform_device:
+       platform_device_unregister(pf_device);
+out_platform_registered:
+       platform_driver_unregister(&pf_driver);
+       return ret;
+}
+
+static int acpi_remove(struct acpi_device *device)
+{
+       sysfs_remove_group(&pf_device->dev.kobj, &dev_attribute_group);
+       if (inited & INIT_KBD_LED)
+               led_classdev_unregister(&kbd_backlight);
+
+       if (inited & INIT_TPAD_LED)
+               led_classdev_unregister(&tpad_led);
+
+       wmi_input_destroy();
+       platform_device_unregister(pf_device);
+       pf_device = NULL;
+       platform_driver_unregister(&pf_driver);
+
+       return 0;
+}
+
+static const struct acpi_device_id device_ids[] = {
+       {"LGEX0815", 0},
+       {"", 0}
+};
+MODULE_DEVICE_TABLE(acpi, device_ids);
+
+static struct acpi_driver acpi_driver = {
+       .name = "LG Gram Laptop Support",
+       .class = "lg-laptop",
+       .ids = device_ids,
+       .ops = {
+               .add = acpi_add,
+               .remove = acpi_remove,
+               .notify = acpi_notify,
+               },
+       .owner = THIS_MODULE,
+};
+
+static int __init acpi_init(void)
+{
+       int result;
+
+       result = acpi_bus_register_driver(&acpi_driver);
+       if (result < 0) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error registering driver\n"));
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static void __exit acpi_exit(void)
+{
+       acpi_bus_unregister_driver(&acpi_driver);
+}
+
+module_init(acpi_init);
+module_exit(acpi_exit);
index d89936c93ba0fe069900d739e6f8d8ac1e02f902..c2c3a1a19879596bd905952a9e028e96ea7cba01 100644 (file)
@@ -575,7 +575,7 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
 
 static
 struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
-       .items = mlxplat_mlxcpld_msn21xx_items,
+       .items = mlxplat_mlxcpld_msn201x_items,
        .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
        .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
        .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
index cb204f9734913a4cc40b656bb125f8ac1e3c22b4..5f2d7ea912b56e89beb0fa75f8d502e1ef3e9f99 100644 (file)
@@ -42,10 +42,13 @@ static const struct ts_dmi_data chuwi_hi8_data = {
 };
 
 static const struct property_entry chuwi_hi8_pro_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 6),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
        PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
        PROPERTY_ENTRY_BOOL("silead,home-button"),
        { }
 };
@@ -56,6 +59,8 @@ static const struct ts_dmi_data chuwi_hi8_pro_data = {
 };
 
 static const struct property_entry chuwi_vi8_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 6),
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
@@ -88,9 +93,9 @@ static const struct ts_dmi_data chuwi_vi10_data = {
 
 static const struct property_entry connect_tablet9_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
-       PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 10),
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 878),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
        PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
        PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"),
@@ -104,8 +109,10 @@ static const struct ts_dmi_data connect_tablet9_data = {
 };
 
 static const struct property_entry cube_iwork8_air_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 900),
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
        PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
        PROPERTY_ENTRY_U32("silead,max-fingers", 10),
@@ -179,11 +186,14 @@ static const struct ts_dmi_data gp_electronic_t701_data = {
 };
 
 static const struct property_entry itworks_tw891_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 5),
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 890),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 896),
        PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
        PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
        { }
 };
 
@@ -207,8 +217,10 @@ static const struct ts_dmi_data jumper_ezpad_6_pro_data = {
 };
 
 static const struct property_entry jumper_ezpad_mini3_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 23),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1138),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
        PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
        PROPERTY_ENTRY_U32("silead,max-fingers", 10),
@@ -237,6 +249,24 @@ static const struct ts_dmi_data onda_obook_20_plus_data = {
        .properties     = onda_obook_20_plus_props,
 };
 
+static const struct property_entry onda_v80_plus_v3_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 22),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1698),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3676-onda-v80-plus-v3.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data onda_v80_plus_v3_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = onda_v80_plus_v3_props,
+};
+
 static const struct property_entry onda_v820w_32g_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
@@ -322,11 +352,14 @@ static const struct ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
 };
 
 static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1794),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
        PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
        PROPERTY_ENTRY_STRING("firmware-name",
                              "gsl3692-pov-mobii-wintab-p800w.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
        PROPERTY_ENTRY_BOOL("silead,home-button"),
        { }
 };
@@ -366,6 +399,22 @@ static const struct ts_dmi_data teclast_x98plus2_data = {
        .properties     = teclast_x98plus2_props,
 };
 
+static const struct property_entry trekstor_primebook_c11_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1970),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1530),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1680-trekstor-primebook-c11.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data trekstor_primebook_c11_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = trekstor_primebook_c11_props,
+};
+
 static const struct property_entry trekstor_primebook_c13_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
@@ -381,6 +430,22 @@ static const struct ts_dmi_data trekstor_primebook_c13_data = {
        .properties     = trekstor_primebook_c13_props,
 };
 
+static const struct property_entry trekstor_primetab_t13b_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 2500),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1900),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1680-trekstor-primetab-t13b.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       { }
+};
+
+static const struct ts_dmi_data trekstor_primetab_t13b_data = {
+       .acpi_name  = "MSSL1680:00",
+       .properties = trekstor_primetab_t13b_props,
+};
+
 static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
@@ -397,6 +462,8 @@ static const struct ts_dmi_data trekstor_surftab_twin_10_1_data = {
 };
 
 static const struct property_entry trekstor_surftab_wintron70_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 12),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
        PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
        PROPERTY_ENTRY_STRING("firmware-name",
@@ -555,6 +622,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
                },
        },
+       {
+               /* ONDA V80 plus v3 (P80PSBG9V3A01501) */
+               .driver_data = (void *)&onda_v80_plus_v3_data,
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONDA"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V80 PLUS")
+               },
+       },
        {
                /* ONDA V820w DualOS */
                .driver_data = (void *)&onda_v820w_32g_data,
@@ -640,6 +715,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
                },
        },
+       {
+               /* Trekstor Primebook C11 */
+               .driver_data = (void *)&trekstor_primebook_c11_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C11"),
+               },
+       },
        {
                /* Trekstor Primebook C13 */
                .driver_data = (void *)&trekstor_primebook_c13_data,
@@ -648,6 +731,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
                },
        },
+       {
+               /* Trekstor Primetab T13B */
+               .driver_data = (void *)&trekstor_primetab_t13b_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Primetab T13B"),
+               },
+       },
        {
                /* TrekStor SurfTab twin 10.1 ST10432-8 */
                .driver_data = (void *)&trekstor_surftab_twin_10_1_data,
index 04791ea5d97b69f9ed9fc30fb7de46cf2370acbe..bea35be68706d733cf156b993fe0a8b3d3a675e5 100644 (file)
@@ -987,19 +987,19 @@ static struct bus_type wmi_bus_type = {
        .remove = wmi_dev_remove,
 };
 
-static struct device_type wmi_type_event = {
+static const struct device_type wmi_type_event = {
        .name = "event",
        .groups = wmi_event_groups,
        .release = wmi_dev_release,
 };
 
-static struct device_type wmi_type_method = {
+static const struct device_type wmi_type_method = {
        .name = "method",
        .groups = wmi_method_groups,
        .release = wmi_dev_release,
 };
 
-static struct device_type wmi_type_data = {
+static const struct device_type wmi_type_data = {
        .name = "data",
        .groups = wmi_data_groups,
        .release = wmi_dev_release,
index 052d4dd347f90c185916b5db0708c20379be599d..f0abd2608044738bb2ebd9e6e25fcea10074c5cf 100644 (file)
@@ -84,8 +84,16 @@ config KEYSTONE_REMOTEPROC
          It's safe to say N here if you're not interested in the Keystone
          DSPs or just want to use a bare minimum kernel.
 
-config QCOM_ADSP_PIL
-       tristate "Qualcomm ADSP Peripheral Image Loader"
+config QCOM_RPROC_COMMON
+       tristate
+
+config QCOM_Q6V5_COMMON
+       tristate
+       depends on ARCH_QCOM
+       depends on QCOM_SMEM
+
+config QCOM_Q6V5_ADSP
+       tristate "Qualcomm Technology Inc ADSP Peripheral Image Loader"
        depends on OF && ARCH_QCOM
        depends on QCOM_SMEM
        depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
@@ -95,33 +103,41 @@ config QCOM_ADSP_PIL
        select QCOM_MDT_LOADER
        select QCOM_Q6V5_COMMON
        select QCOM_RPROC_COMMON
-       select QCOM_SCM
        help
-         Say y here to support the TrustZone based Peripherial Image Loader
-         for the Qualcomm ADSP remote processors.
+         Say y here to support the Peripheral Image Loader
+         for the Qualcomm Technology Inc. ADSP remote processors.
 
-config QCOM_RPROC_COMMON
-       tristate
-
-config QCOM_Q6V5_COMMON
-       tristate
-       depends on ARCH_QCOM
+config QCOM_Q6V5_MSS
+       tristate "Qualcomm Hexagon V5 self-authenticating modem subsystem support"
+       depends on OF && ARCH_QCOM
        depends on QCOM_SMEM
+       depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
+       depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
+       depends on QCOM_SYSMON || QCOM_SYSMON=n
+       select MFD_SYSCON
+       select QCOM_Q6V5_COMMON
+       select QCOM_RPROC_COMMON
+       select QCOM_SCM
+       help
+         Say y here to support the Qualcomm self-authenticating modem
+         subsystem based on Hexagon V5.
 
-config QCOM_Q6V5_PIL
-       tristate "Qualcomm Hexagon V5 Peripherial Image Loader"
+config QCOM_Q6V5_PAS
+       tristate "Qualcomm Hexagon v5 Peripheral Authentication Service support"
        depends on OF && ARCH_QCOM
        depends on QCOM_SMEM
        depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
        depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
        depends on QCOM_SYSMON || QCOM_SYSMON=n
        select MFD_SYSCON
+       select QCOM_MDT_LOADER
        select QCOM_Q6V5_COMMON
        select QCOM_RPROC_COMMON
        select QCOM_SCM
        help
-         Say y here to support the Qualcomm Peripherial Image Loader for the
-         Hexagon V5 based remote processors.
+         Say y here to support the TrustZone based Peripherial Image Loader
+         for the Qualcomm Hexagon v5 based remote processors. This is commonly
+         used to control subsystems such as ADSP, Compute and Sensor.
 
 config QCOM_Q6V5_WCSS
        tristate "Qualcomm Hexagon based WCSS Peripheral Image Loader"
index 03332fa7e2ee7515d5281c175e632d4a600b3382..ce5d061e92be525e1ded20a97c98e5d9e21406e3 100644 (file)
@@ -14,10 +14,11 @@ obj-$(CONFIG_OMAP_REMOTEPROC)               += omap_remoteproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)            += wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)         += da8xx_remoteproc.o
 obj-$(CONFIG_KEYSTONE_REMOTEPROC)      += keystone_remoteproc.o
-obj-$(CONFIG_QCOM_ADSP_PIL)            += qcom_adsp_pil.o
 obj-$(CONFIG_QCOM_RPROC_COMMON)                += qcom_common.o
 obj-$(CONFIG_QCOM_Q6V5_COMMON)         += qcom_q6v5.o
-obj-$(CONFIG_QCOM_Q6V5_PIL)            += qcom_q6v5_pil.o
+obj-$(CONFIG_QCOM_Q6V5_ADSP)           += qcom_q6v5_adsp.o
+obj-$(CONFIG_QCOM_Q6V5_MSS)            += qcom_q6v5_mss.o
+obj-$(CONFIG_QCOM_Q6V5_PAS)            += qcom_q6v5_pas.o
 obj-$(CONFIG_QCOM_Q6V5_WCSS)           += qcom_q6v5_wcss.o
 obj-$(CONFIG_QCOM_SYSMON)              += qcom_sysmon.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)           += qcom_wcnss_pil.o
index e230bef71be1c67abb92e44ca540545bdf3333ff..d200334577f68f79e0a0c990a8d9044b6409d85b 100644 (file)
@@ -226,7 +226,7 @@ static int da8xx_rproc_get_internal_memories(struct platform_device *pdev,
                                res->start & DA8XX_RPROC_LOCAL_ADDRESS_MASK;
                drproc->mem[i].size = resource_size(res);
 
-               dev_dbg(dev, "memory %8s: bus addr %pa size 0x%x va %p da 0x%x\n",
+               dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
                        mem_names[i], &drproc->mem[i].bus_addr,
                        drproc->mem[i].size, drproc->mem[i].cpu_addr,
                        drproc->mem[i].dev_addr);
diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c
deleted file mode 100644 (file)
index d4339a6..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
- *
- * Copyright (C) 2016 Linaro Ltd
- * Copyright (C) 2014 Sony Mobile Communications AB
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/firmware.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/qcom_scm.h>
-#include <linux/regulator/consumer.h>
-#include <linux/remoteproc.h>
-#include <linux/soc/qcom/mdt_loader.h>
-#include <linux/soc/qcom/smem.h>
-#include <linux/soc/qcom/smem_state.h>
-
-#include "qcom_common.h"
-#include "qcom_q6v5.h"
-#include "remoteproc_internal.h"
-
-struct adsp_data {
-       int crash_reason_smem;
-       const char *firmware_name;
-       int pas_id;
-       bool has_aggre2_clk;
-
-       const char *ssr_name;
-       const char *sysmon_name;
-       int ssctl_id;
-};
-
-struct qcom_adsp {
-       struct device *dev;
-       struct rproc *rproc;
-
-       struct qcom_q6v5 q6v5;
-
-       struct clk *xo;
-       struct clk *aggre2_clk;
-
-       struct regulator *cx_supply;
-       struct regulator *px_supply;
-
-       int pas_id;
-       int crash_reason_smem;
-       bool has_aggre2_clk;
-
-       struct completion start_done;
-       struct completion stop_done;
-
-       phys_addr_t mem_phys;
-       phys_addr_t mem_reloc;
-       void *mem_region;
-       size_t mem_size;
-
-       struct qcom_rproc_glink glink_subdev;
-       struct qcom_rproc_subdev smd_subdev;
-       struct qcom_rproc_ssr ssr_subdev;
-       struct qcom_sysmon *sysmon;
-};
-
-static int adsp_load(struct rproc *rproc, const struct firmware *fw)
-{
-       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
-
-       return qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
-                            adsp->mem_region, adsp->mem_phys, adsp->mem_size,
-                            &adsp->mem_reloc);
-
-}
-
-static int adsp_start(struct rproc *rproc)
-{
-       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
-       int ret;
-
-       qcom_q6v5_prepare(&adsp->q6v5);
-
-       ret = clk_prepare_enable(adsp->xo);
-       if (ret)
-               return ret;
-
-       ret = clk_prepare_enable(adsp->aggre2_clk);
-       if (ret)
-               goto disable_xo_clk;
-
-       ret = regulator_enable(adsp->cx_supply);
-       if (ret)
-               goto disable_aggre2_clk;
-
-       ret = regulator_enable(adsp->px_supply);
-       if (ret)
-               goto disable_cx_supply;
-
-       ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
-       if (ret) {
-               dev_err(adsp->dev,
-                       "failed to authenticate image and release reset\n");
-               goto disable_px_supply;
-       }
-
-       ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
-       if (ret == -ETIMEDOUT) {
-               dev_err(adsp->dev, "start timed out\n");
-               qcom_scm_pas_shutdown(adsp->pas_id);
-               goto disable_px_supply;
-       }
-
-       return 0;
-
-disable_px_supply:
-       regulator_disable(adsp->px_supply);
-disable_cx_supply:
-       regulator_disable(adsp->cx_supply);
-disable_aggre2_clk:
-       clk_disable_unprepare(adsp->aggre2_clk);
-disable_xo_clk:
-       clk_disable_unprepare(adsp->xo);
-
-       return ret;
-}
-
-static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
-{
-       struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
-
-       regulator_disable(adsp->px_supply);
-       regulator_disable(adsp->cx_supply);
-       clk_disable_unprepare(adsp->aggre2_clk);
-       clk_disable_unprepare(adsp->xo);
-}
-
-static int adsp_stop(struct rproc *rproc)
-{
-       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
-       int handover;
-       int ret;
-
-       ret = qcom_q6v5_request_stop(&adsp->q6v5);
-       if (ret == -ETIMEDOUT)
-               dev_err(adsp->dev, "timed out on wait\n");
-
-       ret = qcom_scm_pas_shutdown(adsp->pas_id);
-       if (ret)
-               dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
-
-       handover = qcom_q6v5_unprepare(&adsp->q6v5);
-       if (handover)
-               qcom_pas_handover(&adsp->q6v5);
-
-       return ret;
-}
-
-static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len)
-{
-       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
-       int offset;
-
-       offset = da - adsp->mem_reloc;
-       if (offset < 0 || offset + len > adsp->mem_size)
-               return NULL;
-
-       return adsp->mem_region + offset;
-}
-
-static const struct rproc_ops adsp_ops = {
-       .start = adsp_start,
-       .stop = adsp_stop,
-       .da_to_va = adsp_da_to_va,
-       .parse_fw = qcom_register_dump_segments,
-       .load = adsp_load,
-};
-
-static int adsp_init_clock(struct qcom_adsp *adsp)
-{
-       int ret;
-
-       adsp->xo = devm_clk_get(adsp->dev, "xo");
-       if (IS_ERR(adsp->xo)) {
-               ret = PTR_ERR(adsp->xo);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(adsp->dev, "failed to get xo clock");
-               return ret;
-       }
-
-       if (adsp->has_aggre2_clk) {
-               adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2");
-               if (IS_ERR(adsp->aggre2_clk)) {
-                       ret = PTR_ERR(adsp->aggre2_clk);
-                       if (ret != -EPROBE_DEFER)
-                               dev_err(adsp->dev,
-                                       "failed to get aggre2 clock");
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-static int adsp_init_regulator(struct qcom_adsp *adsp)
-{
-       adsp->cx_supply = devm_regulator_get(adsp->dev, "cx");
-       if (IS_ERR(adsp->cx_supply))
-               return PTR_ERR(adsp->cx_supply);
-
-       regulator_set_load(adsp->cx_supply, 100000);
-
-       adsp->px_supply = devm_regulator_get(adsp->dev, "px");
-       return PTR_ERR_OR_ZERO(adsp->px_supply);
-}
-
-static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
-{
-       struct device_node *node;
-       struct resource r;
-       int ret;
-
-       node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
-       if (!node) {
-               dev_err(adsp->dev, "no memory-region specified\n");
-               return -EINVAL;
-       }
-
-       ret = of_address_to_resource(node, 0, &r);
-       if (ret)
-               return ret;
-
-       adsp->mem_phys = adsp->mem_reloc = r.start;
-       adsp->mem_size = resource_size(&r);
-       adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
-       if (!adsp->mem_region) {
-               dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
-                       &r.start, adsp->mem_size);
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-static int adsp_probe(struct platform_device *pdev)
-{
-       const struct adsp_data *desc;
-       struct qcom_adsp *adsp;
-       struct rproc *rproc;
-       int ret;
-
-       desc = of_device_get_match_data(&pdev->dev);
-       if (!desc)
-               return -EINVAL;
-
-       if (!qcom_scm_is_available())
-               return -EPROBE_DEFER;
-
-       rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
-                           desc->firmware_name, sizeof(*adsp));
-       if (!rproc) {
-               dev_err(&pdev->dev, "unable to allocate remoteproc\n");
-               return -ENOMEM;
-       }
-
-       adsp = (struct qcom_adsp *)rproc->priv;
-       adsp->dev = &pdev->dev;
-       adsp->rproc = rproc;
-       adsp->pas_id = desc->pas_id;
-       adsp->has_aggre2_clk = desc->has_aggre2_clk;
-       platform_set_drvdata(pdev, adsp);
-
-       ret = adsp_alloc_memory_region(adsp);
-       if (ret)
-               goto free_rproc;
-
-       ret = adsp_init_clock(adsp);
-       if (ret)
-               goto free_rproc;
-
-       ret = adsp_init_regulator(adsp);
-       if (ret)
-               goto free_rproc;
-
-       ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
-                            qcom_pas_handover);
-       if (ret)
-               goto free_rproc;
-
-       qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
-       qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
-       qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
-       adsp->sysmon = qcom_add_sysmon_subdev(rproc,
-                                             desc->sysmon_name,
-                                             desc->ssctl_id);
-
-       ret = rproc_add(rproc);
-       if (ret)
-               goto free_rproc;
-
-       return 0;
-
-free_rproc:
-       rproc_free(rproc);
-
-       return ret;
-}
-
-static int adsp_remove(struct platform_device *pdev)
-{
-       struct qcom_adsp *adsp = platform_get_drvdata(pdev);
-
-       rproc_del(adsp->rproc);
-
-       qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
-       qcom_remove_sysmon_subdev(adsp->sysmon);
-       qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
-       qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
-       rproc_free(adsp->rproc);
-
-       return 0;
-}
-
-static const struct adsp_data adsp_resource_init = {
-               .crash_reason_smem = 423,
-               .firmware_name = "adsp.mdt",
-               .pas_id = 1,
-               .has_aggre2_clk = false,
-               .ssr_name = "lpass",
-               .sysmon_name = "adsp",
-               .ssctl_id = 0x14,
-};
-
-static const struct adsp_data slpi_resource_init = {
-               .crash_reason_smem = 424,
-               .firmware_name = "slpi.mdt",
-               .pas_id = 12,
-               .has_aggre2_clk = true,
-               .ssr_name = "dsps",
-               .sysmon_name = "slpi",
-               .ssctl_id = 0x16,
-};
-
-static const struct of_device_id adsp_of_match[] = {
-       { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
-       { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
-       { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
-       { },
-};
-MODULE_DEVICE_TABLE(of, adsp_of_match);
-
-static struct platform_driver adsp_driver = {
-       .probe = adsp_probe,
-       .remove = adsp_remove,
-       .driver = {
-               .name = "qcom_adsp_pil",
-               .of_match_table = adsp_of_match,
-       },
-};
-
-module_platform_driver(adsp_driver);
-MODULE_DESCRIPTION("Qualcomm MSM8974/MSM8996 ADSP Peripherial Image Loader");
-MODULE_LICENSE("GPL v2");
index 61a760ee4aacc9c526defdf73df7806a46258b74..0d33e3079f0dc2abb0cab3bca2a8bf46a885d58f 100644 (file)
@@ -84,6 +84,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *data)
        else
                dev_err(q6v5->dev, "fatal error without message\n");
 
+       q6v5->running = false;
        rproc_report_crash(q6v5->rproc, RPROC_FATAL_ERROR);
 
        return IRQ_HANDLED;
@@ -150,8 +151,6 @@ int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5)
 {
        int ret;
 
-       q6v5->running = false;
-
        qcom_smem_state_update_bits(q6v5->state,
                                    BIT(q6v5->stop_bit), BIT(q6v5->stop_bit));
 
@@ -188,6 +187,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
        init_completion(&q6v5->stop_done);
 
        q6v5->wdog_irq = platform_get_irq_byname(pdev, "wdog");
+       if (q6v5->wdog_irq < 0) {
+               if (q6v5->wdog_irq != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "failed to retrieve wdog IRQ: %d\n",
+                               q6v5->wdog_irq);
+               return q6v5->wdog_irq;
+       }
+
        ret = devm_request_threaded_irq(&pdev->dev, q6v5->wdog_irq,
                                        NULL, q6v5_wdog_interrupt,
                                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -198,6 +205,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
        }
 
        q6v5->fatal_irq = platform_get_irq_byname(pdev, "fatal");
+       if (q6v5->fatal_irq < 0) {
+               if (q6v5->fatal_irq != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "failed to retrieve fatal IRQ: %d\n",
+                               q6v5->fatal_irq);
+               return q6v5->fatal_irq;
+       }
+
        ret = devm_request_threaded_irq(&pdev->dev, q6v5->fatal_irq,
                                        NULL, q6v5_fatal_interrupt,
                                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -208,6 +223,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
        }
 
        q6v5->ready_irq = platform_get_irq_byname(pdev, "ready");
+       if (q6v5->ready_irq < 0) {
+               if (q6v5->ready_irq != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "failed to retrieve ready IRQ: %d\n",
+                               q6v5->ready_irq);
+               return q6v5->ready_irq;
+       }
+
        ret = devm_request_threaded_irq(&pdev->dev, q6v5->ready_irq,
                                        NULL, q6v5_ready_interrupt,
                                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -218,6 +241,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
        }
 
        q6v5->handover_irq = platform_get_irq_byname(pdev, "handover");
+       if (q6v5->handover_irq < 0) {
+               if (q6v5->handover_irq != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "failed to retrieve handover IRQ: %d\n",
+                               q6v5->handover_irq);
+               return q6v5->handover_irq;
+       }
+
        ret = devm_request_threaded_irq(&pdev->dev, q6v5->handover_irq,
                                        NULL, q6v5_handover_interrupt,
                                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -229,6 +260,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev,
        disable_irq(q6v5->handover_irq);
 
        q6v5->stop_irq = platform_get_irq_byname(pdev, "stop-ack");
+       if (q6v5->stop_irq < 0) {
+               if (q6v5->stop_irq != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "failed to retrieve stop-ack IRQ: %d\n",
+                               q6v5->stop_irq);
+               return q6v5->stop_irq;
+       }
+
        ret = devm_request_threaded_irq(&pdev->dev, q6v5->stop_irq,
                                        NULL, q6v5_stop_interrupt,
                                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
new file mode 100644 (file)
index 0000000..79374d1
--- /dev/null
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm Technology Inc. ADSP Peripheral Image Loader for SDM845.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/soc/qcom/smem_state.h>
+
+#include "qcom_common.h"
+#include "qcom_q6v5.h"
+#include "remoteproc_internal.h"
+
+/* time out value */
+#define ACK_TIMEOUT                    1000
+#define BOOT_FSM_TIMEOUT               10000
+/* mask values */
+#define EVB_MASK                       GENMASK(27, 4)
+/*QDSP6SS register offsets*/
+#define RST_EVB_REG                    0x10
+#define CORE_START_REG                 0x400
+#define BOOT_CMD_REG                   0x404
+#define BOOT_STATUS_REG                        0x408
+#define RET_CFG_REG                    0x1C
+/*TCSR register offsets*/
+#define LPASS_MASTER_IDLE_REG          0x8
+#define LPASS_HALTACK_REG              0x4
+#define LPASS_PWR_ON_REG               0x10
+#define LPASS_HALTREQ_REG              0x0
+
+/* list of clocks required by ADSP PIL */
+static const char * const adsp_clk_id[] = {
+       "sway_cbcr", "lpass_aon", "lpass_ahbs_aon_cbcr", "lpass_ahbm_aon_cbcr",
+       "qdsp6ss_xo", "qdsp6ss_sleep", "qdsp6ss_core",
+};
+
+struct adsp_pil_data {
+       int crash_reason_smem;
+       const char *firmware_name;
+
+       const char *ssr_name;
+       const char *sysmon_name;
+       int ssctl_id;
+};
+
+struct qcom_adsp {
+       struct device *dev;
+       struct rproc *rproc;
+
+       struct qcom_q6v5 q6v5;
+
+       struct clk *xo;
+
+       int num_clks;
+       struct clk_bulk_data *clks;
+
+       void __iomem *qdsp6ss_base;
+
+       struct reset_control *pdc_sync_reset;
+       struct reset_control *cc_lpass_restart;
+
+       struct regmap *halt_map;
+       unsigned int halt_lpass;
+
+       int crash_reason_smem;
+
+       struct completion start_done;
+       struct completion stop_done;
+
+       phys_addr_t mem_phys;
+       phys_addr_t mem_reloc;
+       void *mem_region;
+       size_t mem_size;
+
+       struct qcom_rproc_glink glink_subdev;
+       struct qcom_rproc_ssr ssr_subdev;
+       struct qcom_sysmon *sysmon;
+};
+
+static int qcom_adsp_shutdown(struct qcom_adsp *adsp)
+{
+       unsigned long timeout;
+       unsigned int val;
+       int ret;
+
+       /* Reset the retention logic */
+       val = readl(adsp->qdsp6ss_base + RET_CFG_REG);
+       val |= 0x1;
+       writel(val, adsp->qdsp6ss_base + RET_CFG_REG);
+
+       clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
+
+       /* QDSP6 master port needs to be explicitly halted */
+       ret = regmap_read(adsp->halt_map,
+                       adsp->halt_lpass + LPASS_PWR_ON_REG, &val);
+       if (ret || !val)
+               goto reset;
+
+       ret = regmap_read(adsp->halt_map,
+                       adsp->halt_lpass + LPASS_MASTER_IDLE_REG,
+                       &val);
+       if (ret || val)
+               goto reset;
+
+       regmap_write(adsp->halt_map,
+                       adsp->halt_lpass + LPASS_HALTREQ_REG, 1);
+
+       /* Wait for halt ACK from QDSP6 */
+       timeout = jiffies + msecs_to_jiffies(ACK_TIMEOUT);
+       for (;;) {
+               ret = regmap_read(adsp->halt_map,
+                       adsp->halt_lpass + LPASS_HALTACK_REG, &val);
+               if (ret || val || time_after(jiffies, timeout))
+                       break;
+
+               usleep_range(1000, 1100);
+       }
+
+       ret = regmap_read(adsp->halt_map,
+                       adsp->halt_lpass + LPASS_MASTER_IDLE_REG, &val);
+       if (ret || !val)
+               dev_err(adsp->dev, "port failed halt\n");
+
+reset:
+       /* Assert the LPASS PDC Reset */
+       reset_control_assert(adsp->pdc_sync_reset);
+       /* Place the LPASS processor into reset */
+       reset_control_assert(adsp->cc_lpass_restart);
+       /* wait after asserting subsystem restart from AOSS */
+       usleep_range(200, 300);
+
+       /* Clear the halt request for the AXIM and AHBM for Q6 */
+       regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0);
+
+       /* De-assert the LPASS PDC Reset */
+       reset_control_deassert(adsp->pdc_sync_reset);
+       /* Remove the LPASS reset */
+       reset_control_deassert(adsp->cc_lpass_restart);
+       /* wait after de-asserting subsystem restart from AOSS */
+       usleep_range(200, 300);
+
+       return 0;
+}
+
+static int adsp_load(struct rproc *rproc, const struct firmware *fw)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+
+       return qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, 0,
+                            adsp->mem_region, adsp->mem_phys, adsp->mem_size,
+                            &adsp->mem_reloc);
+}
+
+static int adsp_start(struct rproc *rproc)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+       int ret;
+       unsigned int val;
+
+       qcom_q6v5_prepare(&adsp->q6v5);
+
+       ret = clk_prepare_enable(adsp->xo);
+       if (ret)
+               goto disable_irqs;
+
+       dev_pm_genpd_set_performance_state(adsp->dev, INT_MAX);
+       ret = pm_runtime_get_sync(adsp->dev);
+       if (ret)
+               goto disable_xo_clk;
+
+       ret = clk_bulk_prepare_enable(adsp->num_clks, adsp->clks);
+       if (ret) {
+               dev_err(adsp->dev, "adsp clk_enable failed\n");
+               goto disable_power_domain;
+       }
+
+       /* Program boot address */
+       writel(adsp->mem_phys >> 4, adsp->qdsp6ss_base + RST_EVB_REG);
+
+       /* De-assert QDSP6 stop core. QDSP6 will execute after out of reset */
+       writel(0x1, adsp->qdsp6ss_base + CORE_START_REG);
+
+       /* Trigger boot FSM to start QDSP6 */
+       writel(0x1, adsp->qdsp6ss_base + BOOT_CMD_REG);
+
+       /* Wait for core to come out of reset */
+       ret = readl_poll_timeout(adsp->qdsp6ss_base + BOOT_STATUS_REG,
+                       val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
+       if (ret) {
+               dev_err(adsp->dev, "failed to bootup adsp\n");
+               goto disable_adsp_clks;
+       }
+
+       ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5 * HZ));
+       if (ret == -ETIMEDOUT) {
+               dev_err(adsp->dev, "start timed out\n");
+               goto disable_adsp_clks;
+       }
+
+       return 0;
+
+disable_adsp_clks:
+       clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
+disable_power_domain:
+       dev_pm_genpd_set_performance_state(adsp->dev, 0);
+       pm_runtime_put(adsp->dev);
+disable_xo_clk:
+       clk_disable_unprepare(adsp->xo);
+disable_irqs:
+       qcom_q6v5_unprepare(&adsp->q6v5);
+
+       return ret;
+}
+
+static void qcom_adsp_pil_handover(struct qcom_q6v5 *q6v5)
+{
+       struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
+
+       clk_disable_unprepare(adsp->xo);
+       dev_pm_genpd_set_performance_state(adsp->dev, 0);
+       pm_runtime_put(adsp->dev);
+}
+
+static int adsp_stop(struct rproc *rproc)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+       int handover;
+       int ret;
+
+       ret = qcom_q6v5_request_stop(&adsp->q6v5);
+       if (ret == -ETIMEDOUT)
+               dev_err(adsp->dev, "timed out on wait\n");
+
+       ret = qcom_adsp_shutdown(adsp);
+       if (ret)
+               dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
+
+       handover = qcom_q6v5_unprepare(&adsp->q6v5);
+       if (handover)
+               qcom_adsp_pil_handover(&adsp->q6v5);
+
+       return ret;
+}
+
+static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+       int offset;
+
+       offset = da - adsp->mem_reloc;
+       if (offset < 0 || offset + len > adsp->mem_size)
+               return NULL;
+
+       return adsp->mem_region + offset;
+}
+
+static const struct rproc_ops adsp_ops = {
+       .start = adsp_start,
+       .stop = adsp_stop,
+       .da_to_va = adsp_da_to_va,
+       .parse_fw = qcom_register_dump_segments,
+       .load = adsp_load,
+};
+
+static int adsp_init_clock(struct qcom_adsp *adsp)
+{
+       int i, ret;
+
+       adsp->xo = devm_clk_get(adsp->dev, "xo");
+       if (IS_ERR(adsp->xo)) {
+               ret = PTR_ERR(adsp->xo);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(adsp->dev, "failed to get xo clock");
+               return ret;
+       }
+
+       adsp->num_clks = ARRAY_SIZE(adsp_clk_id);
+       adsp->clks = devm_kcalloc(adsp->dev, adsp->num_clks,
+                               sizeof(*adsp->clks), GFP_KERNEL);
+       if (!adsp->clks)
+               return -ENOMEM;
+
+       for (i = 0; i < adsp->num_clks; i++)
+               adsp->clks[i].id = adsp_clk_id[i];
+
+       return devm_clk_bulk_get(adsp->dev, adsp->num_clks, adsp->clks);
+}
+
+static int adsp_init_reset(struct qcom_adsp *adsp)
+{
+       adsp->pdc_sync_reset = devm_reset_control_get_exclusive(adsp->dev,
+                       "pdc_sync");
+       if (IS_ERR(adsp->pdc_sync_reset)) {
+               dev_err(adsp->dev, "failed to acquire pdc_sync reset\n");
+               return PTR_ERR(adsp->pdc_sync_reset);
+       }
+
+       adsp->cc_lpass_restart = devm_reset_control_get_exclusive(adsp->dev,
+                       "cc_lpass");
+       if (IS_ERR(adsp->cc_lpass_restart)) {
+               dev_err(adsp->dev, "failed to acquire cc_lpass restart\n");
+               return PTR_ERR(adsp->cc_lpass_restart);
+       }
+
+       return 0;
+}
+
+static int adsp_init_mmio(struct qcom_adsp *adsp,
+                               struct platform_device *pdev)
+{
+       struct device_node *syscon;
+       struct resource *res;
+       int ret;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       adsp->qdsp6ss_base = devm_ioremap(&pdev->dev, res->start,
+                       resource_size(res));
+       if (!adsp->qdsp6ss_base) {
+               dev_err(adsp->dev, "failed to map QDSP6SS registers\n");
+               return -ENOMEM;
+       }
+
+       syscon = of_parse_phandle(pdev->dev.of_node, "qcom,halt-regs", 0);
+       if (!syscon) {
+               dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
+               return -EINVAL;
+       }
+
+       adsp->halt_map = syscon_node_to_regmap(syscon);
+       of_node_put(syscon);
+       if (IS_ERR(adsp->halt_map))
+               return PTR_ERR(adsp->halt_map);
+
+       ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,halt-regs",
+                       1, &adsp->halt_lpass);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "no offset in syscon\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
+{
+       struct device_node *node;
+       struct resource r;
+       int ret;
+
+       node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
+       if (!node) {
+               dev_err(adsp->dev, "no memory-region specified\n");
+               return -EINVAL;
+       }
+
+       ret = of_address_to_resource(node, 0, &r);
+       if (ret)
+               return ret;
+
+       adsp->mem_phys = adsp->mem_reloc = r.start;
+       adsp->mem_size = resource_size(&r);
+       adsp->mem_region = devm_ioremap_wc(adsp->dev,
+                               adsp->mem_phys, adsp->mem_size);
+       if (!adsp->mem_region) {
+               dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
+                       &r.start, adsp->mem_size);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static int adsp_probe(struct platform_device *pdev)
+{
+       const struct adsp_pil_data *desc;
+       struct qcom_adsp *adsp;
+       struct rproc *rproc;
+       int ret;
+
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
+
+       rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
+                           desc->firmware_name, sizeof(*adsp));
+       if (!rproc) {
+               dev_err(&pdev->dev, "unable to allocate remoteproc\n");
+               return -ENOMEM;
+       }
+
+       adsp = (struct qcom_adsp *)rproc->priv;
+       adsp->dev = &pdev->dev;
+       adsp->rproc = rproc;
+       platform_set_drvdata(pdev, adsp);
+
+       ret = adsp_alloc_memory_region(adsp);
+       if (ret)
+               goto free_rproc;
+
+       ret = adsp_init_clock(adsp);
+       if (ret)
+               goto free_rproc;
+
+       pm_runtime_enable(adsp->dev);
+
+       ret = adsp_init_reset(adsp);
+       if (ret)
+               goto disable_pm;
+
+       ret = adsp_init_mmio(adsp, pdev);
+       if (ret)
+               goto disable_pm;
+
+       ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
+                            qcom_adsp_pil_handover);
+       if (ret)
+               goto disable_pm;
+
+       qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
+       qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
+       adsp->sysmon = qcom_add_sysmon_subdev(rproc,
+                                             desc->sysmon_name,
+                                             desc->ssctl_id);
+
+       ret = rproc_add(rproc);
+       if (ret)
+               goto disable_pm;
+
+       return 0;
+
+disable_pm:
+       pm_runtime_disable(adsp->dev);
+free_rproc:
+       rproc_free(rproc);
+
+       return ret;
+}
+
+static int adsp_remove(struct platform_device *pdev)
+{
+       struct qcom_adsp *adsp = platform_get_drvdata(pdev);
+
+       rproc_del(adsp->rproc);
+
+       qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
+       qcom_remove_sysmon_subdev(adsp->sysmon);
+       qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
+       pm_runtime_disable(adsp->dev);
+       rproc_free(adsp->rproc);
+
+       return 0;
+}
+
+static const struct adsp_pil_data adsp_resource_init = {
+       .crash_reason_smem = 423,
+       .firmware_name = "adsp.mdt",
+       .ssr_name = "lpass",
+       .sysmon_name = "adsp",
+       .ssctl_id = 0x14,
+};
+
+static const struct of_device_id adsp_of_match[] = {
+       { .compatible = "qcom,sdm845-adsp-pil", .data = &adsp_resource_init },
+       { },
+};
+MODULE_DEVICE_TABLE(of, adsp_of_match);
+
+static struct platform_driver adsp_pil_driver = {
+       .probe = adsp_probe,
+       .remove = adsp_remove,
+       .driver = {
+               .name = "qcom_q6v5_adsp",
+               .of_match_table = adsp_of_match,
+       },
+};
+
+module_platform_driver(adsp_pil_driver);
+MODULE_DESCRIPTION("QTI SDM845 ADSP Peripheral Image Loader");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
new file mode 100644 (file)
index 0000000..01be731
--- /dev/null
@@ -0,0 +1,1508 @@
+/*
+ * Qualcomm self-authenticating modem subsystem remoteproc driver
+ *
+ * Copyright (C) 2016 Linaro Ltd.
+ * Copyright (C) 2014 Sony Mobile Communications AB
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/iopoll.h>
+
+#include "remoteproc_internal.h"
+#include "qcom_common.h"
+#include "qcom_q6v5.h"
+
+#include <linux/qcom_scm.h>
+
+#define MPSS_CRASH_REASON_SMEM         421
+
+/* RMB Status Register Values */
+#define RMB_PBL_SUCCESS                        0x1
+
+#define RMB_MBA_XPU_UNLOCKED           0x1
+#define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2
+#define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3
+#define RMB_MBA_AUTH_COMPLETE          0x4
+
+/* PBL/MBA interface registers */
+#define RMB_MBA_IMAGE_REG              0x00
+#define RMB_PBL_STATUS_REG             0x04
+#define RMB_MBA_COMMAND_REG            0x08
+#define RMB_MBA_STATUS_REG             0x0C
+#define RMB_PMI_META_DATA_REG          0x10
+#define RMB_PMI_CODE_START_REG         0x14
+#define RMB_PMI_CODE_LENGTH_REG                0x18
+#define RMB_MBA_MSS_STATUS             0x40
+#define RMB_MBA_ALT_RESET              0x44
+
+#define RMB_CMD_META_DATA_READY                0x1
+#define RMB_CMD_LOAD_READY             0x2
+
+/* QDSP6SS Register Offsets */
+#define QDSP6SS_RESET_REG              0x014
+#define QDSP6SS_GFMUX_CTL_REG          0x020
+#define QDSP6SS_PWR_CTL_REG            0x030
+#define QDSP6SS_MEM_PWR_CTL            0x0B0
+#define QDSP6SS_STRAP_ACC              0x110
+
+/* AXI Halt Register Offsets */
+#define AXI_HALTREQ_REG                        0x0
+#define AXI_HALTACK_REG                        0x4
+#define AXI_IDLE_REG                   0x8
+
+#define HALT_ACK_TIMEOUT_MS            100
+
+/* QDSP6SS_RESET */
+#define Q6SS_STOP_CORE                 BIT(0)
+#define Q6SS_CORE_ARES                 BIT(1)
+#define Q6SS_BUS_ARES_ENABLE           BIT(2)
+
+/* QDSP6SS_GFMUX_CTL */
+#define Q6SS_CLK_ENABLE                        BIT(1)
+
+/* QDSP6SS_PWR_CTL */
+#define Q6SS_L2DATA_SLP_NRET_N_0       BIT(0)
+#define Q6SS_L2DATA_SLP_NRET_N_1       BIT(1)
+#define Q6SS_L2DATA_SLP_NRET_N_2       BIT(2)
+#define Q6SS_L2TAG_SLP_NRET_N          BIT(16)
+#define Q6SS_ETB_SLP_NRET_N            BIT(17)
+#define Q6SS_L2DATA_STBY_N             BIT(18)
+#define Q6SS_SLP_RET_N                 BIT(19)
+#define Q6SS_CLAMP_IO                  BIT(20)
+#define QDSS_BHS_ON                    BIT(21)
+#define QDSS_LDO_BYP                   BIT(22)
+
+/* QDSP6v56 parameters */
+#define QDSP6v56_LDO_BYP               BIT(25)
+#define QDSP6v56_BHS_ON                BIT(24)
+#define QDSP6v56_CLAMP_WL              BIT(21)
+#define QDSP6v56_CLAMP_QMC_MEM         BIT(22)
+#define HALT_CHECK_MAX_LOOPS           200
+#define QDSP6SS_XO_CBCR                0x0038
+#define QDSP6SS_ACC_OVERRIDE_VAL               0x20
+
+/* QDSP6v65 parameters */
+#define QDSP6SS_SLEEP                   0x3C
+#define QDSP6SS_BOOT_CORE_START         0x400
+#define QDSP6SS_BOOT_CMD                0x404
+#define SLEEP_CHECK_MAX_LOOPS           200
+#define BOOT_FSM_TIMEOUT                10000
+
+struct reg_info {
+       struct regulator *reg;
+       int uV;
+       int uA;
+};
+
+struct qcom_mss_reg_res {
+       const char *supply;
+       int uV;
+       int uA;
+};
+
+struct rproc_hexagon_res {
+       const char *hexagon_mba_image;
+       struct qcom_mss_reg_res *proxy_supply;
+       struct qcom_mss_reg_res *active_supply;
+       char **proxy_clk_names;
+       char **reset_clk_names;
+       char **active_clk_names;
+       int version;
+       bool need_mem_protection;
+       bool has_alt_reset;
+};
+
+struct q6v5 {
+       struct device *dev;
+       struct rproc *rproc;
+
+       void __iomem *reg_base;
+       void __iomem *rmb_base;
+
+       struct regmap *halt_map;
+       u32 halt_q6;
+       u32 halt_modem;
+       u32 halt_nc;
+
+       struct reset_control *mss_restart;
+       struct reset_control *pdc_reset;
+
+       struct qcom_q6v5 q6v5;
+
+       struct clk *active_clks[8];
+       struct clk *reset_clks[4];
+       struct clk *proxy_clks[4];
+       int active_clk_count;
+       int reset_clk_count;
+       int proxy_clk_count;
+
+       struct reg_info active_regs[1];
+       struct reg_info proxy_regs[3];
+       int active_reg_count;
+       int proxy_reg_count;
+
+       bool running;
+
+       bool dump_mba_loaded;
+       unsigned long dump_segment_mask;
+       unsigned long dump_complete_mask;
+
+       phys_addr_t mba_phys;
+       void *mba_region;
+       size_t mba_size;
+
+       phys_addr_t mpss_phys;
+       phys_addr_t mpss_reloc;
+       void *mpss_region;
+       size_t mpss_size;
+
+       struct qcom_rproc_glink glink_subdev;
+       struct qcom_rproc_subdev smd_subdev;
+       struct qcom_rproc_ssr ssr_subdev;
+       struct qcom_sysmon *sysmon;
+       bool need_mem_protection;
+       bool has_alt_reset;
+       int mpss_perm;
+       int mba_perm;
+       int version;
+};
+
+enum {
+       MSS_MSM8916,
+       MSS_MSM8974,
+       MSS_MSM8996,
+       MSS_SDM845,
+};
+
+static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
+                              const struct qcom_mss_reg_res *reg_res)
+{
+       int rc;
+       int i;
+
+       if (!reg_res)
+               return 0;
+
+       for (i = 0; reg_res[i].supply; i++) {
+               regs[i].reg = devm_regulator_get(dev, reg_res[i].supply);
+               if (IS_ERR(regs[i].reg)) {
+                       rc = PTR_ERR(regs[i].reg);
+                       if (rc != -EPROBE_DEFER)
+                               dev_err(dev, "Failed to get %s\n regulator",
+                                       reg_res[i].supply);
+                       return rc;
+               }
+
+               regs[i].uV = reg_res[i].uV;
+               regs[i].uA = reg_res[i].uA;
+       }
+
+       return i;
+}
+
+static int q6v5_regulator_enable(struct q6v5 *qproc,
+                                struct reg_info *regs, int count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               if (regs[i].uV > 0) {
+                       ret = regulator_set_voltage(regs[i].reg,
+                                       regs[i].uV, INT_MAX);
+                       if (ret) {
+                               dev_err(qproc->dev,
+                                       "Failed to request voltage for %d.\n",
+                                               i);
+                               goto err;
+                       }
+               }
+
+               if (regs[i].uA > 0) {
+                       ret = regulator_set_load(regs[i].reg,
+                                                regs[i].uA);
+                       if (ret < 0) {
+                               dev_err(qproc->dev,
+                                       "Failed to set regulator mode\n");
+                               goto err;
+                       }
+               }
+
+               ret = regulator_enable(regs[i].reg);
+               if (ret) {
+                       dev_err(qproc->dev, "Regulator enable failed\n");
+                       goto err;
+               }
+       }
+
+       return 0;
+err:
+       for (; i >= 0; i--) {
+               if (regs[i].uV > 0)
+                       regulator_set_voltage(regs[i].reg, 0, INT_MAX);
+
+               if (regs[i].uA > 0)
+                       regulator_set_load(regs[i].reg, 0);
+
+               regulator_disable(regs[i].reg);
+       }
+
+       return ret;
+}
+
+static void q6v5_regulator_disable(struct q6v5 *qproc,
+                                  struct reg_info *regs, int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++) {
+               if (regs[i].uV > 0)
+                       regulator_set_voltage(regs[i].reg, 0, INT_MAX);
+
+               if (regs[i].uA > 0)
+                       regulator_set_load(regs[i].reg, 0);
+
+               regulator_disable(regs[i].reg);
+       }
+}
+
+static int q6v5_clk_enable(struct device *dev,
+                          struct clk **clks, int count)
+{
+       int rc;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               rc = clk_prepare_enable(clks[i]);
+               if (rc) {
+                       dev_err(dev, "Clock enable failed\n");
+                       goto err;
+               }
+       }
+
+       return 0;
+err:
+       for (i--; i >= 0; i--)
+               clk_disable_unprepare(clks[i]);
+
+       return rc;
+}
+
+static void q6v5_clk_disable(struct device *dev,
+                            struct clk **clks, int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++)
+               clk_disable_unprepare(clks[i]);
+}
+
+static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm,
+                                  bool remote_owner, phys_addr_t addr,
+                                  size_t size)
+{
+       struct qcom_scm_vmperm next;
+
+       if (!qproc->need_mem_protection)
+               return 0;
+       if (remote_owner && *current_perm == BIT(QCOM_SCM_VMID_MSS_MSA))
+               return 0;
+       if (!remote_owner && *current_perm == BIT(QCOM_SCM_VMID_HLOS))
+               return 0;
+
+       next.vmid = remote_owner ? QCOM_SCM_VMID_MSS_MSA : QCOM_SCM_VMID_HLOS;
+       next.perm = remote_owner ? QCOM_SCM_PERM_RW : QCOM_SCM_PERM_RWX;
+
+       return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K),
+                                  current_perm, &next, 1);
+}
+
+static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
+{
+       struct q6v5 *qproc = rproc->priv;
+
+       memcpy(qproc->mba_region, fw->data, fw->size);
+
+       return 0;
+}
+
+static int q6v5_reset_assert(struct q6v5 *qproc)
+{
+       int ret;
+
+       if (qproc->has_alt_reset) {
+               reset_control_assert(qproc->pdc_reset);
+               ret = reset_control_reset(qproc->mss_restart);
+               reset_control_deassert(qproc->pdc_reset);
+       } else {
+               ret = reset_control_assert(qproc->mss_restart);
+       }
+
+       return ret;
+}
+
+static int q6v5_reset_deassert(struct q6v5 *qproc)
+{
+       int ret;
+
+       if (qproc->has_alt_reset) {
+               reset_control_assert(qproc->pdc_reset);
+               writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET);
+               ret = reset_control_reset(qproc->mss_restart);
+               writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
+               reset_control_deassert(qproc->pdc_reset);
+       } else {
+               ret = reset_control_deassert(qproc->mss_restart);
+       }
+
+       return ret;
+}
+
+static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
+{
+       unsigned long timeout;
+       s32 val;
+
+       timeout = jiffies + msecs_to_jiffies(ms);
+       for (;;) {
+               val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG);
+               if (val)
+                       break;
+
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+       }
+
+       return val;
+}
+
+static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms)
+{
+
+       unsigned long timeout;
+       s32 val;
+
+       timeout = jiffies + msecs_to_jiffies(ms);
+       for (;;) {
+               val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
+               if (val < 0)
+                       break;
+
+               if (!status && val)
+                       break;
+               else if (status && val == status)
+                       break;
+
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
+
+               msleep(1);
+       }
+
+       return val;
+}
+
+static int q6v5proc_reset(struct q6v5 *qproc)
+{
+       u32 val;
+       int ret;
+       int i;
+
+       if (qproc->version == MSS_SDM845) {
+               val = readl(qproc->reg_base + QDSP6SS_SLEEP);
+               val |= 0x1;
+               writel(val, qproc->reg_base + QDSP6SS_SLEEP);
+
+               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
+                                        val, !(val & BIT(31)), 1,
+                                        SLEEP_CHECK_MAX_LOOPS);
+               if (ret) {
+                       dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
+                       return -ETIMEDOUT;
+               }
+
+               /* De-assert QDSP6 stop core */
+               writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
+               /* Trigger boot FSM */
+               writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
+
+               ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
+                               val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
+               if (ret) {
+                       dev_err(qproc->dev, "Boot FSM failed to complete.\n");
+                       /* Reset the modem so that boot FSM is in reset state */
+                       q6v5_reset_deassert(qproc);
+                       return ret;
+               }
+
+               goto pbl_wait;
+       } else if (qproc->version == MSS_MSM8996) {
+               /* Override the ACC value if required */
+               writel(QDSP6SS_ACC_OVERRIDE_VAL,
+                      qproc->reg_base + QDSP6SS_STRAP_ACC);
+
+               /* Assert resets, stop core */
+               val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
+               val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
+               writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
+
+               /* BHS require xo cbcr to be enabled */
+               val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
+               val |= 0x1;
+               writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
+
+               /* Read CLKOFF bit to go low indicating CLK is enabled */
+               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
+                                        val, !(val & BIT(31)), 1,
+                                        HALT_CHECK_MAX_LOOPS);
+               if (ret) {
+                       dev_err(qproc->dev,
+                               "xo cbcr enabling timed out (rc:%d)\n", ret);
+                       return ret;
+               }
+               /* Enable power block headswitch and wait for it to stabilize */
+               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= QDSP6v56_BHS_ON;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               udelay(1);
+
+               /* Put LDO in bypass mode */
+               val |= QDSP6v56_LDO_BYP;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+               /* Deassert QDSP6 compiler memory clamp */
+               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val &= ~QDSP6v56_CLAMP_QMC_MEM;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+               /* Deassert memory peripheral sleep and L2 memory standby */
+               val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+               /* Turn on L1, L2, ETB and JU memories 1 at a time */
+               val = readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL);
+               for (i = 19; i >= 0; i--) {
+                       val |= BIT(i);
+                       writel(val, qproc->reg_base +
+                                               QDSP6SS_MEM_PWR_CTL);
+                       /*
+                        * Read back value to ensure the write is done then
+                        * wait for 1us for both memory peripheral and data
+                        * array to turn on.
+                        */
+                       val |= readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL);
+                       udelay(1);
+               }
+               /* Remove word line clamp */
+               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val &= ~QDSP6v56_CLAMP_WL;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+       } else {
+               /* Assert resets, stop core */
+               val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
+               val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
+               writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
+
+               /* Enable power block headswitch and wait for it to stabilize */
+               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= QDSS_BHS_ON | QDSS_LDO_BYP;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               udelay(1);
+               /*
+                * Turn on memories. L2 banks should be done individually
+                * to minimize inrush current.
+                */
+               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
+                       Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= Q6SS_L2DATA_SLP_NRET_N_2;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= Q6SS_L2DATA_SLP_NRET_N_1;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= Q6SS_L2DATA_SLP_NRET_N_0;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+       }
+       /* Remove IO clamp */
+       val &= ~Q6SS_CLAMP_IO;
+       writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+       /* Bring core out of reset */
+       val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
+       val &= ~Q6SS_CORE_ARES;
+       writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
+
+       /* Turn on core clock */
+       val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
+       val |= Q6SS_CLK_ENABLE;
+       writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
+
+       /* Start core execution */
+       val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
+       val &= ~Q6SS_STOP_CORE;
+       writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
+
+pbl_wait:
+       /* Wait for PBL status */
+       ret = q6v5_rmb_pbl_wait(qproc, 1000);
+       if (ret == -ETIMEDOUT) {
+               dev_err(qproc->dev, "PBL boot timed out\n");
+       } else if (ret != RMB_PBL_SUCCESS) {
+               dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret);
+               ret = -EINVAL;
+       } else {
+               ret = 0;
+       }
+
+       return ret;
+}
+
+static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
+                                  struct regmap *halt_map,
+                                  u32 offset)
+{
+       unsigned long timeout;
+       unsigned int val;
+       int ret;
+
+       /* Check if we're already idle */
+       ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
+       if (!ret && val)
+               return;
+
+       /* Assert halt request */
+       regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1);
+
+       /* Wait for halt */
+       timeout = jiffies + msecs_to_jiffies(HALT_ACK_TIMEOUT_MS);
+       for (;;) {
+               ret = regmap_read(halt_map, offset + AXI_HALTACK_REG, &val);
+               if (ret || val || time_after(jiffies, timeout))
+                       break;
+
+               msleep(1);
+       }
+
+       ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
+       if (ret || !val)
+               dev_err(qproc->dev, "port failed halt\n");
+
+       /* Clear halt request (port will remain halted until reset) */
+       regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
+}
+
+static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
+{
+       unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
+       dma_addr_t phys;
+       int mdata_perm;
+       int xferop_ret;
+       void *ptr;
+       int ret;
+
+       ptr = dma_alloc_attrs(qproc->dev, fw->size, &phys, GFP_KERNEL, dma_attrs);
+       if (!ptr) {
+               dev_err(qproc->dev, "failed to allocate mdt buffer\n");
+               return -ENOMEM;
+       }
+
+       memcpy(ptr, fw->data, fw->size);
+
+       /* Hypervisor mapping to access metadata by modem */
+       mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
+       ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm,
+                                     true, phys, fw->size);
+       if (ret) {
+               dev_err(qproc->dev,
+                       "assigning Q6 access to metadata failed: %d\n", ret);
+               ret = -EAGAIN;
+               goto free_dma_attrs;
+       }
+
+       writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG);
+       writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
+
+       ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
+       if (ret == -ETIMEDOUT)
+               dev_err(qproc->dev, "MPSS header authentication timed out\n");
+       else if (ret < 0)
+               dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
+
+       /* Metadata authentication done, remove modem access */
+       xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm,
+                                            false, phys, fw->size);
+       if (xferop_ret)
+               dev_warn(qproc->dev,
+                        "mdt buffer not reclaimed system may become unstable\n");
+
+free_dma_attrs:
+       dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
+
+       return ret < 0 ? ret : 0;
+}
+
+static bool q6v5_phdr_valid(const struct elf32_phdr *phdr)
+{
+       if (phdr->p_type != PT_LOAD)
+               return false;
+
+       if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
+               return false;
+
+       if (!phdr->p_memsz)
+               return false;
+
+       return true;
+}
+
+static int q6v5_mba_load(struct q6v5 *qproc)
+{
+       int ret;
+       int xfermemop_ret;
+
+       qcom_q6v5_prepare(&qproc->q6v5);
+
+       ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
+                                   qproc->proxy_reg_count);
+       if (ret) {
+               dev_err(qproc->dev, "failed to enable proxy supplies\n");
+               goto disable_irqs;
+       }
+
+       ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
+                             qproc->proxy_clk_count);
+       if (ret) {
+               dev_err(qproc->dev, "failed to enable proxy clocks\n");
+               goto disable_proxy_reg;
+       }
+
+       ret = q6v5_regulator_enable(qproc, qproc->active_regs,
+                                   qproc->active_reg_count);
+       if (ret) {
+               dev_err(qproc->dev, "failed to enable supplies\n");
+               goto disable_proxy_clk;
+       }
+
+       ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks,
+                             qproc->reset_clk_count);
+       if (ret) {
+               dev_err(qproc->dev, "failed to enable reset clocks\n");
+               goto disable_vdd;
+       }
+
+       ret = q6v5_reset_deassert(qproc);
+       if (ret) {
+               dev_err(qproc->dev, "failed to deassert mss restart\n");
+               goto disable_reset_clks;
+       }
+
+       ret = q6v5_clk_enable(qproc->dev, qproc->active_clks,
+                             qproc->active_clk_count);
+       if (ret) {
+               dev_err(qproc->dev, "failed to enable clocks\n");
+               goto assert_reset;
+       }
+
+       /* Assign MBA image access in DDR to q6 */
+       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
+                                     qproc->mba_phys, qproc->mba_size);
+       if (ret) {
+               dev_err(qproc->dev,
+                       "assigning Q6 access to mba memory failed: %d\n", ret);
+               goto disable_active_clks;
+       }
+
+       writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
+
+       ret = q6v5proc_reset(qproc);
+       if (ret)
+               goto reclaim_mba;
+
+       ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
+       if (ret == -ETIMEDOUT) {
+               dev_err(qproc->dev, "MBA boot timed out\n");
+               goto halt_axi_ports;
+       } else if (ret != RMB_MBA_XPU_UNLOCKED &&
+                  ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) {
+               dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret);
+               ret = -EINVAL;
+               goto halt_axi_ports;
+       }
+
+       qproc->dump_mba_loaded = true;
+       return 0;
+
+halt_axi_ports:
+       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
+       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
+       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
+
+reclaim_mba:
+       xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false,
+                                               qproc->mba_phys,
+                                               qproc->mba_size);
+       if (xfermemop_ret) {
+               dev_err(qproc->dev,
+                       "Failed to reclaim mba buffer, system may become unstable\n");
+       }
+
+disable_active_clks:
+       q6v5_clk_disable(qproc->dev, qproc->active_clks,
+                        qproc->active_clk_count);
+assert_reset:
+       q6v5_reset_assert(qproc);
+disable_reset_clks:
+       q6v5_clk_disable(qproc->dev, qproc->reset_clks,
+                        qproc->reset_clk_count);
+disable_vdd:
+       q6v5_regulator_disable(qproc, qproc->active_regs,
+                              qproc->active_reg_count);
+disable_proxy_clk:
+       q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
+                        qproc->proxy_clk_count);
+disable_proxy_reg:
+       q6v5_regulator_disable(qproc, qproc->proxy_regs,
+                              qproc->proxy_reg_count);
+disable_irqs:
+       qcom_q6v5_unprepare(&qproc->q6v5);
+
+       return ret;
+}
+
+static void q6v5_mba_reclaim(struct q6v5 *qproc)
+{
+       int ret;
+       u32 val;
+
+       qproc->dump_mba_loaded = false;
+
+       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
+       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
+       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
+       if (qproc->version == MSS_MSM8996) {
+               /*
+                * To avoid high MX current during LPASS/MSS restart.
+                */
+               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+               val |= Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL |
+                       QDSP6v56_CLAMP_QMC_MEM;
+               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+       }
+
+       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
+                                     false, qproc->mpss_phys,
+                                     qproc->mpss_size);
+       WARN_ON(ret);
+
+       q6v5_reset_assert(qproc);
+
+       q6v5_clk_disable(qproc->dev, qproc->reset_clks,
+                        qproc->reset_clk_count);
+       q6v5_clk_disable(qproc->dev, qproc->active_clks,
+                        qproc->active_clk_count);
+       q6v5_regulator_disable(qproc, qproc->active_regs,
+                              qproc->active_reg_count);
+
+       /* In case of failure or coredump scenario where reclaiming MBA memory
+        * could not happen reclaim it here.
+        */
+       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false,
+                                     qproc->mba_phys,
+                                     qproc->mba_size);
+       WARN_ON(ret);
+
+       ret = qcom_q6v5_unprepare(&qproc->q6v5);
+       if (ret) {
+               q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
+                                qproc->proxy_clk_count);
+               q6v5_regulator_disable(qproc, qproc->proxy_regs,
+                                      qproc->proxy_reg_count);
+       }
+}
+
+static int q6v5_mpss_load(struct q6v5 *qproc)
+{
+       const struct elf32_phdr *phdrs;
+       const struct elf32_phdr *phdr;
+       const struct firmware *seg_fw;
+       const struct firmware *fw;
+       struct elf32_hdr *ehdr;
+       phys_addr_t mpss_reloc;
+       phys_addr_t boot_addr;
+       phys_addr_t min_addr = PHYS_ADDR_MAX;
+       phys_addr_t max_addr = 0;
+       bool relocate = false;
+       char seg_name[10];
+       ssize_t offset;
+       size_t size = 0;
+       void *ptr;
+       int ret;
+       int i;
+
+       ret = request_firmware(&fw, "modem.mdt", qproc->dev);
+       if (ret < 0) {
+               dev_err(qproc->dev, "unable to load modem.mdt\n");
+               return ret;
+       }
+
+       /* Initialize the RMB validator */
+       writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
+
+       ret = q6v5_mpss_init_image(qproc, fw);
+       if (ret)
+               goto release_firmware;
+
+       ehdr = (struct elf32_hdr *)fw->data;
+       phdrs = (struct elf32_phdr *)(ehdr + 1);
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               phdr = &phdrs[i];
+
+               if (!q6v5_phdr_valid(phdr))
+                       continue;
+
+               if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
+                       relocate = true;
+
+               if (phdr->p_paddr < min_addr)
+                       min_addr = phdr->p_paddr;
+
+               if (phdr->p_paddr + phdr->p_memsz > max_addr)
+                       max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
+       }
+
+       mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
+       qproc->mpss_reloc = mpss_reloc;
+       /* Load firmware segments */
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               phdr = &phdrs[i];
+
+               if (!q6v5_phdr_valid(phdr))
+                       continue;
+
+               offset = phdr->p_paddr - mpss_reloc;
+               if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) {
+                       dev_err(qproc->dev, "segment outside memory range\n");
+                       ret = -EINVAL;
+                       goto release_firmware;
+               }
+
+               ptr = qproc->mpss_region + offset;
+
+               if (phdr->p_filesz) {
+                       snprintf(seg_name, sizeof(seg_name), "modem.b%02d", i);
+                       ret = request_firmware(&seg_fw, seg_name, qproc->dev);
+                       if (ret) {
+                               dev_err(qproc->dev, "failed to load %s\n", seg_name);
+                               goto release_firmware;
+                       }
+
+                       memcpy(ptr, seg_fw->data, seg_fw->size);
+
+                       release_firmware(seg_fw);
+               }
+
+               if (phdr->p_memsz > phdr->p_filesz) {
+                       memset(ptr + phdr->p_filesz, 0,
+                              phdr->p_memsz - phdr->p_filesz);
+               }
+               size += phdr->p_memsz;
+       }
+
+       /* Transfer ownership of modem ddr region to q6 */
+       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true,
+                                     qproc->mpss_phys, qproc->mpss_size);
+       if (ret) {
+               dev_err(qproc->dev,
+                       "assigning Q6 access to mpss memory failed: %d\n", ret);
+               ret = -EAGAIN;
+               goto release_firmware;
+       }
+
+       boot_addr = relocate ? qproc->mpss_phys : min_addr;
+       writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
+       writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
+       writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
+
+       ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
+       if (ret == -ETIMEDOUT)
+               dev_err(qproc->dev, "MPSS authentication timed out\n");
+       else if (ret < 0)
+               dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret);
+
+release_firmware:
+       release_firmware(fw);
+
+       return ret < 0 ? ret : 0;
+}
+
+static void qcom_q6v5_dump_segment(struct rproc *rproc,
+                                  struct rproc_dump_segment *segment,
+                                  void *dest)
+{
+       int ret = 0;
+       struct q6v5 *qproc = rproc->priv;
+       unsigned long mask = BIT((unsigned long)segment->priv);
+       void *ptr = rproc_da_to_va(rproc, segment->da, segment->size);
+
+       /* Unlock mba before copying segments */
+       if (!qproc->dump_mba_loaded)
+               ret = q6v5_mba_load(qproc);
+
+       if (!ptr || ret)
+               memset(dest, 0xff, segment->size);
+       else
+               memcpy(dest, ptr, segment->size);
+
+       qproc->dump_segment_mask |= mask;
+
+       /* Reclaim mba after copying segments */
+       if (qproc->dump_segment_mask == qproc->dump_complete_mask) {
+               if (qproc->dump_mba_loaded)
+                       q6v5_mba_reclaim(qproc);
+       }
+}
+
+static int q6v5_start(struct rproc *rproc)
+{
+       struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
+       int xfermemop_ret;
+       int ret;
+
+       ret = q6v5_mba_load(qproc);
+       if (ret)
+               return ret;
+
+       dev_info(qproc->dev, "MBA booted, loading mpss\n");
+
+       ret = q6v5_mpss_load(qproc);
+       if (ret)
+               goto reclaim_mpss;
+
+       ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000));
+       if (ret == -ETIMEDOUT) {
+               dev_err(qproc->dev, "start timed out\n");
+               goto reclaim_mpss;
+       }
+
+       xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false,
+                                               qproc->mba_phys,
+                                               qproc->mba_size);
+       if (xfermemop_ret)
+               dev_err(qproc->dev,
+                       "Failed to reclaim mba buffer system may become unstable\n");
+
+       /* Reset Dump Segment Mask */
+       qproc->dump_segment_mask = 0;
+       qproc->running = true;
+
+       return 0;
+
+reclaim_mpss:
+       xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
+                                               false, qproc->mpss_phys,
+                                               qproc->mpss_size);
+       WARN_ON(xfermemop_ret);
+       q6v5_mba_reclaim(qproc);
+
+       return ret;
+}
+
+static int q6v5_stop(struct rproc *rproc)
+{
+       struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
+       int ret;
+
+       qproc->running = false;
+
+       ret = qcom_q6v5_request_stop(&qproc->q6v5);
+       if (ret == -ETIMEDOUT)
+               dev_err(qproc->dev, "timed out on wait\n");
+
+       q6v5_mba_reclaim(qproc);
+
+       return 0;
+}
+
+static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+       struct q6v5 *qproc = rproc->priv;
+       int offset;
+
+       offset = da - qproc->mpss_reloc;
+       if (offset < 0 || offset + len > qproc->mpss_size)
+               return NULL;
+
+       return qproc->mpss_region + offset;
+}
+
+static int qcom_q6v5_register_dump_segments(struct rproc *rproc,
+                                           const struct firmware *mba_fw)
+{
+       const struct firmware *fw;
+       const struct elf32_phdr *phdrs;
+       const struct elf32_phdr *phdr;
+       const struct elf32_hdr *ehdr;
+       struct q6v5 *qproc = rproc->priv;
+       unsigned long i;
+       int ret;
+
+       ret = request_firmware(&fw, "modem.mdt", qproc->dev);
+       if (ret < 0) {
+               dev_err(qproc->dev, "unable to load modem.mdt\n");
+               return ret;
+       }
+
+       ehdr = (struct elf32_hdr *)fw->data;
+       phdrs = (struct elf32_phdr *)(ehdr + 1);
+       qproc->dump_complete_mask = 0;
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               phdr = &phdrs[i];
+
+               if (!q6v5_phdr_valid(phdr))
+                       continue;
+
+               ret = rproc_coredump_add_custom_segment(rproc, phdr->p_paddr,
+                                                       phdr->p_memsz,
+                                                       qcom_q6v5_dump_segment,
+                                                       (void *)i);
+               if (ret)
+                       break;
+
+               qproc->dump_complete_mask |= BIT(i);
+       }
+
+       release_firmware(fw);
+       return ret;
+}
+
+static const struct rproc_ops q6v5_ops = {
+       .start = q6v5_start,
+       .stop = q6v5_stop,
+       .da_to_va = q6v5_da_to_va,
+       .parse_fw = qcom_q6v5_register_dump_segments,
+       .load = q6v5_load,
+};
+
+static void qcom_msa_handover(struct qcom_q6v5 *q6v5)
+{
+       struct q6v5 *qproc = container_of(q6v5, struct q6v5, q6v5);
+
+       q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
+                        qproc->proxy_clk_count);
+       q6v5_regulator_disable(qproc, qproc->proxy_regs,
+                              qproc->proxy_reg_count);
+}
+
+static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
+{
+       struct of_phandle_args args;
+       struct resource *res;
+       int ret;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
+       qproc->reg_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(qproc->reg_base))
+               return PTR_ERR(qproc->reg_base);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");
+       qproc->rmb_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(qproc->rmb_base))
+               return PTR_ERR(qproc->rmb_base);
+
+       ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+                                              "qcom,halt-regs", 3, 0, &args);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
+               return -EINVAL;
+       }
+
+       qproc->halt_map = syscon_node_to_regmap(args.np);
+       of_node_put(args.np);
+       if (IS_ERR(qproc->halt_map))
+               return PTR_ERR(qproc->halt_map);
+
+       qproc->halt_q6 = args.args[0];
+       qproc->halt_modem = args.args[1];
+       qproc->halt_nc = args.args[2];
+
+       return 0;
+}
+
+static int q6v5_init_clocks(struct device *dev, struct clk **clks,
+               char **clk_names)
+{
+       int i;
+
+       if (!clk_names)
+               return 0;
+
+       for (i = 0; clk_names[i]; i++) {
+               clks[i] = devm_clk_get(dev, clk_names[i]);
+               if (IS_ERR(clks[i])) {
+                       int rc = PTR_ERR(clks[i]);
+
+                       if (rc != -EPROBE_DEFER)
+                               dev_err(dev, "Failed to get %s clock\n",
+                                       clk_names[i]);
+                       return rc;
+               }
+       }
+
+       return i;
+}
+
+static int q6v5_init_reset(struct q6v5 *qproc)
+{
+       qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev,
+                                                             "mss_restart");
+       if (IS_ERR(qproc->mss_restart)) {
+               dev_err(qproc->dev, "failed to acquire mss restart\n");
+               return PTR_ERR(qproc->mss_restart);
+       }
+
+       if (qproc->has_alt_reset) {
+               qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev,
+                                                                   "pdc_reset");
+               if (IS_ERR(qproc->pdc_reset)) {
+                       dev_err(qproc->dev, "failed to acquire pdc reset\n");
+                       return PTR_ERR(qproc->pdc_reset);
+               }
+       }
+
+       return 0;
+}
+
+static int q6v5_alloc_memory_region(struct q6v5 *qproc)
+{
+       struct device_node *child;
+       struct device_node *node;
+       struct resource r;
+       int ret;
+
+       child = of_get_child_by_name(qproc->dev->of_node, "mba");
+       node = of_parse_phandle(child, "memory-region", 0);
+       ret = of_address_to_resource(node, 0, &r);
+       if (ret) {
+               dev_err(qproc->dev, "unable to resolve mba region\n");
+               return ret;
+       }
+       of_node_put(node);
+
+       qproc->mba_phys = r.start;
+       qproc->mba_size = resource_size(&r);
+       qproc->mba_region = devm_ioremap_wc(qproc->dev, qproc->mba_phys, qproc->mba_size);
+       if (!qproc->mba_region) {
+               dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
+                       &r.start, qproc->mba_size);
+               return -EBUSY;
+       }
+
+       child = of_get_child_by_name(qproc->dev->of_node, "mpss");
+       node = of_parse_phandle(child, "memory-region", 0);
+       ret = of_address_to_resource(node, 0, &r);
+       if (ret) {
+               dev_err(qproc->dev, "unable to resolve mpss region\n");
+               return ret;
+       }
+       of_node_put(node);
+
+       qproc->mpss_phys = qproc->mpss_reloc = r.start;
+       qproc->mpss_size = resource_size(&r);
+       qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size);
+       if (!qproc->mpss_region) {
+               dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
+                       &r.start, qproc->mpss_size);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static int q6v5_probe(struct platform_device *pdev)
+{
+       const struct rproc_hexagon_res *desc;
+       struct q6v5 *qproc;
+       struct rproc *rproc;
+       int ret;
+
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
+
+       if (desc->need_mem_protection && !qcom_scm_is_available())
+               return -EPROBE_DEFER;
+
+       rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
+                           desc->hexagon_mba_image, sizeof(*qproc));
+       if (!rproc) {
+               dev_err(&pdev->dev, "failed to allocate rproc\n");
+               return -ENOMEM;
+       }
+
+       qproc = (struct q6v5 *)rproc->priv;
+       qproc->dev = &pdev->dev;
+       qproc->rproc = rproc;
+       platform_set_drvdata(pdev, qproc);
+
+       ret = q6v5_init_mem(qproc, pdev);
+       if (ret)
+               goto free_rproc;
+
+       ret = q6v5_alloc_memory_region(qproc);
+       if (ret)
+               goto free_rproc;
+
+       ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
+                              desc->proxy_clk_names);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
+               goto free_rproc;
+       }
+       qproc->proxy_clk_count = ret;
+
+       ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks,
+                              desc->reset_clk_names);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to get reset clocks.\n");
+               goto free_rproc;
+       }
+       qproc->reset_clk_count = ret;
+
+       ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
+                              desc->active_clk_names);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to get active clocks.\n");
+               goto free_rproc;
+       }
+       qproc->active_clk_count = ret;
+
+       ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs,
+                                 desc->proxy_supply);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
+               goto free_rproc;
+       }
+       qproc->proxy_reg_count = ret;
+
+       ret = q6v5_regulator_init(&pdev->dev,  qproc->active_regs,
+                                 desc->active_supply);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to get active regulators.\n");
+               goto free_rproc;
+       }
+       qproc->active_reg_count = ret;
+
+       qproc->has_alt_reset = desc->has_alt_reset;
+       ret = q6v5_init_reset(qproc);
+       if (ret)
+               goto free_rproc;
+
+       qproc->version = desc->version;
+       qproc->need_mem_protection = desc->need_mem_protection;
+
+       ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM,
+                            qcom_msa_handover);
+       if (ret)
+               goto free_rproc;
+
+       qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
+       qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
+       qcom_add_glink_subdev(rproc, &qproc->glink_subdev);
+       qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
+       qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
+       qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
+
+       ret = rproc_add(rproc);
+       if (ret)
+               goto free_rproc;
+
+       return 0;
+
+free_rproc:
+       rproc_free(rproc);
+
+       return ret;
+}
+
+static int q6v5_remove(struct platform_device *pdev)
+{
+       struct q6v5 *qproc = platform_get_drvdata(pdev);
+
+       rproc_del(qproc->rproc);
+
+       qcom_remove_sysmon_subdev(qproc->sysmon);
+       qcom_remove_glink_subdev(qproc->rproc, &qproc->glink_subdev);
+       qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
+       qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev);
+       rproc_free(qproc->rproc);
+
+       return 0;
+}
+
+static const struct rproc_hexagon_res sdm845_mss = {
+       .hexagon_mba_image = "mba.mbn",
+       .proxy_clk_names = (char*[]){
+                       "xo",
+                       "prng",
+                       NULL
+       },
+       .reset_clk_names = (char*[]){
+                       "iface",
+                       "snoc_axi",
+                       NULL
+       },
+       .active_clk_names = (char*[]){
+                       "bus",
+                       "mem",
+                       "gpll0_mss",
+                       "mnoc_axi",
+                       NULL
+       },
+       .need_mem_protection = true,
+       .has_alt_reset = true,
+       .version = MSS_SDM845,
+};
+
+static const struct rproc_hexagon_res msm8996_mss = {
+       .hexagon_mba_image = "mba.mbn",
+       .proxy_clk_names = (char*[]){
+                       "xo",
+                       "pnoc",
+                       NULL
+       },
+       .active_clk_names = (char*[]){
+                       "iface",
+                       "bus",
+                       "mem",
+                       "gpll0_mss_clk",
+                       NULL
+       },
+       .need_mem_protection = true,
+       .has_alt_reset = false,
+       .version = MSS_MSM8996,
+};
+
+static const struct rproc_hexagon_res msm8916_mss = {
+       .hexagon_mba_image = "mba.mbn",
+       .proxy_supply = (struct qcom_mss_reg_res[]) {
+               {
+                       .supply = "mx",
+                       .uV = 1050000,
+               },
+               {
+                       .supply = "cx",
+                       .uA = 100000,
+               },
+               {
+                       .supply = "pll",
+                       .uA = 100000,
+               },
+               {}
+       },
+       .proxy_clk_names = (char*[]){
+               "xo",
+               NULL
+       },
+       .active_clk_names = (char*[]){
+               "iface",
+               "bus",
+               "mem",
+               NULL
+       },
+       .need_mem_protection = false,
+       .has_alt_reset = false,
+       .version = MSS_MSM8916,
+};
+
+static const struct rproc_hexagon_res msm8974_mss = {
+       .hexagon_mba_image = "mba.b00",
+       .proxy_supply = (struct qcom_mss_reg_res[]) {
+               {
+                       .supply = "mx",
+                       .uV = 1050000,
+               },
+               {
+                       .supply = "cx",
+                       .uA = 100000,
+               },
+               {
+                       .supply = "pll",
+                       .uA = 100000,
+               },
+               {}
+       },
+       .active_supply = (struct qcom_mss_reg_res[]) {
+               {
+                       .supply = "mss",
+                       .uV = 1050000,
+                       .uA = 100000,
+               },
+               {}
+       },
+       .proxy_clk_names = (char*[]){
+               "xo",
+               NULL
+       },
+       .active_clk_names = (char*[]){
+               "iface",
+               "bus",
+               "mem",
+               NULL
+       },
+       .need_mem_protection = false,
+       .has_alt_reset = false,
+       .version = MSS_MSM8974,
+};
+
+static const struct of_device_id q6v5_of_match[] = {
+       { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
+       { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
+       { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
+       { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
+       { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
+       { },
+};
+MODULE_DEVICE_TABLE(of, q6v5_of_match);
+
+static struct platform_driver q6v5_driver = {
+       .probe = q6v5_probe,
+       .remove = q6v5_remove,
+       .driver = {
+               .name = "qcom-q6v5-mss",
+               .of_match_table = q6v5_of_match,
+       },
+};
+module_platform_driver(q6v5_driver);
+
+MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
new file mode 100644 (file)
index 0000000..b1e63fc
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
+ *
+ * Copyright (C) 2016 Linaro Ltd
+ * Copyright (C) 2014 Sony Mobile Communications AB
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/qcom_scm.h>
+#include <linux/regulator/consumer.h>
+#include <linux/remoteproc.h>
+#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/soc/qcom/smem_state.h>
+
+#include "qcom_common.h"
+#include "qcom_q6v5.h"
+#include "remoteproc_internal.h"
+
+struct adsp_data {
+       int crash_reason_smem;
+       const char *firmware_name;
+       int pas_id;
+       bool has_aggre2_clk;
+
+       const char *ssr_name;
+       const char *sysmon_name;
+       int ssctl_id;
+};
+
+struct qcom_adsp {
+       struct device *dev;
+       struct rproc *rproc;
+
+       struct qcom_q6v5 q6v5;
+
+       struct clk *xo;
+       struct clk *aggre2_clk;
+
+       struct regulator *cx_supply;
+       struct regulator *px_supply;
+
+       int pas_id;
+       int crash_reason_smem;
+       bool has_aggre2_clk;
+
+       struct completion start_done;
+       struct completion stop_done;
+
+       phys_addr_t mem_phys;
+       phys_addr_t mem_reloc;
+       void *mem_region;
+       size_t mem_size;
+
+       struct qcom_rproc_glink glink_subdev;
+       struct qcom_rproc_subdev smd_subdev;
+       struct qcom_rproc_ssr ssr_subdev;
+       struct qcom_sysmon *sysmon;
+};
+
+static int adsp_load(struct rproc *rproc, const struct firmware *fw)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+
+       return qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
+                            adsp->mem_region, adsp->mem_phys, adsp->mem_size,
+                            &adsp->mem_reloc);
+
+}
+
+static int adsp_start(struct rproc *rproc)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+       int ret;
+
+       qcom_q6v5_prepare(&adsp->q6v5);
+
+       ret = clk_prepare_enable(adsp->xo);
+       if (ret)
+               return ret;
+
+       ret = clk_prepare_enable(adsp->aggre2_clk);
+       if (ret)
+               goto disable_xo_clk;
+
+       ret = regulator_enable(adsp->cx_supply);
+       if (ret)
+               goto disable_aggre2_clk;
+
+       ret = regulator_enable(adsp->px_supply);
+       if (ret)
+               goto disable_cx_supply;
+
+       ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
+       if (ret) {
+               dev_err(adsp->dev,
+                       "failed to authenticate image and release reset\n");
+               goto disable_px_supply;
+       }
+
+       ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
+       if (ret == -ETIMEDOUT) {
+               dev_err(adsp->dev, "start timed out\n");
+               qcom_scm_pas_shutdown(adsp->pas_id);
+               goto disable_px_supply;
+       }
+
+       return 0;
+
+disable_px_supply:
+       regulator_disable(adsp->px_supply);
+disable_cx_supply:
+       regulator_disable(adsp->cx_supply);
+disable_aggre2_clk:
+       clk_disable_unprepare(adsp->aggre2_clk);
+disable_xo_clk:
+       clk_disable_unprepare(adsp->xo);
+
+       return ret;
+}
+
+static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
+{
+       struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
+
+       regulator_disable(adsp->px_supply);
+       regulator_disable(adsp->cx_supply);
+       clk_disable_unprepare(adsp->aggre2_clk);
+       clk_disable_unprepare(adsp->xo);
+}
+
+static int adsp_stop(struct rproc *rproc)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+       int handover;
+       int ret;
+
+       ret = qcom_q6v5_request_stop(&adsp->q6v5);
+       if (ret == -ETIMEDOUT)
+               dev_err(adsp->dev, "timed out on wait\n");
+
+       ret = qcom_scm_pas_shutdown(adsp->pas_id);
+       if (ret)
+               dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
+
+       handover = qcom_q6v5_unprepare(&adsp->q6v5);
+       if (handover)
+               qcom_pas_handover(&adsp->q6v5);
+
+       return ret;
+}
+
+static void *adsp_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+       struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
+       int offset;
+
+       offset = da - adsp->mem_reloc;
+       if (offset < 0 || offset + len > adsp->mem_size)
+               return NULL;
+
+       return adsp->mem_region + offset;
+}
+
+static const struct rproc_ops adsp_ops = {
+       .start = adsp_start,
+       .stop = adsp_stop,
+       .da_to_va = adsp_da_to_va,
+       .parse_fw = qcom_register_dump_segments,
+       .load = adsp_load,
+};
+
+static int adsp_init_clock(struct qcom_adsp *adsp)
+{
+       int ret;
+
+       adsp->xo = devm_clk_get(adsp->dev, "xo");
+       if (IS_ERR(adsp->xo)) {
+               ret = PTR_ERR(adsp->xo);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(adsp->dev, "failed to get xo clock");
+               return ret;
+       }
+
+       if (adsp->has_aggre2_clk) {
+               adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2");
+               if (IS_ERR(adsp->aggre2_clk)) {
+                       ret = PTR_ERR(adsp->aggre2_clk);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(adsp->dev,
+                                       "failed to get aggre2 clock");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int adsp_init_regulator(struct qcom_adsp *adsp)
+{
+       adsp->cx_supply = devm_regulator_get(adsp->dev, "cx");
+       if (IS_ERR(adsp->cx_supply))
+               return PTR_ERR(adsp->cx_supply);
+
+       regulator_set_load(adsp->cx_supply, 100000);
+
+       adsp->px_supply = devm_regulator_get(adsp->dev, "px");
+       return PTR_ERR_OR_ZERO(adsp->px_supply);
+}
+
+static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
+{
+       struct device_node *node;
+       struct resource r;
+       int ret;
+
+       node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
+       if (!node) {
+               dev_err(adsp->dev, "no memory-region specified\n");
+               return -EINVAL;
+       }
+
+       ret = of_address_to_resource(node, 0, &r);
+       if (ret)
+               return ret;
+
+       adsp->mem_phys = adsp->mem_reloc = r.start;
+       adsp->mem_size = resource_size(&r);
+       adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
+       if (!adsp->mem_region) {
+               dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
+                       &r.start, adsp->mem_size);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static int adsp_probe(struct platform_device *pdev)
+{
+       const struct adsp_data *desc;
+       struct qcom_adsp *adsp;
+       struct rproc *rproc;
+       int ret;
+
+       desc = of_device_get_match_data(&pdev->dev);
+       if (!desc)
+               return -EINVAL;
+
+       if (!qcom_scm_is_available())
+               return -EPROBE_DEFER;
+
+       rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
+                           desc->firmware_name, sizeof(*adsp));
+       if (!rproc) {
+               dev_err(&pdev->dev, "unable to allocate remoteproc\n");
+               return -ENOMEM;
+       }
+
+       adsp = (struct qcom_adsp *)rproc->priv;
+       adsp->dev = &pdev->dev;
+       adsp->rproc = rproc;
+       adsp->pas_id = desc->pas_id;
+       adsp->has_aggre2_clk = desc->has_aggre2_clk;
+       platform_set_drvdata(pdev, adsp);
+
+       ret = adsp_alloc_memory_region(adsp);
+       if (ret)
+               goto free_rproc;
+
+       ret = adsp_init_clock(adsp);
+       if (ret)
+               goto free_rproc;
+
+       ret = adsp_init_regulator(adsp);
+       if (ret)
+               goto free_rproc;
+
+       ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
+                            qcom_pas_handover);
+       if (ret)
+               goto free_rproc;
+
+       qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
+       qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
+       qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
+       adsp->sysmon = qcom_add_sysmon_subdev(rproc,
+                                             desc->sysmon_name,
+                                             desc->ssctl_id);
+
+       ret = rproc_add(rproc);
+       if (ret)
+               goto free_rproc;
+
+       return 0;
+
+free_rproc:
+       rproc_free(rproc);
+
+       return ret;
+}
+
+static int adsp_remove(struct platform_device *pdev)
+{
+       struct qcom_adsp *adsp = platform_get_drvdata(pdev);
+
+       rproc_del(adsp->rproc);
+
+       qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
+       qcom_remove_sysmon_subdev(adsp->sysmon);
+       qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
+       qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
+       rproc_free(adsp->rproc);
+
+       return 0;
+}
+
+static const struct adsp_data adsp_resource_init = {
+               .crash_reason_smem = 423,
+               .firmware_name = "adsp.mdt",
+               .pas_id = 1,
+               .has_aggre2_clk = false,
+               .ssr_name = "lpass",
+               .sysmon_name = "adsp",
+               .ssctl_id = 0x14,
+};
+
+static const struct adsp_data cdsp_resource_init = {
+       .crash_reason_smem = 601,
+       .firmware_name = "cdsp.mdt",
+       .pas_id = 18,
+       .has_aggre2_clk = false,
+       .ssr_name = "cdsp",
+       .sysmon_name = "cdsp",
+       .ssctl_id = 0x17,
+};
+
+static const struct adsp_data slpi_resource_init = {
+               .crash_reason_smem = 424,
+               .firmware_name = "slpi.mdt",
+               .pas_id = 12,
+               .has_aggre2_clk = true,
+               .ssr_name = "dsps",
+               .sysmon_name = "slpi",
+               .ssctl_id = 0x16,
+};
+
+static const struct adsp_data wcss_resource_init = {
+       .crash_reason_smem = 421,
+       .firmware_name = "wcnss.mdt",
+       .pas_id = 6,
+       .ssr_name = "mpss",
+       .sysmon_name = "wcnss",
+       .ssctl_id = 0x12,
+};
+
+static const struct of_device_id adsp_of_match[] = {
+       { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
+       { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
+       { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
+       { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
+       { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
+       { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
+       { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
+       { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
+       { },
+};
+MODULE_DEVICE_TABLE(of, adsp_of_match);
+
+static struct platform_driver adsp_driver = {
+       .probe = adsp_probe,
+       .remove = adsp_remove,
+       .driver = {
+               .name = "qcom_q6v5_pas",
+               .of_match_table = adsp_of_match,
+       },
+};
+
+module_platform_driver(adsp_driver);
+MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
deleted file mode 100644 (file)
index d7a4b9e..0000000
+++ /dev/null
@@ -1,1378 +0,0 @@
-/*
- * Qualcomm Peripheral Image Loader
- *
- * Copyright (C) 2016 Linaro Ltd.
- * Copyright (C) 2014 Sony Mobile Communications AB
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/remoteproc.h>
-#include <linux/reset.h>
-#include <linux/soc/qcom/mdt_loader.h>
-#include <linux/iopoll.h>
-
-#include "remoteproc_internal.h"
-#include "qcom_common.h"
-#include "qcom_q6v5.h"
-
-#include <linux/qcom_scm.h>
-
-#define MPSS_CRASH_REASON_SMEM         421
-
-/* RMB Status Register Values */
-#define RMB_PBL_SUCCESS                        0x1
-
-#define RMB_MBA_XPU_UNLOCKED           0x1
-#define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2
-#define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3
-#define RMB_MBA_AUTH_COMPLETE          0x4
-
-/* PBL/MBA interface registers */
-#define RMB_MBA_IMAGE_REG              0x00
-#define RMB_PBL_STATUS_REG             0x04
-#define RMB_MBA_COMMAND_REG            0x08
-#define RMB_MBA_STATUS_REG             0x0C
-#define RMB_PMI_META_DATA_REG          0x10
-#define RMB_PMI_CODE_START_REG         0x14
-#define RMB_PMI_CODE_LENGTH_REG                0x18
-#define RMB_MBA_MSS_STATUS             0x40
-#define RMB_MBA_ALT_RESET              0x44
-
-#define RMB_CMD_META_DATA_READY                0x1
-#define RMB_CMD_LOAD_READY             0x2
-
-/* QDSP6SS Register Offsets */
-#define QDSP6SS_RESET_REG              0x014
-#define QDSP6SS_GFMUX_CTL_REG          0x020
-#define QDSP6SS_PWR_CTL_REG            0x030
-#define QDSP6SS_MEM_PWR_CTL            0x0B0
-#define QDSP6SS_STRAP_ACC              0x110
-
-/* AXI Halt Register Offsets */
-#define AXI_HALTREQ_REG                        0x0
-#define AXI_HALTACK_REG                        0x4
-#define AXI_IDLE_REG                   0x8
-
-#define HALT_ACK_TIMEOUT_MS            100
-
-/* QDSP6SS_RESET */
-#define Q6SS_STOP_CORE                 BIT(0)
-#define Q6SS_CORE_ARES                 BIT(1)
-#define Q6SS_BUS_ARES_ENABLE           BIT(2)
-
-/* QDSP6SS_GFMUX_CTL */
-#define Q6SS_CLK_ENABLE                        BIT(1)
-
-/* QDSP6SS_PWR_CTL */
-#define Q6SS_L2DATA_SLP_NRET_N_0       BIT(0)
-#define Q6SS_L2DATA_SLP_NRET_N_1       BIT(1)
-#define Q6SS_L2DATA_SLP_NRET_N_2       BIT(2)
-#define Q6SS_L2TAG_SLP_NRET_N          BIT(16)
-#define Q6SS_ETB_SLP_NRET_N            BIT(17)
-#define Q6SS_L2DATA_STBY_N             BIT(18)
-#define Q6SS_SLP_RET_N                 BIT(19)
-#define Q6SS_CLAMP_IO                  BIT(20)
-#define QDSS_BHS_ON                    BIT(21)
-#define QDSS_LDO_BYP                   BIT(22)
-
-/* QDSP6v56 parameters */
-#define QDSP6v56_LDO_BYP               BIT(25)
-#define QDSP6v56_BHS_ON                BIT(24)
-#define QDSP6v56_CLAMP_WL              BIT(21)
-#define QDSP6v56_CLAMP_QMC_MEM         BIT(22)
-#define HALT_CHECK_MAX_LOOPS           200
-#define QDSP6SS_XO_CBCR                0x0038
-#define QDSP6SS_ACC_OVERRIDE_VAL               0x20
-
-/* QDSP6v65 parameters */
-#define QDSP6SS_SLEEP                   0x3C
-#define QDSP6SS_BOOT_CORE_START         0x400
-#define QDSP6SS_BOOT_CMD                0x404
-#define SLEEP_CHECK_MAX_LOOPS           200
-#define BOOT_FSM_TIMEOUT                10000
-
-struct reg_info {
-       struct regulator *reg;
-       int uV;
-       int uA;
-};
-
-struct qcom_mss_reg_res {
-       const char *supply;
-       int uV;
-       int uA;
-};
-
-struct rproc_hexagon_res {
-       const char *hexagon_mba_image;
-       struct qcom_mss_reg_res *proxy_supply;
-       struct qcom_mss_reg_res *active_supply;
-       char **proxy_clk_names;
-       char **reset_clk_names;
-       char **active_clk_names;
-       int version;
-       bool need_mem_protection;
-       bool has_alt_reset;
-};
-
-struct q6v5 {
-       struct device *dev;
-       struct rproc *rproc;
-
-       void __iomem *reg_base;
-       void __iomem *rmb_base;
-
-       struct regmap *halt_map;
-       u32 halt_q6;
-       u32 halt_modem;
-       u32 halt_nc;
-
-       struct reset_control *mss_restart;
-
-       struct qcom_q6v5 q6v5;
-
-       struct clk *active_clks[8];
-       struct clk *reset_clks[4];
-       struct clk *proxy_clks[4];
-       int active_clk_count;
-       int reset_clk_count;
-       int proxy_clk_count;
-
-       struct reg_info active_regs[1];
-       struct reg_info proxy_regs[3];
-       int active_reg_count;
-       int proxy_reg_count;
-
-       bool running;
-
-       phys_addr_t mba_phys;
-       void *mba_region;
-       size_t mba_size;
-
-       phys_addr_t mpss_phys;
-       phys_addr_t mpss_reloc;
-       void *mpss_region;
-       size_t mpss_size;
-
-       struct qcom_rproc_glink glink_subdev;
-       struct qcom_rproc_subdev smd_subdev;
-       struct qcom_rproc_ssr ssr_subdev;
-       struct qcom_sysmon *sysmon;
-       bool need_mem_protection;
-       bool has_alt_reset;
-       int mpss_perm;
-       int mba_perm;
-       int version;
-};
-
-enum {
-       MSS_MSM8916,
-       MSS_MSM8974,
-       MSS_MSM8996,
-       MSS_SDM845,
-};
-
-static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
-                              const struct qcom_mss_reg_res *reg_res)
-{
-       int rc;
-       int i;
-
-       if (!reg_res)
-               return 0;
-
-       for (i = 0; reg_res[i].supply; i++) {
-               regs[i].reg = devm_regulator_get(dev, reg_res[i].supply);
-               if (IS_ERR(regs[i].reg)) {
-                       rc = PTR_ERR(regs[i].reg);
-                       if (rc != -EPROBE_DEFER)
-                               dev_err(dev, "Failed to get %s\n regulator",
-                                       reg_res[i].supply);
-                       return rc;
-               }
-
-               regs[i].uV = reg_res[i].uV;
-               regs[i].uA = reg_res[i].uA;
-       }
-
-       return i;
-}
-
-static int q6v5_regulator_enable(struct q6v5 *qproc,
-                                struct reg_info *regs, int count)
-{
-       int ret;
-       int i;
-
-       for (i = 0; i < count; i++) {
-               if (regs[i].uV > 0) {
-                       ret = regulator_set_voltage(regs[i].reg,
-                                       regs[i].uV, INT_MAX);
-                       if (ret) {
-                               dev_err(qproc->dev,
-                                       "Failed to request voltage for %d.\n",
-                                               i);
-                               goto err;
-                       }
-               }
-
-               if (regs[i].uA > 0) {
-                       ret = regulator_set_load(regs[i].reg,
-                                                regs[i].uA);
-                       if (ret < 0) {
-                               dev_err(qproc->dev,
-                                       "Failed to set regulator mode\n");
-                               goto err;
-                       }
-               }
-
-               ret = regulator_enable(regs[i].reg);
-               if (ret) {
-                       dev_err(qproc->dev, "Regulator enable failed\n");
-                       goto err;
-               }
-       }
-
-       return 0;
-err:
-       for (; i >= 0; i--) {
-               if (regs[i].uV > 0)
-                       regulator_set_voltage(regs[i].reg, 0, INT_MAX);
-
-               if (regs[i].uA > 0)
-                       regulator_set_load(regs[i].reg, 0);
-
-               regulator_disable(regs[i].reg);
-       }
-
-       return ret;
-}
-
-static void q6v5_regulator_disable(struct q6v5 *qproc,
-                                  struct reg_info *regs, int count)
-{
-       int i;
-
-       for (i = 0; i < count; i++) {
-               if (regs[i].uV > 0)
-                       regulator_set_voltage(regs[i].reg, 0, INT_MAX);
-
-               if (regs[i].uA > 0)
-                       regulator_set_load(regs[i].reg, 0);
-
-               regulator_disable(regs[i].reg);
-       }
-}
-
-static int q6v5_clk_enable(struct device *dev,
-                          struct clk **clks, int count)
-{
-       int rc;
-       int i;
-
-       for (i = 0; i < count; i++) {
-               rc = clk_prepare_enable(clks[i]);
-               if (rc) {
-                       dev_err(dev, "Clock enable failed\n");
-                       goto err;
-               }
-       }
-
-       return 0;
-err:
-       for (i--; i >= 0; i--)
-               clk_disable_unprepare(clks[i]);
-
-       return rc;
-}
-
-static void q6v5_clk_disable(struct device *dev,
-                            struct clk **clks, int count)
-{
-       int i;
-
-       for (i = 0; i < count; i++)
-               clk_disable_unprepare(clks[i]);
-}
-
-static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm,
-                                  bool remote_owner, phys_addr_t addr,
-                                  size_t size)
-{
-       struct qcom_scm_vmperm next;
-
-       if (!qproc->need_mem_protection)
-               return 0;
-       if (remote_owner && *current_perm == BIT(QCOM_SCM_VMID_MSS_MSA))
-               return 0;
-       if (!remote_owner && *current_perm == BIT(QCOM_SCM_VMID_HLOS))
-               return 0;
-
-       next.vmid = remote_owner ? QCOM_SCM_VMID_MSS_MSA : QCOM_SCM_VMID_HLOS;
-       next.perm = remote_owner ? QCOM_SCM_PERM_RW : QCOM_SCM_PERM_RWX;
-
-       return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K),
-                                  current_perm, &next, 1);
-}
-
-static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
-{
-       struct q6v5 *qproc = rproc->priv;
-
-       memcpy(qproc->mba_region, fw->data, fw->size);
-
-       return 0;
-}
-
-static int q6v5_reset_assert(struct q6v5 *qproc)
-{
-       if (qproc->has_alt_reset)
-               return reset_control_reset(qproc->mss_restart);
-       else
-               return reset_control_assert(qproc->mss_restart);
-}
-
-static int q6v5_reset_deassert(struct q6v5 *qproc)
-{
-       int ret;
-
-       if (qproc->has_alt_reset) {
-               writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET);
-               ret = reset_control_reset(qproc->mss_restart);
-               writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
-       } else {
-               ret = reset_control_deassert(qproc->mss_restart);
-       }
-
-       return ret;
-}
-
-static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
-{
-       unsigned long timeout;
-       s32 val;
-
-       timeout = jiffies + msecs_to_jiffies(ms);
-       for (;;) {
-               val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG);
-               if (val)
-                       break;
-
-               if (time_after(jiffies, timeout))
-                       return -ETIMEDOUT;
-
-               msleep(1);
-       }
-
-       return val;
-}
-
-static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms)
-{
-
-       unsigned long timeout;
-       s32 val;
-
-       timeout = jiffies + msecs_to_jiffies(ms);
-       for (;;) {
-               val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
-               if (val < 0)
-                       break;
-
-               if (!status && val)
-                       break;
-               else if (status && val == status)
-                       break;
-
-               if (time_after(jiffies, timeout))
-                       return -ETIMEDOUT;
-
-               msleep(1);
-       }
-
-       return val;
-}
-
-static int q6v5proc_reset(struct q6v5 *qproc)
-{
-       u32 val;
-       int ret;
-       int i;
-
-       if (qproc->version == MSS_SDM845) {
-               val = readl(qproc->reg_base + QDSP6SS_SLEEP);
-               val |= 0x1;
-               writel(val, qproc->reg_base + QDSP6SS_SLEEP);
-
-               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
-                                        val, !(val & BIT(31)), 1,
-                                        SLEEP_CHECK_MAX_LOOPS);
-               if (ret) {
-                       dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
-                       return -ETIMEDOUT;
-               }
-
-               /* De-assert QDSP6 stop core */
-               writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
-               /* Trigger boot FSM */
-               writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
-
-               ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
-                               val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
-               if (ret) {
-                       dev_err(qproc->dev, "Boot FSM failed to complete.\n");
-                       /* Reset the modem so that boot FSM is in reset state */
-                       q6v5_reset_deassert(qproc);
-                       return ret;
-               }
-
-               goto pbl_wait;
-       } else if (qproc->version == MSS_MSM8996) {
-               /* Override the ACC value if required */
-               writel(QDSP6SS_ACC_OVERRIDE_VAL,
-                      qproc->reg_base + QDSP6SS_STRAP_ACC);
-
-               /* Assert resets, stop core */
-               val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
-               val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
-               writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
-
-               /* BHS require xo cbcr to be enabled */
-               val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
-               val |= 0x1;
-               writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
-
-               /* Read CLKOFF bit to go low indicating CLK is enabled */
-               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
-                                        val, !(val & BIT(31)), 1,
-                                        HALT_CHECK_MAX_LOOPS);
-               if (ret) {
-                       dev_err(qproc->dev,
-                               "xo cbcr enabling timed out (rc:%d)\n", ret);
-                       return ret;
-               }
-               /* Enable power block headswitch and wait for it to stabilize */
-               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= QDSP6v56_BHS_ON;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               udelay(1);
-
-               /* Put LDO in bypass mode */
-               val |= QDSP6v56_LDO_BYP;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-
-               /* Deassert QDSP6 compiler memory clamp */
-               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val &= ~QDSP6v56_CLAMP_QMC_MEM;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-
-               /* Deassert memory peripheral sleep and L2 memory standby */
-               val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-
-               /* Turn on L1, L2, ETB and JU memories 1 at a time */
-               val = readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL);
-               for (i = 19; i >= 0; i--) {
-                       val |= BIT(i);
-                       writel(val, qproc->reg_base +
-                                               QDSP6SS_MEM_PWR_CTL);
-                       /*
-                        * Read back value to ensure the write is done then
-                        * wait for 1us for both memory peripheral and data
-                        * array to turn on.
-                        */
-                       val |= readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL);
-                       udelay(1);
-               }
-               /* Remove word line clamp */
-               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val &= ~QDSP6v56_CLAMP_WL;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-       } else {
-               /* Assert resets, stop core */
-               val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
-               val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
-               writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
-
-               /* Enable power block headswitch and wait for it to stabilize */
-               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= QDSS_BHS_ON | QDSS_LDO_BYP;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               udelay(1);
-               /*
-                * Turn on memories. L2 banks should be done individually
-                * to minimize inrush current.
-                */
-               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
-                       Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= Q6SS_L2DATA_SLP_NRET_N_2;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= Q6SS_L2DATA_SLP_NRET_N_1;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= Q6SS_L2DATA_SLP_NRET_N_0;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-       }
-       /* Remove IO clamp */
-       val &= ~Q6SS_CLAMP_IO;
-       writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-
-       /* Bring core out of reset */
-       val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
-       val &= ~Q6SS_CORE_ARES;
-       writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
-
-       /* Turn on core clock */
-       val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
-       val |= Q6SS_CLK_ENABLE;
-       writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
-
-       /* Start core execution */
-       val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
-       val &= ~Q6SS_STOP_CORE;
-       writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
-
-pbl_wait:
-       /* Wait for PBL status */
-       ret = q6v5_rmb_pbl_wait(qproc, 1000);
-       if (ret == -ETIMEDOUT) {
-               dev_err(qproc->dev, "PBL boot timed out\n");
-       } else if (ret != RMB_PBL_SUCCESS) {
-               dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret);
-               ret = -EINVAL;
-       } else {
-               ret = 0;
-       }
-
-       return ret;
-}
-
-static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
-                                  struct regmap *halt_map,
-                                  u32 offset)
-{
-       unsigned long timeout;
-       unsigned int val;
-       int ret;
-
-       /* Check if we're already idle */
-       ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
-       if (!ret && val)
-               return;
-
-       /* Assert halt request */
-       regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1);
-
-       /* Wait for halt */
-       timeout = jiffies + msecs_to_jiffies(HALT_ACK_TIMEOUT_MS);
-       for (;;) {
-               ret = regmap_read(halt_map, offset + AXI_HALTACK_REG, &val);
-               if (ret || val || time_after(jiffies, timeout))
-                       break;
-
-               msleep(1);
-       }
-
-       ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
-       if (ret || !val)
-               dev_err(qproc->dev, "port failed halt\n");
-
-       /* Clear halt request (port will remain halted until reset) */
-       regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
-}
-
-static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
-{
-       unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
-       dma_addr_t phys;
-       int mdata_perm;
-       int xferop_ret;
-       void *ptr;
-       int ret;
-
-       ptr = dma_alloc_attrs(qproc->dev, fw->size, &phys, GFP_KERNEL, dma_attrs);
-       if (!ptr) {
-               dev_err(qproc->dev, "failed to allocate mdt buffer\n");
-               return -ENOMEM;
-       }
-
-       memcpy(ptr, fw->data, fw->size);
-
-       /* Hypervisor mapping to access metadata by modem */
-       mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
-       ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm,
-                                     true, phys, fw->size);
-       if (ret) {
-               dev_err(qproc->dev,
-                       "assigning Q6 access to metadata failed: %d\n", ret);
-               ret = -EAGAIN;
-               goto free_dma_attrs;
-       }
-
-       writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG);
-       writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
-
-       ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
-       if (ret == -ETIMEDOUT)
-               dev_err(qproc->dev, "MPSS header authentication timed out\n");
-       else if (ret < 0)
-               dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
-
-       /* Metadata authentication done, remove modem access */
-       xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm,
-                                            false, phys, fw->size);
-       if (xferop_ret)
-               dev_warn(qproc->dev,
-                        "mdt buffer not reclaimed system may become unstable\n");
-
-free_dma_attrs:
-       dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
-
-       return ret < 0 ? ret : 0;
-}
-
-static bool q6v5_phdr_valid(const struct elf32_phdr *phdr)
-{
-       if (phdr->p_type != PT_LOAD)
-               return false;
-
-       if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
-               return false;
-
-       if (!phdr->p_memsz)
-               return false;
-
-       return true;
-}
-
-static int q6v5_mpss_load(struct q6v5 *qproc)
-{
-       const struct elf32_phdr *phdrs;
-       const struct elf32_phdr *phdr;
-       const struct firmware *seg_fw;
-       const struct firmware *fw;
-       struct elf32_hdr *ehdr;
-       phys_addr_t mpss_reloc;
-       phys_addr_t boot_addr;
-       phys_addr_t min_addr = PHYS_ADDR_MAX;
-       phys_addr_t max_addr = 0;
-       bool relocate = false;
-       char seg_name[10];
-       ssize_t offset;
-       size_t size = 0;
-       void *ptr;
-       int ret;
-       int i;
-
-       ret = request_firmware(&fw, "modem.mdt", qproc->dev);
-       if (ret < 0) {
-               dev_err(qproc->dev, "unable to load modem.mdt\n");
-               return ret;
-       }
-
-       /* Initialize the RMB validator */
-       writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
-
-       ret = q6v5_mpss_init_image(qproc, fw);
-       if (ret)
-               goto release_firmware;
-
-       ehdr = (struct elf32_hdr *)fw->data;
-       phdrs = (struct elf32_phdr *)(ehdr + 1);
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               phdr = &phdrs[i];
-
-               if (!q6v5_phdr_valid(phdr))
-                       continue;
-
-               if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
-                       relocate = true;
-
-               if (phdr->p_paddr < min_addr)
-                       min_addr = phdr->p_paddr;
-
-               if (phdr->p_paddr + phdr->p_memsz > max_addr)
-                       max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
-       }
-
-       mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
-       /* Load firmware segments */
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               phdr = &phdrs[i];
-
-               if (!q6v5_phdr_valid(phdr))
-                       continue;
-
-               offset = phdr->p_paddr - mpss_reloc;
-               if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) {
-                       dev_err(qproc->dev, "segment outside memory range\n");
-                       ret = -EINVAL;
-                       goto release_firmware;
-               }
-
-               ptr = qproc->mpss_region + offset;
-
-               if (phdr->p_filesz) {
-                       snprintf(seg_name, sizeof(seg_name), "modem.b%02d", i);
-                       ret = request_firmware(&seg_fw, seg_name, qproc->dev);
-                       if (ret) {
-                               dev_err(qproc->dev, "failed to load %s\n", seg_name);
-                               goto release_firmware;
-                       }
-
-                       memcpy(ptr, seg_fw->data, seg_fw->size);
-
-                       release_firmware(seg_fw);
-               }
-
-               if (phdr->p_memsz > phdr->p_filesz) {
-                       memset(ptr + phdr->p_filesz, 0,
-                              phdr->p_memsz - phdr->p_filesz);
-               }
-               size += phdr->p_memsz;
-       }
-
-       /* Transfer ownership of modem ddr region to q6 */
-       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true,
-                                     qproc->mpss_phys, qproc->mpss_size);
-       if (ret) {
-               dev_err(qproc->dev,
-                       "assigning Q6 access to mpss memory failed: %d\n", ret);
-               ret = -EAGAIN;
-               goto release_firmware;
-       }
-
-       boot_addr = relocate ? qproc->mpss_phys : min_addr;
-       writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
-       writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
-       writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
-
-       ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
-       if (ret == -ETIMEDOUT)
-               dev_err(qproc->dev, "MPSS authentication timed out\n");
-       else if (ret < 0)
-               dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret);
-
-release_firmware:
-       release_firmware(fw);
-
-       return ret < 0 ? ret : 0;
-}
-
-static int q6v5_start(struct rproc *rproc)
-{
-       struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
-       int xfermemop_ret;
-       int ret;
-
-       qcom_q6v5_prepare(&qproc->q6v5);
-
-       ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
-                                   qproc->proxy_reg_count);
-       if (ret) {
-               dev_err(qproc->dev, "failed to enable proxy supplies\n");
-               goto disable_irqs;
-       }
-
-       ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
-                             qproc->proxy_clk_count);
-       if (ret) {
-               dev_err(qproc->dev, "failed to enable proxy clocks\n");
-               goto disable_proxy_reg;
-       }
-
-       ret = q6v5_regulator_enable(qproc, qproc->active_regs,
-                                   qproc->active_reg_count);
-       if (ret) {
-               dev_err(qproc->dev, "failed to enable supplies\n");
-               goto disable_proxy_clk;
-       }
-
-       ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks,
-                             qproc->reset_clk_count);
-       if (ret) {
-               dev_err(qproc->dev, "failed to enable reset clocks\n");
-               goto disable_vdd;
-       }
-
-       ret = q6v5_reset_deassert(qproc);
-       if (ret) {
-               dev_err(qproc->dev, "failed to deassert mss restart\n");
-               goto disable_reset_clks;
-       }
-
-       ret = q6v5_clk_enable(qproc->dev, qproc->active_clks,
-                             qproc->active_clk_count);
-       if (ret) {
-               dev_err(qproc->dev, "failed to enable clocks\n");
-               goto assert_reset;
-       }
-
-       /* Assign MBA image access in DDR to q6 */
-       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
-                                     qproc->mba_phys, qproc->mba_size);
-       if (ret) {
-               dev_err(qproc->dev,
-                       "assigning Q6 access to mba memory failed: %d\n", ret);
-               goto disable_active_clks;
-       }
-
-       writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
-
-       ret = q6v5proc_reset(qproc);
-       if (ret)
-               goto reclaim_mba;
-
-       ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
-       if (ret == -ETIMEDOUT) {
-               dev_err(qproc->dev, "MBA boot timed out\n");
-               goto halt_axi_ports;
-       } else if (ret != RMB_MBA_XPU_UNLOCKED &&
-                  ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) {
-               dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret);
-               ret = -EINVAL;
-               goto halt_axi_ports;
-       }
-
-       dev_info(qproc->dev, "MBA booted, loading mpss\n");
-
-       ret = q6v5_mpss_load(qproc);
-       if (ret)
-               goto reclaim_mpss;
-
-       ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000));
-       if (ret == -ETIMEDOUT) {
-               dev_err(qproc->dev, "start timed out\n");
-               goto reclaim_mpss;
-       }
-
-       xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false,
-                                               qproc->mba_phys,
-                                               qproc->mba_size);
-       if (xfermemop_ret)
-               dev_err(qproc->dev,
-                       "Failed to reclaim mba buffer system may become unstable\n");
-       qproc->running = true;
-
-       return 0;
-
-reclaim_mpss:
-       xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
-                                               false, qproc->mpss_phys,
-                                               qproc->mpss_size);
-       WARN_ON(xfermemop_ret);
-
-halt_axi_ports:
-       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
-       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
-       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
-
-reclaim_mba:
-       xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false,
-                                               qproc->mba_phys,
-                                               qproc->mba_size);
-       if (xfermemop_ret) {
-               dev_err(qproc->dev,
-                       "Failed to reclaim mba buffer, system may become unstable\n");
-       }
-
-disable_active_clks:
-       q6v5_clk_disable(qproc->dev, qproc->active_clks,
-                        qproc->active_clk_count);
-
-assert_reset:
-       q6v5_reset_assert(qproc);
-disable_reset_clks:
-       q6v5_clk_disable(qproc->dev, qproc->reset_clks,
-                        qproc->reset_clk_count);
-disable_vdd:
-       q6v5_regulator_disable(qproc, qproc->active_regs,
-                              qproc->active_reg_count);
-disable_proxy_clk:
-       q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
-                        qproc->proxy_clk_count);
-disable_proxy_reg:
-       q6v5_regulator_disable(qproc, qproc->proxy_regs,
-                              qproc->proxy_reg_count);
-
-disable_irqs:
-       qcom_q6v5_unprepare(&qproc->q6v5);
-
-       return ret;
-}
-
-static int q6v5_stop(struct rproc *rproc)
-{
-       struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
-       int ret;
-       u32 val;
-
-       qproc->running = false;
-
-       ret = qcom_q6v5_request_stop(&qproc->q6v5);
-       if (ret == -ETIMEDOUT)
-               dev_err(qproc->dev, "timed out on wait\n");
-
-       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
-       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
-       q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
-       if (qproc->version == MSS_MSM8996) {
-               /*
-                * To avoid high MX current during LPASS/MSS restart.
-                */
-               val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-               val |= Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL |
-                       QDSP6v56_CLAMP_QMC_MEM;
-               writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-       }
-
-
-       ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false,
-                                     qproc->mpss_phys, qproc->mpss_size);
-       WARN_ON(ret);
-
-       q6v5_reset_assert(qproc);
-
-       ret = qcom_q6v5_unprepare(&qproc->q6v5);
-       if (ret) {
-               q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
-                                qproc->proxy_clk_count);
-               q6v5_regulator_disable(qproc, qproc->proxy_regs,
-                                      qproc->proxy_reg_count);
-       }
-
-       q6v5_clk_disable(qproc->dev, qproc->reset_clks,
-                        qproc->reset_clk_count);
-       q6v5_clk_disable(qproc->dev, qproc->active_clks,
-                        qproc->active_clk_count);
-       q6v5_regulator_disable(qproc, qproc->active_regs,
-                              qproc->active_reg_count);
-
-       return 0;
-}
-
-static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len)
-{
-       struct q6v5 *qproc = rproc->priv;
-       int offset;
-
-       offset = da - qproc->mpss_reloc;
-       if (offset < 0 || offset + len > qproc->mpss_size)
-               return NULL;
-
-       return qproc->mpss_region + offset;
-}
-
-static const struct rproc_ops q6v5_ops = {
-       .start = q6v5_start,
-       .stop = q6v5_stop,
-       .da_to_va = q6v5_da_to_va,
-       .load = q6v5_load,
-};
-
-static void qcom_msa_handover(struct qcom_q6v5 *q6v5)
-{
-       struct q6v5 *qproc = container_of(q6v5, struct q6v5, q6v5);
-
-       q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
-                        qproc->proxy_clk_count);
-       q6v5_regulator_disable(qproc, qproc->proxy_regs,
-                              qproc->proxy_reg_count);
-}
-
-static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
-{
-       struct of_phandle_args args;
-       struct resource *res;
-       int ret;
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
-       qproc->reg_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(qproc->reg_base))
-               return PTR_ERR(qproc->reg_base);
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");
-       qproc->rmb_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(qproc->rmb_base))
-               return PTR_ERR(qproc->rmb_base);
-
-       ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
-                                              "qcom,halt-regs", 3, 0, &args);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
-               return -EINVAL;
-       }
-
-       qproc->halt_map = syscon_node_to_regmap(args.np);
-       of_node_put(args.np);
-       if (IS_ERR(qproc->halt_map))
-               return PTR_ERR(qproc->halt_map);
-
-       qproc->halt_q6 = args.args[0];
-       qproc->halt_modem = args.args[1];
-       qproc->halt_nc = args.args[2];
-
-       return 0;
-}
-
-static int q6v5_init_clocks(struct device *dev, struct clk **clks,
-               char **clk_names)
-{
-       int i;
-
-       if (!clk_names)
-               return 0;
-
-       for (i = 0; clk_names[i]; i++) {
-               clks[i] = devm_clk_get(dev, clk_names[i]);
-               if (IS_ERR(clks[i])) {
-                       int rc = PTR_ERR(clks[i]);
-
-                       if (rc != -EPROBE_DEFER)
-                               dev_err(dev, "Failed to get %s clock\n",
-                                       clk_names[i]);
-                       return rc;
-               }
-       }
-
-       return i;
-}
-
-static int q6v5_init_reset(struct q6v5 *qproc)
-{
-       qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev,
-                                                             NULL);
-       if (IS_ERR(qproc->mss_restart)) {
-               dev_err(qproc->dev, "failed to acquire mss restart\n");
-               return PTR_ERR(qproc->mss_restart);
-       }
-
-       return 0;
-}
-
-static int q6v5_alloc_memory_region(struct q6v5 *qproc)
-{
-       struct device_node *child;
-       struct device_node *node;
-       struct resource r;
-       int ret;
-
-       child = of_get_child_by_name(qproc->dev->of_node, "mba");
-       node = of_parse_phandle(child, "memory-region", 0);
-       ret = of_address_to_resource(node, 0, &r);
-       if (ret) {
-               dev_err(qproc->dev, "unable to resolve mba region\n");
-               return ret;
-       }
-       of_node_put(node);
-
-       qproc->mba_phys = r.start;
-       qproc->mba_size = resource_size(&r);
-       qproc->mba_region = devm_ioremap_wc(qproc->dev, qproc->mba_phys, qproc->mba_size);
-       if (!qproc->mba_region) {
-               dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
-                       &r.start, qproc->mba_size);
-               return -EBUSY;
-       }
-
-       child = of_get_child_by_name(qproc->dev->of_node, "mpss");
-       node = of_parse_phandle(child, "memory-region", 0);
-       ret = of_address_to_resource(node, 0, &r);
-       if (ret) {
-               dev_err(qproc->dev, "unable to resolve mpss region\n");
-               return ret;
-       }
-       of_node_put(node);
-
-       qproc->mpss_phys = qproc->mpss_reloc = r.start;
-       qproc->mpss_size = resource_size(&r);
-       qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size);
-       if (!qproc->mpss_region) {
-               dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
-                       &r.start, qproc->mpss_size);
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-static int q6v5_probe(struct platform_device *pdev)
-{
-       const struct rproc_hexagon_res *desc;
-       struct q6v5 *qproc;
-       struct rproc *rproc;
-       int ret;
-
-       desc = of_device_get_match_data(&pdev->dev);
-       if (!desc)
-               return -EINVAL;
-
-       rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
-                           desc->hexagon_mba_image, sizeof(*qproc));
-       if (!rproc) {
-               dev_err(&pdev->dev, "failed to allocate rproc\n");
-               return -ENOMEM;
-       }
-
-       qproc = (struct q6v5 *)rproc->priv;
-       qproc->dev = &pdev->dev;
-       qproc->rproc = rproc;
-       platform_set_drvdata(pdev, qproc);
-
-       ret = q6v5_init_mem(qproc, pdev);
-       if (ret)
-               goto free_rproc;
-
-       ret = q6v5_alloc_memory_region(qproc);
-       if (ret)
-               goto free_rproc;
-
-       ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
-                              desc->proxy_clk_names);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
-               goto free_rproc;
-       }
-       qproc->proxy_clk_count = ret;
-
-       ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks,
-                              desc->reset_clk_names);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to get reset clocks.\n");
-               goto free_rproc;
-       }
-       qproc->reset_clk_count = ret;
-
-       ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
-                              desc->active_clk_names);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to get active clocks.\n");
-               goto free_rproc;
-       }
-       qproc->active_clk_count = ret;
-
-       ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs,
-                                 desc->proxy_supply);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
-               goto free_rproc;
-       }
-       qproc->proxy_reg_count = ret;
-
-       ret = q6v5_regulator_init(&pdev->dev,  qproc->active_regs,
-                                 desc->active_supply);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to get active regulators.\n");
-               goto free_rproc;
-       }
-       qproc->active_reg_count = ret;
-
-       ret = q6v5_init_reset(qproc);
-       if (ret)
-               goto free_rproc;
-
-       qproc->version = desc->version;
-       qproc->has_alt_reset = desc->has_alt_reset;
-       qproc->need_mem_protection = desc->need_mem_protection;
-
-       ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM,
-                            qcom_msa_handover);
-       if (ret)
-               goto free_rproc;
-
-       qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
-       qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
-       qcom_add_glink_subdev(rproc, &qproc->glink_subdev);
-       qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
-       qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
-       qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
-
-       ret = rproc_add(rproc);
-       if (ret)
-               goto free_rproc;
-
-       return 0;
-
-free_rproc:
-       rproc_free(rproc);
-
-       return ret;
-}
-
-static int q6v5_remove(struct platform_device *pdev)
-{
-       struct q6v5 *qproc = platform_get_drvdata(pdev);
-
-       rproc_del(qproc->rproc);
-
-       qcom_remove_sysmon_subdev(qproc->sysmon);
-       qcom_remove_glink_subdev(qproc->rproc, &qproc->glink_subdev);
-       qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
-       qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev);
-       rproc_free(qproc->rproc);
-
-       return 0;
-}
-
-static const struct rproc_hexagon_res sdm845_mss = {
-       .hexagon_mba_image = "mba.mbn",
-       .proxy_clk_names = (char*[]){
-                       "xo",
-                       "prng",
-                       NULL
-       },
-       .reset_clk_names = (char*[]){
-                       "iface",
-                       "snoc_axi",
-                       NULL
-       },
-       .active_clk_names = (char*[]){
-                       "bus",
-                       "mem",
-                       "gpll0_mss",
-                       "mnoc_axi",
-                       NULL
-       },
-       .need_mem_protection = true,
-       .has_alt_reset = true,
-       .version = MSS_SDM845,
-};
-
-static const struct rproc_hexagon_res msm8996_mss = {
-       .hexagon_mba_image = "mba.mbn",
-       .proxy_clk_names = (char*[]){
-                       "xo",
-                       "pnoc",
-                       NULL
-       },
-       .active_clk_names = (char*[]){
-                       "iface",
-                       "bus",
-                       "mem",
-                       "gpll0_mss_clk",
-                       NULL
-       },
-       .need_mem_protection = true,
-       .has_alt_reset = false,
-       .version = MSS_MSM8996,
-};
-
-static const struct rproc_hexagon_res msm8916_mss = {
-       .hexagon_mba_image = "mba.mbn",
-       .proxy_supply = (struct qcom_mss_reg_res[]) {
-               {
-                       .supply = "mx",
-                       .uV = 1050000,
-               },
-               {
-                       .supply = "cx",
-                       .uA = 100000,
-               },
-               {
-                       .supply = "pll",
-                       .uA = 100000,
-               },
-               {}
-       },
-       .proxy_clk_names = (char*[]){
-               "xo",
-               NULL
-       },
-       .active_clk_names = (char*[]){
-               "iface",
-               "bus",
-               "mem",
-               NULL
-       },
-       .need_mem_protection = false,
-       .has_alt_reset = false,
-       .version = MSS_MSM8916,
-};
-
-static const struct rproc_hexagon_res msm8974_mss = {
-       .hexagon_mba_image = "mba.b00",
-       .proxy_supply = (struct qcom_mss_reg_res[]) {
-               {
-                       .supply = "mx",
-                       .uV = 1050000,
-               },
-               {
-                       .supply = "cx",
-                       .uA = 100000,
-               },
-               {
-                       .supply = "pll",
-                       .uA = 100000,
-               },
-               {}
-       },
-       .active_supply = (struct qcom_mss_reg_res[]) {
-               {
-                       .supply = "mss",
-                       .uV = 1050000,
-                       .uA = 100000,
-               },
-               {}
-       },
-       .proxy_clk_names = (char*[]){
-               "xo",
-               NULL
-       },
-       .active_clk_names = (char*[]){
-               "iface",
-               "bus",
-               "mem",
-               NULL
-       },
-       .need_mem_protection = false,
-       .has_alt_reset = false,
-       .version = MSS_MSM8974,
-};
-
-static const struct of_device_id q6v5_of_match[] = {
-       { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
-       { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
-       { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
-       { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
-       { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
-       { },
-};
-MODULE_DEVICE_TABLE(of, q6v5_of_match);
-
-static struct platform_driver q6v5_driver = {
-       .probe = q6v5_probe,
-       .remove = q6v5_remove,
-       .driver = {
-               .name = "qcom-q6v5-pil",
-               .of_match_table = q6v5_of_match,
-       },
-};
-module_platform_driver(q6v5_driver);
-
-MODULE_DESCRIPTION("Peripheral Image Loader for Hexagon");
-MODULE_LICENSE("GPL v2");
index aa6206706fe335008060a9e3da7a8a97d2f91e50..54ec38fc5dca621ad5d4d2b10e4f7fc0afa647b4 100644 (file)
@@ -53,6 +53,11 @@ typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
 typedef int (*rproc_handle_resource_t)(struct rproc *rproc,
                                 void *, int offset, int avail);
 
+static int rproc_alloc_carveout(struct rproc *rproc,
+                               struct rproc_mem_entry *mem);
+static int rproc_release_carveout(struct rproc *rproc,
+                                 struct rproc_mem_entry *mem);
+
 /* Unique indices for remoteproc devices */
 static DEFINE_IDA(rproc_dev_index);
 
@@ -140,6 +145,22 @@ static void rproc_disable_iommu(struct rproc *rproc)
        iommu_domain_free(domain);
 }
 
+static phys_addr_t rproc_va_to_pa(void *cpu_addr)
+{
+       /*
+        * Return physical address according to virtual address location
+        * - in vmalloc: if region ioremapped or defined as dma_alloc_coherent
+        * - in kernel: if region allocated in generic dma memory pool
+        */
+       if (is_vmalloc_addr(cpu_addr)) {
+               return page_to_phys(vmalloc_to_page(cpu_addr)) +
+                                   offset_in_page(cpu_addr);
+       }
+
+       WARN_ON(!virt_addr_valid(cpu_addr));
+       return virt_to_phys(cpu_addr);
+}
+
 /**
  * rproc_da_to_va() - lookup the kernel virtual address for a remoteproc address
  * @rproc: handle of a remote processor
@@ -201,27 +222,128 @@ out:
 }
 EXPORT_SYMBOL(rproc_da_to_va);
 
+/**
+ * rproc_find_carveout_by_name() - lookup the carveout region by a name
+ * @rproc: handle of a remote processor
+ * @name,..: carveout name to find (standard printf format)
+ *
+ * Platform driver has the capability to register some pre-allacoted carveout
+ * (physically contiguous memory regions) before rproc firmware loading and
+ * associated resource table analysis. These regions may be dedicated memory
+ * regions internal to the coprocessor or specified DDR region with specific
+ * attributes
+ *
+ * This function is a helper function with which we can go over the
+ * allocated carveouts and return associated region characteristics like
+ * coprocessor address, length or processor virtual address.
+ *
+ * Return: a valid pointer on carveout entry on success or NULL on failure.
+ */
+struct rproc_mem_entry *
+rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...)
+{
+       va_list args;
+       char _name[32];
+       struct rproc_mem_entry *carveout, *mem = NULL;
+
+       if (!name)
+               return NULL;
+
+       va_start(args, name);
+       vsnprintf(_name, sizeof(_name), name, args);
+       va_end(args);
+
+       list_for_each_entry(carveout, &rproc->carveouts, node) {
+               /* Compare carveout and requested names */
+               if (!strcmp(carveout->name, _name)) {
+                       mem = carveout;
+                       break;
+               }
+       }
+
+       return mem;
+}
+
+/**
+ * rproc_check_carveout_da() - Check specified carveout da configuration
+ * @rproc: handle of a remote processor
+ * @mem: pointer on carveout to check
+ * @da: area device address
+ * @len: associated area size
+ *
+ * This function is a helper function to verify requested device area (couple
+ * da, len) is part of specified carevout.
+ *
+ * Return: 0 if carveout match request else -ENOMEM
+ */
+int rproc_check_carveout_da(struct rproc *rproc, struct rproc_mem_entry *mem,
+                           u32 da, u32 len)
+{
+       struct device *dev = &rproc->dev;
+       int delta = 0;
+
+       /* Check requested resource length */
+       if (len > mem->len) {
+               dev_err(dev, "Registered carveout doesn't fit len request\n");
+               return -ENOMEM;
+       }
+
+       if (da != FW_RSC_ADDR_ANY && mem->da == FW_RSC_ADDR_ANY) {
+               /* Update existing carveout da */
+               mem->da = da;
+       } else if (da != FW_RSC_ADDR_ANY && mem->da != FW_RSC_ADDR_ANY) {
+               delta = da - mem->da;
+
+               /* Check requested resource belongs to registered carveout */
+               if (delta < 0) {
+                       dev_err(dev,
+                               "Registered carveout doesn't fit da request\n");
+                       return -ENOMEM;
+               }
+
+               if (delta + len > mem->len) {
+                       dev_err(dev,
+                               "Registered carveout doesn't fit len request\n");
+                       return -ENOMEM;
+               }
+       }
+
+       return 0;
+}
+
 int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
 {
        struct rproc *rproc = rvdev->rproc;
        struct device *dev = &rproc->dev;
        struct rproc_vring *rvring = &rvdev->vring[i];
        struct fw_rsc_vdev *rsc;
-       dma_addr_t dma;
-       void *va;
        int ret, size, notifyid;
+       struct rproc_mem_entry *mem;
 
        /* actual size of vring (in bytes) */
        size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
 
-       /*
-        * Allocate non-cacheable memory for the vring. In the future
-        * this call will also configure the IOMMU for us
-        */
-       va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
-       if (!va) {
-               dev_err(dev->parent, "dma_alloc_coherent failed\n");
-               return -EINVAL;
+       rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
+
+       /* Search for pre-registered carveout */
+       mem = rproc_find_carveout_by_name(rproc, "vdev%dvring%d", rvdev->index,
+                                         i);
+       if (mem) {
+               if (rproc_check_carveout_da(rproc, mem, rsc->vring[i].da, size))
+                       return -ENOMEM;
+       } else {
+               /* Register carveout in in list */
+               mem = rproc_mem_entry_init(dev, 0, 0, size, rsc->vring[i].da,
+                                          rproc_alloc_carveout,
+                                          rproc_release_carveout,
+                                          "vdev%dvring%d",
+                                          rvdev->index, i);
+               if (!mem) {
+                       dev_err(dev, "Can't allocate memory entry structure\n");
+                       return -ENOMEM;
+               }
+
+               rproc_add_carveout(rproc, mem);
        }
 
        /*
@@ -232,7 +354,6 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
        ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL);
        if (ret < 0) {
                dev_err(dev, "idr_alloc failed: %d\n", ret);
-               dma_free_coherent(dev->parent, size, va, dma);
                return ret;
        }
        notifyid = ret;
@@ -241,21 +362,9 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
        if (notifyid > rproc->max_notifyid)
                rproc->max_notifyid = notifyid;
 
-       dev_dbg(dev, "vring%d: va %pK dma %pad size 0x%x idr %d\n",
-               i, va, &dma, size, notifyid);
-
-       rvring->va = va;
-       rvring->dma = dma;
        rvring->notifyid = notifyid;
 
-       /*
-        * Let the rproc know the notifyid and da of this vring.
-        * Not all platforms use dma_alloc_coherent to automatically
-        * set up the iommu. In this case the device address (da) will
-        * hold the physical address and not the device address.
-        */
-       rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
-       rsc->vring[i].da = dma;
+       /* Let the rproc know the notifyid of this vring.*/
        rsc->vring[i].notifyid = notifyid;
        return 0;
 }
@@ -287,12 +396,10 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
 
 void rproc_free_vring(struct rproc_vring *rvring)
 {
-       int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
        struct rproc *rproc = rvring->rvdev->rproc;
        int idx = rvring->rvdev->vring - rvring;
        struct fw_rsc_vdev *rsc;
 
-       dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
        idr_remove(&rproc->notifyids, rvring->notifyid);
 
        /* reset resource entry info */
@@ -379,6 +486,7 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
 
        rvdev->id = rsc->id;
        rvdev->rproc = rproc;
+       rvdev->index = rproc->nb_vdev++;
 
        /* parse the vrings */
        for (i = 0; i < rsc->num_of_vrings; i++) {
@@ -423,9 +531,6 @@ void rproc_vdev_release(struct kref *ref)
 
        for (id = 0; id < ARRAY_SIZE(rvdev->vring); id++) {
                rvring = &rvdev->vring[id];
-               if (!rvring->va)
-                       continue;
-
                rproc_free_vring(rvring);
        }
 
@@ -584,61 +689,31 @@ out:
 }
 
 /**
- * rproc_handle_carveout() - handle phys contig memory allocation requests
+ * rproc_alloc_carveout() - allocated specified carveout
  * @rproc: rproc handle
- * @rsc: the resource entry
- * @avail: size of available data (for image validation)
- *
- * This function will handle firmware requests for allocation of physically
- * contiguous memory regions.
- *
- * These request entries should come first in the firmware's resource table,
- * as other firmware entries might request placing other data objects inside
- * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ * @mem: the memory entry to allocate
  *
- * Allocating memory this way helps utilizing the reserved physical memory
- * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
- * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
- * pressure is important; it may have a substantial impact on performance.
+ * This function allocate specified memory entry @mem using
+ * dma_alloc_coherent() as default allocator
  */
-static int rproc_handle_carveout(struct rproc *rproc,
-                                struct fw_rsc_carveout *rsc,
-                                int offset, int avail)
+static int rproc_alloc_carveout(struct rproc *rproc,
+                               struct rproc_mem_entry *mem)
 {
-       struct rproc_mem_entry *carveout, *mapping;
+       struct rproc_mem_entry *mapping = NULL;
        struct device *dev = &rproc->dev;
        dma_addr_t dma;
        void *va;
        int ret;
 
-       if (sizeof(*rsc) > avail) {
-               dev_err(dev, "carveout rsc is truncated\n");
-               return -EINVAL;
-       }
-
-       /* make sure reserved bytes are zeroes */
-       if (rsc->reserved) {
-               dev_err(dev, "carveout rsc has non zero reserved bytes\n");
-               return -EINVAL;
-       }
-
-       dev_dbg(dev, "carveout rsc: name: %s, da 0x%x, pa 0x%x, len 0x%x, flags 0x%x\n",
-               rsc->name, rsc->da, rsc->pa, rsc->len, rsc->flags);
-
-       carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
-       if (!carveout)
-               return -ENOMEM;
-
-       va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
+       va = dma_alloc_coherent(dev->parent, mem->len, &dma, GFP_KERNEL);
        if (!va) {
                dev_err(dev->parent,
-                       "failed to allocate dma memory: len 0x%x\n", rsc->len);
-               ret = -ENOMEM;
-               goto free_carv;
+                       "failed to allocate dma memory: len 0x%x\n", mem->len);
+               return -ENOMEM;
        }
 
        dev_dbg(dev, "carveout va %pK, dma %pad, len 0x%x\n",
-               va, &dma, rsc->len);
+               va, &dma, mem->len);
 
        /*
         * Ok, this is non-standard.
@@ -657,15 +732,23 @@ static int rproc_handle_carveout(struct rproc *rproc,
         * to use the iommu-based DMA API: we expect 'dma' to contain the
         * physical address in this case.
         */
-       if (rproc->domain) {
+
+       if (mem->da != FW_RSC_ADDR_ANY) {
+               if (!rproc->domain) {
+                       dev_err(dev->parent,
+                               "Bad carveout rsc configuration\n");
+                       ret = -ENOMEM;
+                       goto dma_free;
+               }
+
                mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
                if (!mapping) {
                        ret = -ENOMEM;
                        goto dma_free;
                }
 
-               ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
-                               rsc->flags);
+               ret = iommu_map(rproc->domain, mem->da, dma, mem->len,
+                               mem->flags);
                if (ret) {
                        dev_err(dev, "iommu_map failed: %d\n", ret);
                        goto free_mapping;
@@ -678,52 +761,219 @@ static int rproc_handle_carveout(struct rproc *rproc,
                 * We can't trust the remote processor not to change the
                 * resource table, so we must maintain this info independently.
                 */
-               mapping->da = rsc->da;
-               mapping->len = rsc->len;
+               mapping->da = mem->da;
+               mapping->len = mem->len;
                list_add_tail(&mapping->node, &rproc->mappings);
 
                dev_dbg(dev, "carveout mapped 0x%x to %pad\n",
-                       rsc->da, &dma);
+                       mem->da, &dma);
+       } else {
+               mem->da = (u32)dma;
        }
 
-       /*
-        * Some remote processors might need to know the pa
-        * even though they are behind an IOMMU. E.g., OMAP4's
-        * remote M3 processor needs this so it can control
-        * on-chip hardware accelerators that are not behind
-        * the IOMMU, and therefor must know the pa.
-        *
-        * Generally we don't want to expose physical addresses
-        * if we don't have to (remote processors are generally
-        * _not_ trusted), so we might want to do this only for
-        * remote processor that _must_ have this (e.g. OMAP4's
-        * dual M3 subsystem).
-        *
-        * Non-IOMMU processors might also want to have this info.
-        * In this case, the device address and the physical address
-        * are the same.
-        */
-       rsc->pa = dma;
-
-       carveout->va = va;
-       carveout->len = rsc->len;
-       carveout->dma = dma;
-       carveout->da = rsc->da;
-
-       list_add_tail(&carveout->node, &rproc->carveouts);
+       mem->dma = (u32)dma;
+       mem->va = va;
 
        return 0;
 
 free_mapping:
        kfree(mapping);
 dma_free:
-       dma_free_coherent(dev->parent, rsc->len, va, dma);
-free_carv:
-       kfree(carveout);
+       dma_free_coherent(dev->parent, mem->len, va, dma);
        return ret;
 }
 
-/*
+/**
+ * rproc_release_carveout() - release acquired carveout
+ * @rproc: rproc handle
+ * @mem: the memory entry to release
+ *
+ * This function releases specified memory entry @mem allocated via
+ * rproc_alloc_carveout() function by @rproc.
+ */
+static int rproc_release_carveout(struct rproc *rproc,
+                                 struct rproc_mem_entry *mem)
+{
+       struct device *dev = &rproc->dev;
+
+       /* clean up carveout allocations */
+       dma_free_coherent(dev->parent, mem->len, mem->va, mem->dma);
+       return 0;
+}
+
+/**
+ * rproc_handle_carveout() - handle phys contig memory allocation requests
+ * @rproc: rproc handle
+ * @rsc: the resource entry
+ * @avail: size of available data (for image validation)
+ *
+ * This function will handle firmware requests for allocation of physically
+ * contiguous memory regions.
+ *
+ * These request entries should come first in the firmware's resource table,
+ * as other firmware entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ */
+static int rproc_handle_carveout(struct rproc *rproc,
+                                struct fw_rsc_carveout *rsc,
+                                int offset, int avail)
+{
+       struct rproc_mem_entry *carveout;
+       struct device *dev = &rproc->dev;
+
+       if (sizeof(*rsc) > avail) {
+               dev_err(dev, "carveout rsc is truncated\n");
+               return -EINVAL;
+       }
+
+       /* make sure reserved bytes are zeroes */
+       if (rsc->reserved) {
+               dev_err(dev, "carveout rsc has non zero reserved bytes\n");
+               return -EINVAL;
+       }
+
+       dev_dbg(dev, "carveout rsc: name: %s, da 0x%x, pa 0x%x, len 0x%x, flags 0x%x\n",
+               rsc->name, rsc->da, rsc->pa, rsc->len, rsc->flags);
+
+       /*
+        * Check carveout rsc already part of a registered carveout,
+        * Search by name, then check the da and length
+        */
+       carveout = rproc_find_carveout_by_name(rproc, rsc->name);
+
+       if (carveout) {
+               if (carveout->rsc_offset != FW_RSC_ADDR_ANY) {
+                       dev_err(dev,
+                               "Carveout already associated to resource table\n");
+                       return -ENOMEM;
+               }
+
+               if (rproc_check_carveout_da(rproc, carveout, rsc->da, rsc->len))
+                       return -ENOMEM;
+
+               /* Update memory carveout with resource table info */
+               carveout->rsc_offset = offset;
+               carveout->flags = rsc->flags;
+
+               return 0;
+       }
+
+       /* Register carveout in in list */
+       carveout = rproc_mem_entry_init(dev, 0, 0, rsc->len, rsc->da,
+                                       rproc_alloc_carveout,
+                                       rproc_release_carveout, rsc->name);
+       if (!carveout) {
+               dev_err(dev, "Can't allocate memory entry structure\n");
+               return -ENOMEM;
+       }
+
+       carveout->flags = rsc->flags;
+       carveout->rsc_offset = offset;
+       rproc_add_carveout(rproc, carveout);
+
+       return 0;
+}
+
+/**
+ * rproc_add_carveout() - register an allocated carveout region
+ * @rproc: rproc handle
+ * @mem: memory entry to register
+ *
+ * This function registers specified memory entry in @rproc carveouts list.
+ * Specified carveout should have been allocated before registering.
+ */
+void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem)
+{
+       list_add_tail(&mem->node, &rproc->carveouts);
+}
+EXPORT_SYMBOL(rproc_add_carveout);
+
+/**
+ * rproc_mem_entry_init() - allocate and initialize rproc_mem_entry struct
+ * @dev: pointer on device struct
+ * @va: virtual address
+ * @dma: dma address
+ * @len: memory carveout length
+ * @da: device address
+ * @release: memory carveout function
+ * @name: carveout name
+ *
+ * This function allocates a rproc_mem_entry struct and fill it with parameters
+ * provided by client.
+ */
+struct rproc_mem_entry *
+rproc_mem_entry_init(struct device *dev,
+                    void *va, dma_addr_t dma, int len, u32 da,
+                    int (*alloc)(struct rproc *, struct rproc_mem_entry *),
+                    int (*release)(struct rproc *, struct rproc_mem_entry *),
+                    const char *name, ...)
+{
+       struct rproc_mem_entry *mem;
+       va_list args;
+
+       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       if (!mem)
+               return mem;
+
+       mem->va = va;
+       mem->dma = dma;
+       mem->da = da;
+       mem->len = len;
+       mem->alloc = alloc;
+       mem->release = release;
+       mem->rsc_offset = FW_RSC_ADDR_ANY;
+       mem->of_resm_idx = -1;
+
+       va_start(args, name);
+       vsnprintf(mem->name, sizeof(mem->name), name, args);
+       va_end(args);
+
+       return mem;
+}
+EXPORT_SYMBOL(rproc_mem_entry_init);
+
+/**
+ * rproc_of_resm_mem_entry_init() - allocate and initialize rproc_mem_entry struct
+ * from a reserved memory phandle
+ * @dev: pointer on device struct
+ * @of_resm_idx: reserved memory phandle index in "memory-region"
+ * @len: memory carveout length
+ * @da: device address
+ * @name: carveout name
+ *
+ * This function allocates a rproc_mem_entry struct and fill it with parameters
+ * provided by client.
+ */
+struct rproc_mem_entry *
+rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, int len,
+                            u32 da, const char *name, ...)
+{
+       struct rproc_mem_entry *mem;
+       va_list args;
+
+       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       if (!mem)
+               return mem;
+
+       mem->da = da;
+       mem->len = len;
+       mem->rsc_offset = FW_RSC_ADDR_ANY;
+       mem->of_resm_idx = of_resm_idx;
+
+       va_start(args, name);
+       vsnprintf(mem->name, sizeof(mem->name), name, args);
+       va_end(args);
+
+       return mem;
+}
+EXPORT_SYMBOL(rproc_of_resm_mem_entry_init);
+
+/**
  * A lookup table for resource handlers. The indices are defined in
  * enum fw_resource_type.
  */
@@ -844,6 +1094,70 @@ static void rproc_unprepare_subdevices(struct rproc *rproc)
        }
 }
 
+/**
+ * rproc_alloc_registered_carveouts() - allocate all carveouts registered
+ * in the list
+ * @rproc: the remote processor handle
+ *
+ * This function parses registered carveout list, performs allocation
+ * if alloc() ops registered and updates resource table information
+ * if rsc_offset set.
+ *
+ * Return: 0 on success
+ */
+static int rproc_alloc_registered_carveouts(struct rproc *rproc)
+{
+       struct rproc_mem_entry *entry, *tmp;
+       struct fw_rsc_carveout *rsc;
+       struct device *dev = &rproc->dev;
+       int ret;
+
+       list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
+               if (entry->alloc) {
+                       ret = entry->alloc(rproc, entry);
+                       if (ret) {
+                               dev_err(dev, "Unable to allocate carveout %s: %d\n",
+                                       entry->name, ret);
+                               return -ENOMEM;
+                       }
+               }
+
+               if (entry->rsc_offset != FW_RSC_ADDR_ANY) {
+                       /* update resource table */
+                       rsc = (void *)rproc->table_ptr + entry->rsc_offset;
+
+                       /*
+                        * Some remote processors might need to know the pa
+                        * even though they are behind an IOMMU. E.g., OMAP4's
+                        * remote M3 processor needs this so it can control
+                        * on-chip hardware accelerators that are not behind
+                        * the IOMMU, and therefor must know the pa.
+                        *
+                        * Generally we don't want to expose physical addresses
+                        * if we don't have to (remote processors are generally
+                        * _not_ trusted), so we might want to do this only for
+                        * remote processor that _must_ have this (e.g. OMAP4's
+                        * dual M3 subsystem).
+                        *
+                        * Non-IOMMU processors might also want to have this info.
+                        * In this case, the device address and the physical address
+                        * are the same.
+                        */
+
+                       /* Use va if defined else dma to generate pa */
+                       if (entry->va)
+                               rsc->pa = (u32)rproc_va_to_pa(entry->va);
+                       else
+                               rsc->pa = (u32)entry->dma;
+
+                       rsc->da = entry->da;
+                       rsc->len = entry->len;
+               }
+       }
+
+       return 0;
+}
+
 /**
  * rproc_coredump_cleanup() - clean up dump_segments list
  * @rproc: the remote processor handle
@@ -896,8 +1210,8 @@ static void rproc_resource_cleanup(struct rproc *rproc)
 
        /* clean up carveout allocations */
        list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
-               dma_free_coherent(dev->parent, entry->len, entry->va,
-                                 entry->dma);
+               if (entry->release)
+                       entry->release(rproc, entry);
                list_del(&entry->node);
                kfree(entry);
        }
@@ -1009,6 +1323,9 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
        /* reset max_notifyid */
        rproc->max_notifyid = -1;
 
+       /* reset handled vdev */
+       rproc->nb_vdev = 0;
+
        /* handle fw resources which are required to boot rproc */
        ret = rproc_handle_resources(rproc, rproc_loading_handlers);
        if (ret) {
@@ -1016,6 +1333,14 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
                goto clean_up_resources;
        }
 
+       /* Allocate carveout resources associated to rproc */
+       ret = rproc_alloc_registered_carveouts(rproc);
+       if (ret) {
+               dev_err(dev, "Failed to allocate associated carveouts: %d\n",
+                       ret);
+               goto clean_up_resources;
+       }
+
        ret = rproc_start(rproc, fw);
        if (ret)
                goto clean_up_resources;
@@ -1121,6 +1446,44 @@ int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size)
 }
 EXPORT_SYMBOL(rproc_coredump_add_segment);
 
+/**
+ * rproc_coredump_add_custom_segment() - add custom coredump segment
+ * @rproc:     handle of a remote processor
+ * @da:                device address
+ * @size:      size of segment
+ * @dumpfn:    custom dump function called for each segment during coredump
+ * @priv:      private data
+ *
+ * Add device memory to the list of segments to be included in the coredump
+ * and associate the segment with the given custom dump function and private
+ * data.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+int rproc_coredump_add_custom_segment(struct rproc *rproc,
+                                     dma_addr_t da, size_t size,
+                                     void (*dumpfn)(struct rproc *rproc,
+                                                    struct rproc_dump_segment *segment,
+                                                    void *dest),
+                                     void *priv)
+{
+       struct rproc_dump_segment *segment;
+
+       segment = kzalloc(sizeof(*segment), GFP_KERNEL);
+       if (!segment)
+               return -ENOMEM;
+
+       segment->da = da;
+       segment->size = size;
+       segment->priv = priv;
+       segment->dump = dumpfn;
+
+       list_add_tail(&segment->node, &rproc->dump_segments);
+
+       return 0;
+}
+EXPORT_SYMBOL(rproc_coredump_add_custom_segment);
+
 /**
  * rproc_coredump() - perform coredump
  * @rproc:     rproc handle
@@ -1183,14 +1546,18 @@ static void rproc_coredump(struct rproc *rproc)
                phdr->p_flags = PF_R | PF_W | PF_X;
                phdr->p_align = 0;
 
-               ptr = rproc_da_to_va(rproc, segment->da, segment->size);
-               if (!ptr) {
-                       dev_err(&rproc->dev,
-                               "invalid coredump segment (%pad, %zu)\n",
-                               &segment->da, segment->size);
-                       memset(data + offset, 0xff, segment->size);
+               if (segment->dump) {
+                       segment->dump(rproc, segment, data + offset);
                } else {
-                       memcpy(data + offset, ptr, segment->size);
+                       ptr = rproc_da_to_va(rproc, segment->da, segment->size);
+                       if (!ptr) {
+                               dev_err(&rproc->dev,
+                                       "invalid coredump segment (%pad, %zu)\n",
+                                       &segment->da, segment->size);
+                               memset(data + offset, 0xff, segment->size);
+                       } else {
+                               memcpy(data + offset, ptr, segment->size);
+                       }
                }
 
                offset += phdr->p_filesz;
index a5c29f2764a34f4d12b3080cbcec30d4fc908506..e90135c64af0761ec37d392921a33aa602829f0f 100644 (file)
@@ -260,6 +260,7 @@ static int rproc_carveouts_show(struct seq_file *seq, void *p)
 
        list_for_each_entry(carveout, &rproc->carveouts, node) {
                seq_puts(seq, "Carveout memory entry:\n");
+               seq_printf(seq, "\tName: %s\n", carveout->name);
                seq_printf(seq, "\tVirtual address: %pK\n", carveout->va);
                seq_printf(seq, "\tDMA address: %pad\n", &carveout->dma);
                seq_printf(seq, "\tDevice address: 0x%x\n", carveout->da);
index 7570beb035b5f462f9c9ae19ef9ed1ceff6a6424..f6cad243d7cac9a7255be1107db5981d5ab3eff2 100644 (file)
@@ -60,6 +60,8 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw);
 int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw);
 struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
                                                       const struct firmware *fw);
+struct rproc_mem_entry *
+rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);
 
 static inline
 int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
index 47be411400e56aed1b48f44d4254e0178a640412..3a4c3d7cafca35f7752c9ddb402a643549be4050 100644 (file)
@@ -48,6 +48,11 @@ static ssize_t firmware_store(struct device *dev,
        }
 
        len = strcspn(buf, "\n");
+       if (!len) {
+               dev_err(dev, "can't provide a NULL firmware\n");
+               err = -EINVAL;
+               goto out;
+       }
 
        p = kstrndup(buf, len, GFP_KERNEL);
        if (!p) {
index bbecd44df7e8de3b28ee10b7066c42913aec540a..de21f620b88229d9fd27f2374c61756021df9b75 100644 (file)
@@ -76,7 +76,9 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
        struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
        struct rproc *rproc = vdev_to_rproc(vdev);
        struct device *dev = &rproc->dev;
+       struct rproc_mem_entry *mem;
        struct rproc_vring *rvring;
+       struct fw_rsc_vdev *rsc;
        struct virtqueue *vq;
        void *addr;
        int len, size;
@@ -88,8 +90,14 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
        if (!name)
                return NULL;
 
+       /* Search allocated memory region by name */
+       mem = rproc_find_carveout_by_name(rproc, "vdev%dvring%d", rvdev->index,
+                                         id);
+       if (!mem || !mem->va)
+               return ERR_PTR(-ENOMEM);
+
        rvring = &rvdev->vring[id];
-       addr = rvring->va;
+       addr = mem->va;
        len = rvring->len;
 
        /* zero vring */
@@ -114,6 +122,10 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
        rvring->vq = vq;
        vq->priv = rvring;
 
+       /* Update vring in resource table */
+       rsc = (void *)rproc->table_ptr + rvdev->rsc_offset;
+       rsc->vring[id].da = mem->da;
+
        return vq;
 }
 
index 13d28fdbdbb535cdf665b39c8b52ad5127d0b9b9..c21da9fe51ec0f1ef47c4798379904433e2b553f 100644 (file)
@@ -98,6 +98,15 @@ config RESET_QCOM_AOSS
          reset signals provided by AOSS for Modem, Venus, ADSP,
          GPU, Camera, Wireless, Display subsystem. Otherwise, say N.
 
+config RESET_QCOM_PDC
+       tristate "Qualcomm PDC Reset Driver"
+       depends on ARCH_QCOM || COMPILE_TEST
+       help
+         This enables the PDC (Power Domain Controller) reset driver
+         for Qualcomm Technologies Inc SDM845 SoCs. Say Y if you want
+         to control reset signals provided by PDC for Modem, Compute,
+         Display, GPU, Debug, AOP, Sensors, Audio, SP and APPS.
+
 config RESET_SIMPLE
        bool "Simple Reset Controller Driver" if COMPILE_TEST
        default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED
index 4243c38228e284478048c42cfbf0f900b7d7aed4..d08e8b90046a96f8d38b770126a13ef1df8d0283 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
 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_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
index 225e34c56b94a2e315f17a598bd7a74d6dae1932..d1887c0ed5d3f2aa7e51f94f5f9e61cbf50ca5ea 100644 (file)
@@ -496,28 +496,29 @@ struct reset_control *__of_reset_control_get(struct device_node *node,
                        break;
                }
        }
-       of_node_put(args.np);
 
        if (!rcdev) {
-               mutex_unlock(&reset_list_mutex);
-               return ERR_PTR(-EPROBE_DEFER);
+               rstc = ERR_PTR(-EPROBE_DEFER);
+               goto out;
        }
 
        if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) {
-               mutex_unlock(&reset_list_mutex);
-               return ERR_PTR(-EINVAL);
+               rstc = ERR_PTR(-EINVAL);
+               goto out;
        }
 
        rstc_id = rcdev->of_xlate(rcdev, &args);
        if (rstc_id < 0) {
-               mutex_unlock(&reset_list_mutex);
-               return ERR_PTR(rstc_id);
+               rstc = ERR_PTR(rstc_id);
+               goto out;
        }
 
        /* reset_list_mutex also protects the rcdev's reset_control list */
        rstc = __reset_control_get_internal(rcdev, rstc_id, shared);
 
+out:
        mutex_unlock(&reset_list_mutex);
+       of_node_put(args.np);
 
        return rstc;
 }
diff --git a/drivers/reset/reset-qcom-pdc.c b/drivers/reset/reset-qcom-pdc.c
new file mode 100644 (file)
index 0000000..ab74bcc
--- /dev/null
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/reset/qcom,sdm845-pdc.h>
+
+#define RPMH_PDC_SYNC_RESET    0x100
+
+struct qcom_pdc_reset_map {
+       u8 bit;
+};
+
+struct qcom_pdc_reset_data {
+       struct reset_controller_dev rcdev;
+       struct regmap *regmap;
+};
+
+static const struct regmap_config sdm845_pdc_regmap_config = {
+       .name           = "pdc-reset",
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x20000,
+       .fast_io        = true,
+};
+
+static const struct qcom_pdc_reset_map sdm845_pdc_resets[] = {
+       [PDC_APPS_SYNC_RESET] = {0},
+       [PDC_SP_SYNC_RESET] = {1},
+       [PDC_AUDIO_SYNC_RESET] = {2},
+       [PDC_SENSORS_SYNC_RESET] = {3},
+       [PDC_AOP_SYNC_RESET] = {4},
+       [PDC_DEBUG_SYNC_RESET] = {5},
+       [PDC_GPU_SYNC_RESET] = {6},
+       [PDC_DISPLAY_SYNC_RESET] = {7},
+       [PDC_COMPUTE_SYNC_RESET] = {8},
+       [PDC_MODEM_SYNC_RESET] = {9},
+};
+
+static inline struct qcom_pdc_reset_data *to_qcom_pdc_reset_data(
+                               struct reset_controller_dev *rcdev)
+{
+       return container_of(rcdev, struct qcom_pdc_reset_data, rcdev);
+}
+
+static int qcom_pdc_control_assert(struct reset_controller_dev *rcdev,
+                                       unsigned long idx)
+{
+       struct qcom_pdc_reset_data *data = to_qcom_pdc_reset_data(rcdev);
+
+       return regmap_update_bits(data->regmap, RPMH_PDC_SYNC_RESET,
+                                 BIT(sdm845_pdc_resets[idx].bit),
+                                 BIT(sdm845_pdc_resets[idx].bit));
+}
+
+static int qcom_pdc_control_deassert(struct reset_controller_dev *rcdev,
+                                       unsigned long idx)
+{
+       struct qcom_pdc_reset_data *data = to_qcom_pdc_reset_data(rcdev);
+
+       return regmap_update_bits(data->regmap, RPMH_PDC_SYNC_RESET,
+                                 BIT(sdm845_pdc_resets[idx].bit), 0);
+}
+
+static const struct reset_control_ops qcom_pdc_reset_ops = {
+       .assert = qcom_pdc_control_assert,
+       .deassert = qcom_pdc_control_deassert,
+};
+
+static int qcom_pdc_reset_probe(struct platform_device *pdev)
+{
+       struct qcom_pdc_reset_data *data;
+       struct device *dev = &pdev->dev;
+       void __iomem *base;
+       struct resource *res;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       data->regmap = devm_regmap_init_mmio(dev, base,
+                                            &sdm845_pdc_regmap_config);
+       if (IS_ERR(data->regmap)) {
+               dev_err(dev, "Unable to initialize regmap\n");
+               return PTR_ERR(data->regmap);
+       }
+
+       data->rcdev.owner = THIS_MODULE;
+       data->rcdev.ops = &qcom_pdc_reset_ops;
+       data->rcdev.nr_resets = ARRAY_SIZE(sdm845_pdc_resets);
+       data->rcdev.of_node = dev->of_node;
+
+       return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static const struct of_device_id qcom_pdc_reset_of_match[] = {
+       { .compatible = "qcom,sdm845-pdc-global" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, qcom_pdc_reset_of_match);
+
+static struct platform_driver qcom_pdc_reset_driver = {
+       .probe = qcom_pdc_reset_probe,
+       .driver = {
+               .name = "qcom_pdc_reset",
+               .of_match_table = qcom_pdc_reset_of_match,
+       },
+};
+module_platform_driver(qcom_pdc_reset_driver);
+
+MODULE_DESCRIPTION("Qualcomm PDC Reset Driver");
+MODULE_LICENSE("GPL v2");
index e2ce4e638258b7a64de8e9f41e6167f09aaf8c74..f46c787733e8ac6ac63cf5eca85a40cad0665272 100644 (file)
@@ -792,9 +792,6 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
                return -EAGAIN;
        }
 
-       if (WARN(chunk_size % 4, "Incoming data must be word aligned\n"))
-               return -EINVAL;
-
        rcid = le16_to_cpu(hdr.msg.param1);
        spin_lock_irqsave(&glink->idr_lock, flags);
        channel = idr_find(&glink->rcids, rcid);
index 2b5cf279095403f9ab54ffac2db194d4445b2503..64a5ce324c7f7e52b740db8a86d62ed84c3111e7 100644 (file)
@@ -89,15 +89,11 @@ static void glink_smem_rx_peak(struct qcom_glink_pipe *np,
                tail -= pipe->native.length;
 
        len = min_t(size_t, count, pipe->native.length - tail);
-       if (len) {
-               __ioread32_copy(data, pipe->fifo + tail,
-                               len / sizeof(u32));
-       }
+       if (len)
+               memcpy_fromio(data, pipe->fifo + tail, len);
 
-       if (len != count) {
-               __ioread32_copy(data + len, pipe->fifo,
-                               (count - len) / sizeof(u32));
-       }
+       if (len != count)
+               memcpy_fromio(data + len, pipe->fifo, (count - len));
 }
 
 static void glink_smem_rx_advance(struct qcom_glink_pipe *np,
@@ -205,7 +201,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent,
        dev->parent = parent;
        dev->of_node = node;
        dev->release = qcom_glink_smem_release;
-       dev_set_name(dev, "%s:%s", node->parent->name, node->name);
+       dev_set_name(dev, "%pOFn:%pOFn", node->parent, node);
        ret = device_register(dev);
        if (ret) {
                pr_err("failed to register glink edge\n");
index 8da83a4ebadc32143ec2950f3fda2a922f86812c..4abbeea782fa426b92d1f6103a3bf28f789cc3e3 100644 (file)
@@ -1122,8 +1122,10 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 
        channel->edge = edge;
        channel->name = kstrdup(name, GFP_KERNEL);
-       if (!channel->name)
-               return ERR_PTR(-ENOMEM);
+       if (!channel->name) {
+               ret = -ENOMEM;
+               goto free_channel;
+       }
 
        spin_lock_init(&channel->tx_lock);
        spin_lock_init(&channel->recv_lock);
@@ -1173,6 +1175,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 
 free_name_and_channel:
        kfree(channel->name);
+free_channel:
        kfree(channel);
 
        return ERR_PTR(ret);
@@ -1454,7 +1457,7 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent,
        edge->dev.release = qcom_smd_edge_release;
        edge->dev.of_node = node;
        edge->dev.groups = qcom_smd_edge_groups;
-       dev_set_name(&edge->dev, "%s:%s", dev_name(parent), node->name);
+       dev_set_name(&edge->dev, "%s:%pOFn", dev_name(parent), node);
        ret = device_register(&edge->dev);
        if (ret) {
                pr_err("failed to register smd edge\n");
index a76b963a7e50f31e919c9e476de8d2161fad390f..eea5ebbb5119a85eb12b1ca550ea93b75ed88c8f 100644 (file)
@@ -167,9 +167,9 @@ static int rpmsg_eptdev_release(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static ssize_t rpmsg_eptdev_read(struct file *filp, char __user *buf,
-                                size_t len, loff_t *f_pos)
+static ssize_t rpmsg_eptdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
+       struct file *filp = iocb->ki_filp;
        struct rpmsg_eptdev *eptdev = filp->private_data;
        unsigned long flags;
        struct sk_buff *skb;
@@ -205,8 +205,8 @@ static ssize_t rpmsg_eptdev_read(struct file *filp, char __user *buf,
        if (!skb)
                return -EFAULT;
 
-       use = min_t(size_t, len, skb->len);
-       if (copy_to_user(buf, skb->data, use))
+       use = min_t(size_t, iov_iter_count(to), skb->len);
+       if (copy_to_iter(skb->data, use, to) != use)
                use = -EFAULT;
 
        kfree_skb(skb);
@@ -214,16 +214,21 @@ static ssize_t rpmsg_eptdev_read(struct file *filp, char __user *buf,
        return use;
 }
 
-static ssize_t rpmsg_eptdev_write(struct file *filp, const char __user *buf,
-                                 size_t len, loff_t *f_pos)
+static ssize_t rpmsg_eptdev_write_iter(struct kiocb *iocb,
+                                      struct iov_iter *from)
 {
+       struct file *filp = iocb->ki_filp;
        struct rpmsg_eptdev *eptdev = filp->private_data;
+       size_t len = iov_iter_count(from);
        void *kbuf;
        int ret;
 
-       kbuf = memdup_user(buf, len);
-       if (IS_ERR(kbuf))
-               return PTR_ERR(kbuf);
+       kbuf = kzalloc(len, GFP_KERNEL);
+       if (!kbuf)
+               return -ENOMEM;
+
+       if (!copy_from_iter_full(kbuf, len, from))
+               return -EFAULT;
 
        if (mutex_lock_interruptible(&eptdev->ept_lock)) {
                ret = -ERESTARTSYS;
@@ -281,8 +286,8 @@ static const struct file_operations rpmsg_eptdev_fops = {
        .owner = THIS_MODULE,
        .open = rpmsg_eptdev_open,
        .release = rpmsg_eptdev_release,
-       .read = rpmsg_eptdev_read,
-       .write = rpmsg_eptdev_write,
+       .read_iter = rpmsg_eptdev_read_iter,
+       .write_iter = rpmsg_eptdev_write_iter,
        .poll = rpmsg_eptdev_poll,
        .unlocked_ioctl = rpmsg_eptdev_ioctl,
        .compat_ioctl = rpmsg_eptdev_ioctl,
index 16a4e8528bbc34198677f1e9f879790192fb4f33..8f3a2eeb28dca0b579d2d773057296e92f379342 100644 (file)
@@ -8,7 +8,7 @@
  *     Copyright IBM Corp. 2003, 2009
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index 5b8af278228282914a4250ee655aa4f85355ef7f..2b0c36c2c5688ebf6ef0266d66cad52793b7ae1b 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/workqueue.h>
 
 #include <linux/slab.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/compat.h>
 
 #include <asm/ccwdev.h>
index 8af4948dae806d56e22fc16a913eb84f47b77cbc..72dd2471ec1ebdd97445f157261c7a373055a9bd 100644 (file)
@@ -13,7 +13,7 @@
 #define KMSG_COMPONENT "cio"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/list.h>
index 8f5c1d7f751aee594b763100c2bf6265df9f3a7d..97b6f197f0079b949e4947df00efaed4dbfd76fe 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/err.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
index 153b3f3cc795fdd5b7d0e31ff5a18043b738b4c8..a5136901dd8a94463f49cd87089403b0bf6e121c 100644 (file)
@@ -59,7 +59,7 @@
 #define KMSG_COMPONENT "SFI"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
index 113e884697fd8c3478d9b7900a79360fb3fad2f5..446166ba0bec43e65d3f041bf16244ebf3d98330 100644 (file)
@@ -18,7 +18,7 @@ obj-y                         += qcom/
 obj-y                          += renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)    += rockchip/
 obj-$(CONFIG_SOC_SAMSUNG)      += samsung/
-obj-$(CONFIG_ARCH_SUNXI)       += sunxi/
+obj-y                          += sunxi/
 obj-$(CONFIG_ARCH_TEGRA)       += tegra/
 obj-$(CONFIG_SOC_TI)           += ti/
 obj-$(CONFIG_ARCH_U8500)       += ux500/
index 9d68b5a771c330ff1107eee5abdb7f8ebebf5bb9..1a0b9649efb4cbb7e722896aff18ba65b21c7b65 100644 (file)
@@ -10,7 +10,7 @@ config OWL_PM_DOMAINS
        select PM_GENERIC_DOMAINS
        help
          Say 'y' here to enable support for Smart Power System (SPS)
-         power-gating on Actions Semiconductor S500 SoC.
+         power-gating on Actions Semiconductor S500, S700 and S900 SoCs.
          If unsure, say 'n'.
 
 endif
index 1e101b06bab1e22ba838933870459f81627a4f66..4db9e7b050e5d9eaf1ee63f2e31282cdd8432cbc 100644 (file)
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
 obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o
 obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
index 9d7a2c2b44ec804a15eea28e2526eea3443b6c45..291a206d6f04aaeb9c1bf247a39560e931816859 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Actions Semi Owl Smart Power System (SPS) shared helpers
  *
@@ -5,11 +6,6 @@
  * Author: Actions Semi, Inc.
  *
  * Copyright (c) 2017 Andreas Färber
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
  */
 
 #include <linux/delay.h>
index 032921d8d41f3cf67ccb66ddfa9c65dc4dff1e64..73a9e0bb7e8ed98c651f63a559bdce95893903e5 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Actions Semi Owl Smart Power System (SPS)
  *
@@ -5,11 +6,6 @@
  * Author: Actions Semi, Inc.
  *
  * Copyright (c) 2017 Andreas Färber
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
  */
 
 #include <linux/of_address.h>
@@ -18,6 +14,7 @@
 #include <linux/soc/actions/owl-sps.h>
 #include <dt-bindings/power/owl-s500-powergate.h>
 #include <dt-bindings/power/owl-s700-powergate.h>
+#include <dt-bindings/power/owl-s900-powergate.h>
 
 struct owl_sps_domain_info {
        const char *name;
@@ -244,9 +241,66 @@ static const struct owl_sps_info s700_sps_info = {
        .domains = s700_sps_domains,
 };
 
+static const struct owl_sps_domain_info s900_sps_domains[] = {
+       [S900_PD_GPU_B] = {
+               .name = "GPU_B",
+               .pwr_bit = 3,
+       },
+       [S900_PD_VCE] = {
+               .name = "VCE",
+               .pwr_bit = 4,
+       },
+       [S900_PD_SENSOR] = {
+               .name = "SENSOR",
+               .pwr_bit = 5,
+       },
+       [S900_PD_VDE] = {
+               .name = "VDE",
+               .pwr_bit = 6,
+       },
+       [S900_PD_HDE] = {
+               .name = "HDE",
+               .pwr_bit = 7,
+       },
+       [S900_PD_USB3] = {
+               .name = "USB3",
+               .pwr_bit = 8,
+       },
+       [S900_PD_DDR0] = {
+               .name = "DDR0",
+               .pwr_bit = 9,
+       },
+       [S900_PD_DDR1] = {
+               .name = "DDR1",
+               .pwr_bit = 10,
+       },
+       [S900_PD_DE] = {
+               .name = "DE",
+               .pwr_bit = 13,
+       },
+       [S900_PD_NAND] = {
+               .name = "NAND",
+               .pwr_bit = 14,
+       },
+       [S900_PD_USB2_H0] = {
+               .name = "USB2_H0",
+               .pwr_bit = 15,
+       },
+       [S900_PD_USB2_H1] = {
+               .name = "USB2_H1",
+               .pwr_bit = 16,
+       },
+};
+
+static const struct owl_sps_info s900_sps_info = {
+       .num_domains = ARRAY_SIZE(s900_sps_domains),
+       .domains = s900_sps_domains,
+};
+
 static const struct of_device_id owl_sps_of_matches[] = {
        { .compatible = "actions,s500-sps", .data = &s500_sps_info },
        { .compatible = "actions,s700-sps", .data = &s700_sps_info },
+       { .compatible = "actions,s900-sps", .data = &s900_sps_info },
        { }
 };
 
index b04f6e4aedbc1ea32c2717af5555293e865fece6..2f282b47291205a8a4304e0e74d07feda4459c8b 100644 (file)
@@ -1,5 +1,12 @@
 menu "Amlogic SoC drivers"
 
+config MESON_CANVAS
+       tristate "Amlogic Meson Canvas driver"
+       depends on ARCH_MESON || COMPILE_TEST
+       default n
+       help
+         Say yes to support the canvas IP for Amlogic SoCs.
+
 config MESON_GX_SOCINFO
        bool "Amlogic Meson GX SoC Information driver"
        depends on ARCH_MESON || COMPILE_TEST
index 8fa321893928de7329173cd6651baac2f3f1a4da..0ab16d35ac36dfc9cd8af43c29f62cc3aceac279 100644 (file)
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MESON_CANVAS) += meson-canvas.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
diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c
new file mode 100644 (file)
index 0000000..fce33ca
--- /dev/null
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * Copyright (C) 2014 Endless Mobile
+ */
+
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/soc/amlogic/meson-canvas.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define NUM_CANVAS 256
+
+/* DMC Registers */
+#define DMC_CAV_LUT_DATAL      0x00
+       #define CANVAS_WIDTH_LBIT       29
+       #define CANVAS_WIDTH_LWID       3
+#define DMC_CAV_LUT_DATAH      0x04
+       #define CANVAS_WIDTH_HBIT       0
+       #define CANVAS_HEIGHT_BIT       9
+       #define CANVAS_WRAP_BIT         22
+       #define CANVAS_BLKMODE_BIT      24
+       #define CANVAS_ENDIAN_BIT       26
+#define DMC_CAV_LUT_ADDR       0x08
+       #define CANVAS_LUT_WR_EN        BIT(9)
+       #define CANVAS_LUT_RD_EN        BIT(8)
+
+struct meson_canvas {
+       struct device *dev;
+       void __iomem *reg_base;
+       spinlock_t lock; /* canvas device lock */
+       u8 used[NUM_CANVAS];
+};
+
+static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val)
+{
+       writel_relaxed(val, canvas->reg_base + reg);
+}
+
+static u32 canvas_read(struct meson_canvas *canvas, u32 reg)
+{
+       return readl_relaxed(canvas->reg_base + reg);
+}
+
+struct meson_canvas *meson_canvas_get(struct device *dev)
+{
+       struct device_node *canvas_node;
+       struct platform_device *canvas_pdev;
+
+       canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0);
+       if (!canvas_node)
+               return ERR_PTR(-ENODEV);
+
+       canvas_pdev = of_find_device_by_node(canvas_node);
+       if (!canvas_pdev)
+               return ERR_PTR(-EPROBE_DEFER);
+
+       return dev_get_drvdata(&canvas_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(meson_canvas_get);
+
+int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index,
+                       u32 addr, u32 stride, u32 height,
+                       unsigned int wrap,
+                       unsigned int blkmode,
+                       unsigned int endian)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&canvas->lock, flags);
+       if (!canvas->used[canvas_index]) {
+               dev_err(canvas->dev,
+                       "Trying to setup non allocated canvas %u\n",
+                       canvas_index);
+               spin_unlock_irqrestore(&canvas->lock, flags);
+               return -EINVAL;
+       }
+
+       canvas_write(canvas, DMC_CAV_LUT_DATAL,
+                    ((addr + 7) >> 3) |
+                    (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));
+
+       canvas_write(canvas, DMC_CAV_LUT_DATAH,
+                    ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
+                                               CANVAS_WIDTH_HBIT) |
+                    (height << CANVAS_HEIGHT_BIT) |
+                    (wrap << CANVAS_WRAP_BIT) |
+                    (blkmode << CANVAS_BLKMODE_BIT) |
+                    (endian << CANVAS_ENDIAN_BIT));
+
+       canvas_write(canvas, DMC_CAV_LUT_ADDR,
+                    CANVAS_LUT_WR_EN | canvas_index);
+
+       /* Force a read-back to make sure everything is flushed. */
+       canvas_read(canvas, DMC_CAV_LUT_DATAH);
+       spin_unlock_irqrestore(&canvas->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_config);
+
+int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index)
+{
+       int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&canvas->lock, flags);
+       for (i = 0; i < NUM_CANVAS; ++i) {
+               if (!canvas->used[i]) {
+                       canvas->used[i] = 1;
+                       spin_unlock_irqrestore(&canvas->lock, flags);
+                       *canvas_index = i;
+                       return 0;
+               }
+       }
+       spin_unlock_irqrestore(&canvas->lock, flags);
+
+       dev_err(canvas->dev, "No more canvas available\n");
+       return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_alloc);
+
+int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&canvas->lock, flags);
+       if (!canvas->used[canvas_index]) {
+               dev_err(canvas->dev,
+                       "Trying to free unused canvas %u\n", canvas_index);
+               spin_unlock_irqrestore(&canvas->lock, flags);
+               return -EINVAL;
+       }
+       canvas->used[canvas_index] = 0;
+       spin_unlock_irqrestore(&canvas->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(meson_canvas_free);
+
+static int meson_canvas_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct meson_canvas *canvas;
+       struct device *dev = &pdev->dev;
+
+       canvas = devm_kzalloc(dev, sizeof(*canvas), GFP_KERNEL);
+       if (!canvas)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       canvas->reg_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(canvas->reg_base))
+               return PTR_ERR(canvas->reg_base);
+
+       canvas->dev = dev;
+       spin_lock_init(&canvas->lock);
+       dev_set_drvdata(dev, canvas);
+
+       return 0;
+}
+
+static const struct of_device_id canvas_dt_match[] = {
+       { .compatible = "amlogic,canvas" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, canvas_dt_match);
+
+static struct platform_driver meson_canvas_driver = {
+       .probe = meson_canvas_probe,
+       .driver = {
+               .name = "amlogic-canvas",
+               .of_match_table = canvas_dt_match,
+       },
+};
+module_platform_driver(meson_canvas_driver);
+
+MODULE_DESCRIPTION("Amlogic Canvas driver");
+MODULE_AUTHOR("Maxime Jourdan <mjourdan@baylibre.com>");
+MODULE_LICENSE("GPL");
index b60b77bfaffae1d04d5975b1d5fd288a930f7caa..e58fcc9096e82f7527d0293942b2c77d6a0e9b97 100644 (file)
@@ -50,13 +50,10 @@ static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev)
 
 static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
 {
-       struct dpio_priv *priv;
        int error;
        struct fsl_mc_device_irq *irq;
        cpumask_t mask;
 
-       priv = dev_get_drvdata(&dpio_dev->dev);
-
        irq = dpio_dev->irqs[0];
        error = devm_request_irq(&dpio_dev->dev,
                                 irq->msi_desc->irq,
index d570cb5fd381964176611eff2dc144295e469354..b0943e5417960ceb4dc0b7d51e52899c6791ff67 100644 (file)
@@ -1,6 +1,6 @@
 menuconfig FSL_DPAA
        bool "QorIQ DPAA1 framework support"
-       depends on (FSL_SOC_BOOKE || ARCH_LAYERSCAPE)
+       depends on ((FSL_SOC_BOOKE || ARCH_LAYERSCAPE) && ARCH_DMA_ADDR_T_64BIT)
        select GENERIC_ALLOCATOR
        help
          The Freescale Data Path Acceleration Architecture (DPAA) is a set of
index f9485cedc648f70380944f904f1ee15563c697f7..f84ab596bde8c3b43920a6c1c3d54620f4d6132b 100644 (file)
@@ -562,11 +562,9 @@ static int bman_create_portal(struct bman_portal *portal,
                dev_err(c->dev, "request_irq() failed\n");
                goto fail_irq;
        }
-       if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
-           irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
-               dev_err(c->dev, "irq_set_affinity() failed\n");
+
+       if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
                goto fail_affinity;
-       }
 
        /* Need RCR to be empty before continuing */
        ret = bm_rcr_get_fill(p);
index 2f71f7df3465a0a65301cb031ab183c4b0ddee7c..2c95cf59f3e7c55372cf4d57de0bb3480a61326b 100644 (file)
@@ -65,7 +65,9 @@ static int bman_offline_cpu(unsigned int cpu)
        if (!pcfg)
                return 0;
 
-       irq_set_affinity(pcfg->irq, cpumask_of(0));
+       /* use any other online CPU */
+       cpu = cpumask_any_but(cpu_online_mask, cpu);
+       irq_set_affinity(pcfg->irq, cpumask_of(cpu));
        return 0;
 }
 
@@ -91,7 +93,15 @@ 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;
+       int irq, cpu, err;
+
+       err = bman_is_probed();
+       if (!err)
+               return -EPROBE_DEFER;
+       if (err < 0) {
+               dev_err(&pdev->dev, "failing probe due to bman probe error\n");
+               return -ENODEV;
+       }
 
        pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
        if (!pcfg)
index 9f379000da85aa1dc23bbc48ed7775ce0939c14b..ae8afa552b1ef47e629de1eae4f324dc8b0af181 100644 (file)
@@ -111,4 +111,24 @@ int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
 #define QBMAN_MEMREMAP_ATTR    MEMREMAP_WC
 #endif
 
+static inline int dpaa_set_portal_irq_affinity(struct device *dev,
+                                              int irq, int cpu)
+{
+       int ret = 0;
+
+       if (!irq_can_set_affinity(irq)) {
+               dev_err(dev, "unable to set IRQ affinity\n");
+               return -EINVAL;
+       }
+
+       if (cpu == -1 || !cpu_online(cpu))
+               cpu = cpumask_any(cpu_online_mask);
+
+       ret = irq_set_affinity(irq, cpumask_of(cpu));
+       if (ret)
+               dev_err(dev, "irq_set_affinity() on CPU %d failed\n", cpu);
+
+       return ret;
+}
+
 #endif /* __DPAA_SYS_H */
index 8cc0151830433230e8f629c2660eec90871b7e8c..5ce24718c2fd1aa37ef0206a12a102025a987b7d 100644 (file)
@@ -850,12 +850,24 @@ static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
 
 static inline int qm_mc_init(struct qm_portal *portal)
 {
+       u8 rr0, rr1;
        struct qm_mc *mc = &portal->mc;
 
        mc->cr = portal->addr.ce + QM_CL_CR;
        mc->rr = portal->addr.ce + QM_CL_RR0;
-       mc->rridx = (mc->cr->_ncw_verb & QM_MCC_VERB_VBIT)
-                   ? 0 : 1;
+       /*
+        * The expected valid bit polarity for the next CR command is 0
+        * if RR1 contains a valid response, and is 1 if RR0 contains a
+        * valid response. If both RR contain all 0, this indicates either
+        * that no command has been executed since reset (in which case the
+        * expected valid bit polarity is 1)
+        */
+       rr0 = mc->rr->verb;
+       rr1 = (mc->rr+1)->verb;
+       if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
+               mc->rridx = 1;
+       else
+               mc->rridx = 0;
        mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
 #ifdef CONFIG_FSL_DPAA_CHECKING
        mc->state = qman_mc_idle;
@@ -1000,6 +1012,37 @@ static inline void put_affine_portal(void)
 
 static struct workqueue_struct *qm_portal_wq;
 
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+{
+       if (!portal)
+               return;
+
+       qm_dqrr_set_ithresh(&portal->p, ithresh);
+       portal->p.dqrr.ithresh = ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_set_ithresh);
+
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh)
+{
+       if (portal && ithresh)
+               *ithresh = portal->p.dqrr.ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_get_ithresh);
+
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod)
+{
+       if (portal && iperiod)
+               *iperiod = qm_in(&portal->p, QM_REG_ITPR);
+}
+EXPORT_SYMBOL(qman_portal_get_iperiod);
+
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+{
+       if (portal)
+               qm_out(&portal->p, QM_REG_ITPR, iperiod);
+}
+EXPORT_SYMBOL(qman_portal_set_iperiod);
+
 int qman_wq_alloc(void)
 {
        qm_portal_wq = alloc_workqueue("qman_portal_wq", 0, 1);
@@ -1210,11 +1253,9 @@ static int qman_create_portal(struct qman_portal *portal,
                dev_err(c->dev, "request_irq() failed\n");
                goto fail_irq;
        }
-       if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
-           irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
-               dev_err(c->dev, "irq_set_affinity() failed\n");
+
+       if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
                goto fail_affinity;
-       }
 
        /* Need EQCR to be empty before continuing */
        isdr &= ~QM_PIRQ_EQCI;
index 3e9391d117c543cb46f49893610e528ed52984e8..661c9b234d32bc04da676e54e5568c0a10e3a0b4 100644 (file)
@@ -195,8 +195,10 @@ static int qman_offline_cpu(unsigned int cpu)
        if (p) {
                pcfg = qman_get_qm_portal_config(p);
                if (pcfg) {
-                       irq_set_affinity(pcfg->irq, cpumask_of(0));
-                       qman_portal_update_sdest(pcfg, 0);
+                       /* select any other online CPU */
+                       cpu = cpumask_any_but(cpu_online_mask, cpu);
+                       irq_set_affinity(pcfg->irq, cpumask_of(cpu));
+                       qman_portal_update_sdest(pcfg, cpu);
                }
        }
        return 0;
index 2ef6fc6487c113f8cb33aade2fa4f3d1d30f5454..612d9c551be5de8ba27dea64f9fb30705964ed83 100644 (file)
@@ -588,11 +588,7 @@ struct qe_firmware_info *qe_get_firmware_info(void)
        }
 
        /* Find the 'firmware' child node */
-       for_each_child_of_node(qe, fw) {
-               if (strcmp(fw->name, "firmware") == 0)
-                       break;
-       }
-
+       fw = of_get_child_by_name(qe, "firmware");
        of_node_put(qe);
 
        /* Did we find the 'firmware' node? */
index b3da635970ea70f56d98a4db94d234178cfa9a82..aa3729ecaa9ef86291ab685e2a5beafa6371e972 100644 (file)
@@ -1,13 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
  * Copyright 2011-2013 Freescale Semiconductor, Inc.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/clk.h>
@@ -69,7 +63,7 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
        u32 val;
 
        /* Read ISO and ISO2SW power down delays */
-       regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val);
+       regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PDNSCR_OFFS, &val);
        iso = val & 0x3f;
        iso2sw = (val >> 8) & 0x3f;
 
@@ -247,6 +241,7 @@ builtin_platform_driver(imx_pgc_power_domain_driver)
 #define GPC_PGC_DOMAIN_ARM     0
 #define GPC_PGC_DOMAIN_PU      1
 #define GPC_PGC_DOMAIN_DISPLAY 2
+#define GPC_PGC_DOMAIN_PCI     3
 
 static struct genpd_power_state imx6_pm_domain_pu_state = {
        .power_off_latency_ns = 25000,
@@ -254,12 +249,13 @@ static struct genpd_power_state imx6_pm_domain_pu_state = {
 };
 
 static struct imx_pm_domain imx_gpc_domains[] = {
-       {
+       [GPC_PGC_DOMAIN_ARM] {
                .base = {
                        .name = "ARM",
                        .flags = GENPD_FLAG_ALWAYS_ON,
                },
-       }, {
+       },
+       [GPC_PGC_DOMAIN_PU] {
                .base = {
                        .name = "PU",
                        .power_off = imx6_pm_domain_power_off,
@@ -269,7 +265,8 @@ static struct imx_pm_domain imx_gpc_domains[] = {
                },
                .reg_offs = 0x260,
                .cntr_pdn_bit = 0,
-       }, {
+       },
+       [GPC_PGC_DOMAIN_DISPLAY] {
                .base = {
                        .name = "DISPLAY",
                        .power_off = imx6_pm_domain_power_off,
@@ -277,7 +274,8 @@ static struct imx_pm_domain imx_gpc_domains[] = {
                },
                .reg_offs = 0x240,
                .cntr_pdn_bit = 4,
-       }, {
+       },
+       [GPC_PGC_DOMAIN_PCI] {
                .base = {
                        .name = "PCI",
                        .power_off = imx6_pm_domain_power_off,
@@ -348,8 +346,8 @@ static const struct regmap_config imx_gpc_regmap_config = {
 };
 
 static struct generic_pm_domain *imx_gpc_onecell_domains[] = {
-       &imx_gpc_domains[0].base,
-       &imx_gpc_domains[1].base,
+       &imx_gpc_domains[GPC_PGC_DOMAIN_ARM].base,
+       &imx_gpc_domains[GPC_PGC_DOMAIN_PU].base,
 };
 
 static struct genpd_onecell_data imx_gpc_onecell_data = {
index 6ef18cf8f24387e324cf455ae98c30f2b27c95d3..e7b5994fee9d0b4d1f1908509b5b49ecfea453a7 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2017 Impinj, Inc
  * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
@@ -5,29 +6,23 @@
  * Based on the code of analogus driver:
  *
  * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <dt-bindings/power/imx7-power.h>
 
-#define GPC_LPCR_A7_BSC                        0x000
+#define GPC_LPCR_A_CORE_BSC                    0x000
 
 #define GPC_PGC_CPU_MAPPING            0x0ec
-#define USB_HSIC_PHY_A7_DOMAIN         BIT(6)
-#define USB_OTG2_PHY_A7_DOMAIN         BIT(5)
-#define USB_OTG1_PHY_A7_DOMAIN         BIT(4)
-#define PCIE_PHY_A7_DOMAIN             BIT(3)
-#define MIPI_PHY_A7_DOMAIN             BIT(2)
+#define USB_HSIC_PHY_A_CORE_DOMAIN             BIT(6)
+#define USB_OTG2_PHY_A_CORE_DOMAIN             BIT(5)
+#define USB_OTG1_PHY_A_CORE_DOMAIN             BIT(4)
+#define PCIE_PHY_A_CORE_DOMAIN         BIT(3)
+#define MIPI_PHY_A_CORE_DOMAIN         BIT(2)
 
 #define GPC_PU_PGC_SW_PUP_REQ          0x0f8
 #define GPC_PU_PGC_SW_PDN_REQ          0x104
@@ -53,7 +48,7 @@
 
 #define GPC_PGC_CTRL_PCR               BIT(0)
 
-struct imx7_pgc_domain {
+struct imx_pgc_domain {
        struct generic_pm_domain genpd;
        struct regmap *regmap;
        struct regulator *regulator;
@@ -69,11 +64,16 @@ struct imx7_pgc_domain {
        struct device *dev;
 };
 
-static int imx7_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
+struct imx_pgc_domain_data {
+       const struct imx_pgc_domain *domains;
+       size_t domains_num;
+};
+
+static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
                                      bool on)
 {
-       struct imx7_pgc_domain *domain = container_of(genpd,
-                                                     struct imx7_pgc_domain,
+       struct imx_pgc_domain *domain = container_of(genpd,
+                                                     struct imx_pgc_domain,
                                                      genpd);
        unsigned int offset = on ?
                GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ;
@@ -150,24 +150,24 @@ unmap:
        return ret;
 }
 
-static int imx7_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
+static int imx_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
 {
-       return imx7_gpc_pu_pgc_sw_pxx_req(genpd, true);
+       return imx_gpc_pu_pgc_sw_pxx_req(genpd, true);
 }
 
-static int imx7_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
+static int imx_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
 {
-       return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false);
+       return imx_gpc_pu_pgc_sw_pxx_req(genpd, false);
 }
 
-static const struct imx7_pgc_domain imx7_pgc_domains[] = {
+static const struct imx_pgc_domain imx7_pgc_domains[] = {
        [IMX7_POWER_DOMAIN_MIPI_PHY] = {
                .genpd = {
                        .name      = "mipi-phy",
                },
                .bits  = {
                        .pxx = MIPI_PHY_SW_Pxx_REQ,
-                       .map = MIPI_PHY_A7_DOMAIN,
+                       .map = MIPI_PHY_A_CORE_DOMAIN,
                },
                .voltage   = 1000000,
                .pgc       = PGC_MIPI,
@@ -179,7 +179,7 @@ static const struct imx7_pgc_domain imx7_pgc_domains[] = {
                },
                .bits  = {
                        .pxx = PCIE_PHY_SW_Pxx_REQ,
-                       .map = PCIE_PHY_A7_DOMAIN,
+                       .map = PCIE_PHY_A_CORE_DOMAIN,
                },
                .voltage   = 1000000,
                .pgc       = PGC_PCIE,
@@ -191,16 +191,21 @@ static const struct imx7_pgc_domain imx7_pgc_domains[] = {
                },
                .bits  = {
                        .pxx = USB_HSIC_PHY_SW_Pxx_REQ,
-                       .map = USB_HSIC_PHY_A7_DOMAIN,
+                       .map = USB_HSIC_PHY_A_CORE_DOMAIN,
                },
                .voltage   = 1200000,
                .pgc       = PGC_USB_HSIC,
        },
 };
 
-static int imx7_pgc_domain_probe(struct platform_device *pdev)
+static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
+       .domains = imx7_pgc_domains,
+       .domains_num = ARRAY_SIZE(imx7_pgc_domains),
+};
+
+static int imx_pgc_domain_probe(struct platform_device *pdev)
 {
-       struct imx7_pgc_domain *domain = pdev->dev.platform_data;
+       struct imx_pgc_domain *domain = pdev->dev.platform_data;
        int ret;
 
        domain->dev = &pdev->dev;
@@ -233,9 +238,9 @@ static int imx7_pgc_domain_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int imx7_pgc_domain_remove(struct platform_device *pdev)
+static int imx_pgc_domain_remove(struct platform_device *pdev)
 {
-       struct imx7_pgc_domain *domain = pdev->dev.platform_data;
+       struct imx_pgc_domain *domain = pdev->dev.platform_data;
 
        of_genpd_del_provider(domain->dev->of_node);
        pm_genpd_remove(&domain->genpd);
@@ -243,25 +248,26 @@ static int imx7_pgc_domain_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct platform_device_id imx7_pgc_domain_id[] = {
-       { "imx7-pgc-domain", },
+static const struct platform_device_id imx_pgc_domain_id[] = {
+       { "imx-pgc-domain", },
        { },
 };
 
-static struct platform_driver imx7_pgc_domain_driver = {
+static struct platform_driver imx_pgc_domain_driver = {
        .driver = {
-               .name = "imx7-pgc",
+               .name = "imx-pgc",
        },
-       .probe    = imx7_pgc_domain_probe,
-       .remove   = imx7_pgc_domain_remove,
-       .id_table = imx7_pgc_domain_id,
+       .probe    = imx_pgc_domain_probe,
+       .remove   = imx_pgc_domain_remove,
+       .id_table = imx_pgc_domain_id,
 };
-builtin_platform_driver(imx7_pgc_domain_driver)
+builtin_platform_driver(imx_pgc_domain_driver)
 
 static int imx_gpcv2_probe(struct platform_device *pdev)
 {
+       static const struct imx_pgc_domain_data *domain_data;
        static const struct regmap_range yes_ranges[] = {
-               regmap_reg_range(GPC_LPCR_A7_BSC,
+               regmap_reg_range(GPC_LPCR_A_CORE_BSC,
                                 GPC_M4_PU_PDN_FLG),
                regmap_reg_range(GPC_PGC_CTRL(PGC_MIPI),
                                 GPC_PGC_SR(PGC_MIPI)),
@@ -307,9 +313,11 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
                return ret;
        }
 
+       domain_data = of_device_get_match_data(&pdev->dev);
+
        for_each_child_of_node(pgc_np, np) {
                struct platform_device *pd_pdev;
-               struct imx7_pgc_domain *domain;
+               struct imx_pgc_domain *domain;
                u32 domain_index;
 
                ret = of_property_read_u32(np, "reg", &domain_index);
@@ -319,14 +327,14 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
                        return ret;
                }
 
-               if (domain_index >= ARRAY_SIZE(imx7_pgc_domains)) {
+               if (domain_index >= domain_data->domains_num) {
                        dev_warn(dev,
                                 "Domain index %d is out of bounds\n",
                                 domain_index);
                        continue;
                }
 
-               pd_pdev = platform_device_alloc("imx7-pgc-domain",
+               pd_pdev = platform_device_alloc("imx-pgc-domain",
                                                domain_index);
                if (!pd_pdev) {
                        dev_err(dev, "Failed to allocate platform device\n");
@@ -335,8 +343,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
                }
 
                ret = platform_device_add_data(pd_pdev,
-                                              &imx7_pgc_domains[domain_index],
-                                              sizeof(imx7_pgc_domains[domain_index]));
+                                              &domain_data->domains[domain_index],
+                                              sizeof(domain_data->domains[domain_index]));
                if (ret) {
                        platform_device_put(pd_pdev);
                        of_node_put(np);
@@ -345,8 +353,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
 
                domain = pd_pdev->dev.platform_data;
                domain->regmap = regmap;
-               domain->genpd.power_on  = imx7_gpc_pu_pgc_sw_pup_req;
-               domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req;
+               domain->genpd.power_on  = imx_gpc_pu_pgc_sw_pup_req;
+               domain->genpd.power_off = imx_gpc_pu_pgc_sw_pdn_req;
 
                pd_pdev->dev.parent = dev;
                pd_pdev->dev.of_node = np;
@@ -363,7 +371,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id imx_gpcv2_dt_ids[] = {
-       { .compatible = "fsl,imx7d-gpc" },
+       { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
        { }
 };
 
index 4e931fdf4d0918aa59368390ed7d8dc8c194b26c..8236a6c87e19f0bcd3f066b409307a844c2f1e61 100644 (file)
 #define PWRAP_SLV_CAP_SECURITY BIT(2)
 #define HAS_CAP(_c, _x)        (((_c) & (_x)) == (_x))
 
+/* Group of bits used for shown pwrap capability */
+#define PWRAP_CAP_BRIDGE       BIT(0)
+#define PWRAP_CAP_RESET                BIT(1)
+#define PWRAP_CAP_DCM          BIT(2)
+#define PWRAP_CAP_INT1_EN      BIT(3)
+#define PWRAP_CAP_WDT_SRC1     BIT(4)
+
 /* defines for slave device wrapper registers */
 enum dew_regs {
        PWRAP_DEW_BASE,
@@ -91,6 +98,27 @@ enum dew_regs {
        PWRAP_DEW_CIPHER_MODE,
        PWRAP_DEW_CIPHER_SWRST,
 
+       /* MT6323 only regs */
+       PWRAP_DEW_CIPHER_EN,
+       PWRAP_DEW_RDDMY_NO,
+
+       /* MT6358 only regs */
+       PWRAP_SMT_CON1,
+       PWRAP_DRV_CON1,
+       PWRAP_FILTER_CON0,
+       PWRAP_GPIO_PULLEN0_CLR,
+       PWRAP_RG_SPI_CON0,
+       PWRAP_RG_SPI_RECORD0,
+       PWRAP_RG_SPI_CON2,
+       PWRAP_RG_SPI_CON3,
+       PWRAP_RG_SPI_CON4,
+       PWRAP_RG_SPI_CON5,
+       PWRAP_RG_SPI_CON6,
+       PWRAP_RG_SPI_CON7,
+       PWRAP_RG_SPI_CON8,
+       PWRAP_RG_SPI_CON13,
+       PWRAP_SPISLV_KEY,
+
        /* MT6397 only regs */
        PWRAP_DEW_EVENT_OUT_EN,
        PWRAP_DEW_EVENT_SRC_EN,
@@ -100,10 +128,6 @@ enum dew_regs {
        PWRAP_DEW_EVENT_TEST,
        PWRAP_DEW_CIPHER_LOAD,
        PWRAP_DEW_CIPHER_START,
-
-       /* MT6323 only regs */
-       PWRAP_DEW_CIPHER_EN,
-       PWRAP_DEW_RDDMY_NO,
 };
 
 static const u32 mt6323_regs[] = {
@@ -123,6 +147,64 @@ static const u32 mt6323_regs[] = {
        [PWRAP_DEW_RDDMY_NO] =          0x01a4,
 };
 
+static const u32 mt6351_regs[] = {
+       [PWRAP_DEW_DIO_EN] =            0x02F2,
+       [PWRAP_DEW_READ_TEST] =         0x02F4,
+       [PWRAP_DEW_WRITE_TEST] =        0x02F6,
+       [PWRAP_DEW_CRC_EN] =            0x02FA,
+       [PWRAP_DEW_CRC_VAL] =           0x02FC,
+       [PWRAP_DEW_CIPHER_KEY_SEL] =    0x0300,
+       [PWRAP_DEW_CIPHER_IV_SEL] =     0x0302,
+       [PWRAP_DEW_CIPHER_EN] =         0x0304,
+       [PWRAP_DEW_CIPHER_RDY] =        0x0306,
+       [PWRAP_DEW_CIPHER_MODE] =       0x0308,
+       [PWRAP_DEW_CIPHER_SWRST] =      0x030A,
+       [PWRAP_DEW_RDDMY_NO] =          0x030C,
+};
+
+static const u32 mt6357_regs[] = {
+       [PWRAP_DEW_DIO_EN] =            0x040A,
+       [PWRAP_DEW_READ_TEST] =         0x040C,
+       [PWRAP_DEW_WRITE_TEST] =        0x040E,
+       [PWRAP_DEW_CRC_EN] =            0x0412,
+       [PWRAP_DEW_CRC_VAL] =           0x0414,
+       [PWRAP_DEW_CIPHER_KEY_SEL] =    0x0418,
+       [PWRAP_DEW_CIPHER_IV_SEL] =     0x041A,
+       [PWRAP_DEW_CIPHER_EN] =         0x041C,
+       [PWRAP_DEW_CIPHER_RDY] =        0x041E,
+       [PWRAP_DEW_CIPHER_MODE] =       0x0420,
+       [PWRAP_DEW_CIPHER_SWRST] =      0x0422,
+       [PWRAP_DEW_RDDMY_NO] =          0x0424,
+};
+
+static const u32 mt6358_regs[] = {
+       [PWRAP_SMT_CON1] =              0x0030,
+       [PWRAP_DRV_CON1] =              0x0038,
+       [PWRAP_FILTER_CON0] =           0x0040,
+       [PWRAP_GPIO_PULLEN0_CLR] =      0x0098,
+       [PWRAP_RG_SPI_CON0] =           0x0408,
+       [PWRAP_RG_SPI_RECORD0] =        0x040a,
+       [PWRAP_DEW_DIO_EN] =            0x040c,
+       [PWRAP_DEW_READ_TEST]   =       0x040e,
+       [PWRAP_DEW_WRITE_TEST]  =       0x0410,
+       [PWRAP_DEW_CRC_EN] =            0x0414,
+       [PWRAP_DEW_CIPHER_KEY_SEL] =    0x041a,
+       [PWRAP_DEW_CIPHER_IV_SEL] =     0x041c,
+       [PWRAP_DEW_CIPHER_EN]   =       0x041e,
+       [PWRAP_DEW_CIPHER_RDY] =        0x0420,
+       [PWRAP_DEW_CIPHER_MODE] =       0x0422,
+       [PWRAP_DEW_CIPHER_SWRST] =      0x0424,
+       [PWRAP_RG_SPI_CON2] =           0x0432,
+       [PWRAP_RG_SPI_CON3] =           0x0434,
+       [PWRAP_RG_SPI_CON4] =           0x0436,
+       [PWRAP_RG_SPI_CON5] =           0x0438,
+       [PWRAP_RG_SPI_CON6] =           0x043a,
+       [PWRAP_RG_SPI_CON7] =           0x043c,
+       [PWRAP_RG_SPI_CON8] =           0x043e,
+       [PWRAP_RG_SPI_CON13] =          0x0448,
+       [PWRAP_SPISLV_KEY] =            0x044a,
+};
+
 static const u32 mt6397_regs[] = {
        [PWRAP_DEW_BASE] =              0xbc00,
        [PWRAP_DEW_EVENT_OUT_EN] =      0xbc00,
@@ -146,21 +228,6 @@ static const u32 mt6397_regs[] = {
        [PWRAP_DEW_CIPHER_SWRST] =      0xbc24,
 };
 
-static const u32 mt6351_regs[] = {
-       [PWRAP_DEW_DIO_EN] =            0x02F2,
-       [PWRAP_DEW_READ_TEST] =         0x02F4,
-       [PWRAP_DEW_WRITE_TEST] =        0x02F6,
-       [PWRAP_DEW_CRC_EN] =            0x02FA,
-       [PWRAP_DEW_CRC_VAL] =           0x02FC,
-       [PWRAP_DEW_CIPHER_KEY_SEL] =    0x0300,
-       [PWRAP_DEW_CIPHER_IV_SEL] =     0x0302,
-       [PWRAP_DEW_CIPHER_EN] =         0x0304,
-       [PWRAP_DEW_CIPHER_RDY] =        0x0306,
-       [PWRAP_DEW_CIPHER_MODE] =       0x0308,
-       [PWRAP_DEW_CIPHER_SWRST] =      0x030A,
-       [PWRAP_DEW_RDDMY_NO] =          0x030C,
-};
-
 enum pwrap_regs {
        PWRAP_MUX_SEL,
        PWRAP_WRAP_EN,
@@ -221,6 +288,8 @@ enum pwrap_regs {
        PWRAP_CIPHER_SWRST,
        PWRAP_DCM_EN,
        PWRAP_DCM_DBC_PRD,
+       PWRAP_EINT_STA0_ADR,
+       PWRAP_EINT_STA1_ADR,
 
        /* MT2701 only regs */
        PWRAP_ADC_CMD_ADDR,
@@ -230,8 +299,6 @@ enum pwrap_regs {
        PWRAP_ADC_RDATA_ADDR2,
 
        /* MT7622 only regs */
-       PWRAP_EINT_STA0_ADR,
-       PWRAP_EINT_STA1_ADR,
        PWRAP_STA,
        PWRAP_CLR,
        PWRAP_DVFS_ADR8,
@@ -293,6 +360,27 @@ enum pwrap_regs {
        PWRAP_DVFS_WDATA7,
        PWRAP_SPMINF_STA,
        PWRAP_CIPHER_EN,
+
+       /* MT8183 only regs */
+       PWRAP_SI_SAMPLE_CTRL,
+       PWRAP_CSLEXT_WRITE,
+       PWRAP_CSLEXT_READ,
+       PWRAP_EXT_CK_WRITE,
+       PWRAP_STAUPD_CTRL,
+       PWRAP_WACS_P2P_EN,
+       PWRAP_INIT_DONE_P2P,
+       PWRAP_WACS_MD32_EN,
+       PWRAP_INIT_DONE_MD32,
+       PWRAP_INT1_EN,
+       PWRAP_INT1_FLG,
+       PWRAP_INT1_CLR,
+       PWRAP_WDT_SRC_EN_1,
+       PWRAP_INT_GPS_AUXADC_CMD_ADDR,
+       PWRAP_INT_GPS_AUXADC_CMD,
+       PWRAP_INT_GPS_AUXADC_RDATA_ADDR,
+       PWRAP_EXT_GPS_AUXADC_RDATA_ADDR,
+       PWRAP_GPSINF_0_STA,
+       PWRAP_GPSINF_1_STA,
 };
 
 static int mt2701_regs[] = {
@@ -381,6 +469,38 @@ static int mt2701_regs[] = {
        [PWRAP_ADC_RDATA_ADDR2] =       0x154,
 };
 
+static int mt6765_regs[] = {
+       [PWRAP_MUX_SEL] =               0x0,
+       [PWRAP_WRAP_EN] =               0x4,
+       [PWRAP_DIO_EN] =                0x8,
+       [PWRAP_RDDMY] =                 0x20,
+       [PWRAP_CSHEXT_WRITE] =          0x24,
+       [PWRAP_CSHEXT_READ] =           0x28,
+       [PWRAP_CSLEXT_START] =          0x2C,
+       [PWRAP_CSLEXT_END] =            0x30,
+       [PWRAP_STAUPD_PRD] =            0x3C,
+       [PWRAP_HARB_HPRIO] =            0x68,
+       [PWRAP_HIPRIO_ARB_EN] =         0x6C,
+       [PWRAP_MAN_EN] =                0x7C,
+       [PWRAP_MAN_CMD] =               0x80,
+       [PWRAP_WACS0_EN] =              0x8C,
+       [PWRAP_WACS1_EN] =              0x94,
+       [PWRAP_WACS2_EN] =              0x9C,
+       [PWRAP_INIT_DONE2] =            0xA0,
+       [PWRAP_WACS2_CMD] =             0xC20,
+       [PWRAP_WACS2_RDATA] =           0xC24,
+       [PWRAP_WACS2_VLDCLR] =          0xC28,
+       [PWRAP_INT_EN] =                0xB4,
+       [PWRAP_INT_FLG_RAW] =           0xB8,
+       [PWRAP_INT_FLG] =               0xBC,
+       [PWRAP_INT_CLR] =               0xC0,
+       [PWRAP_TIMER_EN] =              0xE8,
+       [PWRAP_WDT_UNIT] =              0xF0,
+       [PWRAP_WDT_SRC_EN] =            0xF4,
+       [PWRAP_DCM_EN] =                0x1DC,
+       [PWRAP_DCM_DBC_PRD] =           0x1E0,
+};
+
 static int mt6797_regs[] = {
        [PWRAP_MUX_SEL] =               0x0,
        [PWRAP_WRAP_EN] =               0x4,
@@ -526,6 +646,79 @@ static int mt7622_regs[] = {
        [PWRAP_SPI2_CTRL] =             0x244,
 };
 
+static int mt8135_regs[] = {
+       [PWRAP_MUX_SEL] =               0x0,
+       [PWRAP_WRAP_EN] =               0x4,
+       [PWRAP_DIO_EN] =                0x8,
+       [PWRAP_SIDLY] =                 0xc,
+       [PWRAP_CSHEXT] =                0x10,
+       [PWRAP_CSHEXT_WRITE] =          0x14,
+       [PWRAP_CSHEXT_READ] =           0x18,
+       [PWRAP_CSLEXT_START] =          0x1c,
+       [PWRAP_CSLEXT_END] =            0x20,
+       [PWRAP_STAUPD_PRD] =            0x24,
+       [PWRAP_STAUPD_GRPEN] =          0x28,
+       [PWRAP_STAUPD_MAN_TRIG] =       0x2c,
+       [PWRAP_STAUPD_STA] =            0x30,
+       [PWRAP_EVENT_IN_EN] =           0x34,
+       [PWRAP_EVENT_DST_EN] =          0x38,
+       [PWRAP_WRAP_STA] =              0x3c,
+       [PWRAP_RRARB_INIT] =            0x40,
+       [PWRAP_RRARB_EN] =              0x44,
+       [PWRAP_RRARB_STA0] =            0x48,
+       [PWRAP_RRARB_STA1] =            0x4c,
+       [PWRAP_HARB_INIT] =             0x50,
+       [PWRAP_HARB_HPRIO] =            0x54,
+       [PWRAP_HIPRIO_ARB_EN] =         0x58,
+       [PWRAP_HARB_STA0] =             0x5c,
+       [PWRAP_HARB_STA1] =             0x60,
+       [PWRAP_MAN_EN] =                0x64,
+       [PWRAP_MAN_CMD] =               0x68,
+       [PWRAP_MAN_RDATA] =             0x6c,
+       [PWRAP_MAN_VLDCLR] =            0x70,
+       [PWRAP_WACS0_EN] =              0x74,
+       [PWRAP_INIT_DONE0] =            0x78,
+       [PWRAP_WACS0_CMD] =             0x7c,
+       [PWRAP_WACS0_RDATA] =           0x80,
+       [PWRAP_WACS0_VLDCLR] =          0x84,
+       [PWRAP_WACS1_EN] =              0x88,
+       [PWRAP_INIT_DONE1] =            0x8c,
+       [PWRAP_WACS1_CMD] =             0x90,
+       [PWRAP_WACS1_RDATA] =           0x94,
+       [PWRAP_WACS1_VLDCLR] =          0x98,
+       [PWRAP_WACS2_EN] =              0x9c,
+       [PWRAP_INIT_DONE2] =            0xa0,
+       [PWRAP_WACS2_CMD] =             0xa4,
+       [PWRAP_WACS2_RDATA] =           0xa8,
+       [PWRAP_WACS2_VLDCLR] =          0xac,
+       [PWRAP_INT_EN] =                0xb0,
+       [PWRAP_INT_FLG_RAW] =           0xb4,
+       [PWRAP_INT_FLG] =               0xb8,
+       [PWRAP_INT_CLR] =               0xbc,
+       [PWRAP_SIG_ADR] =               0xc0,
+       [PWRAP_SIG_MODE] =              0xc4,
+       [PWRAP_SIG_VALUE] =             0xc8,
+       [PWRAP_SIG_ERRVAL] =            0xcc,
+       [PWRAP_CRC_EN] =                0xd0,
+       [PWRAP_EVENT_STA] =             0xd4,
+       [PWRAP_EVENT_STACLR] =          0xd8,
+       [PWRAP_TIMER_EN] =              0xdc,
+       [PWRAP_TIMER_STA] =             0xe0,
+       [PWRAP_WDT_UNIT] =              0xe4,
+       [PWRAP_WDT_SRC_EN] =            0xe8,
+       [PWRAP_WDT_FLG] =               0xec,
+       [PWRAP_DEBUG_INT_SEL] =         0xf0,
+       [PWRAP_CIPHER_KEY_SEL] =        0x134,
+       [PWRAP_CIPHER_IV_SEL] =         0x138,
+       [PWRAP_CIPHER_LOAD] =           0x13c,
+       [PWRAP_CIPHER_START] =          0x140,
+       [PWRAP_CIPHER_RDY] =            0x144,
+       [PWRAP_CIPHER_MODE] =           0x148,
+       [PWRAP_CIPHER_SWRST] =          0x14c,
+       [PWRAP_DCM_EN] =                0x15c,
+       [PWRAP_DCM_DBC_PRD] =           0x160,
+};
+
 static int mt8173_regs[] = {
        [PWRAP_MUX_SEL] =               0x0,
        [PWRAP_WRAP_EN] =               0x4,
@@ -608,92 +801,74 @@ static int mt8173_regs[] = {
        [PWRAP_DCM_DBC_PRD] =           0x148,
 };
 
-static int mt8135_regs[] = {
-       [PWRAP_MUX_SEL] =               0x0,
-       [PWRAP_WRAP_EN] =               0x4,
-       [PWRAP_DIO_EN] =                0x8,
-       [PWRAP_SIDLY] =                 0xc,
-       [PWRAP_CSHEXT] =                0x10,
-       [PWRAP_CSHEXT_WRITE] =          0x14,
-       [PWRAP_CSHEXT_READ] =           0x18,
-       [PWRAP_CSLEXT_START] =          0x1c,
-       [PWRAP_CSLEXT_END] =            0x20,
-       [PWRAP_STAUPD_PRD] =            0x24,
-       [PWRAP_STAUPD_GRPEN] =          0x28,
-       [PWRAP_STAUPD_MAN_TRIG] =       0x2c,
-       [PWRAP_STAUPD_STA] =            0x30,
-       [PWRAP_EVENT_IN_EN] =           0x34,
-       [PWRAP_EVENT_DST_EN] =          0x38,
-       [PWRAP_WRAP_STA] =              0x3c,
-       [PWRAP_RRARB_INIT] =            0x40,
-       [PWRAP_RRARB_EN] =              0x44,
-       [PWRAP_RRARB_STA0] =            0x48,
-       [PWRAP_RRARB_STA1] =            0x4c,
-       [PWRAP_HARB_INIT] =             0x50,
-       [PWRAP_HARB_HPRIO] =            0x54,
-       [PWRAP_HIPRIO_ARB_EN] =         0x58,
-       [PWRAP_HARB_STA0] =             0x5c,
-       [PWRAP_HARB_STA1] =             0x60,
-       [PWRAP_MAN_EN] =                0x64,
-       [PWRAP_MAN_CMD] =               0x68,
-       [PWRAP_MAN_RDATA] =             0x6c,
-       [PWRAP_MAN_VLDCLR] =            0x70,
-       [PWRAP_WACS0_EN] =              0x74,
-       [PWRAP_INIT_DONE0] =            0x78,
-       [PWRAP_WACS0_CMD] =             0x7c,
-       [PWRAP_WACS0_RDATA] =           0x80,
-       [PWRAP_WACS0_VLDCLR] =          0x84,
-       [PWRAP_WACS1_EN] =              0x88,
-       [PWRAP_INIT_DONE1] =            0x8c,
-       [PWRAP_WACS1_CMD] =             0x90,
-       [PWRAP_WACS1_RDATA] =           0x94,
-       [PWRAP_WACS1_VLDCLR] =          0x98,
-       [PWRAP_WACS2_EN] =              0x9c,
-       [PWRAP_INIT_DONE2] =            0xa0,
-       [PWRAP_WACS2_CMD] =             0xa4,
-       [PWRAP_WACS2_RDATA] =           0xa8,
-       [PWRAP_WACS2_VLDCLR] =          0xac,
-       [PWRAP_INT_EN] =                0xb0,
-       [PWRAP_INT_FLG_RAW] =           0xb4,
-       [PWRAP_INT_FLG] =               0xb8,
-       [PWRAP_INT_CLR] =               0xbc,
-       [PWRAP_SIG_ADR] =               0xc0,
-       [PWRAP_SIG_MODE] =              0xc4,
-       [PWRAP_SIG_VALUE] =             0xc8,
-       [PWRAP_SIG_ERRVAL] =            0xcc,
-       [PWRAP_CRC_EN] =                0xd0,
-       [PWRAP_EVENT_STA] =             0xd4,
-       [PWRAP_EVENT_STACLR] =          0xd8,
-       [PWRAP_TIMER_EN] =              0xdc,
-       [PWRAP_TIMER_STA] =             0xe0,
-       [PWRAP_WDT_UNIT] =              0xe4,
-       [PWRAP_WDT_SRC_EN] =            0xe8,
-       [PWRAP_WDT_FLG] =               0xec,
-       [PWRAP_DEBUG_INT_SEL] =         0xf0,
-       [PWRAP_CIPHER_KEY_SEL] =        0x134,
-       [PWRAP_CIPHER_IV_SEL] =         0x138,
-       [PWRAP_CIPHER_LOAD] =           0x13c,
-       [PWRAP_CIPHER_START] =          0x140,
-       [PWRAP_CIPHER_RDY] =            0x144,
-       [PWRAP_CIPHER_MODE] =           0x148,
-       [PWRAP_CIPHER_SWRST] =          0x14c,
-       [PWRAP_DCM_EN] =                0x15c,
-       [PWRAP_DCM_DBC_PRD] =           0x160,
+static int mt8183_regs[] = {
+       [PWRAP_MUX_SEL] =                       0x0,
+       [PWRAP_WRAP_EN] =                       0x4,
+       [PWRAP_DIO_EN] =                        0x8,
+       [PWRAP_SI_SAMPLE_CTRL] =                0xC,
+       [PWRAP_RDDMY] =                         0x14,
+       [PWRAP_CSHEXT_WRITE] =                  0x18,
+       [PWRAP_CSHEXT_READ] =                   0x1C,
+       [PWRAP_CSLEXT_WRITE] =                  0x20,
+       [PWRAP_CSLEXT_READ] =                   0x24,
+       [PWRAP_EXT_CK_WRITE] =                  0x28,
+       [PWRAP_STAUPD_CTRL] =                   0x30,
+       [PWRAP_STAUPD_GRPEN] =                  0x34,
+       [PWRAP_EINT_STA0_ADR] =                 0x38,
+       [PWRAP_HARB_HPRIO] =                    0x5C,
+       [PWRAP_HIPRIO_ARB_EN] =                 0x60,
+       [PWRAP_MAN_EN] =                        0x70,
+       [PWRAP_MAN_CMD] =                       0x74,
+       [PWRAP_WACS0_EN] =                      0x80,
+       [PWRAP_INIT_DONE0] =                    0x84,
+       [PWRAP_WACS1_EN] =                      0x88,
+       [PWRAP_INIT_DONE1] =                    0x8C,
+       [PWRAP_WACS2_EN] =                      0x90,
+       [PWRAP_INIT_DONE2] =                    0x94,
+       [PWRAP_WACS_P2P_EN] =                   0xA0,
+       [PWRAP_INIT_DONE_P2P] =                 0xA4,
+       [PWRAP_WACS_MD32_EN] =                  0xA8,
+       [PWRAP_INIT_DONE_MD32] =                0xAC,
+       [PWRAP_INT_EN] =                        0xB0,
+       [PWRAP_INT_FLG] =                       0xB8,
+       [PWRAP_INT_CLR] =                       0xBC,
+       [PWRAP_INT1_EN] =                       0xC0,
+       [PWRAP_INT1_FLG] =                      0xC8,
+       [PWRAP_INT1_CLR] =                      0xCC,
+       [PWRAP_SIG_ADR] =                       0xD0,
+       [PWRAP_CRC_EN] =                        0xE0,
+       [PWRAP_TIMER_EN] =                      0xE4,
+       [PWRAP_WDT_UNIT] =                      0xEC,
+       [PWRAP_WDT_SRC_EN] =                    0xF0,
+       [PWRAP_WDT_SRC_EN_1] =                  0xF4,
+       [PWRAP_INT_GPS_AUXADC_CMD_ADDR] =       0x1DC,
+       [PWRAP_INT_GPS_AUXADC_CMD] =            0x1E0,
+       [PWRAP_INT_GPS_AUXADC_RDATA_ADDR] =     0x1E4,
+       [PWRAP_EXT_GPS_AUXADC_RDATA_ADDR] =     0x1E8,
+       [PWRAP_GPSINF_0_STA] =                  0x1EC,
+       [PWRAP_GPSINF_1_STA] =                  0x1F0,
+       [PWRAP_WACS2_CMD] =                     0xC20,
+       [PWRAP_WACS2_RDATA] =                   0xC24,
+       [PWRAP_WACS2_VLDCLR] =                  0xC28,
 };
 
 enum pmic_type {
        PMIC_MT6323,
        PMIC_MT6351,
+       PMIC_MT6357,
+       PMIC_MT6358,
        PMIC_MT6380,
        PMIC_MT6397,
 };
 
 enum pwrap_type {
        PWRAP_MT2701,
+       PWRAP_MT6765,
        PWRAP_MT6797,
        PWRAP_MT7622,
        PWRAP_MT8135,
        PWRAP_MT8173,
+       PWRAP_MT8183,
 };
 
 struct pmic_wrapper;
@@ -731,9 +906,11 @@ struct pmic_wrapper_type {
        enum pwrap_type type;
        u32 arb_en_all;
        u32 int_en_all;
+       u32 int1_en_all;
        u32 spi_w;
        u32 wdt_src;
-       unsigned int has_bridge:1;
+       /* Flags indicating the capability for the target pwrap */
+       u32 caps;
        int (*init_reg_clock)(struct pmic_wrapper *wrp);
        int (*init_soc_specific)(struct pmic_wrapper *wrp);
 };
@@ -1096,7 +1273,7 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
        ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY],
                         &rdata);
        if (ret)
-               return 0;
+               return false;
 
        return rdata == 1;
 }
@@ -1117,6 +1294,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
                pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
                break;
        case PWRAP_MT2701:
+       case PWRAP_MT6765:
        case PWRAP_MT6797:
        case PWRAP_MT8173:
                pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
@@ -1124,6 +1302,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
        case PWRAP_MT7622:
                pwrap_writel(wrp, 0, PWRAP_CIPHER_EN);
                break;
+       case PWRAP_MT8183:
+               break;
        }
 
        /* Config cipher mode @PMIC */
@@ -1141,6 +1321,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
                break;
        case PMIC_MT6323:
        case PMIC_MT6351:
+       case PMIC_MT6357:
                pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
                            0x1);
                break;
@@ -1276,6 +1457,23 @@ static int pwrap_mt7622_init_soc_specific(struct pmic_wrapper *wrp)
        return 0;
 }
 
+static int pwrap_mt8183_init_soc_specific(struct pmic_wrapper *wrp)
+{
+       pwrap_writel(wrp, 0xf5, PWRAP_STAUPD_GRPEN);
+
+       pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1);
+       pwrap_writel(wrp, 1, PWRAP_CRC_EN);
+       pwrap_writel(wrp, 0x416, PWRAP_SIG_ADR);
+       pwrap_writel(wrp, 0x42e, PWRAP_EINT_STA0_ADR);
+
+       pwrap_writel(wrp, 1, PWRAP_WACS_P2P_EN);
+       pwrap_writel(wrp, 1, PWRAP_WACS_MD32_EN);
+       pwrap_writel(wrp, 1, PWRAP_INIT_DONE_P2P);
+       pwrap_writel(wrp, 1, PWRAP_INIT_DONE_MD32);
+
+       return 0;
+}
+
 static int pwrap_init(struct pmic_wrapper *wrp)
 {
        int ret;
@@ -1348,7 +1546,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
        pwrap_writel(wrp, 1, PWRAP_INIT_DONE0);
        pwrap_writel(wrp, 1, PWRAP_INIT_DONE1);
 
-       if (wrp->master->has_bridge) {
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_BRIDGE)) {
                writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE3);
                writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE4);
        }
@@ -1362,11 +1560,15 @@ static irqreturn_t pwrap_interrupt(int irqno, void *dev_id)
        struct pmic_wrapper *wrp = dev_id;
 
        rdata = pwrap_readl(wrp, PWRAP_INT_FLG);
-
        dev_err(wrp->dev, "unexpected interrupt int=0x%x\n", rdata);
-
        pwrap_writel(wrp, 0xffffffff, PWRAP_INT_CLR);
 
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_INT1_EN)) {
+               rdata = pwrap_readl(wrp, PWRAP_INT1_FLG);
+               dev_err(wrp->dev, "unexpected interrupt int1=0x%x\n", rdata);
+               pwrap_writel(wrp, 0xffffffff, PWRAP_INT1_CLR);
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -1398,6 +1600,33 @@ static const struct pwrap_slv_type pmic_mt6323 = {
        .pwrap_write = pwrap_write16,
 };
 
+static const struct pwrap_slv_type pmic_mt6351 = {
+       .dew_regs = mt6351_regs,
+       .type = PMIC_MT6351,
+       .regmap = &pwrap_regmap_config16,
+       .caps = 0,
+       .pwrap_read = pwrap_read16,
+       .pwrap_write = pwrap_write16,
+};
+
+static const struct pwrap_slv_type pmic_mt6357 = {
+       .dew_regs = mt6357_regs,
+       .type = PMIC_MT6357,
+       .regmap = &pwrap_regmap_config16,
+       .caps = 0,
+       .pwrap_read = pwrap_read16,
+       .pwrap_write = pwrap_write16,
+};
+
+static const struct pwrap_slv_type pmic_mt6358 = {
+       .dew_regs = mt6358_regs,
+       .type = PMIC_MT6358,
+       .regmap = &pwrap_regmap_config16,
+       .caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO,
+       .pwrap_read = pwrap_read16,
+       .pwrap_write = pwrap_write16,
+};
+
 static const struct pwrap_slv_type pmic_mt6380 = {
        .dew_regs = NULL,
        .type = PMIC_MT6380,
@@ -1417,19 +1646,19 @@ static const struct pwrap_slv_type pmic_mt6397 = {
        .pwrap_write = pwrap_write16,
 };
 
-static const struct pwrap_slv_type pmic_mt6351 = {
-       .dew_regs = mt6351_regs,
-       .type = PMIC_MT6351,
-       .regmap = &pwrap_regmap_config16,
-       .caps = 0,
-       .pwrap_read = pwrap_read16,
-       .pwrap_write = pwrap_write16,
-};
-
 static const struct of_device_id of_slave_match_tbl[] = {
        {
                .compatible = "mediatek,mt6323",
                .data = &pmic_mt6323,
+       }, {
+               .compatible = "mediatek,mt6351",
+               .data = &pmic_mt6351,
+       }, {
+               .compatible = "mediatek,mt6357",
+               .data = &pmic_mt6357,
+       }, {
+               .compatible = "mediatek,mt6358",
+               .data = &pmic_mt6358,
        }, {
                /* The MT6380 PMIC only implements a regulator, so we bind it
                 * directly instead of using a MFD.
@@ -1439,9 +1668,6 @@ static const struct of_device_id of_slave_match_tbl[] = {
        }, {
                .compatible = "mediatek,mt6397",
                .data = &pmic_mt6397,
-       }, {
-               .compatible = "mediatek,mt6351",
-               .data = &pmic_mt6351,
        }, {
                /* sentinel */
        }
@@ -1453,21 +1679,35 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
        .type = PWRAP_MT2701,
        .arb_en_all = 0x3f,
        .int_en_all = ~(u32)(BIT(31) | BIT(2)),
+       .int1_en_all = 0,
        .spi_w = PWRAP_MAN_CMD_SPI_WRITE_NEW,
        .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
-       .has_bridge = 0,
+       .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
        .init_reg_clock = pwrap_mt2701_init_reg_clock,
        .init_soc_specific = pwrap_mt2701_init_soc_specific,
 };
 
+static const struct pmic_wrapper_type pwrap_mt6765 = {
+       .regs = mt6765_regs,
+       .type = PWRAP_MT6765,
+       .arb_en_all = 0x3fd35,
+       .int_en_all = 0xffffffff,
+       .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+       .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+       .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
+       .init_reg_clock = pwrap_common_init_reg_clock,
+       .init_soc_specific = NULL,
+};
+
 static const struct pmic_wrapper_type pwrap_mt6797 = {
        .regs = mt6797_regs,
        .type = PWRAP_MT6797,
        .arb_en_all = 0x01fff,
        .int_en_all = 0xffffffc6,
+       .int1_en_all = 0,
        .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
        .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
-       .has_bridge = 0,
+       .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
        .init_reg_clock = pwrap_common_init_reg_clock,
        .init_soc_specific = NULL,
 };
@@ -1477,9 +1717,10 @@ static const struct pmic_wrapper_type pwrap_mt7622 = {
        .type = PWRAP_MT7622,
        .arb_en_all = 0xff,
        .int_en_all = ~(u32)BIT(31),
+       .int1_en_all = 0,
        .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
        .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
-       .has_bridge = 0,
+       .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
        .init_reg_clock = pwrap_common_init_reg_clock,
        .init_soc_specific = pwrap_mt7622_init_soc_specific,
 };
@@ -1489,9 +1730,10 @@ static const struct pmic_wrapper_type pwrap_mt8135 = {
        .type = PWRAP_MT8135,
        .arb_en_all = 0x1ff,
        .int_en_all = ~(u32)(BIT(31) | BIT(1)),
+       .int1_en_all = 0,
        .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
        .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
-       .has_bridge = 1,
+       .caps = PWRAP_CAP_BRIDGE | PWRAP_CAP_RESET | PWRAP_CAP_DCM,
        .init_reg_clock = pwrap_common_init_reg_clock,
        .init_soc_specific = pwrap_mt8135_init_soc_specific,
 };
@@ -1501,17 +1743,34 @@ static const struct pmic_wrapper_type pwrap_mt8173 = {
        .type = PWRAP_MT8173,
        .arb_en_all = 0x3f,
        .int_en_all = ~(u32)(BIT(31) | BIT(1)),
+       .int1_en_all = 0,
        .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
        .wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
-       .has_bridge = 0,
+       .caps = PWRAP_CAP_RESET | PWRAP_CAP_DCM,
        .init_reg_clock = pwrap_common_init_reg_clock,
        .init_soc_specific = pwrap_mt8173_init_soc_specific,
 };
 
+static const struct pmic_wrapper_type pwrap_mt8183 = {
+       .regs = mt8183_regs,
+       .type = PWRAP_MT8183,
+       .arb_en_all = 0x3fa75,
+       .int_en_all = 0xffffffff,
+       .int1_en_all = 0xeef7ffff,
+       .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+       .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+       .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_WDT_SRC1,
+       .init_reg_clock = pwrap_common_init_reg_clock,
+       .init_soc_specific = pwrap_mt8183_init_soc_specific,
+};
+
 static const struct of_device_id of_pwrap_match_tbl[] = {
        {
                .compatible = "mediatek,mt2701-pwrap",
                .data = &pwrap_mt2701,
+       }, {
+               .compatible = "mediatek,mt6765-pwrap",
+               .data = &pwrap_mt6765,
        }, {
                .compatible = "mediatek,mt6797-pwrap",
                .data = &pwrap_mt6797,
@@ -1524,6 +1783,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
        }, {
                .compatible = "mediatek,mt8173-pwrap",
                .data = &pwrap_mt8173,
+       }, {
+               .compatible = "mediatek,mt8183-pwrap",
+               .data = &pwrap_mt8183,
        }, {
                /* sentinel */
        }
@@ -1561,14 +1823,16 @@ static int pwrap_probe(struct platform_device *pdev)
        if (IS_ERR(wrp->base))
                return PTR_ERR(wrp->base);
 
-       wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
-       if (IS_ERR(wrp->rstc)) {
-               ret = PTR_ERR(wrp->rstc);
-               dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
-               return ret;
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_RESET)) {
+               wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
+               if (IS_ERR(wrp->rstc)) {
+                       ret = PTR_ERR(wrp->rstc);
+                       dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
+                       return ret;
+               }
        }
 
-       if (wrp->master->has_bridge) {
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_BRIDGE)) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                "pwrap-bridge");
                wrp->bridge_base = devm_ioremap_resource(wrp->dev, res);
@@ -1608,8 +1872,10 @@ static int pwrap_probe(struct platform_device *pdev)
                goto err_out1;
 
        /* Enable internal dynamic clock */
-       pwrap_writel(wrp, 1, PWRAP_DCM_EN);
-       pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_DCM)) {
+               pwrap_writel(wrp, 1, PWRAP_DCM_EN);
+               pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
+       }
 
        /*
         * The PMIC could already be initialized by the bootloader.
@@ -1636,8 +1902,17 @@ static int pwrap_probe(struct platform_device *pdev)
         * so STAUPD of WDT_SRC which should be turned off
         */
        pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN);
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_WDT_SRC1))
+               pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN_1);
+
        pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
        pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
+       /*
+        * We add INT1 interrupt to handle starvation and request exception
+        * If we support it, we should enable it here.
+        */
+       if (HAS_CAP(wrp->master->caps, PWRAP_CAP_INT1_EN))
+               pwrap_writel(wrp, wrp->master->int1_en_all, PWRAP_INT1_EN);
 
        irq = platform_get_irq(pdev, 0);
        ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt,
index 41986d96f24b6952c8f90b541a5af723899617c3..684cb51694d1ff7a917b6883d5d00847698570d3 100644 (file)
@@ -33,7 +33,7 @@ config QCOM_GLINK_SSR
 
 config QCOM_GSBI
         tristate "QCOM General Serial Bus Interface"
-        depends on ARCH_QCOM
+        depends on ARCH_QCOM || COMPILE_TEST
         select MFD_SYSCON
         help
           Say y here to enable GSBI support.  The GSBI provides control
@@ -42,7 +42,7 @@ config QCOM_GSBI
 
 config QCOM_LLCC
        tristate "Qualcomm Technologies, Inc. LLCC driver"
-       depends on ARCH_QCOM
+       depends on ARCH_QCOM || COMPILE_TEST
        help
          Qualcomm Technologies, Inc. platform specific
          Last Level Cache Controller(LLCC) driver. This provides interfaces
@@ -73,7 +73,8 @@ config QCOM_PM
 
 config QCOM_QMI_HELPERS
        tristate
-       depends on (ARCH_QCOM || COMPILE_TEST) && NET
+       depends on ARCH_QCOM || COMPILE_TEST
+       depends on NET
        help
          Helper library for handling QMI encoded messages.  QMI encoded
          messages are used in communication between the majority of QRTR
@@ -94,7 +95,7 @@ config QCOM_RMTFS_MEM
 
 config QCOM_RPMH
        bool "Qualcomm RPM-Hardened (RPMH) Communication"
-       depends on ARCH_QCOM && ARM64 && OF || COMPILE_TEST
+       depends on ARCH_QCOM && ARM64 || COMPILE_TEST
        help
          Support for communication with the hardened-RPM blocks in
          Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an
@@ -104,7 +105,7 @@ config QCOM_RPMH
 
 config QCOM_SMEM
        tristate "Qualcomm Shared Memory Manager (SMEM)"
-       depends on ARCH_QCOM
+       depends on ARCH_QCOM || COMPILE_TEST
        depends on HWSPINLOCK
        help
          Say y here to enable support for the Qualcomm Shared Memory Manager.
@@ -113,8 +114,8 @@ config QCOM_SMEM
 
 config QCOM_SMD_RPM
        tristate "Qualcomm Resource Power Manager (RPM) over SMD"
-       depends on ARCH_QCOM
-       depends on RPMSG && OF
+       depends on ARCH_QCOM || COMPILE_TEST
+       depends on RPMSG
        help
          If you say yes to this option, support will be included for the
          Resource Power Manager system found in the Qualcomm 8974 based
@@ -134,6 +135,7 @@ config QCOM_SMP2P
        depends on MAILBOX
        depends on QCOM_SMEM
        select QCOM_SMEM_STATE
+       select IRQ_DOMAIN
        help
          Say yes here to support the Qualcomm Shared Memory Point to Point
          protocol.
@@ -142,13 +144,14 @@ config QCOM_SMSM
        tristate "Qualcomm Shared Memory State Machine"
        depends on QCOM_SMEM
        select QCOM_SMEM_STATE
+       select IRQ_DOMAIN
        help
          Say yes here to support the Qualcomm Shared Memory State Machine.
          The state machine is represented by bits in shared memory.
 
 config QCOM_WCNSS_CTRL
        tristate "Qualcomm WCNSS control driver"
-       depends on ARCH_QCOM
+       depends on ARCH_QCOM || COMPILE_TEST
        depends on RPMSG
        help
          Client driver for the WCNSS_CTRL SMD channel, used to download nv
@@ -156,7 +159,7 @@ config QCOM_WCNSS_CTRL
 
 config QCOM_APR
        tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
-       depends on ARCH_QCOM
+       depends on ARCH_QCOM || COMPILE_TEST
        depends on RPMSG
        help
           Enable APR IPC protocol support between
index 4bda793ba6ae5bbc2d73082397700ae276255470..74f8b9607daa16fc3e7bbd6e26e6fcd67244dcde 100644 (file)
@@ -87,7 +87,7 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
        }
 
        if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) {
-               dev_err(apr->dev, "APR: Wrong paket size\n");
+               dev_err(apr->dev, "APR: Wrong packet size\n");
                return -EINVAL;
        }
 
@@ -221,7 +221,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
        if (np)
                snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np);
        else
-               strncpy(adev->name, id->name, APR_NAME_SIZE);
+               strscpy(adev->name, id->name, APR_NAME_SIZE);
 
        dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
                     id->domain_id, id->svc_id);
index 54063a31132fa0b21e2c1ee3ed5fd85c87e759c8..192ca761b2cb3a1f6c7615b3e179c94b0e1be51c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mutex.h>
 #include <linux/of_device.h>
 #include <linux/regmap.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/soc/qcom/llcc-qcom.h>
 
@@ -106,22 +107,24 @@ static int llcc_update_act_ctrl(u32 sid,
        u32 slice_status;
        int ret;
 
-       act_ctrl_reg = drv_data->bcast_off + LLCC_TRP_ACT_CTRLn(sid);
-       status_reg = drv_data->bcast_off + LLCC_TRP_STATUSn(sid);
+       act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
+       status_reg = LLCC_TRP_STATUSn(sid);
 
        /* Set the ACTIVE trigger */
        act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
-       ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val);
+       ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
+                               act_ctrl_reg_val);
        if (ret)
                return ret;
 
        /* Clear the ACTIVE trigger */
        act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
-       ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val);
+       ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
+                               act_ctrl_reg_val);
        if (ret)
                return ret;
 
-       ret = regmap_read_poll_timeout(drv_data->regmap, status_reg,
+       ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
                                      slice_status, !(slice_status & status),
                                      0, LLCC_STATUS_READ_DELAY);
        return ret;
@@ -223,19 +226,16 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
        u32 attr0_val;
        u32 max_cap_cacheline;
        u32 sz;
-       int ret;
+       int ret = 0;
        const struct llcc_slice_config *llcc_table;
        struct llcc_slice_desc desc;
-       u32 bcast_off = drv_data->bcast_off;
 
        sz = drv_data->cfg_size;
        llcc_table = drv_data->cfg;
 
        for (i = 0; i < sz; i++) {
-               attr1_cfg = bcast_off +
-                               LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
-               attr0_cfg = bcast_off +
-                               LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
+               attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
+               attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
 
                attr1_val = llcc_table[i].cache_mode;
                attr1_val |= llcc_table[i].probe_target_ways <<
@@ -260,10 +260,12 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
                attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
                attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
 
-               ret = regmap_write(drv_data->regmap, attr1_cfg, attr1_val);
+               ret = regmap_write(drv_data->bcast_regmap, attr1_cfg,
+                                       attr1_val);
                if (ret)
                        return ret;
-               ret = regmap_write(drv_data->regmap, attr0_cfg, attr0_val);
+               ret = regmap_write(drv_data->bcast_regmap, attr0_cfg,
+                                       attr0_val);
                if (ret)
                        return ret;
                if (llcc_table[i].activate_on_init) {
@@ -279,24 +281,37 @@ int qcom_llcc_probe(struct platform_device *pdev,
 {
        u32 num_banks;
        struct device *dev = &pdev->dev;
-       struct resource *res;
-       void __iomem *base;
+       struct resource *llcc_banks_res, *llcc_bcast_res;
+       void __iomem *llcc_banks_base, *llcc_bcast_base;
        int ret, i;
+       struct platform_device *llcc_edac;
 
        drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
        if (!drv_data)
                return -ENOMEM;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(base))
-               return PTR_ERR(base);
+       llcc_banks_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                       "llcc_base");
+       llcc_banks_base = devm_ioremap_resource(&pdev->dev, llcc_banks_res);
+       if (IS_ERR(llcc_banks_base))
+               return PTR_ERR(llcc_banks_base);
 
-       drv_data->regmap = devm_regmap_init_mmio(dev, base,
-                                       &llcc_regmap_config);
+       drv_data->regmap = devm_regmap_init_mmio(dev, llcc_banks_base,
+                                               &llcc_regmap_config);
        if (IS_ERR(drv_data->regmap))
                return PTR_ERR(drv_data->regmap);
 
+       llcc_bcast_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                       "llcc_broadcast_base");
+       llcc_bcast_base = devm_ioremap_resource(&pdev->dev, llcc_bcast_res);
+       if (IS_ERR(llcc_bcast_base))
+               return PTR_ERR(llcc_bcast_base);
+
+       drv_data->bcast_regmap = devm_regmap_init_mmio(dev, llcc_bcast_base,
+                                                       &llcc_regmap_config);
+       if (IS_ERR(drv_data->bcast_regmap))
+               return PTR_ERR(drv_data->bcast_regmap);
+
        ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
                                                &num_banks);
        if (ret)
@@ -318,8 +333,6 @@ int qcom_llcc_probe(struct platform_device *pdev,
        for (i = 0; i < num_banks; i++)
                drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
 
-       drv_data->bcast_off = num_banks * BANK_OFFSET_STRIDE;
-
        drv_data->bitmap = devm_kcalloc(dev,
        BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
                                                GFP_KERNEL);
@@ -331,7 +344,20 @@ int qcom_llcc_probe(struct platform_device *pdev,
        mutex_init(&drv_data->lock);
        platform_set_drvdata(pdev, drv_data);
 
-       return qcom_llcc_cfg_program(pdev);
+       ret = qcom_llcc_cfg_program(pdev);
+       if (ret)
+               return ret;
+
+       drv_data->ecc_irq = platform_get_irq(pdev, 0);
+       if (drv_data->ecc_irq >= 0) {
+               llcc_edac = platform_device_register_data(&pdev->dev,
+                                               "qcom_llcc_edac", -1, drv_data,
+                                               sizeof(*drv_data));
+               if (IS_ERR(llcc_edac))
+                       dev_err(dev, "Failed to register llcc edac driver\n");
+       }
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_llcc_probe);
 
index 8a3678c2e83cf609daddfdcd7c50e9de0a671ad2..97bb5989aa21158dee92d58e5f22bc74729dbbc2 100644 (file)
@@ -212,6 +212,11 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to parse qcom,vmid\n");
                goto remove_cdev;
        } else if (!ret) {
+               if (!qcom_scm_is_available()) {
+                       ret = -EPROBE_DEFER;
+                       goto remove_cdev;
+               }
+
                perms[0].vmid = QCOM_SCM_VMID_HLOS;
                perms[0].perm = QCOM_SCM_PERM_RW;
                perms[1].vmid = vmid;
index ee75da66d64bf06466791a41182bae0e64e1643f..75bd9a83aef00670d474a69c86fde81aa4794e93 100644 (file)
@@ -121,6 +121,7 @@ static int tcs_invalidate(struct rsc_drv *drv, int type)
                        return -EAGAIN;
                }
                write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0);
+               write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, m, 0);
        }
        bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
        spin_unlock(&tcs->lock);
@@ -239,6 +240,7 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
 skip:
                /* Reclaim the TCS */
                write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
+               write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, i, 0);
                write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i));
                spin_lock(&drv->lock);
                clear_bit(i, drv->tcs_in_use);
index bf4bd71ab53fd9a36460b7d1a1f52793ea998506..f80d040601fd7cfa75efc6180ba59fc19b6ecb93 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/soc/qcom/smem.h>
 
@@ -277,7 +278,7 @@ struct qcom_smem {
        u32 item_count;
 
        unsigned num_regions;
-       struct smem_region regions[0];
+       struct smem_region regions[];
 };
 
 static void *
@@ -489,7 +490,7 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
                                  size_t *size)
 {
        struct smem_header *header;
-       struct smem_region *area;
+       struct smem_region *region;
        struct smem_global_entry *entry;
        u32 aux_base;
        unsigned i;
@@ -502,12 +503,12 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
        aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
 
        for (i = 0; i < smem->num_regions; i++) {
-               area = &smem->regions[i];
+               region = &smem->regions[i];
 
-               if (area->aux_base == aux_base || !aux_base) {
+               if (region->aux_base == aux_base || !aux_base) {
                        if (size != NULL)
                                *size = le32_to_cpu(entry->size);
-                       return area->virt_base + le32_to_cpu(entry->offset);
+                       return region->virt_base + le32_to_cpu(entry->offset);
                }
        }
 
@@ -722,12 +723,59 @@ static u32 qcom_smem_get_item_count(struct qcom_smem *smem)
        return le16_to_cpu(info->num_items);
 }
 
+/*
+ * Validate the partition header for a partition whose partition
+ * table entry is supplied.  Returns a pointer to its header if
+ * valid, or a null pointer otherwise.
+ */
+static struct smem_partition_header *
+qcom_smem_partition_header(struct qcom_smem *smem,
+               struct smem_ptable_entry *entry, u16 host0, u16 host1)
+{
+       struct smem_partition_header *header;
+       u32 size;
+
+       header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+
+       if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
+               dev_err(smem->dev, "bad partition magic %02x %02x %02x %02x\n",
+                       header->magic[0], header->magic[1],
+                       header->magic[2], header->magic[3]);
+               return NULL;
+       }
+
+       if (host0 != le16_to_cpu(header->host0)) {
+               dev_err(smem->dev, "bad host0 (%hu != %hu)\n",
+                               host0, le16_to_cpu(header->host0));
+               return NULL;
+       }
+       if (host1 != le16_to_cpu(header->host1)) {
+               dev_err(smem->dev, "bad host1 (%hu != %hu)\n",
+                               host1, le16_to_cpu(header->host1));
+               return NULL;
+       }
+
+       size = le32_to_cpu(header->size);
+       if (size != le32_to_cpu(entry->size)) {
+               dev_err(smem->dev, "bad partition size (%u != %u)\n",
+                       size, le32_to_cpu(entry->size));
+               return NULL;
+       }
+
+       if (le32_to_cpu(header->offset_free_uncached) > size) {
+               dev_err(smem->dev, "bad partition free uncached (%u > %u)\n",
+                       le32_to_cpu(header->offset_free_uncached), size);
+               return NULL;
+       }
+
+       return header;
+}
+
 static int qcom_smem_set_global_partition(struct qcom_smem *smem)
 {
        struct smem_partition_header *header;
        struct smem_ptable_entry *entry;
        struct smem_ptable *ptable;
-       u32 host0, host1, size;
        bool found = false;
        int i;
 
@@ -742,10 +790,15 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
 
        for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
                entry = &ptable->entry[i];
-               host0 = le16_to_cpu(entry->host0);
-               host1 = le16_to_cpu(entry->host1);
+               if (!le32_to_cpu(entry->offset))
+                       continue;
+               if (!le32_to_cpu(entry->size))
+                       continue;
+
+               if (le16_to_cpu(entry->host0) != SMEM_GLOBAL_HOST)
+                       continue;
 
-               if (host0 == SMEM_GLOBAL_HOST && host0 == host1) {
+               if (le16_to_cpu(entry->host1) == SMEM_GLOBAL_HOST) {
                        found = true;
                        break;
                }
@@ -756,36 +809,10 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
                return -EINVAL;
        }
 
-       if (!le32_to_cpu(entry->offset) || !le32_to_cpu(entry->size)) {
-               dev_err(smem->dev, "Invalid entry for global partition\n");
+       header = qcom_smem_partition_header(smem, entry,
+                               SMEM_GLOBAL_HOST, SMEM_GLOBAL_HOST);
+       if (!header)
                return -EINVAL;
-       }
-
-       header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
-       host0 = le16_to_cpu(header->host0);
-       host1 = le16_to_cpu(header->host1);
-
-       if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
-               dev_err(smem->dev, "Global partition has invalid magic\n");
-               return -EINVAL;
-       }
-
-       if (host0 != SMEM_GLOBAL_HOST && host1 != SMEM_GLOBAL_HOST) {
-               dev_err(smem->dev, "Global partition hosts are invalid\n");
-               return -EINVAL;
-       }
-
-       if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
-               dev_err(smem->dev, "Global partition has invalid size\n");
-               return -EINVAL;
-       }
-
-       size = le32_to_cpu(header->offset_free_uncached);
-       if (size > le32_to_cpu(header->size)) {
-               dev_err(smem->dev,
-                       "Global partition has invalid free pointer\n");
-               return -EINVAL;
-       }
 
        smem->global_partition = header;
        smem->global_cacheline = le32_to_cpu(entry->cacheline);
@@ -793,14 +820,14 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
        return 0;
 }
 
-static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
-                                         unsigned int local_host)
+static int
+qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
 {
        struct smem_partition_header *header;
        struct smem_ptable_entry *entry;
        struct smem_ptable *ptable;
        unsigned int remote_host;
-       u32 host0, host1;
+       u16 host0, host1;
        int i;
 
        ptable = qcom_smem_get_ptable(smem);
@@ -809,71 +836,33 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
 
        for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
                entry = &ptable->entry[i];
-               host0 = le16_to_cpu(entry->host0);
-               host1 = le16_to_cpu(entry->host1);
-
-               if (host0 != local_host && host1 != local_host)
-                       continue;
-
                if (!le32_to_cpu(entry->offset))
                        continue;
-
                if (!le32_to_cpu(entry->size))
                        continue;
 
+               host0 = le16_to_cpu(entry->host0);
+               host1 = le16_to_cpu(entry->host1);
                if (host0 == local_host)
                        remote_host = host1;
-               else
+               else if (host1 == local_host)
                        remote_host = host0;
+               else
+                       continue;
 
                if (remote_host >= SMEM_HOST_COUNT) {
-                       dev_err(smem->dev,
-                               "Invalid remote host %d\n",
-                               remote_host);
+                       dev_err(smem->dev, "bad host %hu\n", remote_host);
                        return -EINVAL;
                }
 
                if (smem->partitions[remote_host]) {
-                       dev_err(smem->dev,
-                               "Already found a partition for host %d\n",
-                               remote_host);
-                       return -EINVAL;
-               }
-
-               header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
-               host0 = le16_to_cpu(header->host0);
-               host1 = le16_to_cpu(header->host1);
-
-               if (memcmp(header->magic, SMEM_PART_MAGIC,
-                           sizeof(header->magic))) {
-                       dev_err(smem->dev,
-                               "Partition %d has invalid magic\n", i);
+                       dev_err(smem->dev, "duplicate host %hu\n", remote_host);
                        return -EINVAL;
                }
 
-               if (host0 != local_host && host1 != local_host) {
-                       dev_err(smem->dev,
-                               "Partition %d hosts are invalid\n", i);
+               header = qcom_smem_partition_header(smem, entry, host0, host1);
+               if (!header)
                        return -EINVAL;
-               }
-
-               if (host0 != remote_host && host1 != remote_host) {
-                       dev_err(smem->dev,
-                               "Partition %d hosts are invalid\n", i);
-                       return -EINVAL;
-               }
-
-               if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
-                       dev_err(smem->dev,
-                               "Partition %d has invalid size\n", i);
-                       return -EINVAL;
-               }
-
-               if (le32_to_cpu(header->offset_free_uncached) > le32_to_cpu(header->size)) {
-                       dev_err(smem->dev,
-                               "Partition %d has invalid free pointer\n", i);
-                       return -EINVAL;
-               }
 
                smem->partitions[remote_host] = header;
                smem->cacheline[remote_host] = le32_to_cpu(entry->cacheline);
@@ -887,6 +876,7 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
 {
        struct device_node *np;
        struct resource r;
+       resource_size_t size;
        int ret;
 
        np = of_parse_phandle(dev->of_node, name, 0);
@@ -899,12 +889,13 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
        of_node_put(np);
        if (ret)
                return ret;
+       size = resource_size(&r);
 
-       smem->regions[i].aux_base = (u32)r.start;
-       smem->regions[i].size = resource_size(&r);
-       smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, resource_size(&r));
+       smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, size);
        if (!smem->regions[i].virt_base)
                return -ENOMEM;
+       smem->regions[i].aux_base = (u32)r.start;
+       smem->regions[i].size = size;
 
        return 0;
 }
@@ -962,6 +953,7 @@ static int qcom_smem_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       BUILD_BUG_ON(SMEM_HOST_APPS >= SMEM_HOST_COUNT);
        ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS);
        if (ret < 0 && ret != -ENOENT)
                return ret;
index f9d7a85b2822036dd1cdd7497032c98f2f7ea383..53807e839664e9f3ca70e92d9e5a5e336e38b4c0 100644 (file)
@@ -219,6 +219,9 @@ static int __init qcom_cpuidle_init(struct device_node *cpu_node, int cpu)
        cpumask_t mask;
        bool use_scm_power_down = false;
 
+       if (!qcom_scm_is_available())
+               return -EPROBE_DEFER;
+
        for (i = 0; ; i++) {
                state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
                if (!state_node)
index df3ccb30bc2dddba0d2d6accccdd6a6c5a7bc53c..373400dd816d6802378dcf5bc7373fb921b22343 100644 (file)
@@ -281,7 +281,7 @@ struct rpmsg_endpoint *qcom_wcnss_open_channel(void *wcnss, const char *name, rp
        struct rpmsg_channel_info chinfo;
        struct wcnss_ctrl *_wcnss = wcnss;
 
-       strncpy(chinfo.name, name, sizeof(chinfo.name));
+       strscpy(chinfo.name, name, sizeof(chinfo.name));
        chinfo.src = RPMSG_ADDR_ANY;
        chinfo.dst = RPMSG_ADDR_ANY;
 
index 1d824cbd462dc2eaf875b3572e07e282e0ee2614..407f02c80e8b721ce5ed15dd9fcbb59b527d436a 100644 (file)
@@ -1,14 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
 config SOC_RENESAS
        bool "Renesas SoC driver support" if COMPILE_TEST && !ARCH_RENESAS
        default y if ARCH_RENESAS
        select SOC_BUS
        select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
-                          ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
-                          ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77990 || \
-                          ARCH_R8A77995
-       select SYSC_R8A7743 if ARCH_R8A7743
+                          ARCH_R8A774A1 || ARCH_R8A774C0 || ARCH_R8A7795 || \
+                          ARCH_R8A7796 || ARCH_R8A77965 || ARCH_R8A77970 || \
+                          ARCH_R8A77980 || ARCH_R8A77990 || ARCH_R8A77995
+       select SYSC_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744
        select SYSC_R8A7745 if ARCH_R8A7745
        select SYSC_R8A77470 if ARCH_R8A77470
+       select SYSC_R8A774A1 if ARCH_R8A774A1
+       select SYSC_R8A774C0 if ARCH_R8A774C0
        select SYSC_R8A7779 if ARCH_R8A7779
        select SYSC_R8A7790 if ARCH_R8A7790
        select SYSC_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
@@ -37,6 +40,14 @@ config SYSC_R8A77470
        bool "RZ/G1C System Controller support" if COMPILE_TEST
        select SYSC_RCAR
 
+config SYSC_R8A774A1
+       bool "RZ/G2M System Controller support" if COMPILE_TEST
+       select SYSC_RCAR
+
+config SYSC_R8A774C0
+       bool "RZ/G2E System Controller support" if COMPILE_TEST
+       select SYSC_RCAR
+
 config SYSC_R8A7779
        bool "R-Car H1 System Controller support" if COMPILE_TEST
        select SYSC_RCAR
index c37b0803c1b60d9f0d385c76dd2be05a136dd35e..3bdd7dbc38a9c7a3a9407454ff00d81bc1ad90d4 100644 (file)
@@ -6,6 +6,8 @@ obj-$(CONFIG_SOC_RENESAS)       += renesas-soc.o
 obj-$(CONFIG_SYSC_R8A7743)     += r8a7743-sysc.o
 obj-$(CONFIG_SYSC_R8A7745)     += r8a7745-sysc.o
 obj-$(CONFIG_SYSC_R8A77470)    += r8a77470-sysc.o
+obj-$(CONFIG_SYSC_R8A774A1)    += r8a774a1-sysc.o
+obj-$(CONFIG_SYSC_R8A774C0)    += r8a774c0-sysc.o
 obj-$(CONFIG_SYSC_R8A7779)     += r8a7779-sysc.o
 obj-$(CONFIG_SYSC_R8A7790)     += r8a7790-sysc.o
 obj-$(CONFIG_SYSC_R8A7791)     += r8a7791-sysc.o
index 9583a327d90c71600d28fcb100231b5f23a8b2b3..edf6436e879fa662803e1715d08bc6b87c4cbc93 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas RZ/G1M System Controller
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation; of the License.
  */
 
 #include <linux/bug.h>
index d17887c08aa1915ab5233aa9af41183ca85a4818..65dc6b09cc858d38eec48f05eded6a80f987b64f 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas RZ/G1E System Controller
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation; of the License.
  */
 
 #include <linux/bug.h>
diff --git a/drivers/soc/renesas/r8a774a1-sysc.c b/drivers/soc/renesas/r8a774a1-sysc.c
new file mode 100644 (file)
index 0000000..9db51ff
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2M System Controller
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * Based on Renesas R-Car M3-W System Controller
+ * Copyright (C) 2016 Glider bvba
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a774a1-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a774a1_areas[] __initconst = {
+       { "always-on",      0, 0, R8A774A1_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+       { "ca57-scu",   0x1c0, 0, R8A774A1_PD_CA57_SCU, R8A774A1_PD_ALWAYS_ON,
+         PD_SCU },
+       { "ca57-cpu0",   0x80, 0, R8A774A1_PD_CA57_CPU0, R8A774A1_PD_CA57_SCU,
+         PD_CPU_NOCR },
+       { "ca57-cpu1",   0x80, 1, R8A774A1_PD_CA57_CPU1, R8A774A1_PD_CA57_SCU,
+         PD_CPU_NOCR },
+       { "ca53-scu",   0x140, 0, R8A774A1_PD_CA53_SCU, R8A774A1_PD_ALWAYS_ON,
+         PD_SCU },
+       { "ca53-cpu0",  0x200, 0, R8A774A1_PD_CA53_CPU0, R8A774A1_PD_CA53_SCU,
+         PD_CPU_NOCR },
+       { "ca53-cpu1",  0x200, 1, R8A774A1_PD_CA53_CPU1, R8A774A1_PD_CA53_SCU,
+         PD_CPU_NOCR },
+       { "ca53-cpu2",  0x200, 2, R8A774A1_PD_CA53_CPU2, R8A774A1_PD_CA53_SCU,
+         PD_CPU_NOCR },
+       { "ca53-cpu3",  0x200, 3, R8A774A1_PD_CA53_CPU3, R8A774A1_PD_CA53_SCU,
+         PD_CPU_NOCR },
+       { "a3vc",       0x380, 0, R8A774A1_PD_A3VC,     R8A774A1_PD_ALWAYS_ON },
+       { "a2vc0",      0x3c0, 0, R8A774A1_PD_A2VC0,    R8A774A1_PD_A3VC },
+       { "a2vc1",      0x3c0, 1, R8A774A1_PD_A2VC1,    R8A774A1_PD_A3VC },
+       { "3dg-a",      0x100, 0, R8A774A1_PD_3DG_A,    R8A774A1_PD_ALWAYS_ON },
+       { "3dg-b",      0x100, 1, R8A774A1_PD_3DG_B,    R8A774A1_PD_3DG_A },
+};
+
+const struct rcar_sysc_info r8a774a1_sysc_info __initconst = {
+       .areas = r8a774a1_areas,
+       .num_areas = ARRAY_SIZE(r8a774a1_areas),
+};
diff --git a/drivers/soc/renesas/r8a774c0-sysc.c b/drivers/soc/renesas/r8a774c0-sysc.c
new file mode 100644 (file)
index 0000000..e1ac4c0
--- /dev/null
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2E System Controller
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ * Based on Renesas R-Car E3 System Controller
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/sys_soc.h>
+
+#include <dt-bindings/power/r8a774c0-sysc.h>
+
+#include "rcar-sysc.h"
+
+static struct rcar_sysc_area r8a774c0_areas[] __initdata = {
+       { "always-on",      0, 0, R8A774C0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+       { "ca53-scu",   0x140, 0, R8A774C0_PD_CA53_SCU,  R8A774C0_PD_ALWAYS_ON,
+         PD_SCU },
+       { "ca53-cpu0",  0x200, 0, R8A774C0_PD_CA53_CPU0, R8A774C0_PD_CA53_SCU,
+         PD_CPU_NOCR },
+       { "ca53-cpu1",  0x200, 1, R8A774C0_PD_CA53_CPU1, R8A774C0_PD_CA53_SCU,
+         PD_CPU_NOCR },
+       { "a3vc",       0x380, 0, R8A774C0_PD_A3VC,     R8A774C0_PD_ALWAYS_ON },
+       { "a2vc1",      0x3c0, 1, R8A774C0_PD_A2VC1,    R8A774C0_PD_A3VC },
+       { "3dg-a",      0x100, 0, R8A774C0_PD_3DG_A,    R8A774C0_PD_ALWAYS_ON },
+       { "3dg-b",      0x100, 1, R8A774C0_PD_3DG_B,    R8A774C0_PD_3DG_A },
+};
+
+static void __init rcar_sysc_fix_parent(struct rcar_sysc_area *areas,
+                                       unsigned int num_areas, u8 id,
+                                       int new_parent)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_areas; i++)
+               if (areas[i].isr_bit == id) {
+                       areas[i].parent = new_parent;
+                       return;
+               }
+}
+
+/* Fixups for RZ/G2E ES1.0 revision */
+static const struct soc_device_attribute r8a774c0[] __initconst = {
+       { .soc_id = "r8a774c0", .revision = "ES1.0" },
+       { /* sentinel */ }
+};
+
+static int __init r8a774c0_sysc_init(void)
+{
+       if (soc_device_match(r8a774c0)) {
+               rcar_sysc_fix_parent(r8a774c0_areas,
+                                    ARRAY_SIZE(r8a774c0_areas),
+                                    R8A774C0_PD_3DG_A, R8A774C0_PD_3DG_B);
+               rcar_sysc_fix_parent(r8a774c0_areas,
+                                    ARRAY_SIZE(r8a774c0_areas),
+                                    R8A774C0_PD_3DG_B, R8A774C0_PD_ALWAYS_ON);
+       }
+
+       return 0;
+}
+
+const struct rcar_sysc_info r8a774c0_sysc_info __initconst = {
+       .init = r8a774c0_sysc_init,
+       .areas = r8a774c0_areas,
+       .num_areas = ARRAY_SIZE(r8a774c0_areas),
+};
index 9e8e6b7faa04468495754509b702edb138285027..517aa40fa6e6d493ec42de51e08de67252b2a691 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car H1 System Controller
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index 7a567ad0ff73c2c7c68f4dcecb47217ce7e4d8fa..9b5a6bb6215209639e2e39cb28f6d987b27ac89e 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car H2 System Controller
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index 03b9f41a34e62f36bad9983f6de1d56778604787..acf545cdebfbe1f20ddeeebac88698e23b33f8d0 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car M2-W/N System Controller
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index ca7467d7b7ecf84ed8ff9a04feffb75ec54304ac..05b78525cc430bacacad72e597a15cd1db117cfb 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car V2H (R8A7792) System Controller
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index c4da2941e06c9468711f8d59f9317e6f1bfaccc1..0d42637fa662099433fb956f23e705b74124c7b9 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car E2 System Controller
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index 7412666187b30420235e1ef10d64ce7926c5e7f7..cda27a67de9876afe751df27d1f135af0b3f5247 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car H3 System Controller
  *
  * Copyright (C) 2016-2017 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index f700c842b9e1d010b8f2c1e947c62e7c95671de0..1b06f868b6e81c798dfb17614ad53e96a6f23f47 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car M3-W System Controller
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index caf894f193edcc6446165d2d763c98fd090da540..35b30d6a8958a063cb04e7976bd87ae5a09c5720 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car V3M System Controller
  *
  * Copyright (C) 2017 Cogent Embedded Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/bug.h>
index 1b2ef415bbe1cbf7f6adccdf36a52abce3ad22e4..6243aaaf60fbb51cff3a792ac39dfb1b1bd588f5 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas R-Car D3 System Controller
  *
  * Copyright (C) 2017 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #include <linux/bug.h>
index d9c1034e70e94d05d4557d98535aeac873aa51a4..d183c381e8dbb6c14ccb26b0eed8e819a9f7be19 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car Gen1 RESET/WDT, R-Car Gen2, Gen3, and RZ/G RST Driver
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/err.h>
@@ -41,10 +38,14 @@ static const struct rst_config rcar_rst_gen3 __initconst = {
 };
 
 static const struct of_device_id rcar_rst_matches[] __initconst = {
-       /* RZ/G is handled like R-Car Gen2 */
+       /* RZ/G1 is handled like R-Car Gen2 */
        { .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 },
+       { .compatible = "renesas,r8a7744-rst", .data = &rcar_rst_gen2 },
        { .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 },
        { .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 },
+       /* RZ/G2 is handled like R-Car Gen3 */
+       { .compatible = "renesas,r8a774a1-rst", .data = &rcar_rst_gen3 },
+       { .compatible = "renesas,r8a774c0-rst", .data = &rcar_rst_gen3 },
        /* R-Car Gen1 */
        { .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 },
        { .compatible = "renesas,r8a7779-reset-wdt", .data = &rcar_rst_gen1 },
index 029188e8be6e95f2b86d30dc6963a94ce01fc3c9..af53363eda0374ceeaaa22d362f2078539f64588 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car SYSC Power management support
  *
  * Copyright (C) 2014  Magnus Damm
  * Copyright (C) 2015-2017 Glider bvba
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/clk/renesas.h>
@@ -268,6 +265,8 @@ finalize:
 static const struct of_device_id rcar_sysc_matches[] __initconst = {
 #ifdef CONFIG_SYSC_R8A7743
        { .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info },
+       /* RZ/G1N is identical to RZ/G2M w.r.t. power domains. */
+       { .compatible = "renesas,r8a7744-sysc", .data = &r8a7743_sysc_info },
 #endif
 #ifdef CONFIG_SYSC_R8A7745
        { .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info },
@@ -275,6 +274,12 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = {
 #ifdef CONFIG_SYSC_R8A77470
        { .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info },
 #endif
+#ifdef CONFIG_SYSC_R8A774A1
+       { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info },
+#endif
+#ifdef CONFIG_SYSC_R8A774C0
+       { .compatible = "renesas,r8a774c0-sysc", .data = &r8a774c0_sysc_info },
+#endif
 #ifdef CONFIG_SYSC_R8A7779
        { .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
 #endif
index a22e7cf25e309bb5a4700b4b840c83d240804798..485520a5b295c13e58ab8fe1ac00708b77271fac 100644 (file)
@@ -1,11 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * Renesas R-Car System Controller
  *
  * Copyright (C) 2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 #ifndef __SOC_RENESAS_RCAR_SYSC_H__
 #define __SOC_RENESAS_RCAR_SYSC_H__
@@ -52,6 +49,8 @@ struct rcar_sysc_info {
 extern const struct rcar_sysc_info r8a7743_sysc_info;
 extern const struct rcar_sysc_info r8a7745_sysc_info;
 extern const struct rcar_sysc_info r8a77470_sysc_info;
+extern const struct rcar_sysc_info r8a774a1_sysc_info;
+extern const struct rcar_sysc_info r8a774c0_sysc_info;
 extern const struct rcar_sysc_info r8a7779_sysc_info;
 extern const struct rcar_sysc_info r8a7790_sysc_info;
 extern const struct rcar_sysc_info r8a7791_sysc_info;
index d44d0e687ab8adb3bdcf97537d5ac97aade5c6c6..4af96e668a2f1d69f49c0045f56b3b4ea2be6dbf 100644 (file)
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas SoC Identification
  *
  * Copyright (C) 2014-2016 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/io.h>
@@ -46,15 +38,24 @@ static const struct renesas_family fam_rmobile __initconst __maybe_unused = {
        .reg    = 0xe600101c,           /* CCCR (Common Chip Code Register) */
 };
 
-static const struct renesas_family fam_rza __initconst __maybe_unused = {
-       .name   = "RZ/A",
+static const struct renesas_family fam_rza1 __initconst __maybe_unused = {
+       .name   = "RZ/A1",
+};
+
+static const struct renesas_family fam_rza2 __initconst __maybe_unused = {
+       .name   = "RZ/A2",
 };
 
-static const struct renesas_family fam_rzg __initconst __maybe_unused = {
-       .name   = "RZ/G",
+static const struct renesas_family fam_rzg1 __initconst __maybe_unused = {
+       .name   = "RZ/G1",
        .reg    = 0xff000044,           /* PRR (Product Register) */
 };
 
+static const struct renesas_family fam_rzg2 __initconst __maybe_unused = {
+       .name   = "RZ/G2",
+       .reg    = 0xfff00044,           /* PRR (Product Register) */
+};
+
 static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
        .name   = "SH-Mobile",
        .reg    = 0xe600101c,           /* CCCR (Common Chip Code Register) */
@@ -67,7 +68,12 @@ struct renesas_soc {
 };
 
 static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = {
-       .family = &fam_rza,
+       .family = &fam_rza1,
+};
+
+static const struct renesas_soc soc_rz_a2m __initconst __maybe_unused = {
+       .family = &fam_rza2,
+       .id     = 0x3b,
 };
 
 static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = {
@@ -81,30 +87,40 @@ static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = {
 };
 
 static const struct renesas_soc soc_rz_g1h __initconst __maybe_unused = {
-       .family = &fam_rzg,
+       .family = &fam_rzg1,
        .id     = 0x45,
 };
 
 static const struct renesas_soc soc_rz_g1m __initconst __maybe_unused = {
-       .family = &fam_rzg,
+       .family = &fam_rzg1,
        .id     = 0x47,
 };
 
 static const struct renesas_soc soc_rz_g1n __initconst __maybe_unused = {
-       .family = &fam_rzg,
+       .family = &fam_rzg1,
        .id     = 0x4b,
 };
 
 static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = {
-       .family = &fam_rzg,
+       .family = &fam_rzg1,
        .id     = 0x4c,
 };
 
 static const struct renesas_soc soc_rz_g1c __initconst __maybe_unused = {
-       .family = &fam_rzg,
+       .family = &fam_rzg1,
        .id     = 0x53,
 };
 
+static const struct renesas_soc soc_rz_g2m __initconst __maybe_unused = {
+       .family = &fam_rzg2,
+       .id     = 0x52,
+};
+
+static const struct renesas_soc soc_rz_g2e __initconst __maybe_unused = {
+       .family = &fam_rzg2,
+       .id     = 0x57,
+};
+
 static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
        .family = &fam_rcar_gen1,
 };
@@ -184,6 +200,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R7S72100
        { .compatible = "renesas,r7s72100",     .data = &soc_rz_a1h },
 #endif
+#ifdef CONFIG_ARCH_R7S9210
+       { .compatible = "renesas,r7s9210",      .data = &soc_rz_a2m },
+#endif
 #ifdef CONFIG_ARCH_R8A73A4
        { .compatible = "renesas,r8a73a4",      .data = &soc_rmobile_ape6 },
 #endif
@@ -205,6 +224,12 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R8A77470
        { .compatible = "renesas,r8a77470",     .data = &soc_rz_g1c },
 #endif
+#ifdef CONFIG_ARCH_R8A774A1
+       { .compatible = "renesas,r8a774a1",     .data = &soc_rz_g2m },
+#endif
+#ifdef CONFIG_ARCH_R8A774C0
+       { .compatible = "renesas,r8a774c0",     .data = &soc_rz_g2e },
+#endif
 #ifdef CONFIG_ARCH_R8A7778
        { .compatible = "renesas,r8a7778",      .data = &soc_rcar_m1a },
 #endif
@@ -262,7 +287,7 @@ static int __init renesas_soc_init(void)
        void __iomem *chipid = NULL;
        struct soc_device *soc_dev;
        struct device_node *np;
-       unsigned int product;
+       unsigned int product, eshi = 0, eslo;
 
        match = of_match_node(renesas_socs, of_root);
        if (!match)
@@ -271,6 +296,31 @@ static int __init renesas_soc_init(void)
        soc = match->data;
        family = soc->family;
 
+       np = of_find_compatible_node(NULL, NULL, "renesas,bsid");
+       if (np) {
+               chipid = of_iomap(np, 0);
+               of_node_put(np);
+
+               if (chipid) {
+                       product = readl(chipid);
+                       iounmap(chipid);
+
+                       if (soc->id && ((product >> 16) & 0xff) != soc->id) {
+                               pr_warn("SoC mismatch (product = 0x%x)\n",
+                                       product);
+                               return -ENODEV;
+                       }
+               }
+
+               /*
+                * TODO: Upper 4 bits of BSID are for chip version, but the
+                * format is not known at this time so we don't know how to
+                * specify eshi and eslo
+                */
+
+               goto done;
+       }
+
        /* Try PRR first, then hardcoded fallback */
        np = of_find_compatible_node(NULL, NULL, "renesas,prr");
        if (np) {
@@ -289,8 +339,11 @@ static int __init renesas_soc_init(void)
                        pr_warn("SoC mismatch (product = 0x%x)\n", product);
                        return -ENODEV;
                }
+               eshi = ((product >> 4) & 0x0f) + 1;
+               eslo = product & 0xf;
        }
 
+done:
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
        if (!soc_dev_attr)
                return -ENOMEM;
@@ -302,10 +355,9 @@ static int __init renesas_soc_init(void)
        soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
        soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1,
                                             GFP_KERNEL);
-       if (chipid)
-               soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
-                                                  ((product >> 4) & 0x0f) + 1,
-                                                  product & 0xf);
+       if (eshi)
+               soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi,
+                                                  eslo);
 
        pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family,
                soc_dev_attr->soc_id, soc_dev_attr->revision ?: "");
index acbe63e925d597c270b54a846b54791d6c0e3655..1fa840e3d930dcc3058d272e15b3ed85885c49c8 100644 (file)
@@ -33,6 +33,9 @@
 #include <linux/of_address.h>
 #include <linux/of_clk.h>
 #include <linux/of_platform.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/reboot.h>
@@ -45,6 +48,8 @@
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
 
+#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
+
 #define PMC_CNTRL                      0x0
 #define  PMC_CNTRL_INTR_POLARITY       BIT(17) /* inverts INTR polarity */
 #define  PMC_CNTRL_CPU_PWRREQ_OE       BIT(16) /* CPU pwr req enable */
@@ -65,6 +70,8 @@
 
 #define PWRGATE_STATUS                 0x38
 
+#define PMC_IMPL_E_33V_PWR             0x40
+
 #define PMC_PWR_DET                    0x48
 
 #define PMC_SCRATCH0_MODE_RECOVERY     BIT(31)
@@ -135,6 +142,7 @@ struct tegra_io_pad_soc {
        enum tegra_io_pad id;
        unsigned int dpd;
        unsigned int voltage;
+       const char *name;
 };
 
 struct tegra_pmc_regs {
@@ -154,10 +162,14 @@ struct tegra_pmc_soc {
        bool has_tsense_reset;
        bool has_gpu_clamps;
        bool needs_mbist_war;
+       bool has_impl_33v_pwr;
 
        const struct tegra_io_pad_soc *io_pads;
        unsigned int num_io_pads;
 
+       const struct pinctrl_pin_desc *pin_descs;
+       unsigned int num_pin_descs;
+
        const struct tegra_pmc_regs *regs;
        void (*init)(struct tegra_pmc *pmc);
        void (*setup_irq_polarity)(struct tegra_pmc *pmc,
@@ -216,6 +228,8 @@ struct tegra_pmc {
        DECLARE_BITMAP(powergates_available, TEGRA_POWERGATE_MAX);
 
        struct mutex powergates_lock;
+
+       struct pinctrl_dev *pctl_dev;
 };
 
 static struct tegra_pmc *pmc = &(struct tegra_pmc) {
@@ -919,11 +933,12 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
        return NULL;
 }
 
-static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
-                               unsigned long *status, u32 *mask)
+static int tegra_io_pad_get_dpd_register_bit(enum tegra_io_pad id,
+                                            unsigned long *request,
+                                            unsigned long *status,
+                                            u32 *mask)
 {
        const struct tegra_io_pad_soc *pad;
-       unsigned long rate, value;
 
        pad = tegra_io_pad_find(pmc, id);
        if (!pad) {
@@ -944,6 +959,19 @@ static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
                *request = pmc->soc->regs->dpd2_req;
        }
 
+       return 0;
+}
+
+static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
+                               unsigned long *status, u32 *mask)
+{
+       unsigned long rate, value;
+       int err;
+
+       err = tegra_io_pad_get_dpd_register_bit(id, request, status, mask);
+       if (err)
+               return err;
+
        if (pmc->clk) {
                rate = clk_get_rate(pmc->clk);
                if (!rate) {
@@ -1058,8 +1086,22 @@ unlock:
 }
 EXPORT_SYMBOL(tegra_io_pad_power_disable);
 
-int tegra_io_pad_set_voltage(enum tegra_io_pad id,
-                            enum tegra_io_pad_voltage voltage)
+static int tegra_io_pad_is_powered(enum tegra_io_pad id)
+{
+       unsigned long request, status;
+       u32 mask, value;
+       int err;
+
+       err = tegra_io_pad_get_dpd_register_bit(id, &request, &status, &mask);
+       if (err)
+               return err;
+
+       value = tegra_pmc_readl(status);
+
+       return !(value & mask);
+}
+
+static int tegra_io_pad_set_voltage(enum tegra_io_pad id, int voltage)
 {
        const struct tegra_io_pad_soc *pad;
        u32 value;
@@ -1073,20 +1115,31 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id,
 
        mutex_lock(&pmc->powergates_lock);
 
-       /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
-       value = tegra_pmc_readl(PMC_PWR_DET);
-       value |= BIT(pad->voltage);
-       tegra_pmc_writel(value, PMC_PWR_DET);
+       if (pmc->soc->has_impl_33v_pwr) {
+               value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR);
 
-       /* update I/O voltage */
-       value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+               if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
+                       value &= ~BIT(pad->voltage);
+               else
+                       value |= BIT(pad->voltage);
 
-       if (voltage == TEGRA_IO_PAD_1800000UV)
-               value &= ~BIT(pad->voltage);
-       else
+               tegra_pmc_writel(value, PMC_IMPL_E_33V_PWR);
+       } else {
+               /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
+               value = tegra_pmc_readl(PMC_PWR_DET);
                value |= BIT(pad->voltage);
+               tegra_pmc_writel(value, PMC_PWR_DET);
 
-       tegra_pmc_writel(value, PMC_PWR_DET_VALUE);
+               /* update I/O voltage */
+               value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+
+               if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
+                       value &= ~BIT(pad->voltage);
+               else
+                       value |= BIT(pad->voltage);
+
+               tegra_pmc_writel(value, PMC_PWR_DET_VALUE);
+       }
 
        mutex_unlock(&pmc->powergates_lock);
 
@@ -1094,9 +1147,8 @@ int tegra_io_pad_set_voltage(enum tegra_io_pad id,
 
        return 0;
 }
-EXPORT_SYMBOL(tegra_io_pad_set_voltage);
 
-int tegra_io_pad_get_voltage(enum tegra_io_pad id)
+static int tegra_io_pad_get_voltage(enum tegra_io_pad id)
 {
        const struct tegra_io_pad_soc *pad;
        u32 value;
@@ -1108,14 +1160,16 @@ int tegra_io_pad_get_voltage(enum tegra_io_pad id)
        if (pad->voltage == UINT_MAX)
                return -ENOTSUPP;
 
-       value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
+       if (pmc->soc->has_impl_33v_pwr)
+               value = tegra_pmc_readl(PMC_IMPL_E_33V_PWR);
+       else
+               value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
 
        if ((value & BIT(pad->voltage)) == 0)
-               return TEGRA_IO_PAD_1800000UV;
+               return TEGRA_IO_PAD_VOLTAGE_1V8;
 
-       return TEGRA_IO_PAD_3300000UV;
+       return TEGRA_IO_PAD_VOLTAGE_3V3;
 }
-EXPORT_SYMBOL(tegra_io_pad_get_voltage);
 
 /**
  * tegra_io_rail_power_on() - enable power to I/O rail
@@ -1288,7 +1342,7 @@ static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
        if (!pmc->soc->has_tsense_reset)
                return;
 
-       np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip");
+       np = of_get_child_by_name(pmc->dev->of_node, "i2c-thermtrip");
        if (!np) {
                dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
                return;
@@ -1353,6 +1407,142 @@ out:
        of_node_put(np);
 }
 
+static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev)
+{
+       return pmc->soc->num_io_pads;
+}
+
+static const char *tegra_io_pad_pinctrl_get_group_name(
+               struct pinctrl_dev *pctl, unsigned int group)
+{
+       return pmc->soc->io_pads[group].name;
+}
+
+static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev,
+                                              unsigned int group,
+                                              const unsigned int **pins,
+                                              unsigned int *num_pins)
+{
+       *pins = &pmc->soc->io_pads[group].id;
+       *num_pins = 1;
+       return 0;
+}
+
+static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = {
+       .get_groups_count = tegra_io_pad_pinctrl_get_groups_count,
+       .get_group_name = tegra_io_pad_pinctrl_get_group_name,
+       .get_group_pins = tegra_io_pad_pinctrl_get_group_pins,
+       .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+       .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev,
+                                   unsigned int pin, unsigned long *config)
+{
+       const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin);
+       enum pin_config_param param = pinconf_to_config_param(*config);
+       int ret;
+       u32 arg;
+
+       if (!pad)
+               return -EINVAL;
+
+       switch (param) {
+       case PIN_CONFIG_POWER_SOURCE:
+               ret = tegra_io_pad_get_voltage(pad->id);
+               if (ret < 0)
+                       return ret;
+               arg = ret;
+               break;
+       case PIN_CONFIG_LOW_POWER_MODE:
+               ret = tegra_io_pad_is_powered(pad->id);
+               if (ret < 0)
+                       return ret;
+               arg = !ret;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       *config = pinconf_to_config_packed(param, arg);
+
+       return 0;
+}
+
+static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev,
+                                   unsigned int pin, unsigned long *configs,
+                                   unsigned int num_configs)
+{
+       const struct tegra_io_pad_soc *pad = tegra_io_pad_find(pmc, pin);
+       enum pin_config_param param;
+       unsigned int i;
+       int err;
+       u32 arg;
+
+       if (!pad)
+               return -EINVAL;
+
+       for (i = 0; i < num_configs; ++i) {
+               param = pinconf_to_config_param(configs[i]);
+               arg = pinconf_to_config_argument(configs[i]);
+
+               switch (param) {
+               case PIN_CONFIG_LOW_POWER_MODE:
+                       if (arg)
+                               err = tegra_io_pad_power_disable(pad->id);
+                       else
+                               err = tegra_io_pad_power_enable(pad->id);
+                       if (err)
+                               return err;
+                       break;
+               case PIN_CONFIG_POWER_SOURCE:
+                       if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 &&
+                           arg != TEGRA_IO_PAD_VOLTAGE_3V3)
+                               return -EINVAL;
+                       err = tegra_io_pad_set_voltage(pad->id, arg);
+                       if (err)
+                               return err;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static const struct pinconf_ops tegra_io_pad_pinconf_ops = {
+       .pin_config_get = tegra_io_pad_pinconf_get,
+       .pin_config_set = tegra_io_pad_pinconf_set,
+       .is_generic = true,
+};
+
+static struct pinctrl_desc tegra_pmc_pctl_desc = {
+       .pctlops = &tegra_io_pad_pinctrl_ops,
+       .confops = &tegra_io_pad_pinconf_ops,
+};
+
+static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
+{
+       int err = 0;
+
+       if (!pmc->soc->num_pin_descs)
+               return 0;
+
+       tegra_pmc_pctl_desc.name = dev_name(pmc->dev);
+       tegra_pmc_pctl_desc.pins = pmc->soc->pin_descs;
+       tegra_pmc_pctl_desc.npins = pmc->soc->num_pin_descs;
+
+       pmc->pctl_dev = devm_pinctrl_register(pmc->dev, &tegra_pmc_pctl_desc,
+                                             pmc);
+       if (IS_ERR(pmc->pctl_dev)) {
+               err = PTR_ERR(pmc->pctl_dev);
+               dev_err(pmc->dev, "unable to register pinctrl, %d\n", err);
+       }
+
+       return err;
+}
+
 static int tegra_pmc_probe(struct platform_device *pdev)
 {
        void __iomem *base;
@@ -1430,18 +1620,27 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 
        err = register_restart_handler(&tegra_pmc_restart_handler);
        if (err) {
-               debugfs_remove(pmc->debugfs);
                dev_err(&pdev->dev, "unable to register restart handler, %d\n",
                        err);
-               return err;
+               goto cleanup_debugfs;
        }
 
+       err = tegra_pmc_pinctrl_init(pmc);
+       if (err)
+               goto cleanup_restart_handler;
+
        mutex_lock(&pmc->powergates_lock);
        iounmap(pmc->base);
        pmc->base = base;
        mutex_unlock(&pmc->powergates_lock);
 
        return 0;
+
+cleanup_restart_handler:
+       unregister_restart_handler(&tegra_pmc_restart_handler);
+cleanup_debugfs:
+       debugfs_remove(pmc->debugfs);
+       return err;
 }
 
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
@@ -1531,6 +1730,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
        .has_gpu_clamps = false,
        .num_io_pads = 0,
        .io_pads = NULL,
+       .num_pin_descs = 0,
+       .pin_descs = NULL,
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1567,8 +1768,11 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
        .cpu_powergates = tegra30_cpu_powergates,
        .has_tsense_reset = true,
        .has_gpu_clamps = false,
+       .has_impl_33v_pwr = false,
        .num_io_pads = 0,
        .io_pads = NULL,
+       .num_pin_descs = 0,
+       .pin_descs = NULL,
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1609,8 +1813,11 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
        .cpu_powergates = tegra114_cpu_powergates,
        .has_tsense_reset = true,
        .has_gpu_clamps = false,
+       .has_impl_33v_pwr = false,
        .num_io_pads = 0,
        .io_pads = NULL,
+       .num_pin_descs = 0,
+       .pin_descs = NULL,
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1649,37 +1856,59 @@ static const u8 tegra124_cpu_powergates[] = {
        TEGRA_POWERGATE_CPU3,
 };
 
+#define TEGRA_IO_PAD(_id, _dpd, _voltage, _name)       \
+       ((struct tegra_io_pad_soc) {                    \
+               .id     = (_id),                        \
+               .dpd    = (_dpd),                       \
+               .voltage = (_voltage),                  \
+               .name   = (_name),                      \
+       })
+
+#define TEGRA_IO_PIN_DESC(_id, _dpd, _voltage, _name)  \
+       ((struct pinctrl_pin_desc) {                    \
+               .number = (_id),                        \
+               .name   = (_name)                       \
+       })
+
+#define TEGRA124_IO_PAD_TABLE(_pad)                                    \
+       /* .id                          .dpd    .voltage  .name */      \
+       _pad(TEGRA_IO_PAD_AUDIO,        17,     UINT_MAX, "audio"),     \
+       _pad(TEGRA_IO_PAD_BB,           15,     UINT_MAX, "bb"),        \
+       _pad(TEGRA_IO_PAD_CAM,          36,     UINT_MAX, "cam"),       \
+       _pad(TEGRA_IO_PAD_COMP,         22,     UINT_MAX, "comp"),      \
+       _pad(TEGRA_IO_PAD_CSIA,         0,      UINT_MAX, "csia"),      \
+       _pad(TEGRA_IO_PAD_CSIB,         1,      UINT_MAX, "csb"),       \
+       _pad(TEGRA_IO_PAD_CSIE,         44,     UINT_MAX, "cse"),       \
+       _pad(TEGRA_IO_PAD_DSI,          2,      UINT_MAX, "dsi"),       \
+       _pad(TEGRA_IO_PAD_DSIB,         39,     UINT_MAX, "dsib"),      \
+       _pad(TEGRA_IO_PAD_DSIC,         40,     UINT_MAX, "dsic"),      \
+       _pad(TEGRA_IO_PAD_DSID,         41,     UINT_MAX, "dsid"),      \
+       _pad(TEGRA_IO_PAD_HDMI,         28,     UINT_MAX, "hdmi"),      \
+       _pad(TEGRA_IO_PAD_HSIC,         19,     UINT_MAX, "hsic"),      \
+       _pad(TEGRA_IO_PAD_HV,           38,     UINT_MAX, "hv"),        \
+       _pad(TEGRA_IO_PAD_LVDS,         57,     UINT_MAX, "lvds"),      \
+       _pad(TEGRA_IO_PAD_MIPI_BIAS,    3,      UINT_MAX, "mipi-bias"), \
+       _pad(TEGRA_IO_PAD_NAND,         13,     UINT_MAX, "nand"),      \
+       _pad(TEGRA_IO_PAD_PEX_BIAS,     4,      UINT_MAX, "pex-bias"),  \
+       _pad(TEGRA_IO_PAD_PEX_CLK1,     5,      UINT_MAX, "pex-clk1"),  \
+       _pad(TEGRA_IO_PAD_PEX_CLK2,     6,      UINT_MAX, "pex-clk2"),  \
+       _pad(TEGRA_IO_PAD_PEX_CNTRL,    32,     UINT_MAX, "pex-cntrl"), \
+       _pad(TEGRA_IO_PAD_SDMMC1,       33,     UINT_MAX, "sdmmc1"),    \
+       _pad(TEGRA_IO_PAD_SDMMC3,       34,     UINT_MAX, "sdmmc3"),    \
+       _pad(TEGRA_IO_PAD_SDMMC4,       35,     UINT_MAX, "sdmmc4"),    \
+       _pad(TEGRA_IO_PAD_SYS_DDC,      58,     UINT_MAX, "sys_ddc"),   \
+       _pad(TEGRA_IO_PAD_UART,         14,     UINT_MAX, "uart"),      \
+       _pad(TEGRA_IO_PAD_USB0,         9,      UINT_MAX, "usb0"),      \
+       _pad(TEGRA_IO_PAD_USB1,         10,     UINT_MAX, "usb1"),      \
+       _pad(TEGRA_IO_PAD_USB2,         11,     UINT_MAX, "usb2"),      \
+       _pad(TEGRA_IO_PAD_USB_BIAS,     12,     UINT_MAX, "usb_bias")
+
 static const struct tegra_io_pad_soc tegra124_io_pads[] = {
-       { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_BB, .dpd = 15, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_COMP, .dpd = 22, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HV, .dpd = 38, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_NAND, .dpd = 13, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 35, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SYS_DDC, .dpd = 58, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
+       TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD)
+};
+
+static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
+       TEGRA124_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
 };
 
 static const struct tegra_pmc_soc tegra124_pmc_soc = {
@@ -1689,8 +1918,11 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
        .cpu_powergates = tegra124_cpu_powergates,
        .has_tsense_reset = true,
        .has_gpu_clamps = true,
+       .has_impl_33v_pwr = false,
        .num_io_pads = ARRAY_SIZE(tegra124_io_pads),
        .io_pads = tegra124_io_pads,
+       .num_pin_descs = ARRAY_SIZE(tegra124_pin_descs),
+       .pin_descs = tegra124_pin_descs,
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
@@ -1730,45 +1962,53 @@ static const u8 tegra210_cpu_powergates[] = {
        TEGRA_POWERGATE_CPU3,
 };
 
+#define TEGRA210_IO_PAD_TABLE(_pad)                                       \
+       /*   .id                        .dpd     .voltage  .name */        \
+       _pad(TEGRA_IO_PAD_AUDIO,       17,       5,        "audio"),       \
+       _pad(TEGRA_IO_PAD_AUDIO_HV,    61,       18,       "audio-hv"),    \
+       _pad(TEGRA_IO_PAD_CAM,         36,       10,       "cam"),         \
+       _pad(TEGRA_IO_PAD_CSIA,        0,        UINT_MAX, "csia"),        \
+       _pad(TEGRA_IO_PAD_CSIB,        1,        UINT_MAX, "csib"),        \
+       _pad(TEGRA_IO_PAD_CSIC,        42,       UINT_MAX, "csic"),        \
+       _pad(TEGRA_IO_PAD_CSID,        43,       UINT_MAX, "csid"),        \
+       _pad(TEGRA_IO_PAD_CSIE,        44,       UINT_MAX, "csie"),        \
+       _pad(TEGRA_IO_PAD_CSIF,        45,       UINT_MAX, "csif"),        \
+       _pad(TEGRA_IO_PAD_DBG,         25,       19,       "dbg"),         \
+       _pad(TEGRA_IO_PAD_DEBUG_NONAO, 26,       UINT_MAX, "debug-nonao"), \
+       _pad(TEGRA_IO_PAD_DMIC,        50,       20,       "dmic"),        \
+       _pad(TEGRA_IO_PAD_DP,          51,       UINT_MAX, "dp"),          \
+       _pad(TEGRA_IO_PAD_DSI,         2,        UINT_MAX, "dsi"),         \
+       _pad(TEGRA_IO_PAD_DSIB,        39,       UINT_MAX, "dsib"),        \
+       _pad(TEGRA_IO_PAD_DSIC,        40,       UINT_MAX, "dsic"),        \
+       _pad(TEGRA_IO_PAD_DSID,        41,       UINT_MAX, "dsid"),        \
+       _pad(TEGRA_IO_PAD_EMMC,        35,       UINT_MAX, "emmc"),        \
+       _pad(TEGRA_IO_PAD_EMMC2,       37,       UINT_MAX, "emmc2"),       \
+       _pad(TEGRA_IO_PAD_GPIO,        27,       21,       "gpio"),        \
+       _pad(TEGRA_IO_PAD_HDMI,        28,       UINT_MAX, "hdmi"),        \
+       _pad(TEGRA_IO_PAD_HSIC,        19,       UINT_MAX, "hsic"),        \
+       _pad(TEGRA_IO_PAD_LVDS,        57,       UINT_MAX, "lvds"),        \
+       _pad(TEGRA_IO_PAD_MIPI_BIAS,   3,        UINT_MAX, "mipi-bias"),   \
+       _pad(TEGRA_IO_PAD_PEX_BIAS,    4,        UINT_MAX, "pex-bias"),    \
+       _pad(TEGRA_IO_PAD_PEX_CLK1,    5,        UINT_MAX, "pex-clk1"),    \
+       _pad(TEGRA_IO_PAD_PEX_CLK2,    6,        UINT_MAX, "pex-clk2"),    \
+       _pad(TEGRA_IO_PAD_PEX_CNTRL,   UINT_MAX, 11,       "pex-cntrl"),   \
+       _pad(TEGRA_IO_PAD_SDMMC1,      33,       12,       "sdmmc1"),      \
+       _pad(TEGRA_IO_PAD_SDMMC3,      34,       13,       "sdmmc3"),      \
+       _pad(TEGRA_IO_PAD_SPI,         46,       22,       "spi"),         \
+       _pad(TEGRA_IO_PAD_SPI_HV,      47,       23,       "spi-hv"),      \
+       _pad(TEGRA_IO_PAD_UART,        14,       2,        "uart"),        \
+       _pad(TEGRA_IO_PAD_USB0,        9,        UINT_MAX, "usb0"),        \
+       _pad(TEGRA_IO_PAD_USB1,        10,       UINT_MAX, "usb1"),        \
+       _pad(TEGRA_IO_PAD_USB2,        11,       UINT_MAX, "usb2"),        \
+       _pad(TEGRA_IO_PAD_USB3,        18,       UINT_MAX, "usb3"),        \
+       _pad(TEGRA_IO_PAD_USB_BIAS,    12,       UINT_MAX, "usb-bias")
+
 static const struct tegra_io_pad_soc tegra210_io_pads[] = {
-       { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = 5 },
-       { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 18 },
-       { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = 10 },
-       { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIC, .dpd = 42, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSID, .dpd = 43, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIF, .dpd = 45, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = 19 },
-       { .id = TEGRA_IO_PAD_DEBUG_NONAO, .dpd = 26, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DMIC, .dpd = 50, .voltage = 20 },
-       { .id = TEGRA_IO_PAD_DP, .dpd = 51, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_EMMC, .dpd = 35, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_EMMC2, .dpd = 37, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_GPIO, .dpd = 27, .voltage = 21 },
-       { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = UINT_MAX, .voltage = 11 },
-       { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = 12 },
-       { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = 13 },
-       { .id = TEGRA_IO_PAD_SPI, .dpd = 46, .voltage = 22 },
-       { .id = TEGRA_IO_PAD_SPI_HV, .dpd = 47, .voltage = 23 },
-       { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = 2 },
-       { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB3, .dpd = 18, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
+       TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD)
+};
+
+static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
+       TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
 };
 
 static const struct tegra_pmc_soc tegra210_pmc_soc = {
@@ -1778,52 +2018,64 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
        .cpu_powergates = tegra210_cpu_powergates,
        .has_tsense_reset = true,
        .has_gpu_clamps = true,
+       .has_impl_33v_pwr = false,
        .needs_mbist_war = true,
        .num_io_pads = ARRAY_SIZE(tegra210_io_pads),
        .io_pads = tegra210_io_pads,
+       .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
+       .pin_descs = tegra210_pin_descs,
        .regs = &tegra20_pmc_regs,
        .init = tegra20_pmc_init,
        .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
 };
 
+#define TEGRA186_IO_PAD_TABLE(_pad)                                         \
+       /*   .id                        .dpd      .voltage  .name */         \
+       _pad(TEGRA_IO_PAD_CSIA,         0,        UINT_MAX, "csia"),         \
+       _pad(TEGRA_IO_PAD_CSIB,         1,        UINT_MAX, "csib"),         \
+       _pad(TEGRA_IO_PAD_DSI,          2,        UINT_MAX, "dsi"),          \
+       _pad(TEGRA_IO_PAD_MIPI_BIAS,    3,        UINT_MAX, "mipi-bias"),    \
+       _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4,        UINT_MAX, "pex-clk-bias"), \
+       _pad(TEGRA_IO_PAD_PEX_CLK3,     5,        UINT_MAX, "pex-clk3"),     \
+       _pad(TEGRA_IO_PAD_PEX_CLK2,     6,        UINT_MAX, "pex-clk2"),     \
+       _pad(TEGRA_IO_PAD_PEX_CLK1,     7,        UINT_MAX, "pex-clk1"),     \
+       _pad(TEGRA_IO_PAD_USB0,         9,        UINT_MAX, "usb0"),         \
+       _pad(TEGRA_IO_PAD_USB1,         10,       UINT_MAX, "usb1"),         \
+       _pad(TEGRA_IO_PAD_USB2,         11,       UINT_MAX, "usb2"),         \
+       _pad(TEGRA_IO_PAD_USB_BIAS,     12,       UINT_MAX, "usb-bias"),     \
+       _pad(TEGRA_IO_PAD_UART,         14,       UINT_MAX, "uart"),         \
+       _pad(TEGRA_IO_PAD_AUDIO,        17,       UINT_MAX, "audio"),        \
+       _pad(TEGRA_IO_PAD_HSIC,         19,       UINT_MAX, "hsic"),         \
+       _pad(TEGRA_IO_PAD_DBG,          25,       UINT_MAX, "dbg"),          \
+       _pad(TEGRA_IO_PAD_HDMI_DP0,     28,       UINT_MAX, "hdmi-dp0"),     \
+       _pad(TEGRA_IO_PAD_HDMI_DP1,     29,       UINT_MAX, "hdmi-dp1"),     \
+       _pad(TEGRA_IO_PAD_PEX_CNTRL,    32,       UINT_MAX, "pex-cntrl"),    \
+       _pad(TEGRA_IO_PAD_SDMMC2_HV,    34,       5,        "sdmmc2-hv"),    \
+       _pad(TEGRA_IO_PAD_SDMMC4,       36,       UINT_MAX, "sdmmc4"),       \
+       _pad(TEGRA_IO_PAD_CAM,          38,       UINT_MAX, "cam"),          \
+       _pad(TEGRA_IO_PAD_DSIB,         40,       UINT_MAX, "dsib"),         \
+       _pad(TEGRA_IO_PAD_DSIC,         41,       UINT_MAX, "dsic"),         \
+       _pad(TEGRA_IO_PAD_DSID,         42,       UINT_MAX, "dsid"),         \
+       _pad(TEGRA_IO_PAD_CSIC,         43,       UINT_MAX, "csic"),         \
+       _pad(TEGRA_IO_PAD_CSID,         44,       UINT_MAX, "csid"),         \
+       _pad(TEGRA_IO_PAD_CSIE,         45,       UINT_MAX, "csie"),         \
+       _pad(TEGRA_IO_PAD_CSIF,         46,       UINT_MAX, "csif"),         \
+       _pad(TEGRA_IO_PAD_SPI,          47,       UINT_MAX, "spi"),          \
+       _pad(TEGRA_IO_PAD_UFS,          49,       UINT_MAX, "ufs"),          \
+       _pad(TEGRA_IO_PAD_DMIC_HV,      52,       2,        "dmic-hv"),      \
+       _pad(TEGRA_IO_PAD_EDP,          53,       UINT_MAX, "edp"),          \
+       _pad(TEGRA_IO_PAD_SDMMC1_HV,    55,       4,        "sdmmc1-hv"),    \
+       _pad(TEGRA_IO_PAD_SDMMC3_HV,    56,       6,        "sdmmc3-hv"),    \
+       _pad(TEGRA_IO_PAD_CONN,         60,       UINT_MAX, "conn"),         \
+       _pad(TEGRA_IO_PAD_AUDIO_HV,     61,       1,        "audio-hv"),     \
+       _pad(TEGRA_IO_PAD_AO_HV,        UINT_MAX, 0,        "ao-hv")
+
 static const struct tegra_io_pad_soc tegra186_io_pads[] = {
-       { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK_BIAS, .dpd = 4, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK3, .dpd = 5, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 7, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HDMI_DP0, .dpd = 28, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_HDMI_DP1, .dpd = 29, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC2_HV, .dpd = 34, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 36, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CAM, .dpd = 38, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSIB, .dpd = 40, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSIC, .dpd = 41, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DSID, .dpd = 42, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIC, .dpd = 43, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSID, .dpd = 44, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIE, .dpd = 45, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CSIF, .dpd = 46, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SPI, .dpd = 47, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_UFS, .dpd = 49, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_DMIC_HV, .dpd = 52, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_EDP, .dpd = 53, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC1_HV, .dpd = 55, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_SDMMC3_HV, .dpd = 56, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_CONN, .dpd = 60, .voltage = UINT_MAX },
-       { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = UINT_MAX },
+       TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD)
+};
+
+static const struct pinctrl_pin_desc tegra186_pin_descs[] = {
+       TEGRA186_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
 };
 
 static const struct tegra_pmc_regs tegra186_pmc_regs = {
@@ -1876,8 +2128,11 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
        .cpu_powergates = NULL,
        .has_tsense_reset = false,
        .has_gpu_clamps = false,
+       .has_impl_33v_pwr = true,
        .num_io_pads = ARRAY_SIZE(tegra186_io_pads),
        .io_pads = tegra186_io_pads,
+       .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
+       .pin_descs = tegra186_pin_descs,
        .regs = &tegra186_pmc_regs,
        .init = NULL,
        .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
index bbd4e5bc8707ff4601a39783f74ec94fd822ea0b..e05ab16d9a9e3c10224e93745f57f1d477616a22 100644 (file)
@@ -438,7 +438,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
 
        chan_num = of_channel_match_helper(dev->of_node, name, &instance);
        if (chan_num < 0) {
-               dev_err(kdev->dev, "No DMA instace with name %s\n", name);
+               dev_err(kdev->dev, "No DMA instance with name %s\n", name);
                return (void *)-EINVAL;
        }
 
@@ -461,7 +461,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name,
                }
        }
        if (!found) {
-               dev_err(kdev->dev, "No DMA instace with name %s\n", instance);
+               dev_err(kdev->dev, "No DMA instance with name %s\n", instance);
                return (void *)-EINVAL;
        }
 
index 3efc47e82973b43ff7431bdacad428aea757bffc..7c128132799e0cd355c7bae1298d5a776b6c8ec9 100644 (file)
@@ -240,14 +240,14 @@ struct knav_pool {
 };
 
 /**
- * struct knav_queue_inst:             qmss queue instace properties
+ * struct knav_queue_inst:             qmss queue instance properties
  * @descs:                             descriptor pointer
  * @desc_head, desc_tail, desc_count:  descriptor counters
  * @acc:                               accumulator channel pointer
  * @kdev:                              qmss device pointer
  * @range:                             range info
  * @qmgr:                              queue manager info
- * @id:                                        queue instace id
+ * @id:                                        queue instance id
  * @irq_num:                           irq line number
  * @notify_needed:                     notifier needed based on queue type
  * @num_notifiers:                     total notifiers
@@ -274,7 +274,7 @@ struct knav_queue_inst {
 /**
  * struct knav_queue:                  qmss queue properties
  * @reg_push, reg_pop, reg_peek:       push, pop queue registers
- * @inst:                              qmss queue instace properties
+ * @inst:                              qmss queue instance properties
  * @notifier_fn:                       notifier function
  * @notifier_fn_arg:                   notifier function argument
  * @notifier_enabled:                  notier enabled for a give queue
index 1abf76be2aa8c7c49f867bc09dbbf68ca374a4d3..7c015536360dd871c266080128cd1b601bb340a0 100644 (file)
@@ -80,8 +80,6 @@ source "drivers/staging/netlogic/Kconfig"
 
 source "drivers/staging/mt29f_spinand/Kconfig"
 
-source "drivers/staging/dgnc/Kconfig"
-
 source "drivers/staging/gs_fpgaboot/Kconfig"
 
 source "drivers/staging/unisys/Kconfig"
index ab0cbe8815b1c1b6112c2dfd93c06bd508dd92e9..a79b3fe20cf05c84f4def5e17e37aeded54b0cdf 100644 (file)
@@ -29,7 +29,6 @@ obj-$(CONFIG_STAGING_BOARD)   += board/
 obj-$(CONFIG_LTE_GDM724X)      += gdm724x/
 obj-$(CONFIG_FIREWIRE_SERIAL)  += fwserial/
 obj-$(CONFIG_GOLDFISH)         += goldfish/
-obj-$(CONFIG_DGNC)                     += dgnc/
 obj-$(CONFIG_MTD_SPINAND_MT29F)        += mt29f_spinand/
 obj-$(CONFIG_GS_FPGABOOT)      += gs_fpgaboot/
 obj-$(CONFIG_UNISYSSPAR)       += unisys/
index c16dd16afe6a92d504ec4455d872228cfd8d9991..0fdda6f629533d4de97549aecc1d1751490a5190 100644 (file)
@@ -1,6 +1,6 @@
 menuconfig ION
        bool "Ion Memory Manager"
-       depends on HAVE_MEMBLOCK && HAS_DMA && MMU
+       depends on HAS_DMA && MMU
        select GENERIC_ALLOCATOR
        select DMA_SHARED_BUFFER
        help
index 16cbd38a7160d78f80d05c2307a85d4ecdba89d1..c006fc1e5a168bfbc49f5057de7cfb1a7c098904 100644 (file)
@@ -157,8 +157,6 @@ struct ion_heap_ops {
  * @lock:              protects the free list
  * @waitqueue:         queue to wait on from deferred free thread
  * @task:              task struct of deferred free thread
- * @debug_show:                called when heap debug file is read to add any
- *                     heap specific debug info to output
  *
  * Represents a pool of memory from which buffers can be made.  In some
  * systems the only heap is regular system memory allocated via vmalloc.
@@ -179,9 +177,6 @@ struct ion_heap {
        spinlock_t free_lock;
        wait_queue_head_t waitqueue;
        struct task_struct *task;
-
-       int (*debug_show)(struct ion_heap *heap, struct seq_file *s,
-                         void *unused);
 };
 
 /**
index 701eb9f3b0f134f054740a98385336f6a5438821..548bb02c0ca6b049aa0f9949368931b4460b7994 100644 (file)
@@ -212,29 +212,6 @@ static struct ion_heap_ops system_heap_ops = {
        .shrink = ion_system_heap_shrink,
 };
 
-static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
-                                     void *unused)
-{
-       struct ion_system_heap *sys_heap = container_of(heap,
-                                                       struct ion_system_heap,
-                                                       heap);
-       int i;
-       struct ion_page_pool *pool;
-
-       for (i = 0; i < NUM_ORDERS; i++) {
-               pool = sys_heap->pools[i];
-
-               seq_printf(s, "%d order %u highmem pages %lu total\n",
-                          pool->high_count, pool->order,
-                          (PAGE_SIZE << pool->order) * pool->high_count);
-               seq_printf(s, "%d order %u lowmem pages %lu total\n",
-                          pool->low_count, pool->order,
-                          (PAGE_SIZE << pool->order) * pool->low_count);
-       }
-
-       return 0;
-}
-
 static void ion_system_heap_destroy_pools(struct ion_page_pool **pools)
 {
        int i;
@@ -281,7 +258,6 @@ static struct ion_heap *__ion_system_heap_create(void)
        if (ion_system_heap_create_pools(heap->pools))
                goto free_heap;
 
-       heap->heap.debug_show = ion_system_heap_debug_show;
        return &heap->heap;
 
 free_heap:
index abeee0ecc122e7e48ce84cf33e1c95b442b26687..c18bf31f55b6daf1aa480cc885615ec756ddcdf3 100644 (file)
@@ -27,8 +27,6 @@
 #include <linux/interrupt.h>
 #include <linux/param.h>
 #include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/cdev.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/jiffies.h>
@@ -364,11 +362,11 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
                 * if nothing is currently available
                 */
                spin_lock_irq(&fifo->read_queue_lock);
-               ret = wait_event_interruptible_lock_irq_timeout(
-                       fifo->read_queue,
-                       ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
-                       fifo->read_queue_lock,
-                       (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
+               ret = wait_event_interruptible_lock_irq_timeout
+                       (fifo->read_queue,
+                        ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
+                        fifo->read_queue_lock,
+                        (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
                                MAX_SCHEDULE_TIMEOUT);
                spin_unlock_irq(&fifo->read_queue_lock);
 
@@ -482,12 +480,12 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
                 * currently enough room in the fifo
                 */
                spin_lock_irq(&fifo->write_queue_lock);
-               ret = wait_event_interruptible_lock_irq_timeout(
-                       fifo->write_queue,
-                       ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
+               ret = wait_event_interruptible_lock_irq_timeout
+                       (fifo->write_queue,
+                        ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
                                >= words_to_write,
-                       fifo->write_queue_lock,
-                       (write_timeout >= 0) ? msecs_to_jiffies(write_timeout) :
+                        fifo->write_queue_lock,
+                        (write_timeout >= 0) ? msecs_to_jiffies(write_timeout) :
                                MAX_SCHEDULE_TIMEOUT);
                spin_unlock_irq(&fifo->write_queue_lock);
 
@@ -1089,6 +1087,8 @@ static int __init axis_fifo_init(void)
        pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
                read_timeout, write_timeout);
        axis_fifo_driver_class = class_create(THIS_MODULE, DRIVER_NAME);
+       if (IS_ERR(axis_fifo_driver_class))
+               return PTR_ERR(axis_fifo_driver_class);
        return platform_driver_register(&axis_fifo_driver);
 }
 
index cae7e6e695b0ca623797ffc989a8999c101d7e22..15b7a82f4b1e09b718080a99bae9a16d46b5e358 100644 (file)
@@ -199,10 +199,10 @@ static int clk_wzrd_probe(struct platform_device *pdev)
                ret = -ENOMEM;
                goto err_disable_clk;
        }
-       clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor(
-                       &pdev->dev, clk_name,
-                       __clk_get_name(clk_wzrd->clk_in1),
-                       0, reg, 1);
+       clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor
+                       (&pdev->dev, clk_name,
+                        __clk_get_name(clk_wzrd->clk_in1),
+                        0, reg, 1);
        kfree(clk_name);
        if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) {
                dev_err(&pdev->dev, "unable to register fixed-factor clock\n");
@@ -219,10 +219,10 @@ static int clk_wzrd_probe(struct platform_device *pdev)
                goto err_rm_int_clk;
        }
 
-       clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor(
-                       &pdev->dev, clk_name,
-                       __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
-                       0, 1, reg);
+       clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor
+                       (&pdev->dev, clk_name,
+                        __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
+                        0, 1, reg);
        if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) {
                dev_err(&pdev->dev, "unable to register divider clock\n");
                ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
@@ -243,8 +243,8 @@ static int clk_wzrd_probe(struct platform_device *pdev)
                reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(2) + i * 12);
                reg &= WZRD_CLKOUT_DIVIDE_MASK;
                reg >>= WZRD_CLKOUT_DIVIDE_SHIFT;
-               clk_wzrd->clkout[i] = clk_register_fixed_factor(&pdev->dev,
-                               clkout_name, clk_name, 0, 1, reg);
+               clk_wzrd->clkout[i] = clk_register_fixed_factor
+                       (&pdev->dev, clkout_name, clk_name, 0, 1, reg);
                if (IS_ERR(clk_wzrd->clkout[i])) {
                        int j;
 
index 583bce9bb18e3709c12481f5a5f602be0980b1d8..9ab1ee7d36bf99e041a3dfa69bddef791a16f6cd 100644 (file)
@@ -1313,5 +1313,9 @@ config COMEDI_NI_LABPC_ISADMA
 
 config COMEDI_NI_TIO
        tristate
+       select COMEDI_NI_ROUTING
+
+config COMEDI_NI_ROUTING
+       tristate
 
 endif # COMEDI
index bb961ac79b7e925d5e322d55d1e0a3bca8ff43a7..e90b1777528403ea43e3d575b17e90c363f5b9e4 100644 (file)
 #define INSN_WRITE             (1 | INSN_MASK_WRITE)
 #define INSN_BITS              (2 | INSN_MASK_READ | INSN_MASK_WRITE)
 #define INSN_CONFIG            (3 | INSN_MASK_READ | INSN_MASK_WRITE)
+#define INSN_DEVICE_CONFIG     (INSN_CONFIG | INSN_MASK_SPECIAL)
 #define INSN_GTOD              (4 | INSN_MASK_READ | INSN_MASK_SPECIAL)
 #define INSN_WAIT              (5 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
 #define INSN_INTTRIG           (6 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
@@ -301,6 +302,8 @@ enum comedi_io_direction {
  * @INSN_CONFIG_PWM_SET_H_BRIDGE: Set PWM H bridge duty cycle and polarity for
  *                             a relay simultaneously.
  * @INSN_CONFIG_PWM_GET_H_BRIDGE: Get PWM H bridge duty cycle and polarity.
+ * @INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS: Get the hardware timing restraints,
+ *                             regardless of trigger sources.
  */
 enum configuration_ids {
        INSN_CONFIG_DIO_INPUT = COMEDI_INPUT,
@@ -344,7 +347,25 @@ enum configuration_ids {
        INSN_CONFIG_PWM_GET_PERIOD = 5001,
        INSN_CONFIG_GET_PWM_STATUS = 5002,
        INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
-       INSN_CONFIG_PWM_GET_H_BRIDGE = 5004
+       INSN_CONFIG_PWM_GET_H_BRIDGE = 5004,
+       INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS = 5005,
+};
+
+/**
+ * enum device_configuration_ids - COMEDI configuration instruction codes global
+ * to an entire device.
+ * @INSN_DEVICE_CONFIG_TEST_ROUTE:     Validate the possibility of a
+ *                                     globally-named route
+ * @INSN_DEVICE_CONFIG_CONNECT_ROUTE:  Connect a globally-named route
+ * @INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:Disconnect a globally-named route
+ * @INSN_DEVICE_CONFIG_GET_ROUTES:     Get a list of all globally-named routes
+ *                                     that are valid for a particular device.
+ */
+enum device_config_route_ids {
+       INSN_DEVICE_CONFIG_TEST_ROUTE = 0,
+       INSN_DEVICE_CONFIG_CONNECT_ROUTE = 1,
+       INSN_DEVICE_CONFIG_DISCONNECT_ROUTE = 2,
+       INSN_DEVICE_CONFIG_GET_ROUTES = 3,
 };
 
 /**
@@ -928,6 +949,157 @@ enum i8254_mode {
        I8254_BINARY = 0
 };
 
+/* *** BEGIN GLOBALLY-NAMED NI TERMINALS/SIGNALS *** */
+
+/*
+ * Common National Instruments Terminal/Signal names.
+ * Some of these have no NI_ prefix as they are useful for non-NI hardware, such
+ * as those that utilize the PXI/RTSI trigger lines.
+ *
+ * NOTE ABOUT THE CHOICE OF NAMES HERE AND THE CAMELSCRIPT:
+ *   The choice to use CamelScript and the exact names below is for
+ *   maintainability, clarity, similarity to manufacturer's documentation,
+ *   _and_ a mitigation for confusion that has plagued the use of these drivers
+ *   for years!
+ *
+ *   More detail:
+ *   There have been significant confusions over the past many years for users
+ *   when trying to understand how to connect to/from signals and terminals on
+ *   NI hardware using comedi.  The major reason for this is that the actual
+ *   register values were exposed and required to be used by users.  Several
+ *   major reasons exist why this caused major confusion for users:
+ *   1) The register values are _NOT_ in user documentation, but rather in
+ *     arcane locations, such as a few register programming manuals that are
+ *     increasingly hard to find and the NI MHDDK (comments in in example code).
+ *     There is no one place to find the various valid values of the registers.
+ *   2) The register values are _NOT_ completely consistent.  There is no way to
+ *     gain any sense of intuition of which values, or even enums one should use
+ *     for various registers.  There was some attempt in prior use of comedi to
+ *     name enums such that a user might know which enums should be used for
+ *     varying purposes, but the end-user had to gain a knowledge of register
+ *     values to correctly wield this approach.
+ *   3) The names for signals and registers found in the various register level
+ *     programming manuals and vendor-provided documentation are _not_ even
+ *     close to the same names that are in the end-user documentation.
+ *
+ *   Similar, albeit less, confusion plagued NI's previous version of their own
+ *   drivers.  Earlier than 2003, NI greatly simplified the situation for users
+ *   by releasing a new API that abstracted the names of signals/terminals to a
+ *   common and intuitive set of names.
+ *
+ *   The names below mirror the names chosen and well documented by NI.  These
+ *   names are exposed to the user via the comedilib user library.  By keeping
+ *   the names below, in spite of the use of CamelScript, maintenance will be
+ *   greatly eased and confusion for users _and_ comedi developers will be
+ *   greatly reduced.
+ */
+
+/*
+ * Base of abstracted NI names.
+ * The first 16 bits of *_arg are reserved for channel selection.
+ * Since we only actually need the first 4 or 5 bits for all register values on
+ * NI select registers anyways, we'll identify all values >= (1<<15) as being an
+ * abstracted NI signal/terminal name.
+ * These values are also used/returned by INSN_DEVICE_CONFIG_TEST_ROUTE,
+ * INSN_DEVICE_CONFIG_CONNECT_ROUTE, INSN_DEVICE_CONFIG_DISCONNECT_ROUTE,
+ * and INSN_DEVICE_CONFIG_GET_ROUTES.
+ */
+#define NI_NAMES_BASE  0x8000u
+/*
+ * not necessarily all allowed 64 PFIs are valid--certainly not for all devices
+ */
+#define NI_PFI(x)      (NI_NAMES_BASE        + ((x) & 0x3f))
+/* 8 trigger lines by standard, Some devices cannot talk to all eight. */
+#define TRIGGER_LINE(x)        (NI_PFI(-1)       + 1 + ((x) & 0x7))
+/* 4 RTSI shared MUXes to route signals to/from TRIGGER_LINES on NI hardware */
+#define NI_RTSI_BRD(x) (TRIGGER_LINE(-1) + 1 + ((x) & 0x3))
+
+/* *** Counter/timer names : 8 counters max *** */
+#define NI_COUNTER_NAMES_BASE  (NI_RTSI_BRD(-1)  + 1)
+#define NI_MAX_COUNTERS               7
+#define NI_CtrSource(x)               (NI_COUNTER_NAMES_BASE + ((x) & NI_MAX_COUNTERS))
+/* Gate, Aux, A,B,Z are all treated, at times as gates */
+#define NI_GATES_NAMES_BASE    (NI_CtrSource(-1) + 1)
+#define NI_CtrGate(x)         (NI_GATES_NAMES_BASE   + ((x) & NI_MAX_COUNTERS))
+#define NI_CtrAux(x)          (NI_CtrGate(-1)   + 1  + ((x) & NI_MAX_COUNTERS))
+#define NI_CtrA(x)            (NI_CtrAux(-1)    + 1  + ((x) & NI_MAX_COUNTERS))
+#define NI_CtrB(x)            (NI_CtrA(-1)      + 1  + ((x) & NI_MAX_COUNTERS))
+#define NI_CtrZ(x)            (NI_CtrB(-1)      + 1  + ((x) & NI_MAX_COUNTERS))
+#define NI_GATES_NAMES_MAX     NI_CtrZ(-1)
+#define NI_CtrArmStartTrigger(x) (NI_CtrZ(-1)    + 1  + ((x) & NI_MAX_COUNTERS))
+#define NI_CtrInternalOutput(x) \
+                    (NI_CtrArmStartTrigger(-1)  + 1  + ((x) & NI_MAX_COUNTERS))
+/** external pin(s) labeled conveniently as Ctr<i>Out. */
+#define NI_CtrOut(x)  (NI_CtrInternalOutput(-1)  + 1  + ((x) & NI_MAX_COUNTERS))
+/** For Buffered sampling of ctr -- x series capability. */
+#define NI_CtrSampleClock(x)   (NI_CtrOut(-1)   + 1  + ((x) & NI_MAX_COUNTERS))
+#define NI_COUNTER_NAMES_MAX   NI_CtrSampleClock(-1)
+
+enum ni_common_signal_names {
+       /* PXI_Star: this is a non-NI-specific signal */
+       PXI_Star = NI_COUNTER_NAMES_MAX + 1,
+       PXI_Clk10,
+       PXIe_Clk100,
+       NI_AI_SampleClock,
+       NI_AI_SampleClockTimebase,
+       NI_AI_StartTrigger,
+       NI_AI_ReferenceTrigger,
+       NI_AI_ConvertClock,
+       NI_AI_ConvertClockTimebase,
+       NI_AI_PauseTrigger,
+       NI_AI_HoldCompleteEvent,
+       NI_AI_HoldComplete,
+       NI_AI_ExternalMUXClock,
+       NI_AI_STOP, /* pulse signal that occurs when a update is finished(?) */
+       NI_AO_SampleClock,
+       NI_AO_SampleClockTimebase,
+       NI_AO_StartTrigger,
+       NI_AO_PauseTrigger,
+       NI_DI_SampleClock,
+       NI_DI_SampleClockTimebase,
+       NI_DI_StartTrigger,
+       NI_DI_ReferenceTrigger,
+       NI_DI_PauseTrigger,
+       NI_DI_InputBufferFull,
+       NI_DI_ReadyForStartEvent,
+       NI_DI_ReadyForTransferEventBurst,
+       NI_DI_ReadyForTransferEventPipelined,
+       NI_DO_SampleClock,
+       NI_DO_SampleClockTimebase,
+       NI_DO_StartTrigger,
+       NI_DO_PauseTrigger,
+       NI_DO_OutputBufferFull,
+       NI_DO_DataActiveEvent,
+       NI_DO_ReadyForStartEvent,
+       NI_DO_ReadyForTransferEvent,
+       NI_MasterTimebase,
+       NI_20MHzTimebase,
+       NI_80MHzTimebase,
+       NI_100MHzTimebase,
+       NI_200MHzTimebase,
+       NI_100kHzTimebase,
+       NI_10MHzRefClock,
+       NI_FrequencyOutput,
+       NI_ChangeDetectionEvent,
+       NI_AnalogComparisonEvent,
+       NI_WatchdogExpiredEvent,
+       NI_WatchdogExpirationTrigger,
+       NI_SCXI_Trig1,
+       NI_LogicLow,
+       NI_LogicHigh,
+       NI_ExternalStrobe,
+       NI_PFI_DO,
+       NI_CaseGround,
+       /* special internal signal used as variable source for RTSI bus: */
+       NI_RGOUT0,
+
+       /* just a name to make the next more convenient, regardless of above */
+       _NI_NAMES_MAX_PLUS_1,
+       NI_NUM_NAMES = _NI_NAMES_MAX_PLUS_1 - NI_NAMES_BASE,
+};
+
+/* *** END GLOBALLY-NAMED NI TERMINALS/SIGNALS *** */
+
 #define NI_USUAL_PFI_SELECT(x) (((x) < 10) ? (0x1 + (x)) : (0xb + (x)))
 #define NI_USUAL_RTSI_SELECT(x)        (((x) < 7) ? (0xb + (x)) : 0x1b)
 
index e18b61cdbdebac86adf0376cd1314576a62de699..c1c6b2b4ab91c5cc67165ec0179c997c887bc10f 100644 (file)
@@ -1216,6 +1216,10 @@ static int check_insn_config_length(struct comedi_insn *insn,
                if (insn->n == 6)
                        return 0;
                break;
+       case INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS:
+               if (insn->n >= 4)
+                       return 0;
+               break;
                /*
                 * by default we allow the insn since we don't have checks for
                 * all possible cases yet
@@ -1230,6 +1234,57 @@ static int check_insn_config_length(struct comedi_insn *insn,
        return -EINVAL;
 }
 
+static int check_insn_device_config_length(struct comedi_insn *insn,
+                                          unsigned int *data)
+{
+       if (insn->n < 1)
+               return -EINVAL;
+
+       switch (data[0]) {
+       case INSN_DEVICE_CONFIG_TEST_ROUTE:
+       case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
+       case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
+               if (insn->n == 3)
+                       return 0;
+               break;
+       case INSN_DEVICE_CONFIG_GET_ROUTES:
+               /*
+                * Big enough for config_id and the length of the userland
+                * memory buffer.  Additional length should be in factors of 2
+                * to communicate any returned route pairs (source,destination).
+                */
+               if (insn->n >= 2)
+                       return 0;
+               break;
+       }
+       return -EINVAL;
+}
+
+/**
+ * get_valid_routes() - Calls low-level driver get_valid_routes function to
+ *                     either return a count of valid routes to user, or copy
+ *                     of list of all valid device routes to buffer in
+ *                     userspace.
+ * @dev: comedi device pointer
+ * @data: data from user insn call.  The length of the data must be >= 2.
+ *       data[0] must contain the INSN_DEVICE_CONFIG config_id.
+ *       data[1](input) contains the number of _pairs_ for which memory is
+ *               allotted from the user.  If the user specifies '0', then only
+ *               the number of pairs available is returned.
+ *       data[1](output) returns either the number of pairs available (if none
+ *               where requested) or the number of _pairs_ that are copied back
+ *               to the user.
+ *       data[2::2] returns each (source, destination) pair.
+ *
+ * Return: -EINVAL if low-level driver does not allocate and return routes as
+ *        expected.  Returns 0 otherwise.
+ */
+static int get_valid_routes(struct comedi_device *dev, unsigned int *data)
+{
+       data[1] = dev->get_valid_routes(dev, data[1], data + 2);
+       return 0;
+}
+
 static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                      unsigned int *data, void *file)
 {
@@ -1293,6 +1348,24 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                        if (ret >= 0)
                                ret = 1;
                        break;
+               case INSN_DEVICE_CONFIG:
+                       ret = check_insn_device_config_length(insn, data);
+                       if (ret)
+                               break;
+
+                       if (data[0] == INSN_DEVICE_CONFIG_GET_ROUTES) {
+                               /*
+                                * data[1] should be the number of _pairs_ that
+                                * the memory can hold.
+                                */
+                               data[1] = (insn->n - 2) / 2;
+                               ret = get_valid_routes(dev, data);
+                               break;
+                       }
+
+                       /* other global device config instructions. */
+                       ret = dev->insn_device_config(dev, insn, data);
+                       break;
                default:
                        dev_dbg(dev->class_dev, "invalid insn\n");
                        ret = -EINVAL;
index 5775a93917f4d5d035c5460fbca910d8e370481e..a7d569cfca5db6b613e31d54eecb48e08f96413e 100644 (file)
@@ -516,6 +516,15 @@ struct comedi_driver {
  *     called when @use_count changes from 0 to 1.
  * @close: Optional pointer to a function set by the low-level driver to be
  *     called when @use_count changed from 1 to 0.
+ * @insn_device_config: Optional pointer to a handler for all sub-instructions
+ *     except %INSN_DEVICE_CONFIG_GET_ROUTES of the %INSN_DEVICE_CONFIG
+ *     instruction.  If this is not initialized by the low-level driver, a
+ *     default handler will be set during post-configuration.
+ * @get_valid_routes: Optional pointer to a handler for the
+ *     %INSN_DEVICE_CONFIG_GET_ROUTES sub-instruction of the
+ *     %INSN_DEVICE_CONFIG instruction set.  If this is not initialized by the
+ *     low-level driver, a default handler that copies zero routes back to the
+ *     user will be used.
  *
  * This is the main control data structure for a COMEDI device (as far as the
  * COMEDI core is concerned).  There are two groups of COMEDI devices -
@@ -565,6 +574,11 @@ struct comedi_device {
 
        int (*open)(struct comedi_device *dev);
        void (*close)(struct comedi_device *dev);
+       int (*insn_device_config)(struct comedi_device *dev,
+                                 struct comedi_insn *insn, unsigned int *data);
+       unsigned int (*get_valid_routes)(struct comedi_device *dev,
+                                        unsigned int n_pairs,
+                                        unsigned int *pair_data);
 };
 
 /*
index 57dd63d548b7c94e03bbdf615daf1889acfc986a..eefa62f42c0f06d8b84e03379c0499d7b66d8ace 100644 (file)
@@ -211,6 +211,19 @@ static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
        return -EINVAL;
 }
 
+static int insn_device_inval(struct comedi_device *dev,
+                            struct comedi_insn *insn, unsigned int *data)
+{
+       return -EINVAL;
+}
+
+static unsigned int get_zero_valid_routes(struct comedi_device *dev,
+                                         unsigned int n_pairs,
+                                         unsigned int *pair_data)
+{
+       return 0;
+}
+
 int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
               struct comedi_insn *insn, unsigned int *data)
 {
@@ -652,6 +665,12 @@ static int __comedi_device_postconfig(struct comedi_device *dev)
        int ret;
        int i;
 
+       if (!dev->insn_device_config)
+               dev->insn_device_config = insn_device_inval;
+
+       if (!dev->get_valid_routes)
+               dev->get_valid_routes = get_zero_valid_routes;
+
        for (i = 0; i < dev->n_subdevices; i++) {
                s = &dev->subdevices[i];
 
index 98b42b47dfe1effc88e288fce2bab94bc9424d3e..b24ac00cab73c1b5fea1aa34d2354b2139d5f6b5 100644 (file)
@@ -137,6 +137,33 @@ obj-$(CONFIG_COMEDI_VMK80XX)               += vmk80xx.o
 obj-$(CONFIG_COMEDI_MITE)              += mite.o
 obj-$(CONFIG_COMEDI_NI_TIO)            += ni_tio.o
 obj-$(CONFIG_COMEDI_NI_TIOCMD)         += ni_tiocmd.o
+obj-$(CONFIG_COMEDI_NI_ROUTING)                += ni_routing.o
+ni_routing-objs                                += ni_routes.o \
+                                          ni_routing/ni_route_values.o \
+                                          ni_routing/ni_route_values/ni_660x.o \
+                                          ni_routing/ni_route_values/ni_eseries.o \
+                                          ni_routing/ni_route_values/ni_mseries.o \
+                                          ni_routing/ni_device_routes.o \
+                                          ni_routing/ni_device_routes/pxi-6030e.o \
+                                          ni_routing/ni_device_routes/pci-6070e.o \
+                                          ni_routing/ni_device_routes/pci-6220.o \
+                                          ni_routing/ni_device_routes/pci-6221.o \
+                                          ni_routing/ni_device_routes/pxi-6224.o \
+                                          ni_routing/ni_device_routes/pxi-6225.o \
+                                          ni_routing/ni_device_routes/pci-6229.o \
+                                          ni_routing/ni_device_routes/pci-6251.o \
+                                          ni_routing/ni_device_routes/pxi-6251.o \
+                                          ni_routing/ni_device_routes/pxie-6251.o \
+                                          ni_routing/ni_device_routes/pci-6254.o \
+                                          ni_routing/ni_device_routes/pci-6259.o \
+                                          ni_routing/ni_device_routes/pci-6534.o \
+                                          ni_routing/ni_device_routes/pxie-6535.o \
+                                          ni_routing/ni_device_routes/pci-6602.o \
+                                          ni_routing/ni_device_routes/pci-6713.o \
+                                          ni_routing/ni_device_routes/pci-6723.o \
+                                          ni_routing/ni_device_routes/pci-6733.o \
+                                          ni_routing/ni_device_routes/pxi-6733.o \
+                                          ni_routing/ni_device_routes/pxie-6738.o
 obj-$(CONFIG_COMEDI_NI_LABPC)          += ni_labpc_common.o
 obj-$(CONFIG_COMEDI_NI_LABPC_ISADMA)   += ni_labpc_isadma.o
 
@@ -145,3 +172,4 @@ obj-$(CONFIG_COMEDI_8255_SA)                += 8255.o
 obj-$(CONFIG_COMEDI_AMPLC_DIO200)      += amplc_dio200_common.o
 obj-$(CONFIG_COMEDI_AMPLC_PC236)       += amplc_pc236_common.o
 obj-$(CONFIG_COMEDI_DAS08)             += das08.o
+obj-$(CONFIG_COMEDI_TESTS)             += tests/
index d437af721bd81e5c0c6f31d8c5206401bf606068..ef4c7c8a2b71669cd43ef29ee17dadc2c029b5fa 100644 (file)
@@ -626,6 +626,48 @@ static int waveform_ao_insn_write(struct comedi_device *dev,
        return insn->n;
 }
 
+static int waveform_ai_insn_config(struct comedi_device *dev,
+                                  struct comedi_subdevice *s,
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
+{
+       if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
+               /*
+                * input:  data[1], data[2] : scan_begin_src, convert_src
+                * output: data[1], data[2] : scan_begin_min, convert_min
+                */
+               if (data[1] == TRIG_FOLLOW) {
+                       /* exactly TRIG_FOLLOW case */
+                       data[1] = 0;
+                       data[2] = NSEC_PER_USEC;
+               } else {
+                       data[1] = NSEC_PER_USEC;
+                       if (data[2] & TRIG_TIMER)
+                               data[2] = NSEC_PER_USEC;
+                       else
+                               data[2] = 0;
+               }
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int waveform_ao_insn_config(struct comedi_device *dev,
+                                  struct comedi_subdevice *s,
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
+{
+       if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
+               /* we don't care about actual channels */
+               data[1] = NSEC_PER_USEC; /* scan_begin_min */
+               data[2] = 0;             /* convert_min */
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
 static int waveform_common_attach(struct comedi_device *dev,
                                  int amplitude, int period)
 {
@@ -658,6 +700,7 @@ static int waveform_common_attach(struct comedi_device *dev,
        s->do_cmd = waveform_ai_cmd;
        s->do_cmdtest = waveform_ai_cmdtest;
        s->cancel = waveform_ai_cancel;
+       s->insn_config = waveform_ai_insn_config;
 
        s = &dev->subdevices[1];
        dev->write_subdev = s;
@@ -673,6 +716,7 @@ static int waveform_common_attach(struct comedi_device *dev,
        s->do_cmd = waveform_ao_cmd;
        s->do_cmdtest = waveform_ao_cmdtest;
        s->cancel = waveform_ao_cancel;
+       s->insn_config = waveform_ao_insn_config;
 
        /* Our default loopback value is just a 0V flatline */
        for (i = 0; i < s->n_chan; i++)
index e521ed9d0887043bc5e4711e02c1c1f0b0d8d29f..e70a461e723f84276c1a67f6da311a3cf79b8ba5 100644 (file)
@@ -7,7 +7,7 @@
  * Driver: ni_660x
  * Description: National Instruments 660x counter/timer boards
  * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
- *   PXI-6608, PCI-6624, PXI-6624
+ *   PCI-6608, PXI-6608, PCI-6624, PXI-6624
  * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
  *   Herman.Bruyninckx@mech.kuleuven.ac.be,
  *   Wim.Meeussen@mech.kuleuven.ac.be,
@@ -31,6 +31,7 @@
 
 #include "mite.h"
 #include "ni_tio.h"
+#include "ni_routes.h"
 
 /* See Register-Level Programmer Manual page 3.1 */
 enum ni_660x_register {
@@ -201,6 +202,7 @@ enum ni_660x_boardid {
        BOARD_PCI6601,
        BOARD_PCI6602,
        BOARD_PXI6602,
+       BOARD_PCI6608,
        BOARD_PXI6608,
        BOARD_PCI6624,
        BOARD_PXI6624
@@ -224,6 +226,10 @@ static const struct ni_660x_board ni_660x_boards[] = {
                .name           = "PXI-6602",
                .n_chips        = 2,
        },
+       [BOARD_PCI6608] = {
+               .name           = "PCI-6608",
+               .n_chips        = 2,
+       },
        [BOARD_PXI6608] = {
                .name           = "PXI-6608",
                .n_chips        = 2,
@@ -259,6 +265,7 @@ struct ni_660x_private {
        unsigned int dma_cfg[NI660X_MAX_CHIPS];
        unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS];
        u64 io_dir;
+       struct ni_route_tables routing_tables;
 };
 
 static void ni_660x_write(struct comedi_device *dev, unsigned int chip,
@@ -561,6 +568,10 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev,
        unsigned int idle_chip = 0;
        unsigned int bits;
 
+       if (chan >= NI_PFI(0))
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+
        if (board->n_chips > 1) {
                if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
                    chan >= 8 && chan <= 23) {
@@ -589,11 +600,54 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev,
        ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan));
 }
 
+static void ni_660x_set_pfi_direction(struct comedi_device *dev,
+                                     unsigned int chan,
+                                     unsigned int direction)
+{
+       struct ni_660x_private *devpriv = dev->private;
+       u64 bit;
+
+       if (chan >= NI_PFI(0))
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+
+       bit = 1ULL << chan;
+
+       if (direction == COMEDI_OUTPUT) {
+               devpriv->io_dir |= bit;
+               /* reset the output to currently assigned output value */
+               ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
+       } else {
+               devpriv->io_dir &= ~bit;
+               /* set pin to high-z; do not change currently assigned route */
+               ni_660x_select_pfi_output(dev, chan, 0);
+       }
+}
+
+static unsigned int ni_660x_get_pfi_direction(struct comedi_device *dev,
+                                             unsigned int chan)
+{
+       struct ni_660x_private *devpriv = dev->private;
+       u64 bit;
+
+       if (chan >= NI_PFI(0))
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+
+       bit = 1ULL << chan;
+
+       return (devpriv->io_dir & bit) ? COMEDI_OUTPUT : COMEDI_INPUT;
+}
+
 static int ni_660x_set_pfi_routing(struct comedi_device *dev,
                                   unsigned int chan, unsigned int source)
 {
        struct ni_660x_private *devpriv = dev->private;
 
+       if (chan >= NI_PFI(0))
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+
        switch (source) {
        case NI_660X_PFI_OUTPUT_COUNTER:
                if (chan < 8)
@@ -607,36 +661,56 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev,
        }
 
        devpriv->io_cfg[chan] = source;
-       if (devpriv->io_dir & (1ULL << chan))
+       if (ni_660x_get_pfi_direction(dev, chan) == COMEDI_OUTPUT)
                ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
        return 0;
 }
 
+static int ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned int chan)
+{
+       struct ni_660x_private *devpriv = dev->private;
+
+       if (chan >= NI_PFI(0))
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+
+       return devpriv->io_cfg[chan];
+}
+
+static void ni_660x_set_pfi_filter(struct comedi_device *dev,
+                                  unsigned int chan, unsigned int value)
+{
+       unsigned int val;
+
+       if (chan >= NI_PFI(0))
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+
+       val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
+       val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
+       val |= NI660X_IO_CFG_IN_SEL(chan, value);
+       ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
+}
+
 static int ni_660x_dio_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
                                   struct comedi_insn *insn,
                                   unsigned int *data)
 {
-       struct ni_660x_private *devpriv = dev->private;
        unsigned int chan = CR_CHAN(insn->chanspec);
-       u64 bit = 1ULL << chan;
-       unsigned int val;
        int ret;
 
        switch (data[0]) {
        case INSN_CONFIG_DIO_OUTPUT:
-               devpriv->io_dir |= bit;
-               ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
+               ni_660x_set_pfi_direction(dev, chan, COMEDI_OUTPUT);
                break;
 
        case INSN_CONFIG_DIO_INPUT:
-               devpriv->io_dir &= ~bit;
-               ni_660x_select_pfi_output(dev, chan, 0);        /* high-z */
+               ni_660x_set_pfi_direction(dev, chan, COMEDI_INPUT);
                break;
 
        case INSN_CONFIG_DIO_QUERY:
-               data[1] = (devpriv->io_dir & bit) ? COMEDI_OUTPUT
-                                                 : COMEDI_INPUT;
+               data[1] = ni_660x_get_pfi_direction(dev, chan);
                break;
 
        case INSN_CONFIG_SET_ROUTING:
@@ -646,14 +720,11 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
                break;
 
        case INSN_CONFIG_GET_ROUTING:
-               data[1] = devpriv->io_cfg[chan];
+               data[1] = ni_660x_get_pfi_routing(dev, chan);
                break;
 
        case INSN_CONFIG_FILTER:
-               val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
-               val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
-               val |= NI660X_IO_CFG_IN_SEL(chan, data[1]);
-               ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
+               ni_660x_set_pfi_filter(dev, chan, data[1]);
                break;
 
        default:
@@ -663,6 +734,240 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
        return insn->n;
 }
 
+static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
+                                        unsigned int n_pairs,
+                                        unsigned int *pair_data)
+{
+       struct ni_660x_private *devpriv = dev->private;
+
+       return ni_get_valid_routes(&devpriv->routing_tables, n_pairs,
+                                  pair_data);
+}
+
+/*
+ * Retrieves the current source of the output selector for the given
+ * destination.  If the terminal for the destination is not already configured
+ * as an output, this function returns -EINVAL as error.
+ *
+ * Return: The register value of the destination output selector;
+ *        -EINVAL if terminal is not configured for output.
+ */
+static inline int get_output_select_source(int dest, struct comedi_device *dev)
+{
+       struct ni_660x_private *devpriv = dev->private;
+       int reg = -1;
+
+       if (channel_is_pfi(dest)) {
+               if (ni_660x_get_pfi_direction(dev, dest) == COMEDI_OUTPUT)
+                       reg = ni_660x_get_pfi_routing(dev, dest);
+       } else if (channel_is_rtsi(dest)) {
+               dev_dbg(dev->class_dev,
+                       "%s: unhandled rtsi destination (%d) queried\n",
+                       __func__, dest);
+               /*
+                * The following can be enabled when RTSI routing info is
+                * determined (not currently documented):
+                * if (ni_get_rtsi_direction(dev, dest) == COMEDI_OUTPUT) {
+                *      reg = ni_get_rtsi_routing(dev, dest);
+
+                *      if (reg == NI_RTSI_OUTPUT_RGOUT0) {
+                *              dest = NI_RGOUT0; ** prepare for lookup below **
+                *              reg = get_rgout0_reg(dev);
+                *      } else if (reg >= NI_RTSI_OUTPUT_RTSI_BRD(0) &&
+                *                 reg <= NI_RTSI_OUTPUT_RTSI_BRD(3)) {
+                *              const int i = reg - NI_RTSI_OUTPUT_RTSI_BRD(0);
+
+                *              dest = NI_RTSI_BRD(i); ** prepare for lookup **
+                *              reg = get_ith_rtsi_brd_reg(i, dev);
+                *      }
+                * }
+                */
+       } else if (channel_is_ctr(dest)) {
+               reg = ni_tio_get_routing(devpriv->counter_dev, dest);
+       } else {
+               dev_dbg(dev->class_dev,
+                       "%s: unhandled destination (%d) queried\n",
+                       __func__, dest);
+       }
+
+       if (reg >= 0)
+               return ni_find_route_source(CR_CHAN(reg), dest,
+                                           &devpriv->routing_tables);
+       return -EINVAL;
+}
+
+/*
+ * Test a route:
+ *
+ * Return: -1 if not connectible;
+ *         0 if connectible and not connected;
+ *         1 if connectible and connected.
+ */
+static inline int test_route(unsigned int src, unsigned int dest,
+                            struct comedi_device *dev)
+{
+       struct ni_660x_private *devpriv = dev->private;
+       s8 reg = ni_route_to_register(CR_CHAN(src), dest,
+                                     &devpriv->routing_tables);
+
+       if (reg < 0)
+               return -1;
+       if (get_output_select_source(dest, dev) != CR_CHAN(src))
+               return 0;
+       return 1;
+}
+
+/* Connect the actual route.  */
+static inline int connect_route(unsigned int src, unsigned int dest,
+                               struct comedi_device *dev)
+{
+       struct ni_660x_private *devpriv = dev->private;
+       s8 reg = ni_route_to_register(CR_CHAN(src), dest,
+                                     &devpriv->routing_tables);
+       s8 current_src;
+
+       if (reg < 0)
+               /* route is not valid */
+               return -EINVAL;
+
+       current_src = get_output_select_source(dest, dev);
+       if (current_src == CR_CHAN(src))
+               return -EALREADY;
+       if (current_src >= 0)
+               /* destination mux is already busy. complain, don't overwrite */
+               return -EBUSY;
+
+       /* The route is valid and available. Now connect... */
+       if (channel_is_pfi(CR_CHAN(dest))) {
+               /*
+                * set routing and then direction so that the output does not
+                * first get generated with the wrong pin
+                */
+               ni_660x_set_pfi_routing(dev, dest, reg);
+               ni_660x_set_pfi_direction(dev, dest, COMEDI_OUTPUT);
+       } else if (channel_is_rtsi(CR_CHAN(dest))) {
+               dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
+                       __func__, dest);
+               return -EINVAL;
+               /*
+                * The following can be enabled when RTSI routing info is
+                * determined (not currently documented):
+                * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
+                *      int ret = incr_rgout0_src_use(src, dev);
+
+                *      if (ret < 0)
+                *              return ret;
+                * } else if (ni_rtsi_route_requires_mux(reg)) {
+                *      ** Attempt to allocate and  route (src->brd) **
+                *      int brd = incr_rtsi_brd_src_use(src, dev);
+
+                *      if (brd < 0)
+                *              return brd;
+
+                *      ** Now lookup the register value for (brd->dest) **
+                *      reg = ni_lookup_route_register(brd, CR_CHAN(dest),
+                *                                     &devpriv->routing_tables);
+                * }
+
+                * ni_set_rtsi_direction(dev, dest, COMEDI_OUTPUT);
+                * ni_set_rtsi_routing(dev, dest, reg);
+                */
+       } else if (channel_is_ctr(CR_CHAN(dest))) {
+               /*
+                * we are adding back the channel modifier info to set
+                * invert/edge info passed by the user
+                */
+               ni_tio_set_routing(devpriv->counter_dev, dest,
+                                  reg | (src & ~CR_CHAN(-1)));
+       } else {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static inline int disconnect_route(unsigned int src, unsigned int dest,
+                                  struct comedi_device *dev)
+{
+       struct ni_660x_private *devpriv = dev->private;
+       s8 reg = ni_route_to_register(CR_CHAN(src), CR_CHAN(dest),
+                                     &devpriv->routing_tables);
+
+       if (reg < 0)
+               /* route is not valid */
+               return -EINVAL;
+       if (get_output_select_source(dest, dev) != CR_CHAN(src))
+               /* cannot disconnect something not connected */
+               return -EINVAL;
+
+       /* The route is valid and is connected.  Now disconnect... */
+       if (channel_is_pfi(CR_CHAN(dest))) {
+               unsigned int source = ((CR_CHAN(dest) - NI_PFI(0)) < 8)
+                                       ? NI_660X_PFI_OUTPUT_DIO
+                                       : NI_660X_PFI_OUTPUT_COUNTER;
+
+               /* set the pfi to high impedance, and disconnect */
+               ni_660x_set_pfi_direction(dev, dest, COMEDI_INPUT);
+               ni_660x_set_pfi_routing(dev, dest, source);
+       } else if (channel_is_rtsi(CR_CHAN(dest))) {
+               dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
+                       __func__, dest);
+               return -EINVAL;
+               /*
+                * The following can be enabled when RTSI routing info is
+                * determined (not currently documented):
+                * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
+                *      int ret = decr_rgout0_src_use(src, dev);
+
+                *      if (ret < 0)
+                *              return ret;
+                * } else if (ni_rtsi_route_requires_mux(reg)) {
+                *      ** find which RTSI_BRD line is source for rtsi pin **
+                *      int brd = ni_find_route_source(
+                *              ni_get_rtsi_routing(dev, dest), CR_CHAN(dest),
+                *              &devpriv->routing_tables);
+
+                *      if (brd < 0)
+                *              return brd;
+
+                *      ** decrement/disconnect RTSI_BRD line from source **
+                *      decr_rtsi_brd_src_use(src, brd, dev);
+                * }
+
+                * ** set rtsi output selector to default state **
+                * reg = default_rtsi_routing[CR_CHAN(dest) - TRIGGER_LINE(0)];
+                * ni_set_rtsi_direction(dev, dest, COMEDI_INPUT);
+                * ni_set_rtsi_routing(dev, dest, reg);
+                */
+       } else if (channel_is_ctr(CR_CHAN(dest))) {
+               ni_tio_unset_routing(devpriv->counter_dev, dest);
+       } else {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int ni_global_insn_config(struct comedi_device *dev,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       switch (data[0]) {
+       case INSN_DEVICE_CONFIG_TEST_ROUTE:
+               data[0] = test_route(data[1], data[2], dev);
+               return 2;
+       case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
+               return connect_route(data[1], data[2], dev);
+       case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
+               return disconnect_route(data[1], data[2], dev);
+       /*
+        * This case is already handled one level up.
+        * case INSN_DEVICE_CONFIG_GET_ROUTES:
+        */
+       default:
+               return -EINVAL;
+       }
+       return 1;
+}
+
 static void ni_660x_init_tio_chips(struct comedi_device *dev,
                                   unsigned int n_chips)
 {
@@ -730,12 +1035,30 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
 
        ni_660x_init_tio_chips(dev, board->n_chips);
 
+       /* prepare the device for globally-named routes. */
+       if (ni_assign_device_routes("ni_660x", board->name,
+                                   &devpriv->routing_tables) < 0) {
+               dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
+                        __func__, board->name);
+               dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
+                        __func__, board->name);
+       } else {
+               /*
+                * only(?) assign insn_device_config if we have global names for
+                * this device.
+                */
+               dev->insn_device_config = ni_global_insn_config;
+               dev->get_valid_routes = _ni_get_valid_routes;
+       }
+
        n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
        gpct_dev = ni_gpct_device_construct(dev,
                                            ni_660x_gpct_write,
                                            ni_660x_gpct_read,
                                            ni_gpct_variant_660x,
-                                           n_counters);
+                                           n_counters,
+                                           NI660X_COUNTERS_PER_CHIP,
+                                           &devpriv->routing_tables);
        if (!gpct_dev)
                return -ENOMEM;
        devpriv->counter_dev = gpct_dev;
@@ -822,7 +1145,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
                                              : NI_660X_PFI_OUTPUT_COUNTER;
 
                ni_660x_set_pfi_routing(dev, i, source);
-               ni_660x_select_pfi_output(dev, i, 0);           /* high-z */
+               ni_660x_set_pfi_direction(dev, i, COMEDI_INPUT);/* high-z */
        }
 
        /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */
@@ -831,9 +1154,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
                if (i < n_counters) {
                        struct ni_gpct *counter = &gpct_dev->counters[i];
 
-                       counter->chip_index = i / NI660X_COUNTERS_PER_CHIP;
-                       counter->counter_index = i % NI660X_COUNTERS_PER_CHIP;
-
                        s->type         = COMEDI_SUBD_COUNTER;
                        s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
                                          SDF_LSAMPL | SDF_CMD_READ;
@@ -915,6 +1235,7 @@ static const struct pci_device_id ni_660x_pci_table[] = {
        { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
        { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
        { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
+       { PCI_VDEVICE(NI, 0x2db0), BOARD_PCI6608 },
        { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
        { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
        { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
index 4dee2fc37aedeb2f6fc088ecb8e89ce6a8f141a5..2d1e0325d04d122280eb267c7e1ccd997b6988b4 100644 (file)
@@ -351,7 +351,8 @@ static const struct mio_regmap m_series_stc_write_regmap[] = {
        [NISTC_AO_PERSONAL_REG]         = { 0x19c, 2 },
        [NISTC_RTSI_TRIGA_OUT_REG]      = { 0x19e, 2 },
        [NISTC_RTSI_TRIGB_OUT_REG]      = { 0x1a0, 2 },
-       [NISTC_RTSI_BOARD_REG]          = { 0, 0 }, /* Unknown */
+       /* doc for following line: mhddk/nimseries/ChipObjects/tMSeries.h */
+       [NISTC_RTSI_BOARD_REG]          = { 0x1a2, 2 },
        [NISTC_CFG_MEM_CLR_REG]         = { 0x1a4, 2 },
        [NISTC_ADC_FIFO_CLR_REG]        = { 0x1a6, 2 },
        [NISTC_DAC_FIFO_CLR_REG]        = { 0x1a8, 2 },
@@ -2006,7 +2007,6 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
        const struct ni_board_struct *board = dev->board_ptr;
        struct ni_private *devpriv = dev->private;
        int err = 0;
-       unsigned int tmp;
        unsigned int sources;
 
        /* Step 1 : check if triggers are trivially valid */
@@ -2047,12 +2047,9 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
                break;
        case TRIG_EXT:
-               tmp = CR_CHAN(cmd->start_arg);
-
-               if (tmp > 16)
-                       tmp = 16;
-               tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
-               err |= comedi_check_trigger_arg_is(&cmd->start_arg, tmp);
+               err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->start_arg),
+                                                 NI_AI_StartTrigger,
+                                                 &devpriv->routing_tables, 1);
                break;
        }
 
@@ -2064,12 +2061,9 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                                                    0xffffff);
        } else if (cmd->scan_begin_src == TRIG_EXT) {
                /* external trigger */
-               unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
-
-               if (tmp > 16)
-                       tmp = 16;
-               tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
-               err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
+               err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->scan_begin_arg),
+                                                 NI_AI_SampleClock,
+                                                 &devpriv->routing_tables, 1);
        } else {                /* TRIG_OTHER */
                err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        }
@@ -2087,12 +2081,9 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                }
        } else if (cmd->convert_src == TRIG_EXT) {
                /* external trigger */
-               unsigned int tmp = CR_CHAN(cmd->convert_arg);
-
-               if (tmp > 16)
-                       tmp = 16;
-               tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
-               err |= comedi_check_trigger_arg_is(&cmd->convert_arg, tmp);
+               err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->convert_arg),
+                                                 NI_AI_ConvertClock,
+                                                 &devpriv->routing_tables, 1);
        } else if (cmd->convert_src == TRIG_NOW) {
                err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
        }
@@ -2118,7 +2109,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
        /* step 4: fix up any arguments */
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
-               tmp = cmd->scan_begin_arg;
+               unsigned int tmp = cmd->scan_begin_arg;
                cmd->scan_begin_arg =
                    ni_timer_to_ns(dev, ni_ns_to_timer(dev,
                                                       cmd->scan_begin_arg,
@@ -2128,7 +2119,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
        }
        if (cmd->convert_src == TRIG_TIMER) {
                if (!devpriv->is_611x && !devpriv->is_6143) {
-                       tmp = cmd->convert_arg;
+                       unsigned int tmp = cmd->convert_arg;
                        cmd->convert_arg =
                            ni_timer_to_ns(dev, ni_ns_to_timer(dev,
                                                               cmd->convert_arg,
@@ -2206,8 +2197,10 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                           NISTC_AI_TRIG_START1_SEL(0);
                break;
        case TRIG_EXT:
-               ai_trig |= NISTC_AI_TRIG_START1_SEL(CR_CHAN(cmd->start_arg) +
-                                                   1);
+               ai_trig |= NISTC_AI_TRIG_START1_SEL(
+                       ni_get_reg_value_roffs(CR_CHAN(cmd->start_arg),
+                                              NI_AI_StartTrigger,
+                                              &devpriv->routing_tables, 1));
 
                if (cmd->start_arg & CR_INVERT)
                        ai_trig |= NISTC_AI_TRIG_START1_POLARITY;
@@ -2317,8 +2310,10 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                    (cmd->scan_begin_arg & ~CR_EDGE) !=
                    (cmd->convert_arg & ~CR_EDGE))
                        start_stop_select |= NISTC_AI_START_SYNC;
-               start_stop_select |=
-                   NISTC_AI_START_SEL(1 + CR_CHAN(cmd->scan_begin_arg));
+               start_stop_select |= NISTC_AI_START_SEL(
+                       ni_get_reg_value_roffs(CR_CHAN(cmd->scan_begin_arg),
+                                              NI_AI_SampleClock,
+                                              &devpriv->routing_tables, 1));
                ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
                break;
        }
@@ -2346,8 +2341,10 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
                break;
        case TRIG_EXT:
-               mode1 |= NISTC_AI_MODE1_CONVERT_SRC(1 +
-                                                   CR_CHAN(cmd->convert_arg));
+               mode1 |= NISTC_AI_MODE1_CONVERT_SRC(
+                       ni_get_reg_value_roffs(CR_CHAN(cmd->convert_arg),
+                                              NI_AI_ConvertClock,
+                                              &devpriv->routing_tables, 1));
                if ((cmd->convert_arg & CR_INVERT) == 0)
                        mode1 |= NISTC_AI_MODE1_CONVERT_POLARITY;
                ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
@@ -2464,6 +2461,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
                             struct comedi_subdevice *s,
                             struct comedi_insn *insn, unsigned int *data)
 {
+       const struct ni_board_struct *board = dev->board_ptr;
        struct ni_private *devpriv = dev->private;
 
        if (insn->n < 1)
@@ -2498,6 +2496,15 @@ static int ni_ai_insn_config(struct comedi_device *dev,
                        }
                }
                return 2;
+       case INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS:
+               /* we don't care about actual channels */
+               /* data[3] : chanlist_len */
+               data[1] = ni_min_ai_scan_period_ns(dev, data[3]);
+               if (devpriv->is_611x || devpriv->is_6143)
+                       data[2] = 0; /* simultaneous output */
+               else
+                       data[2] = board->ai_speed;
+               return 0;
        default:
                break;
        }
@@ -2834,6 +2841,11 @@ static int ni_ao_insn_config(struct comedi_device *dev,
                return 0;
        case INSN_CONFIG_ARM:
                return ni_ao_arm(dev, s);
+       case INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS:
+               /* we don't care about actual channels */
+               data[1] = board->ao_speed;
+               data[2] = 0;
+               return 0;
        default:
                break;
        }
@@ -2955,7 +2967,10 @@ static void ni_ao_cmd_set_trigger(struct comedi_device *dev,
                trigsel = NISTC_AO_TRIG_START1_EDGE |
                          NISTC_AO_TRIG_START1_SYNC;
        } else { /* TRIG_EXT */
-               trigsel = NISTC_AO_TRIG_START1_SEL(CR_CHAN(cmd->start_arg) + 1);
+               trigsel = NISTC_AO_TRIG_START1_SEL(
+                       ni_get_reg_value_roffs(CR_CHAN(cmd->start_arg),
+                                              NI_AO_StartTrigger,
+                                              &devpriv->routing_tables, 1));
                /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */
                if (cmd->start_arg & CR_INVERT)
                        trigsel |= NISTC_AO_TRIG_START1_POLARITY;
@@ -3117,7 +3132,9 @@ static void ni_ao_cmd_set_update(struct comedi_device *dev,
                /* FIXME:  assert scan_begin_arg != 0, ret failure otherwise */
                devpriv->ao_cmd2  |= NISTC_AO_CMD2_BC_GATE_ENA;
                devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC(
-                                       CR_CHAN(cmd->scan_begin_arg));
+                       ni_get_reg_value(CR_CHAN(cmd->scan_begin_arg),
+                                        NI_AO_SampleClock,
+                                        &devpriv->routing_tables));
                if (cmd->scan_begin_arg & CR_INVERT)
                        devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC_POLARITY;
        }
@@ -3313,12 +3330,9 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
                break;
        case TRIG_EXT:
-               tmp = CR_CHAN(cmd->start_arg);
-
-               if (tmp > 18)
-                       tmp = 18;
-               tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
-               err |= comedi_check_trigger_arg_is(&cmd->start_arg, tmp);
+               err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->start_arg),
+                                                 NI_AO_StartTrigger,
+                                                 &devpriv->routing_tables, 1);
                break;
        }
 
@@ -3328,6 +3342,10 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
                                                    devpriv->clock_ns *
                                                    0xffffff);
+       } else {                /* TRIG_EXT */
+               err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg),
+                                           NI_AO_SampleClock,
+                                           &devpriv->routing_tables);
        }
 
        err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
@@ -3475,6 +3493,15 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
 {
        int ret;
 
+       if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
+               const struct ni_board_struct *board = dev->board_ptr;
+
+               /* we don't care about actual channels */
+               data[1] = board->dio_speed;
+               data[2] = 0;
+               return 0;
+       }
+
        ret = comedi_dio_insn_config(dev, s, insn, data, 0);
        if (ret)
                return ret;
@@ -3516,8 +3543,8 @@ static int ni_cdio_check_chanlist(struct comedi_device *dev,
 static int ni_cdio_cmdtest(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
+       struct ni_private *devpriv = dev->private;
        int err = 0;
-       int tmp;
 
        /* Step 1 : check if triggers are trivially valid */
 
@@ -3537,9 +3564,15 @@ static int ni_cdio_cmdtest(struct comedi_device *dev,
 
        err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 
-       tmp = cmd->scan_begin_arg;
-       tmp &= CR_PACK_FLAGS(NI_M_CDO_MODE_SAMPLE_SRC_MASK, 0, 0, CR_INVERT);
-       if (tmp != cmd->scan_begin_arg)
+       /*
+        * Although NI_D[IO]_SampleClock are the same, perhaps we should still,
+        * for completeness, test whether the cmd is output or input?
+        */
+       err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg),
+                                   NI_DO_SampleClock,
+                                   &devpriv->routing_tables);
+       if (CR_RANGE(cmd->scan_begin_arg) != 0 ||
+           CR_AREF(cmd->scan_begin_arg) != 0)
                err |= -EINVAL;
 
        err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
@@ -3627,9 +3660,16 @@ static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        int retval;
 
        ni_writel(dev, NI_M_CDO_CMD_RESET, NI_M_CDIO_CMD_REG);
+       /*
+        * Although NI_D[IO]_SampleClock are the same, perhaps we should still,
+        * for completeness, test whether the cmd is output or input(?)
+        */
        cdo_mode_bits = NI_M_CDO_MODE_FIFO_MODE |
                        NI_M_CDO_MODE_HALT_ON_ERROR |
-                       NI_M_CDO_MODE_SAMPLE_SRC(CR_CHAN(cmd->scan_begin_arg));
+                       NI_M_CDO_MODE_SAMPLE_SRC(
+                               ni_get_reg_value(CR_CHAN(cmd->scan_begin_arg),
+                                                NI_DO_SampleClock,
+                                                &devpriv->routing_tables));
        if (cmd->scan_begin_arg & CR_INVERT)
                cdo_mode_bits |= NI_M_CDO_MODE_POLARITY;
        ni_writel(dev, cdo_mode_bits, NI_M_CDO_MODE_REG);
@@ -4551,24 +4591,33 @@ static unsigned int ni_get_pfi_routing(struct comedi_device *dev,
 {
        struct ni_private *devpriv = dev->private;
 
+       if (chan >= NI_PFI(0)) {
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+       }
        return (devpriv->is_m_series)
                        ? ni_m_series_get_pfi_routing(dev, chan)
                        : ni_old_get_pfi_routing(dev, chan);
 }
 
+/* Sets the output mux for the specified PFI channel. */
 static int ni_set_pfi_routing(struct comedi_device *dev,
                              unsigned int chan, unsigned int source)
 {
        struct ni_private *devpriv = dev->private;
 
+       if (chan >= NI_PFI(0)) {
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+       }
        return (devpriv->is_m_series)
                        ? ni_m_series_set_pfi_routing(dev, chan, source)
                        : ni_old_set_pfi_routing(dev, chan, source);
 }
 
-static int ni_config_filter(struct comedi_device *dev,
-                           unsigned int pfi_channel,
-                           enum ni_pfi_filter_select filter)
+static int ni_config_pfi_filter(struct comedi_device *dev,
+                               unsigned int chan,
+                               enum ni_pfi_filter_select filter)
 {
        struct ni_private *devpriv = dev->private;
        unsigned int bits;
@@ -4576,19 +4625,46 @@ static int ni_config_filter(struct comedi_device *dev,
        if (!devpriv->is_m_series)
                return -ENOTSUPP;
 
+       if (chan >= NI_PFI(0)) {
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+       }
+
        bits = ni_readl(dev, NI_M_PFI_FILTER_REG);
-       bits &= ~NI_M_PFI_FILTER_SEL_MASK(pfi_channel);
-       bits |= NI_M_PFI_FILTER_SEL(pfi_channel, filter);
+       bits &= ~NI_M_PFI_FILTER_SEL_MASK(chan);
+       bits |= NI_M_PFI_FILTER_SEL(chan, filter);
        ni_writel(dev, bits, NI_M_PFI_FILTER_REG);
        return 0;
 }
 
+static void ni_set_pfi_direction(struct comedi_device *dev, int chan,
+                                unsigned int direction)
+{
+       if (chan >= NI_PFI(0)) {
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+       }
+       direction = (direction == COMEDI_OUTPUT) ? 1u : 0u;
+       ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, direction);
+}
+
+static int ni_get_pfi_direction(struct comedi_device *dev, int chan)
+{
+       struct ni_private *devpriv = dev->private;
+
+       if (chan >= NI_PFI(0)) {
+               /* allow new and old names of pfi channels to work. */
+               chan -= NI_PFI(0);
+       }
+       return devpriv->io_bidirection_pin_reg & (1 << chan) ?
+              COMEDI_OUTPUT : COMEDI_INPUT;
+}
+
 static int ni_pfi_insn_config(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn,
                              unsigned int *data)
 {
-       struct ni_private *devpriv = dev->private;
        unsigned int chan;
 
        if (insn->n < 1)
@@ -4598,23 +4674,19 @@ static int ni_pfi_insn_config(struct comedi_device *dev,
 
        switch (data[0]) {
        case COMEDI_OUTPUT:
-               ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, 1);
-               break;
        case COMEDI_INPUT:
-               ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, 0);
+               ni_set_pfi_direction(dev, chan, data[0]);
                break;
        case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (devpriv->io_bidirection_pin_reg & (1 << chan)) ?
-                   COMEDI_OUTPUT : COMEDI_INPUT;
-               return 0;
+               data[1] = ni_get_pfi_direction(dev, chan);
+               break;
        case INSN_CONFIG_SET_ROUTING:
                return ni_set_pfi_routing(dev, chan, data[1]);
        case INSN_CONFIG_GET_ROUTING:
                data[1] = ni_get_pfi_routing(dev, chan);
                break;
        case INSN_CONFIG_FILTER:
-               return ni_config_filter(dev, chan, data[1]);
+               return ni_config_pfi_filter(dev, chan, data[1]);
        default:
                return -EINVAL;
        }
@@ -4980,7 +5052,10 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev,
        case NI_RTSI_OUTPUT_G_SRC0:
        case NI_RTSI_OUTPUT_G_GATE0:
        case NI_RTSI_OUTPUT_RGOUT0:
-       case NI_RTSI_OUTPUT_RTSI_BRD_0:
+       case NI_RTSI_OUTPUT_RTSI_BRD(0):
+       case NI_RTSI_OUTPUT_RTSI_BRD(1):
+       case NI_RTSI_OUTPUT_RTSI_BRD(2):
+       case NI_RTSI_OUTPUT_RTSI_BRD(3):
                return 1;
        case NI_RTSI_OUTPUT_RTSI_OSC:
                return (devpriv->is_m_series) ? 1 : 0;
@@ -4994,6 +5069,10 @@ static int ni_set_rtsi_routing(struct comedi_device *dev,
 {
        struct ni_private *devpriv = dev->private;
 
+       if (chan >= TRIGGER_LINE(0))
+               /* allow new and old names of rtsi channels to work. */
+               chan -= TRIGGER_LINE(0);
+
        if (ni_valid_rtsi_output_source(dev, chan, src) == 0)
                return -EINVAL;
        if (chan < 4) {
@@ -5001,11 +5080,18 @@ static int ni_set_rtsi_routing(struct comedi_device *dev,
                devpriv->rtsi_trig_a_output_reg |= NISTC_RTSI_TRIG(chan, src);
                ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
                              NISTC_RTSI_TRIGA_OUT_REG);
-       } else if (chan < 8) {
+       } else if (chan < NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
                devpriv->rtsi_trig_b_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan);
                devpriv->rtsi_trig_b_output_reg |= NISTC_RTSI_TRIG(chan, src);
                ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
                              NISTC_RTSI_TRIGB_OUT_REG);
+       } else if (chan != NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
+               /* probably should never reach this, since the
+                * ni_valid_rtsi_output_source above errors out if chan is too
+                * high
+                */
+               dev_err(dev->class_dev, "%s: unknown rtsi channel\n", __func__);
+               return -EINVAL;
        }
        return 2;
 }
@@ -5015,31 +5101,35 @@ static unsigned int ni_get_rtsi_routing(struct comedi_device *dev,
 {
        struct ni_private *devpriv = dev->private;
 
+       if (chan >= TRIGGER_LINE(0))
+               /* allow new and old names of rtsi channels to work. */
+               chan -= TRIGGER_LINE(0);
+
        if (chan < 4) {
                return NISTC_RTSI_TRIG_TO_SRC(chan,
                                              devpriv->rtsi_trig_a_output_reg);
        } else if (chan < NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
                return NISTC_RTSI_TRIG_TO_SRC(chan,
                                              devpriv->rtsi_trig_b_output_reg);
-       } else {
-               if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN)
-                       return NI_RTSI_OUTPUT_RTSI_OSC;
-               dev_err(dev->class_dev, "bug! should never get here?\n");
-               return 0;
+       } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
+               return NI_RTSI_OUTPUT_RTSI_OSC;
        }
+
+       dev_err(dev->class_dev, "%s: unknown rtsi channel\n", __func__);
+       return -EINVAL;
 }
 
-static int ni_rtsi_insn_config(struct comedi_device *dev,
-                              struct comedi_subdevice *s,
-                              struct comedi_insn *insn,
-                              unsigned int *data)
+static void ni_set_rtsi_direction(struct comedi_device *dev, int chan,
+                                 unsigned int direction)
 {
        struct ni_private *devpriv = dev->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int max_chan = NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series);
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
+       if (chan >= TRIGGER_LINE(0))
+               /* allow new and old names of rtsi channels to work. */
+               chan -= TRIGGER_LINE(0);
+
+       if (direction == COMEDI_OUTPUT) {
                if (chan < max_chan) {
                        devpriv->rtsi_trig_direction_reg |=
                            NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series);
@@ -5047,10 +5137,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
                        devpriv->rtsi_trig_direction_reg |=
                            NISTC_RTSI_TRIG_DRV_CLK;
                }
-               ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
-                             NISTC_RTSI_TRIG_DIR_REG);
-               break;
-       case INSN_CONFIG_DIO_INPUT:
+       } else {
                if (chan < max_chan) {
                        devpriv->rtsi_trig_direction_reg &=
                            ~NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series);
@@ -5058,23 +5145,53 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
                        devpriv->rtsi_trig_direction_reg &=
                            ~NISTC_RTSI_TRIG_DRV_CLK;
                }
-               ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
-                             NISTC_RTSI_TRIG_DIR_REG);
+       }
+       ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+                     NISTC_RTSI_TRIG_DIR_REG);
+}
+
+static int ni_get_rtsi_direction(struct comedi_device *dev, int chan)
+{
+       struct ni_private *devpriv = dev->private;
+       unsigned int max_chan = NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series);
+
+       if (chan >= TRIGGER_LINE(0))
+               /* allow new and old names of rtsi channels to work. */
+               chan -= TRIGGER_LINE(0);
+
+       if (chan < max_chan) {
+               return (devpriv->rtsi_trig_direction_reg &
+                       NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series))
+                          ? COMEDI_OUTPUT : COMEDI_INPUT;
+       } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
+               return (devpriv->rtsi_trig_direction_reg &
+                       NISTC_RTSI_TRIG_DRV_CLK)
+                          ? COMEDI_OUTPUT : COMEDI_INPUT;
+       }
+       return -EINVAL;
+}
+
+static int ni_rtsi_insn_config(struct comedi_device *dev,
+                              struct comedi_subdevice *s,
+                              struct comedi_insn *insn,
+                              unsigned int *data)
+{
+       struct ni_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+
+       switch (data[0]) {
+       case COMEDI_OUTPUT:
+       case COMEDI_INPUT:
+               ni_set_rtsi_direction(dev, chan, data[0]);
                break;
-       case INSN_CONFIG_DIO_QUERY:
-               if (chan < max_chan) {
-                       data[1] =
-                           (devpriv->rtsi_trig_direction_reg &
-                            NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series))
-                               ? INSN_CONFIG_DIO_OUTPUT
-                               : INSN_CONFIG_DIO_INPUT;
-               } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
-                       data[1] = (devpriv->rtsi_trig_direction_reg &
-                                  NISTC_RTSI_TRIG_DRV_CLK)
-                                 ? INSN_CONFIG_DIO_OUTPUT
-                                 : INSN_CONFIG_DIO_INPUT;
-               }
+       case INSN_CONFIG_DIO_QUERY: {
+               int ret = ni_get_rtsi_direction(dev, chan);
+
+               if (ret < 0)
+                       return ret;
+               data[1] = ret;
                return 2;
+       }
        case INSN_CONFIG_SET_CLOCK_SRC:
                return ni_set_master_clock(dev, data[1], data[2]);
        case INSN_CONFIG_GET_CLOCK_SRC:
@@ -5083,9 +5200,14 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
                return 3;
        case INSN_CONFIG_SET_ROUTING:
                return ni_set_rtsi_routing(dev, chan, data[1]);
-       case INSN_CONFIG_GET_ROUTING:
-               data[1] = ni_get_rtsi_routing(dev, chan);
+       case INSN_CONFIG_GET_ROUTING: {
+               int ret = ni_get_rtsi_routing(dev, chan);
+
+               if (ret < 0)
+                       return ret;
+               data[1] = ret;
                return 2;
+       }
        default:
                return -EINVAL;
        }
@@ -5102,9 +5224,275 @@ static int ni_rtsi_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
+/*
+ * Default routing for RTSI trigger lines.
+ *
+ * These values are used here in the init function, as well as in the
+ * disconnect_route function, after a RTSI route has been disconnected.
+ */
+static const int default_rtsi_routing[] = {
+       [0] = NI_RTSI_OUTPUT_ADR_START1,
+       [1] = NI_RTSI_OUTPUT_ADR_START2,
+       [2] = NI_RTSI_OUTPUT_SCLKG,
+       [3] = NI_RTSI_OUTPUT_DACUPDN,
+       [4] = NI_RTSI_OUTPUT_DA_START1,
+       [5] = NI_RTSI_OUTPUT_G_SRC0,
+       [6] = NI_RTSI_OUTPUT_G_GATE0,
+       [7] = NI_RTSI_OUTPUT_RTSI_OSC,
+};
+
+/*
+ * Route signals through RGOUT0 terminal.
+ * @reg: raw register value of RGOUT0 bits (only bit0 is important).
+ * @dev: comedi device handle.
+ */
+static void set_rgout0_reg(int reg, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+
+       if (devpriv->is_m_series) {
+               devpriv->rtsi_trig_direction_reg &=
+                       ~NISTC_RTSI_TRIG_DIR_SUB_SEL1;
+               devpriv->rtsi_trig_direction_reg |=
+                       (reg << NISTC_RTSI_TRIG_DIR_SUB_SEL1_SHIFT) &
+                       NISTC_RTSI_TRIG_DIR_SUB_SEL1;
+               ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+                             NISTC_RTSI_TRIG_DIR_REG);
+       } else {
+               devpriv->rtsi_trig_b_output_reg &= ~NISTC_RTSI_TRIGB_SUB_SEL1;
+               devpriv->rtsi_trig_b_output_reg |=
+                       (reg << NISTC_RTSI_TRIGB_SUB_SEL1_SHIFT) &
+                       NISTC_RTSI_TRIGB_SUB_SEL1;
+               ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+                             NISTC_RTSI_TRIGB_OUT_REG);
+       }
+}
+
+static int get_rgout0_reg(struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int reg;
+
+       if (devpriv->is_m_series)
+               reg = (devpriv->rtsi_trig_direction_reg &
+                      NISTC_RTSI_TRIG_DIR_SUB_SEL1)
+                   >> NISTC_RTSI_TRIG_DIR_SUB_SEL1_SHIFT;
+       else
+               reg = (devpriv->rtsi_trig_b_output_reg &
+                      NISTC_RTSI_TRIGB_SUB_SEL1)
+                   >> NISTC_RTSI_TRIGB_SUB_SEL1_SHIFT;
+       return reg;
+}
+
+static inline int get_rgout0_src(struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int reg = get_rgout0_reg(dev);
+
+       return ni_find_route_source(reg, NI_RGOUT0, &devpriv->routing_tables);
+}
+
+/*
+ * Route signals through RGOUT0 terminal and increment the RGOUT0 use for this
+ * particular route.
+ * @src: device-global signal name
+ * @dev: comedi device handle
+ *
+ * Return: -EINVAL if the source is not valid to route to RGOUT0;
+ *        -EBUSY if the RGOUT0 is already used;
+ *        0 if successful.
+ */
+static int incr_rgout0_src_use(int src, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       s8 reg = ni_lookup_route_register(CR_CHAN(src), NI_RGOUT0,
+                                         &devpriv->routing_tables);
+
+       if (reg < 0)
+               return -EINVAL;
+
+       if (devpriv->rgout0_usage > 0 && get_rgout0_reg(dev) != reg)
+               return -EBUSY;
+
+       ++devpriv->rgout0_usage;
+       set_rgout0_reg(reg, dev);
+       return 0;
+}
+
+/*
+ * Unroute signals through RGOUT0 terminal and deccrement the RGOUT0 use for
+ * this particular source.  This function does not actually unroute anything
+ * with respect to RGOUT0.  It does, on the other hand, decrement the usage
+ * counter for the current src->RGOUT0 mapping.
+ *
+ * Return: -EINVAL if the source is not already routed to RGOUT0 (or usage is
+ *     already at zero); 0 if successful.
+ */
+static int decr_rgout0_src_use(int src, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       s8 reg = ni_lookup_route_register(CR_CHAN(src), NI_RGOUT0,
+                                         &devpriv->routing_tables);
+
+       if (devpriv->rgout0_usage > 0 && get_rgout0_reg(dev) == reg) {
+               --devpriv->rgout0_usage;
+               if (!devpriv->rgout0_usage)
+                       set_rgout0_reg(0, dev); /* ok default? */
+               return 0;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Route signals through given NI_RTSI_BRD mux.
+ * @i: index of mux to route
+ * @reg: raw register value of RTSI_BRD bits
+ * @dev: comedi device handle
+ */
+static void set_ith_rtsi_brd_reg(int i, int reg, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int reg_i_sz = 3; /* value for e-series */
+       int reg_i_mask;
+       int reg_i_shift;
+
+       if (devpriv->is_m_series)
+               reg_i_sz = 4;
+       reg_i_mask = ~((~0) << reg_i_sz);
+       reg_i_shift = i * reg_i_sz;
+
+       /* clear out the current reg_i for ith brd */
+       devpriv->rtsi_shared_mux_reg &= ~(reg_i_mask       << reg_i_shift);
+       /* (softcopy) write the new reg_i for ith brd */
+       devpriv->rtsi_shared_mux_reg |= (reg & reg_i_mask) << reg_i_shift;
+       /* (hardcopy) write the new reg_i for ith brd */
+       ni_stc_writew(dev, devpriv->rtsi_shared_mux_reg, NISTC_RTSI_BOARD_REG);
+}
+
+static int get_ith_rtsi_brd_reg(int i, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int reg_i_sz = 3; /* value for e-series */
+       int reg_i_mask;
+       int reg_i_shift;
+
+       if (devpriv->is_m_series)
+               reg_i_sz = 4;
+       reg_i_mask = ~((~0) << reg_i_sz);
+       reg_i_shift = i * reg_i_sz;
+
+       return (devpriv->rtsi_shared_mux_reg >> reg_i_shift) & reg_i_mask;
+}
+
+static inline int get_rtsi_brd_src(int brd, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int brd_index = brd;
+       int reg;
+
+       if (brd >= NI_RTSI_BRD(0))
+               brd_index = brd - NI_RTSI_BRD(0);
+       else
+               brd = NI_RTSI_BRD(brd);
+       /*
+        * And now:
+        * brd : device-global name
+        * brd_index : index number of RTSI_BRD mux
+        */
+
+       reg = get_ith_rtsi_brd_reg(brd_index, dev);
+
+       return ni_find_route_source(reg, brd, &devpriv->routing_tables);
+}
+
+/*
+ * Route signals through NI_RTSI_BRD mux and increment the use counter for this
+ * particular route.
+ *
+ * Return: -EINVAL if the source is not valid to route to NI_RTSI_BRD(i);
+ *        -EBUSY if all NI_RTSI_BRD muxes are already used;
+ *        NI_RTSI_BRD(i) of allocated ith mux if successful.
+ */
+static int incr_rtsi_brd_src_use(int src, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int first_available = -1;
+       int err = -EINVAL;
+       s8 reg;
+       int i;
+
+       /* first look for a mux that is already configured to provide src */
+       for (i = 0; i < NUM_RTSI_SHARED_MUXS; ++i) {
+               reg = ni_lookup_route_register(CR_CHAN(src), NI_RTSI_BRD(i),
+                                              &devpriv->routing_tables);
+
+               if (reg < 0)
+                       continue; /* invalid route */
+
+               if (!devpriv->rtsi_shared_mux_usage[i]) {
+                       if (first_available < 0)
+                               /* found the first unused, but usable mux */
+                               first_available = i;
+               } else {
+                       /*
+                        * we've seen at least one possible route, so change the
+                        * final error to -EBUSY in case there are no muxes
+                        * available.
+                        */
+                       err = -EBUSY;
+
+                       if (get_ith_rtsi_brd_reg(i, dev) == reg) {
+                               /*
+                                * we've found a mux that is already being used
+                                * to provide the requested signal.  Reuse it.
+                                */
+                               goto success;
+                       }
+               }
+       }
+
+       if (first_available < 0)
+               return err;
+
+       /* we did not find a mux to reuse, but there is at least one usable */
+       i = first_available;
+
+success:
+       ++devpriv->rtsi_shared_mux_usage[i];
+       set_ith_rtsi_brd_reg(i, reg, dev);
+       return NI_RTSI_BRD(i);
+}
+
+/*
+ * Unroute signals through NI_RTSI_BRD mux and decrement the user counter for
+ * this particular route.
+ *
+ * Return: -EINVAL if the source is not already routed to rtsi_brd(i) (or usage
+ *     is already at zero); 0 if successful.
+ */
+static int decr_rtsi_brd_src_use(int src, int rtsi_brd,
+                                struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       s8 reg = ni_lookup_route_register(CR_CHAN(src), rtsi_brd,
+                                         &devpriv->routing_tables);
+       const int i = rtsi_brd - NI_RTSI_BRD(0);
+
+       if (devpriv->rtsi_shared_mux_usage[i] > 0 &&
+           get_ith_rtsi_brd_reg(i, dev) == reg) {
+               --devpriv->rtsi_shared_mux_usage[i];
+               if (!devpriv->rtsi_shared_mux_usage[i])
+                       set_ith_rtsi_brd_reg(i, 0, dev); /* ok default? */
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
 static void ni_rtsi_init(struct comedi_device *dev)
 {
        struct ni_private *devpriv = dev->private;
+       int i;
 
        /*  Initialises the RTSI bus signal switch to a default state */
 
@@ -5117,28 +5505,328 @@ static void ni_rtsi_init(struct comedi_device *dev)
        /*  Set clock mode to internal */
        if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
                dev_err(dev->class_dev, "ni_set_master_clock failed, bug?\n");
-       /*  default internal lines routing to RTSI bus lines */
-       devpriv->rtsi_trig_a_output_reg =
-           NISTC_RTSI_TRIG(0, NI_RTSI_OUTPUT_ADR_START1) |
-           NISTC_RTSI_TRIG(1, NI_RTSI_OUTPUT_ADR_START2) |
-           NISTC_RTSI_TRIG(2, NI_RTSI_OUTPUT_SCLKG) |
-           NISTC_RTSI_TRIG(3, NI_RTSI_OUTPUT_DACUPDN);
-       ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
-                     NISTC_RTSI_TRIGA_OUT_REG);
-       devpriv->rtsi_trig_b_output_reg =
-           NISTC_RTSI_TRIG(4, NI_RTSI_OUTPUT_DA_START1) |
-           NISTC_RTSI_TRIG(5, NI_RTSI_OUTPUT_G_SRC0) |
-           NISTC_RTSI_TRIG(6, NI_RTSI_OUTPUT_G_GATE0);
-       if (devpriv->is_m_series)
-               devpriv->rtsi_trig_b_output_reg |=
-                   NISTC_RTSI_TRIG(7, NI_RTSI_OUTPUT_RTSI_OSC);
-       ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
-                     NISTC_RTSI_TRIGB_OUT_REG);
 
+       /* default internal lines routing to RTSI bus lines */
+       for (i = 0; i < 8; ++i) {
+               ni_set_rtsi_direction(dev, i, COMEDI_INPUT);
+               ni_set_rtsi_routing(dev, i, default_rtsi_routing[i]);
+       }
+
+       /*
+        * Sets the source and direction of the 4 on board lines.
+        * This configures all board lines to be:
+        * for e-series:
+        *   1) inputs (not sure what "output" would mean)
+        *   2) copying TRIGGER_LINE(0) (or RTSI0) output
+        * for m-series:
+        *   copying NI_PFI(0) output
+        */
+       devpriv->rtsi_shared_mux_reg = 0;
+       for (i = 0; i < 4; ++i)
+               set_ith_rtsi_brd_reg(i, 0, dev);
+       memset(devpriv->rtsi_shared_mux_usage, 0,
+              sizeof(devpriv->rtsi_shared_mux_usage));
+
+       /* initialize rgout0 pin as unused. */
+       devpriv->rgout0_usage = 0;
+       set_rgout0_reg(0, dev);
+}
+
+/* Get route of GPFO_i/CtrOut pins */
+static inline int ni_get_gout_routing(unsigned int dest,
+                                     struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       unsigned int reg = devpriv->an_trig_etc_reg;
+
+       switch (dest) {
+       case 0:
+               if (reg & NISTC_ATRIG_ETC_GPFO_0_ENA)
+                       return NISTC_ATRIG_ETC_GPFO_0_SEL_TO_SRC(reg);
+               break;
+       case 1:
+               if (reg & NISTC_ATRIG_ETC_GPFO_1_ENA)
+                       return NISTC_ATRIG_ETC_GPFO_1_SEL_TO_SRC(reg);
+               break;
+       }
+
+       return -EINVAL;
+}
+
+/* Set route of GPFO_i/CtrOut pins */
+static inline int ni_disable_gout_routing(unsigned int dest,
+                                         struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+
+       switch (dest) {
+       case 0:
+               devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_0_ENA;
+               break;
+       case 1:
+               devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_1_ENA;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG);
+       return 0;
+}
+
+/* Set route of GPFO_i/CtrOut pins */
+static inline int ni_set_gout_routing(unsigned int src, unsigned int dest,
+                                     struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+
+       switch (dest) {
+       case 0:
+               /* clear reg */
+               devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_0_SEL(-1);
+               /* set reg */
+               devpriv->an_trig_etc_reg |= NISTC_ATRIG_ETC_GPFO_0_ENA
+                                        |  NISTC_ATRIG_ETC_GPFO_0_SEL(src);
+               break;
+       case 1:
+               /* clear reg */
+               devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_1_SEL;
+               src = src ? NISTC_ATRIG_ETC_GPFO_1_SEL : 0;
+               /* set reg */
+               devpriv->an_trig_etc_reg |= NISTC_ATRIG_ETC_GPFO_1_ENA | src;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG);
+       return 0;
+}
+
+/*
+ * Retrieves the current source of the output selector for the given
+ * destination.  If the terminal for the destination is not already configured
+ * as an output, this function returns -EINVAL as error.
+ *
+ * Return: the register value of the destination output selector;
+ *        -EINVAL if terminal is not configured for output.
+ */
+static int get_output_select_source(int dest, struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       int reg = -1;
+
+       if (channel_is_pfi(dest)) {
+               if (ni_get_pfi_direction(dev, dest) == COMEDI_OUTPUT)
+                       reg = ni_get_pfi_routing(dev, dest);
+       } else if (channel_is_rtsi(dest)) {
+               if (ni_get_rtsi_direction(dev, dest) == COMEDI_OUTPUT) {
+                       reg = ni_get_rtsi_routing(dev, dest);
+
+                       if (reg == NI_RTSI_OUTPUT_RGOUT0) {
+                               dest = NI_RGOUT0; /* prepare for lookup below */
+                               reg = get_rgout0_reg(dev);
+                       } else if (reg >= NI_RTSI_OUTPUT_RTSI_BRD(0) &&
+                                  reg <= NI_RTSI_OUTPUT_RTSI_BRD(3)) {
+                               const int i = reg - NI_RTSI_OUTPUT_RTSI_BRD(0);
+
+                               dest = NI_RTSI_BRD(i); /* prepare for lookup */
+                               reg = get_ith_rtsi_brd_reg(i, dev);
+                       }
+               }
+       } else if (dest >= NI_CtrOut(0) && dest <= NI_CtrOut(-1)) {
+               /*
+                * not handled by ni_tio.  Only available for GPFO registers in
+                * e/m series.
+                */
+               dest -= NI_CtrOut(0);
+               if (dest > 1)
+                       /* there are only two g_out outputs. */
+                       return -EINVAL;
+               reg = ni_get_gout_routing(dest, dev);
+       } else if (channel_is_ctr(dest)) {
+               reg = ni_tio_get_routing(devpriv->counter_dev, dest);
+       } else {
+               dev_dbg(dev->class_dev, "%s: unhandled destination (%d) queried\n",
+                       __func__, dest);
+       }
+
+       if (reg >= 0)
+               return ni_find_route_source(CR_CHAN(reg), dest,
+                                           &devpriv->routing_tables);
+       return -EINVAL;
+}
+
+/*
+ * Test a route:
+ *
+ * Return: -1 if not connectible;
+ *         0 if connectible and not connected;
+ *         1 if connectible and connected.
+ */
+static int test_route(unsigned int src, unsigned int dest,
+                     struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       s8 reg = ni_route_to_register(CR_CHAN(src), dest,
+                                     &devpriv->routing_tables);
+
+       if (reg < 0)
+               return -1;
+       if (get_output_select_source(dest, dev) != CR_CHAN(src))
+               return 0;
+       return 1;
+}
+
+/* Connect the actual route.  */
+static int connect_route(unsigned int src, unsigned int dest,
+                        struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       s8 reg = ni_route_to_register(CR_CHAN(src), dest,
+                                     &devpriv->routing_tables);
+       s8 current_src;
+
+       if (reg < 0)
+               /* route is not valid */
+               return -EINVAL;
+
+       current_src = get_output_select_source(dest, dev);
+       if (current_src == CR_CHAN(src))
+               return -EALREADY;
+       if (current_src >= 0)
+               /* destination mux is already busy. complain, don't overwrite */
+               return -EBUSY;
+
+       /* The route is valid and available. Now connect... */
+       if (channel_is_pfi(dest)) {
+               /* set routing source, then open output */
+               ni_set_pfi_routing(dev, dest, reg);
+               ni_set_pfi_direction(dev, dest, COMEDI_OUTPUT);
+       } else if (channel_is_rtsi(dest)) {
+               if (reg == NI_RTSI_OUTPUT_RGOUT0) {
+                       int ret = incr_rgout0_src_use(src, dev);
+
+                       if (ret < 0)
+                               return ret;
+               } else if (ni_rtsi_route_requires_mux(reg)) {
+                       /* Attempt to allocate and  route (src->brd) */
+                       int brd = incr_rtsi_brd_src_use(src, dev);
+
+                       if (brd < 0)
+                               return brd;
+
+                       /* Now lookup the register value for (brd->dest) */
+                       reg = ni_lookup_route_register(
+                               brd, dest, &devpriv->routing_tables);
+               }
+
+               ni_set_rtsi_direction(dev, dest, COMEDI_OUTPUT);
+               ni_set_rtsi_routing(dev, dest, reg);
+       } else if (dest >= NI_CtrOut(0) && dest <= NI_CtrOut(-1)) {
+               /*
+                * not handled by ni_tio.  Only available for GPFO registers in
+                * e/m series.
+                */
+               dest -= NI_CtrOut(0);
+               if (dest > 1)
+                       /* there are only two g_out outputs. */
+                       return -EINVAL;
+               if (ni_set_gout_routing(src, dest, dev))
+                       return -EINVAL;
+       } else if (channel_is_ctr(dest)) {
+               /*
+                * we are adding back the channel modifier info to set
+                * invert/edge info passed by the user
+                */
+               ni_tio_set_routing(devpriv->counter_dev, dest,
+                                  reg | (src & ~CR_CHAN(-1)));
+       } else {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int disconnect_route(unsigned int src, unsigned int dest,
+                           struct comedi_device *dev)
+{
+       struct ni_private *devpriv = dev->private;
+       s8 reg = ni_route_to_register(CR_CHAN(src), dest,
+                                     &devpriv->routing_tables);
+
+       if (reg < 0)
+               /* route is not valid */
+               return -EINVAL;
+       if (get_output_select_source(dest, dev) != src)
+               /* cannot disconnect something not connected */
+               return -EINVAL;
+
+       /* The route is valid and is connected.  Now disconnect... */
+       if (channel_is_pfi(dest)) {
+               /* set the pfi to high impedance, and disconnect */
+               ni_set_pfi_direction(dev, dest, COMEDI_INPUT);
+               ni_set_pfi_routing(dev, dest, NI_PFI_OUTPUT_PFI_DEFAULT);
+       } else if (channel_is_rtsi(dest)) {
+               if (reg == NI_RTSI_OUTPUT_RGOUT0) {
+                       int ret = decr_rgout0_src_use(src, dev);
+
+                       if (ret < 0)
+                               return ret;
+               } else if (ni_rtsi_route_requires_mux(reg)) {
+                       /* find which RTSI_BRD line is source for rtsi pin */
+                       int brd = ni_find_route_source(
+                               ni_get_rtsi_routing(dev, dest), dest,
+                               &devpriv->routing_tables);
+
+                       if (brd < 0)
+                               return brd;
+
+                       /* decrement/disconnect RTSI_BRD line from source */
+                       decr_rtsi_brd_src_use(src, brd, dev);
+               }
+
+               /* set rtsi output selector to default state */
+               reg = default_rtsi_routing[dest - TRIGGER_LINE(0)];
+               ni_set_rtsi_direction(dev, dest, COMEDI_INPUT);
+               ni_set_rtsi_routing(dev, dest, reg);
+       } else if (dest >= NI_CtrOut(0) && dest <= NI_CtrOut(-1)) {
+               /*
+                * not handled by ni_tio.  Only available for GPFO registers in
+                * e/m series.
+                */
+               dest -= NI_CtrOut(0);
+               if (dest > 1)
+                       /* there are only two g_out outputs. */
+                       return -EINVAL;
+               reg = ni_disable_gout_routing(dest, dev);
+       } else if (channel_is_ctr(dest)) {
+               ni_tio_unset_routing(devpriv->counter_dev, dest);
+       } else {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int ni_global_insn_config(struct comedi_device *dev,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       switch (data[0]) {
+       case INSN_DEVICE_CONFIG_TEST_ROUTE:
+               data[0] = test_route(data[1], data[2], dev);
+               return 2;
+       case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
+               return connect_route(data[1], data[2], dev);
+       case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
+               return disconnect_route(data[1], data[2], dev);
        /*
-        * Sets the source and direction of the 4 on board lines
-        * ni_stc_writew(dev, 0, NISTC_RTSI_BOARD_REG);
+        * This case is already handled one level up.
+        * case INSN_DEVICE_CONFIG_GET_ROUTES:
         */
+       default:
+               return -EINVAL;
+       }
+       return 1;
 }
 
 #ifdef PCIDMA
@@ -5244,6 +5932,16 @@ static int ni_alloc_private(struct comedi_device *dev)
        return 0;
 }
 
+static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
+                                        unsigned int n_pairs,
+                                        unsigned int *pair_data)
+{
+       struct ni_private *devpriv = dev->private;
+
+       return ni_get_valid_routes(&devpriv->routing_tables, n_pairs,
+                                  pair_data);
+}
+
 static int ni_E_init(struct comedi_device *dev,
                     unsigned int interrupt_pin, unsigned int irq_polarity)
 {
@@ -5252,6 +5950,24 @@ static int ni_E_init(struct comedi_device *dev,
        struct comedi_subdevice *s;
        int ret;
        int i;
+       const char *dev_family = devpriv->is_m_series ? "ni_mseries"
+                                                     : "ni_eseries";
+
+       /* prepare the device for globally-named routes. */
+       if (ni_assign_device_routes(dev_family, board->name,
+                                   &devpriv->routing_tables) < 0) {
+               dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
+                        __func__, board->name);
+               dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
+                        __func__, board->name);
+       } else {
+               /*
+                * only(?) assign insn_device_config if we have global names for
+                * this device.
+                */
+               dev->insn_device_config = ni_global_insn_config;
+               dev->get_valid_routes = _ni_get_valid_routes;
+       }
 
        if (board->n_aochan > MAX_N_AO_CHAN) {
                dev_err(dev->class_dev, "bug! n_aochan > MAX_N_AO_CHAN\n");
@@ -5508,7 +6224,9 @@ static int ni_E_init(struct comedi_device *dev,
                                        (devpriv->is_m_series)
                                                ? ni_gpct_variant_m_series
                                                : ni_gpct_variant_e_series,
-                                       NUM_GPCT);
+                                       NUM_GPCT,
+                                       NUM_GPCT,
+                                       &devpriv->routing_tables);
        if (!devpriv->counter_dev)
                return -ENOMEM;
 
@@ -5517,8 +6235,6 @@ static int ni_E_init(struct comedi_device *dev,
                struct ni_gpct *gpct = &devpriv->counter_dev->counters[i];
 
                /* setup and initialize the counter */
-               gpct->chip_index = 0;
-               gpct->counter_index = i;
                ni_tio_init_counter(gpct);
 
                s = &dev->subdevices[NI_GPCT_SUBDEV(i)];
@@ -5544,6 +6260,10 @@ static int ni_E_init(struct comedi_device *dev,
                s->private      = gpct;
        }
 
+       /* Initialize GPFO_{0,1} to produce output of counters */
+       ni_set_gout_routing(0, 0, dev); /* output of counter 0; DAQ STC, p338 */
+       ni_set_gout_routing(0, 1, dev); /* output of counter 1; DAQ STC, p338 */
+
        /* Frequency output subdevice */
        s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
        s->type         = COMEDI_SUBD_COUNTER;
index 6692af5ff79bf1b5f3119c7d2111da96517bdca9..b9a0dc6eac443ced99a36dc74d76a9a469875635 100644 (file)
@@ -260,18 +260,22 @@ enum nidio_boardid {
 struct nidio_board {
        const char *name;
        unsigned int uses_firmware:1;
+       unsigned int dio_speed;
 };
 
 static const struct nidio_board nidio_boards[] = {
        [BOARD_PCIDIO_32HS] = {
                .name           = "pci-dio-32hs",
+               .dio_speed      = 50,
        },
        [BOARD_PXI6533] = {
                .name           = "pxi-6533",
+               .dio_speed      = 50,
        },
        [BOARD_PCI6534] = {
                .name           = "pci-6534",
                .uses_firmware  = 1,
+               .dio_speed      = 50,
        },
 };
 
@@ -467,6 +471,15 @@ static int ni_pcidio_insn_config(struct comedi_device *dev,
 {
        int ret;
 
+       if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
+               const struct nidio_board *board = dev->board_ptr;
+
+               /* we don't care about actual channels */
+               data[1] = board->dio_speed;
+               data[2] = 0;
+               return 0;
+       }
+
        ret = comedi_dio_insn_config(dev, s, insn, data, 0);
        if (ret)
                return ret;
index f9e466d18b3fcb14d4ed7f58742c887f17b01752..14b26fffe0492ad3b4d5e380e9dbe0c3523f5ea0 100644 (file)
@@ -693,6 +693,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ai_speed       = 4000,
                .reg_type       = ni_reg_622x,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PCI6221] = {
                .name           = "pci-6221",
@@ -708,6 +709,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_622x,
                .ao_speed       = 1200,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PCI6221_37PIN] = {
                .name           = "pci-6221_37pin",
@@ -738,6 +740,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_622x,
                .ao_speed       = 1200,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PCI6224] = {
                .name           = "pci-6224",
@@ -749,6 +752,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_622x,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PXI6224] = {
                .name           = "pxi-6224",
@@ -760,6 +764,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_622x,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PCI6225] = {
                .name           = "pci-6225",
@@ -776,6 +781,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_speed       = 1200,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PXI6225] = {
                .name           = "pxi-6225",
@@ -792,6 +798,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_speed       = 1200,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PCI6229] = {
                .name           = "pci-6229",
@@ -824,6 +831,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_speed       = 1200,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 1000,
        },
        [BOARD_PCI6250] = {
                .name           = "pci-6250",
@@ -844,6 +852,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ai_speed       = 800,
                .reg_type       = ni_reg_625x,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6251] = {
                .name           = "pci-6251",
@@ -859,6 +868,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_625x,
                .ao_speed       = 350,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PXI6251] = {
                .name           = "pxi-6251",
@@ -874,6 +884,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_625x,
                .ao_speed       = 350,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCIE6251] = {
                .name           = "pcie-6251",
@@ -889,6 +900,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_625x,
                .ao_speed       = 350,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PXIE6251] = {
                .name           = "pxie-6251",
@@ -904,6 +916,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_625x,
                .ao_speed       = 350,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6254] = {
                .name           = "pci-6254",
@@ -926,6 +939,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_625x,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6259] = {
                .name           = "pci-6259",
@@ -958,6 +972,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_speed       = 350,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCIE6259] = {
                .name           = "pcie-6259",
@@ -990,6 +1005,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_speed       = 350,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6280] = {
                .name           = "pci-6280",
@@ -1012,6 +1028,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_fifo_depth  = 8191,
                .reg_type       = ni_reg_628x,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6281] = {
                .name           = "pci-6281",
@@ -1027,6 +1044,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_628x,
                .ao_speed       = 350,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PXI6281] = {
                .name           = "pxi-6281",
@@ -1042,6 +1060,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_628x,
                .ao_speed       = 350,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6284] = {
                .name           = "pci-6284",
@@ -1064,6 +1083,7 @@ static const struct ni_board_struct ni_boards[] = {
                .reg_type       = ni_reg_628x,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6289] = {
                .name           = "pci-6289",
@@ -1096,6 +1116,7 @@ static const struct ni_board_struct ni_boards[] = {
                .ao_speed       = 350,
                .has_32dio_chan = 1,
                .caldac         = { caldac_none },
+               .dio_speed      = 100,
        },
        [BOARD_PCI6143] = {
                .name           = "pci-6143",
diff --git a/drivers/staging/comedi/drivers/ni_routes.c b/drivers/staging/comedi/drivers/ni_routes.c
new file mode 100644 (file)
index 0000000..eb61494
--- /dev/null
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routes.c
+ *  Route information for NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/bsearch.h>
+#include <linux/sort.h>
+
+#include "../comedi.h"
+
+#include "ni_routes.h"
+#include "ni_routing/ni_route_values.h"
+#include "ni_routing/ni_device_routes.h"
+
+/*
+ * This is defined in ni_routing/ni_route_values.h:
+ * #define B(x)        ((x) - NI_NAMES_BASE)
+ */
+
+/*
+ * These are defined in ni_routing/ni_route_values.h to identify clearly
+ * elements of the table that were set.  In other words, entries that are zero
+ * are invalid.  To get the value to use for the register, one must mask out the
+ * high bit.
+ *
+ * #define V(x)        ((x) | 0x80)
+ *
+ * #define UNMARK(x)   ((x) & (~(0x80)))
+ *
+ */
+
+/* Helper for accessing data. */
+#define RVi(table, src, dest)  ((table)[(dest) * NI_NUM_NAMES + (src)])
+
+static const size_t route_table_size = NI_NUM_NAMES * NI_NUM_NAMES;
+
+/*
+ * Find the proper route_values and ni_device_routes tables for this particular
+ * device.
+ *
+ * Return: -ENODATA if either was not found; 0 if both were found.
+ */
+static int ni_find_device_routes(const char *device_family,
+                                const char *board_name,
+                                struct ni_route_tables *tables)
+{
+       const struct ni_device_routes *dr = NULL;
+       const u8 *rv = NULL;
+       int i;
+
+       /* First, find the register_values table for this device family */
+       for (i = 0; ni_all_route_values[i]; ++i) {
+               if (memcmp(ni_all_route_values[i]->family, device_family,
+                          strnlen(device_family, 30)) == 0) {
+                       rv = &ni_all_route_values[i]->register_values[0][0];
+                       break;
+               }
+       }
+
+       if (!rv)
+               return -ENODATA;
+
+       /* Second, find the set of routes valid for this device. */
+       for (i = 0; ni_device_routes_list[i]; ++i) {
+               if (memcmp(ni_device_routes_list[i]->device, board_name,
+                          strnlen(board_name, 30)) == 0) {
+                       dr = ni_device_routes_list[i];
+                       break;
+               }
+       }
+
+       if (!dr)
+               return -ENODATA;
+
+       tables->route_values = rv;
+       tables->valid_routes = dr;
+
+       return 0;
+}
+
+/**
+ * ni_assign_device_routes() - Assign the proper lookup table for NI signal
+ *                            routing to the specified NI device.
+ *
+ * Return: -ENODATA if assignment was not successful; 0 if successful.
+ */
+int ni_assign_device_routes(const char *device_family,
+                           const char *board_name,
+                           struct ni_route_tables *tables)
+{
+       memset(tables, 0, sizeof(struct ni_route_tables));
+       return ni_find_device_routes(device_family, board_name, tables);
+}
+EXPORT_SYMBOL_GPL(ni_assign_device_routes);
+
+/**
+ * ni_count_valid_routes() - Count the number of valid routes.
+ * @tables: Routing tables for which to count all valid routes.
+ */
+unsigned int ni_count_valid_routes(const struct ni_route_tables *tables)
+{
+       int total = 0;
+       int i;
+
+       for (i = 0; i < tables->valid_routes->n_route_sets; ++i) {
+               const struct ni_route_set *R = &tables->valid_routes->routes[i];
+               int j;
+
+               for (j = 0; j < R->n_src; ++j) {
+                       const int src  = R->src[j];
+                       const int dest = R->dest;
+                       const u8 *rv = tables->route_values;
+
+                       if (RVi(rv, B(src), B(dest)))
+                               /* direct routing is valid */
+                               ++total;
+                       else if (channel_is_rtsi(dest) &&
+                                (RVi(rv, B(src), B(NI_RGOUT0)) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(0))) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(1))) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(2))) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(3))))) {
+                               ++total;
+                       }
+               }
+       }
+       return total;
+}
+EXPORT_SYMBOL_GPL(ni_count_valid_routes);
+
+/**
+ * ni_get_valid_routes() - Implements INSN_DEVICE_CONFIG_GET_ROUTES.
+ * @tables:    pointer to relevant set of routing tables.
+ * @n_pairs:   Number of pairs for which memory is allocated by the user.  If
+ *             the user specifies '0', only the number of available pairs is
+ *             returned.
+ * @pair_data: Pointer to memory allocated to return pairs back to user.  Each
+ *             even, odd indexed member of this array will hold source,
+ *             destination of a route pair respectively.
+ *
+ * Return: the number of valid routes if n_pairs == 0; otherwise, the number of
+ *     valid routes copied.
+ */
+unsigned int ni_get_valid_routes(const struct ni_route_tables *tables,
+                                unsigned int n_pairs,
+                                unsigned int *pair_data)
+{
+       unsigned int n_valid = ni_count_valid_routes(tables);
+       int i;
+
+       if (n_pairs == 0 || n_valid == 0)
+               return n_valid;
+
+       if (!pair_data)
+               return 0;
+
+       n_valid = 0;
+
+       for (i = 0; i < tables->valid_routes->n_route_sets; ++i) {
+               const struct ni_route_set *R = &tables->valid_routes->routes[i];
+               int j;
+
+               for (j = 0; j < R->n_src; ++j) {
+                       const int src  = R->src[j];
+                       const int dest = R->dest;
+                       bool valid = false;
+                       const u8 *rv = tables->route_values;
+
+                       if (RVi(rv, B(src), B(dest)))
+                               /* direct routing is valid */
+                               valid = true;
+                       else if (channel_is_rtsi(dest) &&
+                                (RVi(rv, B(src), B(NI_RGOUT0)) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(0))) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(1))) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(2))) ||
+                                 RVi(rv, B(src), B(NI_RTSI_BRD(3))))) {
+                               /* indirect routing also valid */
+                               valid = true;
+                       }
+
+                       if (valid) {
+                               pair_data[2 * n_valid] = src;
+                               pair_data[2 * n_valid + 1] = dest;
+                               ++n_valid;
+                       }
+
+                       if (n_valid >= n_pairs)
+                               return n_valid;
+               }
+       }
+       return n_valid;
+}
+EXPORT_SYMBOL_GPL(ni_get_valid_routes);
+
+/**
+ * List of NI global signal names that, as destinations, are only routeable
+ * indirectly through the *_arg elements of the comedi_cmd structure.
+ */
+static const int NI_CMD_DESTS[] = {
+       NI_AI_SampleClock,
+       NI_AI_StartTrigger,
+       NI_AI_ConvertClock,
+       NI_AO_SampleClock,
+       NI_AO_StartTrigger,
+       NI_DI_SampleClock,
+       NI_DO_SampleClock,
+};
+
+/**
+ * ni_is_cmd_dest() - Determine whether the given destination is only
+ *                   configurable via a comedi_cmd struct.
+ * @dest: Destination to test.
+ */
+bool ni_is_cmd_dest(int dest)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(NI_CMD_DESTS); ++i)
+               if (NI_CMD_DESTS[i] == dest)
+                       return true;
+       return false;
+}
+EXPORT_SYMBOL_GPL(ni_is_cmd_dest);
+
+/* **** BEGIN Routes sort routines **** */
+static int _ni_sort_destcmp(const void *va, const void *vb)
+{
+       const struct ni_route_set *a = va;
+       const struct ni_route_set *b = vb;
+
+       if (a->dest < b->dest)
+               return -1;
+       else if (a->dest > b->dest)
+               return 1;
+       return 0;
+}
+
+static int _ni_sort_srccmp(const void *vsrc0, const void *vsrc1)
+{
+       const int *src0 = vsrc0;
+       const int *src1 = vsrc1;
+
+       if (*src0 < *src1)
+               return -1;
+       else if (*src0 > *src1)
+               return 1;
+       return 0;
+}
+
+/**
+ * ni_sort_device_routes() - Sort the list of valid device signal routes in
+ *                          preparation for use.
+ * @valid_routes:      pointer to ni_device_routes struct to sort.
+ */
+void ni_sort_device_routes(struct ni_device_routes *valid_routes)
+{
+       unsigned int n;
+
+       /* 1. Count and set the number of ni_route_set objects. */
+       valid_routes->n_route_sets = 0;
+       while (valid_routes->routes[valid_routes->n_route_sets].dest != 0)
+               ++valid_routes->n_route_sets;
+
+       /* 2. sort all ni_route_set objects by destination. */
+       sort(valid_routes->routes, valid_routes->n_route_sets,
+            sizeof(struct ni_route_set), _ni_sort_destcmp, NULL);
+
+       /* 3. Loop through each route_set for sorting. */
+       for (n = 0; n < valid_routes->n_route_sets; ++n) {
+               struct ni_route_set *rs = &valid_routes->routes[n];
+
+               /* 3a. Count and set the number of sources. */
+               rs->n_src = 0;
+               while (rs->src[rs->n_src])
+                       ++rs->n_src;
+
+               /* 3a. Sort sources. */
+               sort(valid_routes->routes[n].src, valid_routes->routes[n].n_src,
+                    sizeof(int), _ni_sort_srccmp, NULL);
+       }
+}
+EXPORT_SYMBOL_GPL(ni_sort_device_routes);
+
+/* sort all valid device signal routes in prep for use */
+static void ni_sort_all_device_routes(void)
+{
+       unsigned int i;
+
+       for (i = 0; ni_device_routes_list[i]; ++i)
+               ni_sort_device_routes(ni_device_routes_list[i]);
+}
+
+/* **** BEGIN Routes search routines **** */
+static int _ni_bsearch_destcmp(const void *vkey, const void *velt)
+{
+       const int *key = vkey;
+       const struct ni_route_set *elt = velt;
+
+       if (*key < elt->dest)
+               return -1;
+       else if (*key > elt->dest)
+               return 1;
+       return 0;
+}
+
+static int _ni_bsearch_srccmp(const void *vkey, const void *velt)
+{
+       const int *key = vkey;
+       const int *elt = velt;
+
+       if (*key < *elt)
+               return -1;
+       else if (*key > *elt)
+               return 1;
+       return 0;
+}
+
+/**
+ * ni_find_route_set() - Finds the proper route set with the specified
+ *                      destination.
+ * @destination: Destination of which to search for the route set.
+ * @valid_routes: Pointer to device routes within which to search.
+ *
+ * Return: NULL if no route_set is found with the specified @destination;
+ *     otherwise, a pointer to the route_set if found.
+ */
+const struct ni_route_set *
+ni_find_route_set(const int destination,
+                 const struct ni_device_routes *valid_routes)
+{
+       return bsearch(&destination, valid_routes->routes,
+                      valid_routes->n_route_sets, sizeof(struct ni_route_set),
+                      _ni_bsearch_destcmp);
+}
+EXPORT_SYMBOL_GPL(ni_find_route_set);
+
+/**
+ * ni_route_set_has_source() - Determines whether the given source is in
+ *                            included given route_set.
+ *
+ * Return: true if found; false otherwise.
+ */
+bool ni_route_set_has_source(const struct ni_route_set *routes,
+                            const int source)
+{
+       if (!bsearch(&source, routes->src, routes->n_src, sizeof(int),
+                    _ni_bsearch_srccmp))
+               return false;
+       return true;
+}
+EXPORT_SYMBOL_GPL(ni_route_set_has_source);
+
+/**
+ * ni_lookup_route_register() - Look up a register value for a particular route
+ *                             without checking whether the route is valid for
+ *                             the particular device.
+ * @src:       global-identifier for route source
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ *
+ * Return: -EINVAL if the specified route is not valid for this device family.
+ */
+s8 ni_lookup_route_register(int src, int dest,
+                           const struct ni_route_tables *tables)
+{
+       s8 regval;
+
+       /*
+        * Be sure to use the B() macro to subtract off the NI_NAMES_BASE before
+        * indexing into the route_values array.
+        */
+       src = B(src);
+       dest = B(dest);
+       if (src < 0 || src >= NI_NUM_NAMES || dest < 0 || dest >= NI_NUM_NAMES)
+               return -EINVAL;
+       regval = RVi(tables->route_values, src, dest);
+       if (!regval)
+               return -EINVAL;
+       /* mask out the valid-value marking bit */
+       return UNMARK(regval);
+}
+EXPORT_SYMBOL_GPL(ni_lookup_route_register);
+
+/**
+ * ni_route_to_register() - Validates and converts the specified signal route
+ *                         (src-->dest) to the value used at the appropriate
+ *                         register.
+ * @src:       global-identifier for route source
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ *
+ * Generally speaking, most routes require the first six bits and a few require
+ * 7 bits.  Special handling is given for the return value when the route is to
+ * be handled by the RTSI sub-device.  In this case, the returned register may
+ * not be sufficient to define the entire route path, but rather may only
+ * indicate the intermediate route.  For example, if the route must go through
+ * the RGOUT0 pin, the (src->RGOUT0) register value will be returned.
+ * Similarly, if the route must go through the NI_RTSI_BRD lines, the BIT(6)
+ * will be set:
+ *
+ * if route does not need RTSI_BRD lines:
+ *   bits 0:7 : register value
+ *              for a route that must go through RGOUT0 pin, this will be equal
+ *              to the (src->RGOUT0) register value.
+ * else: * route is (src->RTSI_BRD(x), RTSI_BRD(x)->TRIGGER_LINE(i)) *
+ *   bits 0:5 : zero
+ *   bits 6   : set to 1
+ *   bits 7:7 : zero
+ *
+ * Return: register value to be used for source at destination with special
+ *     cases given above; Otherwise, -1 if the specified route is not valid for
+ *     this particular device.
+ */
+s8 ni_route_to_register(const int src, const int dest,
+                       const struct ni_route_tables *tables)
+{
+       const struct ni_route_set *routes =
+               ni_find_route_set(dest, tables->valid_routes);
+       const u8 *rv;
+       s8 regval;
+
+       /* first check to see if source is listed with bunch of destinations. */
+       if (!routes)
+               return -1;
+       /* 2nd, check to see if destination is in list of source's targets. */
+       if (!ni_route_set_has_source(routes, src))
+               return -1;
+       /*
+        * finally, check to see if we know how to route...
+        * Be sure to use the B() macro to subtract off the NI_NAMES_BASE before
+        * indexing into the route_values array.
+        */
+       rv = tables->route_values;
+       regval = RVi(rv, B(src), B(dest));
+
+       /*
+        * if we did not validate the route, we'll see if we can route through
+        * one of the muxes
+        */
+       if (!regval && channel_is_rtsi(dest)) {
+               regval = RVi(rv, B(src), B(NI_RGOUT0));
+               if (!regval && (RVi(rv, B(src), B(NI_RTSI_BRD(0))) ||
+                               RVi(rv, B(src), B(NI_RTSI_BRD(1))) ||
+                               RVi(rv, B(src), B(NI_RTSI_BRD(2))) ||
+                               RVi(rv, B(src), B(NI_RTSI_BRD(3)))))
+                       regval = BIT(6);
+       }
+
+       if (!regval)
+               return -1;
+       /* mask out the valid-value marking bit */
+       return UNMARK(regval);
+}
+EXPORT_SYMBOL_GPL(ni_route_to_register);
+
+/**
+ * ni_find_route_source() - Finds the signal source corresponding to a signal
+ *                         route (src-->dest) of the specified routing register
+ *                         value and the specified route destination on the
+ *                         specified device.
+ *
+ * Note that this function does _not_ validate the source based on device
+ * routes.
+ *
+ * Return: The NI signal value (e.g. NI_PFI(0) or PXI_Clk10) if found.
+ *     If the source was not found (i.e. the register value is not
+ *     valid for any routes to the destination), -EINVAL is returned.
+ */
+int ni_find_route_source(const u8 src_sel_reg_value, int dest,
+                        const struct ni_route_tables *tables)
+{
+       int src;
+
+       dest = B(dest); /* subtract NI names offset */
+       /* ensure we are not going to under/over run the route value table */
+       if (dest < 0 || dest >= NI_NUM_NAMES)
+               return -EINVAL;
+       for (src = 0; src < NI_NUM_NAMES; ++src)
+               if (RVi(tables->route_values, src, dest) ==
+                   V(src_sel_reg_value))
+                       return src + NI_NAMES_BASE;
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(ni_find_route_source);
+
+/* **** END Routes search routines **** */
+
+/* **** BEGIN simple module entry/exit functions **** */
+static int __init ni_routes_module_init(void)
+{
+       ni_sort_all_device_routes();
+       return 0;
+}
+
+static void __exit ni_routes_module_exit(void)
+{
+}
+
+module_init(ni_routes_module_init);
+module_exit(ni_routes_module_exit);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi helper for routing signals-->terminals for NI");
+MODULE_LICENSE("GPL");
+/* **** END simple module entry/exit functions **** */
diff --git a/drivers/staging/comedi/drivers/ni_routes.h b/drivers/staging/comedi/drivers/ni_routes.h
new file mode 100644 (file)
index 0000000..3211a16
--- /dev/null
@@ -0,0 +1,329 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routes.h
+ *  Route information for NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTES_H
+#define _COMEDI_DRIVERS_NI_ROUTES_H
+
+#include <linux/types.h>
+#include <linux/errno.h>
+
+#ifndef NI_ROUTE_VALUE_EXTERNAL_CONVERSION
+#include <linux/bitops.h>
+#endif
+
+#include "../comedi.h"
+
+/**
+ * struct ni_route_set - Set of destinations with a common source.
+ * @dest: Destination of all sources in this route set.
+ * @n_src: Number of sources for this route set.
+ * @src: List of sources that all map to the same destination.
+ */
+struct ni_route_set {
+       int dest;
+       int n_src;
+       int *src;
+};
+
+/**
+ * struct ni_device_routes - List of all src->dest sets for a particular device.
+ * @device: Name of board/device (e.g. pxi-6733).
+ * @n_route_sets: Number of route sets that are valid for this device.
+ * @routes: List of route sets that are valid for this device.
+ */
+struct ni_device_routes {
+       const char *device;
+       int n_route_sets;
+       struct ni_route_set *routes;
+};
+
+/**
+ * struct ni_route_tables - Register values and valid routes for a device.
+ * @valid_routes: Pointer to a all valid route sets for a single device.
+ * @route_values: Pointer to register values for all routes for the family to
+ *               which the device belongs.
+ *
+ * Link to the valid src->dest routes and the register values used to assign
+ * such routes for that particular device.
+ */
+struct ni_route_tables {
+       const struct ni_device_routes *valid_routes;
+       const u8 *route_values;
+};
+
+/*
+ * ni_assign_device_routes() - Assign the proper lookup table for NI signal
+ *                            routing to the specified NI device.
+ *
+ * Return: -ENODATA if assignment was not successful; 0 if successful.
+ */
+int ni_assign_device_routes(const char *device_family,
+                           const char *board_name,
+                           struct ni_route_tables *tables);
+
+/*
+ * ni_find_route_set() - Finds the proper route set with the specified
+ *                      destination.
+ * @destination: Destination of which to search for the route set.
+ * @valid_routes: Pointer to device routes within which to search.
+ *
+ * Return: NULL if no route_set is found with the specified @destination;
+ *     otherwise, a pointer to the route_set if found.
+ */
+const struct ni_route_set *
+ni_find_route_set(const int destination,
+                 const struct ni_device_routes *valid_routes);
+
+/*
+ * ni_route_set_has_source() - Determines whether the given source is in
+ *                            included given route_set.
+ *
+ * Return: true if found; false otherwise.
+ */
+bool ni_route_set_has_source(const struct ni_route_set *routes, const int src);
+
+/*
+ * ni_route_to_register() - Validates and converts the specified signal route
+ *                         (src-->dest) to the value used at the appropriate
+ *                         register.
+ * @src:       global-identifier for route source
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ *
+ * Generally speaking, most routes require the first six bits and a few require
+ * 7 bits.  Special handling is given for the return value when the route is to
+ * be handled by the RTSI sub-device.  In this case, the returned register may
+ * not be sufficient to define the entire route path, but rather may only
+ * indicate the intermediate route.  For example, if the route must go through
+ * the RGOUT0 pin, the (src->RGOUT0) register value will be returned.
+ * Similarly, if the route must go through the NI_RTSI_BRD lines, the BIT(6)
+ * will be set:
+ *
+ * if route does not need RTSI_BRD lines:
+ *   bits 0:7 : register value
+ *              for a route that must go through RGOUT0 pin, this will be equal
+ *              to the (src->RGOUT0) register value.
+ * else: * route is (src->RTSI_BRD(x), RTSI_BRD(x)->TRIGGER_LINE(i)) *
+ *   bits 0:5 : zero
+ *   bits 6   : set to 1
+ *   bits 7:7 : zero
+ *
+ * Return: register value to be used for source at destination with special
+ *     cases given above; Otherwise, -1 if the specified route is not valid for
+ *     this particular device.
+ */
+s8 ni_route_to_register(const int src, const int dest,
+                       const struct ni_route_tables *tables);
+
+static inline bool ni_rtsi_route_requires_mux(s8 value)
+{
+       return value & BIT(6);
+}
+
+/*
+ * ni_lookup_route_register() - Look up a register value for a particular route
+ *                             without checking whether the route is valid for
+ *                             the particular device.
+ * @src:       global-identifier for route source
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ *
+ * Return: -EINVAL if the specified route is not valid for this device family.
+ */
+s8 ni_lookup_route_register(int src, int dest,
+                           const struct ni_route_tables *tables);
+
+/**
+ * route_is_valid() - Determines whether the specified signal route (src-->dest)
+ *                   is valid for the given NI comedi_device.
+ * @src:       global-identifier for route source
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ *
+ * Return: True if the route is valid, otherwise false.
+ */
+static inline bool route_is_valid(const int src, const int dest,
+                                 const struct ni_route_tables *tables)
+{
+       return ni_route_to_register(src, dest, tables) >= 0;
+}
+
+/*
+ * ni_is_cmd_dest() - Determine whether the given destination is only
+ *                   configurable via a comedi_cmd struct.
+ * @dest: Destination to test.
+ */
+bool ni_is_cmd_dest(int dest);
+
+static inline bool channel_is_pfi(int channel)
+{
+       return NI_PFI(0) <= channel && channel <= NI_PFI(-1);
+}
+
+static inline bool channel_is_rtsi(int channel)
+{
+       return TRIGGER_LINE(0) <= channel && channel <= TRIGGER_LINE(-1);
+}
+
+static inline bool channel_is_ctr(int channel)
+{
+       return channel >= NI_COUNTER_NAMES_BASE &&
+              channel <= NI_COUNTER_NAMES_MAX;
+}
+
+/*
+ * ni_count_valid_routes() - Count the number of valid routes.
+ * @tables: Routing tables for which to count all valid routes.
+ */
+unsigned int ni_count_valid_routes(const struct ni_route_tables *tables);
+
+/*
+ * ni_get_valid_routes() - Implements INSN_DEVICE_CONFIG_GET_ROUTES.
+ * @tables:    pointer to relevant set of routing tables.
+ * @n_pairs:   Number of pairs for which memory is allocated by the user.  If
+ *             the user specifies '0', only the number of available pairs is
+ *             returned.
+ * @pair_data: Pointer to memory allocated to return pairs back to user.  Each
+ *             even, odd indexed member of this array will hold source,
+ *             destination of a route pair respectively.
+ *
+ * Return: the number of valid routes if n_pairs == 0; otherwise, the number of
+ *     valid routes copied.
+ */
+unsigned int ni_get_valid_routes(const struct ni_route_tables *tables,
+                                unsigned int n_pairs,
+                                unsigned int *pair_data);
+
+/*
+ * ni_sort_device_routes() - Sort the list of valid device signal routes in
+ *                          preparation for use.
+ * @valid_routes:      pointer to ni_device_routes struct to sort.
+ */
+void ni_sort_device_routes(struct ni_device_routes *valid_routes);
+
+/*
+ * ni_find_route_source() - Finds the signal source corresponding to a signal
+ *                         route (src-->dest) of the specified routing register
+ *                         value and the specified route destination on the
+ *                         specified device.
+ *
+ * Note that this function does _not_ validate the source based on device
+ * routes.
+ *
+ * Return: The NI signal value (e.g. NI_PFI(0) or PXI_Clk10) if found.
+ *     If the source was not found (i.e. the register value is not
+ *     valid for any routes to the destination), -EINVAL is returned.
+ */
+int ni_find_route_source(const u8 src_sel_reg_value, const int dest,
+                        const struct ni_route_tables *tables);
+
+/**
+ * route_register_is_valid() - Determines whether the register value for the
+ *                            specified route destination on the specified
+ *                            device is valid.
+ */
+static inline bool route_register_is_valid(const u8 src_sel_reg_value,
+                                          const int dest,
+                                          const struct ni_route_tables *tables)
+{
+       return ni_find_route_source(src_sel_reg_value, dest, tables) >= 0;
+}
+
+/**
+ * ni_get_reg_value_roffs() - Determines the proper register value for a
+ *                           particular valid NI signal/terminal route.
+ * @src:       Either a direct register value or one of NI_* signal names.
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ * @direct_reg_offset:
+ *             Compatibility compensation argument.  This argument allows us to
+ *             arbitrarily apply an offset to src if src is a direct register
+ *             value reference.  This is necessary to be compatible with
+ *             definitions of register values as previously exported directly
+ *             to user space.
+ *
+ * Return: the register value (>0) to be used at the destination if the src is
+ *     valid for the given destination; -1 otherwise.
+ */
+static inline s8 ni_get_reg_value_roffs(int src, const int dest,
+                                       const struct ni_route_tables *tables,
+                                       const int direct_reg_offset)
+{
+       if (src < NI_NAMES_BASE) {
+               src += direct_reg_offset;
+               /*
+                * In this case, the src is expected to actually be a register
+                * value.
+                */
+               if (route_register_is_valid(src, dest, tables))
+                       return src;
+               return -1;
+       }
+
+       /*
+        * Otherwise, the src is expected to be one of the abstracted NI
+        * signal/terminal names.
+        */
+       return ni_route_to_register(src, dest, tables);
+}
+
+static inline int ni_get_reg_value(const int src, const int dest,
+                                  const struct ni_route_tables *tables)
+{
+       return ni_get_reg_value_roffs(src, dest, tables, 0);
+}
+
+/**
+ * ni_check_trigger_arg_roffs() - Checks the trigger argument (*_arg) of an NI
+ *                               device to ensure that the *_arg value
+ *                               corresponds to _either_ a valid register value
+ *                               to define a trigger source, _or_ a valid NI
+ *                               signal/terminal name that has a valid route to
+ *                               the destination on the particular device.
+ * @src:       Either a direct register value or one of NI_* signal names.
+ * @dest:      global-identifier for route destination
+ * @tables:    pointer to relevant set of routing tables.
+ * @direct_reg_offset:
+ *             Compatibility compensation argument.  This argument allows us to
+ *             arbitrarily apply an offset to src if src is a direct register
+ *             value reference.  This is necessary to be compatible with
+ *             definitions of register values as previously exported directly
+ *             to user space.
+ *
+ * Return: 0 if the src (either register value or NI signal/terminal name) is
+ *     valid for the destination; -EINVAL otherwise.
+ */
+static inline
+int ni_check_trigger_arg_roffs(int src, const int dest,
+                              const struct ni_route_tables *tables,
+                              const int direct_reg_offset)
+{
+       if (ni_get_reg_value_roffs(src, dest, tables, direct_reg_offset) < 0)
+               return -EINVAL;
+       return 0;
+}
+
+static inline int ni_check_trigger_arg(const int src, const int dest,
+                                      const struct ni_route_tables *tables)
+{
+       return ni_check_trigger_arg_roffs(src, dest, tables, 0);
+}
+
+#endif /* _COMEDI_DRIVERS_NI_ROUTES_H */
diff --git a/drivers/staging/comedi/drivers/ni_routing/README b/drivers/staging/comedi/drivers/ni_routing/README
new file mode 100644 (file)
index 0000000..b65c4eb
--- /dev/null
@@ -0,0 +1,240 @@
+Framework for Maintaining Common National Instruments Terminal/Signal names
+
+The contents of this directory are primarily for maintaining and formatting all
+known valid signal routes for various National Instruments devices.
+
+Some background:
+  There have been significant confusions over the past many years for users
+  when trying to understand how to connect to/from signals and terminals on
+  NI hardware using comedi.  The major reason for this is that the actual
+  register values were exposed and required to be used by users.  Several
+  major reasons exist why this caused major confusion for users:
+
+  1) The register values are _NOT_ in user documentation, but rather in
+    arcane locations, such as a few register programming manuals that are
+    increasingly hard to find and the NI-MHDDK (comments in in example code).
+    There is no one place to find the various valid values of the registers.
+
+  2) The register values are _NOT_ completely consistent.  There is no way to
+    gain any sense of intuition of which values, or even enums one should use
+    for various registers.  There was some attempt in prior use of comedi to
+    name enums such that a user might know which enums should be used for
+    varying purposes, but the end-user had to gain a knowledge of register
+    values to correctly wield this approach.
+
+  3) The names for signals and registers found in the various register level
+    programming manuals and vendor-provided documentation are _not_ even
+    close to the same names that are in the end-user documentation.
+
+  4) The sets of routes that are valid are not consistent from device to device.
+    One additional major challenge is that this information does not seem to be
+    obtainable in any programmatic fashion, neither through the proprietary
+    NIDAQmx(-base) c-libraries, nor with register level programming, _nor_
+    through any documentation.  In fact, the only consistent source of this
+    information is through the proprietary NI-MAX software, which currently only
+    runs on Windows platforms.  A further challenge is that this information
+    cannot be exported from NI-MAX, except by screenshot.
+
+
+
+The content of this directory is part of an effort to greatly simplify the use
+of signal routing capabilities of National Instruments data-acquisition and
+control hardware.  In order to facilitate the transfer of register-level
+information _and_ the knowledge of valid routes per device, a few specific
+choices were made:
+
+
+1) The names of the National Instruments signals/terminals that are used in this
+  directory are chosen to be consistent with (a) the NI's user level
+  documentation, (b) NI's user-level code, (c) the information as provided by
+  the proprietary NI-MAX software, and (d) the user interface code provided by
+  the user-land comedilib library.
+
+  The impact of this choice implies that one allows the use of CamelScript names
+  in the kernel.  In short, the choice to use CamelScript and the exact names
+  below is for maintainability, clarity, similarity to manufacturer's
+  documentation, _and_ a mitigation for confusion that has plagued the use of
+  these drivers for years!
+
+2) The bulk of the real content for this directory is stored in two separate
+  collections (i.e. sub-directories) of tables stored in c source files:
+
+  (a) ni_route_values/ni_[series-label]series.c
+
+        This data represents all the various register values to use for the
+        multiple different signal MUXes for the specific device families.
+
+        The values are all wrapped in one of three macros to help document and
+        track which values have been implemented and tested.
+        These macros are:
+          V(<value>) : register value is valid, tested, and implemented
+          I(<value>) : register value is implemented but needs testing
+          U(<value>) : register value is not implemented
+
+        The actual function of these macros will depend on whether the code is
+        compiled in the kernel or whether it is compiled into the conversion
+        tools.  For the conversion tools, it can be used to indicate the status
+        of the register value.  For the kernel, V() and I() both perform the
+        same function and prepare data to be used; U() zeroes out the value to
+        ensure that it cannot be used.
+
+        *** It would be a great help for users to test these values such that
+        these files can be correctly marked/documented ***
+
+  (b) ni_device_routes/[board-name].c
+
+        This data represents the known set of valid signal routes that are
+        possible for each specific board.  Although the family defines the
+        register values to use for a particular signal MUX, not all possible
+        signals are actually available on each board.
+
+        In order for a particular board to take advantage of the effort to
+        simplify/clarify signal routing on NI devices, a corresponding
+        [board-name].c file must be created.  This file should reflect the known
+        valid _direct_ routing capabilities of the board.
+
+        As noted above, the only known consistent source of information for
+        valid device routes comes from the proprietary National Instruments
+        Windows software, NI-MAX.  Also, as noted above, this information can
+        only be visually conveyed from NI-MAX to other media.  To make this
+        easier, the naming conventions used in the [board-name].c file are
+        similar to the naming conventions as presented by NI-MAX.
+
+
+3) Two other files aggregate the above data to integrate it into comedi:
+    ni_route_values.c
+    ni_device_routes.c
+
+  When adding a new [board-name].c file, be sure to also add in the line in
+  ni_device_routes.c to include this information into comedi.
+
+
+4) Several tools have been included to convert from/to the c file formats.
+  These tools are best used/demonstrated via the included Makefile targets:
+  (a) `make csv-files`
+     Creates new csv-files using content of c-files of existing
+     ni_routing/* content.  New csv files are placed in csv
+     sub-directory.
+
+     As noted above, the only consistent source of information of valid
+     device routes comes from the proprietary National Instruments Windows
+     software, NI-MAX.  Also, as noted above, this information can only be
+     visually conveyed from NI-MAX to other media.  This make target creates
+     spreadsheet representations of the routing data.  The choice of using a
+     spreadsheet (ala CSV) to copy this information allows for easy direct
+     visual comparison to the NI-MAX "Valid Routes" tables.
+
+     Furthermore, the register-level information is much easier to identify and
+     correct when entire families of NI devices are shown side by side in table
+     format.  This is made easy by using a file-storage format that can be
+     loaded into a spreadsheet application.
+
+     Finally, .csv content is very easy to edit and read using a variety of
+     tools, including spreadsheets or various other scripting languages.  In
+     fact, the tools provided here enable quick conversion of the
+     spreadsheet-like .csv format to c-files that follow the kernel coding
+     conventions.
+
+
+  (b) `make c-files`
+     Creates new c-files using content of csv sub-directory.  These
+     new c-files can be compared to the active content in the
+     ni_routing directory.
+  (c) `make csv-blank`
+     Create a new blank csv file.  This is useful for establishing a
+     new data table for either a device family (less likely) or a
+     specific board of an existing device family (more likely).
+  (d) `make clean`
+     Remove all generated files/directories.
+  (e) `make everything`
+     Build all csv-files, then all new c-files.
+
+
+
+
+In summary, similar confusion about signal routing configuration, albeit less,
+plagued NI's previous version of their own proprietary drivers.  Earlier than
+2003, NI greatly simplified the situation for users by releasing a new API that
+abstracted the names of signals/terminals to a common and intuitive set of
+names.  In addition, this new API provided a much more common interface to use
+for most of NI hardware.
+
+Comedi already provides such a common interface for data-acquisition and control
+hardware.  This effort complements comedi's abstraction layers by further
+abstracting much more of the use cases for NI hardware, but allowing users _and_
+developers to directly refer to NI documentation (user-level, register-level,
+and the register-level examples of the NI-MHDDK).
+
+
+
+--------------------------------------------------------------------------------
+Various naming conventions and relations:
+--------------------------------------------------------------------------------
+These are various notes that help to relate the naming conventions used in the
+NI-STC with those naming conventions used here.
+--------------------------------------------------------------------------------
+
+  Signal sources for most signals-destinations are given a specific naming
+  convention, although the register values are not consistent.  This next table
+  shows the mapping between the names used in comedi for NI and those names
+  typically used within the NI-STC documentation.
+
+  (comedi)                      (NI-STC input or output)    (NOTE)
+  ------------------------------------------------------------------------------
+  TRIGGER_LINE(i)               RTSI_Trig_i_Output_Select   i in range [0..7]
+  NI_AI_STOP                    AI_STOP
+  NI_AI_SampleClock             AI_START_Select
+  NI_AI_SampleClockTimebase     AI_SI                       If internal sample
+                                                            clock signal is used
+  NI_AI_StartTrigger            AI_START1_Select
+  NI_AI_ReferenceTrigger        AI_START2_Select            for pre-triggered
+                                                            acquisition---not
+                                                            currently supported
+                                                            in comedi
+  NI_AI_ConvertClock            AI_CONVERT_Source_Select
+  NI_AI_ConvertClockTimebase    AI_SI2                      If internal convert
+                                                            signal is used
+  NI_AI_HoldCompleteEvent
+  NI_AI_PauseTrigger            AI_External_Gate
+  NI_AO_SampleClock             AO_UPDATE
+  NI_AO_SampleClockTimebase     AO_UI
+  NI_AO_StartTrigger            AO_START1
+  NI_AO_PauseTrigger            AO_External_Gate
+  NI_DI_SampleClock
+  NI_DO_SampleClock
+  NI_MasterTimebase
+  NI_20MHzTimebase              TIMEBASE 1 && TIMEBASE 3 if no higher clock exists
+  NI_80MHzTimebase              TIMEBASE 3
+  NI_100kHzTimebase             TIMEBASE 2
+  NI_10MHzRefClock
+  PXI_Clk10
+  NI_CtrOut(0)                  GPFO_0                      external ctr0out pin
+  NI_CtrOut(1)                  GPFO_1                      external ctr1out pin
+  NI_CtrSource(0)
+  NI_CtrSource(1)
+  NI_CtrGate(0)
+  NI_CtrGate(1)
+  NI_CtrInternalOutput(0)       G_OUT0, G0_TC               for Ctr1Source, Ctr1Gate
+  NI_CtrInternalOutput(1)       G_OUT1, G1_TC               for Ctr0Source, Ctr0Gate
+  NI_RGOUT0                     RGOUT0                      internal signal
+  NI_FrequencyOutput
+  #NI_FrequencyOutputTimebase
+  NI_ChangeDetectionEvent
+  NI_RTSI_BRD(0)
+  NI_RTSI_BRD(1)
+  NI_RTSI_BRD(2)
+  NI_RTSI_BRD(3)
+  #NI_SoftwareStrobe
+  NI_LogicLow
+  NI_CtrA(0)                    G0_A_Select                 see M-Series user
+                                                            manual (371022K-01)
+  NI_CtrA(1)                    G1_A_Select                 see M-Series user
+                                                            manual (371022K-01)
+  NI_CtrB(0)                    G0_B_Select, up/down        see M-Series user
+                                                            manual (371022K-01)
+  NI_CtrB(1)                    G1_B_Select, up/down        see M-Series user
+                                                            manual (371022K-01)
+  NI_CtrZ(0)                                                see M-Series user
+                                                            manual (371022K-01)
+  NI_CtrZ(1)                                                see M-Series user
+                                                            manual (371022K-01)
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c
new file mode 100644 (file)
index 0000000..7b6a74d
--- /dev/null
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "ni_device_routes.h"
+#include "ni_device_routes/all.h"
+
+struct ni_device_routes *const ni_device_routes_list[] = {
+       &ni_pxi_6030e_device_routes,
+       &ni_pci_6070e_device_routes,
+       &ni_pci_6220_device_routes,
+       &ni_pci_6221_device_routes,
+       &ni_pxi_6224_device_routes,
+       &ni_pxi_6225_device_routes,
+       &ni_pci_6229_device_routes,
+       &ni_pci_6251_device_routes,
+       &ni_pxi_6251_device_routes,
+       &ni_pxie_6251_device_routes,
+       &ni_pci_6254_device_routes,
+       &ni_pci_6259_device_routes,
+       &ni_pci_6534_device_routes,
+       &ni_pci_6602_device_routes,
+       &ni_pci_6713_device_routes,
+       &ni_pci_6723_device_routes,
+       &ni_pci_6733_device_routes,
+       &ni_pxi_6733_device_routes,
+       NULL,
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h
new file mode 100644 (file)
index 0000000..b9f1c47
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file is meant to be included by comedi/drivers/ni_routes.c
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTINT_NI_DEVICE_ROUTES_H
+#define _COMEDI_DRIVERS_NI_ROUTINT_NI_DEVICE_ROUTES_H
+
+#include "../ni_routes.h"
+
+extern struct ni_device_routes *const ni_device_routes_list[];
+
+#endif /* _COMEDI_DRIVERS_NI_ROUTINT_NI_DEVICE_ROUTES_H */
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h
new file mode 100644 (file)
index 0000000..78b2413
--- /dev/null
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/all.h
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
+#define _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
+
+#include "../ni_device_routes.h"
+
+extern struct ni_device_routes ni_pxi_6030e_device_routes;
+extern struct ni_device_routes ni_pci_6070e_device_routes;
+extern struct ni_device_routes ni_pci_6220_device_routes;
+extern struct ni_device_routes ni_pci_6221_device_routes;
+extern struct ni_device_routes ni_pxi_6224_device_routes;
+extern struct ni_device_routes ni_pxi_6225_device_routes;
+extern struct ni_device_routes ni_pci_6229_device_routes;
+extern struct ni_device_routes ni_pci_6251_device_routes;
+extern struct ni_device_routes ni_pxi_6251_device_routes;
+extern struct ni_device_routes ni_pxie_6251_device_routes;
+extern struct ni_device_routes ni_pci_6254_device_routes;
+extern struct ni_device_routes ni_pci_6259_device_routes;
+extern struct ni_device_routes ni_pci_6534_device_routes;
+extern struct ni_device_routes ni_pxie_6535_device_routes;
+extern struct ni_device_routes ni_pci_6602_device_routes;
+extern struct ni_device_routes ni_pci_6713_device_routes;
+extern struct ni_device_routes ni_pci_6723_device_routes;
+extern struct ni_device_routes ni_pci_6733_device_routes;
+extern struct ni_device_routes ni_pxi_6733_device_routes;
+extern struct ni_device_routes ni_pxie_6738_device_routes;
+
+#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c
new file mode 100644 (file)
index 0000000..f1126a0
--- /dev/null
@@ -0,0 +1,639 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6070e_device_routes = {
+       .device = "pci-6070e",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               NI_AI_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               NI_AI_ConvertClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               NI_AI_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(1),
+                       .src = (int[]){
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_AI_SampleClockTimebase,
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_HoldComplete,
+                       .src = (int[]){
+                               NI_AI_HoldCompleteEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c
new file mode 100644 (file)
index 0000000..74a5922
--- /dev/null
@@ -0,0 +1,1418 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6220.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6220_device_routes = {
+       .device = "pci-6220",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c
new file mode 100644 (file)
index 0000000..44dcbab
--- /dev/null
@@ -0,0 +1,1602 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6221.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6221_device_routes = {
+       .device = "pci-6221",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AI_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c
new file mode 100644 (file)
index 0000000..fa5794e
--- /dev/null
@@ -0,0 +1,1602 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6229.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6229_device_routes = {
+       .device = "pci-6229",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AI_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c
new file mode 100644 (file)
index 0000000..645fd1c
--- /dev/null
@@ -0,0 +1,1652 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6251.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6251_device_routes = {
+       .device = "pci-6251",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c
new file mode 100644 (file)
index 0000000..056a240
--- /dev/null
@@ -0,0 +1,1464 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6254.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6254_device_routes = {
+       .device = "pci-6254",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c
new file mode 100644 (file)
index 0000000..e0b5fa7
--- /dev/null
@@ -0,0 +1,1652 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6259.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6259_device_routes = {
+       .device = "pci-6259",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c
new file mode 100644 (file)
index 0000000..a2472ed
--- /dev/null
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6534.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6534_device_routes = {
+       .device = "pci-6534",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c
new file mode 100644 (file)
index 0000000..91de9da
--- /dev/null
@@ -0,0 +1,3378 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6602.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6602_device_routes = {
+       .device = "pci-6602",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               NI_80MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_80MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_PFI(7),
+                               NI_PFI(15),
+                               NI_PFI(23),
+                               NI_PFI(31),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_PFI(7),
+                               NI_PFI(15),
+                               NI_PFI(23),
+                               NI_PFI(31),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               NI_CtrGate(7),
+                               NI_LogicLow,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               NI_CtrSource(7),
+                               NI_LogicLow,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               NI_PFI(6),
+                               NI_PFI(14),
+                               NI_PFI(22),
+                               NI_PFI(30),
+                               NI_PFI(38),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               NI_PFI(6),
+                               NI_PFI(14),
+                               NI_PFI(22),
+                               NI_PFI(30),
+                               NI_PFI(38),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               NI_CtrGate(6),
+                               NI_LogicLow,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               NI_CtrSource(6),
+                               NI_LogicLow,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(16),
+                       .src = (int[]){
+                               NI_PFI(5),
+                               NI_PFI(13),
+                               NI_PFI(21),
+                               NI_PFI(29),
+                               NI_PFI(37),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(17),
+                       .src = (int[]){
+                               NI_PFI(5),
+                               NI_PFI(13),
+                               NI_PFI(21),
+                               NI_PFI(29),
+                               NI_PFI(37),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(18),
+                       .src = (int[]){
+                               NI_CtrGate(5),
+                               NI_LogicLow,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(19),
+                       .src = (int[]){
+                               NI_CtrSource(5),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(20),
+                       .src = (int[]){
+                               NI_PFI(4),
+                               NI_PFI(12),
+                               NI_PFI(28),
+                               NI_PFI(36),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(21),
+                       .src = (int[]){
+                               NI_PFI(4),
+                               NI_PFI(12),
+                               NI_PFI(20),
+                               NI_PFI(28),
+                               NI_PFI(36),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(22),
+                       .src = (int[]){
+                               NI_CtrGate(4),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(23),
+                       .src = (int[]){
+                               NI_CtrSource(4),
+                               NI_LogicLow,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(24),
+                       .src = (int[]){
+                               NI_PFI(3),
+                               NI_PFI(11),
+                               NI_PFI(19),
+                               NI_PFI(27),
+                               NI_PFI(35),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(3),
+                               NI_CtrSource(7),
+                               NI_CtrGate(3),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(25),
+                       .src = (int[]){
+                               NI_PFI(3),
+                               NI_PFI(11),
+                               NI_PFI(19),
+                               NI_PFI(27),
+                               NI_PFI(35),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(3),
+                               NI_CtrSource(7),
+                               NI_CtrGate(3),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(26),
+                       .src = (int[]){
+                               NI_CtrGate(3),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(27),
+                       .src = (int[]){
+                               NI_CtrSource(3),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(28),
+                       .src = (int[]){
+                               NI_PFI(2),
+                               NI_PFI(10),
+                               NI_PFI(18),
+                               NI_PFI(26),
+                               NI_PFI(34),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(2),
+                               NI_CtrSource(6),
+                               NI_CtrGate(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(29),
+                       .src = (int[]){
+                               NI_PFI(2),
+                               NI_PFI(10),
+                               NI_PFI(18),
+                               NI_PFI(26),
+                               NI_PFI(34),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(2),
+                               NI_CtrSource(6),
+                               NI_CtrGate(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(30),
+                       .src = (int[]){
+                               NI_CtrGate(2),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(31),
+                       .src = (int[]){
+                               NI_CtrSource(2),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(32),
+                       .src = (int[]){
+                               NI_PFI(1),
+                               NI_PFI(9),
+                               NI_PFI(17),
+                               NI_PFI(25),
+                               NI_PFI(33),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(5),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(33),
+                       .src = (int[]){
+                               NI_PFI(1),
+                               NI_PFI(9),
+                               NI_PFI(17),
+                               NI_PFI(25),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(5),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(34),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(35),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(36),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(5),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(37),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(5),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(38),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(39),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(3),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(7),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(3),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(6),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(6),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(6),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(7),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(7),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(7),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               NI_PFI(16),
+                               NI_PFI(17),
+                               NI_PFI(18),
+                               NI_PFI(19),
+                               NI_PFI(20),
+                               NI_PFI(21),
+                               NI_PFI(22),
+                               NI_PFI(23),
+                               NI_PFI(24),
+                               NI_PFI(25),
+                               NI_PFI(26),
+                               NI_PFI(27),
+                               NI_PFI(28),
+                               NI_PFI(29),
+                               NI_PFI(30),
+                               NI_PFI(31),
+                               NI_PFI(32),
+                               NI_PFI(33),
+                               NI_PFI(34),
+                               NI_PFI(35),
+                               NI_PFI(36),
+                               NI_PFI(37),
+                               NI_PFI(38),
+                               NI_PFI(39),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(4),
+                               NI_CtrSource(5),
+                               NI_CtrSource(6),
+                               NI_CtrGate(4),
+                               NI_CtrGate(5),
+                               NI_CtrGate(6),
+                               NI_CtrInternalOutput(4),
+                               NI_CtrInternalOutput(5),
+                               NI_CtrInternalOutput(6),
+                               NI_LogicLow,
+                               NI_LogicHigh,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c
new file mode 100644 (file)
index 0000000..d378b36
--- /dev/null
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6713.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6713_device_routes = {
+       .device = "pci-6713",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(1),
+                       .src = (int[]){
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c
new file mode 100644 (file)
index 0000000..e0cc57a
--- /dev/null
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6723.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6723_device_routes = {
+       .device = "pci-6723",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(1),
+                       .src = (int[]){
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c
new file mode 100644 (file)
index 0000000..f6e1e17
--- /dev/null
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pci-6733.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pci_6733_device_routes = {
+       .device = "pci-6733",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(1),
+                       .src = (int[]){
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c
new file mode 100644 (file)
index 0000000..9978d63
--- /dev/null
@@ -0,0 +1,608 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxi_6030e_device_routes = {
+       .device = "pxi-6030e",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               NI_AI_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               NI_AI_ReferenceTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               NI_AI_ConvertClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               NI_AI_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(1),
+                       .src = (int[]){
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_AI_SampleClockTimebase,
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_HoldComplete,
+                       .src = (int[]){
+                               NI_AI_HoldCompleteEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c
new file mode 100644 (file)
index 0000000..1b89e27
--- /dev/null
@@ -0,0 +1,1432 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxi_6224_device_routes = {
+       .device = "pxi-6224",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c
new file mode 100644 (file)
index 0000000..10dfc34
--- /dev/null
@@ -0,0 +1,1613 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxi_6225_device_routes = {
+       .device = "pxi-6225",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c
new file mode 100644 (file)
index 0000000..25db4b7
--- /dev/null
@@ -0,0 +1,1655 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxi_6251_device_routes = {
+       .device = "pxi-6251",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               PXI_Star,
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c
new file mode 100644 (file)
index 0000000..27da443
--- /dev/null
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxi_6733_device_routes = {
+       .device = "pxi-6733",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_CtrSource(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_CtrGate(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               NI_CtrGate(0),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               PXI_Star,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(0),
+                               PXI_Star,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrOut(1),
+                       .src = (int[]){
+                               NI_CtrInternalOutput(1),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = PXI_Star,
+                       .src = (int[]){
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrOut(0),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_CtrInternalOutput(1),
+                               PXI_Star,
+                               NI_AO_SampleClockTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(7),
+                               PXI_Star,
+                               NI_MasterTimebase,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               PXI_Star,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               PXI_Star,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               PXI_Star,
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               PXI_Star,
+                               NI_AO_SampleClock,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_MasterTimebase,
+                       .src = (int[]){
+                               TRIGGER_LINE(7),
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c
new file mode 100644 (file)
index 0000000..8354fe9
--- /dev/null
@@ -0,0 +1,1656 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxie_6251_device_routes = {
+       .device = "pxie-6251",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(8),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(9),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(10),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(11),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(12),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(13),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(14),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(15),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_DI_SampleClock,
+                               NI_DO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AI_ConvertClock,
+                               NI_AI_PauseTrigger,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(1),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrGate(0),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_80MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_AI_StartTrigger,
+                               NI_AI_ReferenceTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_ConvertClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_ConvertClockTimebase,
+                       .src = (int[]){
+                               NI_AI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AO_SampleClockTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AI_StartTrigger,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_PFI(8),
+                               NI_PFI(9),
+                               NI_PFI(10),
+                               NI_PFI(11),
+                               NI_PFI(12),
+                               NI_PFI(13),
+                               NI_PFI(14),
+                               NI_PFI(15),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_AI_SampleClock,
+                               NI_AI_ConvertClock,
+                               NI_AO_SampleClock,
+                               NI_FrequencyOutput,
+                               NI_ChangeDetectionEvent,
+                               NI_AnalogComparisonEvent,
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c
new file mode 100644 (file)
index 0000000..2ebb679
--- /dev/null
@@ -0,0 +1,575 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxie_6535_device_routes = {
+       .device = "pxie-6535",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_InputBufferFull,
+                               NI_DI_ReadyForStartEvent,
+                               NI_DI_ReadyForTransferEventBurst,
+                               NI_DI_ReadyForTransferEventPipelined,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_OutputBufferFull,
+                               NI_DO_DataActiveEvent,
+                               NI_DO_ReadyForStartEvent,
+                               NI_DO_ReadyForTransferEvent,
+                               NI_ChangeDetectionEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(5),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(4),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c
new file mode 100644 (file)
index 0000000..d885043
--- /dev/null
@@ -0,0 +1,3083 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "all.h"
+
+struct ni_device_routes ni_pxie_6738_device_routes = {
+       .device = "pxie-6738",
+       .routes = (struct ni_route_set[]){
+               {
+                       .dest = NI_PFI(0),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(1),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(2),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(3),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(4),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(5),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(6),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_PFI(7),
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(4),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(5),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(6),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = TRIGGER_LINE(7),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrZ(0),
+                               NI_CtrZ(1),
+                               NI_CtrZ(2),
+                               NI_CtrZ(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               PXI_Clk10,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               PXI_Clk10,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               PXI_Clk10,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSource(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               PXI_Clk10,
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrGate(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrAux(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrA(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrB(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrZ(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrArmStartTrigger(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSampleClock(0),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSampleClock(1),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSampleClock(2),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_CtrSampleClock(3),
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClockTimebase,
+                               NI_DI_SampleClock,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_AO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_DI_SampleClockTimebase,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_ReferenceTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DI_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DO_SampleClock,
+                               NI_DO_StartTrigger,
+                               NI_DO_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClock,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_DO_SampleClockTimebase,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_SampleClockTimebase,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               PXI_Clk10,
+                               NI_20MHzTimebase,
+                               NI_100MHzTimebase,
+                               NI_100kHzTimebase,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_StartTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_DO_PauseTrigger,
+                       .src = (int[]){
+                               NI_PFI(0),
+                               NI_PFI(1),
+                               NI_PFI(2),
+                               NI_PFI(3),
+                               NI_PFI(4),
+                               NI_PFI(5),
+                               NI_PFI(6),
+                               NI_PFI(7),
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               NI_CtrSource(0),
+                               NI_CtrSource(1),
+                               NI_CtrSource(2),
+                               NI_CtrSource(3),
+                               NI_CtrGate(0),
+                               NI_CtrGate(1),
+                               NI_CtrGate(2),
+                               NI_CtrGate(3),
+                               NI_CtrArmStartTrigger(0),
+                               NI_CtrArmStartTrigger(1),
+                               NI_CtrArmStartTrigger(2),
+                               NI_CtrArmStartTrigger(3),
+                               NI_CtrInternalOutput(0),
+                               NI_CtrInternalOutput(1),
+                               NI_CtrInternalOutput(2),
+                               NI_CtrInternalOutput(3),
+                               NI_CtrSampleClock(0),
+                               NI_CtrSampleClock(1),
+                               NI_CtrSampleClock(2),
+                               NI_CtrSampleClock(3),
+                               NI_AO_SampleClock,
+                               NI_AO_StartTrigger,
+                               NI_AO_PauseTrigger,
+                               NI_DI_SampleClock,
+                               NI_DI_StartTrigger,
+                               NI_DI_ReferenceTrigger,
+                               NI_DI_PauseTrigger,
+                               NI_10MHzRefClock,
+                               NI_ChangeDetectionEvent,
+                               NI_WatchdogExpiredEvent,
+                               0, /* Termination */
+                       }
+               },
+               {
+                       .dest = NI_WatchdogExpirationTrigger,
+                       .src = (int[]){
+                               TRIGGER_LINE(0),
+                               TRIGGER_LINE(1),
+                               TRIGGER_LINE(2),
+                               TRIGGER_LINE(3),
+                               TRIGGER_LINE(4),
+                               TRIGGER_LINE(5),
+                               TRIGGER_LINE(6),
+                               TRIGGER_LINE(7),
+                               0, /* Termination */
+                       }
+               },
+               { /* Termination of list */
+                       .dest = 0,
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values.c
new file mode 100644 (file)
index 0000000..5901762
--- /dev/null
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_route_values.c
+ *  Route information for NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file includes the tables that are a list of all the values of various
+ * signals routes available on NI hardware.  In many cases, one does not
+ * explicitly make these routes, rather one might indicate that something is
+ * used as the source of one particular trigger or another (using
+ * *_src=TRIG_EXT).
+ *
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "ni_route_values.h"
+#include "ni_route_values/all.h"
+
+const struct family_route_values *const ni_all_route_values[] = {
+       &ni_660x_route_values,
+       &ni_eseries_route_values,
+       &ni_mseries_route_values,
+       NULL,
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values.h b/drivers/staging/comedi/drivers/ni_routing/ni_route_values.h
new file mode 100644 (file)
index 0000000..80e0145
--- /dev/null
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_route_values.h
+ *  Route information for NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTINT_NI_ROUTE_VALUES_H
+#define _COMEDI_DRIVERS_NI_ROUTINT_NI_ROUTE_VALUES_H
+
+#include "../../comedi.h"
+#include <linux/types.h>
+
+/*
+ * This file includes the tables that are a list of all the values of various
+ * signals routes available on NI hardware.  In many cases, one does not
+ * explicitly make these routes, rather one might indicate that something is
+ * used as the source of one particular trigger or another (using
+ * *_src=TRIG_EXT).
+ *
+ * This file is meant to be included by comedi/drivers/ni_routes.c
+ */
+
+#define B(x)   ((x) - NI_NAMES_BASE)
+
+/** Marks a register value as valid, implemented, and tested. */
+#define V(x)   (((x) & 0x7f) | 0x80)
+
+#ifndef NI_ROUTE_VALUE_EXTERNAL_CONVERSION
+       /** Marks a register value as implemented but needing testing. */
+       #define I(x)    V(x)
+       /** Marks a register value as not implemented. */
+       #define U(x)    0x0
+
+       typedef u8 register_type;
+#else
+       /** Marks a register value as implemented but needing testing. */
+       #define I(x)    (((x) & 0x7f) | 0x100)
+       /** Marks a register value as not implemented. */
+       #define U(x)    (((x) & 0x7f) | 0x200)
+
+       /** Tests whether a register is marked as valid/implemented/tested */
+       #define MARKED_V(x)     (((x) & 0x80) != 0)
+       /** Tests whether a register is implemented but not tested */
+       #define MARKED_I(x)     (((x) & 0x100) != 0)
+       /** Tests whether a register is not implemented */
+       #define MARKED_U(x)     (((x) & 0x200) != 0)
+
+       /* need more space to store extra marks */
+       typedef u16 register_type;
+#endif
+
+/* Mask out the marking bit(s). */
+#define UNMARK(x)      ((x) & 0x7f)
+
+/*
+ * Gi_SRC(x,1) implements Gi_Src_SubSelect = 1
+ *
+ * This appears to only really be a valid MUX for m-series devices.
+ */
+#define Gi_SRC(val, subsel)    ((val) | ((subsel) << 6))
+
+/**
+ * struct family_route_values - Register values for all routes for a particular
+ *                             family.
+ * @family: lower-case string representation of a specific series or family of
+ *         devices from National Instruments where each member of this family
+ *         shares the same register values for the various signal MUXes.  It
+ *         should be noted that not all devices of any family have access to
+ *         all routes defined.
+ * @register_values: Table of all register values for various signal MUXes on
+ *         National Instruments devices.  The first index of this table is the
+ *         signal destination (i.e. identification of the signal MUX).  The
+ *         second index of this table is the signal source (i.e. input of the
+ *         signal MUX).
+ */
+struct family_route_values {
+       const char *family;
+       const register_type register_values[NI_NUM_NAMES][NI_NUM_NAMES];
+
+};
+
+extern const struct family_route_values *const ni_all_route_values[];
+
+#endif /* _COMEDI_DRIVERS_NI_ROUTINT_NI_ROUTE_VALUES_H */
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h
new file mode 100644 (file)
index 0000000..7227461
--- /dev/null
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_route_values/all.h
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
+#define _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
+
+#include "../ni_route_values.h"
+
+extern const struct family_route_values ni_660x_route_values;
+extern const struct family_route_values ni_eseries_route_values;
+extern const struct family_route_values ni_mseries_route_values;
+
+#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c
new file mode 100644 (file)
index 0000000..f1c7e66
--- /dev/null
@@ -0,0 +1,650 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_route_values/ni_660x.c
+ *  Route information for NI_660X boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file includes a list of all the values of various signals routes
+ * available on NI 660x hardware.  In many cases, one does not explicitly make
+ * these routes, rather one might indicate that something is used as the source
+ * of one particular trigger or another (using *_src=TRIG_EXT).
+ *
+ * The contents of this file can be generated using the tools in
+ * comedi/drivers/ni_routing/tools.  This file also contains specific notes to
+ * this family of devices.
+ *
+ * Please use those tools to help maintain the contents of this file, but be
+ * mindful to not lose the notes already made in this file, since these notes
+ * are critical to a complete undertsanding of the register values of this
+ * family.
+ */
+
+#include "../ni_route_values.h"
+#include "all.h"
+
+const struct family_route_values ni_660x_route_values = {
+       .family = "ni_660x",
+       .register_values = {
+               /*
+                * destination = {
+                *              source          = register value,
+                *              ...
+                * }
+                */
+               [B(NI_PFI(8))] = {
+                       [B(NI_CtrInternalOutput(7))]    = I(1),
+               },
+               [B(NI_PFI(10))] = {
+                       [B(NI_CtrGate(7))]      = I(1),
+               },
+               [B(NI_PFI(11))] = {
+                       [B(NI_CtrSource(7))]    = I(1),
+               },
+               [B(NI_PFI(12))] = {
+                       [B(NI_CtrInternalOutput(6))]    = I(1),
+               },
+               [B(NI_PFI(14))] = {
+                       [B(NI_CtrGate(6))]      = I(1),
+               },
+               [B(NI_PFI(15))] = {
+                       [B(NI_CtrSource(6))]    = I(1),
+               },
+               [B(NI_PFI(16))] = {
+                       [B(NI_CtrInternalOutput(5))]    = I(1),
+               },
+               [B(NI_PFI(18))] = {
+                       [B(NI_CtrGate(5))]      = I(1),
+               },
+               [B(NI_PFI(19))] = {
+                       [B(NI_CtrSource(5))]    = I(1),
+               },
+               [B(NI_PFI(20))] = {
+                       [B(NI_CtrInternalOutput(4))]    = I(1),
+               },
+               [B(NI_PFI(22))] = {
+                       [B(NI_CtrGate(4))]      = I(1),
+               },
+               [B(NI_PFI(23))] = {
+                       [B(NI_CtrSource(4))]    = I(1),
+               },
+               [B(NI_PFI(24))] = {
+                       [B(NI_CtrInternalOutput(3))]    = I(1),
+               },
+               [B(NI_PFI(26))] = {
+                       [B(NI_CtrGate(3))]      = I(1),
+               },
+               [B(NI_PFI(27))] = {
+                       [B(NI_CtrSource(3))]    = I(1),
+               },
+               [B(NI_PFI(28))] = {
+                       [B(NI_CtrInternalOutput(2))]    = I(1),
+               },
+               [B(NI_PFI(30))] = {
+                       [B(NI_CtrGate(2))]      = I(1),
+               },
+               [B(NI_PFI(31))] = {
+                       [B(NI_CtrSource(2))]    = I(1),
+               },
+               [B(NI_PFI(32))] = {
+                       [B(NI_CtrInternalOutput(1))]    = I(1),
+               },
+               [B(NI_PFI(34))] = {
+                       [B(NI_CtrGate(1))]      = I(1),
+               },
+               [B(NI_PFI(35))] = {
+                       [B(NI_CtrSource(1))]    = I(1),
+               },
+               [B(NI_PFI(36))] = {
+                       [B(NI_CtrInternalOutput(0))]    = I(1),
+               },
+               [B(NI_PFI(38))] = {
+                       [B(NI_CtrGate(0))]      = I(1),
+               },
+               [B(NI_PFI(39))] = {
+                       [B(NI_CtrSource(0))]    = I(1),
+               },
+               [B(NI_CtrSource(0))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2 /* or 1 */),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(1))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(1))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3 /* or 1 */),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(2))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(2))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4 /* or 1 */),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(3))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(3))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5 /* or 1 */),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(4))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(4))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6 /* or 1 */),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(5))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(5))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7 /* or 1 */),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(6))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(6))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9),
+                       [B(NI_PFI(15))] = U(8 /* or 1 */),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(7))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(7))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(11))] = U(9 /* or 1 */),
+                       [B(NI_PFI(15))] = U(8),
+                       [B(NI_PFI(19))] = U(7),
+                       [B(NI_PFI(23))] = U(6),
+                       [B(NI_PFI(27))] = U(5),
+                       [B(NI_PFI(31))] = U(4),
+                       [B(NI_PFI(35))] = U(3),
+                       [B(NI_PFI(39))] = U(2),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrGate(0))]      = U(10),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(30),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrGate(0))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2 /* or 1 */),
+                       [B(NI_PFI(39))] = I(0),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(1))]    = I(10),
+                       [B(NI_CtrInternalOutput(1))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(1))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3 /* or 1 */),
+                       [B(NI_PFI(35))] = I(0),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(2))]    = I(10),
+                       [B(NI_CtrInternalOutput(2))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(2))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4 /* or 1 */),
+                       [B(NI_PFI(31))] = I(0),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(3))]    = I(10),
+                       [B(NI_CtrInternalOutput(3))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(3))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5 /* or 1 */),
+                       [B(NI_PFI(27))] = I(0),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(4))]    = I(10),
+                       [B(NI_CtrInternalOutput(4))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(4))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6 /* or 1 */),
+                       [B(NI_PFI(23))] = I(0),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(5))]    = I(10),
+                       [B(NI_CtrInternalOutput(5))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(5))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7 /* or 1 */),
+                       [B(NI_PFI(19))] = I(0),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(6))]    = I(10),
+                       [B(NI_CtrInternalOutput(6))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(6))] = {
+                       [B(NI_PFI(10))] = I(9),
+                       [B(NI_PFI(14))] = I(8 /* or 1 */),
+                       [B(NI_PFI(15))] = I(0),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(7))]    = I(10),
+                       [B(NI_CtrInternalOutput(7))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrGate(7))] = {
+                       [B(NI_PFI(10))] = I(9 /* or 1 */),
+                       [B(NI_PFI(11))] = I(0),
+                       [B(NI_PFI(14))] = I(8),
+                       [B(NI_PFI(18))] = I(7),
+                       [B(NI_PFI(22))] = I(6),
+                       [B(NI_PFI(26))] = I(5),
+                       [B(NI_PFI(30))] = I(4),
+                       [B(NI_PFI(34))] = I(3),
+                       [B(NI_PFI(38))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(0))]    = I(10),
+                       [B(NI_CtrInternalOutput(0))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31 /* or 30 */),
+               },
+               [B(NI_CtrAux(0))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2 /* or 1 */),
+                       [B(NI_PFI(39))] = I(0),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(1))]    = I(10),
+                       [B(NI_CtrGate(1))]      = I(30),
+                       [B(NI_CtrInternalOutput(1))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(1))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3 /* or 1 */),
+                       [B(NI_PFI(35))] = I(0),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(2))]    = I(10),
+                       [B(NI_CtrGate(2))]      = I(30),
+                       [B(NI_CtrInternalOutput(2))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(2))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4 /* or 1 */),
+                       [B(NI_PFI(31))] = I(0),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(3))]    = I(10),
+                       [B(NI_CtrGate(3))]      = I(30),
+                       [B(NI_CtrInternalOutput(3))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(3))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5 /* or 1 */),
+                       [B(NI_PFI(27))] = I(0),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(4))]    = I(10),
+                       [B(NI_CtrGate(4))]      = I(30),
+                       [B(NI_CtrInternalOutput(4))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(4))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6 /* or 1 */),
+                       [B(NI_PFI(23))] = I(0),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(5))]    = I(10),
+                       [B(NI_CtrGate(5))]      = I(30),
+                       [B(NI_CtrInternalOutput(5))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(5))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7 /* or 1 */),
+                       [B(NI_PFI(19))] = I(0),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(6))]    = I(10),
+                       [B(NI_CtrGate(6))]      = I(30),
+                       [B(NI_CtrInternalOutput(6))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(6))] = {
+                       [B(NI_PFI(9))]  = I(9),
+                       [B(NI_PFI(13))] = I(8 /* or 1 */),
+                       [B(NI_PFI(15))] = I(0),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(7))]    = I(10),
+                       [B(NI_CtrGate(7))]      = I(30),
+                       [B(NI_CtrInternalOutput(7))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(7))] = {
+                       [B(NI_PFI(9))]  = I(9 /* or 1 */),
+                       [B(NI_PFI(11))] = I(0),
+                       [B(NI_PFI(13))] = I(8),
+                       [B(NI_PFI(17))] = I(7),
+                       [B(NI_PFI(21))] = I(6),
+                       [B(NI_PFI(25))] = I(5),
+                       [B(NI_PFI(29))] = I(4),
+                       [B(NI_PFI(33))] = I(3),
+                       [B(NI_PFI(37))] = I(2),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrSource(0))]    = I(10),
+                       [B(NI_CtrGate(0))]      = I(30),
+                       [B(NI_CtrInternalOutput(0))]    = I(20),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c
new file mode 100644 (file)
index 0000000..d1ab3c9
--- /dev/null
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_route_values/ni_eseries.c
+ *  Route information for NI_ESERIES boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file includes a list of all the values of various signals routes
+ * available on NI 660x hardware.  In many cases, one does not explicitly make
+ * these routes, rather one might indicate that something is used as the source
+ * of one particular trigger or another (using *_src=TRIG_EXT).
+ *
+ * The contents of this file can be generated using the tools in
+ * comedi/drivers/ni_routing/tools.  This file also contains specific notes to
+ * this family of devices.
+ *
+ * Please use those tools to help maintain the contents of this file, but be
+ * mindful to not lose the notes already made in this file, since these notes
+ * are critical to a complete undertsanding of the register values of this
+ * family.
+ */
+
+#include "../ni_route_values.h"
+#include "all.h"
+
+/*
+ * Note that for e-series devices, the backplane TRIGGER_LINE(6) is generally
+ * not connected to RTSI(6).
+ */
+
+const struct family_route_values ni_eseries_route_values = {
+       .family = "ni_eseries",
+       .register_values = {
+               /*
+                * destination = {
+                *              source          = register value,
+                *              ...
+                * }
+                */
+               [B(NI_PFI(0))] = {
+                       [B(NI_AI_StartTrigger)] = I(NI_PFI_OUTPUT_AI_START1),
+               },
+               [B(NI_PFI(1))] = {
+                       [B(NI_AI_ReferenceTrigger)]     = I(NI_PFI_OUTPUT_AI_START2),
+               },
+               [B(NI_PFI(2))] = {
+                       [B(NI_AI_ConvertClock)] = I(NI_PFI_OUTPUT_AI_CONVERT),
+               },
+               [B(NI_PFI(3))] = {
+                       [B(NI_CtrSource(1))]    = I(NI_PFI_OUTPUT_G_SRC1),
+               },
+               [B(NI_PFI(4))] = {
+                       [B(NI_CtrGate(1))]      = I(NI_PFI_OUTPUT_G_GATE1),
+               },
+               [B(NI_PFI(5))] = {
+                       [B(NI_AO_SampleClock)]  = I(NI_PFI_OUTPUT_AO_UPDATE_N),
+               },
+               [B(NI_PFI(6))] = {
+                       [B(NI_AO_StartTrigger)] = I(NI_PFI_OUTPUT_AO_START1),
+               },
+               [B(NI_PFI(7))] = {
+                       [B(NI_AI_SampleClock)]  = I(NI_PFI_OUTPUT_AI_START_PULSE),
+               },
+               [B(NI_PFI(8))] = {
+                       [B(NI_CtrSource(0))]    = I(NI_PFI_OUTPUT_G_SRC0),
+               },
+               [B(NI_PFI(9))] = {
+                       [B(NI_CtrGate(0))]      = I(NI_PFI_OUTPUT_G_GATE0),
+               },
+               [B(TRIGGER_LINE(0))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(1))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(2))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(3))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(4))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(5))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(6))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(7))] = {
+                       [B(NI_20MHzTimebase)]   = I(NI_RTSI_OUTPUT_RTSI_OSC),
+               },
+               [B(NI_RTSI_BRD(0))] = {
+                       [B(TRIGGER_LINE(0))]    = I(0),
+                       [B(TRIGGER_LINE(1))]    = I(1),
+                       [B(TRIGGER_LINE(2))]    = I(2),
+                       [B(TRIGGER_LINE(3))]    = I(3),
+                       [B(TRIGGER_LINE(4))]    = I(4),
+                       [B(TRIGGER_LINE(5))]    = I(5),
+                       [B(TRIGGER_LINE(6))]    = I(6),
+                       [B(PXI_Star)]   = I(6),
+                       [B(NI_AI_STOP)] = I(7),
+               },
+               [B(NI_RTSI_BRD(1))] = {
+                       [B(TRIGGER_LINE(0))]    = I(0),
+                       [B(TRIGGER_LINE(1))]    = I(1),
+                       [B(TRIGGER_LINE(2))]    = I(2),
+                       [B(TRIGGER_LINE(3))]    = I(3),
+                       [B(TRIGGER_LINE(4))]    = I(4),
+                       [B(TRIGGER_LINE(5))]    = I(5),
+                       [B(TRIGGER_LINE(6))]    = I(6),
+                       [B(PXI_Star)]   = I(6),
+                       [B(NI_AI_STOP)] = I(7),
+               },
+               [B(NI_RTSI_BRD(2))] = {
+                       [B(TRIGGER_LINE(0))]    = I(0),
+                       [B(TRIGGER_LINE(1))]    = I(1),
+                       [B(TRIGGER_LINE(2))]    = I(2),
+                       [B(TRIGGER_LINE(3))]    = I(3),
+                       [B(TRIGGER_LINE(4))]    = I(4),
+                       [B(TRIGGER_LINE(5))]    = I(5),
+                       [B(TRIGGER_LINE(6))]    = I(6),
+                       [B(PXI_Star)]   = I(6),
+                       [B(NI_AI_SampleClock)]  = I(7),
+               },
+               [B(NI_RTSI_BRD(3))] = {
+                       [B(TRIGGER_LINE(0))]    = I(0),
+                       [B(TRIGGER_LINE(1))]    = I(1),
+                       [B(TRIGGER_LINE(2))]    = I(2),
+                       [B(TRIGGER_LINE(3))]    = I(3),
+                       [B(TRIGGER_LINE(4))]    = I(4),
+                       [B(TRIGGER_LINE(5))]    = I(5),
+                       [B(TRIGGER_LINE(6))]    = I(6),
+                       [B(PXI_Star)]   = I(6),
+                       [B(NI_AI_SampleClock)]  = I(7),
+               },
+               [B(NI_CtrSource(0))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrInternalOutput(1))]    = U(19),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(1))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(NI_CtrInternalOutput(0))]    = U(19),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrGate(0))] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrInternalOutput(1))]    = I(20),
+                       [B(PXI_Star)]   = I(17),
+                       [B(NI_AI_StartTrigger)] = I(21),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrGate(1))] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrInternalOutput(0))]    = I(20),
+                       [B(PXI_Star)]   = I(17),
+                       [B(NI_AI_StartTrigger)] = I(21),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrOut(0))] = {
+                       [B(TRIGGER_LINE(0))]    = I(1),
+                       [B(TRIGGER_LINE(1))]    = I(2),
+                       [B(TRIGGER_LINE(2))]    = I(3),
+                       [B(TRIGGER_LINE(3))]    = I(4),
+                       [B(TRIGGER_LINE(4))]    = I(5),
+                       [B(TRIGGER_LINE(5))]    = I(6),
+                       [B(TRIGGER_LINE(6))]    = I(7),
+                       [B(NI_CtrInternalOutput(0))]    = I(0),
+                       [B(PXI_Star)]   = I(7),
+               },
+               [B(NI_CtrOut(1))] = {
+                       [B(NI_CtrInternalOutput(1))]    = I(0),
+               },
+               [B(NI_AI_SampleClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrInternalOutput(0))]    = I(19),
+                       [B(PXI_Star)]   = I(17),
+                       [B(NI_AI_SampleClockTimebase)]  = I(0),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AI_SampleClockTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_100kHzTimebase)]  = U(19),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_AI_StartTrigger)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrInternalOutput(0))]    = I(18),
+                       [B(PXI_Star)]   = I(17),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AI_ReferenceTrigger)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_AI_ConvertClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrInternalOutput(0))]    = I(19),
+                       [B(PXI_Star)]   = I(17),
+                       [B(NI_AI_ConvertClockTimebase)] = I(0),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AI_ConvertClockTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_AI_SampleClockTimebase)]  = U(0),
+                       [B(NI_20MHzTimebase)]   = U(1),
+               },
+               [B(NI_AI_PauseTrigger)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_AO_SampleClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(NI_CtrInternalOutput(1))]    = I(19),
+                       [B(PXI_Star)]   = I(17),
+                       [B(NI_AO_SampleClockTimebase)]  = I(0),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AO_SampleClockTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_100kHzTimebase)]  = U(19),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_AO_StartTrigger)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(PXI_Star)]   = I(17),
+                       /*
+                        * for the signal route
+                        * (NI_AI_StartTrigger->NI_AO_StartTrigger), MHDDK says
+                        * used register value 18 and DAQ-STC says 19.
+                        * Hoping that the MHDDK is correct--being a "working"
+                        * example.
+                        */
+                       [B(NI_AI_StartTrigger)] = I(18),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AO_PauseTrigger)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(PXI_Star)]   = U(17),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_MasterTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(TRIGGER_LINE(7))]    = U(1),
+                       [B(PXI_Star)]   = U(2),
+                       [B(PXI_Clk10)]  = U(3),
+                       [B(NI_10MHzRefClock)]   = U(0),
+               },
+               /*
+                * This symbol is not defined and nothing for this is
+                * implemented--just including this because data was found in
+                * the NI-STC for it--can't remember where.
+                * [B(NI_FrequencyOutTimebase)] = {
+                *      ** These are not currently implemented in ni modules **
+                *      [B(NI_20MHzTimebase)]   = U(0),
+                *      [B(NI_100kHzTimebase)]  = U(1),
+                * },
+                */
+               [B(NI_RGOUT0)] = {
+                       [B(NI_CtrInternalOutput(0))]    = I(0),
+                       [B(NI_CtrOut(0))]       = I(1),
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c
new file mode 100644 (file)
index 0000000..c59d8af
--- /dev/null
@@ -0,0 +1,1752 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/ni_route_values/ni_mseries.c
+ *  Route information for NI_MSERIES boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file includes a list of all the values of various signals routes
+ * available on NI 660x hardware.  In many cases, one does not explicitly make
+ * these routes, rather one might indicate that something is used as the source
+ * of one particular trigger or another (using *_src=TRIG_EXT).
+ *
+ * The contents of this file can be generated using the tools in
+ * comedi/drivers/ni_routing/tools.  This file also contains specific notes to
+ * this family of devices.
+ *
+ * Please use those tools to help maintain the contents of this file, but be
+ * mindful to not lose the notes already made in this file, since these notes
+ * are critical to a complete undertsanding of the register values of this
+ * family.
+ */
+
+#include "../ni_route_values.h"
+#include "all.h"
+
+/*
+ * GATE SELECT NOTE:
+ * CtrAux and CtrArmStartrigger register values are not documented in the
+ * DAQ-STC.  There is some evidence that using CtrGate values is valid (see
+ * comedi.h).  Some information and hints exist in the M-Series user manual
+ * (ni-62xx user-manual 371022K-01).
+ */
+
+const struct family_route_values ni_mseries_route_values = {
+       .family = "ni_mseries",
+       .register_values = {
+               /*
+                * destination = {
+                *              source          = register value,
+                *              ...
+                * }
+                */
+               [B(NI_PFI(0))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(1))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(2))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(3))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(4))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(5))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(6))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(7))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(8))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(9))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(10))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(11))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(12))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(13))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(14))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(NI_PFI(15))] = {
+                       [B(TRIGGER_LINE(0))]    = I(18),
+                       [B(TRIGGER_LINE(1))]    = I(19),
+                       [B(TRIGGER_LINE(2))]    = I(20),
+                       [B(TRIGGER_LINE(3))]    = I(21),
+                       [B(TRIGGER_LINE(4))]    = I(22),
+                       [B(TRIGGER_LINE(5))]    = I(23),
+                       [B(TRIGGER_LINE(6))]    = I(24),
+                       [B(TRIGGER_LINE(7))]    = I(25),
+                       [B(NI_CtrSource(0))]    = I(9),
+                       [B(NI_CtrSource(1))]    = I(4),
+                       [B(NI_CtrGate(0))]      = I(10),
+                       [B(NI_CtrGate(1))]      = I(5),
+                       [B(NI_CtrInternalOutput(0))]    = I(13),
+                       [B(NI_CtrInternalOutput(1))]    = I(14),
+                       [B(PXI_Star)]   = I(26),
+                       [B(NI_AI_SampleClock)]  = I(8),
+                       [B(NI_AI_StartTrigger)] = I(1),
+                       [B(NI_AI_ReferenceTrigger)]     = I(2),
+                       [B(NI_AI_ConvertClock)] = I(3),
+                       [B(NI_AI_ExternalMUXClock)]     = I(12),
+                       [B(NI_AO_SampleClock)]  = I(6),
+                       [B(NI_AO_StartTrigger)] = I(7),
+                       [B(NI_DI_SampleClock)]  = I(29),
+                       [B(NI_DO_SampleClock)]  = I(30),
+                       [B(NI_FrequencyOutput)] = I(15),
+                       [B(NI_ChangeDetectionEvent)]    = I(28),
+                       [B(NI_AnalogComparisonEvent)]   = I(17),
+                       [B(NI_SCXI_Trig1)]      = I(27),
+                       [B(NI_ExternalStrobe)]  = I(11),
+                       [B(NI_PFI_DO)]  = I(16),
+               },
+               [B(TRIGGER_LINE(0))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(1))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(2))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(3))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(4))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(5))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(6))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(TRIGGER_LINE(7))] = {
+                       [B(NI_RTSI_BRD(0))]     = I(8),
+                       [B(NI_RTSI_BRD(1))]     = I(9),
+                       [B(NI_RTSI_BRD(2))]     = I(10),
+                       [B(NI_RTSI_BRD(3))]     = I(11),
+                       [B(NI_CtrSource(0))]    = I(5),
+                       [B(NI_CtrGate(0))]      = I(6),
+                       [B(NI_AI_StartTrigger)] = I(0),
+                       [B(NI_AI_ReferenceTrigger)]     = I(1),
+                       [B(NI_AI_ConvertClock)] = I(2),
+                       [B(NI_AO_SampleClock)]  = I(3),
+                       [B(NI_AO_StartTrigger)] = I(4),
+                       /*
+                        * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
+                        * RTSI_OSC according to MHDDK mseries source.  There
+                        * are hints in comedi that show that this is actually a
+                        * 20MHz source for 628x cards(?)
+                        */
+                       [B(NI_10MHzRefClock)]   = I(12),
+                       [B(NI_RGOUT0)]  = I(7),
+               },
+               [B(NI_RTSI_BRD(0))] = {
+                       [B(NI_PFI(0))]  = I(0),
+                       [B(NI_PFI(1))]  = I(1),
+                       [B(NI_PFI(2))]  = I(2),
+                       [B(NI_PFI(3))]  = I(3),
+                       [B(NI_PFI(4))]  = I(4),
+                       [B(NI_PFI(5))]  = I(5),
+                       [B(NI_CtrSource(1))]    = I(11),
+                       [B(NI_CtrGate(1))]      = I(10),
+                       [B(NI_CtrZ(0))] = I(13),
+                       [B(NI_CtrZ(1))] = I(12),
+                       [B(NI_CtrOut(1))]       = I(9),
+                       [B(NI_AI_SampleClock)]  = I(15),
+                       [B(NI_AI_PauseTrigger)] = I(7),
+                       [B(NI_AO_PauseTrigger)] = I(6),
+                       [B(NI_FrequencyOutput)] = I(8),
+                       [B(NI_AnalogComparisonEvent)]   = I(14),
+               },
+               [B(NI_RTSI_BRD(1))] = {
+                       [B(NI_PFI(0))]  = I(0),
+                       [B(NI_PFI(1))]  = I(1),
+                       [B(NI_PFI(2))]  = I(2),
+                       [B(NI_PFI(3))]  = I(3),
+                       [B(NI_PFI(4))]  = I(4),
+                       [B(NI_PFI(5))]  = I(5),
+                       [B(NI_CtrSource(1))]    = I(11),
+                       [B(NI_CtrGate(1))]      = I(10),
+                       [B(NI_CtrZ(0))] = I(13),
+                       [B(NI_CtrZ(1))] = I(12),
+                       [B(NI_CtrOut(1))]       = I(9),
+                       [B(NI_AI_SampleClock)]  = I(15),
+                       [B(NI_AI_PauseTrigger)] = I(7),
+                       [B(NI_AO_PauseTrigger)] = I(6),
+                       [B(NI_FrequencyOutput)] = I(8),
+                       [B(NI_AnalogComparisonEvent)]   = I(14),
+               },
+               [B(NI_RTSI_BRD(2))] = {
+                       [B(NI_PFI(0))]  = I(0),
+                       [B(NI_PFI(1))]  = I(1),
+                       [B(NI_PFI(2))]  = I(2),
+                       [B(NI_PFI(3))]  = I(3),
+                       [B(NI_PFI(4))]  = I(4),
+                       [B(NI_PFI(5))]  = I(5),
+                       [B(NI_CtrSource(1))]    = I(11),
+                       [B(NI_CtrGate(1))]      = I(10),
+                       [B(NI_CtrZ(0))] = I(13),
+                       [B(NI_CtrZ(1))] = I(12),
+                       [B(NI_CtrOut(1))]       = I(9),
+                       [B(NI_AI_SampleClock)]  = I(15),
+                       [B(NI_AI_PauseTrigger)] = I(7),
+                       [B(NI_AO_PauseTrigger)] = I(6),
+                       [B(NI_FrequencyOutput)] = I(8),
+                       [B(NI_AnalogComparisonEvent)]   = I(14),
+               },
+               [B(NI_RTSI_BRD(3))] = {
+                       [B(NI_PFI(0))]  = I(0),
+                       [B(NI_PFI(1))]  = I(1),
+                       [B(NI_PFI(2))]  = I(2),
+                       [B(NI_PFI(3))]  = I(3),
+                       [B(NI_PFI(4))]  = I(4),
+                       [B(NI_PFI(5))]  = I(5),
+                       [B(NI_CtrSource(1))]    = I(11),
+                       [B(NI_CtrGate(1))]      = I(10),
+                       [B(NI_CtrZ(0))] = I(13),
+                       [B(NI_CtrZ(1))] = I(12),
+                       [B(NI_CtrOut(1))]       = I(9),
+                       [B(NI_AI_SampleClock)]  = I(15),
+                       [B(NI_AI_PauseTrigger)] = I(7),
+                       [B(NI_AO_PauseTrigger)] = I(6),
+                       [B(NI_FrequencyOutput)] = I(8),
+                       [B(NI_AnalogComparisonEvent)]   = I(14),
+               },
+               [B(NI_CtrSource(0))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(NI_CtrGate(1))]      = U(Gi_SRC(20, 0)),
+                       [B(NI_CtrInternalOutput(1))]    = U(19),
+                       [B(PXI_Star)]   = U(Gi_SRC(20, 1)),
+                       [B(PXI_Clk10)]  = U(29),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(Gi_SRC(30, 0)),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_AnalogComparisonEvent)]   = U(Gi_SRC(30, 1)),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrSource(1))] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(NI_CtrGate(0))]      = U(Gi_SRC(20, 0)),
+                       [B(NI_CtrInternalOutput(0))]    = U(19),
+                       [B(PXI_Star)]   = U(Gi_SRC(20, 1)),
+                       [B(PXI_Clk10)]  = U(29),
+                       [B(NI_20MHzTimebase)]   = U(0),
+                       [B(NI_80MHzTimebase)]   = U(Gi_SRC(30, 0)),
+                       [B(NI_100kHzTimebase)]  = U(18),
+                       [B(NI_AnalogComparisonEvent)]   = U(Gi_SRC(30, 1)),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_CtrGate(0))] = {
+                       [B(NI_PFI(0))]  = I(1 /* source:  mhddk examples */),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrSource(1))]    = I(29),
+                       /* source for following line:  mhddk GP examples */
+                       [B(NI_CtrInternalOutput(1))]    = I(20),
+                       [B(PXI_Star)]   = I(19),
+                       [B(NI_AI_StartTrigger)] = I(28),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrGate(1))] = {
+                       /* source for following line:  mhddk examples */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrSource(0))]    = I(29),
+                       /* source for following line:  mhddk GP examples */
+                       [B(NI_CtrInternalOutput(0))]    = I(20),
+                       [B(PXI_Star)]   = I(19),
+                       [B(NI_AI_StartTrigger)] = I(28),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(0))] = {
+                       /* these are just a guess; see GATE SELECT NOTE */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrSource(1))]    = I(29),
+                       /* source for following line:  mhddk GP examples */
+                       [B(NI_CtrInternalOutput(1))]    = I(20),
+                       [B(PXI_Star)]   = I(19),
+                       [B(NI_AI_StartTrigger)] = I(28),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrAux(1))] = {
+                       /* these are just a guess; see GATE SELECT NOTE */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrSource(0))]    = I(29),
+                       /* source for following line:  mhddk GP examples */
+                       [B(NI_CtrInternalOutput(0))]    = I(20),
+                       [B(PXI_Star)]   = I(19),
+                       [B(NI_AI_StartTrigger)] = I(28),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrA(0))] = {
+                       /*
+                        * See nimseries/Examples for outputs; inputs a guess
+                        * from device routes shown on NI-MAX.
+                        * see M-Series user manual (371022K-01)
+                        */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrA(1))] = {
+                       /*
+                        * See nimseries/Examples for outputs; inputs a guess
+                        * from device routes shown on NI-MAX.
+                        * see M-Series user manual (371022K-01)
+                        */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrB(0))] = {
+                       /*
+                        * See nimseries/Examples for outputs; inputs a guess
+                        * from device routes shown on NI-MAX.
+                        * see M-Series user manual (371022K-01)
+                        */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrB(1))] = {
+                       /*
+                        * See nimseries/Examples for outputs; inputs a guess
+                        * from device routes shown on NI-MAX.
+                        * see M-Series user manual (371022K-01)
+                        */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrZ(0))] = {
+                       /*
+                        * See nimseries/Examples for outputs; inputs a guess
+                        * from device routes shown on NI-MAX.
+                        * see M-Series user manual (371022K-01)
+                        */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrZ(1))] = {
+                       /*
+                        * See nimseries/Examples for outputs; inputs a guess
+                        * from device routes shown on NI-MAX.
+                        * see M-Series user manual (371022K-01)
+                        */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrArmStartTrigger(0))] = {
+                       /* these are just a guess; see GATE SELECT NOTE */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrSource(1))]    = I(29),
+                       /* source for following line:  mhddk GP examples */
+                       [B(NI_CtrInternalOutput(1))]    = I(20),
+                       [B(PXI_Star)]   = I(19),
+                       [B(NI_AI_StartTrigger)] = I(28),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrArmStartTrigger(1))] = {
+                       /* these are just a guess; see GATE SELECT NOTE */
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrSource(0))]    = I(29),
+                       /* source for following line:  mhddk GP examples */
+                       [B(NI_CtrInternalOutput(0))]    = I(20),
+                       [B(PXI_Star)]   = I(19),
+                       [B(NI_AI_StartTrigger)] = I(28),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_CtrOut(0))] = {
+                       [B(TRIGGER_LINE(0))]    = I(1),
+                       [B(TRIGGER_LINE(1))]    = I(2),
+                       [B(TRIGGER_LINE(2))]    = I(3),
+                       [B(TRIGGER_LINE(3))]    = I(4),
+                       [B(TRIGGER_LINE(4))]    = I(5),
+                       [B(TRIGGER_LINE(5))]    = I(6),
+                       [B(TRIGGER_LINE(6))]    = I(7),
+                       [B(NI_CtrInternalOutput(0))]    = I(0),
+               },
+               [B(NI_CtrOut(1))] = {
+                       [B(NI_CtrInternalOutput(1))]    = I(0),
+               },
+               [B(NI_AI_SampleClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrInternalOutput(0))]    = I(19),
+                       [B(NI_CtrInternalOutput(1))]    = I(28),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AI_SampleClockTimebase)]  = I(0),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_SCXI_Trig1)]      = I(29),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AI_SampleClockTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(PXI_Star)]   = U(20),
+                       [B(PXI_Clk10)]  = U(29),
+                       /*
+                        * For routes (*->NI_AI_SampleClockTimebase) and
+                        * (*->NI_AO_SampleClockTimebase), tMSeries.h of MHDDK
+                        * shows 0 value as selecting ground (case ground?) and
+                        * 28 value selecting TIMEBASE 1.
+                        */
+                       [B(NI_20MHzTimebase)]   = U(28),
+                       [B(NI_100kHzTimebase)]  = U(19),
+                       [B(NI_AnalogComparisonEvent)]   = U(30),
+                       [B(NI_LogicLow)]        = U(31),
+                       [B(NI_CaseGround)]      = U(0),
+               },
+               [B(NI_AI_StartTrigger)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrInternalOutput(0))]    = I(18),
+                       [B(NI_CtrInternalOutput(1))]    = I(19),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AI_ReferenceTrigger)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(PXI_Star)]   = U(20),
+                       [B(NI_AnalogComparisonEvent)]   = U(30),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_AI_ConvertClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       /* source for following line:  mhddk example headers */
+                       [B(NI_CtrInternalOutput(0))]    = I(19),
+                       /* source for following line:  mhddk example headers */
+                       [B(NI_CtrInternalOutput(1))]    = I(18),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AI_ConvertClockTimebase)] = I(0),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AI_ConvertClockTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_AI_SampleClockTimebase)]  = U(0),
+                       [B(NI_20MHzTimebase)]   = U(1),
+               },
+               [B(NI_AI_PauseTrigger)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(PXI_Star)]   = U(20),
+                       [B(NI_AnalogComparisonEvent)]   = U(30),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_AO_SampleClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrInternalOutput(0))]    = I(18),
+                       [B(NI_CtrInternalOutput(1))]    = I(19),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AO_SampleClockTimebase)]  = I(0),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AO_SampleClockTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(PXI_Star)]   = U(20),
+                       [B(PXI_Clk10)]  = U(29),
+                       /*
+                        * For routes (*->NI_AI_SampleClockTimebase) and
+                        * (*->NI_AO_SampleClockTimebase), tMSeries.h of MHDDK
+                        * shows 0 value as selecting ground (case ground?) and
+                        * 28 value selecting TIMEBASE 1.
+                        */
+                       [B(NI_20MHzTimebase)]   = U(28),
+                       [B(NI_100kHzTimebase)]  = U(19),
+                       [B(NI_AnalogComparisonEvent)]   = U(30),
+                       [B(NI_LogicLow)]        = U(31),
+                       [B(NI_CaseGround)]      = U(0),
+               },
+               [B(NI_AO_StartTrigger)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(PXI_Star)]   = I(20),
+                       /*
+                        * for the signal route
+                        * (NI_AI_StartTrigger->NI_AO_StartTrigger), DAQ-STC &
+                        * MHDDK disagreed for e-series.  MHDDK for m-series
+                        * agrees with DAQ-STC description and uses the value 18
+                        * for the route
+                        * (NI_AI_ReferenceTrigger->NI_AO_StartTrigger).  The
+                        * m-series devices are supposed to have DAQ-STC2.
+                        * There are no DAQ-STC2 docs to compare with.
+                        */
+                       [B(NI_AI_StartTrigger)] = I(19),
+                       [B(NI_AI_ReferenceTrigger)]     = I(18),
+                       [B(NI_AnalogComparisonEvent)]   = I(30),
+                       [B(NI_LogicLow)]        = I(31),
+               },
+               [B(NI_AO_PauseTrigger)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(NI_PFI(0))]  = U(1),
+                       [B(NI_PFI(1))]  = U(2),
+                       [B(NI_PFI(2))]  = U(3),
+                       [B(NI_PFI(3))]  = U(4),
+                       [B(NI_PFI(4))]  = U(5),
+                       [B(NI_PFI(5))]  = U(6),
+                       [B(NI_PFI(6))]  = U(7),
+                       [B(NI_PFI(7))]  = U(8),
+                       [B(NI_PFI(8))]  = U(9),
+                       [B(NI_PFI(9))]  = U(10),
+                       [B(NI_PFI(10))] = U(21),
+                       [B(NI_PFI(11))] = U(22),
+                       [B(NI_PFI(12))] = U(23),
+                       [B(NI_PFI(13))] = U(24),
+                       [B(NI_PFI(14))] = U(25),
+                       [B(NI_PFI(15))] = U(26),
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(PXI_Star)]   = U(20),
+                       [B(NI_AnalogComparisonEvent)]   = U(30),
+                       [B(NI_LogicLow)]        = U(31),
+               },
+               [B(NI_DI_SampleClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrInternalOutput(0))]    = I(28),
+                       [B(NI_CtrInternalOutput(1))]    = I(29),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AI_SampleClock)]  = I(18),
+                       [B(NI_AI_ConvertClock)] = I(19),
+                       [B(NI_AO_SampleClock)]  = I(31),
+                       [B(NI_FrequencyOutput)] = I(32),
+                       [B(NI_ChangeDetectionEvent)]    = I(33),
+                       [B(NI_CaseGround)]      = I(0),
+               },
+               [B(NI_DO_SampleClock)] = {
+                       [B(NI_PFI(0))]  = I(1),
+                       [B(NI_PFI(1))]  = I(2),
+                       [B(NI_PFI(2))]  = I(3),
+                       [B(NI_PFI(3))]  = I(4),
+                       [B(NI_PFI(4))]  = I(5),
+                       [B(NI_PFI(5))]  = I(6),
+                       [B(NI_PFI(6))]  = I(7),
+                       [B(NI_PFI(7))]  = I(8),
+                       [B(NI_PFI(8))]  = I(9),
+                       [B(NI_PFI(9))]  = I(10),
+                       [B(NI_PFI(10))] = I(21),
+                       [B(NI_PFI(11))] = I(22),
+                       [B(NI_PFI(12))] = I(23),
+                       [B(NI_PFI(13))] = I(24),
+                       [B(NI_PFI(14))] = I(25),
+                       [B(NI_PFI(15))] = I(26),
+                       [B(TRIGGER_LINE(0))]    = I(11),
+                       [B(TRIGGER_LINE(1))]    = I(12),
+                       [B(TRIGGER_LINE(2))]    = I(13),
+                       [B(TRIGGER_LINE(3))]    = I(14),
+                       [B(TRIGGER_LINE(4))]    = I(15),
+                       [B(TRIGGER_LINE(5))]    = I(16),
+                       [B(TRIGGER_LINE(6))]    = I(17),
+                       [B(TRIGGER_LINE(7))]    = I(27),
+                       [B(NI_CtrInternalOutput(0))]    = I(28),
+                       [B(NI_CtrInternalOutput(1))]    = I(29),
+                       [B(PXI_Star)]   = I(20),
+                       [B(NI_AI_SampleClock)]  = I(18),
+                       [B(NI_AI_ConvertClock)] = I(19),
+                       [B(NI_AO_SampleClock)]  = I(31),
+                       [B(NI_FrequencyOutput)] = I(32),
+                       [B(NI_ChangeDetectionEvent)]    = I(33),
+                       [B(NI_CaseGround)]      = I(0),
+               },
+               [B(NI_MasterTimebase)] = {
+                       /* These are not currently implemented in ni modules */
+                       [B(TRIGGER_LINE(0))]    = U(11),
+                       [B(TRIGGER_LINE(1))]    = U(12),
+                       [B(TRIGGER_LINE(2))]    = U(13),
+                       [B(TRIGGER_LINE(3))]    = U(14),
+                       [B(TRIGGER_LINE(4))]    = U(15),
+                       [B(TRIGGER_LINE(5))]    = U(16),
+                       [B(TRIGGER_LINE(6))]    = U(17),
+                       [B(TRIGGER_LINE(7))]    = U(27),
+                       [B(PXI_Star)]   = U(20),
+                       [B(PXI_Clk10)]  = U(29),
+                       [B(NI_10MHzRefClock)]   = U(0),
+               },
+               /*
+                * This symbol is not defined and nothing for this is
+                * implemented--just including this because data was found in
+                * the NI-STC for it--can't remember where.
+                * [B(NI_FrequencyOutTimebase)] = {
+                *      ** These are not currently implemented in ni modules **
+                *      [B(NI_20MHzTimebase)]   = U(0),
+                *      [B(NI_100kHzTimebase)]  = U(1),
+                * },
+                */
+               [B(NI_RGOUT0)] = {
+                       [B(NI_CtrInternalOutput(0))]    = I(0),
+                       [B(NI_CtrOut(0))]       = I(1),
+               },
+       },
+};
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/.gitignore b/drivers/staging/comedi/drivers/ni_routing/tools/.gitignore
new file mode 100644 (file)
index 0000000..ef38008
--- /dev/null
@@ -0,0 +1,7 @@
+comedi_h.py
+*.pyc
+ni_values.py
+convert_c_to_py
+c/
+csv/
+all_cfiles.c
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/Makefile b/drivers/staging/comedi/drivers/ni_routing/tools/Makefile
new file mode 100644 (file)
index 0000000..1966850
--- /dev/null
@@ -0,0 +1,79 @@
+# this make file is simply to help autogenerate these files:
+#      ni_route_values.h
+#      ni_device_routes.h
+# in order to do this, we are also generating a python representation (using
+# ctypesgen) of ../../comedi.h.
+# This allows us to sort NI signal/terminal names numerically to use a binary
+# search through the device_routes tables to find valid routes.
+
+ALL:
+       @echo Typical targets:
+       @echo "\`make csv-files\`"
+       @echo "  Creates new csv-files using content of c-files of existing"
+       @echo "  ni_routing/* content.  New csv files are placed in csv"
+       @echo "  sub-directory."
+       @echo "\`make c-files\`"
+       @echo "  Creates new c-files using content of csv sub-directory.  These"
+       @echo "  new c-files can be compared to the active content in the"
+       @echo "  ni_routing directory."
+       @echo "\`make csv-blank\`"
+       @echo "  Create a new blank csv file.  This is useful for establishing a"
+       @echo "  new data table for either a device family \(less likely\) or a"
+       @echo "  specific board of an existing device family \(more likely\)."
+       @echo "\`make clean-partial\`"
+       @echo "  Remove all generated files/directories EXCEPT for csv/c files."
+       @echo "\`make clean\`"
+       @echo "  Remove all generated files/directories."
+       @echo "\`make everything\`"
+       @echo "  Build all csv-files, then all new c-files."
+
+everything : csv-files c-files csv-blank
+
+CPPFLAGS=-D"BIT(x)=(1UL<<(x))" -D__user=
+
+comedi_h.py : ../../../comedi.h
+       ctypesgen $< --include "sys/ioctl.h" --cpp 'gcc -E $(CPPFLAGS)' -o $@
+
+convert_c_to_py: all_cfiles.c
+       gcc -g convert_c_to_py.c -o convert_c_to_py -std=c99
+
+ni_values.py: convert_c_to_py
+       ./convert_c_to_py
+
+csv-files : ni_values.py comedi_h.py
+       ./convert_py_to_csv.py
+
+csv-blank :
+       ./make_blank_csv.py
+       @echo New blank csv signal table in csv/blank_route_table.csv
+
+c-files : comedi_h.py
+       ./convert_csv_to_c.py --route_values --device_routes
+
+ROUTE_VALUES_SRC=$(wildcard ../ni_route_values/*.c)
+DEVICE_ROUTES_SRC=$(wildcard ../ni_device_routes/*.c)
+all_cfiles.c : $(DEVICE_ROUTES_SRC) $(ROUTE_VALUES_SRC)
+       @for i in $(DEVICE_ROUTES_SRC) $(ROUTE_VALUES_SRC); do \
+               echo "#include \"$$i\"" >> all_cfiles.c; \
+       done
+
+clean-partial :
+       $(RM) -rf comedi_h.py ni_values.py convert_c_to_py all_cfiles.c *.pyc \
+               __pycache__/
+
+clean : partial_clean
+       $(RM) -rf c/ csv/
+
+# Note:  One could also use ctypeslib in order to generate these files.  The
+# caveat is that ctypeslib does not do a great job at handling macro functions.
+# The make rules are as follows:
+# comedi.h.xml : ../../comedi.h
+#      # note that we have to use PWD here to avoid h2xml finding a system
+#      # installed version of the comedilib/comedi.h file
+#      h2xml ${PWD}/../../comedi.h -c -D__user="" -D"BIT(x)=(1<<(x))" \
+#              -o comedi.h.xml
+#
+# comedi_h.py : comedi.h.xml
+#      xml2py ./comedi.h.xml -o comedi_h.py
+# clean :
+#      rm -f comedi.h.xml comedi_h.py comedi_h.pyc
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c b/drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c
new file mode 100644 (file)
index 0000000..dedb6f2
--- /dev/null
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <errno.h>
+#include <stdlib.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef int8_t  s8;
+#define __user
+#define BIT(x)  (1UL << (x))
+
+#define NI_ROUTE_VALUE_EXTERNAL_CONVERSION 1
+
+#include "../ni_route_values.c"
+#include "../ni_device_routes.c"
+#include "all_cfiles.c"
+
+#include <stdio.h>
+
+#define RVij(rv, src, dest)    ((rv)->register_values[(dest)][(src)])
+
+/*
+ * write out
+ * {
+ *   "family" : "<family-name>",
+ *   "register_values": {
+ *      <destination0>:[src0, src1, ...],
+ *      <destination0>:[src0, src1, ...],
+ *      ...
+ *   }
+ * }
+ */
+void family_write(const struct family_route_values *rv, FILE *fp)
+{
+       fprintf(fp,
+               "  \"%s\" : {\n"
+               "    # dest -> {src0:val0, src1:val1, ...}\n"
+               , rv->family);
+       for (unsigned int dest = NI_NAMES_BASE;
+            dest < (NI_NAMES_BASE + NI_NUM_NAMES);
+            ++dest) {
+               unsigned int src = NI_NAMES_BASE;
+
+               for (; src < (NI_NAMES_BASE + NI_NUM_NAMES) &&
+                    RVij(rv, B(src), B(dest)) == 0; ++src)
+                       ;
+
+               if (src >= (NI_NAMES_BASE + NI_NUM_NAMES))
+                       continue; /* no data here */
+
+               fprintf(fp, "    %u : {\n", dest);
+               for (src = NI_NAMES_BASE; src < (NI_NAMES_BASE + NI_NUM_NAMES);
+                    ++src) {
+                       register_type r = RVij(rv, B(src), B(dest));
+                       const char *M;
+
+                       if (r == 0) {
+                               continue;
+                       } else if (MARKED_V(r)) {
+                               M = "V";
+                       } else if (MARKED_I(r)) {
+                               M = "I";
+                       } else if (MARKED_U(r)) {
+                               M = "U";
+                       } else {
+                               fprintf(stderr,
+                                       "Invalid register marking %s[%u][%u] = %u\n",
+                                       rv->family, dest, src, r);
+                               exit(1);
+                       }
+
+                       fprintf(fp, "      %u : \"%s(%u)\",\n",
+                               src, M, UNMARK(r));
+               }
+               fprintf(fp, "    },\n");
+       }
+       fprintf(fp, "  },\n\n");
+}
+
+bool is_valid_ni_sig(unsigned int sig)
+{
+       return (sig >= NI_NAMES_BASE) && (sig < (NI_NAMES_BASE + NI_NUM_NAMES));
+}
+
+/*
+ * write out
+ * {
+ *   "family" : "<family-name>",
+ *   "register_values": {
+ *      <destination0>:[src0, src1, ...],
+ *      <destination0>:[src0, src1, ...],
+ *      ...
+ *   }
+ * }
+ */
+void device_write(const struct ni_device_routes *dR, FILE *fp)
+{
+       fprintf(fp,
+               "  \"%s\" : {\n"
+               "    # dest -> [src0, src1, ...]\n"
+               , dR->device);
+
+       unsigned int i = 0;
+
+       while (dR->routes[i].dest != 0) {
+               if (!is_valid_ni_sig(dR->routes[i].dest)) {
+                       fprintf(stderr,
+                               "Invalid NI signal value [%u] for destination %s.[%u]\n",
+                               dR->routes[i].dest, dR->device, i);
+                       exit(1);
+               }
+
+               fprintf(fp, "    %u : [", dR->routes[i].dest);
+
+               unsigned int j = 0;
+
+               while (dR->routes[i].src[j] != 0) {
+                       if (!is_valid_ni_sig(dR->routes[i].src[j])) {
+                               fprintf(stderr,
+                                       "Invalid NI signal value [%u] for source %s.[%u].[%u]\n",
+                                       dR->routes[i].src[j], dR->device, i, j);
+                               exit(1);
+                       }
+
+                       fprintf(fp, "%u,", dR->routes[i].src[j]);
+
+                       ++j;
+               }
+               fprintf(fp, "],\n");
+
+               ++i;
+       }
+       fprintf(fp, "  },\n\n");
+}
+
+int main(void)
+{
+       FILE *fp = fopen("ni_values.py", "w");
+
+       /* write route register values */
+       fprintf(fp, "ni_route_values = {\n");
+       for (int i = 0; ni_all_route_values[i]; ++i)
+               family_write(ni_all_route_values[i], fp);
+       fprintf(fp, "}\n\n");
+
+       /* write valid device routes */
+       fprintf(fp, "ni_device_routes = {\n");
+       for (int i = 0; ni_device_routes_list[i]; ++i)
+               device_write(ni_device_routes_list[i], fp);
+       fprintf(fp, "}\n");
+
+       /* finish; close file */
+       fclose(fp);
+       return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py b/drivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py
new file mode 100755 (executable)
index 0000000..532eb63
--- /dev/null
@@ -0,0 +1,503 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0+
+# vim: ts=2:sw=2:et:tw=80:nowrap
+
+# This is simply to aide in creating the entries in the order of the value of
+# the device-global NI signal/terminal constants defined in comedi.h
+import comedi_h
+import os, sys, re
+from csv_collection import CSVCollection
+
+
+def c_to_o(filename, prefix='\t\t\t\t\t   ni_routing/', suffix=' \\'):
+  if not filename.endswith('.c'):
+    return ''
+  return prefix + filename.rpartition('.c')[0] + '.o' + suffix
+
+
+def routedict_to_structinit_single(name, D, return_name=False):
+  Locals = dict()
+  lines = [
+    '\t.family = "{}",'.format(name),
+    '\t.register_values = {',
+    '\t\t/*',
+    '\t\t * destination = {',
+         '\t\t *              source          = register value,',
+         '\t\t *              ...',
+         '\t\t * }',
+               '\t\t */',
+  ]
+  if (False):
+    # print table with index0:src, index1:dest
+    D0 = D # (src-> dest->reg_value)
+    #D1 : destD
+  else:
+    D0 = dict()
+    for src, destD in D.items():
+      for dest, val in destD.items():
+        D0.setdefault(dest, {})[src] = val
+
+
+  D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
+
+  for D0_sig, D1_D in D0:
+    D1 = sorted(D1_D.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
+
+    lines.append('\t\t[B({})] = {{'.format(D0_sig))
+    for D1_sig, value in D1:
+      if not re.match('[VIU]\([^)]*\)', value):
+        sys.stderr.write('Invalid register format: {}\n'.format(repr(value)))
+        sys.stderr.write(
+          'Register values should be formatted with V(),I(),or U()\n')
+        raise RuntimeError('Invalid register values format')
+      lines.append('\t\t\t[B({})]\t= {},'.format(D1_sig, value))
+    lines.append('\t\t},')
+  lines.append('\t},')
+
+  lines = '\n'.join(lines)
+  if return_name:
+    return N, lines
+  else:
+    return lines
+
+
+def routedict_to_routelist_single(name, D, indent=1):
+  Locals = dict()
+
+  indents = dict(
+    I0 = '\t'*(indent),
+    I1 = '\t'*(indent+1),
+    I2 = '\t'*(indent+2),
+    I3 = '\t'*(indent+3),
+    I4 = '\t'*(indent+4),
+  )
+
+  if (False):
+    # data is src -> dest-list
+    D0 = D
+    keyname = 'src'
+    valname = 'dest'
+  else:
+    # data is dest -> src-list
+    keyname = 'dest'
+    valname = 'src'
+    D0 = dict()
+    for src, destD in D.items():
+      for dest, val in destD.items():
+        D0.setdefault(dest, {})[src] = val
+
+  # Sort by order of device-global names (numerically)
+  D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
+
+  lines = [ '{I0}.device = "{name}",\n'
+            '{I0}.routes = (struct ni_route_set[]){{'
+            .format(name=name, **indents) ]
+  for D0_sig, D1_D in D0:
+    D1 = [ k for k,v in D1_D.items() if v ]
+    D1.sort(key=lambda i: eval(i, comedi_h.__dict__, Locals))
+
+    lines.append('{I1}{{\n{I2}.{keyname} = {D0_sig},\n'
+                         '{I2}.{valname} = (int[]){{'
+                 .format(keyname=keyname, valname=valname, D0_sig=D0_sig, **indents)
+    )
+    for D1_sig in D1:
+      lines.append( '{I3}{D1_sig},'.format(D1_sig=D1_sig, **indents) )
+    lines.append( '{I3}0, /* Termination */'.format(**indents) )
+
+    lines.append('{I2}}}\n{I1}}},'.format(**indents))
+
+  lines.append('{I1}{{ /* Termination of list */\n{I2}.{keyname} = 0,\n{I1}}},'
+               .format(keyname=keyname, **indents))
+
+  lines.append('{I0}}},'.format(**indents))
+
+  return '\n'.join(lines)
+
+
+class DeviceRoutes(CSVCollection):
+  MKFILE_SEGMENTS = 'device-route.mk'
+  SET_C = 'ni_device_routes.c'
+  ITEMS_DIR = 'ni_device_routes'
+  EXTERN_H = 'all.h'
+  OUTPUT_DIR = 'c'
+
+  output_file_top = """\
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/{filename}
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "ni_device_routes.h"
+#include "{extern_h}"\
+""".format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
+
+  extern_header = """\
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/{filename}
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
+#define _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
+
+#include "../ni_device_routes.h"
+
+{externs}
+
+#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
+"""
+
+  single_output_file_top = """\
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/{filename}
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "../ni_device_routes.h"
+#include "{extern_h}"
+
+struct ni_device_routes {table_name} = {{\
+"""
+
+  def __init__(self, pattern='csv/device_routes/*.csv'):
+    super(DeviceRoutes,self).__init__(pattern)
+
+  def to_listinit(self):
+    chunks = [ self.output_file_top,
+      '',
+      'struct ni_device_routes *const ni_device_routes_list[] = {'
+    ]
+    # put the sheets in lexical order of device numbers then bus
+    sheets = sorted(self.items(), key=lambda i : tuple(i[0].split('-')[::-1]) )
+
+    externs = []
+    objs = [c_to_o(self.SET_C)]
+
+    for sheet,D in sheets:
+      S = sheet.lower()
+      dev_table_name = 'ni_{}_device_routes'.format(S.replace('-','_'))
+      sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
+      externs.append('extern struct ni_device_routes {};'.format(dev_table_name))
+
+      chunks.append('\t&{},'.format(dev_table_name))
+
+      s_chunks = [
+        self.single_output_file_top.format(
+          filename    = sheet_filename,
+          table_name  = dev_table_name,
+          extern_h    = self.EXTERN_H,
+        ),
+        routedict_to_routelist_single(S, D),
+        '};',
+      ]
+
+      objs.append(c_to_o(sheet_filename))
+
+      with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
+        f.write('\n'.join(s_chunks))
+        f.write('\n')
+
+    with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
+      f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
+      f.write('ni_routing-objs\t\t\t\t+= \\\n')
+      f.write('\n'.join(objs))
+      f.write('\n')
+
+    EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
+    with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
+      f.write(self.extern_header.format(
+        filename=EXTERN_H, externs='\n'.join(externs)))
+
+    chunks.append('\tNULL,') # terminate list
+    chunks.append('};')
+    return '\n'.join(chunks)
+
+  def save(self):
+    filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
+
+    try:
+      os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
+    except:
+      pass
+    with open(filename,'w') as f:
+      f.write( self.to_listinit() )
+      f.write( '\n' )
+
+
+class RouteValues(CSVCollection):
+  MKFILE_SEGMENTS = 'route-values.mk'
+  SET_C = 'ni_route_values.c'
+  ITEMS_DIR = 'ni_route_values'
+  EXTERN_H = 'all.h'
+  OUTPUT_DIR = 'c'
+
+  output_file_top = """\
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/{filename}
+ *  Route information for NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file includes the tables that are a list of all the values of various
+ * signals routes available on NI hardware.  In many cases, one does not
+ * explicitly make these routes, rather one might indicate that something is
+ * used as the source of one particular trigger or another (using
+ * *_src=TRIG_EXT).
+ *
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#include "ni_route_values.h"
+#include "{extern_h}"\
+""".format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
+
+  extern_header = """\
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/{filename}
+ *  List of valid routes for specific NI boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * The contents of this file are generated using the tools in
+ * comedi/drivers/ni_routing/tools
+ *
+ * Please use those tools to help maintain the contents of this file.
+ */
+
+#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
+#define _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
+
+#include "../ni_route_values.h"
+
+{externs}
+
+#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
+"""
+
+  single_output_file_top = """\
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/ni_routing/{filename}
+ *  Route information for {sheet} boards.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+/*
+ * This file includes a list of all the values of various signals routes
+ * available on NI 660x hardware.  In many cases, one does not explicitly make
+ * these routes, rather one might indicate that something is used as the source
+ * of one particular trigger or another (using *_src=TRIG_EXT).
+ *
+ * The contents of this file can be generated using the tools in
+ * comedi/drivers/ni_routing/tools.  This file also contains specific notes to
+ * this family of devices.
+ *
+ * Please use those tools to help maintain the contents of this file, but be
+ * mindful to not lose the notes already made in this file, since these notes
+ * are critical to a complete undertsanding of the register values of this
+ * family.
+ */
+
+#include "../ni_route_values.h"
+#include "{extern_h}"
+
+const struct family_route_values {table_name} = {{\
+"""
+
+  def __init__(self, pattern='csv/route_values/*.csv'):
+    super(RouteValues,self).__init__(pattern)
+
+  def to_structinit(self):
+    chunks = [ self.output_file_top,
+      '',
+      'const struct family_route_values *const ni_all_route_values[] = {'
+    ]
+    # put the sheets in lexical order for consistency
+    sheets = sorted(self.items(), key=lambda i : i[0] )
+
+    externs = []
+    objs = [c_to_o(self.SET_C)]
+
+    for sheet,D in sheets:
+      S = sheet.lower()
+      fam_table_name = '{}_route_values'.format(S.replace('-','_'))
+      sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
+      externs.append('extern const struct family_route_values {};'.format(fam_table_name))
+
+      chunks.append('\t&{},'.format(fam_table_name))
+
+      s_chunks = [
+        self.single_output_file_top.format(
+          filename    = sheet_filename,
+          sheet       = sheet.upper(),
+          table_name  = fam_table_name,
+          extern_h    = self.EXTERN_H,
+        ),
+        routedict_to_structinit_single(S, D),
+        '};',
+      ]
+
+      objs.append(c_to_o(sheet_filename))
+
+      with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
+        f.write('\n'.join(s_chunks))
+        f.write( '\n' )
+
+    with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
+      f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
+      f.write('ni_routing-objs\t\t\t\t+= \\\n')
+      f.write('\n'.join(objs))
+      f.write('\n')
+
+    EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
+    with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
+      f.write(self.extern_header.format(
+        filename=EXTERN_H, externs='\n'.join(externs)))
+
+    chunks.append('\tNULL,') # terminate list
+    chunks.append('};')
+    return '\n'.join(chunks)
+
+  def save(self):
+    filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
+
+    try:
+      os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
+    except:
+      pass
+    with open(filename,'w') as f:
+      f.write( self.to_structinit() )
+      f.write( '\n' )
+
+
+
+if __name__ == '__main__':
+  import argparse
+  parser = argparse.ArgumentParser()
+  parser.add_argument( '--route_values', action='store_true',
+    help='Extract route values from csv/route_values/*.csv' )
+  parser.add_argument( '--device_routes', action='store_true',
+    help='Extract route values from csv/device_routes/*.csv' )
+  args = parser.parse_args()
+  KL = list()
+  if args.route_values:
+    KL.append( RouteValues )
+  if args.device_routes:
+    KL.append( DeviceRoutes )
+  if not KL:
+    parser.error('nothing to do...')
+  for K in KL:
+    doc = K()
+    doc.save()
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py b/drivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py
new file mode 100755 (executable)
index 0000000..b3e6472
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0+
+# vim: ts=2:sw=2:et:tw=80:nowrap
+
+from os import path
+import os, csv
+from itertools import chain
+
+from csv_collection import CSVCollection
+from ni_names import value_to_name
+import ni_values
+
+CSV_DIR = 'csv'
+
+def iter_src_values(D):
+  return D.items()
+
+def iter_src(D):
+  for dest in D:
+    yield dest, 1
+
+def create_csv(name, D, src_iter):
+  # have to change dest->{src:val} to src->{dest:val}
+  fieldnames = [value_to_name[i] for i in sorted(D.keys())]
+  fieldnames.insert(0, CSVCollection.source_column_name)
+
+  S = dict()
+  for dest, srcD in D.items():
+    for src,val in src_iter(srcD):
+      S.setdefault(src,{})[dest] = val
+
+  S = sorted(S.items(), key = lambda src_destD : src_destD[0])
+
+
+  csv_fname = path.join(CSV_DIR, name + '.csv')
+  with open(csv_fname, 'w') as F_csv:
+    dR = csv.DictWriter(F_csv, fieldnames, delimiter=';', quotechar='"')
+    dR.writeheader()
+
+    # now change the json back into the csv dictionaries
+    rows = [
+      dict(chain(
+        ((CSVCollection.source_column_name,value_to_name[src]),),
+        *(((value_to_name[dest],v),) for dest,v in destD.items())
+      ))
+      for src, destD in S
+    ]
+
+    dR.writerows(rows)
+
+
+def to_csv():
+  for d in ['route_values', 'device_routes']:
+    try:
+      os.makedirs(path.join(CSV_DIR,d))
+    except:
+      pass
+
+  for family, dst_src_map in ni_values.ni_route_values.items():
+    create_csv(path.join('route_values',family), dst_src_map, iter_src_values)
+
+  for device, dst_src_map in ni_values.ni_device_routes.items():
+    create_csv(path.join('device_routes',device), dst_src_map, iter_src)
+
+
+if __name__ == '__main__':
+  to_csv()
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py b/drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py
new file mode 100644 (file)
index 0000000..1261732
--- /dev/null
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0+
+# vim: ts=2:sw=2:et:tw=80:nowrap
+
+import os, csv, glob
+
+class CSVCollection(dict):
+  delimiter=';'
+  quotechar='"'
+  source_column_name = 'Sources / Destinations'
+
+  """
+  This class is a dictionary representation of the collection of sheets that
+  exist in a given .ODS file.
+  """
+  def __init__(self, pattern, skip_commented_lines=True, strip_lines=True):
+    super(CSVCollection, self).__init__()
+    self.pattern = pattern
+    C = '#' if skip_commented_lines else 'blahblahblah'
+
+    if strip_lines:
+      strip = lambda s:s.strip()
+    else:
+      strip = lambda s:s
+
+    # load all CSV files
+    key = self.source_column_name
+    for fname in glob.glob(pattern):
+      with open(fname) as F:
+        dR = csv.DictReader(F, delimiter=self.delimiter,
+                            quotechar=self.quotechar)
+        name = os.path.basename(fname).partition('.')[0]
+        D = {
+          r[key]:{f:strip(c) for f,c in r.items()
+                  if f != key and f[:1] not in ['', C] and
+                     strip(c)[:1] not in ['', C]}
+          for r in dR if r[key][:1] not in ['', C]
+        }
+        # now, go back through and eliminate all empty dictionaries
+        D = {k:v for k,v in D.items() if v}
+        self[name] = D
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py b/drivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py
new file mode 100755 (executable)
index 0000000..89c90a0
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0+
+# vim: ts=2:sw=2:et:tw=80:nowrap
+
+from os import path
+import os, csv
+
+from csv_collection import CSVCollection
+from ni_names import value_to_name
+
+CSV_DIR = 'csv'
+
+def to_csv():
+  try:
+    os.makedirs(CSV_DIR)
+  except:
+    pass
+
+  csv_fname = path.join(CSV_DIR, 'blank_route_table.csv')
+
+  fieldnames = [sig for sig_val, sig in sorted(value_to_name.items())]
+  fieldnames.insert(0, CSVCollection.source_column_name)
+
+  with open(csv_fname, 'w') as F_csv:
+    dR = csv.DictWriter(F_csv, fieldnames, delimiter=';', quotechar='"')
+    dR.writeheader()
+
+    for sig in fieldnames[1:]:
+      dR.writerow({CSVCollection.source_column_name: sig})
+
+if __name__ == '__main__':
+  to_csv()
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py b/drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py
new file mode 100644 (file)
index 0000000..5f9b825
--- /dev/null
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0+
+# vim: ts=2:sw=2:et:tw=80:nowrap
+"""
+This file helps to extract string names of NI signals as included in comedi.h
+between NI_NAMES_BASE and NI_NAMES_BASE+NI_NUM_NAMES.
+"""
+
+# This is simply to aide in creating the entries in the order of the value of
+# the device-global NI signal/terminal constants defined in comedi.h
+import comedi_h
+
+
+ni_macros = (
+  'NI_PFI',
+  'TRIGGER_LINE',
+  'NI_RTSI_BRD',
+  'NI_CtrSource',
+  'NI_CtrGate',
+  'NI_CtrAux',
+  'NI_CtrA',
+  'NI_CtrB',
+  'NI_CtrZ',
+  'NI_CtrArmStartTrigger',
+  'NI_CtrInternalOutput',
+  'NI_CtrOut',
+  'NI_CtrSampleClock',
+)
+
+def get_ni_names():
+  name_dict = dict()
+
+  # load all the static names; start with those that do not begin with NI_
+  name_dict['PXI_Star'] = comedi_h.PXI_Star
+  name_dict['PXI_Clk10'] = comedi_h.PXI_Clk10
+
+  #load all macro values
+  for fun in ni_macros:
+    f = getattr(comedi_h, fun)
+    name_dict.update({
+      '{}({})'.format(fun,i):f(i) for i in range(1 + f(-1) - f(0))
+    })
+
+  #load everything else in ni_common_signal_names enum
+  name_dict.update({
+    k:v for k,v in comedi_h.__dict__.items()
+    if k.startswith('NI_') and (not callable(v)) and
+       comedi_h.NI_COUNTER_NAMES_MAX < v < (comedi_h.NI_NAMES_BASE + comedi_h.NI_NUM_NAMES)
+  })
+
+  # now create reverse lookup (value -> name)
+
+  val_dict = {v:k for k,v in name_dict.items()}
+
+  return name_dict, val_dict
+
+name_to_value, value_to_name = get_ni_names()
index 831088c5cabb81d7839158d277153d80f5929519..6c023b40fb53a959cce2c2ca025b250ed3f33788 100644 (file)
@@ -15,6 +15,7 @@
 #define _COMEDI_NI_STC_H
 
 #include "ni_tio.h"
+#include "ni_routes.h"
 
 /*
  * Registers in the National Instruments DAQ-STC chip
 #define NISTC_RTSI_TRIG_OLD_CLK_CHAN   7
 #define NISTC_RTSI_TRIG_NUM_CHAN(_m)   ((_m) ? 8 : 7)
 #define NISTC_RTSI_TRIG_DIR(_c, _m)    ((_m) ? BIT(8 + (_c)) : BIT(7 + (_c)))
+#define NISTC_RTSI_TRIG_DIR_SUB_SEL1   BIT(2)  /* only for M-Series */
+#define NISTC_RTSI_TRIG_DIR_SUB_SEL1_SHIFT     2       /* only for M-Series */
 #define NISTC_RTSI_TRIG_USE_CLK                BIT(1)
 #define NISTC_RTSI_TRIG_DRV_CLK                BIT(0)
 
 #define NISTC_ATRIG_ETC_REG            61
 #define NISTC_ATRIG_ETC_GPFO_1_ENA     BIT(15)
 #define NISTC_ATRIG_ETC_GPFO_0_ENA     BIT(14)
-#define NISTC_ATRIG_ETC_GPFO_0_SEL(x)  (((x) & 0x3) << 11)
+#define NISTC_ATRIG_ETC_GPFO_0_SEL(x)  (((x) & 0x7) << 11)
+#define NISTC_ATRIG_ETC_GPFO_0_SEL_TO_SRC(x)   (((x) >> 11) & 0x7)
 #define NISTC_ATRIG_ETC_GPFO_1_SEL     BIT(7)
+#define NISTC_ATRIG_ETC_GPFO_1_SEL_TO_SRC(x)   (((x) >> 7) & 0x1)
 #define NISTC_ATRIG_ETC_DRV            BIT(4)
 #define NISTC_ATRIG_ETC_ENA            BIT(3)
 #define NISTC_ATRIG_ETC_MODE(x)                (((x) & 0x7) << 0)
+#define NISTC_GPFO_0_G_OUT             0 /* input to GPFO_0_SEL for Ctr0Out */
+#define NISTC_GPFO_1_G_OUT             0 /* input to GPFO_1_SEL for Ctr1Out */
 
 #define NISTC_AI_START_STOP_REG                62
 #define NISTC_AI_START_POLARITY                BIT(15)
 #define NISTC_RTSI_TRIGA_OUT_REG       79
 #define NISTC_RTSI_TRIGB_OUT_REG       80
 #define NISTC_RTSI_TRIGB_SUB_SEL1      BIT(15) /* not for M-Series */
+#define NISTC_RTSI_TRIGB_SUB_SEL1_SHIFT        15      /* not for M-Series */
 #define NISTC_RTSI_TRIG(_c, _s)                (((_s) & 0xf) << (((_c) % 4) * 4))
 #define NISTC_RTSI_TRIG_MASK(_c)       NISTC_RTSI_TRIG((_c), 0xf)
 #define NISTC_RTSI_TRIG_TO_SRC(_c, _b) (((_b) >> (((_c) % 4) * 4)) & 0xf)
@@ -953,6 +961,7 @@ struct ni_board_struct {
        int reg_type;
        unsigned int has_8255:1;
        unsigned int has_32dio_chan:1;
+       unsigned int dio_speed; /* not for e-series */
 
        enum caldac_enum caldac[3];
 };
@@ -962,6 +971,7 @@ struct ni_board_struct {
 #define NUM_GPCT                       2
 
 #define NUM_PFI_OUTPUT_SELECT_REGS     6
+#define NUM_RTSI_SHARED_MUXS           (NI_RTSI_BRD(-1) - NI_RTSI_BRD(0) + 1)
 
 #define M_SERIES_EEPROM_SIZE           1024
 
@@ -1057,6 +1067,73 @@ struct ni_private {
         * possible.
         */
        unsigned int ao_needs_arming:1;
+
+       /* device signal route tables */
+       struct ni_route_tables routing_tables;
+
+       /*
+        * Number of clients (RTSI lines) for current RTSI MUX source.
+        *
+        * This allows resource management of RTSI board/shared mux lines by
+        * marking the RTSI line that is using a particular MUX.  Currently,
+        * these lines are only automatically allocated based on source of the
+        * route requested.  Furthermore, the only way that this auto-allocation
+        * and configuration works is via the globally-named ni signal/terminal
+        * names.
+        */
+       u8 rtsi_shared_mux_usage[NUM_RTSI_SHARED_MUXS];
+
+       /*
+        * softcopy register for rtsi shared mux/board lines.
+        * For e-series, the bit layout of this register is
+        * (docs: mhddk/nieseries/ChipObjects/tSTC.{h,ipp},
+        *        DAQ-STC, Jan 1999, 340934B-01):
+        *   bits 0:2  --  NI_RTSI_BRD(0) source selection
+        *   bits 3:5  --  NI_RTSI_BRD(1) source selection
+        *   bits 6:8  --  NI_RTSI_BRD(2) source selection
+        *   bits 9:11 --  NI_RTSI_BRD(3) source selection
+        *   bit  12   --  NI_RTSI_BRD(0) direction, 0:input, 1:output
+        *   bit  13   --  NI_RTSI_BRD(1) direction, 0:input, 1:output
+        *   bit  14   --  NI_RTSI_BRD(2) direction, 0:input, 1:output
+        *   bit  15   --  NI_RTSI_BRD(3) direction, 0:input, 1:output
+        *   According to DAQ-STC:
+        *     RTSI Board Interface--Configured as an input, each bidirectional
+        *     RTSI_BRD pin can drive any of the seven RTSI_TRIGGER pins.
+        *     RTSI_BRD<0..1> can also be driven by AI STOP and RTSI_BRD<2..3>
+        *     can also be driven by the AI START and SCAN_IN_PROG signals.
+        *     These pins provide a mechanism for additional board-level signals
+        *     to be sent on or received from the RTSI bus.
+        *   Couple of comments:
+        *   - Neither the DAQ-STC nor the MHDDK is clear on what the direction
+        *     of the RTSI_BRD pins actually means.  There does not appear to be
+        *     any clear indication on what "output" would mean, since the point
+        *     of the RTSI_BRD lines is to always drive one of the
+        *     RTSI_TRIGGER<0..6> lines.
+        *   - The DAQ-STC also indicates that the NI_RTSI_BRD lines can be
+        *     driven by any of the RTSI_TRIGGER<0..6> lines.
+        *     But, looking at valid device routes, as visually imported from
+        *     NI-MAX, there appears to be only one family (so far) that has the
+        *     ability to route a signal from one TRIGGER_LINE to another
+        *     TRIGGER_LINE: the 653x family of DIO devices.
+        *
+        * For m-series, the bit layout of this register is
+        * (docs: mhddk/nimseries/ChipObjects/tMSeries.{h,ipp}):
+        *   bits  0:3  --  NI_RTSI_BRD(0) source selection
+        *   bits  4:7  --  NI_RTSI_BRD(1) source selection
+        *   bits  8:11 --  NI_RTSI_BRD(2) source selection
+        *   bits 12:15 --  NI_RTSI_BRD(3) source selection
+        *   Note:  The m-series does not have any option to change direction of
+        *   NI_RTSI_BRD muxes.  Furthermore, there are no register values that
+        *   indicate the ability to have TRIGGER_LINES driving the output of
+        *   the NI_RTSI_BRD muxes.
+        */
+       u16 rtsi_shared_mux_reg;
+
+       /*
+        * Number of clients (RTSI lines) for current RGOUT0 path.
+        * Stored in part of in RTSI_TRIG_DIR or RTSI_TRIGB registers
+        */
+       u8 rgout0_usage;
 };
 
 static const struct comedi_lrange range_ni_E_ao_ext;
index ef919b21b7d98bd6282dfc32517e9d54b8f946cd..0eb388c0e1f09048272783c7d8c782e4fb7db43d 100644 (file)
@@ -818,10 +818,79 @@ static int ni_tio_get_clock_src(struct ni_gpct *counter,
        return 0;
 }
 
+static inline void ni_tio_set_gate_raw(struct ni_gpct *counter,
+                                      unsigned int gate_source)
+{
+       ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(counter->counter_index),
+                       GI_GATE_SEL_MASK, GI_GATE_SEL(gate_source));
+}
+
+static inline void ni_tio_set_gate2_raw(struct ni_gpct *counter,
+                                       unsigned int gate_source)
+{
+       ni_tio_set_bits(counter, NITIO_GATE2_REG(counter->counter_index),
+                       GI_GATE2_SEL_MASK, GI_GATE2_SEL(gate_source));
+}
+
+/* Set the mode bits for gate. */
+static inline void ni_tio_set_gate_mode(struct ni_gpct *counter,
+                                       unsigned int src)
+{
+       unsigned int mode_bits = 0;
+
+       if (CR_CHAN(src) & NI_GPCT_DISABLED_GATE_SELECT) {
+               /*
+                * Allowing bitwise comparison here to allow non-zero raw
+                * register value to be used for channel when disabling.
+                */
+               mode_bits = GI_GATING_DISABLED;
+       } else {
+               if (src & CR_INVERT)
+                       mode_bits |= GI_GATE_POL_INVERT;
+               if (src & CR_EDGE)
+                       mode_bits |= GI_RISING_EDGE_GATING;
+               else
+                       mode_bits |= GI_LEVEL_GATING;
+       }
+       ni_tio_set_bits(counter, NITIO_MODE_REG(counter->counter_index),
+                       GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
+                       mode_bits);
+}
+
+/*
+ * Set the mode bits for gate2.
+ *
+ * Previously, the code this function represents did not actually write anything
+ * to the register.  Rather, writing to this register was reserved for the code
+ * ni ni_tio_set_gate2_raw.
+ */
+static inline void ni_tio_set_gate2_mode(struct ni_gpct *counter,
+                                        unsigned int src)
+{
+       /*
+        * The GI_GATE2_MODE bit was previously set in the code that also sets
+        * the gate2 source.
+        * We'll set mode bits _after_ source bits now, and thus, this function
+        * will effectively enable the second gate after all bits are set.
+        */
+       unsigned int mode_bits = GI_GATE2_MODE;
+
+       if (CR_CHAN(src) & NI_GPCT_DISABLED_GATE_SELECT)
+               /*
+                * Allowing bitwise comparison here to allow non-zero raw
+                * register value to be used for channel when disabling.
+                */
+               mode_bits = GI_GATING_DISABLED;
+       if (src & CR_INVERT)
+               mode_bits |= GI_GATE2_POL_INVERT;
+
+       ni_tio_set_bits(counter, NITIO_GATE2_REG(counter->counter_index),
+                       GI_GATE2_POL_INVERT | GI_GATE2_MODE, mode_bits);
+}
+
 static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
 {
        unsigned int chan = CR_CHAN(gate_source);
-       unsigned int cidx = counter->counter_index;
        unsigned int gate_sel;
        unsigned int i;
 
@@ -854,15 +923,13 @@ static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
                        break;
                return -EINVAL;
        }
-       ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
-                       GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
+       ni_tio_set_gate_raw(counter, gate_sel);
        return 0;
 }
 
 static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
 {
        unsigned int chan = CR_CHAN(gate_source);
-       unsigned int cidx = counter->counter_index;
        unsigned int gate_sel;
        unsigned int i;
 
@@ -896,17 +963,13 @@ static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
                        break;
                return -EINVAL;
        }
-       ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
-                       GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
+       ni_tio_set_gate_raw(counter, gate_sel);
        return 0;
 }
 
 static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
 {
-       struct ni_gpct_device *counter_dev = counter->counter_dev;
-       unsigned int cidx = counter->counter_index;
        unsigned int chan = CR_CHAN(gate_source);
-       unsigned int gate2_reg = NITIO_GATE2_REG(cidx);
        unsigned int gate2_sel;
        unsigned int i;
 
@@ -940,94 +1003,106 @@ static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
                        break;
                return -EINVAL;
        }
-       counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
-       counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
-       counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
-       ni_tio_write(counter, counter_dev->regs[gate2_reg], gate2_reg);
+       ni_tio_set_gate2_raw(counter, gate2_sel);
        return 0;
 }
 
 static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
 {
-       struct ni_gpct_device *counter_dev = counter->counter_dev;
-       unsigned int cidx = counter->counter_index;
-       unsigned int chan = CR_CHAN(gate_source);
-       unsigned int gate2_reg = NITIO_GATE2_REG(cidx);
-       unsigned int gate2_sel;
-
        /*
         * FIXME: We don't know what the m-series second gate codes are,
         * so we'll just pass the bits through for now.
         */
-       switch (chan) {
-       default:
-               gate2_sel = chan & 0x1f;
+       ni_tio_set_gate2_raw(counter, gate_source);
+       return 0;
+}
+
+int ni_tio_set_gate_src_raw(struct ni_gpct *counter,
+                           unsigned int gate, unsigned int src)
+{
+       struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+       switch (gate) {
+       case 0:
+               /* 1.  start by disabling gate */
+               ni_tio_set_gate_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
+               /* 2.  set the requested gate source */
+               ni_tio_set_gate_raw(counter, src);
+               /* 3.  reenable & set mode to starts things back up */
+               ni_tio_set_gate_mode(counter, src);
+               break;
+       case 1:
+               if (!ni_tio_has_gate2_registers(counter_dev))
+                       return -EINVAL;
+
+               /* 1.  start by disabling gate */
+               ni_tio_set_gate2_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
+               /* 2.  set the requested gate source */
+               ni_tio_set_gate2_raw(counter, src);
+               /* 3.  reenable & set mode to starts things back up */
+               ni_tio_set_gate2_mode(counter, src);
                break;
+       default:
+               return -EINVAL;
        }
-       counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
-       counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
-       counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
-       ni_tio_write(counter, counter_dev->regs[gate2_reg], gate2_reg);
        return 0;
 }
+EXPORT_SYMBOL_GPL(ni_tio_set_gate_src_raw);
 
 int ni_tio_set_gate_src(struct ni_gpct *counter,
                        unsigned int gate, unsigned int src)
 {
        struct ni_gpct_device *counter_dev = counter->counter_dev;
-       unsigned int cidx = counter->counter_index;
-       unsigned int chan = CR_CHAN(src);
-       unsigned int gate2_reg = NITIO_GATE2_REG(cidx);
-       unsigned int mode = 0;
+       /*
+        * mask off disable flag.  This high bit still passes CR_CHAN.
+        * Doing this allows one to both set the gate as disabled, but also
+        * change the route value of the gate.
+        */
+       int chan = CR_CHAN(src) & (~NI_GPCT_DISABLED_GATE_SELECT);
+       int ret;
 
        switch (gate) {
        case 0:
-               if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
-                       ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
-                                       GI_GATING_MODE_MASK,
-                                       GI_GATING_DISABLED);
-                       return 0;
-               }
-               if (src & CR_INVERT)
-                       mode |= GI_GATE_POL_INVERT;
-               if (src & CR_EDGE)
-                       mode |= GI_RISING_EDGE_GATING;
-               else
-                       mode |= GI_LEVEL_GATING;
-               ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
-                               GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
-                               mode);
+               /* 1.  start by disabling gate */
+               ni_tio_set_gate_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
+               /* 2.  set the requested gate source */
                switch (counter_dev->variant) {
                case ni_gpct_variant_e_series:
                case ni_gpct_variant_m_series:
-               default:
-                       return ni_m_set_gate(counter, src);
+                       ret = ni_m_set_gate(counter, chan);
+                       break;
                case ni_gpct_variant_660x:
-                       return ni_660x_set_gate(counter, src);
+                       ret = ni_660x_set_gate(counter, chan);
+                       break;
+               default:
+                       return -EINVAL;
                }
+               if (ret)
+                       return ret;
+               /* 3.  reenable & set mode to starts things back up */
+               ni_tio_set_gate_mode(counter, src);
                break;
        case 1:
                if (!ni_tio_has_gate2_registers(counter_dev))
                        return -EINVAL;
 
-               if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
-                       counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE;
-                       ni_tio_write(counter, counter_dev->regs[gate2_reg],
-                                    gate2_reg);
-                       return 0;
-               }
-               if (src & CR_INVERT)
-                       counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT;
-               else
-                       counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT;
+               /* 1.  start by disabling gate */
+               ni_tio_set_gate2_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
+               /* 2.  set the requested gate source */
                switch (counter_dev->variant) {
                case ni_gpct_variant_m_series:
-                       return ni_m_set_gate2(counter, src);
+                       ret = ni_m_set_gate2(counter, chan);
+                       break;
                case ni_gpct_variant_660x:
-                       return ni_660x_set_gate2(counter, src);
+                       ret = ni_660x_set_gate2(counter, chan);
+                       break;
                default:
                        return -EINVAL;
                }
+               if (ret)
+                       return ret;
+               /* 3.  reenable & set mode to starts things back up */
+               ni_tio_set_gate2_mode(counter, src);
                break;
        default:
                return -EINVAL;
@@ -1047,19 +1122,21 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index,
                return -EINVAL;
 
        abz_reg = NITIO_ABZ_REG(cidx);
-       switch (index) {
-       case NI_GPCT_SOURCE_ENCODER_A:
+
+       /* allow for new device-global names */
+       if (index == NI_GPCT_SOURCE_ENCODER_A ||
+           (index >= NI_CtrA(0) && index <= NI_CtrA(-1))) {
                shift = 10;
-               break;
-       case NI_GPCT_SOURCE_ENCODER_B:
+       } else if (index == NI_GPCT_SOURCE_ENCODER_B ||
+           (index >= NI_CtrB(0) && index <= NI_CtrB(-1))) {
                shift = 5;
-               break;
-       case NI_GPCT_SOURCE_ENCODER_Z:
+       } else if (index == NI_GPCT_SOURCE_ENCODER_Z ||
+           (index >= NI_CtrZ(0) && index <= NI_CtrZ(-1))) {
                shift = 0;
-               break;
-       default:
+       } else {
                return -EINVAL;
        }
+
        mask = 0x1f << shift;
        if (source > 0x1f)
                source = 0x1f;  /* Disable gate */
@@ -1070,6 +1147,39 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index,
        return 0;
 }
 
+static int ni_tio_get_other_src(struct ni_gpct *counter, unsigned int index,
+                               unsigned int *source)
+{
+       struct ni_gpct_device *counter_dev = counter->counter_dev;
+       unsigned int cidx = counter->counter_index;
+       unsigned int abz_reg, shift, mask;
+
+       if (counter_dev->variant != ni_gpct_variant_m_series)
+               /* A,B,Z only valid for m-series */
+               return -EINVAL;
+
+       abz_reg = NITIO_ABZ_REG(cidx);
+
+       /* allow for new device-global names */
+       if (index == NI_GPCT_SOURCE_ENCODER_A ||
+           (index >= NI_CtrA(0) && index <= NI_CtrA(-1))) {
+               shift = 10;
+       } else if (index == NI_GPCT_SOURCE_ENCODER_B ||
+           (index >= NI_CtrB(0) && index <= NI_CtrB(-1))) {
+               shift = 5;
+       } else if (index == NI_GPCT_SOURCE_ENCODER_Z ||
+           (index >= NI_CtrZ(0) && index <= NI_CtrZ(-1))) {
+               shift = 0;
+       } else {
+               return -EINVAL;
+       }
+
+       mask = 0x1f;
+
+       *source = (ni_tio_get_soft_copy(counter, abz_reg) >> shift) & mask;
+       return 0;
+}
+
 static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src)
 {
        unsigned int source;
@@ -1112,7 +1222,7 @@ static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src)
        }
        *src = source;
        return 0;
-};
+}
 
 static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src)
 {
@@ -1165,7 +1275,7 @@ static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src)
        }
        *src = source;
        return 0;
-};
+}
 
 static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
 {
@@ -1212,7 +1322,7 @@ static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
        }
        *src = source;
        return 0;
-};
+}
 
 static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
 {
@@ -1222,32 +1332,60 @@ static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
         */
        *src = gate;
        return 0;
-};
+}
+
+static inline unsigned int ni_tio_get_gate_mode(struct ni_gpct *counter)
+{
+       unsigned int mode = ni_tio_get_soft_copy(
+               counter, NITIO_MODE_REG(counter->counter_index));
+       unsigned int ret = 0;
+
+       if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED)
+               ret |= NI_GPCT_DISABLED_GATE_SELECT;
+       if (mode & GI_GATE_POL_INVERT)
+               ret |= CR_INVERT;
+       if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
+               ret |= CR_EDGE;
+
+       return ret;
+}
+
+static inline unsigned int ni_tio_get_gate2_mode(struct ni_gpct *counter)
+{
+       unsigned int mode = ni_tio_get_soft_copy(
+               counter, NITIO_GATE2_REG(counter->counter_index));
+       unsigned int ret = 0;
+
+       if (!(mode & GI_GATE2_MODE))
+               ret |= NI_GPCT_DISABLED_GATE_SELECT;
+       if (mode & GI_GATE2_POL_INVERT)
+               ret |= CR_INVERT;
+
+       return ret;
+}
+
+static inline unsigned int ni_tio_get_gate_val(struct ni_gpct *counter)
+{
+       return GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter,
+               NITIO_INPUT_SEL_REG(counter->counter_index)));
+}
+
+static inline unsigned int ni_tio_get_gate2_val(struct ni_gpct *counter)
+{
+       return GI_BITS_TO_GATE2(ni_tio_get_soft_copy(counter,
+               NITIO_GATE2_REG(counter->counter_index)));
+}
 
 static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index,
                               unsigned int *gate_source)
 {
-       struct ni_gpct_device *counter_dev = counter->counter_dev;
-       unsigned int cidx = counter->counter_index;
-       unsigned int mode;
-       unsigned int reg;
        unsigned int gate;
        int ret;
 
-       mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
-       if (((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) ||
-           (gate_index == 1 &&
-            !(counter_dev->regs[NITIO_GATE2_REG(cidx)] & GI_GATE2_MODE))) {
-               *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
-               return 0;
-       }
-
        switch (gate_index) {
        case 0:
-               reg = NITIO_INPUT_SEL_REG(cidx);
-               gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter, reg));
-
-               switch (counter_dev->variant) {
+               gate = ni_tio_get_gate_val(counter);
+               switch (counter->counter_dev->variant) {
                case ni_gpct_variant_e_series:
                case ni_gpct_variant_m_series:
                default:
@@ -1259,16 +1397,11 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index,
                }
                if (ret)
                        return ret;
-               if (mode & GI_GATE_POL_INVERT)
-                       *gate_source |= CR_INVERT;
-               if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
-                       *gate_source |= CR_EDGE;
+               *gate_source |= ni_tio_get_gate_mode(counter);
                break;
        case 1:
-               reg = NITIO_GATE2_REG(cidx);
-               gate = GI_BITS_TO_GATE2(counter_dev->regs[reg]);
-
-               switch (counter_dev->variant) {
+               gate = ni_tio_get_gate2_val(counter);
+               switch (counter->counter_dev->variant) {
                case ni_gpct_variant_e_series:
                case ni_gpct_variant_m_series:
                default:
@@ -1280,11 +1413,26 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index,
                }
                if (ret)
                        return ret;
-               if (counter_dev->regs[reg] & GI_GATE2_POL_INVERT)
-                       *gate_source |= CR_INVERT;
-               /* second gate can't have edge/level mode set independently */
-               if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
-                       *gate_source |= CR_EDGE;
+               *gate_source |= ni_tio_get_gate2_mode(counter);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int ni_tio_get_gate_src_raw(struct ni_gpct *counter,
+                                  unsigned int gate_index,
+                                  unsigned int *gate_source)
+{
+       switch (gate_index) {
+       case 0:
+               *gate_source = ni_tio_get_gate_mode(counter)
+                            | ni_tio_get_gate_val(counter);
+               break;
+       case 1:
+               *gate_source = ni_tio_get_gate2_mode(counter)
+                            | ni_tio_get_gate2_val(counter);
                break;
        default:
                return -EINVAL;
@@ -1347,6 +1495,107 @@ int ni_tio_insn_config(struct comedi_device *dev,
 }
 EXPORT_SYMBOL_GPL(ni_tio_insn_config);
 
+/**
+ * Retrieves the register value of the current source of the output selector for
+ * the given destination.
+ *
+ * If the terminal for the destination is not already configured as an output,
+ * this function returns -EINVAL as error.
+ *
+ * Return: the register value of the destination output selector;
+ *         -EINVAL if terminal is not configured for output.
+ */
+int ni_tio_get_routing(struct ni_gpct_device *counter_dev, unsigned int dest)
+{
+       /* we need to know the actual counter below... */
+       int ctr_index = (dest - NI_COUNTER_NAMES_BASE) % NI_MAX_COUNTERS;
+       struct ni_gpct *counter = &counter_dev->counters[ctr_index];
+       int ret = 1;
+       unsigned int reg;
+
+       if (dest >= NI_CtrA(0) && dest <= NI_CtrZ(-1)) {
+               ret = ni_tio_get_other_src(counter, dest, &reg);
+       } else if (dest >= NI_CtrGate(0) && dest <= NI_CtrGate(-1)) {
+               ret = ni_tio_get_gate_src_raw(counter, 0, &reg);
+       } else if (dest >= NI_CtrAux(0) && dest <= NI_CtrAux(-1)) {
+               ret = ni_tio_get_gate_src_raw(counter, 1, &reg);
+       /*
+        * This case is not possible through this interface.  A user must use
+        * INSN_CONFIG_SET_CLOCK_SRC instead.
+        * } else if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) {
+        *      ret = ni_tio_set_clock_src(counter, &reg, &period_ns);
+        */
+       }
+
+       if (ret)
+               return -EINVAL;
+
+       return reg;
+}
+EXPORT_SYMBOL_GPL(ni_tio_get_routing);
+
+/**
+ * Sets the register value of the selector MUX for the given destination.
+ * @counter_dev:Pointer to general counter device.
+ * @destination:Device-global identifier of route destination.
+ * @register_value:
+ *             The first several bits of this value should store the desired
+ *             value to write to the register.  All other bits are for
+ *             transmitting information that modify the mode of the particular
+ *             destination/gate.  These mode bits might include a bitwise or of
+ *             CR_INVERT and CR_EDGE.  Note that the calling function should
+ *             have already validated the correctness of this value.
+ */
+int ni_tio_set_routing(struct ni_gpct_device *counter_dev, unsigned int dest,
+                      unsigned int reg)
+{
+       /* we need to know the actual counter below... */
+       int ctr_index = (dest - NI_COUNTER_NAMES_BASE) % NI_MAX_COUNTERS;
+       struct ni_gpct *counter = &counter_dev->counters[ctr_index];
+       int ret;
+
+       if (dest >= NI_CtrA(0) && dest <= NI_CtrZ(-1)) {
+               ret = ni_tio_set_other_src(counter, dest, reg);
+       } else if (dest >= NI_CtrGate(0) && dest <= NI_CtrGate(-1)) {
+               ret = ni_tio_set_gate_src_raw(counter, 0, reg);
+       } else if (dest >= NI_CtrAux(0) && dest <= NI_CtrAux(-1)) {
+               ret = ni_tio_set_gate_src_raw(counter, 1, reg);
+       /*
+        * This case is not possible through this interface.  A user must use
+        * INSN_CONFIG_SET_CLOCK_SRC instead.
+        * } else if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) {
+        *      ret = ni_tio_set_clock_src(counter, reg, period_ns);
+        */
+       } else {
+               return -EINVAL;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(ni_tio_set_routing);
+
+/**
+ * Sets the given destination MUX to its default value or disable it.
+ *
+ * Return: 0 if successful; -EINVAL if terminal is unknown.
+ */
+int ni_tio_unset_routing(struct ni_gpct_device *counter_dev, unsigned int dest)
+{
+       if (dest >= NI_GATES_NAMES_BASE && dest <= NI_GATES_NAMES_MAX)
+               /* Disable gate (via mode bits) and set to default 0-value */
+               return ni_tio_set_routing(counter_dev, dest,
+                                         NI_GPCT_DISABLED_GATE_SELECT);
+       /*
+        * This case is not possible through this interface.  A user must use
+        * INSN_CONFIG_SET_CLOCK_SRC instead.
+        * if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1))
+        *      return ni_tio_set_clock_src(counter, reg, period_ns);
+        */
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(ni_tio_unset_routing);
+
 static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev,
                                            struct comedi_subdevice *s)
 {
@@ -1504,13 +1753,15 @@ ni_gpct_device_construct(struct comedi_device *dev,
                         unsigned int (*read)(struct ni_gpct *counter,
                                              enum ni_gpct_register reg),
                         enum ni_gpct_variant variant,
-                        unsigned int num_counters)
+                        unsigned int num_counters,
+                        unsigned int counters_per_chip,
+                        const struct ni_route_tables *routing_tables)
 {
        struct ni_gpct_device *counter_dev;
        struct ni_gpct *counter;
        unsigned int i;
 
-       if (num_counters == 0)
+       if (num_counters == 0 || counters_per_chip == 0)
                return NULL;
 
        counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL);
@@ -1521,6 +1772,7 @@ ni_gpct_device_construct(struct comedi_device *dev,
        counter_dev->write = write;
        counter_dev->read = read;
        counter_dev->variant = variant;
+       counter_dev->routing_tables = routing_tables;
 
        spin_lock_init(&counter_dev->regs_lock);
 
@@ -1534,9 +1786,12 @@ ni_gpct_device_construct(struct comedi_device *dev,
        for (i = 0; i < num_counters; ++i) {
                counter = &counter_dev->counters[i];
                counter->counter_dev = counter_dev;
+               counter->chip_index = i / counters_per_chip;
+               counter->counter_index = i % counters_per_chip;
                spin_lock_init(&counter->lock);
        }
        counter_dev->num_counters = num_counters;
+       counter_dev->counters_per_chip = counters_per_chip;
 
        return counter_dev;
 }
index 23221cead8ca0cca92bc8912d74b3aa2b9961730..340d63c744677ea01067b2a44f82f955c566a9e8 100644 (file)
@@ -107,8 +107,10 @@ struct ni_gpct_device {
        enum ni_gpct_variant variant;
        struct ni_gpct *counters;
        unsigned int num_counters;
+       unsigned int counters_per_chip;
        unsigned int regs[NITIO_NUM_REGS];
        spinlock_t regs_lock;           /* protects 'regs' */
+       const struct ni_route_tables *routing_tables; /* link to routes */
 };
 
 struct ni_gpct_device *
@@ -119,7 +121,9 @@ ni_gpct_device_construct(struct comedi_device *dev,
                         unsigned int (*read)(struct ni_gpct *counter,
                                              enum ni_gpct_register),
                         enum ni_gpct_variant,
-                        unsigned int num_counters);
+                        unsigned int num_counters,
+                        unsigned int counters_per_chip,
+                        const struct ni_route_tables *routing_tables);
 void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev);
 void ni_tio_init_counter(struct ni_gpct *counter);
 int ni_tio_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
@@ -138,4 +142,40 @@ void ni_tio_set_mite_channel(struct ni_gpct *counter,
                             struct mite_channel *mite_chan);
 void ni_tio_acknowledge(struct ni_gpct *counter);
 
+/*
+ * Retrieves the register value of the current source of the output selector for
+ * the given destination.
+ *
+ * If the terminal for the destination is not already configured as an output,
+ * this function returns -EINVAL as error.
+ *
+ * Return: the register value of the destination output selector;
+ *         -EINVAL if terminal is not configured for output.
+ */
+int ni_tio_get_routing(struct ni_gpct_device *counter_dev,
+                      unsigned int destination);
+
+/*
+ * Sets the register value of the selector MUX for the given destination.
+ * @counter_dev:Pointer to general counter device.
+ * @destination:Device-global identifier of route destination.
+ * @register_value:
+ *             The first several bits of this value should store the desired
+ *             value to write to the register.  All other bits are for
+ *             transmitting information that modify the mode of the particular
+ *             destination/gate.  These mode bits might include a bitwise or of
+ *             CR_INVERT and CR_EDGE.  Note that the calling function should
+ *             have already validated the correctness of this value.
+ */
+int ni_tio_set_routing(struct ni_gpct_device *counter_dev,
+                      unsigned int destination, unsigned int register_value);
+
+/*
+ * Sets the given destination MUX to its default value or disable it.
+ *
+ * Return: 0 if successful; -EINVAL if terminal is unknown.
+ */
+int ni_tio_unset_routing(struct ni_gpct_device *counter_dev,
+                        unsigned int destination);
+
 #endif /* _COMEDI_NI_TIO_H */
index f4d99d78208ad0850b6c03a8d5b9c1019edc47f7..652a28990132912031a1b5691814d70ceea3fb2e 100644 (file)
@@ -170,5 +170,7 @@ unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter,
 int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger);
 int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned int gate,
                        unsigned int src);
+int ni_tio_set_gate_src_raw(struct ni_gpct *counter, unsigned int gate,
+                           unsigned int src);
 
 #endif /* _COMEDI_NI_TIO_INTERNAL_H */
index 050bee0b9515672ae4d5daec15dd155ab22e0b8e..2a9f7e9821a7c9a1334cb3813fac22cbad9db557 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include "ni_tio_internal.h"
 #include "mite.h"
+#include "ni_routes.h"
 
 static void ni_tio_configure_dma(struct ni_gpct *counter,
                                 bool enable, bool read)
@@ -100,6 +101,8 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s)
 {
        struct ni_gpct *counter = s->private;
        struct ni_gpct_device *counter_dev = counter->counter_dev;
+       const struct ni_route_tables *routing_tables =
+               counter_dev->routing_tables;
        unsigned int cidx = counter->counter_index;
        struct comedi_async *async = s->async;
        struct comedi_cmd *cmd = &async->cmd;
@@ -128,8 +131,19 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s)
 
                if (cmd->start_src == TRIG_NOW)
                        ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE);
-               else if (cmd->start_src == TRIG_EXT)
-                       ret = ni_tio_arm(counter, true, cmd->start_arg);
+               else if (cmd->start_src == TRIG_EXT) {
+                       int reg = CR_CHAN(cmd->start_arg);
+
+                       if (reg >= NI_NAMES_BASE) {
+                               /* using a device-global name. lookup reg */
+                               reg = ni_get_reg_value(reg,
+                                                      NI_CtrArmStartTrigger(cidx),
+                                                      routing_tables);
+                               /* mark this as a raw register value */
+                               reg |= NI_GPCT_HW_ARM;
+                       }
+                       ret = ni_tio_arm(counter, true, reg);
+               }
        }
        return ret;
 }
@@ -148,6 +162,8 @@ static int ni_tio_cmd_setup(struct comedi_subdevice *s)
        struct comedi_cmd *cmd = &s->async->cmd;
        struct ni_gpct *counter = s->private;
        unsigned int cidx = counter->counter_index;
+       const struct ni_route_tables *routing_tables =
+               counter->counter_dev->routing_tables;
        int set_gate_source = 0;
        unsigned int gate_source;
        int retval = 0;
@@ -159,8 +175,24 @@ static int ni_tio_cmd_setup(struct comedi_subdevice *s)
                set_gate_source = 1;
                gate_source = cmd->convert_arg;
        }
-       if (set_gate_source)
-               retval = ni_tio_set_gate_src(counter, 0, gate_source);
+       if (set_gate_source) {
+               if (CR_CHAN(gate_source) >= NI_NAMES_BASE) {
+                       /* Lookup and use the real register values */
+                       int reg = ni_get_reg_value(CR_CHAN(gate_source),
+                                                  NI_CtrGate(cidx),
+                                                  routing_tables);
+                       if (reg < 0)
+                               return -EINVAL;
+                       retval = ni_tio_set_gate_src_raw(counter, 0, reg);
+               } else {
+                       /*
+                        * This function must be used separately since it does
+                        * not expect real register values and attempts to
+                        * convert these to real register values.
+                        */
+                       retval = ni_tio_set_gate_src(counter, 0, gate_source);
+               }
+       }
        if (cmd->flags & CMDF_WAKE_EOS) {
                ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
                                GI_GATE_INTERRUPT_ENABLE(cidx),
@@ -203,6 +235,9 @@ int ni_tio_cmdtest(struct comedi_device *dev,
                   struct comedi_cmd *cmd)
 {
        struct ni_gpct *counter = s->private;
+       unsigned int cidx = counter->counter_index;
+       const struct ni_route_tables *routing_tables =
+               counter->counter_dev->routing_tables;
        int err = 0;
        unsigned int sources;
 
@@ -247,14 +282,37 @@ int ni_tio_cmdtest(struct comedi_device *dev,
                break;
        case TRIG_EXT:
                /* start_arg is the start_trigger passed to ni_tio_arm() */
+               /*
+                * This should be done, but we don't yet know the actual
+                * register values.  These should be tested and then documented
+                * in the ni_route_values/ni_*.csv files, with indication of
+                * who/when/which/how these these were tested.
+                * When at least a e/m/660x series have been tested, this code
+                * should be uncommented:
+                *
+                * err |= ni_check_trigger_arg(CR_CHAN(cmd->start_arg),
+                *                          NI_CtrArmStartTrigger(cidx),
+                *                          routing_tables);
+                */
                break;
        }
 
+       /*
+        * It seems that convention is to allow either scan_begin_arg or
+        * convert_arg to specify the Gate source, with scan_begin_arg taking
+        * precedence.
+        */
        if (cmd->scan_begin_src != TRIG_EXT)
                err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+       else
+               err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg),
+                                           NI_CtrGate(cidx), routing_tables);
 
        if (cmd->convert_src != TRIG_EXT)
                err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
+       else
+               err |= ni_check_trigger_arg(CR_CHAN(cmd->convert_arg),
+                                           NI_CtrGate(cidx), routing_tables);
 
        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
                                           cmd->chanlist_len);
diff --git a/drivers/staging/comedi/drivers/tests/Makefile b/drivers/staging/comedi/drivers/tests/Makefile
new file mode 100644 (file)
index 0000000..b5d8e13
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for comedi drivers unit tests
+#
+ccflags-$(CONFIG_COMEDI_DEBUG)         := -DDEBUG
+
+obj-$(CONFIG_COMEDI_TESTS)             += example_test.o ni_routes_test.o
+CFLAGS_ni_routes_test.o                        := -DDEBUG
diff --git a/drivers/staging/comedi/drivers/tests/example_test.c b/drivers/staging/comedi/drivers/tests/example_test.c
new file mode 100644 (file)
index 0000000..fc65158
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/tests/example_test.c
+ *  Example set of unit tests.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+
+#include "unittest.h"
+
+/* *** BEGIN fake board data *** */
+struct comedi_device {
+       const char *board_name;
+       int item;
+};
+
+static struct comedi_device dev = {
+       .board_name = "fake_device",
+};
+
+/* *** END fake board data *** */
+
+/* *** BEGIN fake data init *** */
+void init_fake(void)
+{
+       dev.item = 10;
+}
+
+/* *** END fake data init *** */
+
+void test0(void)
+{
+       init_fake();
+       unittest(dev.item != 11, "negative result\n");
+       unittest(dev.item == 10, "positive result\n");
+}
+
+/* **** BEGIN simple module entry/exit functions **** */
+static int __init unittest_enter(void)
+{
+       const unittest_fptr unit_tests[] = {
+               (unittest_fptr)test0,
+               NULL,
+       };
+
+       exec_unittests("example", unit_tests);
+       return 0;
+}
+
+static void __exit unittest_exit(void) { }
+
+module_init(unittest_enter);
+module_exit(unittest_exit);
+
+MODULE_AUTHOR("Spencer Olson <olsonse@umich.edu>");
+MODULE_DESCRIPTION("Comedi unit-tests example");
+MODULE_LICENSE("GPL");
+/* **** END simple module entry/exit functions **** */
diff --git a/drivers/staging/comedi/drivers/tests/ni_routes_test.c b/drivers/staging/comedi/drivers/tests/ni_routes_test.c
new file mode 100644 (file)
index 0000000..a1eda03
--- /dev/null
@@ -0,0 +1,613 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/tests/ni_routes_test.c
+ *  Unit tests for NI routes (ni_routes.c module).
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+
+#include "../ni_stc.h"
+#include "../ni_routes.h"
+#include "unittest.h"
+
+#define RVi(table, src, dest)  ((table)[(dest) * NI_NUM_NAMES + (src)])
+#define O(x)   ((x) + NI_NAMES_BASE)
+#define B(x)   ((x) - NI_NAMES_BASE)
+#define V(x)   ((x) | 0x80)
+
+/* *** BEGIN fake board data *** */
+static const char *pci_6070e = "pci-6070e";
+static const char *pci_6220 = "pci-6220";
+static const char *pci_fake = "pci-fake";
+
+static const char *ni_eseries = "ni_eseries";
+static const char *ni_mseries = "ni_mseries";
+
+static struct ni_board_struct board = {
+       .name = NULL,
+};
+
+static struct ni_private private = {
+       .is_m_series = 0,
+};
+
+static const int bad_dest = O(8), dest0 = O(0), desti = O(5);
+static const int ith_dest_index = 2;
+static const int no_val_dest = O(7), no_val_index = 4;
+
+/* These have to be defs to be used in init code below */
+#define rgout0_src0    (O(100))
+#define rgout0_src1    (O(101))
+#define brd0_src0      (O(110))
+#define brd0_src1      (O(111))
+#define brd1_src0      (O(120))
+#define brd1_src1      (O(121))
+#define brd2_src0      (O(130))
+#define brd2_src1      (O(131))
+#define brd3_src0      (O(140))
+#define brd3_src1      (O(141))
+
+/* I1 and I2 should not call O(...).  Mostly here to shut checkpatch.pl up */
+#define I1(x1) \
+       (int[]){ \
+               x1, 0 \
+       }
+#define I2(x1, x2)     \
+       (int[]){ \
+               (x1), (x2), 0 \
+       }
+#define I3(x1, x2, x3) \
+       (int[]){ \
+               (x1), (x2), (x3), 0 \
+       }
+
+/* O9 is build to call O(...) for each arg */
+#define O9(x1, x2, x3, x4, x5, x6, x7, x8, x9) \
+       (int[]){ \
+               O(x1), O(x2), O(x3), O(x4), O(x5), O(x6), O(x7), O(x8), O(x9), \
+               0 \
+       }
+
+static struct ni_device_routes DR = {
+       .device = "testdev",
+       .routes = (struct ni_route_set[]){
+               {.dest = O(0), .src = O9(/**/1, 2, 3, 4, 5, 6, 7, 8, 9)},
+               {.dest = O(1), .src = O9(0, /**/2, 3, 4, 5, 6, 7, 8, 9)},
+               /* ith route_set */
+               {.dest = O(5), .src = O9(0, 1, 2, 3, 4,/**/ 6, 7, 8, 9)},
+               {.dest = O(6), .src = O9(0, 1, 2, 3, 4, 5,/**/ 7, 8, 9)},
+               /* next one will not have valid reg values */
+               {.dest = O(7), .src = O9(0, 1, 2, 3, 4, 5, 6,/**/ 8, 9)},
+               {.dest = O(9), .src = O9(0, 1, 2, 3, 4, 5, 6, 7, 8/**/)},
+
+               /* indirect routes done through muxes */
+               {.dest = TRIGGER_LINE(0), .src = I1(rgout0_src0)},
+               {.dest = TRIGGER_LINE(1), .src = I3(rgout0_src0,
+                                                   brd3_src0,
+                                                   brd3_src1)},
+               {.dest = TRIGGER_LINE(2), .src = I3(rgout0_src1,
+                                                   brd2_src0,
+                                                   brd2_src1)},
+               {.dest = TRIGGER_LINE(3), .src = I3(rgout0_src1,
+                                                   brd1_src0,
+                                                   brd1_src1)},
+               {.dest = TRIGGER_LINE(4), .src = I2(brd0_src0,
+                                                   brd0_src1)},
+               {.dest = 0},
+       },
+};
+
+#undef I1
+#undef I2
+#undef O9
+
+#define RV9(x1, x2, x3, x4, x5, x6, x7, x8, x9) \
+       [x1] = V(x1), [x2] = V(x2), [x3] = V(x3), [x4] = V(x4), \
+       [x5] = V(x5), [x6] = V(x6), [x7] = V(x7), [x8] = V(x8), \
+       [x9] = V(x9),
+
+/* This table is indexed as RV[destination][source] */
+static const u8 RV[NI_NUM_NAMES][NI_NUM_NAMES] = {
+       [0] = {RV9(/**/1, 2, 3, 4, 5, 6, 7, 8, 9)},
+       [1] = {RV9(0,/**/ 2, 3, 4, 5, 6, 7, 8, 9)},
+       [2] = {RV9(0,  1,/**/3, 4, 5, 6, 7, 8, 9)},
+       [3] = {RV9(0,  1, 2,/**/4, 5, 6, 7, 8, 9)},
+       [4] = {RV9(0,  1, 2, 3,/**/5, 6, 7, 8, 9)},
+       [5] = {RV9(0,  1, 2, 3, 4,/**/6, 7, 8, 9)},
+       [6] = {RV9(0,  1, 2, 3, 4, 5,/**/7, 8, 9)},
+       /* [7] is intentionaly left absent to test invalid routes */
+       [8] = {RV9(0,  1, 2, 3, 4, 5, 6, 7,/**/9)},
+       [9] = {RV9(0,  1, 2, 3, 4, 5, 6, 7, 8/**/)},
+       /* some tests for needing extra muxes */
+       [B(NI_RGOUT0)]  = {[B(rgout0_src0)]   = V(0),
+                          [B(rgout0_src1)]   = V(1)},
+       [B(NI_RTSI_BRD(0))] = {[B(brd0_src0)] = V(0),
+                              [B(brd0_src1)] = V(1)},
+       [B(NI_RTSI_BRD(1))] = {[B(brd1_src0)] = V(0),
+                              [B(brd1_src1)] = V(1)},
+       [B(NI_RTSI_BRD(2))] = {[B(brd2_src0)] = V(0),
+                              [B(brd2_src1)] = V(1)},
+       [B(NI_RTSI_BRD(3))] = {[B(brd3_src0)] = V(0),
+                              [B(brd3_src1)] = V(1)},
+};
+
+#undef RV9
+
+/* *** END fake board data *** */
+
+/* *** BEGIN board data initializers *** */
+static void init_private(void)
+{
+       memset(&private, 0, sizeof(struct ni_private));
+}
+
+static void init_pci_6070e(void)
+{
+       board.name = pci_6070e;
+       init_private();
+       private.is_m_series = 0;
+}
+
+static void init_pci_6220(void)
+{
+       board.name = pci_6220;
+       init_private();
+       private.is_m_series = 1;
+}
+
+static void init_pci_fake(void)
+{
+       board.name = pci_fake;
+       init_private();
+       private.routing_tables.route_values = &RV[0][0];
+       private.routing_tables.valid_routes = &DR;
+}
+
+/* *** END board data initializers *** */
+
+/* Tests that route_sets are in order of the signal destination. */
+static bool route_set_dests_in_order(const struct ni_device_routes *devroutes)
+{
+       int i;
+       int last = NI_NAMES_BASE - 1;
+
+       for (i = 0; i < devroutes->n_route_sets; ++i) {
+               if (last >= devroutes->routes[i].dest)
+                       return false;
+               last = devroutes->routes[i].dest;
+       }
+       return true;
+}
+
+/* Tests that all route_set->src are in order of the signal source. */
+bool route_set_sources_in_order(const struct ni_device_routes *devroutes)
+{
+       int i;
+
+       for (i = 0; i < devroutes->n_route_sets; ++i) {
+               int j;
+               int last = NI_NAMES_BASE - 1;
+
+               for (j = 0; j < devroutes->routes[i].n_src; ++j) {
+                       if (last >= devroutes->routes[i].src[j])
+                               return false;
+                       last = devroutes->routes[i].src[j];
+               }
+       }
+       return true;
+}
+
+void test_ni_assign_device_routes(void)
+{
+       const struct ni_device_routes *devroutes, *olddevroutes;
+       const u8 *table, *oldtable;
+
+       init_pci_6070e();
+       ni_assign_device_routes(ni_eseries, pci_6070e, &private.routing_tables);
+       devroutes = private.routing_tables.valid_routes;
+       table = private.routing_tables.route_values;
+
+       unittest(strncmp(devroutes->device, pci_6070e, 10) == 0,
+                "find device pci-6070e\n");
+       unittest(devroutes->n_route_sets == 37,
+                "number of pci-6070e route_sets == 37\n");
+       unittest(devroutes->routes->dest == NI_PFI(0),
+                "first pci-6070e route_set is for NI_PFI(0)\n");
+       unittest(devroutes->routes->n_src == 1,
+                "first pci-6070e route_set length == 1\n");
+       unittest(devroutes->routes->src[0] == NI_AI_StartTrigger,
+                "first pci-6070e route_set src. == NI_AI_StartTrigger\n");
+       unittest(devroutes->routes[10].dest == TRIGGER_LINE(0),
+                "10th pci-6070e route_set is for TRIGGER_LINE(0)\n");
+       unittest(devroutes->routes[10].n_src == 10,
+                "10th pci-6070e route_set length == 10\n");
+       unittest(devroutes->routes[10].src[0] == NI_CtrSource(0),
+                "10th pci-6070e route_set src. == NI_CtrSource(0)\n");
+       unittest(route_set_dests_in_order(devroutes),
+                "all pci-6070e route_sets in order of signal destination\n");
+       unittest(route_set_sources_in_order(devroutes),
+                "all pci-6070e route_set->src's in order of signal source\n");
+
+       unittest(
+         RVi(table, B(PXI_Star), B(NI_AI_SampleClock)) == V(17) &&
+         RVi(table, B(NI_10MHzRefClock), B(TRIGGER_LINE(0))) == 0 &&
+         RVi(table, B(NI_AI_ConvertClock), B(NI_PFI(0))) == 0 &&
+         RVi(table, B(NI_AI_ConvertClock), B(NI_PFI(2))) ==
+               V(NI_PFI_OUTPUT_AI_CONVERT),
+         "pci-6070e finds e-series route_values table\n");
+
+       olddevroutes = devroutes;
+       oldtable = table;
+       init_pci_6220();
+       ni_assign_device_routes(ni_mseries, pci_6220, &private.routing_tables);
+       devroutes = private.routing_tables.valid_routes;
+       table = private.routing_tables.route_values;
+
+       unittest(strncmp(devroutes->device, pci_6220, 10) == 0,
+                "find device pci-6220\n");
+       unittest(oldtable != table, "pci-6220 find other route_values table\n");
+
+       unittest(
+         RVi(table, B(PXI_Star), B(NI_AI_SampleClock)) == V(20) &&
+         RVi(table, B(NI_10MHzRefClock), B(TRIGGER_LINE(0))) == V(12) &&
+         RVi(table, B(NI_AI_ConvertClock), B(NI_PFI(0))) == V(3) &&
+         RVi(table, B(NI_AI_ConvertClock), B(NI_PFI(2))) == V(3),
+         "pci-6220 finds m-series route_values table\n");
+}
+
+void test_ni_sort_device_routes(void)
+{
+       /* We begin by sorting the device routes for use in later tests */
+       ni_sort_device_routes(&DR);
+       /* now we test that sorting. */
+       unittest(route_set_dests_in_order(&DR),
+                "all route_sets of fake data in order of sig. destination\n");
+       unittest(route_set_sources_in_order(&DR),
+                "all route_set->src's of fake data in order of sig. source\n");
+}
+
+void test_ni_find_route_set(void)
+{
+       unittest(ni_find_route_set(bad_dest, &DR) == NULL,
+                "check for nonexistent route_set\n");
+       unittest(ni_find_route_set(dest0, &DR) == &DR.routes[0],
+                "find first route_set\n");
+       unittest(ni_find_route_set(desti, &DR) == &DR.routes[ith_dest_index],
+                "find ith route_set\n");
+       unittest(ni_find_route_set(no_val_dest, &DR) ==
+                &DR.routes[no_val_index],
+                "find no_val route_set in spite of missing values\n");
+       unittest(ni_find_route_set(DR.routes[DR.n_route_sets - 1].dest, &DR) ==
+                &DR.routes[DR.n_route_sets - 1],
+                "find last route_set\n");
+}
+
+void test_ni_route_set_has_source(void)
+{
+       unittest(!ni_route_set_has_source(&DR.routes[0], O(0)),
+                "check for bad source\n");
+       unittest(ni_route_set_has_source(&DR.routes[0], O(1)),
+                "find first source\n");
+       unittest(ni_route_set_has_source(&DR.routes[0], O(5)),
+                "find fifth source\n");
+       unittest(ni_route_set_has_source(&DR.routes[0], O(9)),
+                "find last source\n");
+}
+
+void test_ni_route_to_register(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(ni_route_to_register(O(0), O(0), T) < 0,
+                "check for bad route 0-->0\n");
+       unittest(ni_route_to_register(O(1), O(0), T) == 1,
+                "validate first destination\n");
+       unittest(ni_route_to_register(O(6), O(5), T) == 6,
+                "validate middle destination\n");
+       unittest(ni_route_to_register(O(8), O(9), T) == 8,
+                "validate last destination\n");
+
+       /* choice of trigger line in the following is somewhat random */
+       unittest(ni_route_to_register(rgout0_src0, TRIGGER_LINE(0), T) == 0,
+                "validate indirect route through rgout0 to TRIGGER_LINE(0)\n");
+       unittest(ni_route_to_register(rgout0_src0, TRIGGER_LINE(1), T) == 0,
+                "validate indirect route through rgout0 to TRIGGER_LINE(1)\n");
+       unittest(ni_route_to_register(rgout0_src1, TRIGGER_LINE(2), T) == 1,
+                "validate indirect route through rgout0 to TRIGGER_LINE(2)\n");
+       unittest(ni_route_to_register(rgout0_src1, TRIGGER_LINE(3), T) == 1,
+                "validate indirect route through rgout0 to TRIGGER_LINE(3)\n");
+
+       unittest(ni_route_to_register(brd0_src0, TRIGGER_LINE(4), T) ==
+                BIT(6),
+                "validate indirect route through brd0 to TRIGGER_LINE(4)\n");
+       unittest(ni_route_to_register(brd0_src1, TRIGGER_LINE(4), T) ==
+                BIT(6),
+                "validate indirect route through brd0 to TRIGGER_LINE(4)\n");
+       unittest(ni_route_to_register(brd1_src0, TRIGGER_LINE(3), T) ==
+                BIT(6),
+                "validate indirect route through brd1 to TRIGGER_LINE(3)\n");
+       unittest(ni_route_to_register(brd1_src1, TRIGGER_LINE(3), T) ==
+                BIT(6),
+                "validate indirect route through brd1 to TRIGGER_LINE(3)\n");
+       unittest(ni_route_to_register(brd2_src0, TRIGGER_LINE(2), T) ==
+                BIT(6),
+                "validate indirect route through brd2 to TRIGGER_LINE(2)\n");
+       unittest(ni_route_to_register(brd2_src1, TRIGGER_LINE(2), T) ==
+                BIT(6),
+                "validate indirect route through brd2 to TRIGGER_LINE(2)\n");
+       unittest(ni_route_to_register(brd3_src0, TRIGGER_LINE(1), T) ==
+                BIT(6),
+                "validate indirect route through brd3 to TRIGGER_LINE(1)\n");
+       unittest(ni_route_to_register(brd3_src1, TRIGGER_LINE(1), T) ==
+                BIT(6),
+                "validate indirect route through brd3 to TRIGGER_LINE(1)\n");
+}
+
+void test_ni_lookup_route_register(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(ni_lookup_route_register(O(0), O(0), T) == -EINVAL,
+                "check for bad route 0-->0\n");
+       unittest(ni_lookup_route_register(O(1), O(0), T) == 1,
+                "validate first destination\n");
+       unittest(ni_lookup_route_register(O(6), O(5), T) == 6,
+                "validate middle destination\n");
+       unittest(ni_lookup_route_register(O(8), O(9), T) == 8,
+                "validate last destination\n");
+       unittest(ni_lookup_route_register(O(10), O(9), T) == -EINVAL,
+                "lookup invalid desination\n");
+
+       unittest(ni_lookup_route_register(rgout0_src0, TRIGGER_LINE(0), T) ==
+                -EINVAL,
+                "rgout0_src0: no direct lookup of indirect route\n");
+       unittest(ni_lookup_route_register(rgout0_src0, NI_RGOUT0, T) == 0,
+                "rgout0_src0: lookup indirect route register\n");
+       unittest(ni_lookup_route_register(rgout0_src1, TRIGGER_LINE(2), T) ==
+                -EINVAL,
+                "rgout0_src1: no direct lookup of indirect route\n");
+       unittest(ni_lookup_route_register(rgout0_src1, NI_RGOUT0, T) == 1,
+                "rgout0_src1: lookup indirect route register\n");
+
+       unittest(ni_lookup_route_register(brd0_src0, TRIGGER_LINE(4), T) ==
+                -EINVAL,
+                "brd0_src0: no direct lookup of indirect route\n");
+       unittest(ni_lookup_route_register(brd0_src0, NI_RTSI_BRD(0), T) == 0,
+                "brd0_src0: lookup indirect route register\n");
+       unittest(ni_lookup_route_register(brd0_src1, TRIGGER_LINE(4), T) ==
+                -EINVAL,
+                "brd0_src1: no direct lookup of indirect route\n");
+       unittest(ni_lookup_route_register(brd0_src1, NI_RTSI_BRD(0), T) == 1,
+                "brd0_src1: lookup indirect route register\n");
+}
+
+void test_route_is_valid(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(!route_is_valid(O(0), O(0), T),
+                "check for bad route 0-->0\n");
+       unittest(route_is_valid(O(0), O(1), T),
+                "validate first destination\n");
+       unittest(route_is_valid(O(5), O(6), T),
+                "validate middle destination\n");
+       unittest(route_is_valid(O(8), O(9), T),
+                "validate last destination\n");
+}
+
+void test_ni_is_cmd_dest(void)
+{
+       init_pci_fake();
+       unittest(ni_is_cmd_dest(NI_AI_SampleClock),
+                "check that AI/SampleClock is cmd destination\n");
+       unittest(ni_is_cmd_dest(NI_AI_StartTrigger),
+                "check that AI/StartTrigger is cmd destination\n");
+       unittest(ni_is_cmd_dest(NI_AI_ConvertClock),
+                "check that AI/ConvertClock is cmd destination\n");
+       unittest(ni_is_cmd_dest(NI_AO_SampleClock),
+                "check that AO/SampleClock is cmd destination\n");
+       unittest(ni_is_cmd_dest(NI_DO_SampleClock),
+                "check that DO/SampleClock is cmd destination\n");
+       unittest(!ni_is_cmd_dest(NI_AO_SampleClockTimebase),
+                "check that AO/SampleClockTimebase _not_ cmd destination\n");
+}
+
+void test_channel_is_pfi(void)
+{
+       init_pci_fake();
+       unittest(channel_is_pfi(NI_PFI(0)), "check First pfi channel\n");
+       unittest(channel_is_pfi(NI_PFI(10)), "check 10th pfi channel\n");
+       unittest(channel_is_pfi(NI_PFI(-1)), "check last pfi channel\n");
+       unittest(!channel_is_pfi(NI_PFI(-1) + 1),
+                "check first non pfi channel\n");
+}
+
+void test_channel_is_rtsi(void)
+{
+       init_pci_fake();
+       unittest(channel_is_rtsi(TRIGGER_LINE(0)),
+                "check First rtsi channel\n");
+       unittest(channel_is_rtsi(TRIGGER_LINE(3)),
+                "check 3rd rtsi channel\n");
+       unittest(channel_is_rtsi(TRIGGER_LINE(-1)),
+                "check last rtsi channel\n");
+       unittest(!channel_is_rtsi(TRIGGER_LINE(-1) + 1),
+                "check first non rtsi channel\n");
+}
+
+void test_ni_count_valid_routes(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(ni_count_valid_routes(T) == 57, "count all valid routes\n");
+}
+
+void test_ni_get_valid_routes(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+       unsigned int pair_data[2];
+
+       init_pci_fake();
+       unittest(ni_get_valid_routes(T, 0, NULL) == 57,
+                "count all valid routes through ni_get_valid_routes\n");
+
+       unittest(ni_get_valid_routes(T, 1, pair_data) == 1,
+                "copied first valid route from ni_get_valid_routes\n");
+       unittest(pair_data[0] == O(1),
+                "source of first valid pair from ni_get_valid_routes\n");
+       unittest(pair_data[1] == O(0),
+                "destination of first valid pair from ni_get_valid_routes\n");
+}
+
+void test_ni_find_route_source(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(ni_find_route_source(4, O(4), T) == -EINVAL,
+                "check for bad source 4-->4\n");
+       unittest(ni_find_route_source(0, O(1), T) == O(0),
+                "find first source\n");
+       unittest(ni_find_route_source(4, O(6), T) == O(4),
+                "find middle source\n");
+       unittest(ni_find_route_source(9, O(8), T) == O(9),
+                "find last source");
+       unittest(ni_find_route_source(8, O(9), T) == O(8),
+                "find invalid source (without checking device routes)\n");
+}
+
+void test_route_register_is_valid(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(route_register_is_valid(4, O(4), T) == false,
+                "check for bad source 4-->4\n");
+       unittest(route_register_is_valid(0, O(1), T) == true,
+                "find first source\n");
+       unittest(route_register_is_valid(4, O(6), T) == true,
+                "find middle source\n");
+       unittest(route_register_is_valid(9, O(8), T) == true,
+                "find last source");
+}
+
+void test_ni_check_trigger_arg(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(ni_check_trigger_arg(0, O(0), T) == -EINVAL,
+                "check bad direct trigger arg for first reg->dest\n");
+       unittest(ni_check_trigger_arg(0, O(1), T) == 0,
+                "check direct trigger arg for first reg->dest\n");
+       unittest(ni_check_trigger_arg(4, O(6), T) == 0,
+                "check direct trigger arg for middle reg->dest\n");
+       unittest(ni_check_trigger_arg(9, O(8), T) == 0,
+                "check direct trigger arg for last reg->dest\n");
+
+       unittest(ni_check_trigger_arg_roffs(-1, O(0), T, 1) == -EINVAL,
+                "check bad direct trigger arg for first reg->dest w/offs\n");
+       unittest(ni_check_trigger_arg_roffs(0, O(1), T, 0) == 0,
+                "check direct trigger arg for first reg->dest w/offs\n");
+       unittest(ni_check_trigger_arg_roffs(3, O(6), T, 1) == 0,
+                "check direct trigger arg for middle reg->dest w/offs\n");
+       unittest(ni_check_trigger_arg_roffs(7, O(8), T, 2) == 0,
+                "check direct trigger arg for last reg->dest w/offs\n");
+
+       unittest(ni_check_trigger_arg(O(0), O(0), T) == -EINVAL,
+                "check bad trigger arg for first src->dest\n");
+       unittest(ni_check_trigger_arg(O(0), O(1), T) == 0,
+                "check trigger arg for first src->dest\n");
+       unittest(ni_check_trigger_arg(O(5), O(6), T) == 0,
+                "check trigger arg for middle src->dest\n");
+       unittest(ni_check_trigger_arg(O(8), O(9), T) == 0,
+                "check trigger arg for last src->dest\n");
+}
+
+void test_ni_get_reg_value(void)
+{
+       const struct ni_route_tables *T = &private.routing_tables;
+
+       init_pci_fake();
+       unittest(ni_get_reg_value(0, O(0), T) == -1,
+                "check bad direct trigger arg for first reg->dest\n");
+       unittest(ni_get_reg_value(0, O(1), T) == 0,
+                "check direct trigger arg for first reg->dest\n");
+       unittest(ni_get_reg_value(4, O(6), T) == 4,
+                "check direct trigger arg for middle reg->dest\n");
+       unittest(ni_get_reg_value(9, O(8), T) == 9,
+                "check direct trigger arg for last reg->dest\n");
+
+       unittest(ni_get_reg_value_roffs(-1, O(0), T, 1) == -1,
+                "check bad direct trigger arg for first reg->dest w/offs\n");
+       unittest(ni_get_reg_value_roffs(0, O(1), T, 0) == 0,
+                "check direct trigger arg for first reg->dest w/offs\n");
+       unittest(ni_get_reg_value_roffs(3, O(6), T, 1) == 4,
+                "check direct trigger arg for middle reg->dest w/offs\n");
+       unittest(ni_get_reg_value_roffs(7, O(8), T, 2) == 9,
+                "check direct trigger arg for last reg->dest w/offs\n");
+
+       unittest(ni_get_reg_value(O(0), O(0), T) == -1,
+                "check bad trigger arg for first src->dest\n");
+       unittest(ni_get_reg_value(O(0), O(1), T) == 0,
+                "check trigger arg for first src->dest\n");
+       unittest(ni_get_reg_value(O(5), O(6), T) == 5,
+                "check trigger arg for middle src->dest\n");
+       unittest(ni_get_reg_value(O(8), O(9), T) == 8,
+                "check trigger arg for last src->dest\n");
+}
+
+/* **** BEGIN simple module entry/exit functions **** */
+static int __init ni_routes_unittest(void)
+{
+       const unittest_fptr unit_tests[] = {
+               (unittest_fptr)test_ni_assign_device_routes,
+               (unittest_fptr)test_ni_sort_device_routes,
+               (unittest_fptr)test_ni_find_route_set,
+               (unittest_fptr)test_ni_route_set_has_source,
+               (unittest_fptr)test_ni_route_to_register,
+               (unittest_fptr)test_ni_lookup_route_register,
+               (unittest_fptr)test_route_is_valid,
+               (unittest_fptr)test_ni_is_cmd_dest,
+               (unittest_fptr)test_channel_is_pfi,
+               (unittest_fptr)test_channel_is_rtsi,
+               (unittest_fptr)test_ni_count_valid_routes,
+               (unittest_fptr)test_ni_get_valid_routes,
+               (unittest_fptr)test_ni_find_route_source,
+               (unittest_fptr)test_route_register_is_valid,
+               (unittest_fptr)test_ni_check_trigger_arg,
+               (unittest_fptr)test_ni_get_reg_value,
+               NULL,
+       };
+
+       exec_unittests("ni_routes", unit_tests);
+       return 0;
+}
+
+static void __exit ni_routes_unittest_exit(void) { }
+
+module_init(ni_routes_unittest);
+module_exit(ni_routes_unittest_exit);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi unit-tests for ni_routes module");
+MODULE_LICENSE("GPL");
+/* **** END simple module entry/exit functions **** */
diff --git a/drivers/staging/comedi/drivers/tests/unittest.h b/drivers/staging/comedi/drivers/tests/unittest.h
new file mode 100644 (file)
index 0000000..b8e622e
--- /dev/null
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
+/*
+ *  comedi/drivers/tests/unittest.h
+ *  Simple framework for unittests for comedi drivers.
+ *
+ *  COMEDI - Linux Control and Measurement Device Interface
+ *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
+ *  based of parts of drivers/of/unittest.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _COMEDI_DRIVERS_TESTS_UNITTEST_H
+#define _COMEDI_DRIVERS_TESTS_UNITTEST_H
+
+static struct unittest_results {
+       int passed;
+       int failed;
+} unittest_results;
+
+typedef void *(*unittest_fptr)(void);
+
+#define unittest(result, fmt, ...) ({ \
+       bool failed = !(result); \
+       if (failed) { \
+               ++unittest_results.failed; \
+               pr_err("FAIL %s():%i " fmt, __func__, __LINE__, \
+                      ##__VA_ARGS__); \
+       } else { \
+               ++unittest_results.passed; \
+               pr_debug("pass %s():%i " fmt, __func__, __LINE__, \
+                        ##__VA_ARGS__); \
+       } \
+       failed; \
+})
+
+/**
+ * Execute an array of unit tests.
+ * @name:      Name of set of unit tests--will be shown at INFO log level.
+ * @unit_tests:        A null-terminated list of unit tests to execute.
+ */
+static inline void exec_unittests(const char *name,
+                                 const unittest_fptr *unit_tests)
+{
+       pr_info("begin comedi:\"%s\" unittests\n", name);
+
+       for (; (*unit_tests) != NULL; ++unit_tests)
+               (*unit_tests)();
+
+       pr_info("end of comedi:\"%s\" unittests - %i passed, %i failed\n", name,
+               unittest_results.passed, unittest_results.failed);
+}
+
+#endif /* _COMEDI_DRIVERS_TESTS_UNITTEST_H */
diff --git a/drivers/staging/dgnc/Kconfig b/drivers/staging/dgnc/Kconfig
deleted file mode 100644 (file)
index 032c2a7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-config DGNC
-       tristate "Digi Neo and Classic PCI Products"
-       default n
-       depends on TTY && PCI
-       ---help---
-       Driver for the Digi International Neo and Classic PCI based product line.
diff --git a/drivers/staging/dgnc/Makefile b/drivers/staging/dgnc/Makefile
deleted file mode 100644 (file)
index 4963304..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-obj-$(CONFIG_DGNC) += dgnc.o
-
-dgnc-objs :=   dgnc_cls.o dgnc_driver.o\
-               dgnc_tty.o
diff --git a/drivers/staging/dgnc/TODO b/drivers/staging/dgnc/TODO
deleted file mode 100644 (file)
index d4cc657..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-* remove unnecessary comments
-* there is a lot of unnecessary code in the driver. It was
-  originally a standalone driver. Remove unneeded code.
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
-Cc: Lidza Louina <lidza.louina@gmail.com>
diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c
deleted file mode 100644 (file)
index 7e6cbfe..0000000
+++ /dev/null
@@ -1,1135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/serial.h>
-#include <linux/serial_reg.h>
-#include <linux/pci.h>
-
-#include "dgnc_driver.h"
-#include "dgnc_cls.h"
-#include "dgnc_tty.h"
-
-static inline void cls_set_cts_flow_control(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char ier = readb(&ch->ch_cls_uart->ier);
-       unsigned char isr_fcr = 0;
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn on CTS flow control, turn off IXON flow control */
-       isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR);
-       isr_fcr &= ~(UART_EXAR654_EFR_IXON);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /*
-        * Enable interrupts for CTS flow, turn off interrupts for
-        * received XOFF chars
-        */
-       ier |= (UART_EXAR654_IER_CTSDSR);
-       ier &= ~(UART_EXAR654_IER_XOFF);
-       writeb(ier, &ch->ch_cls_uart->ier);
-
-       /* Set the usual FIFO values */
-       writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
-               UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
-               &ch->ch_cls_uart->isr_fcr);
-
-       ch->ch_t_tlevel = 16;
-}
-
-static inline void cls_set_ixon_flow_control(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char ier = readb(&ch->ch_cls_uart->ier);
-       unsigned char isr_fcr = 0;
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn on IXON flow control, turn off CTS flow control */
-       isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON);
-       isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Now set our current start/stop chars while in enhanced mode */
-       writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
-       writeb(0, &ch->ch_cls_uart->lsr);
-       writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
-       writeb(0, &ch->ch_cls_uart->spr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /*
-        * Disable interrupts for CTS flow, turn on interrupts for
-        * received XOFF chars
-        */
-       ier &= ~(UART_EXAR654_IER_CTSDSR);
-       ier |= (UART_EXAR654_IER_XOFF);
-       writeb(ier, &ch->ch_cls_uart->ier);
-
-       /* Set the usual FIFO values */
-       writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
-               UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
-               &ch->ch_cls_uart->isr_fcr);
-}
-
-static inline void cls_set_no_output_flow_control(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char ier = readb(&ch->ch_cls_uart->ier);
-       unsigned char isr_fcr = 0;
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn off IXON flow control, turn off CTS flow control */
-       isr_fcr |= (UART_EXAR654_EFR_ECB);
-       isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /*
-        * Disable interrupts for CTS flow, turn off interrupts for
-        * received XOFF chars
-        */
-       ier &= ~(UART_EXAR654_IER_CTSDSR);
-       ier &= ~(UART_EXAR654_IER_XOFF);
-       writeb(ier, &ch->ch_cls_uart->ier);
-
-       /* Set the usual FIFO values */
-       writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
-               UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
-               &ch->ch_cls_uart->isr_fcr);
-
-       ch->ch_r_watermark = 0;
-       ch->ch_t_tlevel = 16;
-       ch->ch_r_tlevel = 16;
-}
-
-static inline void cls_set_rts_flow_control(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char ier = readb(&ch->ch_cls_uart->ier);
-       unsigned char isr_fcr = 0;
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn on RTS flow control, turn off IXOFF flow control */
-       isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR);
-       isr_fcr &= ~(UART_EXAR654_EFR_IXOFF);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /* Enable interrupts for RTS flow */
-       ier |= (UART_EXAR654_IER_RTSDTR);
-       writeb(ier, &ch->ch_cls_uart->ier);
-
-       /* Set the usual FIFO values */
-       writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
-               UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
-               &ch->ch_cls_uart->isr_fcr);
-
-       ch->ch_r_watermark = 4;
-       ch->ch_r_tlevel = 8;
-}
-
-static inline void cls_set_ixoff_flow_control(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char ier = readb(&ch->ch_cls_uart->ier);
-       unsigned char isr_fcr = 0;
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn on IXOFF flow control, turn off RTS flow control */
-       isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF);
-       isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Now set our current start/stop chars while in enhanced mode */
-       writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
-       writeb(0, &ch->ch_cls_uart->lsr);
-       writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
-       writeb(0, &ch->ch_cls_uart->spr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /* Disable interrupts for RTS flow */
-       ier &= ~(UART_EXAR654_IER_RTSDTR);
-       writeb(ier, &ch->ch_cls_uart->ier);
-
-       /* Set the usual FIFO values */
-       writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
-               UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
-               &ch->ch_cls_uart->isr_fcr);
-}
-
-static inline void cls_set_no_input_flow_control(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char ier = readb(&ch->ch_cls_uart->ier);
-       unsigned char isr_fcr = 0;
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn off IXOFF flow control, turn off RTS flow control */
-       isr_fcr |= (UART_EXAR654_EFR_ECB);
-       isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /* Disable interrupts for RTS flow */
-       ier &= ~(UART_EXAR654_IER_RTSDTR);
-       writeb(ier, &ch->ch_cls_uart->ier);
-
-       /* Set the usual FIFO values */
-       writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
-               UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
-               &ch->ch_cls_uart->isr_fcr);
-
-       ch->ch_t_tlevel = 16;
-       ch->ch_r_tlevel = 16;
-}
-
-/*
- * Determines whether its time to shut off break condition.
- *
- * No locks are assumed to be held when calling this function.
- * channel lock is held and released in this function.
- */
-static inline void cls_clear_break(struct channel_t *ch, int force)
-{
-       unsigned long flags;
-
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       if (!ch->ch_stop_sending_break) {
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return;
-       }
-
-       /* Turn break off, and unset some variables */
-       if (ch->ch_flags & CH_BREAK_SENDING) {
-               if (time_after(jiffies, ch->ch_stop_sending_break) || force) {
-                       unsigned char temp = readb(&ch->ch_cls_uart->lcr);
-
-                       writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
-                       ch->ch_flags &= ~(CH_BREAK_SENDING);
-                       ch->ch_stop_sending_break = 0;
-               }
-       }
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void cls_copy_data_from_uart_to_queue(struct channel_t *ch)
-{
-       int qleft = 0;
-       unsigned char linestatus = 0;
-       unsigned char error_mask = 0;
-       ushort head;
-       ushort tail;
-       unsigned long flags;
-
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       head = ch->ch_r_head;
-       tail = ch->ch_r_tail;
-
-       qleft = tail - head - 1;
-       if (qleft < 0)
-               qleft += RQUEUEMASK + 1;
-
-       /*
-        * Create a mask to determine whether we should
-        * insert the character (if any) into our queue.
-        */
-       if (ch->ch_c_iflag & IGNBRK)
-               error_mask |= UART_LSR_BI;
-
-       while (1) {
-               linestatus = readb(&ch->ch_cls_uart->lsr);
-
-               if (!(linestatus & (UART_LSR_DR)))
-                       break;
-
-               /* Discard character if we are ignoring the error mask. */
-               if (linestatus & error_mask)  {
-                       linestatus = 0;
-                       readb(&ch->ch_cls_uart->txrx);
-                       continue;
-               }
-
-               /*
-                * If our queue is full, we have no choice but to drop some
-                * data. The assumption is that HWFLOW or SWFLOW should have
-                * stopped things way way before we got to this point.
-                */
-               while (qleft < 1) {
-                       tail = (tail + 1) & RQUEUEMASK;
-                       ch->ch_r_tail = tail;
-                       ch->ch_err_overrun++;
-                       qleft++;
-               }
-
-               ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
-                                                                | UART_LSR_FE);
-               ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
-
-               qleft--;
-
-               if (ch->ch_equeue[head] & UART_LSR_PE)
-                       ch->ch_err_parity++;
-               if (ch->ch_equeue[head] & UART_LSR_BI)
-                       ch->ch_err_break++;
-               if (ch->ch_equeue[head] & UART_LSR_FE)
-                       ch->ch_err_frame++;
-
-               head = (head + 1) & RQUEUEMASK;
-               ch->ch_rxcount++;
-       }
-
-       ch->ch_r_head = head & RQUEUEMASK;
-       ch->ch_e_head = head & EQUEUEMASK;
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Make the UART raise any of the output signals we want up */
-static void cls_assert_modem_signals(struct channel_t *ch)
-{
-       unsigned char out;
-
-       if (!ch)
-               return;
-
-       out = ch->ch_mostat;
-
-       if (ch->ch_flags & CH_LOOPBACK)
-               out |= UART_MCR_LOOP;
-
-       writeb(out, &ch->ch_cls_uart->mcr);
-
-       /* Give time for the UART to actually drop the signals */
-       usleep_range(10, 20);
-}
-
-static void cls_copy_data_from_queue_to_uart(struct channel_t *ch)
-{
-       ushort head;
-       ushort tail;
-       int n;
-       int qlen;
-       uint len_written = 0;
-       unsigned long flags;
-
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       if (ch->ch_w_tail == ch->ch_w_head)
-               goto exit_unlock;
-
-       /* If port is "stopped", don't send any data to the UART */
-       if ((ch->ch_flags & CH_FORCED_STOP) ||
-           (ch->ch_flags & CH_BREAK_SENDING))
-               goto exit_unlock;
-
-       if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
-               goto exit_unlock;
-
-       n = 32;
-
-       head = ch->ch_w_head & WQUEUEMASK;
-       tail = ch->ch_w_tail & WQUEUEMASK;
-       qlen = (head - tail) & WQUEUEMASK;
-
-       n = min(n, qlen);
-
-       while (n > 0) {
-               /*
-                * If RTS Toggle mode is on, turn on RTS now if not already set,
-                * and make sure we get an event when the data transfer has
-                * completed.
-                */
-               if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
-                       if (!(ch->ch_mostat & UART_MCR_RTS)) {
-                               ch->ch_mostat |= (UART_MCR_RTS);
-                               cls_assert_modem_signals(ch);
-                       }
-                       ch->ch_tun.un_flags |= (UN_EMPTY);
-               }
-
-               /*
-                * If DTR Toggle mode is on, turn on DTR now if not already set,
-                * and make sure we get an event when the data transfer has
-                * completed.
-                */
-               if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
-                       if (!(ch->ch_mostat & UART_MCR_DTR)) {
-                               ch->ch_mostat |= (UART_MCR_DTR);
-                               cls_assert_modem_signals(ch);
-                       }
-                       ch->ch_tun.un_flags |= (UN_EMPTY);
-               }
-               writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx);
-               ch->ch_w_tail++;
-               ch->ch_w_tail &= WQUEUEMASK;
-               ch->ch_txcount++;
-               len_written++;
-               n--;
-       }
-
-       if (len_written > 0)
-               ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-
-exit_unlock:
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void cls_parse_modem(struct channel_t *ch, unsigned char signals)
-{
-       unsigned char msignals = signals;
-       unsigned long flags;
-
-       if (!ch)
-               return;
-
-       /*
-        * Do altpin switching. Altpin switches DCD and DSR.
-        * This prolly breaks DSRPACE, so we should be more clever here.
-        */
-       spin_lock_irqsave(&ch->ch_lock, flags);
-       if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
-               unsigned char mswap = signals;
-
-               if (mswap & UART_MSR_DDCD) {
-                       msignals &= ~UART_MSR_DDCD;
-                       msignals |= UART_MSR_DDSR;
-               }
-               if (mswap & UART_MSR_DDSR) {
-                       msignals &= ~UART_MSR_DDSR;
-                       msignals |= UART_MSR_DDCD;
-               }
-               if (mswap & UART_MSR_DCD) {
-                       msignals &= ~UART_MSR_DCD;
-                       msignals |= UART_MSR_DSR;
-               }
-               if (mswap & UART_MSR_DSR) {
-                       msignals &= ~UART_MSR_DSR;
-                       msignals |= UART_MSR_DCD;
-               }
-       }
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       /* Scrub off lower bits. They signify delta's */
-       signals &= 0xf0;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-       if (msignals & UART_MSR_DCD)
-               ch->ch_mistat |= UART_MSR_DCD;
-       else
-               ch->ch_mistat &= ~UART_MSR_DCD;
-
-       if (msignals & UART_MSR_DSR)
-               ch->ch_mistat |= UART_MSR_DSR;
-       else
-               ch->ch_mistat &= ~UART_MSR_DSR;
-
-       if (msignals & UART_MSR_RI)
-               ch->ch_mistat |= UART_MSR_RI;
-       else
-               ch->ch_mistat &= ~UART_MSR_RI;
-
-       if (msignals & UART_MSR_CTS)
-               ch->ch_mistat |= UART_MSR_CTS;
-       else
-               ch->ch_mistat &= ~UART_MSR_CTS;
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Parse the ISR register for the specific port */
-static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
-{
-       struct channel_t *ch;
-       unsigned char isr = 0;
-       unsigned long flags;
-
-       /*
-        * No need to verify board pointer, it was already
-        * verified in the interrupt routine.
-        */
-
-       if (port >= brd->nasync)
-               return;
-
-       ch = brd->channels[port];
-
-       /* Here we try to figure out what caused the interrupt to happen */
-       while (1) {
-               isr = readb(&ch->ch_cls_uart->isr_fcr);
-
-               if (isr & UART_IIR_NO_INT)
-                       break;
-
-               /* Receive Interrupt pending */
-               if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
-                       cls_copy_data_from_uart_to_queue(ch);
-                       dgnc_check_queue_flow_control(ch);
-               }
-
-               /* Transmit Hold register empty pending */
-               if (isr & UART_IIR_THRI) {
-                       spin_lock_irqsave(&ch->ch_lock, flags);
-                       ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-                       spin_unlock_irqrestore(&ch->ch_lock, flags);
-                       cls_copy_data_from_queue_to_uart(ch);
-               }
-
-               cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
-       }
-}
-
-/* Channel lock MUST be held before calling this function! */
-static void cls_flush_uart_write(struct channel_t *ch)
-{
-       if (!ch)
-               return;
-
-       writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
-              &ch->ch_cls_uart->isr_fcr);
-
-       /* Must use *delay family functions in atomic context */
-       udelay(10);
-
-       ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-}
-
-/* Channel lock MUST be held before calling this function! */
-static void cls_flush_uart_read(struct channel_t *ch)
-{
-       if (!ch)
-               return;
-
-       /*
-        * For complete POSIX compatibility, we should be purging the
-        * read FIFO in the UART here.
-        *
-        * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
-        * incorrectly flushes write data as well as just basically trashing the
-        * FIFO.
-        *
-        * Presumably, this is a bug in this UART.
-        */
-
-       udelay(10);
-}
-
-/* Send any/all changes to the line to the UART. */
-static void cls_param(struct tty_struct *tty)
-{
-       unsigned char lcr = 0;
-       unsigned char uart_lcr = 0;
-       unsigned char ier = 0;
-       unsigned char uart_ier = 0;
-       uint baud = 9600;
-       int quot = 0;
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t   *un;
-
-       if (!tty)
-               return;
-
-       un = (struct un_t *)tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       /* If baud rate is zero, flush queues, and set mval to drop DTR. */
-       if ((ch->ch_c_cflag & (CBAUD)) == 0) {
-               ch->ch_r_head = 0;
-               ch->ch_r_tail = 0;
-               ch->ch_e_head = 0;
-               ch->ch_e_tail = 0;
-               ch->ch_w_head = 0;
-               ch->ch_w_tail = 0;
-
-               cls_flush_uart_write(ch);
-               cls_flush_uart_read(ch);
-
-               /* The baudrate is B0 so all modem lines are to be dropped. */
-               ch->ch_flags |= (CH_BAUD0);
-               ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
-               cls_assert_modem_signals(ch);
-               ch->ch_old_baud = 0;
-               return;
-       } else if (ch->ch_custom_speed) {
-               baud = ch->ch_custom_speed;
-               /* Handle transition from B0 */
-               if (ch->ch_flags & CH_BAUD0) {
-                       ch->ch_flags &= ~(CH_BAUD0);
-
-                       /*
-                        * Bring back up RTS and DTR...
-                        * Also handle RTS or DTR toggle if set.
-                        */
-                       if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
-                               ch->ch_mostat |= (UART_MCR_RTS);
-                       if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
-                               ch->ch_mostat |= (UART_MCR_DTR);
-               }
-
-       } else {
-               int iindex = 0;
-               int jindex = 0;
-
-               ulong bauds[4][16] = {
-                       { /* slowbaud */
-                               0,      50,     75,     110,
-                               134,    150,    200,    300,
-                               600,    1200,   1800,   2400,
-                               4800,   9600,   19200,  38400 },
-                       { /* slowbaud & CBAUDEX */
-                               0,      57600,  115200, 230400,
-                               460800, 150,    200,    921600,
-                               600,    1200,   1800,   2400,
-                               4800,   9600,   19200,  38400 },
-                       { /* fastbaud */
-                               0,      57600,   76800, 115200,
-                               131657, 153600, 230400, 460800,
-                               921600, 1200,   1800,   2400,
-                               4800,   9600,   19200,  38400 },
-                       { /* fastbaud & CBAUDEX */
-                               0,      57600,  115200, 230400,
-                               460800, 150,    200,    921600,
-                               600,    1200,   1800,   2400,
-                               4800,   9600,   19200,  38400 }
-               };
-
-               /*
-                * Only use the TXPrint baud rate if the terminal
-                * unit is NOT open
-                */
-               if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
-                   (un->un_type == DGNC_PRINT))
-                       baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
-               else
-                       baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;
-
-               if (ch->ch_c_cflag & CBAUDEX)
-                       iindex = 1;
-
-               if (ch->ch_digi.digi_flags & DIGI_FAST)
-                       iindex += 2;
-
-               jindex = baud;
-
-               if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) &&
-                   (jindex < 16)) {
-                       baud = bauds[iindex][jindex];
-               } else {
-                       baud = 0;
-               }
-
-               if (baud == 0)
-                       baud = 9600;
-
-               /* Handle transition from B0 */
-               if (ch->ch_flags & CH_BAUD0) {
-                       ch->ch_flags &= ~(CH_BAUD0);
-
-                       /*
-                        * Bring back up RTS and DTR...
-                        * Also handle RTS or DTR toggle if set.
-                        */
-                       if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
-                               ch->ch_mostat |= (UART_MCR_RTS);
-                       if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
-                               ch->ch_mostat |= (UART_MCR_DTR);
-               }
-       }
-
-       if (ch->ch_c_cflag & PARENB)
-               lcr |= UART_LCR_PARITY;
-
-       if (!(ch->ch_c_cflag & PARODD))
-               lcr |= UART_LCR_EPAR;
-
-#ifdef CMSPAR
-       if (ch->ch_c_cflag & CMSPAR)
-               lcr |= UART_LCR_SPAR;
-#endif
-
-       if (ch->ch_c_cflag & CSTOPB)
-               lcr |= UART_LCR_STOP;
-
-       switch (ch->ch_c_cflag & CSIZE) {
-       case CS5:
-               lcr |= UART_LCR_WLEN5;
-               break;
-       case CS6:
-               lcr |= UART_LCR_WLEN6;
-               break;
-       case CS7:
-               lcr |= UART_LCR_WLEN7;
-               break;
-       case CS8:
-       default:
-               lcr |= UART_LCR_WLEN8;
-               break;
-       }
-
-       uart_ier = readb(&ch->ch_cls_uart->ier);
-       ier =  uart_ier;
-       uart_lcr = readb(&ch->ch_cls_uart->lcr);
-
-       if (baud == 0)
-               baud = 9600;
-
-       quot = ch->ch_bd->bd_dividend / baud;
-
-       if (quot != 0 && ch->ch_old_baud != baud) {
-               ch->ch_old_baud = baud;
-               writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr);
-               writeb((quot & 0xff), &ch->ch_cls_uart->txrx);
-               writeb((quot >> 8), &ch->ch_cls_uart->ier);
-               writeb(lcr, &ch->ch_cls_uart->lcr);
-       }
-
-       if (uart_lcr != lcr)
-               writeb(lcr, &ch->ch_cls_uart->lcr);
-
-       if (ch->ch_c_cflag & CREAD)
-               ier |= (UART_IER_RDI | UART_IER_RLSI);
-       else
-               ier &= ~(UART_IER_RDI | UART_IER_RLSI);
-
-       /*
-        * Have the UART interrupt on modem signal changes ONLY when
-        * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set.
-        */
-       if ((ch->ch_digi.digi_flags & CTSPACE) ||
-           (ch->ch_digi.digi_flags & RTSPACE) ||
-           (ch->ch_c_cflag & CRTSCTS) ||
-           !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
-           !(ch->ch_c_cflag & CLOCAL))
-               ier |= UART_IER_MSI;
-       else
-               ier &= ~UART_IER_MSI;
-
-       ier |= UART_IER_THRI;
-
-       if (ier != uart_ier)
-               writeb(ier, &ch->ch_cls_uart->ier);
-
-       if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
-               cls_set_cts_flow_control(ch);
-       } else if (ch->ch_c_iflag & IXON) {
-               if ((ch->ch_startc == _POSIX_VDISABLE) ||
-                   (ch->ch_stopc == _POSIX_VDISABLE))
-                       cls_set_no_output_flow_control(ch);
-               else
-                       cls_set_ixon_flow_control(ch);
-       } else {
-               cls_set_no_output_flow_control(ch);
-       }
-
-       if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
-               cls_set_rts_flow_control(ch);
-       } else if (ch->ch_c_iflag & IXOFF) {
-               if ((ch->ch_startc == _POSIX_VDISABLE) ||
-                   (ch->ch_stopc == _POSIX_VDISABLE))
-                       cls_set_no_input_flow_control(ch);
-               else
-                       cls_set_ixoff_flow_control(ch);
-       } else {
-               cls_set_no_input_flow_control(ch);
-       }
-
-       cls_assert_modem_signals(ch);
-
-       cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
-}
-
-/* Board poller function. */
-static void cls_tasklet(unsigned long data)
-{
-       struct dgnc_board *bd = (struct dgnc_board *)data;
-       struct channel_t *ch;
-       unsigned long flags;
-       int i;
-       int state = 0;
-       int ports = 0;
-
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&bd->bd_lock, flags);
-       state = bd->state;
-       ports = bd->nasync;
-       spin_unlock_irqrestore(&bd->bd_lock, flags);
-
-       /*
-        * Do NOT allow the interrupt routine to read the intr registers
-        * Until we release this lock.
-        */
-       spin_lock_irqsave(&bd->bd_intr_lock, flags);
-
-       if ((state == BOARD_READY) && (ports > 0)) {
-               for (i = 0; i < ports; i++) {
-                       ch = bd->channels[i];
-
-                       /*
-                        * NOTE: Remember you CANNOT hold any channel
-                        * locks when calling input.
-                        * During input processing, its possible we
-                        * will call ld, which might do callbacks back
-                        * into us.
-                        */
-                       dgnc_input(ch);
-
-                       /*
-                        * Channel lock is grabbed and then released
-                        * inside this routine.
-                        */
-                       cls_copy_data_from_queue_to_uart(ch);
-                       dgnc_wakeup_writes(ch);
-
-                       dgnc_carrier(ch);
-
-                       /*
-                        * The timing check of turning off the break is done
-                        * inside clear_break()
-                        */
-                       if (ch->ch_stop_sending_break)
-                               cls_clear_break(ch, 0);
-               }
-       }
-
-       spin_unlock_irqrestore(&bd->bd_intr_lock, flags);
-}
-
-/* Classic specific interrupt handler. */
-static irqreturn_t cls_intr(int irq, void *voidbrd)
-{
-       struct dgnc_board *brd = voidbrd;
-       uint i = 0;
-       unsigned char poll_reg;
-       unsigned long flags;
-
-       if (!brd)
-               return IRQ_NONE;
-
-       spin_lock_irqsave(&brd->bd_intr_lock, flags);
-
-       poll_reg = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET);
-       if (!poll_reg) {
-               spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
-               return IRQ_NONE;
-       }
-
-       for (i = 0; i < brd->nasync; i++)
-               cls_parse_isr(brd, i);
-
-       tasklet_schedule(&brd->helper_tasklet);
-
-       spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
-
-       return IRQ_HANDLED;
-}
-
-static void cls_disable_receiver(struct channel_t *ch)
-{
-       unsigned char tmp = readb(&ch->ch_cls_uart->ier);
-
-       tmp &= ~(UART_IER_RDI);
-       writeb(tmp, &ch->ch_cls_uart->ier);
-}
-
-static void cls_enable_receiver(struct channel_t *ch)
-{
-       unsigned char tmp = readb(&ch->ch_cls_uart->ier);
-
-       tmp |= (UART_IER_RDI);
-       writeb(tmp, &ch->ch_cls_uart->ier);
-}
-
-/*
- * This function basically goes to sleep for seconds, or until
- * it gets signalled that the port has fully drained.
- */
-static int cls_drain(struct tty_struct *tty, uint seconds)
-{
-       unsigned long flags;
-       struct channel_t *ch;
-       struct un_t *un;
-
-       if (!tty)
-               return -ENXIO;
-
-       un = (struct un_t *)tty->driver_data;
-       if (!un)
-               return -ENXIO;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -ENXIO;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-       un->un_flags |= UN_EMPTY;
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       /* NOTE: Do something with time passed in. */
-
-       /* If ret is non-zero, user ctrl-c'ed us */
-
-       return wait_event_interruptible(un->un_flags_wait,
-                                        ((un->un_flags & UN_EMPTY) == 0));
-}
-
-static void cls_send_start_character(struct channel_t *ch)
-{
-       if (!ch)
-               return;
-
-       if (ch->ch_startc != _POSIX_VDISABLE) {
-               ch->ch_xon_sends++;
-               writeb(ch->ch_startc, &ch->ch_cls_uart->txrx);
-       }
-}
-
-static void cls_send_stop_character(struct channel_t *ch)
-{
-       if (!ch)
-               return;
-
-       if (ch->ch_stopc != _POSIX_VDISABLE) {
-               ch->ch_xoff_sends++;
-               writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx);
-       }
-}
-
-static void cls_uart_init(struct channel_t *ch)
-{
-       unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
-       unsigned char isr_fcr = 0;
-
-       writeb(0, &ch->ch_cls_uart->ier);
-
-       /*
-        * The Enhanced Register Set may only be accessed when
-        * the Line Control Register is set to 0xBFh.
-        */
-       writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
-
-       isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
-
-       /* Turn on Enhanced/Extended controls */
-       isr_fcr |= (UART_EXAR654_EFR_ECB);
-
-       writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
-
-       /* Write old LCR value back out, which turns enhanced access off */
-       writeb(lcrb, &ch->ch_cls_uart->lcr);
-
-       /* Clear out UART and FIFO */
-       readb(&ch->ch_cls_uart->txrx);
-
-       writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
-              &ch->ch_cls_uart->isr_fcr);
-       usleep_range(10, 20);
-
-       ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-
-       readb(&ch->ch_cls_uart->lsr);
-       readb(&ch->ch_cls_uart->msr);
-}
-
-static void cls_uart_off(struct channel_t *ch)
-{
-       writeb(0, &ch->ch_cls_uart->ier);
-}
-
-/*
- * The channel lock MUST be held by the calling function.
- * Returns 0 is nothing left in the FIFO, returns 1 otherwise.
- */
-static uint cls_get_uart_bytes_left(struct channel_t *ch)
-{
-       unsigned char left = 0;
-       unsigned char lsr = 0;
-
-       if (!ch)
-               return 0;
-
-       lsr = readb(&ch->ch_cls_uart->lsr);
-
-       /* Determine whether the Transmitter is empty or not */
-       if (!(lsr & UART_LSR_TEMT)) {
-               if (ch->ch_flags & CH_TX_FIFO_EMPTY)
-                       tasklet_schedule(&ch->ch_bd->helper_tasklet);
-               left = 1;
-       } else {
-               ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-               left = 0;
-       }
-
-       return left;
-}
-
-/*
- * Starts sending a break thru the UART.
- * The channel lock MUST be held by the calling function.
- */
-static void cls_send_break(struct channel_t *ch, int msecs)
-{
-       if (!ch)
-               return;
-
-       /* If we receive a time of 0, this means turn off the break. */
-       if (msecs == 0) {
-               if (ch->ch_flags & CH_BREAK_SENDING) {
-                       unsigned char temp = readb(&ch->ch_cls_uart->lcr);
-
-                       writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
-                       ch->ch_flags &= ~(CH_BREAK_SENDING);
-                       ch->ch_stop_sending_break = 0;
-               }
-               return;
-       }
-
-       /*
-        * Set the time we should stop sending the break.
-        * If we are already sending a break, toss away the existing
-        * time to stop, and use this new value instead.
-        */
-       ch->ch_stop_sending_break = jiffies + dgnc_jiffies_from_ms(msecs);
-
-       /* Tell the UART to start sending the break */
-       if (!(ch->ch_flags & CH_BREAK_SENDING)) {
-               unsigned char temp = readb(&ch->ch_cls_uart->lcr);
-
-               writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr);
-               ch->ch_flags |= (CH_BREAK_SENDING);
-       }
-}
-
-/*
- * Sends a specific character as soon as possible to the UART,
- * jumping over any bytes that might be in the write queue.
- *
- * The channel lock MUST be held by the calling function.
- */
-static void cls_send_immediate_char(struct channel_t *ch, unsigned char c)
-{
-       if (!ch)
-               return;
-
-       writeb(c, &ch->ch_cls_uart->txrx);
-}
-
-struct board_ops dgnc_cls_ops = {
-       .tasklet =                      cls_tasklet,
-       .intr =                         cls_intr,
-       .uart_init =                    cls_uart_init,
-       .uart_off =                     cls_uart_off,
-       .drain =                        cls_drain,
-       .param =                        cls_param,
-       .assert_modem_signals =         cls_assert_modem_signals,
-       .flush_uart_write =             cls_flush_uart_write,
-       .flush_uart_read =              cls_flush_uart_read,
-       .disable_receiver =             cls_disable_receiver,
-       .enable_receiver =              cls_enable_receiver,
-       .send_break =                   cls_send_break,
-       .send_start_character =         cls_send_start_character,
-       .send_stop_character =          cls_send_stop_character,
-       .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
-       .get_uart_bytes_left =          cls_get_uart_bytes_left,
-       .send_immediate_char =          cls_send_immediate_char
-};
diff --git a/drivers/staging/dgnc/dgnc_cls.h b/drivers/staging/dgnc/dgnc_cls.h
deleted file mode 100644 (file)
index d315085..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#ifndef _DGNC_CLS_H
-#define _DGNC_CLS_H
-
-/**
- * struct cls_uart_struct - Per channel/port Classic UART.
- *
- * key - W = read write
- *     - R = read only
- *     - U = unused
- *
- * @txrx: (WR) Holding Register.
- * @ier: (WR) Interrupt Enable Register.
- * @isr_fcr: (WR) Interrupt Status Register/Fifo Control Register.
- * @lcr: (WR) Line Control Register.
- * @mcr: (WR) Modem Control Register.
- * @lsr: (WR) Line Status Register.
- * @msr: (WR) Modem Status Register.
- * @spr: (WR) Scratch Pad Register.
- */
-struct cls_uart_struct {
-       u8 txrx;
-       u8 ier;
-       u8 isr_fcr;
-       u8 lcr;
-       u8 mcr;
-       u8 lsr;
-       u8 msr;
-       u8 spr;
-};
-
-/* Where to read the interrupt register (8bits) */
-#define        UART_CLASSIC_POLL_ADDR_OFFSET   0x40
-
-#define UART_EXAR654_ENHANCED_REGISTER_SET 0xBF
-
-#define UART_16654_FCR_TXTRIGGER_16    0x10
-#define UART_16654_FCR_RXTRIGGER_16    0x40
-#define UART_16654_FCR_RXTRIGGER_56    0x80
-
-/* Received CTS/RTS change of state */
-#define UART_IIR_CTSRTS                        0x20
-
-/* Receiver data TIMEOUT */
-#define UART_IIR_RDI_TIMEOUT           0x0C
-
-/*
- * These are the EXTENDED definitions for the Exar 654's Interrupt
- * Enable Register.
- */
-#define UART_EXAR654_EFR_ECB      0x10    /* Enhanced control bit */
-#define UART_EXAR654_EFR_IXON     0x2     /* Receiver compares Xon1/Xoff1 */
-#define UART_EXAR654_EFR_IXOFF    0x8     /* Transmit Xon1/Xoff1 */
-#define UART_EXAR654_EFR_RTSDTR   0x40    /* Auto RTS/DTR Flow Control Enable */
-#define UART_EXAR654_EFR_CTSDSR   0x80    /* Auto CTS/DSR Flow Control Enable */
-#define UART_EXAR654_IER_XOFF     0x20    /* Xoff Interrupt Enable */
-#define UART_EXAR654_IER_RTSDTR   0x40    /* Output Interrupt Enable */
-#define UART_EXAR654_IER_CTSDSR   0x80    /* Input Interrupt Enable */
-
-extern struct board_ops dgnc_cls_ops;
-
-#endif /* _DGNC_CLS_H */
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
deleted file mode 100644 (file)
index 5d8c2d9..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include "dgnc_driver.h"
-#include "dgnc_tty.h"
-#include "dgnc_cls.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Digi International, http://www.digi.com");
-MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line");
-MODULE_SUPPORTED_DEVICE("dgnc");
-
-static unsigned int dgnc_num_boards;
-struct dgnc_board              *dgnc_board[MAXBOARDS];
-static DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */
-
-static int             dgnc_poll_tick = 20;    /* Poll interval - 20 ms */
-static ulong           dgnc_poll_time; /* Time of next poll */
-static uint            dgnc_poll_stop; /* Used to tell poller to stop */
-static struct timer_list dgnc_poll_timer;
-
-#define DIGI_VID                               0x114F
-#define PCI_DEVICE_CLASSIC_4_DID               0x0028
-#define PCI_DEVICE_CLASSIC_8_DID               0x0029
-#define PCI_DEVICE_CLASSIC_4_422_DID           0x00D0
-#define PCI_DEVICE_CLASSIC_8_422_DID           0x00D1
-
-#define PCI_DEVICE_CLASSIC_4_PCI_NAME          "ClassicBoard 4 PCI"
-#define PCI_DEVICE_CLASSIC_8_PCI_NAME          "ClassicBoard 8 PCI"
-#define PCI_DEVICE_CLASSIC_4_422_PCI_NAME      "ClassicBoard 4 422 PCI"
-#define PCI_DEVICE_CLASSIC_8_422_PCI_NAME      "ClassicBoard 8 422 PCI"
-
-static const struct pci_device_id dgnc_pci_tbl[] = {
-       {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_DID),     .driver_data = 0},
-       {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID), .driver_data = 1},
-       {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_8_DID),     .driver_data = 2},
-       {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID), .driver_data = 3},
-       {0,}
-};
-MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl);
-
-struct board_id {
-       unsigned char *name;
-       uint maxports;
-       unsigned int is_pci_express;
-};
-
-static const struct board_id dgnc_ids[] = {
-       {       PCI_DEVICE_CLASSIC_4_PCI_NAME,          4,      0       },
-       {       PCI_DEVICE_CLASSIC_4_422_PCI_NAME,      4,      0       },
-       {       PCI_DEVICE_CLASSIC_8_PCI_NAME,          8,      0       },
-       {       PCI_DEVICE_CLASSIC_8_422_PCI_NAME,      8,      0       },
-       {       NULL,                                   0,      0       }
-};
-
-/* Remap PCI memory. */
-static int dgnc_do_remap(struct dgnc_board *brd)
-{
-       brd->re_map_membase = ioremap(brd->membase, 0x1000);
-       if (!brd->re_map_membase)
-               return -ENOMEM;
-
-       return 0;
-}
-
-/* A board has been found, initialize  it. */
-static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id)
-{
-       struct dgnc_board *brd;
-       unsigned int pci_irq;
-       int rc = 0;
-
-       brd = kzalloc(sizeof(*brd), GFP_KERNEL);
-       if (!brd)
-               return ERR_PTR(-ENOMEM);
-
-       /* store the info for the board we've found */
-       brd->boardnum = dgnc_num_boards;
-       brd->device = dgnc_pci_tbl[id].device;
-       brd->pdev = pdev;
-       brd->name = dgnc_ids[id].name;
-       brd->maxports = dgnc_ids[id].maxports;
-       init_waitqueue_head(&brd->state_wait);
-
-       spin_lock_init(&brd->bd_lock);
-       spin_lock_init(&brd->bd_intr_lock);
-
-       brd->state              = BOARD_FOUND;
-
-       pci_irq = pdev->irq;
-       brd->irq = pci_irq;
-
-       switch (brd->device) {
-       case PCI_DEVICE_CLASSIC_4_DID:
-       case PCI_DEVICE_CLASSIC_8_DID:
-       case PCI_DEVICE_CLASSIC_4_422_DID:
-       case PCI_DEVICE_CLASSIC_8_422_DID:
-               /*
-                * For PCI ClassicBoards
-                * PCI Local Address (i.e. "resource" number) space
-                * 0    PLX Memory Mapped Config
-                * 1    PLX I/O Mapped Config
-                * 2    I/O Mapped UARTs and Status
-                * 3    Memory Mapped VPD
-                * 4    Memory Mapped UARTs and Status
-                */
-
-               brd->membase = pci_resource_start(pdev, 4);
-
-               if (!brd->membase) {
-                       dev_err(&brd->pdev->dev,
-                               "Card has no PCI IO resources, failing.\n");
-                       rc = -ENODEV;
-                       goto failed;
-               }
-
-               brd->membase_end = pci_resource_end(pdev, 4);
-
-               if (brd->membase & 1)
-                       brd->membase &= ~3;
-               else
-                       brd->membase &= ~15;
-
-               brd->iobase     = pci_resource_start(pdev, 1);
-               brd->iobase_end = pci_resource_end(pdev, 1);
-               brd->iobase     = ((unsigned int)(brd->iobase)) & 0xFFFE;
-
-               brd->bd_ops = &dgnc_cls_ops;
-
-               brd->bd_uart_offset = 0x8;
-               brd->bd_dividend = 921600;
-
-               rc = dgnc_do_remap(brd);
-               if (rc < 0)
-                       goto failed;
-
-               /*
-                * Enable Local Interrupt 1               (0x1),
-                * Local Interrupt 1 Polarity Active high (0x2),
-                * Enable PCI interrupt                   (0x40)
-                */
-               outb(0x43, brd->iobase + 0x4c);
-
-               break;
-
-       default:
-               dev_err(&brd->pdev->dev,
-                       "Didn't find any compatible Neo/Classic PCI boards.\n");
-               rc = -ENXIO;
-               goto failed;
-       }
-
-       tasklet_init(&brd->helper_tasklet,
-                    brd->bd_ops->tasklet,
-                    (unsigned long)brd);
-
-       wake_up_interruptible(&brd->state_wait);
-
-       return brd;
-
-failed:
-       kfree(brd);
-
-       return ERR_PTR(rc);
-}
-
-static int dgnc_request_irq(struct dgnc_board *brd)
-{
-       if (brd->irq) {
-               int rc = request_irq(brd->irq, brd->bd_ops->intr,
-                                IRQF_SHARED, "DGNC", brd);
-               if (rc) {
-                       dev_err(&brd->pdev->dev,
-                               "Failed to hook IRQ %d\n", brd->irq);
-                       brd->state = BOARD_FAILED;
-                       return -ENODEV;
-               }
-       }
-       return 0;
-}
-
-static void dgnc_free_irq(struct dgnc_board *brd)
-{
-       if (brd->irq)
-               free_irq(brd->irq, brd);
-}
-
- /*
-  * As each timer expires, it determines (a) whether the "transmit"
-  * waiter needs to be woken up, and (b) whether the poller needs to
-  * be rescheduled.
-  */
-static void dgnc_poll_handler(struct timer_list *unused)
-{
-       struct dgnc_board *brd;
-       unsigned long flags;
-       int i;
-       unsigned long new_time;
-
-       for (i = 0; i < dgnc_num_boards; i++) {
-               brd = dgnc_board[i];
-
-               spin_lock_irqsave(&brd->bd_lock, flags);
-
-               if (brd->state == BOARD_FAILED) {
-                       spin_unlock_irqrestore(&brd->bd_lock, flags);
-                       continue;
-               }
-
-               tasklet_schedule(&brd->helper_tasklet);
-
-               spin_unlock_irqrestore(&brd->bd_lock, flags);
-       }
-
-       /* Schedule ourself back at the nominal wakeup interval. */
-
-       spin_lock_irqsave(&dgnc_poll_lock, flags);
-       dgnc_poll_time += dgnc_jiffies_from_ms(dgnc_poll_tick);
-
-       new_time = dgnc_poll_time - jiffies;
-
-       if ((ulong)new_time >= 2 * dgnc_poll_tick)
-               dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick);
-
-       timer_setup(&dgnc_poll_timer, dgnc_poll_handler, 0);
-       dgnc_poll_timer.expires = dgnc_poll_time;
-       spin_unlock_irqrestore(&dgnc_poll_lock, flags);
-
-       if (!dgnc_poll_stop)
-               add_timer(&dgnc_poll_timer);
-}
-
-/* returns count (>= 0), or negative on error */
-static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-       int rc;
-       struct dgnc_board *brd;
-
-       rc = pci_enable_device(pdev);
-       if (rc)
-               return -EIO;
-
-       brd = dgnc_found_board(pdev, ent->driver_data);
-       if (IS_ERR(brd))
-               return PTR_ERR(brd);
-
-       rc = dgnc_tty_register(brd);
-       if (rc < 0) {
-               pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc);
-               goto failed;
-       }
-
-       rc = dgnc_request_irq(brd);
-       if (rc < 0) {
-               pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc);
-               goto unregister_tty;
-       }
-
-       rc = dgnc_tty_init(brd);
-       if (rc < 0) {
-               pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc);
-               goto free_irq;
-       }
-
-       brd->state = BOARD_READY;
-
-       dgnc_board[dgnc_num_boards++] = brd;
-
-       return 0;
-
-free_irq:
-       dgnc_free_irq(brd);
-unregister_tty:
-       dgnc_tty_unregister(brd);
-failed:
-       kfree(brd);
-
-       return rc;
-}
-
-static struct pci_driver dgnc_driver = {
-       .name           = "dgnc",
-       .probe          = dgnc_init_one,
-       .id_table       = dgnc_pci_tbl,
-};
-
-static int dgnc_start(void)
-{
-       unsigned long flags;
-
-       /* Start the poller */
-       spin_lock_irqsave(&dgnc_poll_lock, flags);
-       timer_setup(&dgnc_poll_timer, dgnc_poll_handler, 0);
-       dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick);
-       dgnc_poll_timer.expires = dgnc_poll_time;
-       spin_unlock_irqrestore(&dgnc_poll_lock, flags);
-
-       add_timer(&dgnc_poll_timer);
-
-       return 0;
-}
-
-/* Free all the memory associated with a board */
-static void dgnc_cleanup_board(struct dgnc_board *brd)
-{
-       int i = 0;
-
-       if (!brd)
-               return;
-
-       switch (brd->device) {
-       case PCI_DEVICE_CLASSIC_4_DID:
-       case PCI_DEVICE_CLASSIC_8_DID:
-       case PCI_DEVICE_CLASSIC_4_422_DID:
-       case PCI_DEVICE_CLASSIC_8_422_DID:
-
-               /* Tell card not to interrupt anymore. */
-               outb(0, brd->iobase + 0x4c);
-               break;
-
-       default:
-               break;
-       }
-
-       if (brd->irq)
-               free_irq(brd->irq, brd);
-
-       tasklet_kill(&brd->helper_tasklet);
-
-       if (brd->re_map_membase) {
-               iounmap(brd->re_map_membase);
-               brd->re_map_membase = NULL;
-       }
-
-       for (i = 0; i < MAXPORTS ; i++) {
-               if (brd->channels[i]) {
-                       kfree(brd->channels[i]->ch_rqueue);
-                       kfree(brd->channels[i]->ch_equeue);
-                       kfree(brd->channels[i]->ch_wqueue);
-                       kfree(brd->channels[i]);
-                       brd->channels[i] = NULL;
-               }
-       }
-
-       dgnc_board[brd->boardnum] = NULL;
-
-       kfree(brd);
-}
-
-/* Driver load/unload functions */
-
-static void cleanup(void)
-{
-       int i;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dgnc_poll_lock, flags);
-       dgnc_poll_stop = 1;
-       spin_unlock_irqrestore(&dgnc_poll_lock, flags);
-
-       /* Turn off poller right away. */
-       del_timer_sync(&dgnc_poll_timer);
-
-       for (i = 0; i < dgnc_num_boards; ++i) {
-               dgnc_cleanup_tty(dgnc_board[i]);
-               dgnc_cleanup_board(dgnc_board[i]);
-       }
-}
-
-static void __exit dgnc_cleanup_module(void)
-{
-       cleanup();
-       pci_unregister_driver(&dgnc_driver);
-}
-
-static int __init dgnc_init_module(void)
-{
-       int rc;
-
-       /* Initialize global stuff */
-       rc = dgnc_start();
-       if (rc < 0)
-               return rc;
-
-       /* Find and configure all the cards */
-       rc = pci_register_driver(&dgnc_driver);
-       if (rc) {
-               pr_warn("WARNING: dgnc driver load failed.  No Digi Neo or Classic boards found.\n");
-               cleanup();
-               return rc;
-       }
-       return 0;
-}
-
-module_init(dgnc_init_module);
-module_exit(dgnc_cleanup_module);
diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h
deleted file mode 100644 (file)
index b4d9f71..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *      Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#ifndef _DGNC_DRIVER_H
-#define _DGNC_DRIVER_H
-
-#include <linux/types.h>
-#include <linux/tty.h>
-#include <linux/interrupt.h>
-
-#include "digi.h"              /* Digi specific ioctl header */
-
-/* Driver identification and error statements */
-#define        PROCSTR         "dgnc"                  /* /proc entries */
-#define        DEVSTR          "/dev/dg/dgnc"          /* /dev entries */
-#define        DRVSTR          "dgnc"                  /* Driver name string */
-#define        DG_PART         "40002369_F"            /* RPM part number */
-
-#define TRC_TO_CONSOLE 1
-
-/* Number of boards we support at once. */
-#define        MAXBOARDS       20
-#define        MAXPORTS        8
-#define MAXTTYNAMELEN  200
-
-/* Serial port types */
-#define DGNC_SERIAL            0
-#define DGNC_PRINT             1
-
-#define        SERIAL_TYPE_NORMAL      1
-
-#define PORT_NUM(dev)  ((dev) & 0x7f)
-#define IS_PRINT(dev)  (((dev) & 0xff) >= 0x80)
-
-/* MAX number of stop characters sent when our read queue is getting full */
-#define MAX_STOPS_SENT 5
-
-/* 4 extra for alignment play space */
-#define WRITEBUFLEN            ((4096) + 4)
-
-#define dgnc_jiffies_from_ms(a) (((a) * HZ) / 1000)
-
-#ifndef _POSIX_VDISABLE
-#define   _POSIX_VDISABLE '\0'
-#endif
-
-/* All the possible states the driver can be while being loaded. */
-enum {
-       DRIVER_INITIALIZED = 0,
-       DRIVER_READY
-};
-
-/* All the possible states the board can be while booting up. */
-enum {
-       BOARD_FAILED = 0,
-       BOARD_FOUND,
-       BOARD_READY
-};
-
-struct dgnc_board;
-struct channel_t;
-
-/**
- * struct board_ops - Per board operations.
- */
-struct board_ops {
-       void (*tasklet)(unsigned long data);
-       irqreturn_t (*intr)(int irq, void *voidbrd);
-       void (*uart_init)(struct channel_t *ch);
-       void (*uart_off)(struct channel_t *ch);
-       int  (*drain)(struct tty_struct *tty, uint seconds);
-       void (*param)(struct tty_struct *tty);
-       void (*assert_modem_signals)(struct channel_t *ch);
-       void (*flush_uart_write)(struct channel_t *ch);
-       void (*flush_uart_read)(struct channel_t *ch);
-       void (*disable_receiver)(struct channel_t *ch);
-       void (*enable_receiver)(struct channel_t *ch);
-       void (*send_break)(struct channel_t *ch, int msec);
-       void (*send_start_character)(struct channel_t *ch);
-       void (*send_stop_character)(struct channel_t *ch);
-       void (*copy_data_from_queue_to_uart)(struct channel_t *ch);
-       uint (*get_uart_bytes_left)(struct channel_t *ch);
-       void (*send_immediate_char)(struct channel_t *ch, unsigned char c);
-};
-
-/**
- * struct dgnc_board - Per board information.
- * @boardnum: Board number (0 - 32).
- *
- * @name: Product name.
- * @pdev: Pointer to the pci_dev structure.
- * @device: PCI device ID.
- * @maxports: Maximum ports this board can handle.
- * @bd_lock: Used to protect board.
- * @bd_intr_lock: Protect poller tasklet and interrupt routine from each other.
- * @state: State of the card.
- * @state_wait: Queue to sleep on for state change.
- * @helper_tasklet: Poll helper tasklet.
- * @nasync: Number of ports on card.
- * @irq: Interrupt request number.
- * @membase: Start of base memory of the card.
- * @membase_end: End of base memory of the card.
- * @iobase: Start of IO base of the card.
- * @iobase_end: End of IO base of the card.
- * @bd_uart_offset: Space between each UART.
- * @channels: array of pointers to our channels.
- * @serial_driver: Pointer to the serial driver.
- * @serial_name: Serial driver name.
- * @print_dirver: Pointer to the print driver.
- * @print_name: Print driver name.
- * @bd_dividend: Board/UART's specific dividend.
- * @bd_ops: Pointer to board operations structure.
- */
-struct dgnc_board {
-       int             boardnum;
-       char            *name;
-       struct pci_dev  *pdev;
-       u16             device;
-       uint            maxports;
-
-       /* used to protect the board */
-       spinlock_t      bd_lock;
-
-       /*  Protect poller tasklet and interrupt routine from each other. */
-       spinlock_t      bd_intr_lock;
-
-       uint            state;
-       wait_queue_head_t state_wait;
-
-       struct tasklet_struct helper_tasklet;
-
-       uint            nasync;
-
-       uint            irq;
-
-       ulong           membase;
-       ulong           membase_end;
-
-       u8 __iomem      *re_map_membase;
-
-       ulong           iobase;
-       ulong           iobase_end;
-
-       uint            bd_uart_offset;
-
-       struct channel_t *channels[MAXPORTS];
-
-       struct tty_driver *serial_driver;
-       char            serial_name[200];
-       struct tty_driver *print_driver;
-       char            print_name[200];
-
-       uint            bd_dividend;
-
-       struct board_ops *bd_ops;
-};
-
-/* Unit flag definitions for un_flags. */
-#define UN_ISOPEN      0x0001          /* Device is open */
-#define UN_CLOSING     0x0002          /* Line is being closed */
-#define UN_IMM         0x0004          /* Service immediately */
-#define UN_BUSY                0x0008          /* Some work this channel */
-#define UN_BREAKI      0x0010          /* Input break received */
-#define UN_PWAIT       0x0020          /* Printer waiting for terminal */
-#define UN_TIME                0x0040          /* Waiting on time */
-#define UN_EMPTY       0x0080          /* Waiting output queue empty */
-#define UN_LOW         0x0100          /* Waiting output low water mark*/
-#define UN_EXCL_OPEN   0x0200          /* Open for exclusive use */
-#define UN_WOPEN       0x0400          /* Device waiting for open */
-#define UN_WIOCTL      0x0800          /* Device waiting for open */
-#define UN_HANGUP      0x8000          /* Carrier lost */
-
-struct device;
-
-/**
- * struct un_t - terminal or printer unit
- * @un_open_count: Counter of opens to port.
- * @un_tty: Pointer to unit tty structure.
- * @un_flags: Unit flags.
- * @un_flags_wait: Place to sleep to wait on unit.
- * @un_dev: Minor device number.
- */
-struct un_t {
-       struct  channel_t *un_ch;
-       uint    un_type;
-       uint    un_open_count;
-       struct tty_struct *un_tty;
-       uint    un_flags;
-       wait_queue_head_t un_flags_wait;
-       uint    un_dev;
-       struct device *un_sysfs;
-};
-
-/* Device flag definitions for ch_flags. */
-#define CH_PRON                0x0001          /* Printer on string */
-#define CH_STOP                0x0002          /* Output is stopped */
-#define CH_STOPI       0x0004          /* Input is stopped */
-#define CH_CD          0x0008          /* Carrier is present */
-#define CH_FCAR                0x0010          /* Carrier forced on */
-#define CH_HANGUP       0x0020         /* Hangup received */
-
-#define CH_RECEIVER_OFF        0x0040          /* Receiver is off */
-#define CH_OPENING     0x0080          /* Port in fragile open state */
-#define CH_CLOSING     0x0100          /* Port in fragile close state */
-#define CH_FIFO_ENABLED 0x0200         /* Port has FIFOs enabled */
-#define CH_TX_FIFO_EMPTY 0x0400                /* TX Fifo is completely empty */
-#define CH_TX_FIFO_LWM  0x0800         /* TX Fifo is below Low Water */
-#define CH_BREAK_SENDING 0x1000                /* Break is being sent */
-#define CH_LOOPBACK    0x2000          /* Channel is in lookback mode */
-#define CH_BAUD0       0x08000         /* Used for checking B0 transitions */
-#define CH_FORCED_STOP  0x20000                /* Output is forcibly stopped */
-#define CH_FORCED_STOPI 0x40000                /* Input is forcibly stopped */
-
-/* Our Read/Error/Write queue sizes */
-#define RQUEUEMASK     0x1FFF          /* 8 K - 1 */
-#define EQUEUEMASK     0x1FFF          /* 8 K - 1 */
-#define WQUEUEMASK     0x0FFF          /* 4 K - 1 */
-#define RQUEUESIZE     (RQUEUEMASK + 1)
-#define EQUEUESIZE     RQUEUESIZE
-#define WQUEUESIZE     (WQUEUEMASK + 1)
-
-/**
- * struct channel_t - Channel information.
- * @dgnc_board: Pointer to board structure.
- * @ch_bd: Transparent print structure.
- * @ch_tun: Terminal unit information.
- * @ch_pun: Printer unit information.
- * @ch_lock: Provide for serialization.
- * @ch_flags_wait: Channel flags wait queue.
- * @ch_portnum: Port number, 0 offset.
- * @ch_open_count: Open count.
- * @ch_flags: Channel flags.
- * @ch_close_delay: How long we should drop RTS/DTR for.
- * @ch_cpstime: Time for CPS calculations.
- * @ch_c_iflag: Channel iflags.
- * @ch_c_cflag: Channel cflags.
- * @ch_c_oflag: Channel oflags.
- * @ch_c_lflag: Channel lflags.
- * @ch_stopc: Stop character.
- * @ch_startc: Start character.
- * @ch_old_baud: Cache of the current baud rate.
- * @ch_custom_speed: Custom baud rate, if set.
- * @ch_wopen: Waiting for open process count.
- * @ch_mostat: FEP output modem status.
- * @ch_mistat: FEP input modem status.
- * @ch_cls_uart:  Pointer to the mapped cls UART struct
- * @ch_cached_lsr: Cached value of the LSR register.
- * @ch_rqueue: Read queue buffer, malloc'ed.
- * @ch_r_head: Head location of the read queue.
- * @ch_r_tail: Tail location of the read queue.
- * @ch_equeue: Error queue buffer, malloc'ed.
- * @ch_e_head: Head location of the error queue.
- * @ch_e_tail: Tail location of the error queue.
- * @ch_wqueue: Write queue buffer, malloc'ed.
- * @ch_w_head: Head location of the write queue.
- * @ch_w_tail: Tail location of the write queue.
- * @ch_rxcount: Total of data received so far.
- * @ch_txcount: Total of data transmitted so far.
- * @ch_r_tlevel: Receive trigger level.
- * @ch_t_tlevel: Transmit trigger level.
- * @ch_r_watermark: Receive water mark.
- * @ch_stop_sending_break: Time we should STOP sending a break.
- * @ch_stops_sent: How many times I have send a stop character to try
- *                 to stop the other guy sending.
- * @ch_err_parity: Count of parity
- * @ch_err_frame: Count of framing errors on channel.
- * @ch_err_break: Count of breaks on channel.
- * @ch_err_overrun: Count of overruns on channel.
- * @ch_xon_sends: Count of xons transmitted.
- * @ch_xoff_sends: Count of xoffs transmitted.
- */
-struct channel_t {
-       struct dgnc_board *ch_bd;
-       struct digi_t   ch_digi;
-       struct un_t     ch_tun;
-       struct un_t     ch_pun;
-
-       spinlock_t      ch_lock; /* provide for serialization */
-       wait_queue_head_t ch_flags_wait;
-
-       uint            ch_portnum;
-       uint            ch_open_count;
-       uint            ch_flags;
-
-       ulong           ch_close_delay;
-
-       ulong           ch_cpstime;
-
-       tcflag_t        ch_c_iflag;
-       tcflag_t        ch_c_cflag;
-       tcflag_t        ch_c_oflag;
-       tcflag_t        ch_c_lflag;
-       unsigned char   ch_stopc;
-       unsigned char   ch_startc;
-
-       uint            ch_old_baud;
-       uint            ch_custom_speed;
-
-       uint            ch_wopen;
-
-       unsigned char   ch_mostat;
-       unsigned char   ch_mistat;
-
-       struct cls_uart_struct __iomem *ch_cls_uart;
-
-       unsigned char   ch_cached_lsr;
-
-       unsigned char   *ch_rqueue;
-       ushort          ch_r_head;
-       ushort          ch_r_tail;
-
-       unsigned char   *ch_equeue;
-       ushort          ch_e_head;
-       ushort          ch_e_tail;
-
-       unsigned char   *ch_wqueue;
-       ushort          ch_w_head;
-       ushort          ch_w_tail;
-
-       ulong           ch_rxcount;
-       ulong           ch_txcount;
-
-       unsigned char   ch_r_tlevel;
-       unsigned char   ch_t_tlevel;
-
-       unsigned char   ch_r_watermark;
-
-       ulong           ch_stop_sending_break;
-       uint            ch_stops_sent;
-
-       ulong           ch_err_parity;
-       ulong           ch_err_frame;
-       ulong           ch_err_break;
-       ulong           ch_err_overrun;
-
-       ulong           ch_xon_sends;
-       ulong           ch_xoff_sends;
-};
-
-extern struct dgnc_board *dgnc_board[MAXBOARDS];/* Array of boards */
-
-#endif /* _DGNC_DRIVER_H */
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
deleted file mode 100644 (file)
index b8f8650..0000000
+++ /dev/null
@@ -1,2372 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-/*
- * This file implements the tty driver functionality for the
- * Neo and ClassicBoard PCI based product lines.
- */
-
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>        /* For jiffies, task states, etc. */
-#include <linux/interrupt.h>   /* For tasklet and interrupt structs/defines */
-#include <linux/module.h>
-#include <linux/ctype.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/types.h>
-#include <linux/serial_reg.h>
-#include <linux/slab.h>
-#include <linux/delay.h>       /* For udelay */
-#include <linux/uaccess.h>     /* For copy_from_user/copy_to_user */
-#include <linux/pci.h>
-#include "dgnc_driver.h"
-#include "dgnc_tty.h"
-#include "dgnc_cls.h"
-
-/* Default transparent print information. */
-
-static const struct digi_t dgnc_digi_init = {
-       .digi_flags =   DIGI_COOK,      /* Flags */
-       .digi_maxcps =  100,            /* Max CPS */
-       .digi_maxchar = 50,             /* Max chars in print queue */
-       .digi_bufsize = 100,            /* Printer buffer size */
-       .digi_onlen =   4,              /* size of printer on string */
-       .digi_offlen =  4,              /* size of printer off string */
-       .digi_onstr =   "\033[5i",      /* ANSI printer on string ] */
-       .digi_offstr =  "\033[4i",      /* ANSI printer off string ] */
-       .digi_term =    "ansi"          /* default terminal type */
-};
-
-static int dgnc_tty_open(struct tty_struct *tty, struct file *file);
-static void dgnc_tty_close(struct tty_struct *tty, struct file *file);
-static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file,
-                               struct channel_t *ch);
-static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
-                         unsigned long arg);
-static int dgnc_tty_digigeta(struct tty_struct *tty,
-                            struct digi_t __user *retinfo);
-static int dgnc_tty_digiseta(struct tty_struct *tty,
-                            struct digi_t __user *new_info);
-static int dgnc_tty_write_room(struct tty_struct *tty);
-static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c);
-static int dgnc_tty_chars_in_buffer(struct tty_struct *tty);
-static void dgnc_tty_start(struct tty_struct *tty);
-static void dgnc_tty_stop(struct tty_struct *tty);
-static void dgnc_tty_throttle(struct tty_struct *tty);
-static void dgnc_tty_unthrottle(struct tty_struct *tty);
-static void dgnc_tty_flush_chars(struct tty_struct *tty);
-static void dgnc_tty_flush_buffer(struct tty_struct *tty);
-static void dgnc_tty_hangup(struct tty_struct *tty);
-static int dgnc_tty_tiocmget(struct tty_struct *tty);
-static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set,
-                            unsigned int clear);
-static int dgnc_tty_send_break(struct tty_struct *tty, int msec);
-static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout);
-static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf,
-                         int count);
-static void dgnc_tty_set_termios(struct tty_struct *tty,
-                                struct ktermios *old_termios);
-static void dgnc_tty_send_xchar(struct tty_struct *tty, char ch);
-static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char line);
-static void dgnc_wake_up_unit(struct un_t *unit);
-
-static const struct tty_operations dgnc_tty_ops = {
-       .open = dgnc_tty_open,
-       .close = dgnc_tty_close,
-       .write = dgnc_tty_write,
-       .write_room = dgnc_tty_write_room,
-       .flush_buffer = dgnc_tty_flush_buffer,
-       .chars_in_buffer = dgnc_tty_chars_in_buffer,
-       .flush_chars = dgnc_tty_flush_chars,
-       .ioctl = dgnc_tty_ioctl,
-       .set_termios = dgnc_tty_set_termios,
-       .stop = dgnc_tty_stop,
-       .start = dgnc_tty_start,
-       .throttle = dgnc_tty_throttle,
-       .unthrottle = dgnc_tty_unthrottle,
-       .hangup = dgnc_tty_hangup,
-       .put_char = dgnc_tty_put_char,
-       .tiocmget = dgnc_tty_tiocmget,
-       .tiocmset = dgnc_tty_tiocmset,
-       .break_ctl = dgnc_tty_send_break,
-       .wait_until_sent = dgnc_tty_wait_until_sent,
-       .send_xchar = dgnc_tty_send_xchar
-};
-
-/* TTY Initialization/Cleanup Functions */
-
-static struct tty_driver *dgnc_tty_create(char *serial_name, uint maxports,
-                                         int major, int minor)
-{
-       int rc;
-       struct tty_driver *drv;
-
-       drv = tty_alloc_driver(maxports,
-                              TTY_DRIVER_REAL_RAW |
-                              TTY_DRIVER_DYNAMIC_DEV |
-                              TTY_DRIVER_HARDWARE_BREAK);
-       if (IS_ERR(drv))
-               return drv;
-
-       drv->name = serial_name;
-       drv->name_base = 0;
-       drv->major = major;
-       drv->minor_start = minor;
-       drv->type = TTY_DRIVER_TYPE_SERIAL;
-       drv->subtype = SERIAL_TYPE_NORMAL;
-       drv->init_termios = tty_std_termios;
-       drv->init_termios.c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL);
-       drv->init_termios.c_ispeed = 9600;
-       drv->init_termios.c_ospeed = 9600;
-       drv->driver_name = DRVSTR;
-       /*
-        * Entry points for driver.  Called by the kernel from
-        * tty_io.c and n_tty.c.
-        */
-       tty_set_operations(drv, &dgnc_tty_ops);
-       rc = tty_register_driver(drv);
-       if (rc < 0) {
-               put_tty_driver(drv);
-               return ERR_PTR(rc);
-       }
-       return drv;
-}
-
-static void dgnc_tty_free(struct tty_driver *drv)
-{
-       tty_unregister_driver(drv);
-       put_tty_driver(drv);
-}
-
-/**
- * dgnc_tty_register() - Init the tty subsystem for this board.
- */
-int dgnc_tty_register(struct dgnc_board *brd)
-{
-       int rc;
-
-       snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_",
-                brd->boardnum);
-
-       brd->serial_driver = dgnc_tty_create(brd->serial_name,
-                                            brd->maxports, 0, 0);
-       if (IS_ERR(brd->serial_driver)) {
-               rc = PTR_ERR(brd->serial_driver);
-               dev_dbg(&brd->pdev->dev, "Can't register tty device (%d)\n",
-                       rc);
-               return rc;
-       }
-
-       snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum);
-       brd->print_driver = dgnc_tty_create(brd->print_name, brd->maxports,
-                                           0x80,
-                                           brd->serial_driver->major);
-       if (IS_ERR(brd->print_driver)) {
-               rc = PTR_ERR(brd->print_driver);
-               dev_dbg(&brd->pdev->dev,
-                       "Can't register Transparent Print device(%d)\n", rc);
-               dgnc_tty_free(brd->serial_driver);
-               return rc;
-       }
-       return 0;
-}
-
-void dgnc_tty_unregister(struct dgnc_board *brd)
-{
-       dgnc_tty_free(brd->print_driver);
-       dgnc_tty_free(brd->serial_driver);
-}
-
-/**
- * dgnc_tty_init() - Initialize the tty subsystem.
- *
- * Called once per board after board has been downloaded and initialized.
- */
-int dgnc_tty_init(struct dgnc_board *brd)
-{
-       int i;
-       int rc;
-       void __iomem *vaddr;
-       struct channel_t *ch;
-
-       if (!brd)
-               return -ENXIO;
-
-       /* Initialize board structure elements. */
-
-       vaddr = brd->re_map_membase;
-
-       brd->nasync = brd->maxports;
-
-       for (i = 0; i < brd->nasync; i++) {
-               brd->channels[i] = kzalloc(sizeof(*brd->channels[i]),
-                                          GFP_KERNEL);
-               if (!brd->channels[i]) {
-                       rc = -ENOMEM;
-                       goto err_free_channels;
-               }
-       }
-
-       ch = brd->channels[0];
-       vaddr = brd->re_map_membase;
-
-       /* Set up channel variables */
-       for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {
-               spin_lock_init(&ch->ch_lock);
-
-               ch->ch_tun.un_ch = ch;
-               ch->ch_tun.un_type = DGNC_SERIAL;
-               ch->ch_tun.un_dev = i;
-
-               ch->ch_pun.un_ch = ch;
-               ch->ch_pun.un_type = DGNC_PRINT;
-               ch->ch_pun.un_dev = i + 128;
-
-               ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i);
-
-               ch->ch_bd = brd;
-               ch->ch_portnum = i;
-               ch->ch_digi = dgnc_digi_init;
-
-               /* .25 second delay */
-               ch->ch_close_delay = 250;
-
-               init_waitqueue_head(&ch->ch_flags_wait);
-               init_waitqueue_head(&ch->ch_tun.un_flags_wait);
-               init_waitqueue_head(&ch->ch_pun.un_flags_wait);
-
-               {
-                       struct device *classp;
-
-                       classp = tty_register_device(brd->serial_driver, i,
-                                                    &ch->ch_bd->pdev->dev);
-                       ch->ch_tun.un_sysfs = classp;
-
-                       classp = tty_register_device(brd->print_driver, i,
-                                                    &ch->ch_bd->pdev->dev);
-                       ch->ch_pun.un_sysfs = classp;
-               }
-       }
-
-       return 0;
-
-err_free_channels:
-       for (i = i - 1; i >= 0; --i) {
-               kfree(brd->channels[i]);
-               brd->channels[i] = NULL;
-       }
-
-       return rc;
-}
-
-/**
- * dgnc_cleanup_tty() - Cleanup driver.
- *
- * Uninitialize the TTY portion of this driver.  Free all memory and
- * resources.
- */
-void dgnc_cleanup_tty(struct dgnc_board *brd)
-{
-       int i = 0;
-
-       for (i = 0; i < brd->nasync; i++)
-               tty_unregister_device(brd->serial_driver, i);
-
-       tty_unregister_driver(brd->serial_driver);
-
-       for (i = 0; i < brd->nasync; i++)
-               tty_unregister_device(brd->print_driver, i);
-
-       tty_unregister_driver(brd->print_driver);
-
-       put_tty_driver(brd->serial_driver);
-       put_tty_driver(brd->print_driver);
-}
-
-/**
- * dgnc_wmove() - Write data to transmit queue.
- * @ch: Pointer to channel structure.
- * @buf: Pointer to characters to be moved.
- * @n: Number of characters to move.
- */
-static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
-{
-       int     remain;
-       uint    head;
-
-       if (!ch)
-               return;
-
-       head = ch->ch_w_head & WQUEUEMASK;
-
-       /*
-        * If the write wraps over the top of the circular buffer,
-        * move the portion up to the wrap point, and reset the
-        * pointers to the bottom.
-        */
-       remain = WQUEUESIZE - head;
-
-       if (n >= remain) {
-               n -= remain;
-               memcpy(ch->ch_wqueue + head, buf, remain);
-               head = 0;
-               buf += remain;
-       }
-
-       if (n > 0) {
-               /* Move rest of data. */
-               remain = n;
-               memcpy(ch->ch_wqueue + head, buf, remain);
-               head += remain;
-       }
-
-       head &= WQUEUEMASK;
-       ch->ch_w_head = head;
-}
-
-/**
- * dgnc_input() - Process received data.
- * @ch: Pointer to channel structure.
- */
-void dgnc_input(struct channel_t *ch)
-{
-       struct dgnc_board *bd;
-       struct tty_struct *tp;
-       struct tty_ldisc *ld = NULL;
-       uint    rmask;
-       ushort  head;
-       ushort  tail;
-       int     data_len;
-       unsigned long flags;
-       int flip_len;
-       int len = 0;
-       int n = 0;
-       int s = 0;
-       int i = 0;
-
-       if (!ch)
-               return;
-
-       tp = ch->ch_tun.un_tty;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       rmask = RQUEUEMASK;
-       head = ch->ch_r_head & rmask;
-       tail = ch->ch_r_tail & rmask;
-       data_len = (head - tail) & rmask;
-
-       if (data_len == 0)
-               goto exit_unlock;
-
-       /*
-        * If the device is not open, or CREAD is off,
-        * flush input data and return immediately.
-        */
-       if (!tp ||
-           !(ch->ch_tun.un_flags & UN_ISOPEN) ||
-           !C_CREAD(tp) ||
-           (ch->ch_tun.un_flags & UN_CLOSING)) {
-               ch->ch_r_head = tail;
-
-               /* Force queue flow control to be released, if needed */
-               dgnc_check_queue_flow_control(ch);
-
-               goto exit_unlock;
-       }
-
-       if (ch->ch_flags & CH_FORCED_STOPI)
-               goto exit_unlock;
-
-       flip_len = TTY_FLIPBUF_SIZE;
-
-       len = min(data_len, flip_len);
-       len = min(len, (N_TTY_BUF_SIZE - 1));
-
-       ld = tty_ldisc_ref(tp);
-       if (!ld) {
-               len = 0;
-       } else {
-               if (!ld->ops->receive_buf) {
-                       ch->ch_r_head = ch->ch_r_tail;
-                       len = 0;
-               }
-       }
-
-       if (len <= 0)
-               goto exit_unlock;
-
-       /*
-        * The tty layer in the kernel has changed in 2.6.16+.
-        *
-        * The flip buffers in the tty structure are no longer exposed,
-        * and probably will be going away eventually.
-        *
-        * If we are completely raw, we don't need to go through a lot
-        * of the tty layers that exist.
-        * In this case, we take the shortest and fastest route we
-        * can to relay the data to the user.
-        *
-        * On the other hand, if we are not raw, we need to go through
-        * the new 2.6.16+ tty layer, which has its API more well defined.
-        */
-       len = tty_buffer_request_room(tp->port, len);
-       n = len;
-
-       /*
-        * n now contains the most amount of data we can copy,
-        * bounded either by how much the Linux tty layer can handle,
-        * or the amount of data the card actually has pending...
-        */
-       while (n) {
-               unsigned char *ch_pos = ch->ch_equeue + tail;
-
-               s = ((head >= tail) ? head : RQUEUESIZE) - tail;
-               s = min(s, n);
-
-               if (s <= 0)
-                       break;
-
-               /*
-                * If conditions are such that ld needs to see all
-                * UART errors, we will have to walk each character
-                * and error byte and send them to the buffer one at
-                * a time.
-                */
-               if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
-                       for (i = 0; i < s; i++) {
-                               unsigned char ch = *(ch_pos + i);
-                               char flag = TTY_NORMAL;
-
-                               if (ch & UART_LSR_BI)
-                                       flag = TTY_BREAK;
-                               else if (ch & UART_LSR_PE)
-                                       flag = TTY_PARITY;
-                               else if (ch & UART_LSR_FE)
-                                       flag = TTY_FRAME;
-
-                               tty_insert_flip_char(tp->port, ch, flag);
-                       }
-               } else {
-                       tty_insert_flip_string(tp->port, ch_pos, s);
-               }
-
-               tail += s;
-               n -= s;
-               /* Flip queue if needed */
-               tail &= rmask;
-       }
-
-       ch->ch_r_tail = tail & rmask;
-       ch->ch_e_tail = tail & rmask;
-       dgnc_check_queue_flow_control(ch);
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       /* Tell the tty layer its okay to "eat" the data now */
-       tty_flip_buffer_push(tp->port);
-
-       if (ld)
-               tty_ldisc_deref(ld);
-       return;
-
-exit_unlock:
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-       if (ld)
-               tty_ldisc_deref(ld);
-}
-
-/**
- * dgnc_carrier()
- *
- * Determines when CARRIER changes state and takes appropriate
- * action.
- */
-void dgnc_carrier(struct channel_t *ch)
-{
-       int virt_carrier = 0;
-       int phys_carrier = 0;
-
-       if (!ch)
-               return;
-
-       if (ch->ch_mistat & UART_MSR_DCD)
-               phys_carrier = 1;
-
-       if (ch->ch_digi.digi_flags & DIGI_FORCEDCD)
-               virt_carrier = 1;
-
-       if (ch->ch_c_cflag & CLOCAL)
-               virt_carrier = 1;
-
-       /* Test for a VIRTUAL carrier transition to HIGH. */
-
-       if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
-               /*
-                * When carrier rises, wake any threads waiting
-                * for carrier in the open routine.
-                */
-               if (waitqueue_active(&ch->ch_flags_wait))
-                       wake_up_interruptible(&ch->ch_flags_wait);
-       }
-
-       /* Test for a PHYSICAL carrier transition to HIGH. */
-
-       if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
-               /*
-                * When carrier rises, wake any threads waiting
-                * for carrier in the open routine.
-                */
-               if (waitqueue_active(&ch->ch_flags_wait))
-                       wake_up_interruptible(&ch->ch_flags_wait);
-       }
-
-       /*
-        *  Test for a PHYSICAL transition to low, so long as we aren't
-        *  currently ignoring physical transitions (which is what "virtual
-        *  carrier" indicates).
-        *
-        *  The transition of the virtual carrier to low really doesn't
-        *  matter... it really only means "ignore carrier state", not
-        *  "make pretend that carrier is there".
-        */
-       if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) &&
-           (phys_carrier == 0)) {
-               /*
-                *   When carrier drops:
-                *
-                *   Drop carrier on all open units.
-                *
-                *   Flush queues, waking up any task waiting in the
-                *   line discipline.
-                *
-                *   Send a hangup to the control terminal.
-                *
-                *   Enable all select calls.
-                */
-               if (waitqueue_active(&ch->ch_flags_wait))
-                       wake_up_interruptible(&ch->ch_flags_wait);
-
-               if (ch->ch_tun.un_open_count > 0)
-                       tty_hangup(ch->ch_tun.un_tty);
-
-               if (ch->ch_pun.un_open_count > 0)
-                       tty_hangup(ch->ch_pun.un_tty);
-       }
-
-       /*  Make sure that our cached values reflect the current reality. */
-
-       if (virt_carrier == 1)
-               ch->ch_flags |= CH_FCAR;
-       else
-               ch->ch_flags &= ~CH_FCAR;
-
-       if (phys_carrier == 1)
-               ch->ch_flags |= CH_CD;
-       else
-               ch->ch_flags &= ~CH_CD;
-}
-
-/*  Assign the custom baud rate to the channel structure */
-static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate)
-{
-       int testdiv;
-       int testrate_high;
-       int testrate_low;
-       int deltahigh;
-       int deltalow;
-
-       if (newrate <= 0) {
-               ch->ch_custom_speed = 0;
-               return;
-       }
-
-       /*
-        *  Since the divisor is stored in a 16-bit integer, we make sure
-        *  we don't allow any rates smaller than a 16-bit integer would allow.
-        *  And of course, rates above the dividend won't fly.
-        */
-       if (newrate && newrate < ((ch->ch_bd->bd_dividend / 0xFFFF) + 1))
-               newrate = (ch->ch_bd->bd_dividend / 0xFFFF) + 1;
-
-       if (newrate && newrate > ch->ch_bd->bd_dividend)
-               newrate = ch->ch_bd->bd_dividend;
-
-       if (newrate > 0) {
-               testdiv = ch->ch_bd->bd_dividend / newrate;
-
-               /*
-                *  If we try to figure out what rate the board would use
-                *  with the test divisor, it will be either equal or higher
-                *  than the requested baud rate.  If we then determine the
-                *  rate with a divisor one higher, we will get the next lower
-                *  supported rate below the requested.
-                */
-               testrate_high = ch->ch_bd->bd_dividend / testdiv;
-               testrate_low  = ch->ch_bd->bd_dividend / (testdiv + 1);
-
-               /*
-                *  If the rate for the requested divisor is correct, just
-                *  use it and be done.
-                */
-               if (testrate_high != newrate) {
-                       /*
-                        *  Otherwise, pick the rate that is closer
-                        *  (i.e. whichever rate has a smaller delta).
-                        */
-                       deltahigh = testrate_high - newrate;
-                       deltalow = newrate - testrate_low;
-
-                       if (deltahigh < deltalow)
-                               newrate = testrate_high;
-                       else
-                               newrate = testrate_low;
-               }
-       }
-
-       ch->ch_custom_speed = newrate;
-}
-
-void dgnc_check_queue_flow_control(struct channel_t *ch)
-{
-       int qleft;
-
-       qleft = ch->ch_r_tail - ch->ch_r_head - 1;
-       if (qleft < 0)
-               qleft += RQUEUEMASK + 1;
-
-       /*
-        * Check to see if we should enforce flow control on our queue because
-        * the ld (or user) isn't reading data out of our queue fast enuf.
-        *
-        * NOTE: This is done based on what the current flow control of the
-        * port is set for.
-        *
-        * 1) HWFLOW (RTS) - Turn off the UART's Receive interrupt.
-        *      This will cause the UART's FIFO to back up, and force
-        *      the RTS signal to be dropped.
-        * 2) SWFLOW (IXOFF) - Keep trying to send a stop character to
-        *      the other side, in hopes it will stop sending data to us.
-        * 3) NONE - Nothing we can do.  We will simply drop any extra data
-        *      that gets sent into us when the queue fills up.
-        */
-       if (qleft < 256) {
-               /* HWFLOW */
-               if (ch->ch_digi.digi_flags & CTSPACE ||
-                   ch->ch_c_cflag & CRTSCTS) {
-                       if (!(ch->ch_flags & CH_RECEIVER_OFF)) {
-                               ch->ch_bd->bd_ops->disable_receiver(ch);
-                               ch->ch_flags |= (CH_RECEIVER_OFF);
-                       }
-               }
-               /* SWFLOW */
-               else if (ch->ch_c_iflag & IXOFF) {
-                       if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
-                               ch->ch_bd->bd_ops->send_stop_character(ch);
-                               ch->ch_stops_sent++;
-                       }
-               }
-       }
-
-       /*
-        * Check to see if we should unenforce flow control because
-        * ld (or user) finally read enuf data out of our queue.
-        *
-        * NOTE: This is done based on what the current flow control of the
-        * port is set for.
-        *
-        * 1) HWFLOW (RTS) - Turn back on the UART's Receive interrupt.
-        *      This will cause the UART's FIFO to raise RTS back up,
-        *      which will allow the other side to start sending data again.
-        * 2) SWFLOW (IXOFF) - Send a start character to
-        *      the other side, so it will start sending data to us again.
-        * 3) NONE - Do nothing. Since we didn't do anything to turn off the
-        *      other side, we don't need to do anything now.
-        */
-       if (qleft > (RQUEUESIZE / 2)) {
-               /* HWFLOW */
-               if (ch->ch_digi.digi_flags & RTSPACE ||
-                   ch->ch_c_cflag & CRTSCTS) {
-                       if (ch->ch_flags & CH_RECEIVER_OFF) {
-                               ch->ch_bd->bd_ops->enable_receiver(ch);
-                               ch->ch_flags &= ~(CH_RECEIVER_OFF);
-                       }
-               }
-               /* SWFLOW */
-               else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
-                       ch->ch_stops_sent = 0;
-                       ch->ch_bd->bd_ops->send_start_character(ch);
-               }
-       }
-}
-
-static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char sig)
-{
-       ch->ch_mostat &= ~(sig);
-       ch->ch_bd->bd_ops->assert_modem_signals(ch);
-}
-
-void dgnc_wakeup_writes(struct channel_t *ch)
-{
-       int qlen = 0;
-       unsigned long flags;
-
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       /* If channel now has space, wake up anyone waiting on the condition. */
-
-       qlen = ch->ch_w_head - ch->ch_w_tail;
-       if (qlen < 0)
-               qlen += WQUEUESIZE;
-
-       if (qlen >= (WQUEUESIZE - 256)) {
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return;
-       }
-
-       if (ch->ch_tun.un_flags & UN_ISOPEN) {
-               tty_wakeup(ch->ch_tun.un_tty);
-
-               /*
-                * If unit is set to wait until empty, check to make sure
-                * the queue AND FIFO are both empty.
-                */
-               if (ch->ch_tun.un_flags & UN_EMPTY) {
-                       if ((qlen == 0) &&
-                           (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0)) {
-                               ch->ch_tun.un_flags &= ~(UN_EMPTY);
-
-                               /*
-                                * If RTS Toggle mode is on, whenever
-                                * the queue and UART is empty, keep RTS low.
-                                */
-                               if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
-                                       dgnc_set_signal_low(ch, UART_MCR_RTS);
-
-                               /*
-                                * If DTR Toggle mode is on, whenever
-                                * the queue and UART is empty, keep DTR low.
-                                */
-                               if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
-                                       dgnc_set_signal_low(ch, UART_MCR_DTR);
-                       }
-               }
-
-               wake_up_interruptible(&ch->ch_tun.un_flags_wait);
-       }
-
-       if (ch->ch_pun.un_flags & UN_ISOPEN) {
-               tty_wakeup(ch->ch_pun.un_tty);
-
-               /*
-                * If unit is set to wait until empty, check to make sure
-                * the queue AND FIFO are both empty.
-                */
-               if (ch->ch_pun.un_flags & UN_EMPTY) {
-                       if ((qlen == 0) &&
-                           (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0))
-                               ch->ch_pun.un_flags &= ~(UN_EMPTY);
-               }
-
-               wake_up_interruptible(&ch->ch_pun.un_flags_wait);
-       }
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static struct dgnc_board *find_board_by_major(unsigned int major)
-{
-       int i;
-
-       for (i = 0; i < MAXBOARDS; i++) {
-               struct dgnc_board *brd = dgnc_board[i];
-
-               if (!brd)
-                       return NULL;
-
-               if (major == brd->serial_driver->major ||
-                   major == brd->print_driver->major)
-                       return brd;
-       }
-
-       return NULL;
-}
-
-/* TTY Entry points and helper functions */
-
-static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
-{
-       struct dgnc_board       *brd;
-       struct channel_t *ch;
-       struct un_t     *un;
-       uint            major = 0;
-       uint            minor = 0;
-       int             rc = 0;
-       unsigned long flags;
-
-       rc = 0;
-
-       major = MAJOR(tty_devnum(tty));
-       minor = MINOR(tty_devnum(tty));
-
-       if (major > 255)
-               return -ENXIO;
-
-       brd = find_board_by_major(major);
-       if (!brd)
-               return -ENXIO;
-
-       rc = wait_event_interruptible(brd->state_wait,
-                                     (brd->state & BOARD_READY));
-       if (rc)
-               return rc;
-
-       spin_lock_irqsave(&brd->bd_lock, flags);
-
-       if (PORT_NUM(minor) >= brd->nasync) {
-               rc = -ENXIO;
-               goto err_brd_unlock;
-       }
-
-       ch = brd->channels[PORT_NUM(minor)];
-       if (!ch) {
-               rc = -ENXIO;
-               goto err_brd_unlock;
-       }
-
-       spin_unlock_irqrestore(&brd->bd_lock, flags);
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       /* Figure out our type */
-       if (!IS_PRINT(minor)) {
-               un = &brd->channels[PORT_NUM(minor)]->ch_tun;
-               un->un_type = DGNC_SERIAL;
-       } else if (IS_PRINT(minor)) {
-               un = &brd->channels[PORT_NUM(minor)]->ch_pun;
-               un->un_type = DGNC_PRINT;
-       } else {
-               rc = -ENXIO;
-               goto err_ch_unlock;
-       }
-
-       /*
-        * If the port is still in a previous open, and in a state
-        * where we simply cannot safely keep going, wait until the
-        * state clears.
-        */
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       rc = wait_event_interruptible(ch->ch_flags_wait,
-                                     ((ch->ch_flags & CH_OPENING) == 0));
-       /* If ret is non-zero, user ctrl-c'ed us */
-       if (rc)
-               return -EINTR;
-
-       /*
-        * If either unit is in the middle of the fragile part of close,
-        * we just cannot touch the channel safely.
-        * Go to sleep, knowing that when the channel can be
-        * touched safely, the close routine will signal the
-        * ch_flags_wait to wake us back up.
-        */
-       rc = wait_event_interruptible(ch->ch_flags_wait,
-                                     !((ch->ch_tun.un_flags |
-                                     ch->ch_pun.un_flags) & UN_CLOSING));
-       /* If ret is non-zero, user ctrl-c'ed us */
-       if (rc)
-               return -EINTR;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       tty->driver_data = un;
-
-       /* Initialize tty's */
-
-       if (!(un->un_flags & UN_ISOPEN)) {
-               un->un_tty = tty;
-
-               /* Maybe do something here to the TTY struct as well? */
-       }
-
-       /*
-        * Allocate channel buffers for read/write/error.
-        * Set flag, so we don't get trounced on.
-        */
-       ch->ch_flags |= (CH_OPENING);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       if (!ch->ch_rqueue)
-               ch->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL);
-       if (!ch->ch_equeue)
-               ch->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL);
-       if (!ch->ch_wqueue)
-               ch->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL);
-
-       if (!ch->ch_rqueue || !ch->ch_equeue || !ch->ch_wqueue) {
-               kfree(ch->ch_rqueue);
-               kfree(ch->ch_equeue);
-               kfree(ch->ch_wqueue);
-               return -ENOMEM;
-       }
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_flags &= ~(CH_OPENING);
-       wake_up_interruptible(&ch->ch_flags_wait);
-
-       /* Initialize if neither terminal or printer is open. */
-
-       if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
-               /* Flush input queues. */
-               ch->ch_r_head = 0;
-               ch->ch_r_tail = 0;
-               ch->ch_e_head = 0;
-               ch->ch_e_tail = 0;
-               ch->ch_w_head = 0;
-               ch->ch_w_tail = 0;
-
-               brd->bd_ops->flush_uart_write(ch);
-               brd->bd_ops->flush_uart_read(ch);
-
-               ch->ch_flags = 0;
-               ch->ch_cached_lsr = 0;
-               ch->ch_stop_sending_break = 0;
-               ch->ch_stops_sent = 0;
-
-               ch->ch_c_cflag   = tty->termios.c_cflag;
-               ch->ch_c_iflag   = tty->termios.c_iflag;
-               ch->ch_c_oflag   = tty->termios.c_oflag;
-               ch->ch_c_lflag   = tty->termios.c_lflag;
-               ch->ch_startc = tty->termios.c_cc[VSTART];
-               ch->ch_stopc  = tty->termios.c_cc[VSTOP];
-
-               /*
-                * Bring up RTS and DTR...
-                * Also handle RTS or DTR toggle if set.
-                */
-               if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
-                       ch->ch_mostat |= (UART_MCR_RTS);
-               if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
-                       ch->ch_mostat |= (UART_MCR_DTR);
-
-               /* Tell UART to init itself */
-               brd->bd_ops->uart_init(ch);
-       }
-
-       brd->bd_ops->param(tty);
-
-       dgnc_carrier(ch);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       rc = dgnc_block_til_ready(tty, file, ch);
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-       ch->ch_open_count++;
-       un->un_open_count++;
-       un->un_flags |= (UN_ISOPEN);
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return rc;
-
-err_brd_unlock:
-       spin_unlock_irqrestore(&brd->bd_lock, flags);
-
-       return rc;
-err_ch_unlock:
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return rc;
-}
-
-/* Wait for DCD, if needed. */
-static int dgnc_block_til_ready(struct tty_struct *tty,
-                               struct file *file,
-                               struct channel_t *ch)
-{
-       int rc = 0;
-       struct un_t *un = tty->driver_data;
-       unsigned long flags;
-       uint    old_flags = 0;
-       int     sleep_on_un_flags = 0;
-
-       if (!file)
-               return -ENXIO;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_wopen++;
-
-       while (1) {
-               sleep_on_un_flags = 0;
-
-               if (ch->ch_bd->state == BOARD_FAILED) {
-                       rc = -ENXIO;
-                       break;
-               }
-
-               if (tty_hung_up_p(file)) {
-                       rc = -EAGAIN;
-                       break;
-               }
-
-               /*
-                * If either unit is in the middle of the fragile part of close,
-                * we just cannot touch the channel safely.
-                * Go back to sleep, knowing that when the channel can be
-                * touched safely, the close routine will signal the
-                * ch_wait_flags to wake us back up.
-                */
-               if (!((ch->ch_tun.un_flags |
-                   ch->ch_pun.un_flags) &
-                   UN_CLOSING)) {
-                       /*
-                        * Our conditions to leave cleanly and happily:
-                        * 1) NONBLOCKING on the tty is set.
-                        * 2) CLOCAL is set.
-                        * 3) DCD (fake or real) is active.
-                        */
-
-                       if (file->f_flags & O_NONBLOCK)
-                               break;
-
-                       if (tty_io_error(tty)) {
-                               rc = -EIO;
-                               break;
-                       }
-
-                       if (ch->ch_flags & CH_CD)
-                               break;
-
-                       if (ch->ch_flags & CH_FCAR)
-                               break;
-               } else {
-                       sleep_on_un_flags = 1;
-               }
-
-               /*
-                * If there is a signal pending, the user probably
-                * interrupted (ctrl-c) us.
-                */
-               if (signal_pending(current)) {
-                       rc = -ERESTARTSYS;
-                       break;
-               }
-
-               if (sleep_on_un_flags)
-                       old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
-               else
-                       old_flags = ch->ch_flags;
-
-               /*
-                * Let go of channel lock before calling schedule.
-                * Our poller will get any FEP events and wake us up when DCD
-                * eventually goes active.
-                */
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-               /*
-                * Wait for something in the flags to change
-                * from the current value.
-                */
-               if (sleep_on_un_flags)
-                       rc = wait_event_interruptible
-                               (un->un_flags_wait,
-                                (old_flags != (ch->ch_tun.un_flags |
-                                               ch->ch_pun.un_flags)));
-               else
-                       rc = wait_event_interruptible(
-                                       ch->ch_flags_wait,
-                                       (old_flags != ch->ch_flags));
-
-               /*
-                * We got woken up for some reason.
-                * Before looping around, grab our channel lock.
-                */
-               spin_lock_irqsave(&ch->ch_lock, flags);
-       }
-
-       ch->ch_wopen--;
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return rc;
-}
-
-/* Hangup the port.  Like a close, but don't wait for output to drain. */
-static void dgnc_tty_hangup(struct tty_struct *tty)
-{
-       if (!tty)
-               return;
-
-       /* flush the transmit queues */
-       dgnc_tty_flush_buffer(tty);
-}
-
-static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       /*
-        * Determine if this is the last close or not - and if we agree about
-        * which type of close it is with the Line Discipline
-        */
-       if ((tty->count == 1) && (un->un_open_count != 1)) {
-               /*
-                * Uh, oh.  tty->count is 1, which means that the tty
-                * structure will be freed.  un_open_count should always
-                * be one in these conditions.  If it's greater than
-                * one, we've got real problems, since it means the
-                * serial port won't be shutdown.
-                */
-               dev_dbg(tty->dev,
-                       "tty->count is 1, un open count is %d\n",
-                       un->un_open_count);
-               un->un_open_count = 1;
-       }
-
-       if (un->un_open_count)
-               un->un_open_count--;
-       else
-               dev_dbg(tty->dev,
-                       "bad serial port open count of %d\n",
-                       un->un_open_count);
-
-       ch->ch_open_count--;
-
-       if (ch->ch_open_count && un->un_open_count) {
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return;
-       }
-
-       /* OK, its the last close on the unit */
-       un->un_flags |= UN_CLOSING;
-
-       tty->closing = 1;
-
-       /*
-        * Only officially close channel if count is 0 and
-        * DIGI_PRINTER bit is not set.
-        */
-       if ((ch->ch_open_count == 0) &&
-           !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
-               ch->ch_flags &= ~(CH_STOPI | CH_FORCED_STOPI);
-
-               /* turn off print device when closing print device. */
-
-               if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
-                       dgnc_wmove(ch, ch->ch_digi.digi_offstr,
-                                  (int)ch->ch_digi.digi_offlen);
-                       ch->ch_flags &= ~CH_PRON;
-               }
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               /* wait for output to drain */
-               /* This will also return if we take an interrupt */
-
-               bd->bd_ops->drain(tty, 0);
-
-               dgnc_tty_flush_buffer(tty);
-               tty_ldisc_flush(tty);
-
-               spin_lock_irqsave(&ch->ch_lock, flags);
-
-               tty->closing = 0;
-
-               /* If we have HUPCL set, lower DTR and RTS */
-
-               if (ch->ch_c_cflag & HUPCL) {
-                       /* Drop RTS/DTR */
-                       ch->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS);
-                       bd->bd_ops->assert_modem_signals(ch);
-
-                       /*
-                        * Go to sleep to ensure RTS/DTR
-                        * have been dropped for modems to see it.
-                        */
-                       if (ch->ch_close_delay) {
-                               spin_unlock_irqrestore(&ch->ch_lock,
-                                                      flags);
-                               msleep_interruptible(ch->ch_close_delay);
-                               spin_lock_irqsave(&ch->ch_lock, flags);
-                       }
-               }
-
-               ch->ch_old_baud = 0;
-
-               /* Turn off UART interrupts for this port */
-               ch->ch_bd->bd_ops->uart_off(ch);
-       } else {
-               /* turn off print device when closing print device. */
-
-               if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
-                       dgnc_wmove(ch, ch->ch_digi.digi_offstr,
-                                  (int)ch->ch_digi.digi_offlen);
-                       ch->ch_flags &= ~CH_PRON;
-               }
-       }
-
-       un->un_tty = NULL;
-       un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
-
-       wake_up_interruptible(&ch->ch_flags_wait);
-       wake_up_interruptible(&un->un_flags_wait);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/*
- * Return number of characters that have not been transmitted yet.
- *
- * This routine is used by the line discipline to determine if there
- * is data waiting to be transmitted/drained/flushed or not.
- */
-static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
-{
-       struct channel_t *ch = NULL;
-       struct un_t *un = NULL;
-       ushort thead;
-       ushort ttail;
-       uint tmask;
-       uint chars;
-       unsigned long flags;
-
-       if (!tty)
-               return 0;
-
-       un = tty->driver_data;
-       if (!un)
-               return 0;
-
-       ch = un->un_ch;
-       if (!ch)
-               return 0;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       tmask = WQUEUEMASK;
-       thead = ch->ch_w_head & tmask;
-       ttail = ch->ch_w_tail & tmask;
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       if (ttail == thead)
-               chars = 0;
-       else if (thead > ttail)
-               chars = thead - ttail;
-       else
-               chars = thead - ttail + WQUEUESIZE;
-
-       return chars;
-}
-
-/*
- * Reduces bytes_available to the max number of characters
- * that can be sent currently given the maxcps value, and
- * returns the new bytes_available.  This only affects printer
- * output.
- */
-static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available)
-{
-       int rc = bytes_available;
-
-       if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
-               int cps_limit = 0;
-               unsigned long current_time = jiffies;
-               unsigned long buffer_time = current_time +
-                       (HZ * ch->ch_digi.digi_bufsize) /
-                       ch->ch_digi.digi_maxcps;
-
-               if (ch->ch_cpstime < current_time) {
-                       /* buffer is empty */
-                       ch->ch_cpstime = current_time;  /* reset ch_cpstime */
-                       cps_limit = ch->ch_digi.digi_bufsize;
-               } else if (ch->ch_cpstime < buffer_time) {
-                       /* still room in the buffer */
-                       cps_limit = ((buffer_time - ch->ch_cpstime) *
-                                       ch->ch_digi.digi_maxcps) / HZ;
-               } else {
-                       /* no room in the buffer */
-                       cps_limit = 0;
-               }
-
-               rc = min(cps_limit, bytes_available);
-       }
-
-       return rc;
-}
-
-/* Return room available in Tx buffer */
-static int dgnc_tty_write_room(struct tty_struct *tty)
-{
-       struct channel_t *ch = NULL;
-       struct un_t *un = NULL;
-       ushort head;
-       ushort tail;
-       ushort tmask;
-       int room = 0;
-       unsigned long flags;
-
-       if (!tty)
-               return 0;
-
-       un = tty->driver_data;
-       if (!un)
-               return 0;
-
-       ch = un->un_ch;
-       if (!ch)
-               return 0;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       tmask = WQUEUEMASK;
-       head = (ch->ch_w_head) & tmask;
-       tail = (ch->ch_w_tail) & tmask;
-
-       room = tail - head - 1;
-       if (room < 0)
-               room += WQUEUESIZE;
-
-       /* Limit printer to maxcps */
-       if (un->un_type != DGNC_PRINT)
-               room = dgnc_maxcps_room(ch, room);
-
-       /*
-        * If we are printer device, leave room for
-        * possibly both the on and off strings.
-        */
-       if (un->un_type == DGNC_PRINT) {
-               if (!(ch->ch_flags & CH_PRON))
-                       room -= ch->ch_digi.digi_onlen;
-               room -= ch->ch_digi.digi_offlen;
-       } else {
-               if (ch->ch_flags & CH_PRON)
-                       room -= ch->ch_digi.digi_offlen;
-       }
-
-       if (room < 0)
-               room = 0;
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-       return room;
-}
-
-/*
- * Put a character into ch->ch_buf
- * Used by the line discipline for OPOST processing
- */
-static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c)
-{
-       dgnc_tty_write(tty, &c, 1);
-       return 1;
-}
-
-/*
- * Take data from the user or kernel and send it out to the FEP.
- * In here exists all the Transparent Print magic as well.
- */
-static int dgnc_tty_write(struct tty_struct *tty,
-                         const unsigned char *buf, int count)
-{
-       struct channel_t *ch = NULL;
-       struct un_t *un = NULL;
-       int bufcount = 0, n = 0;
-       unsigned long flags;
-       ushort head;
-       ushort tail;
-       ushort tmask;
-       uint remain;
-
-       if (!tty)
-               return 0;
-
-       un = tty->driver_data;
-       if (!un)
-               return 0;
-
-       ch = un->un_ch;
-       if (!ch)
-               return 0;
-
-       if (!count)
-               return 0;
-
-       /*
-        * Store original amount of characters passed in.
-        * This helps to figure out if we should ask the FEP
-        * to send us an event when it has more space available.
-        */
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       tmask = WQUEUEMASK;
-       head = (ch->ch_w_head) & tmask;
-       tail = (ch->ch_w_tail) & tmask;
-
-       bufcount = tail - head - 1;
-       if (bufcount < 0)
-               bufcount += WQUEUESIZE;
-
-       /*
-        * Limit printer output to maxcps overall, with bursts allowed
-        * up to bufsize characters.
-        */
-       if (un->un_type != DGNC_PRINT)
-               bufcount = dgnc_maxcps_room(ch, bufcount);
-
-       count = min(count, bufcount);
-       if (count <= 0)
-               goto exit_retry;
-
-       /*
-        * Output the printer ON string, if we are in terminal mode, but
-        * need to be in printer mode.
-        */
-       if ((un->un_type == DGNC_PRINT) && !(ch->ch_flags & CH_PRON)) {
-               dgnc_wmove(ch, ch->ch_digi.digi_onstr,
-                          (int)ch->ch_digi.digi_onlen);
-               head = (ch->ch_w_head) & tmask;
-               ch->ch_flags |= CH_PRON;
-       }
-
-       /*
-        * On the other hand, output the printer OFF string, if we are
-        * currently in printer mode, but need to output to the terminal.
-        */
-       if ((un->un_type != DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
-               dgnc_wmove(ch, ch->ch_digi.digi_offstr,
-                          (int)ch->ch_digi.digi_offlen);
-               head = (ch->ch_w_head) & tmask;
-               ch->ch_flags &= ~CH_PRON;
-       }
-
-       n = count;
-
-       /*
-        * If the write wraps over the top of the circular buffer,
-        * move the portion up to the wrap point, and reset the
-        * pointers to the bottom.
-        */
-       remain = WQUEUESIZE - head;
-
-       if (n >= remain) {
-               n -= remain;
-               memcpy(ch->ch_wqueue + head, buf, remain);
-               head = 0;
-               buf += remain;
-       }
-
-       if (n > 0) {
-               /* Move rest of data. */
-               remain = n;
-               memcpy(ch->ch_wqueue + head, buf, remain);
-               head += remain;
-       }
-
-       if (count) {
-               head &= tmask;
-               ch->ch_w_head = head;
-       }
-
-       /* Update printer buffer empty time. */
-       if ((un->un_type == DGNC_PRINT) && (ch->ch_digi.digi_maxcps > 0) &&
-           (ch->ch_digi.digi_bufsize > 0)) {
-               ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
-       }
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       if (count)
-               ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch);
-
-       return count;
-
-exit_retry:
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return 0;
-}
-
-/* Return modem signals to ld. */
-static int dgnc_tty_tiocmget(struct tty_struct *tty)
-{
-       struct channel_t *ch;
-       struct un_t *un;
-       int rc;
-       unsigned char mstat = 0;
-       unsigned long flags;
-
-       if (!tty)
-               return -EIO;
-
-       un = tty->driver_data;
-       if (!un)
-               return -EIO;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -EIO;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       mstat = ch->ch_mostat | ch->ch_mistat;
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       rc = 0;
-
-       if (mstat & UART_MCR_DTR)
-               rc |= TIOCM_DTR;
-       if (mstat & UART_MCR_RTS)
-               rc |= TIOCM_RTS;
-       if (mstat & UART_MSR_CTS)
-               rc |= TIOCM_CTS;
-       if (mstat & UART_MSR_DSR)
-               rc |= TIOCM_DSR;
-       if (mstat & UART_MSR_RI)
-               rc |= TIOCM_RI;
-       if (mstat & UART_MSR_DCD)
-               rc |= TIOCM_CD;
-
-       return rc;
-}
-
-/* Set modem signals, called by ld. */
-static int dgnc_tty_tiocmset(struct tty_struct *tty,
-                            unsigned int set, unsigned int clear)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return -EIO;
-
-       un = tty->driver_data;
-       if (!un)
-               return -EIO;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -EIO;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return -EIO;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       if (set & TIOCM_RTS)
-               ch->ch_mostat |= UART_MCR_RTS;
-
-       if (set & TIOCM_DTR)
-               ch->ch_mostat |= UART_MCR_DTR;
-
-       if (clear & TIOCM_RTS)
-               ch->ch_mostat &= ~(UART_MCR_RTS);
-
-       if (clear & TIOCM_DTR)
-               ch->ch_mostat &= ~(UART_MCR_DTR);
-
-       bd->bd_ops->assert_modem_signals(ch);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return 0;
-}
-
-/* Send a Break, called by ld. */
-static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return -EIO;
-
-       un = tty->driver_data;
-       if (!un)
-               return -EIO;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -EIO;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return -EIO;
-
-       if (msec < 0)
-               msec = 0xFFFF;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       bd->bd_ops->send_break(ch, msec);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return 0;
-}
-
-/* wait until data has been transmitted, called by ld. */
-static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       bd->bd_ops->drain(tty, 0);
-}
-
-/* send a high priority character, called by ld. */
-static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-       bd->bd_ops->send_immediate_char(ch, c);
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Ioctl to get the information for ditty. */
-static int dgnc_tty_digigeta(struct tty_struct *tty,
-                            struct digi_t __user *retinfo)
-{
-       struct channel_t *ch;
-       struct un_t *un;
-       struct digi_t tmp;
-       unsigned long flags;
-
-       if (!retinfo)
-               return -EFAULT;
-
-       if (!tty)
-               return -EFAULT;
-
-       un = tty->driver_data;
-       if (!un)
-               return -EFAULT;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -EFAULT;
-
-       memset(&tmp, 0, sizeof(tmp));
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-       memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-               return -EFAULT;
-
-       return 0;
-}
-
-/* Ioctl to set the information for ditty. */
-static int dgnc_tty_digiseta(struct tty_struct *tty,
-                            struct digi_t __user *new_info)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       struct digi_t new_digi;
-       unsigned long flags;
-
-       if (!tty)
-               return -EFAULT;
-
-       un = tty->driver_data;
-       if (!un)
-               return -EFAULT;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -EFAULT;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return -EFAULT;
-
-       if (copy_from_user(&new_digi, new_info, sizeof(new_digi)))
-               return -EFAULT;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       /* Handle transitions to and from RTS Toggle. */
-
-       if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
-           (new_digi.digi_flags & DIGI_RTS_TOGGLE))
-               ch->ch_mostat &= ~(UART_MCR_RTS);
-       if ((ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
-           !(new_digi.digi_flags & DIGI_RTS_TOGGLE))
-               ch->ch_mostat |= (UART_MCR_RTS);
-
-       /* Handle transitions to and from DTR Toggle. */
-
-       if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
-           (new_digi.digi_flags & DIGI_DTR_TOGGLE))
-               ch->ch_mostat &= ~(UART_MCR_DTR);
-       if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
-           !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
-               ch->ch_mostat |= (UART_MCR_DTR);
-
-       memcpy(&ch->ch_digi, &new_digi, sizeof(new_digi));
-
-       if (ch->ch_digi.digi_maxcps < 1)
-               ch->ch_digi.digi_maxcps = 1;
-
-       if (ch->ch_digi.digi_maxcps > 10000)
-               ch->ch_digi.digi_maxcps = 10000;
-
-       if (ch->ch_digi.digi_bufsize < 10)
-               ch->ch_digi.digi_bufsize = 10;
-
-       if (ch->ch_digi.digi_maxchar < 1)
-               ch->ch_digi.digi_maxchar = 1;
-
-       if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
-               ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
-
-       if (ch->ch_digi.digi_onlen > DIGI_PLEN)
-               ch->ch_digi.digi_onlen = DIGI_PLEN;
-
-       if (ch->ch_digi.digi_offlen > DIGI_PLEN)
-               ch->ch_digi.digi_offlen = DIGI_PLEN;
-
-       bd->bd_ops->param(tty);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return 0;
-}
-
-static void dgnc_tty_set_termios(struct tty_struct *tty,
-                                struct ktermios *old_termios)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_c_cflag   = tty->termios.c_cflag;
-       ch->ch_c_iflag   = tty->termios.c_iflag;
-       ch->ch_c_oflag   = tty->termios.c_oflag;
-       ch->ch_c_lflag   = tty->termios.c_lflag;
-       ch->ch_startc = tty->termios.c_cc[VSTART];
-       ch->ch_stopc  = tty->termios.c_cc[VSTOP];
-
-       bd->bd_ops->param(tty);
-       dgnc_carrier(ch);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void dgnc_tty_throttle(struct tty_struct *tty)
-{
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_flags |= (CH_FORCED_STOPI);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void dgnc_tty_unthrottle(struct tty_struct *tty)
-{
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_flags &= ~(CH_FORCED_STOPI);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void dgnc_tty_start(struct tty_struct *tty)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_flags &= ~(CH_FORCED_STOP);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void dgnc_tty_stop(struct tty_struct *tty)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_flags |= (CH_FORCED_STOP);
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/*
- * Flush the cook buffer
- *
- * Note to self, and any other poor souls who venture here:
- *
- * flush in this case DOES NOT mean dispose of the data.
- * instead, it means "stop buffering and send it if you
- * haven't already."  Just guess how I figured that out...   SRW 2-Jun-98
- *
- * It is also always called in interrupt context - JAR 8-Sept-99
- */
-static void dgnc_tty_flush_chars(struct tty_struct *tty)
-{
-       struct dgnc_board *bd;
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       /* Do something maybe here */
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Flush Tx buffer (make in == out) */
-static void dgnc_tty_flush_buffer(struct tty_struct *tty)
-{
-       struct channel_t *ch;
-       struct un_t *un;
-       unsigned long flags;
-
-       if (!tty)
-               return;
-
-       un = tty->driver_data;
-       if (!un)
-               return;
-
-       ch = un->un_ch;
-       if (!ch)
-               return;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       ch->ch_flags &= ~CH_STOP;
-
-       /* Flush our write queue */
-       ch->ch_w_head = ch->ch_w_tail;
-
-       /* Flush UARTs transmit FIFO */
-       ch->ch_bd->bd_ops->flush_uart_write(ch);
-
-       if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) {
-               ch->ch_tun.un_flags &= ~(UN_LOW | UN_EMPTY);
-               wake_up_interruptible(&ch->ch_tun.un_flags_wait);
-       }
-       if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY)) {
-               ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY);
-               wake_up_interruptible(&ch->ch_pun.un_flags_wait);
-       }
-
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Wakes up processes waiting in the unit's (teminal/printer) wait queue */
-static void dgnc_wake_up_unit(struct un_t *unit)
-{
-       unit->un_flags &= ~(UN_LOW | UN_EMPTY);
-       wake_up_interruptible(&unit->un_flags_wait);
-}
-
-/* The IOCTL function and all of its helpers */
-
-/* The usual assortment of ioctl's */
-static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
-                         unsigned long arg)
-{
-       struct dgnc_board *bd;
-       struct board_ops *ch_bd_ops;
-       struct channel_t *ch;
-       struct un_t *un;
-       int rc;
-       unsigned long flags;
-       void __user *uarg = (void __user *)arg;
-
-       if (!tty)
-               return -ENODEV;
-
-       un = tty->driver_data;
-       if (!un)
-               return -ENODEV;
-
-       ch = un->un_ch;
-       if (!ch)
-               return -ENODEV;
-
-       bd = ch->ch_bd;
-       if (!bd)
-               return -ENODEV;
-
-       ch_bd_ops = bd->bd_ops;
-
-       spin_lock_irqsave(&ch->ch_lock, flags);
-
-       if (un->un_open_count <= 0) {
-               rc = -EIO;
-               goto err_unlock;
-       }
-
-       switch (cmd) {
-               /* Here are any additional ioctl's that we want to implement */
-       case TCFLSH:
-               /*
-                * The linux tty driver doesn't have a flush
-                * input routine for the driver, assuming all backed
-                * up data is in the line disc. buffers.  However,
-                * we all know that's not the case.  Here, we
-                * act on the ioctl, but then lie and say we didn't
-                * so the line discipline will process the flush
-                * also.
-                */
-               rc = tty_check_change(tty);
-               if (rc)
-                       goto err_unlock;
-
-               if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
-                       ch->ch_r_head = ch->ch_r_tail;
-                       ch_bd_ops->flush_uart_read(ch);
-                       /* Force queue flow control to be released, if needed */
-                       dgnc_check_queue_flow_control(ch);
-               }
-
-               if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) {
-                       if (!(un->un_type == DGNC_PRINT)) {
-                               ch->ch_w_head = ch->ch_w_tail;
-                               ch_bd_ops->flush_uart_write(ch);
-
-                               if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY))
-                                       dgnc_wake_up_unit(&ch->ch_tun);
-
-                               if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY))
-                                       dgnc_wake_up_unit(&ch->ch_pun);
-                       }
-               }
-
-               /* pretend we didn't recognize this IOCTL */
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return -ENOIOCTLCMD;
-       case TCSETSF:
-       case TCSETSW:
-               /*
-                * The linux tty driver doesn't have a flush
-                * input routine for the driver, assuming all backed
-                * up data is in the line disc. buffers.  However,
-                * we all know that's not the case.  Here, we
-                * act on the ioctl, but then lie and say we didn't
-                * so the line discipline will process the flush
-                * also.
-                */
-               if (cmd == TCSETSF) {
-                       /* flush rx */
-                       ch->ch_flags &= ~CH_STOP;
-                       ch->ch_r_head = ch->ch_r_tail;
-                       ch_bd_ops->flush_uart_read(ch);
-                       /* Force queue flow control to be released, if needed */
-                       dgnc_check_queue_flow_control(ch);
-               }
-
-               /* now wait for all the output to drain */
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               rc = ch_bd_ops->drain(tty, 0);
-               if (rc)
-                       return -EINTR;
-
-               /* pretend we didn't recognize this */
-               return -ENOIOCTLCMD;
-
-       case TCSETAW:
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               rc = ch_bd_ops->drain(tty, 0);
-               if (rc)
-                       return -EINTR;
-
-               /* pretend we didn't recognize this */
-               return -ENOIOCTLCMD;
-
-       case DIGI_GETA:
-               /* get information for ditty */
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return dgnc_tty_digigeta(tty, uarg);
-
-       case DIGI_SETAW:
-       case DIGI_SETAF:
-
-               /* set information for ditty */
-               if (cmd == (DIGI_SETAW)) {
-                       spin_unlock_irqrestore(&ch->ch_lock, flags);
-                       rc = ch_bd_ops->drain(tty, 0);
-                       if (rc)
-                               return -EINTR;
-
-                       spin_lock_irqsave(&ch->ch_lock, flags);
-               } else {
-                       tty_ldisc_flush(tty);
-               }
-               /* fall thru */
-
-       case DIGI_SETA:
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return dgnc_tty_digiseta(tty, uarg);
-
-       case DIGI_LOOPBACK:
-               {
-                       uint loopback = 0;
-                       /*
-                        * Let go of locks when accessing user space,
-                        * could sleep
-                        */
-                       spin_unlock_irqrestore(&ch->ch_lock, flags);
-                       rc = get_user(loopback, (unsigned int __user *)arg);
-                       if (rc)
-                               return rc;
-                       spin_lock_irqsave(&ch->ch_lock, flags);
-
-                       /* Enable/disable internal loopback for this port */
-                       if (loopback)
-                               ch->ch_flags |= CH_LOOPBACK;
-                       else
-                               ch->ch_flags &= ~(CH_LOOPBACK);
-
-                       ch_bd_ops->param(tty);
-                       spin_unlock_irqrestore(&ch->ch_lock, flags);
-                       return 0;
-               }
-
-       case DIGI_GETCUSTOMBAUD:
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return put_user(ch->ch_custom_speed,
-                               (unsigned int __user *)arg);
-
-       case DIGI_SETCUSTOMBAUD:
-       {
-               int new_rate;
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               rc = get_user(new_rate, (int __user *)arg);
-               if (rc)
-                       return rc;
-               spin_lock_irqsave(&ch->ch_lock, flags);
-               dgnc_set_custom_speed(ch, new_rate);
-               ch_bd_ops->param(tty);
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return 0;
-       }
-
-       /*
-        * This ioctl allows insertion of a character into the front
-        * of any pending data to be transmitted.
-        *
-        * This ioctl is to satisfy the "Send Character Immediate"
-        * call that the RealPort protocol spec requires.
-        */
-       case DIGI_REALPORT_SENDIMMEDIATE:
-       {
-               unsigned char c;
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               rc = get_user(c, (unsigned char __user *)arg);
-               if (rc)
-                       return rc;
-               spin_lock_irqsave(&ch->ch_lock, flags);
-               ch_bd_ops->send_immediate_char(ch, c);
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return 0;
-       }
-
-       /*
-        * This ioctl returns all the current counts for the port.
-        *
-        * This ioctl is to satisfy the "Line Error Counters"
-        * call that the RealPort protocol spec requires.
-        */
-       case DIGI_REALPORT_GETCOUNTERS:
-       {
-               struct digi_getcounter buf;
-
-               buf.norun = ch->ch_err_overrun;
-               buf.noflow = 0;         /* The driver doesn't keep this stat */
-               buf.nframe = ch->ch_err_frame;
-               buf.nparity = ch->ch_err_parity;
-               buf.nbreak = ch->ch_err_break;
-               buf.rbytes = ch->ch_rxcount;
-               buf.tbytes = ch->ch_txcount;
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-               if (copy_to_user(uarg, &buf, sizeof(buf)))
-                       return -EFAULT;
-
-               return 0;
-       }
-
-       /*
-        * This ioctl returns all current events.
-        *
-        * This ioctl is to satisfy the "Event Reporting"
-        * call that the RealPort protocol spec requires.
-        */
-       case DIGI_REALPORT_GETEVENTS:
-       {
-               unsigned int events = 0;
-
-               /* NOTE: MORE EVENTS NEEDS TO BE ADDED HERE */
-               if (ch->ch_flags & CH_BREAK_SENDING)
-                       events |= EV_TXB;
-               if ((ch->ch_flags & CH_STOP) ||
-                   (ch->ch_flags & CH_FORCED_STOP))
-                       events |= (EV_OPU | EV_OPS);
-
-               if ((ch->ch_flags & CH_STOPI) ||
-                   (ch->ch_flags & CH_FORCED_STOPI))
-                       events |= (EV_IPU | EV_IPS);
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-               return put_user(events, (unsigned int __user *)arg);
-       }
-
-       /*
-        * This ioctl returns TOUT and TIN counters based
-        * upon the values passed in by the RealPort Server.
-        * It also passes back whether the UART Transmitter is
-        * empty as well.
-        */
-       case DIGI_REALPORT_GETBUFFERS:
-       {
-               struct digi_getbuffer buf;
-               int tdist;
-               int count;
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-               if (copy_from_user(&buf, uarg, sizeof(buf)))
-                       return -EFAULT;
-
-               spin_lock_irqsave(&ch->ch_lock, flags);
-
-               /* Figure out how much data is in our RX and TX queues. */
-
-               buf.rxbuf = (ch->ch_r_head - ch->ch_r_tail) & RQUEUEMASK;
-               buf.txbuf = (ch->ch_w_head - ch->ch_w_tail) & WQUEUEMASK;
-
-               /*
-                * Is the UART empty?
-                * Add that value to whats in our TX queue.
-                */
-
-               count = buf.txbuf + ch_bd_ops->get_uart_bytes_left(ch);
-
-               /*
-                * Figure out how much data the RealPort Server believes should
-                * be in our TX queue.
-                */
-               tdist = (buf.tx_in - buf.tx_out) & 0xffff;
-
-               /*
-                * If we have more data than the RealPort Server believes we
-                * should have, reduce our count to its amount.
-                *
-                * This count difference CAN happen because the Linux LD can
-                * insert more characters into our queue for OPOST processing
-                * that the RealPort Server doesn't know about.
-                */
-               if (buf.txbuf > tdist)
-                       buf.txbuf = tdist;
-
-               /* Report whether our queue and UART TX are completely empty. */
-
-               if (count)
-                       buf.txdone = 0;
-               else
-                       buf.txdone = 1;
-
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-               if (copy_to_user(uarg, &buf, sizeof(buf)))
-                       return -EFAULT;
-
-               return 0;
-       }
-       default:
-               spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-               return -ENOIOCTLCMD;
-       }
-err_unlock:
-       spin_unlock_irqrestore(&ch->ch_lock, flags);
-
-       return rc;
-}
diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h
deleted file mode 100644 (file)
index 00e3103..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#ifndef _DGNC_TTY_H
-#define _DGNC_TTY_H
-
-#include "dgnc_driver.h"
-
-int    dgnc_tty_register(struct dgnc_board *brd);
-void dgnc_tty_unregister(struct dgnc_board *brd);
-
-int     dgnc_tty_init(struct dgnc_board *brd);
-
-void   dgnc_cleanup_tty(struct dgnc_board *brd);
-
-void   dgnc_input(struct channel_t *ch);
-void   dgnc_carrier(struct channel_t *ch);
-void   dgnc_wakeup_writes(struct channel_t *ch);
-void   dgnc_check_queue_flow_control(struct channel_t *ch);
-
-#endif /* _DGNC_TTY_H */
diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h
deleted file mode 100644 (file)
index b414ee8..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- */
-
-#ifndef _DIGI_H
-#define _DIGI_H
-
-#define DIGI_GETA      (('e' << 8) | 94)       /* Read params */
-#define DIGI_SETA      (('e' << 8) | 95)       /* Set params */
-#define DIGI_SETAW     (('e' << 8) | 96)       /* Drain & set params */
-#define DIGI_SETAF     (('e' << 8) | 97)       /* Drain, flush & set params */
-#define DIGI_LOOPBACK (('d' << 8) | 252)       /* Enable/disable UART
-                                                * internal loopback
-                                                */
-#define DIGI_FAST      0x0002          /* Fast baud rates */
-#define RTSPACE                0x0004          /* RTS input flow control */
-#define CTSPACE                0x0008          /* CTS output flow control */
-#define DIGI_COOK      0x0080          /* Cooked processing done in FEP */
-#define DIGI_FORCEDCD  0x0100          /* Force carrier */
-#define        DIGI_ALTPIN     0x0200          /* Alternate RJ-45 pin config */
-#define        DIGI_PRINTER    0x0800          /* Hold port open for flow cntrl*/
-#define DIGI_DTR_TOGGLE        0x2000          /* Support DTR Toggle */
-#define DIGI_RTS_TOGGLE        0x8000          /* Support RTS Toggle */
-#define DIGI_PLEN      28              /* String length */
-#define        DIGI_TSIZ       10              /* Terminal string len */
-
-/*
- * Structure used with ioctl commands for DIGI parameters.
- */
-/**
- * struct digi_t - Ioctl commands for DIGI parameters.
- * @digi_flags: Flags.
- * @digi_maxcps: Maximum printer CPS.
- * @digi_maxchar: Maximum characters in the print queue.
- * @digi_bufsize: Buffer size.
- * @digi_onlen: Length of ON string.
- * @digi_offlen: Length of OFF string.
- * @digi_onstr: Printer ON string.
- * @digi_offstr: Printer OFF string.
- * @digi_term: Terminal string.
- */
-struct digi_t {
-       unsigned short  digi_flags;
-       unsigned short  digi_maxcps;
-       unsigned short  digi_maxchar;
-       unsigned short  digi_bufsize;
-       unsigned char   digi_onlen;
-       unsigned char   digi_offlen;
-       char            digi_onstr[DIGI_PLEN];
-       char            digi_offstr[DIGI_PLEN];
-       char            digi_term[DIGI_TSIZ];
-};
-
-/**
- * struct digi_getbuffer - Holds buffer use counts.
- */
-struct digi_getbuffer {
-       unsigned long tx_in;
-       unsigned long tx_out;
-       unsigned long rxbuf;
-       unsigned long txbuf;
-       unsigned long txdone;
-};
-
-/**
- * struct digi_getcounter
- * @norun: Number of UART overrun errors.
- * @noflow: Number of buffer overflow errors.
- * @nframe: Number of framing errors.
- * @nparity: Number of parity errors.
- * @nbreak: Number of breaks received.
- * @rbytes: Number of received bytes.
- * @tbytes: Number of transmitted bytes.
- */
-struct digi_getcounter {
-       unsigned long norun;
-       unsigned long noflow;
-       unsigned long nframe;
-       unsigned long nparity;
-       unsigned long nbreak;
-       unsigned long rbytes;
-       unsigned long tbytes;
-};
-
-#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */
-#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */
-
-#define DIGI_REALPORT_GETBUFFERS (('e' << 8) | 108)
-#define DIGI_REALPORT_SENDIMMEDIATE (('e' << 8) | 109)
-#define DIGI_REALPORT_GETCOUNTERS (('e' << 8) | 110)
-#define DIGI_REALPORT_GETEVENTS (('e' << 8) | 111)
-
-#define EV_OPU 0x0001 /* Output paused by client */
-#define EV_OPS 0x0002 /* Output paused by regular sw flowctrl */
-#define EV_IPU 0x0010 /* Input paused unconditionally by user */
-#define EV_IPS 0x0020 /* Input paused by high/low water marks */
-#define EV_TXB 0x0040 /* Transmit break pending */
-
-/**
- * struct ni_info - intelligent <--> non-intelligent DPA translation.
- */
-struct ni_info {
-       int board;
-       int channel;
-       int dtr;
-       int rts;
-       int cts;
-       int dsr;
-       int ri;
-       int dcd;
-       int curtx;
-       int currx;
-       unsigned short iflag;
-       unsigned short oflag;
-       unsigned short cflag;
-       unsigned short lflag;
-       unsigned int mstat;
-       unsigned char hflow;
-       unsigned char xmit_stopped;
-       unsigned char recv_stopped;
-       unsigned int baud;
-};
-
-#define TTY_FLIPBUF_SIZE 512
-
-#endif /* _DIGI_H */
index 3e51476a7045106cad1bbae2133d8a12eae38b1d..65cc3d9af972ff9f4adad74257b75e7627d5e6e7 100644 (file)
@@ -1368,25 +1368,6 @@ static void _nbu2ss_set_endpoint_stall(
        }
 }
 
-/*-------------------------------------------------------------------------*/
-/* Device Descriptor */
-static struct usb_device_descriptor device_desc = {
-       .bLength              = sizeof(device_desc),
-       .bDescriptorType      = USB_DT_DEVICE,
-       .bcdUSB               = cpu_to_le16(0x0200),
-       .bDeviceClass         = USB_CLASS_VENDOR_SPEC,
-       .bDeviceSubClass      = 0x00,
-       .bDeviceProtocol      = 0x00,
-       .bMaxPacketSize0      = 64,
-       .idVendor             = cpu_to_le16(0x0409),
-       .idProduct            = cpu_to_le16(0xfff0),
-       .bcdDevice            = 0xffff,
-       .iManufacturer        = 0x00,
-       .iProduct             = 0x00,
-       .iSerialNumber        = 0x00,
-       .bNumConfigurations   = 0x01,
-};
-
 /*-------------------------------------------------------------------------*/
 static void _nbu2ss_set_test_mode(struct nbu2ss_udc *udc, u32 mode)
 {
@@ -2513,7 +2494,7 @@ static int nbu2ss_ep_enable(
        }
 
        ep = container_of(_ep, struct nbu2ss_ep, ep);
-       if ((!ep) || (!ep->udc)) {
+       if ((!ep->udc)) {
                pr_err(" *** %s, ep == NULL !!\n", __func__);
                return -EINVAL;
        }
@@ -2570,7 +2551,7 @@ static int nbu2ss_ep_disable(struct usb_ep *_ep)
        }
 
        ep = container_of(_ep, struct nbu2ss_ep, ep);
-       if ((!ep) || (!ep->udc)) {
+       if (!ep->udc) {
                pr_err("udc: *** %s, ep == NULL !!\n", __func__);
                return -EINVAL;
        }
@@ -2743,10 +2724,6 @@ static int nbu2ss_ep_dequeue(
        }
 
        ep = container_of(_ep, struct nbu2ss_ep, ep);
-       if (!ep) {
-               pr_err("%s, ep == NULL !!\n", __func__);
-               return -EINVAL;
-       }
 
        udc = ep->udc;
        if (!udc)
@@ -2787,10 +2764,6 @@ static int nbu2ss_ep_set_halt(struct usb_ep *_ep, int value)
        }
 
        ep = container_of(_ep, struct nbu2ss_ep, ep);
-       if (!ep) {
-               pr_err("%s, bad ep\n", __func__);
-               return -EINVAL;
-       }
 
        udc = ep->udc;
        if (!udc) {
@@ -2839,10 +2812,6 @@ static int nbu2ss_ep_fifo_status(struct usb_ep *_ep)
        }
 
        ep = container_of(_ep, struct nbu2ss_ep, ep);
-       if (!ep) {
-               pr_err("%s, bad ep\n", __func__);
-               return -EINVAL;
-       }
 
        udc = ep->udc;
        if (!udc) {
@@ -2885,10 +2854,6 @@ static void  nbu2ss_ep_fifo_flush(struct usb_ep *_ep)
        }
 
        ep = container_of(_ep, struct nbu2ss_ep, ep);
-       if (!ep) {
-               pr_err("udc: %s, bad ep\n", __func__);
-               return;
-       }
 
        udc = ep->udc;
        if (!udc) {
@@ -2959,10 +2924,6 @@ static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget)
        }
 
        udc = container_of(pgadget, struct nbu2ss_udc, gadget);
-       if (!udc) {
-               dev_err(&pgadget->dev, "%s, udc == NULL\n", __func__);
-               return -EINVAL;
-       }
 
        data = gpio_get_value(VBUS_VALUE);
        if (data == 0) {
index 663b755bf2fbf1d5b2afb6a8991d78a8b7bcf799..c8521d71039b7ad213c09b9b60fe854365a1fdb7 100644 (file)
@@ -78,6 +78,15 @@ config EROFS_FAULT_INJECTION
          Test EROFS to inject faults such as ENOMEM, EIO, and so on.
          If unsure, say N.
 
+config EROFS_FS_IO_MAX_RETRIES
+       int "EROFS IO Maximum Retries"
+       depends on EROFS_FS
+       default "5"
+       help
+         Maximum retry count of IO Errors.
+
+         If unsure, leave the default value (5 retries, 6 IOs at most).
+
 config EROFS_FS_ZIP
        bool "EROFS Data Compresssion Support"
        depends on EROFS_FS
index ac263a180253e5aaf5375a8da9b65f0ad8b06c40..6384f73e54189c661e30b08dc1179dde15318471 100644 (file)
@@ -25,7 +25,7 @@ static inline void read_endio(struct bio *bio)
                struct page *page = bvec->bv_page;
 
                /* page is already locked */
-               BUG_ON(PageUptodate(page));
+               DBG_BUGON(PageUptodate(page));
 
                if (unlikely(err))
                        SetPageError(page);
@@ -39,38 +39,50 @@ static inline void read_endio(struct bio *bio)
 }
 
 /* prio -- true is used for dir */
-struct page *erofs_get_meta_page(struct super_block *sb,
-       erofs_blk_t blkaddr, bool prio)
+struct page *__erofs_get_meta_page(struct super_block *sb,
+       erofs_blk_t blkaddr, bool prio, bool nofail)
 {
-       struct inode *bd_inode = sb->s_bdev->bd_inode;
-       struct address_space *mapping = bd_inode->i_mapping;
+       struct inode *const bd_inode = sb->s_bdev->bd_inode;
+       struct address_space *const mapping = bd_inode->i_mapping;
+       /* prefer retrying in the allocator to blindly looping below */
+       const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS) |
+               (nofail ? __GFP_NOFAIL : 0);
+       unsigned int io_retries = nofail ? EROFS_IO_MAX_RETRIES_NOFAIL : 0;
        struct page *page;
+       int err;
 
 repeat:
-       page = find_or_create_page(mapping, blkaddr,
-       /*
-        * Prefer looping in the allocator rather than here,
-        * at least that code knows what it's doing.
-        */
-               mapping_gfp_constraint(mapping, ~__GFP_FS) | __GFP_NOFAIL);
-
-       BUG_ON(!page || !PageLocked(page));
+       page = find_or_create_page(mapping, blkaddr, gfp);
+       if (unlikely(page == NULL)) {
+               DBG_BUGON(nofail);
+               return ERR_PTR(-ENOMEM);
+       }
+       DBG_BUGON(!PageLocked(page));
 
        if (!PageUptodate(page)) {
                struct bio *bio;
-               int err;
 
-               bio = prepare_bio(sb, blkaddr, 1, read_endio);
+               bio = erofs_grab_bio(sb, blkaddr, 1, read_endio, nofail);
+               if (IS_ERR(bio)) {
+                       DBG_BUGON(nofail);
+                       err = PTR_ERR(bio);
+                       goto err_out;
+               }
+
                err = bio_add_page(bio, page, PAGE_SIZE, 0);
-               BUG_ON(err != PAGE_SIZE);
+               if (unlikely(err != PAGE_SIZE)) {
+                       err = -EFAULT;
+                       goto err_out;
+               }
 
                __submit_bio(bio, REQ_OP_READ,
                        REQ_META | (prio ? REQ_PRIO : 0));
 
                lock_page(page);
 
-               /* the page has been truncated by others? */
+               /* this page has been truncated by others */
                if (unlikely(page->mapping != mapping)) {
+unlock_repeat:
                        unlock_page(page);
                        put_page(page);
                        goto repeat;
@@ -78,25 +90,32 @@ repeat:
 
                /* more likely a read error */
                if (unlikely(!PageUptodate(page))) {
-                       unlock_page(page);
-                       put_page(page);
-
-                       page = ERR_PTR(-EIO);
+                       if (io_retries) {
+                               --io_retries;
+                               goto unlock_repeat;
+                       }
+                       err = -EIO;
+                       goto err_out;
                }
        }
        return page;
+
+err_out:
+       unlock_page(page);
+       put_page(page);
+       return ERR_PTR(err);
 }
 
 static int erofs_map_blocks_flatmode(struct inode *inode,
        struct erofs_map_blocks *map,
        int flags)
 {
+       int err = 0;
        erofs_blk_t nblocks, lastblk;
        u64 offset = map->m_la;
        struct erofs_vnode *vi = EROFS_V(inode);
 
        trace_erofs_map_blocks_flatmode_enter(inode, map, flags);
-       BUG_ON(is_inode_layout_compression(inode));
 
        nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
        lastblk = nblocks - is_inode_layout_inline(inode);
@@ -123,18 +142,27 @@ static int erofs_map_blocks_flatmode(struct inode *inode,
                map->m_plen = inode->i_size - offset;
 
                /* inline data should locate in one meta block */
-               BUG_ON(erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE);
+               if (erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE) {
+                       DBG_BUGON(1);
+                       err = -EIO;
+                       goto err_out;
+               }
+
                map->m_flags |= EROFS_MAP_META;
        } else {
                errln("internal error @ nid: %llu (size %llu), m_la 0x%llx",
                        vi->nid, inode->i_size, map->m_la);
-               BUG();
+               DBG_BUGON(1);
+               err = -EIO;
+               goto err_out;
        }
 
 out:
        map->m_llen = map->m_plen;
+
+err_out:
        trace_erofs_map_blocks_flatmode_exit(inode, map, flags, 0);
-       return 0;
+       return err;
 }
 
 #ifdef CONFIG_EROFS_FS_ZIP
@@ -183,14 +211,14 @@ static inline struct bio *erofs_read_raw_page(
        struct address_space *mapping,
        struct page *page,
        erofs_off_t *last_block,
-       unsigned nblocks,
+       unsigned int nblocks,
        bool ra)
 {
        struct inode *inode = mapping->host;
        erofs_off_t current_block = (erofs_off_t)page->index;
        int err;
 
-       BUG_ON(!nblocks);
+       DBG_BUGON(!nblocks);
 
        if (PageUptodate(page)) {
                err = 0;
@@ -217,7 +245,7 @@ submit_bio_retry:
                        .m_la = blknr_to_addr(current_block),
                };
                erofs_blk_t blknr;
-               unsigned blkoff;
+               unsigned int blkoff;
 
                err = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
                if (unlikely(err))
@@ -233,7 +261,7 @@ submit_bio_retry:
                }
 
                /* for RAW access mode, m_plen must be equal to m_llen */
-               BUG_ON(map.m_plen != map.m_llen);
+               DBG_BUGON(map.m_plen != map.m_llen);
 
                blknr = erofs_blknr(map.m_pa);
                blkoff = erofs_blkoff(map.m_pa);
@@ -243,7 +271,7 @@ submit_bio_retry:
                        void *vsrc, *vto;
                        struct page *ipage;
 
-                       BUG_ON(map.m_plen > PAGE_SIZE);
+                       DBG_BUGON(map.m_plen > PAGE_SIZE);
 
                        ipage = erofs_get_meta_page(inode->i_sb, blknr, 0);
 
@@ -270,7 +298,7 @@ submit_bio_retry:
                }
 
                /* pa must be block-aligned for raw reading */
-               BUG_ON(erofs_blkoff(map.m_pa) != 0);
+               DBG_BUGON(erofs_blkoff(map.m_pa));
 
                /* max # of continuous pages */
                if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE))
@@ -278,7 +306,14 @@ submit_bio_retry:
                if (nblocks > BIO_MAX_PAGES)
                        nblocks = BIO_MAX_PAGES;
 
-               bio = prepare_bio(inode->i_sb, blknr, nblocks, read_endio);
+               bio = erofs_grab_bio(inode->i_sb,
+                       blknr, nblocks, read_endio, false);
+
+               if (IS_ERR(bio)) {
+                       err = PTR_ERR(bio);
+                       bio = NULL;
+                       goto err_out;
+               }
        }
 
        err = bio_add_page(bio, page, PAGE_SIZE, 0);
@@ -331,13 +366,13 @@ static int erofs_raw_access_readpage(struct file *file, struct page *page)
        if (IS_ERR(bio))
                return PTR_ERR(bio);
 
-       BUG_ON(bio != NULL);    /* since we have only one bio -- must be NULL */
+       DBG_BUGON(bio); /* since we have only one bio -- must be NULL */
        return 0;
 }
 
 static int erofs_raw_access_readpages(struct file *filp,
        struct address_space *mapping,
-       struct list_head *pages, unsigned nr_pages)
+       struct list_head *pages, unsigned int nr_pages)
 {
        erofs_off_t last_block;
        struct bio *bio = NULL;
@@ -369,7 +404,7 @@ static int erofs_raw_access_readpages(struct file *filp,
                /* pages could still be locked */
                put_page(page);
        }
-       BUG_ON(!list_empty(pages));
+       DBG_BUGON(!list_empty(pages));
 
        /* the rare case (end in gaps) */
        if (unlikely(bio != NULL))
index be6ae3b1bdbe1c8394dae3361d46ec48a4394f19..d1cb0d78ab844b0287f4304234fd2664551be317 100644 (file)
@@ -24,8 +24,8 @@ static const unsigned char erofs_filetype_table[EROFS_FT_MAX] = {
 };
 
 static int erofs_fill_dentries(struct dir_context *ctx,
-       void *dentry_blk, unsigned *ofs,
-       unsigned nameoff, unsigned maxsize)
+       void *dentry_blk, unsigned int *ofs,
+       unsigned int nameoff, unsigned int maxsize)
 {
        struct erofs_dirent *de = dentry_blk;
        const struct erofs_dirent *end = dentry_blk + nameoff;
@@ -36,7 +36,7 @@ static int erofs_fill_dentries(struct dir_context *ctx,
                int de_namelen;
                unsigned char d_type;
 #ifdef CONFIG_EROFS_FS_DEBUG
-               unsigned dbg_namelen;
+               unsigned int dbg_namelen;
                unsigned char dbg_namebuf[EROFS_NAME_LEN];
 #endif
 
@@ -81,15 +81,15 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
        struct inode *dir = file_inode(f);
        struct address_space *mapping = dir->i_mapping;
        const size_t dirsize = i_size_read(dir);
-       unsigned i = ctx->pos / EROFS_BLKSIZ;
-       unsigned ofs = ctx->pos % EROFS_BLKSIZ;
+       unsigned int i = ctx->pos / EROFS_BLKSIZ;
+       unsigned int ofs = ctx->pos % EROFS_BLKSIZ;
        int err = 0;
        bool initial = true;
 
        while (ctx->pos < dirsize) {
                struct page *dentry_page;
                struct erofs_dirent *de;
-               unsigned nameoff, maxsize;
+               unsigned int nameoff, maxsize;
 
                dentry_page = read_mapping_page(mapping, i, NULL);
                if (IS_ERR(dentry_page))
@@ -109,7 +109,8 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
                        goto skip_this;
                }
 
-               maxsize = min_t(unsigned, dirsize - ctx->pos + ofs, PAGE_SIZE);
+               maxsize = min_t(unsigned int,
+                               dirsize - ctx->pos + ofs, PAGE_SIZE);
 
                /* search dirents at the arbitrary position */
                if (unlikely(initial)) {
index 2f8e2bf70941dcf32badc5fb54bced880116108b..d4bffa2852b392f8396ce53eaa7255859c541f6f 100644 (file)
@@ -202,6 +202,14 @@ struct erofs_extent_header {
  *        di_u.delta[1] = distance to its corresponding tail cluster
  *                (di_advise could be 0, 1 or 2)
  */
+enum {
+       Z_EROFS_VLE_CLUSTER_TYPE_PLAIN,
+       Z_EROFS_VLE_CLUSTER_TYPE_HEAD,
+       Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD,
+       Z_EROFS_VLE_CLUSTER_TYPE_RESERVED,
+       Z_EROFS_VLE_CLUSTER_TYPE_MAX
+};
+
 #define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS        2
 #define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT         0
 
@@ -260,6 +268,9 @@ static inline void erofs_check_ondisk_layout_definitions(void)
        BUILD_BUG_ON(sizeof(struct erofs_extent_header) != 16);
        BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8);
        BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12);
+
+       BUILD_BUG_ON(BIT(Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) <
+                    Z_EROFS_VLE_CLUSTER_TYPE_MAX - 1);
 }
 
 #endif
index 5aead93a762f1756c1a9d3da41973a3e1f5cd8cd..660c92fc1803e2342f0384b10998080f231db2b3 100644 (file)
@@ -162,7 +162,8 @@ DECLARE_EVENT_CLASS(erofs__map_blocks_enter,
 
        TP_printk("dev = (%d,%d), nid = %llu, la %llu llen %llu flags %s",
                  show_dev_nid(__entry),
-                 __entry->la, __entry->llen, show_map_flags(__entry->flags))
+                 __entry->la, __entry->llen,
+                 __entry->flags ? show_map_flags(__entry->flags) : "NULL")
 );
 
 DEFINE_EVENT(erofs__map_blocks_enter, erofs_map_blocks_flatmode_enter,
@@ -172,6 +173,13 @@ DEFINE_EVENT(erofs__map_blocks_enter, erofs_map_blocks_flatmode_enter,
        TP_ARGS(inode, map, flags)
 );
 
+DEFINE_EVENT(erofs__map_blocks_enter, z_erofs_map_blocks_iter_enter,
+       TP_PROTO(struct inode *inode, struct erofs_map_blocks *map,
+                unsigned int flags),
+
+       TP_ARGS(inode, map, flags)
+);
+
 DECLARE_EVENT_CLASS(erofs__map_blocks_exit,
        TP_PROTO(struct inode *inode, struct erofs_map_blocks *map,
                 unsigned int flags, int ret),
@@ -204,7 +212,8 @@ DECLARE_EVENT_CLASS(erofs__map_blocks_exit,
 
        TP_printk("dev = (%d,%d), nid = %llu, flags %s "
                  "la %llu pa %llu llen %llu plen %llu mflags %s ret %d",
-                 show_dev_nid(__entry), show_map_flags(__entry->flags),
+                 show_dev_nid(__entry),
+                 __entry->flags ? show_map_flags(__entry->flags) : "NULL",
                  __entry->la, __entry->pa, __entry->llen, __entry->plen,
                  show_mflags(__entry->mflags), __entry->ret)
 );
@@ -216,6 +225,13 @@ DEFINE_EVENT(erofs__map_blocks_exit, erofs_map_blocks_flatmode_exit,
        TP_ARGS(inode, map, flags, ret)
 );
 
+DEFINE_EVENT(erofs__map_blocks_exit, z_erofs_map_blocks_iter_exit,
+       TP_PROTO(struct inode *inode, struct erofs_map_blocks *map,
+                unsigned int flags, int ret),
+
+       TP_ARGS(inode, map, flags, ret)
+);
+
 TRACE_EVENT(erofs_destroy_inode,
        TP_PROTO(struct inode *inode),
 
index fbf6ff25cd1bde7517bcde93042c0b7ec21e09fc..04c61a9d7b76692c3d63ac12822ca0ea78e48707 100644 (file)
@@ -19,7 +19,7 @@ static int read_inode(struct inode *inode, void *data)
 {
        struct erofs_vnode *vi = EROFS_V(inode);
        struct erofs_inode_v1 *v1 = data;
-       const unsigned advise = le16_to_cpu(v1->i_advise);
+       const unsigned int advise = le16_to_cpu(v1->i_advise);
 
        vi->data_mapping_mode = __inode_data_mapping(advise);
 
@@ -112,7 +112,8 @@ static int read_inode(struct inode *inode, void *data)
  * try_lock since it takes no much overhead and
  * will success immediately.
  */
-static int fill_inline_data(struct inode *inode, void *data, unsigned m_pofs)
+static int fill_inline_data(struct inode *inode, void *data,
+                           unsigned int m_pofs)
 {
        struct erofs_vnode *vi = EROFS_V(inode);
        struct erofs_sb_info *sbi = EROFS_I_SB(inode);
@@ -152,7 +153,7 @@ static int fill_inode(struct inode *inode, int isdir)
        void *data;
        int err;
        erofs_blk_t blkaddr;
-       unsigned ofs;
+       unsigned int ofs;
 
        trace_erofs_fill_inode(inode, isdir);
 
@@ -231,10 +232,45 @@ out_unlock:
        return err;
 }
 
+/*
+ * erofs nid is 64bits, but i_ino is 'unsigned long', therefore
+ * we should do more for 32-bit platform to find the right inode.
+ */
+#if BITS_PER_LONG == 32
+static int erofs_ilookup_test_actor(struct inode *inode, void *opaque)
+{
+       const erofs_nid_t nid = *(erofs_nid_t *)opaque;
+
+       return EROFS_V(inode)->nid == nid;
+}
+
+static int erofs_iget_set_actor(struct inode *inode, void *opaque)
+{
+       const erofs_nid_t nid = *(erofs_nid_t *)opaque;
+
+       inode->i_ino = erofs_inode_hash(nid);
+       return 0;
+}
+#endif
+
+static inline struct inode *erofs_iget_locked(struct super_block *sb,
+                                             erofs_nid_t nid)
+{
+       const unsigned long hashval = erofs_inode_hash(nid);
+
+#if BITS_PER_LONG >= 64
+       /* it is safe to use iget_locked for >= 64-bit platform */
+       return iget_locked(sb, hashval);
+#else
+       return iget5_locked(sb, hashval, erofs_ilookup_test_actor,
+               erofs_iget_set_actor, &nid);
+#endif
+}
+
 struct inode *erofs_iget(struct super_block *sb,
        erofs_nid_t nid, bool isdir)
 {
-       struct inode *inode = iget_locked(sb, nid);
+       struct inode *inode = erofs_iget_locked(sb, nid);
 
        if (unlikely(inode == NULL))
                return ERR_PTR(-ENOMEM);
@@ -259,22 +295,16 @@ struct inode *erofs_iget(struct super_block *sb,
 const struct inode_operations erofs_generic_xattr_iops = {
        .listxattr = erofs_listxattr,
 };
-#endif
 
-#ifdef CONFIG_EROFS_FS_XATTR
 const struct inode_operations erofs_symlink_xattr_iops = {
        .get_link = page_get_link,
        .listxattr = erofs_listxattr,
 };
-#endif
 
 const struct inode_operations erofs_special_inode_operations = {
-#ifdef CONFIG_EROFS_FS_XATTR
        .listxattr = erofs_listxattr,
-#endif
 };
 
-#ifdef CONFIG_EROFS_FS_XATTR
 const struct inode_operations erofs_fast_symlink_xattr_iops = {
        .get_link = simple_get_link,
        .listxattr = erofs_listxattr,
index 367b39fe46e523ef8da89e083e147cf6f31aa63b..57575c7f56355424a88355297a5d2ed566d1c59f 100644 (file)
 #define DBG_BUGON(...)          ((void)0)
 #endif
 
-#ifdef CONFIG_EROFS_FAULT_INJECTION
 enum {
        FAULT_KMALLOC,
        FAULT_MAX,
 };
 
+#ifdef CONFIG_EROFS_FAULT_INJECTION
 extern char *erofs_fault_name[FAULT_MAX];
 #define IS_FAULT_SET(fi, type) ((fi)->inject_type & (1 << (type)))
 
@@ -95,6 +95,9 @@ struct erofs_sb_info {
        /* the dedicated workstation for compression */
        struct radix_tree_root workstn_tree;
 
+       /* threshold for decompression synchronously */
+       unsigned int max_sync_decompress_pages;
+
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
        struct inode *managed_cache;
 #endif
@@ -143,17 +146,24 @@ static inline bool time_to_inject(struct erofs_sb_info *sbi, int type)
        }
        return false;
 }
+#else
+static inline bool time_to_inject(struct erofs_sb_info *sbi, int type)
+{
+       return false;
+}
+
+static inline void erofs_show_injection_info(int type)
+{
+}
 #endif
 
 static inline void *erofs_kmalloc(struct erofs_sb_info *sbi,
                                        size_t size, gfp_t flags)
 {
-#ifdef CONFIG_EROFS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_KMALLOC)) {
                erofs_show_injection_info(FAULT_KMALLOC);
                return NULL;
        }
-#endif
        return kmalloc(size, flags);
 }
 
@@ -266,6 +276,20 @@ extern int erofs_try_to_free_cached_page(struct address_space *mapping,
        struct page *page);
 #endif
 
+#define DEFAULT_MAX_SYNC_DECOMPRESS_PAGES      3
+
+static inline bool __should_decompress_synchronously(struct erofs_sb_info *sbi,
+                                                    unsigned int nr)
+{
+       return nr <= sbi->max_sync_decompress_pages;
+}
+
+int __init z_erofs_init_zip_subsystem(void);
+void z_erofs_exit_zip_subsystem(void);
+#else
+/* dummy initializer/finalizer for the decompression subsystem */
+static inline int z_erofs_init_zip_subsystem(void) { return 0; }
+static inline void z_erofs_exit_zip_subsystem(void) {}
 #endif
 
 /* we strictly follow PAGE_SIZE and no buffer head yet */
@@ -420,30 +444,30 @@ struct erofs_map_blocks {
 #define EROFS_GET_BLOCKS_RAW    0x0001
 
 /* data.c */
-static inline struct bio *prepare_bio(
-       struct super_block *sb,
-       erofs_blk_t blkaddr, unsigned nr_pages,
-       bio_end_io_t endio)
+static inline struct bio *
+erofs_grab_bio(struct super_block *sb,
+              erofs_blk_t blkaddr, unsigned int nr_pages,
+              bio_end_io_t endio, bool nofail)
 {
-       gfp_t gfp = GFP_NOIO;
-       struct bio *bio = bio_alloc(gfp, nr_pages);
-
-       if (unlikely(bio == NULL) &&
-               (current->flags & PF_MEMALLOC)) {
-               do {
-                       nr_pages /= 2;
-                       if (unlikely(!nr_pages)) {
-                               bio = bio_alloc(gfp | __GFP_NOFAIL, 1);
-                               BUG_ON(bio == NULL);
-                               break;
+       const gfp_t gfp = GFP_NOIO;
+       struct bio *bio;
+
+       do {
+               if (nr_pages == 1) {
+                       bio = bio_alloc(gfp | (nofail ? __GFP_NOFAIL : 0), 1);
+                       if (unlikely(bio == NULL)) {
+                               DBG_BUGON(nofail);
+                               return ERR_PTR(-ENOMEM);
                        }
-                       bio = bio_alloc(gfp, nr_pages);
-               } while (bio == NULL);
-       }
+                       break;
+               }
+               bio = bio_alloc(gfp, nr_pages);
+               nr_pages /= 2;
+       } while (unlikely(bio == NULL));
 
        bio->bi_end_io = endio;
        bio_set_dev(bio, sb->s_bdev);
-       bio->bi_iter.bi_sector = blkaddr << LOG_SECTORS_PER_BLOCK;
+       bio->bi_iter.bi_sector = (sector_t)blkaddr << LOG_SECTORS_PER_BLOCK;
        return bio;
 }
 
@@ -453,8 +477,27 @@ static inline void __submit_bio(struct bio *bio, unsigned op, unsigned op_flags)
        submit_bio(bio);
 }
 
-extern struct page *erofs_get_meta_page(struct super_block *sb,
-       erofs_blk_t blkaddr, bool prio);
+#ifndef CONFIG_EROFS_FS_IO_MAX_RETRIES
+#define EROFS_IO_MAX_RETRIES_NOFAIL    0
+#else
+#define EROFS_IO_MAX_RETRIES_NOFAIL    CONFIG_EROFS_FS_IO_MAX_RETRIES
+#endif
+
+extern struct page *__erofs_get_meta_page(struct super_block *sb,
+       erofs_blk_t blkaddr, bool prio, bool nofail);
+
+static inline struct page *erofs_get_meta_page(struct super_block *sb,
+       erofs_blk_t blkaddr, bool prio)
+{
+       return __erofs_get_meta_page(sb, blkaddr, prio, false);
+}
+
+static inline struct page *erofs_get_meta_page_nofail(struct super_block *sb,
+       erofs_blk_t blkaddr, bool prio)
+{
+       return __erofs_get_meta_page(sb, blkaddr, prio, true);
+}
+
 extern int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int);
 extern int erofs_map_blocks_iter(struct inode *, struct erofs_map_blocks *,
        struct page **, int);
@@ -465,14 +508,24 @@ struct erofs_map_blocks_iter {
 };
 
 
-static inline struct page *erofs_get_inline_page(struct inode *inode,
-       erofs_blk_t blkaddr)
+static inline struct page *
+erofs_get_inline_page(struct inode *inode,
+                     erofs_blk_t blkaddr)
 {
        return erofs_get_meta_page(inode->i_sb,
                blkaddr, S_ISDIR(inode->i_mode));
 }
 
 /* inode.c */
+static inline unsigned long erofs_inode_hash(erofs_nid_t nid)
+{
+#if BITS_PER_LONG == 32
+       return (nid >> 32) ^ (nid & 0xffffffff);
+#else
+       return nid;
+#endif
+}
+
 extern struct inode *erofs_iget(struct super_block *sb,
        erofs_nid_t nid, bool dir);
 
@@ -480,13 +533,11 @@ extern struct inode *erofs_iget(struct super_block *sb,
 int erofs_namei(struct inode *dir, struct qstr *name,
        erofs_nid_t *nid, unsigned *d_type);
 
-/* xattr.c */
 #ifdef CONFIG_EROFS_FS_XATTR
+/* xattr.c */
 extern const struct xattr_handler *erofs_xattr_handlers[];
-#endif
 
-/* symlink */
-#ifdef CONFIG_EROFS_FS_XATTR
+/* symlink and special inode */
 extern const struct inode_operations erofs_symlink_xattr_iops;
 extern const struct inode_operations erofs_fast_symlink_xattr_iops;
 extern const struct inode_operations erofs_special_inode_operations;
index 8cf0617d4ea01108c961c6fd3099d7752fdc4c31..5596c52e246df01ee93ded7beb006f36c6f22537 100644 (file)
@@ -17,9 +17,9 @@
 
 /* based on the value of qn->len is accurate */
 static inline int dirnamecmp(struct qstr *qn,
-       struct qstr *qd, unsigned *matched)
+       struct qstr *qd, unsigned int *matched)
 {
-       unsigned i = *matched, len = min(qn->len, qd->len);
+       unsigned int i = *matched, len = min(qn->len, qd->len);
 loop:
        if (unlikely(i >= len)) {
                *matched = i;
@@ -46,8 +46,8 @@ static struct erofs_dirent *find_target_dirent(
        struct qstr *name,
        u8 *data, int maxsize)
 {
-       unsigned ndirents, head, back;
-       unsigned startprfx, endprfx;
+       unsigned int ndirents, head, back;
+       unsigned int startprfx, endprfx;
        struct erofs_dirent *const de = (struct erofs_dirent *)data;
 
        /* make sure that maxsize is valid */
@@ -63,9 +63,9 @@ static struct erofs_dirent *find_target_dirent(
        startprfx = endprfx = 0;
 
        while (head <= back) {
-               unsigned mid = head + (back - head) / 2;
-               unsigned nameoff = le16_to_cpu(de[mid].nameoff);
-               unsigned matched = min(startprfx, endprfx);
+               unsigned int mid = head + (back - head) / 2;
+               unsigned int nameoff = le16_to_cpu(de[mid].nameoff);
+               unsigned int matched = min(startprfx, endprfx);
 
                struct qstr dname = QSTR_INIT(data + nameoff,
                        unlikely(mid >= ndirents - 1) ?
@@ -95,8 +95,8 @@ static struct page *find_target_block_classic(
        struct inode *dir,
        struct qstr *name, int *_diff)
 {
-       unsigned startprfx, endprfx;
-       unsigned head, back;
+       unsigned int startprfx, endprfx;
+       unsigned int head, back;
        struct address_space *const mapping = dir->i_mapping;
        struct page *candidate = ERR_PTR(-ENOENT);
 
@@ -105,7 +105,7 @@ static struct page *find_target_block_classic(
        back = inode_datablocks(dir) - 1;
 
        while (head <= back) {
-               unsigned mid = head + (back - head) / 2;
+               unsigned int mid = head + (back - head) / 2;
                struct page *page = read_mapping_page(mapping, mid, NULL);
 
                if (IS_ERR(page)) {
@@ -115,10 +115,10 @@ exact_out:
                        return page;
                } else {
                        int diff;
-                       unsigned ndirents, matched;
+                       unsigned int ndirents, matched;
                        struct qstr dname;
                        struct erofs_dirent *de = kmap_atomic(page);
-                       unsigned nameoff = le16_to_cpu(de->nameoff);
+                       unsigned int nameoff = le16_to_cpu(de->nameoff);
 
                        ndirents = nameoff / sizeof(*de);
 
@@ -164,7 +164,7 @@ exact_out:
 
 int erofs_namei(struct inode *dir,
        struct qstr *name,
-       erofs_nid_t *nid, unsigned *d_type)
+       erofs_nid_t *nid, unsigned int *d_type)
 {
        int diff;
        struct page *page;
@@ -204,7 +204,7 @@ static struct dentry *erofs_lookup(struct inode *dir,
 {
        int err;
        erofs_nid_t nid;
-       unsigned d_type;
+       unsigned int d_type;
        struct inode *inode;
 
        DBG_BUGON(!d_really_is_negative(dentry));
index 2df9768edac96d1dc199071698558c6fb1e5da5d..f69e619807a178c4f3b8281376e9af9cd6c4f6f1 100644 (file)
@@ -29,7 +29,7 @@ static void init_once(void *ptr)
        inode_init_once(&vi->vfs_inode);
 }
 
-static int erofs_init_inode_cache(void)
+static int __init erofs_init_inode_cache(void)
 {
        erofs_inode_cachep = kmem_cache_create("erofs_inode",
                sizeof(struct erofs_vnode), 0,
@@ -81,7 +81,7 @@ static int superblock_read(struct super_block *sb)
        struct erofs_sb_info *sbi;
        struct buffer_head *bh;
        struct erofs_super_block *layout;
-       unsigned blkszbits;
+       unsigned int blkszbits;
        int ret;
 
        bh = sb_bread(sb, 0);
@@ -116,9 +116,10 @@ static int superblock_read(struct super_block *sb)
 #endif
        sbi->islotbits = ffs(sizeof(struct erofs_inode_v1)) - 1;
 #ifdef CONFIG_EROFS_FS_ZIP
-       sbi->clusterbits = 12;
+       /* TODO: clusterbits should be related to inode */
+       sbi->clusterbits = blkszbits;
 
-       if (1 << (sbi->clusterbits - 12) > Z_EROFS_CLUSTER_MAX_PAGES)
+       if (1 << (sbi->clusterbits - PAGE_SHIFT) > Z_EROFS_CLUSTER_MAX_PAGES)
                errln("clusterbits %u is not supported on this kernel",
                        sbi->clusterbits);
 #endif
@@ -144,8 +145,8 @@ char *erofs_fault_name[FAULT_MAX] = {
        [FAULT_KMALLOC]         = "kmalloc",
 };
 
-static void erofs_build_fault_attr(struct erofs_sb_info *sbi,
-                                               unsigned int rate)
+static void __erofs_build_fault_attr(struct erofs_sb_info *sbi,
+                                    unsigned int rate)
 {
        struct erofs_fault_info *ffi = &sbi->fault_info;
 
@@ -156,11 +157,52 @@ static void erofs_build_fault_attr(struct erofs_sb_info *sbi,
        } else {
                memset(ffi, 0, sizeof(struct erofs_fault_info));
        }
+
+       set_opt(sbi, FAULT_INJECTION);
+}
+
+static int erofs_build_fault_attr(struct erofs_sb_info *sbi,
+                                 substring_t *args)
+{
+       int rate = 0;
+
+       if (args->from && match_int(args, &rate))
+               return -EINVAL;
+
+       __erofs_build_fault_attr(sbi, rate);
+       return 0;
+}
+
+static unsigned int erofs_get_fault_rate(struct erofs_sb_info *sbi)
+{
+       return sbi->fault_info.inject_rate;
+}
+#else
+static void __erofs_build_fault_attr(struct erofs_sb_info *sbi,
+                                    unsigned int rate)
+{
+}
+
+static int erofs_build_fault_attr(struct erofs_sb_info *sbi,
+                                 substring_t *args)
+{
+       infoln("fault_injection options not supported");
+       return 0;
+}
+
+static unsigned int erofs_get_fault_rate(struct erofs_sb_info *sbi)
+{
+       return 0;
 }
 #endif
 
 static void default_options(struct erofs_sb_info *sbi)
 {
+       /* set up some FS parameters */
+#ifdef CONFIG_EROFS_FS_ZIP
+       sbi->max_sync_decompress_pages = DEFAULT_MAX_SYNC_DECOMPRESS_PAGES;
+#endif
+
 #ifdef CONFIG_EROFS_FS_XATTR
        set_opt(sbi, XATTR_USER);
 #endif
@@ -192,7 +234,7 @@ static int parse_options(struct super_block *sb, char *options)
 {
        substring_t args[MAX_OPT_ARGS];
        char *p;
-       int arg = 0;
+       int err;
 
        if (!options)
                return 0;
@@ -238,15 +280,11 @@ static int parse_options(struct super_block *sb, char *options)
                        break;
 #endif
                case Opt_fault_injection:
-                       if (args->from && match_int(args, &arg))
-                               return -EINVAL;
-#ifdef CONFIG_EROFS_FAULT_INJECTION
-                       erofs_build_fault_attr(EROFS_SB(sb), arg);
-                       set_opt(EROFS_SB(sb), FAULT_INJECTION);
-#else
-                       infoln("FAULT_INJECTION was not selected");
-#endif
+                       err = erofs_build_fault_attr(EROFS_SB(sb), args);
+                       if (err)
+                               return err;
                        break;
+
                default:
                        errln("Unrecognized mount option \"%s\" "
                                        "or missing value", p);
@@ -521,11 +559,6 @@ static struct file_system_type erofs_fs_type = {
 };
 MODULE_ALIAS_FS("erofs");
 
-#ifdef CONFIG_EROFS_FS_ZIP
-extern int z_erofs_init_zip_subsystem(void);
-extern void z_erofs_exit_zip_subsystem(void);
-#endif
-
 static int __init erofs_module_init(void)
 {
        int err;
@@ -541,11 +574,9 @@ static int __init erofs_module_init(void)
        if (err)
                goto shrinker_err;
 
-#ifdef CONFIG_EROFS_FS_ZIP
        err = z_erofs_init_zip_subsystem();
        if (err)
                goto zip_err;
-#endif
 
        err = register_filesystem(&erofs_fs_type);
        if (err)
@@ -555,10 +586,8 @@ static int __init erofs_module_init(void)
        return 0;
 
 fs_err:
-#ifdef CONFIG_EROFS_FS_ZIP
        z_erofs_exit_zip_subsystem();
 zip_err:
-#endif
        unregister_shrinker(&erofs_shrinker_info);
 shrinker_err:
        erofs_exit_inode_cache();
@@ -569,9 +598,7 @@ icache_err:
 static void __exit erofs_module_exit(void)
 {
        unregister_filesystem(&erofs_fs_type);
-#ifdef CONFIG_EROFS_FS_ZIP
        z_erofs_exit_zip_subsystem();
-#endif
        unregister_shrinker(&erofs_shrinker_info);
        erofs_exit_inode_cache();
        infoln("successfully finalize erofs");
@@ -615,20 +642,31 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
        else
                seq_puts(seq, ",noacl");
 #endif
-#ifdef CONFIG_EROFS_FAULT_INJECTION
        if (test_opt(sbi, FAULT_INJECTION))
                seq_printf(seq, ",fault_injection=%u",
-                               sbi->fault_info.inject_rate);
-#endif
+                       erofs_get_fault_rate(sbi));
        return 0;
 }
 
 static int erofs_remount(struct super_block *sb, int *flags, char *data)
 {
+       struct erofs_sb_info *sbi = EROFS_SB(sb);
+       unsigned int org_mnt_opt = sbi->mount_opt;
+       unsigned int org_inject_rate = erofs_get_fault_rate(sbi);
+       int err;
+
        BUG_ON(!sb_rdonly(sb));
+       err = parse_options(sb, data);
+       if (err)
+               goto out;
 
        *flags |= SB_RDONLY;
        return 0;
+out:
+       __erofs_build_fault_attr(sbi, org_inject_rate);
+       sbi->mount_opt = org_mnt_opt;
+
+       return err;
 }
 
 const struct super_operations erofs_sops = {
index 8721f0a41d157b7ac799eed40bdfea06aa30decd..79d3ba62b29854fc6c3a1848ac6a0a03cdda9c0c 100644 (file)
@@ -13,6 +13,8 @@
 #include "unzip_vle.h"
 #include <linux/prefetch.h>
 
+#include <trace/events/erofs.h>
+
 static struct workqueue_struct *z_erofs_workqueue __read_mostly;
 static struct kmem_cache *z_erofs_workgroup_cachep __read_mostly;
 
@@ -27,7 +29,7 @@ void z_erofs_exit_zip_subsystem(void)
 
 static inline int init_unzip_workqueue(void)
 {
-       const unsigned onlinecpus = num_possible_cpus();
+       const unsigned int onlinecpus = num_possible_cpus();
 
        /*
         * we don't need too many threads, limiting threads
@@ -40,7 +42,7 @@ static inline int init_unzip_workqueue(void)
        return z_erofs_workqueue != NULL ? 0 : -ENOMEM;
 }
 
-int z_erofs_init_zip_subsystem(void)
+int __init z_erofs_init_zip_subsystem(void)
 {
        z_erofs_workgroup_cachep =
                kmem_cache_create("erofs_compress",
@@ -89,7 +91,7 @@ struct z_erofs_vle_work_builder {
 
        /* pages used for reading the compressed data */
        struct page **compressed_pages;
-       unsigned compressed_deficit;
+       unsigned int compressed_deficit;
 };
 
 #define VLE_WORK_BUILDER_INIT()        \
@@ -232,7 +234,7 @@ static int z_erofs_vle_work_add_page(
 
        ret = z_erofs_pagevec_ctor_enqueue(&builder->vector,
                page, type, &occupied);
-       builder->work->vcnt += (unsigned)ret;
+       builder->work->vcnt += (unsigned int)ret;
 
        return ret ? 0 : -EAGAIN;
 }
@@ -271,36 +273,39 @@ retry:
        return true;    /* lucky, I am the followee :) */
 }
 
+struct z_erofs_vle_work_finder {
+       struct super_block *sb;
+       pgoff_t idx;
+       unsigned int pageofs;
+
+       struct z_erofs_vle_workgroup **grp_ret;
+       enum z_erofs_vle_work_role *role;
+       z_erofs_vle_owned_workgrp_t *owned_head;
+       bool *hosted;
+};
+
 static struct z_erofs_vle_work *
-z_erofs_vle_work_lookup(struct super_block *sb,
-                       pgoff_t idx, unsigned pageofs,
-                       struct z_erofs_vle_workgroup **grp_ret,
-                       enum z_erofs_vle_work_role *role,
-                       z_erofs_vle_owned_workgrp_t *owned_head,
-                       bool *hosted)
+z_erofs_vle_work_lookup(const struct z_erofs_vle_work_finder *f)
 {
        bool tag, primary;
        struct erofs_workgroup *egrp;
        struct z_erofs_vle_workgroup *grp;
        struct z_erofs_vle_work *work;
 
-       egrp = erofs_find_workgroup(sb, idx, &tag);
+       egrp = erofs_find_workgroup(f->sb, f->idx, &tag);
        if (egrp == NULL) {
-               *grp_ret = NULL;
+               *f->grp_ret = NULL;
                return NULL;
        }
 
-       *grp_ret = grp = container_of(egrp,
-               struct z_erofs_vle_workgroup, obj);
+       grp = container_of(egrp, struct z_erofs_vle_workgroup, obj);
+       *f->grp_ret = grp;
 
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
-       work = z_erofs_vle_grab_work(grp, pageofs);
+       work = z_erofs_vle_grab_work(grp, f->pageofs);
+       /* if multiref is disabled, `primary' is always true */
        primary = true;
-#else
-       BUG();
-#endif
 
-       DBG_BUGON(work->pageofs != pageofs);
+       DBG_BUGON(work->pageofs != f->pageofs);
 
        /*
         * lock must be taken first to avoid grp->next == NIL between
@@ -340,43 +345,35 @@ z_erofs_vle_work_lookup(struct super_block *sb,
         */
        mutex_lock(&work->lock);
 
-       *hosted = false;
+       *f->hosted = false;
        if (!primary)
-               *role = Z_EROFS_VLE_WORK_SECONDARY;
+               *f->role = Z_EROFS_VLE_WORK_SECONDARY;
        /* claim the workgroup if possible */
-       else if (try_to_claim_workgroup(grp, owned_head, hosted))
-               *role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED;
+       else if (try_to_claim_workgroup(grp, f->owned_head, f->hosted))
+               *f->role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED;
        else
-               *role = Z_EROFS_VLE_WORK_PRIMARY;
+               *f->role = Z_EROFS_VLE_WORK_PRIMARY;
 
        return work;
 }
 
 static struct z_erofs_vle_work *
-z_erofs_vle_work_register(struct super_block *sb,
-                         struct z_erofs_vle_workgroup **grp_ret,
-                         struct erofs_map_blocks *map,
-                         pgoff_t index, unsigned pageofs,
-                         enum z_erofs_vle_work_role *role,
-                         z_erofs_vle_owned_workgrp_t *owned_head,
-                         bool *hosted)
+z_erofs_vle_work_register(const struct z_erofs_vle_work_finder *f,
+                         struct erofs_map_blocks *map)
 {
-       bool newgrp = false;
-       struct z_erofs_vle_workgroup *grp = *grp_ret;
+       bool gnew = false;
+       struct z_erofs_vle_workgroup *grp = *f->grp_ret;
        struct z_erofs_vle_work *work;
 
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
+       /* if multiref is disabled, grp should never be nullptr */
        BUG_ON(grp != NULL);
-#else
-       if (grp != NULL)
-               goto skip;
-#endif
+
        /* no available workgroup, let's allocate one */
        grp = kmem_cache_zalloc(z_erofs_workgroup_cachep, GFP_NOFS);
        if (unlikely(grp == NULL))
                return ERR_PTR(-ENOMEM);
 
-       grp->obj.index = index;
+       grp->obj.index = f->idx;
        grp->llen = map->m_llen;
 
        z_erofs_vle_set_workgrp_fmt(grp,
@@ -386,26 +383,20 @@ z_erofs_vle_work_register(struct super_block *sb,
        atomic_set(&grp->obj.refcount, 1);
 
        /* new workgrps have been claimed as type 1 */
-       WRITE_ONCE(grp->next, *owned_head);
+       WRITE_ONCE(grp->next, *f->owned_head);
        /* primary and followed work for all new workgrps */
-       *role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED;
+       *f->role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED;
        /* it should be submitted by ourselves */
-       *hosted = true;
+       *f->hosted = true;
 
-       newgrp = true;
-#ifdef CONFIG_EROFS_FS_ZIP_MULTIREF
-skip:
-       /* currently unimplemented */
-       BUG();
-#else
+       gnew = true;
        work = z_erofs_vle_grab_primary_work(grp);
-#endif
-       work->pageofs = pageofs;
+       work->pageofs = f->pageofs;
 
        mutex_init(&work->lock);
 
-       if (newgrp) {
-               int err = erofs_register_workgroup(sb, &grp->obj, 0);
+       if (gnew) {
+               int err = erofs_register_workgroup(f->sb, &grp->obj, 0);
 
                if (err) {
                        kmem_cache_free(z_erofs_workgroup_cachep, grp);
@@ -413,24 +404,12 @@ skip:
                }
        }
 
-       *owned_head = *grp_ret = grp;
+       *f->owned_head = *f->grp_ret = grp;
 
        mutex_lock(&work->lock);
        return work;
 }
 
-static inline void __update_workgrp_llen(struct z_erofs_vle_workgroup *grp,
-                                        unsigned int llen)
-{
-       while (1) {
-               unsigned int orig_llen = grp->llen;
-
-               if (orig_llen >= llen || orig_llen ==
-                       cmpxchg(&grp->llen, orig_llen, llen))
-                       break;
-       }
-}
-
 #define builder_is_followed(builder) \
        ((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED)
 
@@ -439,10 +418,17 @@ static int z_erofs_vle_work_iter_begin(struct z_erofs_vle_work_builder *builder,
                                       struct erofs_map_blocks *map,
                                       z_erofs_vle_owned_workgrp_t *owned_head)
 {
-       const unsigned clusterpages = erofs_clusterpages(EROFS_SB(sb));
-       const erofs_blk_t index = erofs_blknr(map->m_pa);
-       const unsigned pageofs = map->m_la & ~PAGE_MASK;
+       const unsigned int clusterpages = erofs_clusterpages(EROFS_SB(sb));
        struct z_erofs_vle_workgroup *grp;
+       const struct z_erofs_vle_work_finder finder = {
+               .sb = sb,
+               .idx = erofs_blknr(map->m_pa),
+               .pageofs = map->m_la & ~PAGE_MASK,
+               .grp_ret = &grp,
+               .role = &builder->role,
+               .owned_head = owned_head,
+               .hosted = &builder->hosted
+       };
        struct z_erofs_vle_work *work;
 
        DBG_BUGON(builder->work != NULL);
@@ -454,16 +440,19 @@ static int z_erofs_vle_work_iter_begin(struct z_erofs_vle_work_builder *builder,
        DBG_BUGON(erofs_blkoff(map->m_pa));
 
 repeat:
-       work = z_erofs_vle_work_lookup(sb, index,
-               pageofs, &grp, &builder->role, owned_head, &builder->hosted);
+       work = z_erofs_vle_work_lookup(&finder);
        if (work != NULL) {
-               __update_workgrp_llen(grp, map->m_llen);
+               unsigned int orig_llen;
+
+               /* increase workgroup `llen' if needed */
+               while ((orig_llen = READ_ONCE(grp->llen)) < map->m_llen &&
+                      orig_llen != cmpxchg_relaxed(&grp->llen,
+                                                   orig_llen, map->m_llen))
+                       cpu_relax();
                goto got_it;
        }
 
-       work = z_erofs_vle_work_register(sb, &grp, map, index, pageofs,
-               &builder->role, owned_head, &builder->hosted);
-
+       work = z_erofs_vle_work_register(&finder, map);
        if (unlikely(work == ERR_PTR(-EAGAIN)))
                goto repeat;
 
@@ -605,8 +594,10 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe,
 #endif
 
        enum z_erofs_page_type page_type;
-       unsigned cur, end, spiltted, index;
-       int err;
+       unsigned int cur, end, spiltted, index;
+       int err = 0;
+
+       trace_erofs_readpage(page, false);
 
        /* register locked file pages as online pages in pack */
        z_erofs_onlinepage_init(page);
@@ -624,7 +615,7 @@ repeat:
        /* go ahead the next map_blocks */
        debugln("%s: [out-of-range] pos %llu", __func__, offset + cur);
 
-       if (!z_erofs_vle_work_iter_end(builder))
+       if (z_erofs_vle_work_iter_end(builder))
                fe->initial = false;
 
        map->m_la = offset + cur;
@@ -633,12 +624,11 @@ repeat:
        if (unlikely(err))
                goto err_out;
 
-       /* deal with hole (FIXME! broken now) */
        if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED)))
                goto hitted;
 
        DBG_BUGON(map->m_plen != 1 << sbi->clusterbits);
-       BUG_ON(erofs_blkoff(map->m_pa));
+       DBG_BUGON(erofs_blkoff(map->m_pa));
 
        err = z_erofs_vle_work_iter_begin(builder, sb, map, &fe->owned_head);
        if (unlikely(err))
@@ -662,7 +652,7 @@ repeat:
        tight &= builder_is_followed(builder);
        work = builder->work;
 hitted:
-       cur = end - min_t(unsigned, offset + end - map->m_la, end);
+       cur = end - min_t(unsigned int, offset + end - map->m_la, end);
        if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) {
                zero_user_segment(page, cur, end);
                goto next_part;
@@ -683,7 +673,7 @@ retry:
 
                err = z_erofs_vle_work_add_page(builder,
                        newpage, Z_EROFS_PAGE_TYPE_EXCLUSIVE);
-               if (!err)
+               if (likely(!err))
                        goto retry;
        }
 
@@ -694,9 +684,10 @@ retry:
 
        /* FIXME! avoid the last relundant fixup & endio */
        z_erofs_onlinepage_fixup(page, index, true);
-       ++spiltted;
 
-       /* also update nr_pages and increase queued_pages */
+       /* bump up the number of spiltted parts of a page */
+       ++spiltted;
+       /* also update nr_pages */
        work->nr_pages = max_t(pgoff_t, work->nr_pages, index + 1);
 next_part:
        /* can be used for verification */
@@ -706,16 +697,18 @@ next_part:
        if (end > 0)
                goto repeat;
 
+out:
        /* FIXME! avoid the last relundant fixup & endio */
        z_erofs_onlinepage_endio(page);
 
        debugln("%s, finish page: %pK spiltted: %u map->m_llen %llu",
                __func__, page, spiltted, map->m_llen);
-       return 0;
+       return err;
 
+       /* if some error occurred while processing this page */
 err_out:
-       /* TODO: the missing error handing cases */
-       return err;
+       SetPageError(page);
+       goto out;
 }
 
 static void z_erofs_vle_unzip_kickoff(void *ptr, int bios)
@@ -736,7 +729,7 @@ static void z_erofs_vle_unzip_kickoff(void *ptr, int bios)
 static inline void z_erofs_vle_read_endio(struct bio *bio)
 {
        const blk_status_t err = bio->bi_status;
-       unsigned i;
+       unsigned int i;
        struct bio_vec *bvec;
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
        struct address_space *mngda = NULL;
@@ -788,16 +781,14 @@ static int z_erofs_vle_unzip(struct super_block *sb,
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
        struct address_space *const mngda = sbi->managed_cache->i_mapping;
 #endif
-       const unsigned clusterpages = erofs_clusterpages(sbi);
+       const unsigned int clusterpages = erofs_clusterpages(sbi);
 
        struct z_erofs_pagevec_ctor ctor;
-       unsigned nr_pages;
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
-       unsigned sparsemem_pages = 0;
-#endif
+       unsigned int nr_pages;
+       unsigned int sparsemem_pages = 0;
        struct page *pages_onstack[Z_EROFS_VLE_VMAP_ONSTACK_PAGES];
        struct page **pages, **compressed_pages, *page;
-       unsigned i, llen;
+       unsigned int i, llen;
 
        enum z_erofs_page_type page_type;
        bool overlapped;
@@ -806,11 +797,7 @@ static int z_erofs_vle_unzip(struct super_block *sb,
        int err;
 
        might_sleep();
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
        work = z_erofs_vle_grab_primary_work(grp);
-#else
-       BUG();
-#endif
        BUG_ON(!READ_ONCE(work->nr_pages));
 
        mutex_lock(&work->lock);
@@ -844,7 +831,7 @@ repeat:
                Z_EROFS_VLE_INLINE_PAGEVECS, work->pagevec, 0);
 
        for (i = 0; i < work->vcnt; ++i) {
-               unsigned pagenr;
+               unsigned int pagenr;
 
                page = z_erofs_pagevec_ctor_dequeue(&ctor, &page_type);
 
@@ -861,13 +848,11 @@ repeat:
                        pagenr = z_erofs_onlinepage_index(page);
 
                BUG_ON(pagenr >= nr_pages);
-
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
                BUG_ON(pages[pagenr] != NULL);
-               ++sparsemem_pages;
-#endif
+
                pages[pagenr] = page;
        }
+       sparsemem_pages = i;
 
        z_erofs_pagevec_ctor_exit(&ctor, true);
 
@@ -875,7 +860,7 @@ repeat:
        compressed_pages = grp->compressed_pages;
 
        for (i = 0; i < clusterpages; ++i) {
-               unsigned pagenr;
+               unsigned int pagenr;
 
                page = compressed_pages[i];
 
@@ -897,10 +882,8 @@ repeat:
                pagenr = z_erofs_onlinepage_index(page);
 
                BUG_ON(pagenr >= nr_pages);
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
                BUG_ON(pages[pagenr] != NULL);
                ++sparsemem_pages;
-#endif
                pages[pagenr] = page;
 
                overlapped = true;
@@ -926,12 +909,10 @@ repeat:
        if (err != -ENOTSUPP)
                goto out_percpu;
 
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
        if (sparsemem_pages >= nr_pages) {
                BUG_ON(sparsemem_pages > nr_pages);
                goto skip_allocpage;
        }
-#endif
 
        for (i = 0; i < nr_pages; ++i) {
                if (pages[i] != NULL)
@@ -940,9 +921,7 @@ repeat:
                pages[i] = __stagingpage_alloc(page_pool, GFP_NOFS);
        }
 
-#ifndef CONFIG_EROFS_FS_ZIP_MULTIREF
 skip_allocpage:
-#endif
        vout = erofs_vmap(pages, nr_pages);
 
        err = z_erofs_vle_unzip_vmap(compressed_pages,
@@ -1100,7 +1079,7 @@ static bool z_erofs_vle_submit_all(struct super_block *sb,
                                   bool force_fg)
 {
        struct erofs_sb_info *const sbi = EROFS_SB(sb);
-       const unsigned clusterpages = erofs_clusterpages(sbi);
+       const unsigned int clusterpages = erofs_clusterpages(sbi);
        const gfp_t gfp = GFP_NOFS;
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
        struct address_space *const mngda = sbi->managed_cache->i_mapping;
@@ -1112,7 +1091,7 @@ static bool z_erofs_vle_submit_all(struct super_block *sb,
        /* since bio will be NULL, no need to initialize last_index */
        pgoff_t uninitialized_var(last_index);
        bool force_submit = false;
-       unsigned nr_bios;
+       unsigned int nr_bios;
 
        if (unlikely(owned_head == Z_EROFS_VLE_WORKGRP_TAIL))
                return false;
@@ -1144,7 +1123,7 @@ static bool z_erofs_vle_submit_all(struct super_block *sb,
                struct z_erofs_vle_workgroup *grp;
                struct page **compressed_pages, *oldpage, *page;
                pgoff_t first_index;
-               unsigned i = 0;
+               unsigned int i = 0;
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
                unsigned int noio = 0;
                bool cachemngd;
@@ -1213,8 +1192,8 @@ submit_bio_retry:
                }
 
                if (bio == NULL) {
-                       bio = prepare_bio(sb, first_index + i,
-                               BIO_MAX_PAGES, z_erofs_vle_read_endio);
+                       bio = erofs_grab_bio(sb, first_index + i,
+                               BIO_MAX_PAGES, z_erofs_vle_read_endio, true);
                        bio->bi_private = tagptr_cast_ptr(bi_private);
 
                        ++nr_bios;
@@ -1309,7 +1288,7 @@ static int z_erofs_vle_normalaccess_readpage(struct file *file,
        LIST_HEAD(pagepool);
 
 #if (EROFS_FS_ZIP_CACHE_LVL >= 2)
-       f.cachedzone_la = page->index << PAGE_SHIFT;
+       f.cachedzone_la = (erofs_off_t)page->index << PAGE_SHIFT;
 #endif
        err = z_erofs_do_read_page(&f, page, &pagepool);
        (void)z_erofs_vle_work_iter_end(&f.builder);
@@ -1329,20 +1308,25 @@ out:
        return 0;
 }
 
-static inline int __z_erofs_vle_normalaccess_readpages(
-       struct file *filp,
-       struct address_space *mapping,
-       struct list_head *pages, unsigned nr_pages, bool sync)
+static int z_erofs_vle_normalaccess_readpages(struct file *filp,
+                                             struct address_space *mapping,
+                                             struct list_head *pages,
+                                             unsigned int nr_pages)
 {
        struct inode *const inode = mapping->host;
+       struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
+       const bool sync = __should_decompress_synchronously(sbi, nr_pages);
 
        struct z_erofs_vle_frontend f = VLE_FRONTEND_INIT(inode);
        gfp_t gfp = mapping_gfp_constraint(mapping, GFP_KERNEL);
        struct page *head = NULL;
        LIST_HEAD(pagepool);
 
+       trace_erofs_readpages(mapping->host, lru_to_page(pages),
+                             nr_pages, false);
+
 #if (EROFS_FS_ZIP_CACHE_LVL >= 2)
-       f.cachedzone_la = lru_to_page(pages)->index << PAGE_SHIFT;
+       f.cachedzone_la = (erofs_off_t)lru_to_page(pages)->index << PAGE_SHIFT;
 #endif
        for (; nr_pages; --nr_pages) {
                struct page *page = lru_to_page(pages);
@@ -1390,56 +1374,45 @@ static inline int __z_erofs_vle_normalaccess_readpages(
        return 0;
 }
 
-static int z_erofs_vle_normalaccess_readpages(
-       struct file *filp,
-       struct address_space *mapping,
-       struct list_head *pages, unsigned nr_pages)
-{
-       return __z_erofs_vle_normalaccess_readpages(filp,
-               mapping, pages, nr_pages,
-               nr_pages < 4 /* sync */);
-}
-
 const struct address_space_operations z_erofs_vle_normalaccess_aops = {
        .readpage = z_erofs_vle_normalaccess_readpage,
        .readpages = z_erofs_vle_normalaccess_readpages,
 };
 
+/*
+ * Variable-sized Logical Extent (Fixed Physical Cluster) Compression Mode
+ * ---
+ * VLE compression mode attempts to compress a number of logical data into
+ * a physical cluster with a fixed size.
+ * VLE compression mode uses "struct z_erofs_vle_decompressed_index".
+ */
 #define __vle_cluster_advise(x, bit, bits) \
        ((le16_to_cpu(x) >> (bit)) & ((1 << (bits)) - 1))
 
 #define __vle_cluster_type(advise) __vle_cluster_advise(advise, \
        Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT, Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS)
 
-enum {
-       Z_EROFS_VLE_CLUSTER_TYPE_PLAIN,
-       Z_EROFS_VLE_CLUSTER_TYPE_HEAD,
-       Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD,
-       Z_EROFS_VLE_CLUSTER_TYPE_RESERVED,
-       Z_EROFS_VLE_CLUSTER_TYPE_MAX
-};
-
 #define vle_cluster_type(di)   \
        __vle_cluster_type((di)->di_advise)
 
-static inline unsigned
-vle_compressed_index_clusterofs(unsigned clustersize,
-       struct z_erofs_vle_decompressed_index *di)
+static int
+vle_decompressed_index_clusterofs(unsigned int *clusterofs,
+                                 unsigned int clustersize,
+                                 struct z_erofs_vle_decompressed_index *di)
 {
-       debugln("%s, vle=%pK, advise=%x (type %u), clusterofs=%x blkaddr=%x",
-               __func__, di, di->di_advise, vle_cluster_type(di),
-               di->di_clusterofs, di->di_u.blkaddr);
-
        switch (vle_cluster_type(di)) {
        case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
+               *clusterofs = clustersize;
                break;
        case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
        case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
-               return di->di_clusterofs;
+               *clusterofs = le16_to_cpu(di->di_clusterofs);
+               break;
        default:
-               BUG_ON(1);
+               DBG_BUGON(1);
+               return -EIO;
        }
-       return clustersize;
+       return 0;
 }
 
 static inline erofs_blk_t
@@ -1448,7 +1421,7 @@ vle_extent_blkaddr(struct inode *inode, pgoff_t index)
        struct erofs_sb_info *sbi = EROFS_I_SB(inode);
        struct erofs_vnode *vi = EROFS_V(inode);
 
-       unsigned ofs = Z_EROFS_VLE_EXTENT_ALIGN(vi->inode_isize +
+       unsigned int ofs = Z_EROFS_VLE_EXTENT_ALIGN(vi->inode_isize +
                vi->xattr_isize) + sizeof(struct erofs_extent_header) +
                index * sizeof(struct z_erofs_vle_decompressed_index);
 
@@ -1461,95 +1434,117 @@ vle_extent_blkoff(struct inode *inode, pgoff_t index)
        struct erofs_sb_info *sbi = EROFS_I_SB(inode);
        struct erofs_vnode *vi = EROFS_V(inode);
 
-       unsigned ofs = Z_EROFS_VLE_EXTENT_ALIGN(vi->inode_isize +
+       unsigned int ofs = Z_EROFS_VLE_EXTENT_ALIGN(vi->inode_isize +
                vi->xattr_isize) + sizeof(struct erofs_extent_header) +
                index * sizeof(struct z_erofs_vle_decompressed_index);
 
        return erofs_blkoff(iloc(sbi, vi->nid) + ofs);
 }
 
-/*
- * Variable-sized Logical Extent (Fixed Physical Cluster) Compression Mode
- * ---
- * VLE compression mode attempts to compress a number of logical data into
- * a physical cluster with a fixed size.
- * VLE compression mode uses "struct z_erofs_vle_decompressed_index".
- */
-static erofs_off_t vle_get_logical_extent_head(
-       struct inode *inode,
-       struct page **page_iter,
-       void **kaddr_iter,
-       unsigned lcn,   /* logical cluster number */
-       erofs_blk_t *pcn,
-       unsigned *flags)
+struct vle_map_blocks_iter_ctx {
+       struct inode *inode;
+       struct super_block *sb;
+       unsigned int clusterbits;
+
+       struct page **mpage_ret;
+       void **kaddr_ret;
+};
+
+static int
+vle_get_logical_extent_head(const struct vle_map_blocks_iter_ctx *ctx,
+                           unsigned int lcn,   /* logical cluster number */
+                           unsigned long long *ofs,
+                           erofs_blk_t *pblk,
+                           unsigned int *flags)
 {
-       /* for extent meta */
-       struct page *page = *page_iter;
-       erofs_blk_t blkaddr = vle_extent_blkaddr(inode, lcn);
+       const unsigned int clustersize = 1 << ctx->clusterbits;
+       const erofs_blk_t mblk = vle_extent_blkaddr(ctx->inode, lcn);
+       struct page *mpage = *ctx->mpage_ret;   /* extent metapage */
+
        struct z_erofs_vle_decompressed_index *di;
-       unsigned long long ofs;
-       const unsigned int clusterbits = EROFS_SB(inode->i_sb)->clusterbits;
-       const unsigned int clustersize = 1 << clusterbits;
+       unsigned int cluster_type, delta0;
 
-       if (page->index != blkaddr) {
-               kunmap_atomic(*kaddr_iter);
-               unlock_page(page);
-               put_page(page);
+       if (mpage->index != mblk) {
+               kunmap_atomic(*ctx->kaddr_ret);
+               unlock_page(mpage);
+               put_page(mpage);
 
-               *page_iter = page = erofs_get_meta_page(inode->i_sb,
-                       blkaddr, false);
-               *kaddr_iter = kmap_atomic(page);
+               mpage = erofs_get_meta_page(ctx->sb, mblk, false);
+               if (IS_ERR(mpage)) {
+                       *ctx->mpage_ret = NULL;
+                       return PTR_ERR(mpage);
+               }
+               *ctx->mpage_ret = mpage;
+               *ctx->kaddr_ret = kmap_atomic(mpage);
        }
 
-       di = *kaddr_iter + vle_extent_blkoff(inode, lcn);
-       switch (vle_cluster_type(di)) {
-       case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
-               BUG_ON(!di->di_u.delta[0]);
-               BUG_ON(lcn < di->di_u.delta[0]);
+       di = *ctx->kaddr_ret + vle_extent_blkoff(ctx->inode, lcn);
 
-               ofs = vle_get_logical_extent_head(inode,
-                       page_iter, kaddr_iter,
-                       lcn - di->di_u.delta[0], pcn, flags);
-               break;
+       cluster_type = vle_cluster_type(di);
+       switch (cluster_type) {
+       case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
+               delta0 = le16_to_cpu(di->di_u.delta[0]);
+               if (unlikely(!delta0 || delta0 > lcn)) {
+                       errln("invalid NONHEAD dl0 %u at lcn %u of nid %llu",
+                             delta0, lcn, EROFS_V(ctx->inode)->nid);
+                       DBG_BUGON(1);
+                       return -EIO;
+               }
+               return vle_get_logical_extent_head(ctx,
+                       lcn - delta0, ofs, pblk, flags);
        case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
                *flags ^= EROFS_MAP_ZIPPED;
+               /* fallthrough */
        case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
                /* clustersize should be a power of two */
-               ofs = ((unsigned long long)lcn << clusterbits) +
+               *ofs = ((u64)lcn << ctx->clusterbits) +
                        (le16_to_cpu(di->di_clusterofs) & (clustersize - 1));
-               *pcn = le32_to_cpu(di->di_u.blkaddr);
+               *pblk = le32_to_cpu(di->di_u.blkaddr);
                break;
        default:
-               BUG_ON(1);
+               errln("unknown cluster type %u at lcn %u of nid %llu",
+                     cluster_type, lcn, EROFS_V(ctx->inode)->nid);
+               DBG_BUGON(1);
+               return -EIO;
        }
-       return ofs;
+       return 0;
 }
 
 int z_erofs_map_blocks_iter(struct inode *inode,
        struct erofs_map_blocks *map,
        struct page **mpage_ret, int flags)
 {
+       void *kaddr;
+       const struct vle_map_blocks_iter_ctx ctx = {
+               .inode = inode,
+               .sb = inode->i_sb,
+               .clusterbits = EROFS_I_SB(inode)->clusterbits,
+               .mpage_ret = mpage_ret,
+               .kaddr_ret = &kaddr
+       };
+       const unsigned int clustersize = 1 << ctx.clusterbits;
+       /* if both m_(l,p)len are 0, regularize l_lblk, l_lofs, etc... */
+       const bool initial = !map->m_llen;
+
        /* logicial extent (start, end) offset */
        unsigned long long ofs, end;
-       struct z_erofs_vle_decompressed_index *di;
-       erofs_blk_t e_blkaddr, pcn;
-       unsigned lcn, logical_cluster_ofs, cluster_type;
+       unsigned int lcn;
        u32 ofs_rem;
+
+       /* initialize `pblk' to keep gcc from printing foolish warnings */
+       erofs_blk_t mblk, pblk = 0;
        struct page *mpage = *mpage_ret;
-       void *kaddr;
-       bool initial;
-       const unsigned int clusterbits = EROFS_SB(inode->i_sb)->clusterbits;
-       const unsigned int clustersize = 1 << clusterbits;
+       struct z_erofs_vle_decompressed_index *di;
+       unsigned int cluster_type, logical_cluster_ofs;
        int err = 0;
 
-       /* if both m_(l,p)len are 0, regularize l_lblk, l_lofs, etc... */
-       initial = !map->m_llen;
+       trace_z_erofs_map_blocks_iter_enter(inode, map, flags);
 
        /* when trying to read beyond EOF, leave it unmapped */
        if (unlikely(map->m_la >= inode->i_size)) {
-               BUG_ON(!initial);
+               DBG_BUGON(!initial);
                map->m_llen = map->m_la + 1 - inode->i_size;
-               map->m_la = inode->i_size - 1;
+               map->m_la = inode->i_size;
                map->m_flags = 0;
                goto out;
        }
@@ -1560,16 +1555,20 @@ int z_erofs_map_blocks_iter(struct inode *inode,
        ofs = map->m_la + map->m_llen;
 
        /* clustersize should be power of two */
-       lcn = ofs >> clusterbits;
+       lcn = ofs >> ctx.clusterbits;
        ofs_rem = ofs & (clustersize - 1);
 
-       e_blkaddr = vle_extent_blkaddr(inode, lcn);
+       mblk = vle_extent_blkaddr(inode, lcn);
 
-       if (mpage == NULL || mpage->index != e_blkaddr) {
+       if (!mpage || mpage->index != mblk) {
                if (mpage != NULL)
                        put_page(mpage);
 
-               mpage = erofs_get_meta_page(inode->i_sb, e_blkaddr, false);
+               mpage = erofs_get_meta_page(ctx.sb, mblk, false);
+               if (IS_ERR(mpage)) {
+                       err = PTR_ERR(mpage);
+                       goto out;
+               }
                *mpage_ret = mpage;
        } else {
                lock_page(mpage);
@@ -1579,10 +1578,14 @@ int z_erofs_map_blocks_iter(struct inode *inode,
        kaddr = kmap_atomic(mpage);
        di = kaddr + vle_extent_blkoff(inode, lcn);
 
-       debugln("%s, lcn %u e_blkaddr %u e_blkoff %u", __func__, lcn,
-               e_blkaddr, vle_extent_blkoff(inode, lcn));
+       debugln("%s, lcn %u mblk %u e_blkoff %u", __func__, lcn,
+               mblk, vle_extent_blkoff(inode, lcn));
+
+       err = vle_decompressed_index_clusterofs(&logical_cluster_ofs,
+                                               clustersize, di);
+       if (unlikely(err))
+               goto unmap_out;
 
-       logical_cluster_ofs = vle_compressed_index_clusterofs(clustersize, di);
        if (!initial) {
                /* [walking mode] 'map' has been already initialized */
                map->m_llen += logical_cluster_ofs;
@@ -1592,7 +1595,7 @@ int z_erofs_map_blocks_iter(struct inode *inode,
        /* by default, compressed */
        map->m_flags |= EROFS_MAP_ZIPPED;
 
-       end = (u64)(lcn + 1) * clustersize;
+       end = ((u64)lcn + 1) * clustersize;
 
        cluster_type = vle_cluster_type(di);
 
@@ -1603,13 +1606,13 @@ int z_erofs_map_blocks_iter(struct inode *inode,
                /* fallthrough */
        case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
                if (ofs_rem == logical_cluster_ofs) {
-                       pcn = le32_to_cpu(di->di_u.blkaddr);
+                       pblk = le32_to_cpu(di->di_u.blkaddr);
                        goto exact_hitted;
                }
 
                if (ofs_rem > logical_cluster_ofs) {
-                       ofs = lcn * clustersize | logical_cluster_ofs;
-                       pcn = le32_to_cpu(di->di_u.blkaddr);
+                       ofs = (u64)lcn * clustersize | logical_cluster_ofs;
+                       pblk = le32_to_cpu(di->di_u.blkaddr);
                        break;
                }
 
@@ -1620,13 +1623,19 @@ int z_erofs_map_blocks_iter(struct inode *inode,
                        err = -EIO;
                        goto unmap_out;
                }
-               end = (lcn-- * clustersize) | logical_cluster_ofs;
+               end = ((u64)lcn-- * clustersize) | logical_cluster_ofs;
                /* fallthrough */
        case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
                /* get the correspoinding first chunk */
-               ofs = vle_get_logical_extent_head(inode, mpage_ret,
-                       &kaddr, lcn, &pcn, &map->m_flags);
+               err = vle_get_logical_extent_head(&ctx, lcn, &ofs,
+                                                 &pblk, &map->m_flags);
                mpage = *mpage_ret;
+
+               if (unlikely(err)) {
+                       if (mpage)
+                               goto unmap_out;
+                       goto out;
+               }
                break;
        default:
                errln("unknown cluster type %u at offset %llu of nid %llu",
@@ -1639,7 +1648,7 @@ int z_erofs_map_blocks_iter(struct inode *inode,
 exact_hitted:
        map->m_llen = end - ofs;
        map->m_plen = clustersize;
-       map->m_pa = blknr_to_addr(pcn);
+       map->m_pa = blknr_to_addr(pblk);
        map->m_flags |= EROFS_MAP_MAPPED;
 unmap_out:
        kunmap_atomic(kaddr);
@@ -1649,8 +1658,10 @@ out:
                __func__, map->m_la, map->m_pa,
                map->m_llen, map->m_plen, map->m_flags);
 
+       trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err);
+
        /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */
-       DBG_BUGON(err < 0);
+       DBG_BUGON(err < 0 && err != -ENOMEM);
        return err;
 }
 
index 39399850086521e95ef03c9f5a49c9e39a072ecc..3316bc36965d4fd2ab6b5270f7ee7c2cf1e0eb7d 100644 (file)
@@ -47,13 +47,6 @@ static inline bool z_erofs_gather_if_stagingpage(struct list_head *page_pool,
 #define Z_EROFS_VLE_INLINE_PAGEVECS     3
 
 struct z_erofs_vle_work {
-       /* struct z_erofs_vle_work *left, *right; */
-
-#ifdef CONFIG_EROFS_FS_ZIP_MULTIREF
-       struct list_head list;
-
-       atomic_t refcount;
-#endif
        struct mutex lock;
 
        /* I: decompression offset in page */
@@ -107,10 +100,8 @@ static inline void z_erofs_vle_set_workgrp_fmt(
        grp->flags = fmt | (grp->flags & ~Z_EROFS_VLE_WORKGRP_FMT_MASK);
 }
 
-#ifdef CONFIG_EROFS_FS_ZIP_MULTIREF
-#error multiref decompression is unimplemented yet
-#else
 
+/* definitions if multiref is disabled */
 #define z_erofs_vle_grab_primary_work(grp)     (&(grp)->work)
 #define z_erofs_vle_grab_work(grp, pageofs)    (&(grp)->work)
 #define z_erofs_vle_work_workgroup(wrk, primary)       \
@@ -118,7 +109,6 @@ static inline void z_erofs_vle_set_workgrp_fmt(
                struct z_erofs_vle_workgroup, work) : \
                ({ BUG(); (void *)NULL; }))
 
-#endif
 
 #define Z_EROFS_WORKGROUP_SIZE       sizeof(struct z_erofs_vle_workgroup)
 
index f5b665f15be5294f9a293c044e4ee7425b1f4057..1a428658cbea2751b574b866b69ead3d0bfd5f68 100644 (file)
@@ -23,14 +23,14 @@ static struct {
 } erofs_pcpubuf[NR_CPUS];
 
 int z_erofs_vle_plain_copy(struct page **compressed_pages,
-                          unsigned clusterpages,
+                          unsigned int clusterpages,
                           struct page **pages,
-                          unsigned nr_pages,
+                          unsigned int nr_pages,
                           unsigned short pageofs)
 {
-       unsigned i, j;
+       unsigned int i, j;
        void *src = NULL;
-       const unsigned righthalf = PAGE_SIZE - pageofs;
+       const unsigned int righthalf = PAGE_SIZE - pageofs;
        char *percpu_data;
        bool mirrored[Z_EROFS_CLUSTER_MAX_PAGES] = { 0 };
 
@@ -42,8 +42,8 @@ int z_erofs_vle_plain_copy(struct page **compressed_pages,
                struct page *page = pages[i];
                void *dst;
 
-               if (page == NULL) {
-                       if (src != NULL) {
+               if (!page) {
+                       if (src) {
                                if (!mirrored[j])
                                        kunmap_atomic(src);
                                src = NULL;
@@ -64,14 +64,14 @@ int z_erofs_vle_plain_copy(struct page **compressed_pages,
                }
 
                if (i) {
-                       if (src == NULL)
-                               src = mirrored[i-1] ?
-                                       percpu_data + (i-1) * PAGE_SIZE :
-                                       kmap_atomic(compressed_pages[i-1]);
+                       if (!src)
+                               src = mirrored[i - 1] ?
+                                       percpu_data + (i - 1) * PAGE_SIZE :
+                                       kmap_atomic(compressed_pages[i - 1]);
 
                        memcpy(dst, src + righthalf, pageofs);
 
-                       if (!mirrored[i-1])
+                       if (!mirrored[i - 1])
                                kunmap_atomic(src);
 
                        if (unlikely(i >= clusterpages)) {
@@ -80,9 +80,9 @@ int z_erofs_vle_plain_copy(struct page **compressed_pages,
                        }
                }
 
-               if (!righthalf)
+               if (!righthalf) {
                        src = NULL;
-               else {
+               else {
                        src = mirrored[i] ? percpu_data + i * PAGE_SIZE :
                                kmap_atomic(compressed_pages[i]);
 
@@ -92,7 +92,7 @@ int z_erofs_vle_plain_copy(struct page **compressed_pages,
                kunmap_atomic(dst);
        }
 
-       if (src != NULL && !mirrored[j])
+       if (src && !mirrored[j])
                kunmap_atomic(src);
 
        preempt_enable();
@@ -102,14 +102,14 @@ int z_erofs_vle_plain_copy(struct page **compressed_pages,
 extern int z_erofs_unzip_lz4(void *in, void *out, size_t inlen, size_t outlen);
 
 int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages,
-                                 unsigned clusterpages,
+                                 unsigned int clusterpages,
                                  struct page **pages,
-                                 unsigned outlen,
+                                 unsigned int outlen,
                                  unsigned short pageofs,
                                  void (*endio)(struct page *))
 {
        void *vin, *vout;
-       unsigned nr_pages, i, j;
+       unsigned int nr_pages, i, j;
        int ret;
 
        if (outlen + pageofs > EROFS_PERCPU_NR_PAGES * PAGE_SIZE)
@@ -126,7 +126,7 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages,
        vout = erofs_pcpubuf[smp_processor_id()].data;
 
        ret = z_erofs_unzip_lz4(vin, vout + pageofs,
-               clusterpages * PAGE_SIZE, outlen);
+                               clusterpages * PAGE_SIZE, outlen);
 
        if (ret >= 0) {
                outlen = ret;
@@ -134,14 +134,15 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages,
        }
 
        for (i = 0; i < nr_pages; ++i) {
-               j = min((unsigned)PAGE_SIZE - pageofs, outlen);
+               j = min((unsigned int)PAGE_SIZE - pageofs, outlen);
 
-               if (pages[i] != NULL) {
-                       if (ret < 0)
+               if (pages[i]) {
+                       if (ret < 0) {
                                SetPageError(pages[i]);
-                       else if (clusterpages == 1 && pages[i] == compressed_pages[0])
+                       } else if (clusterpages == 1 &&
+                                  pages[i] == compressed_pages[0]) {
                                memcpy(vin + pageofs, vout + pageofs, j);
-                       else {
+                       else {
                                void *dst = kmap_atomic(pages[i]);
 
                                memcpy(dst + pageofs, vout + pageofs, j);
@@ -164,14 +165,14 @@ int z_erofs_vle_unzip_fast_percpu(struct page **compressed_pages,
 }
 
 int z_erofs_vle_unzip_vmap(struct page **compressed_pages,
-                          unsigned clusterpages,
+                          unsigned int clusterpages,
                           void *vout,
-                          unsigned llen,
+                          unsigned int llen,
                           unsigned short pageofs,
                           bool overlapped)
 {
        void *vin;
-       unsigned i;
+       unsigned int i;
        int ret;
 
        if (overlapped) {
@@ -181,29 +182,27 @@ int z_erofs_vle_unzip_vmap(struct page **compressed_pages,
                for (i = 0; i < clusterpages; ++i) {
                        void *t = kmap_atomic(compressed_pages[i]);
 
-                       memcpy(vin + PAGE_SIZE *i, t, PAGE_SIZE);
+                       memcpy(vin + PAGE_SIZE * i, t, PAGE_SIZE);
                        kunmap_atomic(t);
                }
-       } else if (clusterpages == 1)
+       } else if (clusterpages == 1) {
                vin = kmap_atomic(compressed_pages[0]);
-       else {
+       else {
                vin = erofs_vmap(compressed_pages, clusterpages);
        }
 
        ret = z_erofs_unzip_lz4(vin, vout + pageofs,
-               clusterpages * PAGE_SIZE, llen);
+                               clusterpages * PAGE_SIZE, llen);
        if (ret > 0)
                ret = 0;
 
        if (!overlapped) {
                if (clusterpages == 1)
                        kunmap_atomic(vin);
-               else {
+               else
                        erofs_vunmap(vin, clusterpages);
-               }
-       } else
+       } else {
                preempt_enable();
-
+       }
        return ret;
 }
-
index bdee9bd09f11fac0e5a426e74bb75b5525492a85..ea8a962e5c9504a2c2f7f54e744b10da9bdc1048 100644 (file)
@@ -116,7 +116,7 @@ unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi,
 {
        pgoff_t first_index = 0;
        void *batch[PAGEVEC_SIZE];
-       unsigned freed = 0;
+       unsigned int freed = 0;
 
        int i, found;
 repeat:
index 0e9cfeccdf99789dbccfca79568f9e191f7cd9e4..80dca6a4adbe27b70887b958031ef3054a7ae119 100644 (file)
@@ -19,41 +19,53 @@ struct xattr_iter {
        void *kaddr;
 
        erofs_blk_t blkaddr;
-       unsigned ofs;
+       unsigned int ofs;
 };
 
 static inline void xattr_iter_end(struct xattr_iter *it, bool atomic)
 {
-       /* only init_inode_xattrs use non-atomic once */
+       /* the only user of kunmap() is 'init_inode_xattrs' */
        if (unlikely(!atomic))
                kunmap(it->page);
        else
                kunmap_atomic(it->kaddr);
+
        unlock_page(it->page);
        put_page(it->page);
 }
 
-static void init_inode_xattrs(struct inode *inode)
+static inline void xattr_iter_end_final(struct xattr_iter *it)
+{
+       if (it->page == NULL)
+               return;
+
+       xattr_iter_end(it, true);
+}
+
+static int init_inode_xattrs(struct inode *inode)
 {
        struct xattr_iter it;
-       unsigned i;
+       unsigned int i;
        struct erofs_xattr_ibody_header *ih;
+       struct super_block *sb;
        struct erofs_sb_info *sbi;
        struct erofs_vnode *vi;
        bool atomic_map;
 
        if (likely(inode_has_inited_xattr(inode)))
-               return;
+               return 0;
 
        vi = EROFS_V(inode);
        BUG_ON(!vi->xattr_isize);
 
-       sbi = EROFS_I_SB(inode);
+       sb = inode->i_sb;
+       sbi = EROFS_SB(sb);
        it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
        it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
 
        it.page = erofs_get_inline_page(inode, it.blkaddr);
-       BUG_ON(IS_ERR(it.page));
+       if (IS_ERR(it.page))
+               return PTR_ERR(it.page);
 
        /* read in shared xattr array (non-atomic, see kmalloc below) */
        it.kaddr = kmap(it.page);
@@ -62,9 +74,12 @@ static void init_inode_xattrs(struct inode *inode)
        ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs);
 
        vi->xattr_shared_count = ih->h_shared_count;
-       vi->xattr_shared_xattrs = (unsigned *)kmalloc_array(
-               vi->xattr_shared_count, sizeof(unsigned),
-               GFP_KERNEL | __GFP_NOFAIL);
+       vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count,
+                                               sizeof(uint), GFP_KERNEL);
+       if (vi->xattr_shared_xattrs == NULL) {
+               xattr_iter_end(&it, atomic_map);
+               return -ENOMEM;
+       }
 
        /* let's skip ibody header */
        it.ofs += sizeof(struct erofs_xattr_ibody_header);
@@ -75,9 +90,10 @@ static void init_inode_xattrs(struct inode *inode)
                        BUG_ON(it.ofs != EROFS_BLKSIZ);
                        xattr_iter_end(&it, atomic_map);
 
-                       it.page = erofs_get_meta_page(inode->i_sb,
+                       it.page = erofs_get_meta_page(sb,
                                ++it.blkaddr, S_ISDIR(inode->i_mode));
-                       BUG_ON(IS_ERR(it.page));
+                       if (IS_ERR(it.page))
+                               return PTR_ERR(it.page);
 
                        it.kaddr = kmap_atomic(it.page);
                        atomic_map = true;
@@ -90,27 +106,43 @@ static void init_inode_xattrs(struct inode *inode)
        xattr_iter_end(&it, atomic_map);
 
        inode_set_inited_xattr(inode);
+       return 0;
 }
 
+/*
+ * the general idea for these return values is
+ * if    0 is returned, go on processing the current xattr;
+ *       1 (> 0) is returned, skip this round to process the next xattr;
+ *    -err (< 0) is returned, an error (maybe ENOXATTR) occurred
+ *                            and need to be handled
+ */
 struct xattr_iter_handlers {
        int (*entry)(struct xattr_iter *, struct erofs_xattr_entry *);
-       int (*name)(struct xattr_iter *, unsigned, char *, unsigned);
-       int (*alloc_buffer)(struct xattr_iter *, unsigned);
-       void (*value)(struct xattr_iter *, unsigned, char *, unsigned);
+       int (*name)(struct xattr_iter *, unsigned int, char *, unsigned int);
+       int (*alloc_buffer)(struct xattr_iter *, unsigned int);
+       void (*value)(struct xattr_iter *, unsigned int, char *, unsigned int);
 };
 
-static void xattr_iter_fixup(struct xattr_iter *it)
+static inline int xattr_iter_fixup(struct xattr_iter *it)
 {
-       if (unlikely(it->ofs >= EROFS_BLKSIZ)) {
-               xattr_iter_end(it, true);
+       if (it->ofs < EROFS_BLKSIZ)
+               return 0;
+
+       xattr_iter_end(it, true);
+
+       it->blkaddr += erofs_blknr(it->ofs);
 
-               it->blkaddr += erofs_blknr(it->ofs);
-               it->page = erofs_get_meta_page(it->sb, it->blkaddr, false);
-               BUG_ON(IS_ERR(it->page));
+       it->page = erofs_get_meta_page(it->sb, it->blkaddr, false);
+       if (IS_ERR(it->page)) {
+               int err = PTR_ERR(it->page);
 
-               it->kaddr = kmap_atomic(it->page);
-               it->ofs = erofs_blkoff(it->ofs);
+               it->page = NULL;
+               return err;
        }
+
+       it->kaddr = kmap_atomic(it->page);
+       it->ofs = erofs_blkoff(it->ofs);
+       return 0;
 }
 
 static int inline_xattr_iter_begin(struct xattr_iter *it,
@@ -118,7 +150,7 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
 {
        struct erofs_vnode *const vi = EROFS_V(inode);
        struct erofs_sb_info *const sbi = EROFS_SB(inode->i_sb);
-       unsigned xattr_header_sz, inline_xattr_ofs;
+       unsigned int xattr_header_sz, inline_xattr_ofs;
 
        xattr_header_sz = inlinexattr_header_size(inode);
        if (unlikely(xattr_header_sz >= vi->xattr_isize)) {
@@ -132,21 +164,28 @@ static int inline_xattr_iter_begin(struct xattr_iter *it,
        it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
 
        it->page = erofs_get_inline_page(inode, it->blkaddr);
-       BUG_ON(IS_ERR(it->page));
-       it->kaddr = kmap_atomic(it->page);
+       if (IS_ERR(it->page))
+               return PTR_ERR(it->page);
 
+       it->kaddr = kmap_atomic(it->page);
        return vi->xattr_isize - xattr_header_sz;
 }
 
+/*
+ * Regardless of success or failure, `xattr_foreach' will end up with
+ * `ofs' pointing to the next xattr item rather than an arbitrary position.
+ */
 static int xattr_foreach(struct xattr_iter *it,
-       struct xattr_iter_handlers *op, unsigned *tlimit)
+       const struct xattr_iter_handlers *op, unsigned int *tlimit)
 {
        struct erofs_xattr_entry entry;
-       unsigned value_sz, processed, slice;
+       unsigned int value_sz, processed, slice;
        int err;
 
        /* 0. fixup blkaddr, ofs, ipage */
-       xattr_iter_fixup(it);
+       err = xattr_iter_fixup(it);
+       if (err)
+               return err;
 
        /*
         * 1. read xattr entry to the memory,
@@ -155,7 +194,7 @@ static int xattr_foreach(struct xattr_iter *it,
         */
        entry = *(struct erofs_xattr_entry *)(it->kaddr + it->ofs);
        if (tlimit != NULL) {
-               unsigned entry_sz = EROFS_XATTR_ENTRY_SIZE(&entry);
+               unsigned int entry_sz = EROFS_XATTR_ENTRY_SIZE(&entry);
 
                BUG_ON(*tlimit < entry_sz);
                *tlimit -= entry_sz;
@@ -178,12 +217,14 @@ static int xattr_foreach(struct xattr_iter *it,
                if (it->ofs >= EROFS_BLKSIZ) {
                        BUG_ON(it->ofs > EROFS_BLKSIZ);
 
-                       xattr_iter_fixup(it);
+                       err = xattr_iter_fixup(it);
+                       if (err)
+                               goto out;
                        it->ofs = 0;
                }
 
-               slice = min_t(unsigned, PAGE_SIZE - it->ofs,
-                       entry.e_name_len - processed);
+               slice = min_t(unsigned int, PAGE_SIZE - it->ofs,
+                             entry.e_name_len - processed);
 
                /* handle name */
                err = op->name(it, processed, it->kaddr + it->ofs, slice);
@@ -210,21 +251,24 @@ static int xattr_foreach(struct xattr_iter *it,
        while (processed < value_sz) {
                if (it->ofs >= EROFS_BLKSIZ) {
                        BUG_ON(it->ofs > EROFS_BLKSIZ);
-                       xattr_iter_fixup(it);
+
+                       err = xattr_iter_fixup(it);
+                       if (err)
+                               goto out;
                        it->ofs = 0;
                }
 
-               slice = min_t(unsigned, PAGE_SIZE - it->ofs,
-                       value_sz - processed);
+               slice = min_t(unsigned int, PAGE_SIZE - it->ofs,
+                             value_sz - processed);
                op->value(it, processed, it->kaddr + it->ofs, slice);
                it->ofs += slice;
                processed += slice;
        }
 
 out:
-       /* we assume that ofs is aligned with 4 bytes */
+       /* xattrs should be 4-byte aligned (on-disk constraint) */
        it->ofs = EROFS_XATTR_ALIGN(it->ofs);
-       return err;
+       return err < 0 ? err : 0;
 }
 
 struct getxattr_iter {
@@ -245,7 +289,7 @@ static int xattr_entrymatch(struct xattr_iter *_it,
 }
 
 static int xattr_namematch(struct xattr_iter *_it,
-       unsigned processed, char *buf, unsigned len)
+       unsigned int processed, char *buf, unsigned int len)
 {
        struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
 
@@ -253,7 +297,7 @@ static int xattr_namematch(struct xattr_iter *_it,
 }
 
 static int xattr_checkbuffer(struct xattr_iter *_it,
-       unsigned value_sz)
+       unsigned int value_sz)
 {
        struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
        int err = it->buffer_size < value_sz ? -ERANGE : 0;
@@ -263,14 +307,14 @@ static int xattr_checkbuffer(struct xattr_iter *_it,
 }
 
 static void xattr_copyvalue(struct xattr_iter *_it,
-       unsigned processed, char *buf, unsigned len)
+       unsigned int processed, char *buf, unsigned int len)
 {
        struct getxattr_iter *it = container_of(_it, struct getxattr_iter, it);
 
        memcpy(it->buffer + processed, buf, len);
 }
 
-static struct xattr_iter_handlers find_xattr_handlers = {
+static const struct xattr_iter_handlers find_xattr_handlers = {
        .entry = xattr_entrymatch,
        .name = xattr_namematch,
        .alloc_buffer = xattr_checkbuffer,
@@ -280,7 +324,7 @@ static struct xattr_iter_handlers find_xattr_handlers = {
 static int inline_getxattr(struct inode *inode, struct getxattr_iter *it)
 {
        int ret;
-       unsigned remaining;
+       unsigned int remaining;
 
        ret = inline_xattr_iter_begin(&it->it, inode);
        if (ret < 0)
@@ -289,19 +333,20 @@ static int inline_getxattr(struct inode *inode, struct getxattr_iter *it)
        remaining = ret;
        while (remaining) {
                ret = xattr_foreach(&it->it, &find_xattr_handlers, &remaining);
-               if (ret >= 0)
+               if (ret != -ENOATTR)
                        break;
        }
-       xattr_iter_end(&it->it, true);
+       xattr_iter_end_final(&it->it);
 
-       return ret < 0 ? ret : it->buffer_size;
+       return ret ? ret : it->buffer_size;
 }
 
 static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
 {
        struct erofs_vnode *const vi = EROFS_V(inode);
-       struct erofs_sb_info *const sbi = EROFS_SB(inode->i_sb);
-       unsigned i;
+       struct super_block *const sb = inode->i_sb;
+       struct erofs_sb_info *const sbi = EROFS_SB(sb);
+       unsigned int i;
        int ret = -ENOATTR;
 
        for (i = 0; i < vi->xattr_shared_count; ++i) {
@@ -314,21 +359,22 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
                        if (i)
                                xattr_iter_end(&it->it, true);
 
-                       it->it.page = erofs_get_meta_page(inode->i_sb,
-                               blkaddr, false);
-                       BUG_ON(IS_ERR(it->it.page));
+                       it->it.page = erofs_get_meta_page(sb, blkaddr, false);
+                       if (IS_ERR(it->it.page))
+                               return PTR_ERR(it->it.page);
+
                        it->it.kaddr = kmap_atomic(it->it.page);
                        it->it.blkaddr = blkaddr;
                }
 
                ret = xattr_foreach(&it->it, &find_xattr_handlers, NULL);
-               if (ret >= 0)
+               if (ret != -ENOATTR)
                        break;
        }
        if (vi->xattr_shared_count)
-               xattr_iter_end(&it->it, true);
+               xattr_iter_end_final(&it->it);
 
-       return ret < 0 ? ret : it->buffer_size;
+       return ret ? ret : it->buffer_size;
 }
 
 static bool erofs_xattr_user_list(struct dentry *dentry)
@@ -351,7 +397,9 @@ int erofs_getxattr(struct inode *inode, int index,
        if (unlikely(name == NULL))
                return -EINVAL;
 
-       init_inode_xattrs(inode);
+       ret = init_inode_xattrs(inode);
+       if (ret)
+               return ret;
 
        it.index = index;
 
@@ -446,7 +494,7 @@ static int xattr_entrylist(struct xattr_iter *_it,
 {
        struct listxattr_iter *it =
                container_of(_it, struct listxattr_iter, it);
-       unsigned prefix_len;
+       unsigned int prefix_len;
        const char *prefix;
 
        const struct xattr_handler *h =
@@ -474,7 +522,7 @@ static int xattr_entrylist(struct xattr_iter *_it,
 }
 
 static int xattr_namelist(struct xattr_iter *_it,
-       unsigned processed, char *buf, unsigned len)
+       unsigned int processed, char *buf, unsigned int len)
 {
        struct listxattr_iter *it =
                container_of(_it, struct listxattr_iter, it);
@@ -485,7 +533,7 @@ static int xattr_namelist(struct xattr_iter *_it,
 }
 
 static int xattr_skipvalue(struct xattr_iter *_it,
-       unsigned value_sz)
+       unsigned int value_sz)
 {
        struct listxattr_iter *it =
                container_of(_it, struct listxattr_iter, it);
@@ -494,7 +542,7 @@ static int xattr_skipvalue(struct xattr_iter *_it,
        return 1;
 }
 
-static struct xattr_iter_handlers list_xattr_handlers = {
+static const struct xattr_iter_handlers list_xattr_handlers = {
        .entry = xattr_entrylist,
        .name = xattr_namelist,
        .alloc_buffer = xattr_skipvalue,
@@ -504,7 +552,7 @@ static struct xattr_iter_handlers list_xattr_handlers = {
 static int inline_listxattr(struct listxattr_iter *it)
 {
        int ret;
-       unsigned remaining;
+       unsigned int remaining;
 
        ret = inline_xattr_iter_begin(&it->it, d_inode(it->dentry));
        if (ret < 0)
@@ -513,19 +561,20 @@ static int inline_listxattr(struct listxattr_iter *it)
        remaining = ret;
        while (remaining) {
                ret = xattr_foreach(&it->it, &list_xattr_handlers, &remaining);
-               if (ret < 0)
+               if (ret)
                        break;
        }
-       xattr_iter_end(&it->it, true);
-       return ret < 0 ? ret : it->buffer_ofs;
+       xattr_iter_end_final(&it->it);
+       return ret ? ret : it->buffer_ofs;
 }
 
 static int shared_listxattr(struct listxattr_iter *it)
 {
        struct inode *const inode = d_inode(it->dentry);
        struct erofs_vnode *const vi = EROFS_V(inode);
-       struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
-       unsigned i;
+       struct super_block *const sb = inode->i_sb;
+       struct erofs_sb_info *const sbi = EROFS_SB(sb);
+       unsigned int i;
        int ret = 0;
 
        for (i = 0; i < vi->xattr_shared_count; ++i) {
@@ -537,21 +586,22 @@ static int shared_listxattr(struct listxattr_iter *it)
                        if (i)
                                xattr_iter_end(&it->it, true);
 
-                       it->it.page = erofs_get_meta_page(inode->i_sb,
-                               blkaddr, false);
-                       BUG_ON(IS_ERR(it->it.page));
+                       it->it.page = erofs_get_meta_page(sb, blkaddr, false);
+                       if (IS_ERR(it->it.page))
+                               return PTR_ERR(it->it.page);
+
                        it->it.kaddr = kmap_atomic(it->it.page);
                        it->it.blkaddr = blkaddr;
                }
 
                ret = xattr_foreach(&it->it, &list_xattr_handlers, NULL);
-               if (ret < 0)
+               if (ret)
                        break;
        }
        if (vi->xattr_shared_count)
-               xattr_iter_end(&it->it, true);
+               xattr_iter_end_final(&it->it);
 
-       return ret < 0 ? ret : it->buffer_ofs;
+       return ret ? ret : it->buffer_ofs;
 }
 
 ssize_t erofs_listxattr(struct dentry *dentry,
@@ -560,7 +610,9 @@ ssize_t erofs_listxattr(struct dentry *dentry,
        int ret;
        struct listxattr_iter it;
 
-       init_inode_xattrs(d_inode(dentry));
+       ret = init_inode_xattrs(d_inode(dentry));
+       if (ret)
+               return ret;
 
        it.dentry = dentry;
        it.buffer = buffer;
index 798a8fe98e95796d48c189933cc441fa434d722d..ac427baa464a43886ca004699e3c7210fcd189a4 100644 (file)
@@ -232,7 +232,7 @@ struct fbtft_par {
        bool polarity;
 };
 
-#define NUMARGS(...)  (sizeof((int[]){__VA_ARGS__})/sizeof(int))
+#define NUMARGS(...)  (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
 
 #define write_reg(par, ...)                                            \
        ((par)->fbtftops.write_register(par, NUMARGS(__VA_ARGS__), __VA_ARGS__))
@@ -355,39 +355,39 @@ module_exit(fbtft_driver_module_exit);
 #define DEBUG_LEVEL_6  (DEBUG_LEVEL_4 | DEBUG_LEVEL_5)
 #define DEBUG_LEVEL_7  0xFFFFFFFF
 
-#define DEBUG_DRIVER_INIT_FUNCTIONS (1<<3)
-#define DEBUG_TIME_FIRST_UPDATE     (1<<4)
-#define DEBUG_TIME_EACH_UPDATE      (1<<5)
-#define DEBUG_DEFERRED_IO           (1<<6)
-#define DEBUG_FBTFT_INIT_FUNCTIONS  (1<<7)
+#define DEBUG_DRIVER_INIT_FUNCTIONS BIT(3)
+#define DEBUG_TIME_FIRST_UPDATE     BIT(4)
+#define DEBUG_TIME_EACH_UPDATE      BIT(5)
+#define DEBUG_DEFERRED_IO           BIT(6)
+#define DEBUG_FBTFT_INIT_FUNCTIONS  BIT(7)
 
 /* fbops */
-#define DEBUG_FB_READ               (1<<8)
-#define DEBUG_FB_WRITE              (1<<9)
-#define DEBUG_FB_FILLRECT           (1<<10)
-#define DEBUG_FB_COPYAREA           (1<<11)
-#define DEBUG_FB_IMAGEBLIT          (1<<12)
-#define DEBUG_FB_SETCOLREG          (1<<13)
-#define DEBUG_FB_BLANK              (1<<14)
+#define DEBUG_FB_READ               BIT(8)
+#define DEBUG_FB_WRITE              BIT(9)
+#define DEBUG_FB_FILLRECT           BIT(10)
+#define DEBUG_FB_COPYAREA           BIT(11)
+#define DEBUG_FB_IMAGEBLIT          BIT(12)
+#define DEBUG_FB_SETCOLREG          BIT(13)
+#define DEBUG_FB_BLANK              BIT(14)
 
-#define DEBUG_SYSFS                 (1<<16)
+#define DEBUG_SYSFS                 BIT(16)
 
 /* fbtftops */
-#define DEBUG_BACKLIGHT             (1<<17)
-#define DEBUG_READ                  (1<<18)
-#define DEBUG_WRITE                 (1<<19)
-#define DEBUG_WRITE_VMEM            (1<<20)
-#define DEBUG_WRITE_REGISTER        (1<<21)
-#define DEBUG_SET_ADDR_WIN          (1<<22)
-#define DEBUG_RESET                 (1<<23)
-#define DEBUG_MKDIRTY               (1<<24)
-#define DEBUG_UPDATE_DISPLAY        (1<<25)
-#define DEBUG_INIT_DISPLAY          (1<<26)
-#define DEBUG_BLANK                 (1<<27)
-#define DEBUG_REQUEST_GPIOS         (1<<28)
-#define DEBUG_FREE_GPIOS            (1<<29)
-#define DEBUG_REQUEST_GPIOS_MATCH   (1<<30)
-#define DEBUG_VERIFY_GPIOS          (1<<31)
+#define DEBUG_BACKLIGHT             BIT(17)
+#define DEBUG_READ                  BIT(18)
+#define DEBUG_WRITE                 BIT(19)
+#define DEBUG_WRITE_VMEM            BIT(20)
+#define DEBUG_WRITE_REGISTER        BIT(21)
+#define DEBUG_SET_ADDR_WIN          BIT(22)
+#define DEBUG_RESET                 BIT(23)
+#define DEBUG_MKDIRTY               BIT(24)
+#define DEBUG_UPDATE_DISPLAY        BIT(25)
+#define DEBUG_INIT_DISPLAY          BIT(26)
+#define DEBUG_BLANK                 BIT(27)
+#define DEBUG_REQUEST_GPIOS         BIT(28)
+#define DEBUG_FREE_GPIOS            BIT(29)
+#define DEBUG_REQUEST_GPIOS_MATCH   BIT(30)
+#define DEBUG_VERIFY_GPIOS          BIT(31)
 
 #define fbtft_init_dbg(dev, format, arg...)                  \
 do {                                                         \
index ecdd3d84f95668cd66dc1cc7b0519ad1d5dda24b..7a7ca67822c5fbad7fe476c126516dc896618055 100644 (file)
@@ -717,7 +717,7 @@ static int port_vlans_add(struct net_device *netdev,
                          struct switchdev_trans *trans)
 {
        struct ethsw_port_priv *port_priv = netdev_priv(netdev);
-       int vid, err;
+       int vid, err = 0;
 
        if (netif_is_bridge_master(vlan->obj.orig_dev))
                return -EOPNOTSUPP;
@@ -872,7 +872,7 @@ static int port_vlans_del(struct net_device *netdev,
                          const struct switchdev_obj_port_vlan *vlan)
 {
        struct ethsw_port_priv *port_priv = netdev_priv(netdev);
-       int vid, err;
+       int vid, err = 0;
 
        if (netif_is_bridge_master(vlan->obj.orig_dev))
                return -EOPNOTSUPP;
@@ -1014,10 +1014,8 @@ static void ethsw_switchdev_event_work(struct work_struct *work)
                container_of(work, struct ethsw_switchdev_event_work, work);
        struct net_device *dev = switchdev_work->dev;
        struct switchdev_notifier_fdb_info *fdb_info;
-       struct ethsw_port_priv *port_priv;
 
        rtnl_lock();
-       port_priv = netdev_priv(dev);
        fdb_info = &switchdev_work->fdb_info;
 
        switch (switchdev_work->event) {
index 970e299046c3781e9fad1c67abb1a4f66b8feadc..e82b85541f7ef06fd2a5ddefeee5d238e662cd31 100644 (file)
@@ -14,8 +14,9 @@ config STAGING_APEX_DRIVER
        tristate "Apex Driver"
        depends on STAGING_GASKET_FRAMEWORK
        help
-         This driver supports the Apex device.  Say Y if you want to
-         include this driver in the kernel.
+         This driver supports the Apex Edge TPU device.  See
+         https://cloud.google.com/edge-tpu/ for more information.
+         Say Y if you want to include this driver in the kernel.
 
          To compile this driver as a module, choose M here.  The module
          will be called "apex".
index c747e9ca451860309dab8440bad5705492d014a4..0578bf1ba1e923576e68c7e17a263203f5faa070 100644 (file)
@@ -138,9 +138,6 @@ static const struct gasket_mappable_region mappable_regions[NUM_REGIONS] = {
        { 0x48000, 0x1000 },
 };
 
-static const struct gasket_mappable_region cm_mappable_regions[1] = { { 0x0,
-       APEX_CH_MEM_BYTES } };
-
 /* Gasket device interrupts enums must be dense (i.e., no empty slots). */
 enum apex_interrupt {
        APEX_INTERRUPT_INSTR_QUEUE = 0,
@@ -228,7 +225,6 @@ static struct gasket_interrupt_desc apex_interrupts[] = {
        },
 };
 
-
 /* Allows device to enter power save upon driver close(). */
 static int allow_power_save = 1;
 
@@ -529,7 +525,7 @@ static ssize_t sysfs_show(struct device *device, struct device_attribute *attr,
                return -ENODEV;
        }
 
-       type = (enum sysfs_attribute_type)gasket_sysfs_get_attr(device, attr);
+       type = (enum sysfs_attribute_type)gasket_attr->data.attr_type;
        switch (type) {
        case ATTR_KERNEL_HIB_PAGE_TABLE_SIZE:
                ret = scnprintf(buf, PAGE_SIZE, "%u\n",
index d12ab560411f704bd6f42c4094392ea7522f91d7..a445d58fb39998b6f7ee067b91645233bdaa1fda 100644 (file)
@@ -109,8 +109,6 @@ check_and_invoke_callback(struct gasket_dev *gasket_dev,
 {
        int ret = 0;
 
-       dev_dbg(gasket_dev->dev, "check_and_invoke_callback %p\n",
-               cb_function);
        if (cb_function) {
                mutex_lock(&gasket_dev->mutex);
                ret = cb_function(gasket_dev);
@@ -126,11 +124,8 @@ gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev,
 {
        int ret = 0;
 
-       if (cb_function) {
-               dev_dbg(gasket_dev->dev,
-                       "Invoking device-specific callback.\n");
+       if (cb_function)
                ret = cb_function(gasket_dev);
-       }
        return ret;
 }
 
@@ -189,26 +184,26 @@ static int gasket_find_dev_slot(struct gasket_internal_desc *internal_desc,
  * Returns 0 if successful, a negative error code otherwise.
  */
 static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
-                           struct device *parent, struct gasket_dev **pdev,
-                           const char *kobj_name)
+                           struct device *parent, struct gasket_dev **pdev)
 {
        int dev_idx;
        const struct gasket_driver_desc *driver_desc =
                internal_desc->driver_desc;
        struct gasket_dev *gasket_dev;
        struct gasket_cdev_info *dev_info;
+       const char *parent_name = dev_name(parent);
 
-       pr_debug("Allocating a Gasket device %s.\n", kobj_name);
+       pr_debug("Allocating a Gasket device, parent %s.\n", parent_name);
 
        *pdev = NULL;
 
-       dev_idx = gasket_find_dev_slot(internal_desc, kobj_name);
+       dev_idx = gasket_find_dev_slot(internal_desc, parent_name);
        if (dev_idx < 0)
                return dev_idx;
 
        gasket_dev = *pdev = kzalloc(sizeof(*gasket_dev), GFP_KERNEL);
        if (!gasket_dev) {
-               pr_err("no memory for device %s\n", kobj_name);
+               pr_err("no memory for device, parent %s\n", parent_name);
                return -ENOMEM;
        }
        internal_desc->devs[dev_idx] = gasket_dev;
@@ -217,7 +212,7 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
 
        gasket_dev->internal_desc = internal_desc;
        gasket_dev->dev_idx = dev_idx;
-       snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", kobj_name);
+       snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name);
        gasket_dev->dev = get_device(parent);
        /* gasket_bar_data is uninitialized. */
        gasket_dev->num_page_tables = driver_desc->num_page_tables;
@@ -231,10 +226,9 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
        dev_info->devt =
                MKDEV(driver_desc->major, driver_desc->minor +
                      gasket_dev->dev_idx);
-       dev_info->device = device_create(internal_desc->class, parent,
-               dev_info->devt, gasket_dev, dev_info->name);
-
-       dev_dbg(dev_info->device, "Gasket device allocated.\n");
+       dev_info->device =
+               device_create(internal_desc->class, parent, dev_info->devt,
+                             gasket_dev, dev_info->name);
 
        /* cdev has not yet been added; cdev_added is 0 */
        dev_info->gasket_dev_ptr = gasket_dev;
@@ -652,13 +646,13 @@ void gasket_disable_device(struct gasket_dev *gasket_dev)
 EXPORT_SYMBOL(gasket_disable_device);
 
 /*
- * Registered descriptor lookup.
+ * Registered driver descriptor lookup for PCI devices.
  *
  * Precondition: Called with g_mutex held (to avoid a race on return).
  * Returns NULL if no matching device was found.
  */
 static struct gasket_internal_desc *
-lookup_internal_desc(struct pci_dev *pci_dev)
+lookup_pci_internal_desc(struct pci_dev *pci_dev)
 {
        int i;
 
@@ -1358,13 +1352,7 @@ int gasket_enable_device(struct gasket_dev *gasket_dev)
        const struct gasket_driver_desc *driver_desc =
                gasket_dev->internal_desc->driver_desc;
 
-       ret = gasket_interrupt_init(gasket_dev, driver_desc->name,
-                                   driver_desc->interrupt_type,
-                                   driver_desc->interrupts,
-                                   driver_desc->num_interrupts,
-                                   driver_desc->interrupt_pack_width,
-                                   driver_desc->interrupt_bar_index,
-                                   driver_desc->wire_interrupt_offsets);
+       ret = gasket_interrupt_init(gasket_dev);
        if (ret) {
                dev_err(gasket_dev->dev,
                        "Critical failure to allocate interrupts: %d\n", ret);
@@ -1420,6 +1408,56 @@ int gasket_enable_device(struct gasket_dev *gasket_dev)
 }
 EXPORT_SYMBOL(gasket_enable_device);
 
+static int __gasket_add_device(struct device *parent_dev,
+                              struct gasket_internal_desc *internal_desc,
+                              struct gasket_dev **gasket_devp)
+{
+       int ret;
+       struct gasket_dev *gasket_dev;
+       const struct gasket_driver_desc *driver_desc =
+           internal_desc->driver_desc;
+
+       ret = gasket_alloc_dev(internal_desc, parent_dev, &gasket_dev);
+       if (ret)
+               return ret;
+       if (IS_ERR(gasket_dev->dev_info.device)) {
+               dev_err(parent_dev, "Cannot create %s device %s [ret = %ld]\n",
+                       driver_desc->name, gasket_dev->dev_info.name,
+                       PTR_ERR(gasket_dev->dev_info.device));
+               ret = -ENODEV;
+               goto free_gasket_dev;
+       }
+
+       ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device,
+                                         gasket_dev);
+       if (ret)
+               goto remove_device;
+
+       ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
+                                         gasket_sysfs_generic_attrs);
+       if (ret)
+               goto remove_sysfs_mapping;
+
+       *gasket_devp = gasket_dev;
+       return 0;
+
+remove_sysfs_mapping:
+       gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
+remove_device:
+       device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
+free_gasket_dev:
+       gasket_free_dev(gasket_dev);
+       return ret;
+}
+
+static void __gasket_remove_device(struct gasket_internal_desc *internal_desc,
+                                  struct gasket_dev *gasket_dev)
+{
+       gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
+       device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
+       gasket_free_dev(gasket_dev);
+}
+
 /*
  * Add PCI gasket device.
  *
@@ -1432,16 +1470,14 @@ int gasket_pci_add_device(struct pci_dev *pci_dev,
                          struct gasket_dev **gasket_devp)
 {
        int ret;
-       const char *kobj_name = dev_name(&pci_dev->dev);
        struct gasket_internal_desc *internal_desc;
        struct gasket_dev *gasket_dev;
-       const struct gasket_driver_desc *driver_desc;
        struct device *parent;
 
-       pr_debug("add PCI device %s\n", kobj_name);
+       dev_dbg(&pci_dev->dev, "add PCI gasket device\n");
 
        mutex_lock(&g_mutex);
-       internal_desc = lookup_internal_desc(pci_dev);
+       internal_desc = lookup_pci_internal_desc(pci_dev);
        mutex_unlock(&g_mutex);
        if (!internal_desc) {
                dev_err(&pci_dev->dev,
@@ -1449,29 +1485,15 @@ int gasket_pci_add_device(struct pci_dev *pci_dev,
                return -ENODEV;
        }
 
-       driver_desc = internal_desc->driver_desc;
-
        parent = &pci_dev->dev;
-       ret = gasket_alloc_dev(internal_desc, parent, &gasket_dev, kobj_name);
+       ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
        if (ret)
                return ret;
-       gasket_dev->pci_dev = pci_dev;
-       if (IS_ERR_OR_NULL(gasket_dev->dev_info.device)) {
-               pr_err("Cannot create %s device %s [ret = %ld]\n",
-                      driver_desc->name, gasket_dev->dev_info.name,
-                      PTR_ERR(gasket_dev->dev_info.device));
-               ret = -ENODEV;
-               goto fail1;
-       }
 
+       gasket_dev->pci_dev = pci_dev;
        ret = gasket_setup_pci(pci_dev, gasket_dev);
        if (ret)
-               goto fail2;
-
-       ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device,
-                                         gasket_dev);
-       if (ret)
-               goto fail3;
+               goto cleanup_pci;
 
        /*
         * Once we've created the mapping structures successfully, attempt to
@@ -1482,24 +1504,15 @@ int gasket_pci_add_device(struct pci_dev *pci_dev,
        if (ret) {
                dev_err(gasket_dev->dev,
                        "Cannot create sysfs pci link: %d\n", ret);
-               goto fail3;
+               goto cleanup_pci;
        }
-       ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
-                                         gasket_sysfs_generic_attrs);
-       if (ret)
-               goto fail4;
 
        *gasket_devp = gasket_dev;
        return 0;
 
-fail4:
-fail3:
-       gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
-fail2:
+cleanup_pci:
        gasket_cleanup_pci(gasket_dev);
-       device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
-fail1:
-       gasket_free_dev(gasket_dev);
+       __gasket_remove_device(internal_desc, gasket_dev);
        return ret;
 }
 EXPORT_SYMBOL(gasket_pci_add_device);
@@ -1510,18 +1523,15 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev)
        int i;
        struct gasket_internal_desc *internal_desc;
        struct gasket_dev *gasket_dev = NULL;
-       const struct gasket_driver_desc *driver_desc;
        /* Find the device desc. */
        mutex_lock(&g_mutex);
-       internal_desc = lookup_internal_desc(pci_dev);
+       internal_desc = lookup_pci_internal_desc(pci_dev);
        if (!internal_desc) {
                mutex_unlock(&g_mutex);
                return;
        }
        mutex_unlock(&g_mutex);
 
-       driver_desc = internal_desc->driver_desc;
-
        /* Now find the specific device */
        mutex_lock(&internal_desc->mutex);
        for (i = 0; i < GASKET_DEV_MAX; i++) {
@@ -1540,10 +1550,7 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev)
                internal_desc->driver_desc->name);
 
        gasket_cleanup_pci(gasket_dev);
-
-       gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
-       device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
-       gasket_free_dev(gasket_dev);
+       __gasket_remove_device(internal_desc, gasket_dev);
 }
 EXPORT_SYMBOL(gasket_pci_remove_device);
 
@@ -1791,7 +1798,6 @@ static int __init gasket_init(void)
 {
        int i;
 
-       pr_debug("%s\n", __func__);
        mutex_lock(&g_mutex);
        for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
                g_descs[i].driver_desc = NULL;
@@ -1804,13 +1810,8 @@ static int __init gasket_init(void)
        return 0;
 }
 
-static void __exit gasket_exit(void)
-{
-       pr_debug("%s\n", __func__);
-}
 MODULE_DESCRIPTION("Google Gasket driver framework");
 MODULE_VERSION(GASKET_FRAMEWORK_VERSION);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Rob Springer <rspringer@google.com>");
 module_init(gasket_init);
-module_exit(gasket_exit);
index 275fd0b345b6ea460e8a68e835b026211e622c0e..be44ac1e3118626795912b661a5ce060aa8f6974 100644 (file)
@@ -50,8 +50,6 @@ enum gasket_interrupt_packing {
 /* Type of the interrupt supported by the device. */
 enum gasket_interrupt_type {
        PCI_MSIX = 0,
-       PCI_MSI = 1,
-       PLATFORM_WIRE = 2,
 };
 
 /*
@@ -69,12 +67,6 @@ struct gasket_interrupt_desc {
        int packing;
 };
 
-/* Offsets to the wire interrupt handling registers */
-struct gasket_wire_interrupt_offsets {
-       u64 pending_bit_array;
-       u64 mask_array;
-};
-
 /*
  * This enum is used to identify memory regions being part of the physical
  * memory that belongs to a device.
@@ -231,7 +223,7 @@ struct gasket_coherent_buffer_desc {
 /* Coherent buffer structure. */
 struct gasket_coherent_buffer {
        /* Virtual base address. */
-       u8 __iomem *virt_base;
+       u8 *virt_base;
 
        /* Physical base address. */
        ulong phys_base;
@@ -384,9 +376,6 @@ struct gasket_driver_desc {
         */
        struct gasket_coherent_buffer_desc coherent_buffer_description;
 
-       /* Offset of wire interrupt registers. */
-       const struct gasket_wire_interrupt_offsets *wire_interrupt_offsets;
-
        /* Interrupt type. (One of gasket_interrupt_type). */
        int interrupt_type;
 
@@ -590,25 +579,25 @@ const char *gasket_num_name_lookup(uint num,
 static inline ulong gasket_dev_read_64(struct gasket_dev *gasket_dev, int bar,
                                       ulong location)
 {
-       return readq(&gasket_dev->bar_data[bar].virt_base[location]);
+       return readq_relaxed(&gasket_dev->bar_data[bar].virt_base[location]);
 }
 
 static inline void gasket_dev_write_64(struct gasket_dev *dev, u64 value,
                                       int bar, ulong location)
 {
-       writeq(value, &dev->bar_data[bar].virt_base[location]);
+       writeq_relaxed(value, &dev->bar_data[bar].virt_base[location]);
 }
 
 static inline void gasket_dev_write_32(struct gasket_dev *dev, u32 value,
                                       int bar, ulong location)
 {
-       writel(value, &dev->bar_data[bar].virt_base[location]);
+       writel_relaxed(value, &dev->bar_data[bar].virt_base[location]);
 }
 
 static inline u32 gasket_dev_read_32(struct gasket_dev *dev, int bar,
                                     ulong location)
 {
-       return readl(&dev->bar_data[bar].virt_base[location]);
+       return readl_relaxed(&dev->bar_data[bar].virt_base[location]);
 }
 
 static inline void gasket_read_modify_write_64(struct gasket_dev *dev, int bar,
index 1cfbc120f2284e75e21276460bd81f68bbfeb05b..49d47afad64fa40672a908adc003e534c354d8dd 100644 (file)
@@ -45,9 +45,6 @@ struct gasket_interrupt_data {
        /* The width of a single interrupt in a packed interrupt register. */
        int pack_width;
 
-       /* offset of wire interrupt registers */
-       const struct gasket_wire_interrupt_offsets *wire_interrupt_offsets;
-
        /*
         * Design-wise, these elements should be bundled together, but
         * pci_enable_msix's interface requires that they be managed
@@ -92,19 +89,6 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
 
        dev_dbg(gasket_dev->dev, "Running interrupt setup\n");
 
-       if (interrupt_data->type == PLATFORM_WIRE ||
-           interrupt_data->type == PCI_MSI) {
-               /* Nothing needs to be done for platform or PCI devices. */
-               return;
-       }
-
-       if (interrupt_data->type != PCI_MSIX) {
-               dev_dbg(gasket_dev->dev,
-                       "Cannot handle unsupported interrupt type %d\n",
-                       interrupt_data->type);
-               return;
-       }
-
        /* Setup the MSIX table. */
 
        for (i = 0; i < interrupt_data->num_interrupts; i++) {
@@ -157,9 +141,22 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
        }
 }
 
-static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
+static void
+gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
+                       int interrupt_index)
 {
        struct eventfd_ctx *ctx;
+
+       trace_gasket_interrupt_event(interrupt_data->name, interrupt_index);
+       ctx = interrupt_data->eventfd_ctxs[interrupt_index];
+       if (ctx)
+               eventfd_signal(ctx, 1);
+
+       ++(interrupt_data->interrupt_counts[interrupt_index]);
+}
+
+static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
+{
        struct gasket_interrupt_data *interrupt_data = dev_id;
        int interrupt = -1;
        int i;
@@ -175,14 +172,7 @@ static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
                pr_err("Received unknown irq %d\n", irq);
                return IRQ_HANDLED;
        }
-       trace_gasket_interrupt_event(interrupt_data->name, interrupt);
-
-       ctx = interrupt_data->eventfd_ctxs[interrupt];
-       if (ctx)
-               eventfd_signal(ctx, 1);
-
-       ++(interrupt_data->interrupt_counts[interrupt]);
-
+       gasket_handle_interrupt(interrupt_data, interrupt);
        return IRQ_HANDLED;
 }
 
@@ -192,6 +182,12 @@ gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data)
        int ret = 1;
        int i;
 
+       interrupt_data->msix_entries =
+               kcalloc(interrupt_data->num_interrupts,
+                       sizeof(struct msix_entry), GFP_KERNEL);
+       if (!interrupt_data->msix_entries)
+               return -ENOMEM;
+
        for (i = 0; i < interrupt_data->num_interrupts; i++) {
                interrupt_data->msix_entries[i].entry = i;
                interrupt_data->msix_entries[i].vector = 0;
@@ -319,54 +315,40 @@ static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = {
        GASKET_END_OF_ATTR_ARRAY,
 };
 
-int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
-                         int type,
-                         const struct gasket_interrupt_desc *interrupts,
-                         int num_interrupts, int pack_width, int bar_index,
-                         const struct gasket_wire_interrupt_offsets *wire_int_offsets)
+int gasket_interrupt_init(struct gasket_dev *gasket_dev)
 {
        int ret;
        struct gasket_interrupt_data *interrupt_data;
+       const struct gasket_driver_desc *driver_desc =
+               gasket_get_driver_desc(gasket_dev);
 
        interrupt_data = kzalloc(sizeof(struct gasket_interrupt_data),
                                 GFP_KERNEL);
        if (!interrupt_data)
                return -ENOMEM;
        gasket_dev->interrupt_data = interrupt_data;
-       interrupt_data->name = name;
-       interrupt_data->type = type;
+       interrupt_data->name = driver_desc->name;
+       interrupt_data->type = driver_desc->interrupt_type;
        interrupt_data->pci_dev = gasket_dev->pci_dev;
-       interrupt_data->num_interrupts = num_interrupts;
-       interrupt_data->interrupts = interrupts;
-       interrupt_data->interrupt_bar_index = bar_index;
-       interrupt_data->pack_width = pack_width;
+       interrupt_data->num_interrupts = driver_desc->num_interrupts;
+       interrupt_data->interrupts = driver_desc->interrupts;
+       interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index;
+       interrupt_data->pack_width = driver_desc->interrupt_pack_width;
        interrupt_data->num_configured = 0;
-       interrupt_data->wire_interrupt_offsets = wire_int_offsets;
 
-       /* Allocate all dynamic structures. */
-       interrupt_data->msix_entries = kcalloc(num_interrupts,
-                                              sizeof(struct msix_entry),
-                                              GFP_KERNEL);
-       if (!interrupt_data->msix_entries) {
-               kfree(interrupt_data);
-               return -ENOMEM;
-       }
-
-       interrupt_data->eventfd_ctxs = kcalloc(num_interrupts,
+       interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts,
                                               sizeof(struct eventfd_ctx *),
                                               GFP_KERNEL);
        if (!interrupt_data->eventfd_ctxs) {
-               kfree(interrupt_data->msix_entries);
                kfree(interrupt_data);
                return -ENOMEM;
        }
 
-       interrupt_data->interrupt_counts = kcalloc(num_interrupts,
+       interrupt_data->interrupt_counts = kcalloc(driver_desc->num_interrupts,
                                                   sizeof(ulong),
                                                   GFP_KERNEL);
        if (!interrupt_data->interrupt_counts) {
                kfree(interrupt_data->eventfd_ctxs);
-               kfree(interrupt_data->msix_entries);
                kfree(interrupt_data);
                return -ENOMEM;
        }
@@ -379,12 +361,7 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
                force_msix_interrupt_unmasking(gasket_dev);
                break;
 
-       case PCI_MSI:
-       case PLATFORM_WIRE:
        default:
-               dev_err(gasket_dev->dev,
-                       "Cannot handle unsupported interrupt type %d\n",
-                       interrupt_data->type);
                ret = -EINVAL;
        }
 
@@ -417,6 +394,7 @@ gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data)
        if (interrupt_data->msix_configured)
                pci_disable_msix(interrupt_data->pci_dev);
        interrupt_data->msix_configured = 0;
+       kfree(interrupt_data->msix_entries);
 }
 
 int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
@@ -438,20 +416,16 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
                force_msix_interrupt_unmasking(gasket_dev);
                break;
 
-       case PCI_MSI:
-       case PLATFORM_WIRE:
        default:
-               dev_dbg(gasket_dev->dev,
-                       "Cannot handle unsupported interrupt type %d\n",
-                       gasket_dev->interrupt_data->type);
                ret = -EINVAL;
        }
 
        if (ret) {
-               /* Failing to setup MSIx will cause the device
+               /* Failing to setup interrupts will cause the device
                 * to report GASKET_STATUS_LAMED, but is not fatal.
                 */
-               dev_warn(gasket_dev->dev, "Couldn't init msix: %d\n", ret);
+               dev_warn(gasket_dev->dev, "Couldn't reinit interrupts: %d\n",
+                        ret);
                return 0;
        }
 
@@ -487,17 +461,12 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev)
                gasket_interrupt_msix_cleanup(interrupt_data);
                break;
 
-       case PCI_MSI:
-       case PLATFORM_WIRE:
        default:
-               dev_dbg(gasket_dev->dev,
-                       "Cannot handle unsupported interrupt type %d\n",
-                       interrupt_data->type);
+               break;
        }
 
        kfree(interrupt_data->interrupt_counts);
        kfree(interrupt_data->eventfd_ctxs);
-       kfree(interrupt_data->msix_entries);
        kfree(interrupt_data);
        gasket_dev->interrupt_data = NULL;
 }
@@ -509,11 +478,6 @@ int gasket_interrupt_system_status(struct gasket_dev *gasket_dev)
                return GASKET_STATUS_DEAD;
        }
 
-       if (!gasket_dev->interrupt_data->msix_configured) {
-               dev_dbg(gasket_dev->dev, "Interrupt not initialized\n");
-               return GASKET_STATUS_LAMED;
-       }
-
        if (gasket_dev->interrupt_data->num_configured !=
                gasket_dev->interrupt_data->num_interrupts) {
                dev_dbg(gasket_dev->dev,
index 835af439e96a9cb7a437e5fd0fb0b48dfc1d1c26..85526a1374a1af10ac178e62cdff6fc147d49016 100644 (file)
@@ -24,30 +24,8 @@ struct gasket_interrupt_data;
 /*
  * Initialize the interrupt module.
  * @gasket_dev: The Gasket device structure for the device to be initted.
- * @type: Type of the interrupt. (See gasket_interrupt_type).
- * @name: The name to associate with these interrupts.
- * @interrupts: An array of all interrupt descriptions for this device.
- * @num_interrupts: The length of the @interrupts array.
- * @pack_width: The width, in bits, of a single field in a packed interrupt reg.
- * @bar_index: The bar containing all interrupt registers.
- *
- * Allocates and initializes data to track interrupt state for a device.
- * After this call, no interrupts will be configured/delivered; call
- * gasket_interrupt_set_vector[_packed] to associate each interrupt with an
- * __iomem location, then gasket_interrupt_set_eventfd to associate an eventfd
- * with an interrupt.
- *
- * If num_interrupts interrupts are not available, this call will return a
- * negative error code. In that case, gasket_interrupt_cleanup should still be
- * called. Returns 0 on success (which can include a device where interrupts
- * are not possible to set up, but is otherwise OK; that device will report
- * status LAMED.)
  */
-int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
-                         int type,
-                         const struct gasket_interrupt_desc *interrupts,
-                         int num_interrupts, int pack_width, int bar_index,
-                         const struct gasket_wire_interrupt_offsets *wire_int_offsets);
+int gasket_interrupt_init(struct gasket_dev *gasket_dev);
 
 /*
  * Clean up a device's interrupt structure.
index d4c5f8aa7dd34eb317a1c483a7295d813555e144..b7d460cf15fbc1ccf935801d9d4437f7297203ee 100644 (file)
  *
  * This file assumes 4kB pages throughout; can be factored out when necessary.
  *
- * Address format is as follows:
+ * There is a configurable number of page table entries, as well as a
+ * configurable bit index for the extended address flag. Both of these are
+ * specified in gasket_page_table_init through the page_table_config parameter.
+ *
+ * The following example assumes:
+ *   page_table_config->total_entries = 8192
+ *   page_table_config->extended_bit = 63
+ *
+ * Address format:
  * Simple addresses - those whose containing pages are directly placed in the
  * device's address translation registers - are laid out as:
- * [ 63 - 40: Unused | 39 - 28: 0 | 27 - 12: page index | 11 - 0: page offset ]
+ * [ 63 - 25: 0 | 24 - 12: page index | 11 - 0: page offset ]
  * page index:  The index of the containing page in the device's address
  *              translation registers.
  * page offset: The index of the address into the containing page.
@@ -21,7 +29,7 @@
  * Extended address - those whose containing pages are contained in a second-
  * level page table whose address is present in the device's address translation
  * registers - are laid out as:
- * [ 63 - 40: Unused | 39: flag | 38 - 37: 0 | 36 - 21: dev/level 0 index |
+ * [ 63: flag | 62 - 34: 0 | 33 - 21: dev/level 0 index |
  *   20 - 12: host/level 1 index | 11 - 0: page offset ]
  * flag:        Marker indicating that this is an extended address. Always 1.
  * dev index:   The index of the first-level page in the device's extended
@@ -103,12 +111,6 @@ struct gasket_page_table_entry {
        /* The status of this entry/slot: free or in use. */
        enum pte_status status;
 
-       /* Address of the page in DMA space. */
-       dma_addr_t dma_addr;
-
-       /* Linux page descriptor for the page described by this structure. */
-       struct page *page;
-
        /*
         * Index for alignment into host vaddrs.
         * When a user specifies a host address for a mapping, that address may
@@ -119,6 +121,12 @@ struct gasket_page_table_entry {
         */
        int offset;
 
+       /* Address of the page in DMA space. */
+       dma_addr_t dma_addr;
+
+       /* Linux page descriptor for the page described by this structure. */
+       struct page *page;
+
        /*
         * If this is an extended and first-level entry, sublevel points
         * to the second-level entries underneath this entry.
@@ -317,12 +325,10 @@ static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl,
 
        /* Release the page table from the device */
        writeq(0, slot);
-       /* Force sync around the address release. */
-       mb();
 
        if (pte->dma_addr)
                dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE,
-                              DMA_BIDIRECTIONAL);
+                              DMA_TO_DEVICE);
 
        vfree(pte->sublevel);
 
@@ -435,6 +441,19 @@ static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
        return min <= host_addr && host_addr < max;
 }
 
+/* Safely return a page to the OS. */
+static bool gasket_release_page(struct page *page)
+{
+       if (!page)
+               return false;
+
+       if (!PageReserved(page))
+               SetPageDirty(page);
+       put_page(page);
+
+       return true;
+}
+
 /*
  * Get and map last level page table buffers.
  *
@@ -458,7 +477,6 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
        for (i = 0; i < num_pages; i++) {
                page_addr = host_addr + i * PAGE_SIZE;
                offset = page_addr & (PAGE_SIZE - 1);
-               dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i);
                if (is_coherent(pg_tbl, host_addr)) {
                        u64 off =
                                (u64)host_addr -
@@ -487,24 +505,16 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
                        ptes[i].dma_addr =
                                dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE,
                                             DMA_BIDIRECTIONAL);
-                       dev_dbg(pg_tbl->device,
-                               "%s i %d pte %p pfn %p -> mapped %llx\n",
-                               __func__, i, &ptes[i],
-                               (void *)page_to_pfn(page),
-                               (unsigned long long)ptes[i].dma_addr);
-
-                       if (ptes[i].dma_addr == -1) {
-                               dev_dbg(pg_tbl->device,
-                                       "%s i %d -> fail to map page %llx "
-                                       "[pfn %p ohys %p]\n",
-                                       __func__, i,
-                                       (unsigned long long)ptes[i].dma_addr,
-                                       (void *)page_to_pfn(page),
-                                       (void *)page_to_phys(page));
-                               return -1;
+
+                       if (dma_mapping_error(pg_tbl->device,
+                                             ptes[i].dma_addr)) {
+                               if (gasket_release_page(ptes[i].page))
+                                       --pg_tbl->num_active_pages;
+
+                               memset(&ptes[i], 0,
+                                      sizeof(struct gasket_page_table_entry));
+                               return -EINVAL;
                        }
-                       /* Wait until the page is mapped. */
-                       mb();
                }
 
                /* Make the DMA-space address available to the device. */
@@ -545,7 +555,7 @@ static ulong gasket_extended_lvl0_page_idx(struct gasket_page_table *pg_tbl,
                                           ulong dev_addr)
 {
        return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) &
-              ((1 << GASKET_EXTENDED_LVL0_WIDTH) - 1);
+               (pg_tbl->config.total_entries - 1);
 }
 
 /*
@@ -574,19 +584,6 @@ static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl,
        return 0;
 }
 
-/* Safely return a page to the OS. */
-static bool gasket_release_page(struct page *page)
-{
-       if (!page)
-               return false;
-
-       if (!PageReserved(page))
-               SetPageDirty(page);
-       put_page(page);
-
-       return true;
-}
-
 /*
  * Unmap and release mapped pages.
  * The page table mutex must be held by the caller.
@@ -603,23 +600,23 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl,
         */
        for (i = 0; i < num_pages; i++) {
                /* release the address from the device, */
-               if (is_simple_mapping || ptes[i].status == PTE_INUSE)
+               if (is_simple_mapping || ptes[i].status == PTE_INUSE) {
                        writeq(0, &slots[i]);
-               else
+               } else {
                        ((u64 __force *)slots)[i] = 0;
-               /* Force sync around the address release. */
-               mb();
+                       /* sync above PTE update before updating mappings */
+                       wmb();
+               }
 
                /* release the address from the driver, */
                if (ptes[i].status == PTE_INUSE) {
-                       if (ptes[i].dma_addr) {
+                       if (ptes[i].page && ptes[i].dma_addr) {
                                dma_unmap_page(pg_tbl->device, ptes[i].dma_addr,
-                                              PAGE_SIZE, DMA_FROM_DEVICE);
+                                              PAGE_SIZE, DMA_BIDIRECTIONAL);
                        }
                        if (gasket_release_page(ptes[i].page))
                                --pg_tbl->num_active_pages;
                }
-               ptes[i].status = PTE_FREE;
 
                /* and clear the PTE. */
                memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
@@ -684,38 +681,21 @@ static inline bool gasket_addr_is_simple(struct gasket_page_table *pg_tbl,
  * Convert (simple, page, offset) into a device address.
  * Examples:
  * Simple page 0, offset 32:
- *  Input (0, 0, 32), Output 0x20
+ *  Input (1, 0, 32), Output 0x20
  * Simple page 1000, offset 511:
- *  Input (0, 1000, 512), Output 0x3E81FF
+ *  Input (1, 1000, 511), Output 0x3E81FF
  * Extended page 0, offset 32:
  *  Input (0, 0, 32), Output 0x8000000020
  * Extended page 1000, offset 511:
- *  Input (1, 1000, 512), Output 0x8003E81FF
+ *  Input (0, 1000, 511), Output 0x8003E81FF
  */
 static ulong gasket_components_to_dev_address(struct gasket_page_table *pg_tbl,
                                              int is_simple, uint page_index,
                                              uint offset)
 {
-       ulong lvl0_index, lvl1_index;
-
-       if (is_simple) {
-               /* Return simple addresses directly. */
-               lvl0_index = page_index & (pg_tbl->config.total_entries - 1);
-               return (lvl0_index << GASKET_SIMPLE_PAGE_SHIFT) | offset;
-       }
+       ulong dev_addr = (page_index << GASKET_SIMPLE_PAGE_SHIFT) | offset;
 
-       /*
-        * This could be compressed into fewer statements, but
-        * A) the compiler should optimize it
-        * B) this is not slow
-        * C) this is an uncommon operation
-        * D) this is actually readable this way.
-        */
-       lvl0_index = page_index / GASKET_PAGES_PER_SUBTABLE;
-       lvl1_index = page_index & (GASKET_PAGES_PER_SUBTABLE - 1);
-       return (pg_tbl)->extended_flag |
-              (lvl0_index << GASKET_EXTENDED_LVL0_SHIFT) |
-              (lvl1_index << GASKET_EXTENDED_LVL1_SHIFT) | offset;
+       return is_simple ? dev_addr : (pg_tbl->extended_flag | dev_addr);
 }
 
 /*
@@ -896,9 +876,13 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl,
 
        /* Map the page into DMA space. */
        pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE,
-                                    DMA_BIDIRECTIONAL);
-       /* Wait until the page is mapped. */
-       mb();
+                                    DMA_TO_DEVICE);
+       if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) {
+               free_page(page_addr);
+               vfree(pte->sublevel);
+               memset(pte, 0, sizeof(struct gasket_page_table_entry));
+               return -ENOMEM;
+       }
 
        /* make the addresses available to the device */
        dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG;
@@ -1047,11 +1031,6 @@ int gasket_page_table_map(struct gasket_page_table *pg_tbl, ulong host_addr,
        }
 
        mutex_unlock(&pg_tbl->mutex);
-
-       dev_dbg(pg_tbl->device,
-               "%s done: ha %llx daddr %llx num %d, ret %d\n",
-               __func__, (unsigned long long)host_addr,
-               (unsigned long long)dev_addr, num_pages, ret);
        return ret;
 }
 EXPORT_SYMBOL(gasket_page_table_map);
@@ -1151,7 +1130,7 @@ fail:
        *ppage = NULL;
        *poffset = 0;
        mutex_unlock(&pg_tbl->mutex);
-       return -1;
+       return -EINVAL;
 }
 
 /* See gasket_page_table.h for description. */
@@ -1291,7 +1270,7 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
                return -EINVAL;
 
        mem = dma_alloc_coherent(gasket_get_device(gasket_dev),
-                                num_pages * PAGE_SIZE, &handle, 0);
+                                num_pages * PAGE_SIZE, &handle, GFP_KERNEL);
        if (!mem)
                goto nomem;
 
@@ -1303,7 +1282,6 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
                        GFP_KERNEL);
        if (!gasket_dev->page_table[index]->coherent_pages)
                goto nomem;
-       *dma_address = 0;
 
        gasket_dev->coherent_buffer.length_bytes =
                PAGE_SIZE * (num_pages);
@@ -1318,20 +1296,19 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
                        (u64)mem + j * PAGE_SIZE;
        }
 
-       if (*dma_address == 0)
-               goto nomem;
        return 0;
 
 nomem:
        if (mem) {
                dma_free_coherent(gasket_get_device(gasket_dev),
                                  num_pages * PAGE_SIZE, mem, handle);
+               gasket_dev->coherent_buffer.length_bytes = 0;
+               gasket_dev->coherent_buffer.virt_base = NULL;
+               gasket_dev->coherent_buffer.phys_base = 0;
        }
 
-       if (gasket_dev->page_table[index]->coherent_pages) {
-               kfree(gasket_dev->page_table[index]->coherent_pages);
-               gasket_dev->page_table[index]->coherent_pages = NULL;
-       }
+       kfree(gasket_dev->page_table[index]->coherent_pages);
+       gasket_dev->page_table[index]->coherent_pages = NULL;
        gasket_dev->page_table[index]->num_coherent_pages = 0;
        return -ENOMEM;
 }
@@ -1359,6 +1336,11 @@ int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
                gasket_dev->coherent_buffer.virt_base = NULL;
                gasket_dev->coherent_buffer.phys_base = 0;
        }
+
+       kfree(gasket_dev->page_table[index]->coherent_pages);
+       gasket_dev->page_table[index]->coherent_pages = NULL;
+       gasket_dev->page_table[index]->num_coherent_pages = 0;
+
        return 0;
 }
 
index f32eaf89e056bf7406ef199b9af130709ab7c534..151e8edd28ea63e6ec0cc4f396d1704848912781 100644 (file)
@@ -152,8 +152,8 @@ void gasket_sysfs_put_device_data(struct device *device,
  * Returns the Gasket sysfs attribute associated with the kernel device
  * attribute and device structure itself. Upon success, this call will take a
  * reference to internal sysfs data that must be released with a call to
- * gasket_sysfs_get_device_data. While this reference is held, the underlying
- * device sysfs information/structure will remain valid/will not be deleted.
+ * gasket_sysfs_put_attr. While this reference is held, the underlying device
+ * sysfs information/structure will remain valid/will not be deleted.
  */
 struct gasket_sysfs_attribute *
 gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
index 35acd55ca5ab7bd80682386d4f6b0beb9d851014..08746c85dea6dbd372f987eb376813d2207e75aa 100644 (file)
@@ -1087,7 +1087,6 @@ static const struct of_device_id greybus_asoc_machine_of_match[]  = {
 static struct platform_driver gbaudio_codec_driver = {
        .driver = {
                .name = "apb-dummy-codec",
-               .owner = THIS_MODULE,
 #ifdef CONFIG_PM
                .pm = &gbaudio_codec_pm_ops,
 #endif
index 42f6f3de967c4b0451b8fb2130037543a7496ebe..7080294f705cfcef5bfea44f52fdafd9da6a2d3e 100644 (file)
@@ -97,7 +97,6 @@ struct gb_loopback {
        u32 timeout_min;
        u32 timeout_max;
        u32 outstanding_operations_max;
-       u32 lbid;
        u64 elapsed_nsecs;
        u32 apbridge_latency_ts;
        u32 gbphy_latency_ts;
@@ -1014,16 +1013,9 @@ static int gb_loopback_bus_id_compare(void *priv, struct list_head *lha,
 
 static void gb_loopback_insert_id(struct gb_loopback *gb)
 {
-       struct gb_loopback *gb_list;
-       u32 new_lbid = 0;
-
        /* perform an insertion sort */
        list_add_tail(&gb->entry, &gb_dev.list);
        list_sort(NULL, &gb_dev.list, gb_loopback_bus_id_compare);
-       list_for_each_entry(gb_list, &gb_dev.list, entry) {
-               gb_list->lbid = 1 << new_lbid;
-               new_lbid++;
-       }
 }
 
 #define DEBUGFS_NAMELEN 32
index 845b08dc4696e447cf6215d7972ee0d00be2a320..070a510cbe7ca4c4e81401a6fb36660dc6f4dbb1 100644 (file)
@@ -79,7 +79,7 @@ Here is the summary of the available options:
    -t     must be one of the test names - sink, transfer or ping
    -i     iteration count - the number of iterations to run the test over
  Optional arguments
-   -S     sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/
+   -S     sysfs location - location for greybus 'endo' entries default /sys/bus/greybus/devices/
    -D     debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/
    -s     size of data packet to send during test - defaults to zero
    -m     mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc
index b82e2befe9355338295d3a3c237b0c5594c29cd5..2fa88092514d19646ed0e8e80e4444088d89b42a 100644 (file)
@@ -192,7 +192,7 @@ void usage(void)
        "   -t     must be one of the test names - sink, transfer or ping\n"
        "   -i     iteration count - the number of iterations to run the test over\n"
        " Optional arguments\n"
-       "   -S     sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/\n"
+       "   -S     sysfs location - location for greybus 'endo' entries default /sys/bus/greybus/devices/\n"
        "   -D     debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/\n"
        "   -s     size of data packet to send during test - defaults to zero\n"
        "   -m     mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc\n"
index e17efb03bac02229c439fa6fbf07558061286cf8..9d3062a0746059141144b4239a377e77d253868a 100644 (file)
@@ -11,7 +11,7 @@ config AD7606
        select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Analog Devices:
-         ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC).
+         ad7605-4, ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC).
 
          To compile this driver as a module, choose M here: the
          module will be called ad7606.
index df0499fc4802fb4cb7ac8a17950dcac4266e1f1f..acdbc07fd2592c03084a0c6fb6e89aee073f58fd 100644 (file)
@@ -761,6 +761,6 @@ static struct spi_driver ad7192_driver = {
 };
 module_spi_driver(ad7192_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7190, AD7192, AD7193, AD7195 ADC");
 MODULE_LICENSE("GPL v2");
index b736275c10f53532b0d27d445711dec1bda6de67..58420dcb406d9fb85cf54032e8baf14da5baf754 100644 (file)
@@ -987,6 +987,6 @@ static struct spi_driver ad7280_driver = {
 };
 module_spi_driver(ad7280_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7280A");
 MODULE_LICENSE("GPL v2");
index b7810b1aad0716171331f104d3844ac4f959c4a4..048c205b979ecbceb5a325e60d478d7c3c1561fb 100644 (file)
 
 #include "ad7606.h"
 
-/* Scales are computed as 2.5/2**16 and 5/2**16 respectively */
+/*
+ * Scales are computed as 5000/32768 and 10000/32768 respectively,
+ * so that when applied to the raw values they provide mV values
+ */
 static const unsigned int scale_avail[2][2] = {
-       {0, 38147}, {0, 76294}
+       {0, 152588}, {0, 305176}
 };
 
 static int ad7606_reset(struct ad7606_state *st)
@@ -271,7 +274,7 @@ static const struct attribute_group ad7606_attribute_group_range = {
        .attrs = ad7606_attributes_range,
 };
 
-#define AD7606_CHANNEL(num)                                    \
+#define AD760X_CHANNEL(num, mask)                              \
        {                                                       \
                .type = IIO_VOLTAGE,                            \
                .indexed = 1,                                   \
@@ -279,8 +282,7 @@ static const struct attribute_group ad7606_attribute_group_range = {
                .address = num,                                 \
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
-               .info_mask_shared_by_all =                      \
-                       BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),  \
+               .info_mask_shared_by_all = mask,                \
                .scan_index = num,                              \
                .scan_type = {                                  \
                        .sign = 's',                            \
@@ -290,6 +292,20 @@ static const struct attribute_group ad7606_attribute_group_range = {
                },                                              \
        }
 
+#define AD7605_CHANNEL(num)    \
+       AD760X_CHANNEL(num, 0)
+
+#define AD7606_CHANNEL(num)    \
+       AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO))
+
+static const struct iio_chan_spec ad7605_channels[] = {
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+       AD7605_CHANNEL(0),
+       AD7605_CHANNEL(1),
+       AD7605_CHANNEL(2),
+       AD7605_CHANNEL(3),
+};
+
 static const struct iio_chan_spec ad7606_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(8),
        AD7606_CHANNEL(0),
@@ -306,17 +322,24 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
        /*
         * More devices added in future
         */
+       [ID_AD7605_4] = {
+               .channels = ad7605_channels,
+               .num_channels = 5,
+       },
        [ID_AD7606_8] = {
                .channels = ad7606_channels,
                .num_channels = 9,
+               .has_oversampling = true,
        },
        [ID_AD7606_6] = {
                .channels = ad7606_channels,
                .num_channels = 7,
+               .has_oversampling = true,
        },
        [ID_AD7606_4] = {
                .channels = ad7606_channels,
                .num_channels = 5,
+               .has_oversampling = true,
        },
 };
 
@@ -347,6 +370,9 @@ static int ad7606_request_gpios(struct ad7606_state *st)
        if (IS_ERR(st->gpio_frstdata))
                return PTR_ERR(st->gpio_frstdata);
 
+       if (!st->chip_info->has_oversampling)
+               return 0;
+
        st->gpio_os = devm_gpiod_get_array_optional(dev, "oversampling-ratio",
                        GPIOD_OUT_LOW);
        return PTR_ERR_OR_ZERO(st->gpio_os);
@@ -425,12 +451,12 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
                return ret;
        }
 
+       st->chip_info = &ad7606_chip_info_tbl[id];
+
        ret = ad7606_request_gpios(st);
        if (ret)
                goto error_disable_reg;
 
-       st->chip_info = &ad7606_chip_info_tbl[id];
-
        indio_dev->dev.parent = dev;
        if (st->gpio_os) {
                if (st->gpio_range)
@@ -532,6 +558,6 @@ EXPORT_SYMBOL_GPL(ad7606_pm_ops);
 
 #endif
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
 MODULE_LICENSE("GPL v2");
index 9716ee9d94a75823995a071c16e4418e86aaa59c..86188054b60bb073aab53c2a71e84658e373b94b 100644 (file)
 
 /**
  * struct ad7606_chip_info - chip specific information
- * @name:              identification string for chip
  * @channels:          channel specification
  * @num_channels:      number of channels
- * @lock               protect sensor state
+ * @has_oversampling:   whether the device has oversampling support
  */
 
 struct ad7606_chip_info {
        const struct iio_chan_spec      *channels;
        unsigned int                    num_channels;
+       bool                            has_oversampling;
 };
 
 /**
  * struct ad7606_state - driver instance specific data
- * @lock               protect sensor state
+ * @dev                pointer to kernel device
+ * @chip_info          entry in the table of chips that describes this device
+ * @reg                regulator info for the the power supply of the device
+ * @poll_work          work struct for continuously reading data from the device
+ *                     into an IIO triggered buffer
+ * @wq_data_avail      wait queue struct for buffer mode
+ * @bops               bus operations (SPI or parallel)
+ * @range              voltage range selection, selects which scale to apply
+ * @oversampling       oversampling selection
+ * @done               marks whether reading data is done
+ * @base_address       address from where to read data in parallel operation
+ * @lock               protect sensor state from concurrent accesses to GPIOs
+ * @gpio_convst        GPIO descriptor for conversion start signal (CONVST)
+ * @gpio_reset         GPIO descriptor for device hard-reset
+ * @gpio_range         GPIO descriptor for range selection
+ * @gpio_standby       GPIO descriptor for stand-by signal (STBY),
+ *                     controls power-down mode of device
+ * @gpio_frstdata      GPIO descriptor for reading from device when data
+ *                     is being read on the first channel
+ * @gpio_os            GPIO descriptors to control oversampling on the device
+ * @data               buffer for reading data from the device
  */
 
 struct ad7606_state {
@@ -55,6 +75,10 @@ struct ad7606_state {
        unsigned short                  data[12] ____cacheline_aligned;
 };
 
+/**
+ * struct ad7606_bus_ops - driver bus operations
+ * @read_block         function pointer for reading blocks of data
+ */
 struct ad7606_bus_ops {
        /* more methods added in future? */
        int (*read_block)(struct device *dev, int num, void *data);
@@ -66,6 +90,7 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
 int ad7606_remove(struct device *dev, int irq);
 
 enum ad7606_supported_device_ids {
+       ID_AD7605_4,
        ID_AD7606_8,
        ID_AD7606_6,
        ID_AD7606_4
index a34c2a1d537326d4a5054a2b85a1414eea15c2f1..8bd86e727b02ecb695cc30b22c7d086bfc3dcdaf 100644 (file)
@@ -79,6 +79,9 @@ static int ad7606_par_remove(struct platform_device *pdev)
 
 static const struct platform_device_id ad7606_driver_ids[] = {
        {
+               .name           = "ad7605-4",
+               .driver_data    = ID_AD7605_4,
+       }, {
                .name           = "ad7606-8",
                .driver_data    = ID_AD7606_8,
        }, {
@@ -105,6 +108,6 @@ static struct platform_driver ad7606_driver = {
 
 module_platform_driver(ad7606_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
 MODULE_LICENSE("GPL v2");
index c9b1f26685f49fb0a2bf24e6de9fb4630d3dc659..b76ca5a8c0590bc2ba62a0c12c6fa58caf916b02 100644 (file)
@@ -55,6 +55,7 @@ static int ad7606_spi_remove(struct spi_device *spi)
 }
 
 static const struct spi_device_id ad7606_id[] = {
+       {"ad7605-4", ID_AD7605_4},
        {"ad7606-8", ID_AD7606_8},
        {"ad7606-6", ID_AD7606_6},
        {"ad7606-4", ID_AD7606_4},
@@ -73,6 +74,6 @@ static struct spi_driver ad7606_driver = {
 };
 module_spi_driver(ad7606_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
 MODULE_LICENSE("GPL v2");
index 16d72072c076cbf08ec40daeccb81aa303960b81..b67412db0318a5a312a4993b31209568156f7f83 100644 (file)
@@ -260,6 +260,6 @@ static struct spi_driver ad7780_driver = {
 };
 module_spi_driver(ad7780_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7780 and similar ADCs");
 MODULE_LICENSE("GPL v2");
index f53612a6461d653ce4858a03acbe8554f555bbd1..0eb28fea876ea024fa535fa5aef955c6275687e6 100644 (file)
@@ -758,6 +758,6 @@ static struct i2c_driver ad7746_driver = {
 };
 module_i2c_driver(ad7746_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7746/5/7 capacitive sensor driver");
 MODULE_LICENSE("GPL v2");
index c73eff1f8d73d0bd854c74920d38b121163c44e5..a3ce504277244ea1656ff38cc3792c511fc98ded 100644 (file)
@@ -454,6 +454,6 @@ static struct spi_driver ad9832_driver = {
 };
 module_spi_driver(ad9832_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS");
 MODULE_LICENSE("GPL v2");
index 4c6d4043903e6c1f51a4e95b704b5ee033aef787..1e977014fe5f8ec8090a6daa37b378265f9bb42d 100644 (file)
@@ -526,6 +526,6 @@ static struct spi_driver ad9834_driver = {
 };
 module_spi_driver(ad9834_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS");
 MODULE_LICENSE("GPL v2");
index 14df89510396c29b868035388504d69c33b0426f..a2370dd1e1a8fd51f849f4f96a37a94070b48eb1 100644 (file)
@@ -797,6 +797,6 @@ static struct i2c_driver ad5933_driver = {
 };
 module_i2c_driver(ad5933_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD5933 Impedance Conv. Network Analyzer");
 MODULE_LICENSE("GPL v2");
index 0e554e3359b5c425fe13a64cb381d2bdf85a7a69..065bce193fac75e89372c2a036321b9de6b452a6 100644 (file)
@@ -191,7 +191,6 @@ static u8 read_ie(unsigned char *bp, u8 max, u8 *body)
        return size;
 }
 
-
 static
 int get_ap_information(struct ks_wlan_private *priv, struct ap_info *ap_info,
                       struct local_ap *ap)
@@ -1023,8 +1022,8 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb)
            priv->wpa.mic_failure.stop) {
                if (netif_queue_stopped(priv->net_dev))
                        netif_wake_queue(priv->net_dev);
-               if (skb)
-                       dev_kfree_skb(skb);
+
+               dev_kfree_skb(skb);
 
                return 0;
        }
index db5cf67047ad7c17a45071c27e25028a3aa21931..b3620a8f2d9f7a91051a544bb072576a3252afb4 100644 (file)
@@ -31,6 +31,8 @@ source "drivers/staging/media/mt9t031/Kconfig"
 
 source "drivers/staging/media/omap4iss/Kconfig"
 
+source "drivers/staging/media/sunxi/Kconfig"
+
 source "drivers/staging/media/tegra-vde/Kconfig"
 
 source "drivers/staging/media/zoran/Kconfig"
index 503fbe47fa581d5e3eafe67f4af1621324edf280..42948f8055482fc6fa911a8600f017aea29dd35e 100644 (file)
@@ -5,5 +5,6 @@ obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074/
 obj-$(CONFIG_SOC_CAMERA_MT9T031)       += mt9t031/
 obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
 obj-$(CONFIG_VIDEO_OMAP4)      += omap4iss/
+obj-$(CONFIG_VIDEO_SUNXI)      += sunxi/
 obj-$(CONFIG_TEGRA_VDE)                += tegra-vde/
 obj-$(CONFIG_VIDEO_ZORAN)      += zoran/
index a90b2eb112f9a4724610dcc98d9ddaa0a491c66c..874d290f962268987bdd39749c6371b7837712b6 100644 (file)
@@ -2304,9 +2304,9 @@ static int bcm2048_vidioc_querycap(struct file *file, void *priv,
 {
        struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
 
-       strlcpy(capability->driver, BCM2048_DRIVER_NAME,
+       strscpy(capability->driver, BCM2048_DRIVER_NAME,
                sizeof(capability->driver));
-       strlcpy(capability->card, BCM2048_DRIVER_CARD,
+       strscpy(capability->card, BCM2048_DRIVER_CARD,
                sizeof(capability->card));
        snprintf(capability->bus_info, 32, "I2C: 0x%X", bdev->client->addr);
        capability->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
index 95942768639cdeb7108cb569f238f9b10b2bf324..dcfeac8184512f1934e3cb2e2c3594da1e9bab66 100644 (file)
@@ -695,21 +695,21 @@ static int ipipe_get_gamma_params(struct vpfe_ipipe_device *ipipe, void *param)
 
        if (!gamma->bypass_r) {
                dev_err(dev,
-                       "ipipe_get_gamma_params: table ptr empty for R\n");
+                       "%s: table ptr empty for R\n", __func__);
                return -EINVAL;
        }
        memcpy(gamma_param->table_r, gamma->table_r,
               (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
 
        if (!gamma->bypass_g) {
-               dev_err(dev, "ipipe_get_gamma_params: table ptr empty for G\n");
+               dev_err(dev, "%s: table ptr empty for G\n", __func__);
                return -EINVAL;
        }
        memcpy(gamma_param->table_g, gamma->table_g,
               (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
 
        if (!gamma->bypass_b) {
-               dev_err(dev, "ipipe_get_gamma_params: table ptr empty for B\n");
+               dev_err(dev, "%s: table ptr empty for B\n", __func__);
                return -EINVAL;
        }
        memcpy(gamma_param->table_b, gamma->table_b,
@@ -1801,7 +1801,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
 
        v4l2_subdev_init(sd, &ipipe_v4l2_ops);
        sd->internal_ops = &ipipe_v4l2_internal_ops;
-       strlcpy(sd->name, "DAVINCI IPIPE", sizeof(sd->name));
+       strscpy(sd->name, "DAVINCI IPIPE", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for davinci subdevs */
        v4l2_set_subdevdata(sd, ipipe);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index 11c9edfbdbe39139a12637d4bece8fe1c47c17e9..a53231b08d30ee390e9565cfc52c185023692778 100644 (file)
@@ -1020,7 +1020,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
        v4l2_subdev_init(sd, &ipipeif_v4l2_ops);
 
        sd->internal_ops = &ipipeif_v4l2_internal_ops;
-       strlcpy(sd->name, "DAVINCI IPIPEIF", sizeof(sd->name));
+       strscpy(sd->name, "DAVINCI IPIPEIF", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for davinci subdevs */
 
        v4l2_set_subdevdata(sd, ipipeif);
index 745e33fa6beaec740144984c7e8804a1420e7367..39eb0819ab4e2c670c25e20e2ce3a2a786c70014 100644 (file)
@@ -2038,7 +2038,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
        isif->video_out.ops = &isif_video_ops;
        v4l2_subdev_init(sd, &isif_v4l2_ops);
        sd->internal_ops = &isif_v4l2_internal_ops;
-       strlcpy(sd->name, "DAVINCI ISIF", sizeof(sd->name));
+       strscpy(sd->name, "DAVINCI ISIF", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for davinci subdevs */
        v4l2_set_subdevdata(sd, isif);
        sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
index 2b797474a34463d9743ed1a148f7a004c56c6a62..72bbbc34d18cc58630003788825b2aa898a0bcc2 100644 (file)
@@ -499,7 +499,7 @@ resizer_configure_in_continuous_mode(struct vpfe_resizer_device *resizer)
        configure_resizer_out_params(resizer, RSZ_A,
                                     &cont_config->output1, 1, 0);
        param->rsz_en[RSZ_B] = DISABLE;
-       param->oper_mode = RESIZER_MODE_CONTINIOUS;
+       param->oper_mode = RESIZER_MODE_CONTINUOUS;
 
        if (resizer->resizer_b.output == RESIZER_OUTPUT_MEMORY) {
                struct v4l2_mbus_framefmt *outformat2;
@@ -1903,7 +1903,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 
        v4l2_subdev_init(sd, &resizer_v4l2_ops);
        sd->internal_ops = &resizer_v4l2_internal_ops;
-       strlcpy(sd->name, "DAVINCI RESIZER CROP", sizeof(sd->name));
+       strscpy(sd->name, "DAVINCI RESIZER CROP", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for davinci subdevs */
        v4l2_set_subdevdata(sd, vpfe_rsz);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1927,7 +1927,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 
        v4l2_subdev_init(sd, &resizer_v4l2_ops);
        sd->internal_ops = &resizer_v4l2_internal_ops;
-       strlcpy(sd->name, "DAVINCI RESIZER A", sizeof(sd->name));
+       strscpy(sd->name, "DAVINCI RESIZER A", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for davinci subdevs */
        v4l2_set_subdevdata(sd, vpfe_rsz);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1949,7 +1949,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 
        v4l2_subdev_init(sd, &resizer_v4l2_ops);
        sd->internal_ops = &resizer_v4l2_internal_ops;
-       strlcpy(sd->name, "DAVINCI RESIZER B", sizeof(sd->name));
+       strscpy(sd->name, "DAVINCI RESIZER B", sizeof(sd->name));
        sd->grp_id = 1 << 16;   /* group ID for davinci subdevs */
        v4l2_set_subdevdata(sd, vpfe_rsz);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index 00e64b0d0295eda8b0c3214da9deea364110f2dc..cf560a33d862ffa74020a061b5750059035d5966 100644 (file)
@@ -23,7 +23,7 @@
 #define _DAVINCI_VPFE_DM365_RESIZER_H
 
 enum resizer_oper_mode {
-       RESIZER_MODE_CONTINIOUS = 0,
+       RESIZER_MODE_CONTINUOUS = 0,
        RESIZER_MODE_ONE_SHOT = 1,
 };
 
index e55c815b9b656e7837ce2ae6da4a93c4017b94c1..bdf6ee5ad96cf51a9e1ab993a2ee6f7031e70c48 100644 (file)
@@ -639,7 +639,8 @@ static int vpfe_probe(struct platform_device *pdev)
                goto probe_disable_clock;
 
        vpfe_dev->media_dev.dev = vpfe_dev->pdev;
-       strcpy((char *)&vpfe_dev->media_dev.model, "davinci-media");
+       strscpy((char *)&vpfe_dev->media_dev.model, "davinci-media",
+               sizeof(vpfe_dev->media_dev.model));
 
        ret = media_device_register(&vpfe_dev->media_dev);
        if (ret) {
index 1269a983455e57c5434b71dc145f07f1a088623c..5e9769ea8a50cb8ffa9ef8476fc8328bb52ffe5a 100644 (file)
@@ -618,9 +618,9 @@ static int vpfe_querycap(struct file *file, void  *priv,
                cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
        cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
                            V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
-       strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
-       strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
-       strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
+       strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
+       strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
 
        return 0;
 }
@@ -1135,10 +1135,6 @@ static int vpfe_buffer_prepare(struct vb2_buffer *vb)
 
        v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
 
-       if (vb->state != VB2_BUF_STATE_ACTIVE &&
-           vb->state != VB2_BUF_STATE_PREPARED)
-               return 0;
-
        /* Initialize buffer */
        vb2_set_plane_payload(vb, 0, video->fmt.fmt.pix.sizeimage);
        if (vb2_plane_vaddr(vb, 0) &&
@@ -1429,7 +1425,8 @@ static int vpfe_qbuf(struct file *file, void *priv,
                return -EACCES;
        }
 
-       return vb2_qbuf(&video->buffer_queue, p);
+       return vb2_qbuf(&video->buffer_queue,
+                       video->video_dev.v4l2_dev->mdev, p);
 }
 
 /*
index 9eb7326f3fc69d7ba52ad79cf388587561c70606..aeeb15494a49f61950f79883b8d5d8dab92cc4a0 100644 (file)
   decided whether this feature is useful enough to make it generally
   available by exporting to v4l2-core.
 
-- The OF graph is walked at probe time to form the list of fwnodes to
-  be passed to v4l2_async_notifier_register(), starting from the IPU
-  CSI ports. And after all async subdevices have been bound,
-  v4l2_fwnode_parse_link() is used to form the media links between
-  the entities discovered by walking the OF graph.
+- After all async subdevices have been bound, v4l2_fwnode_parse_link()
+  is used to form the media links between the devices discovered in
+  the OF graph.
 
   While this approach allows support for arbitrary OF graphs, there
   are some assumptions for this to work:
 
-  1. All port parent nodes reachable in the graph from the IPU CSI
-     ports bind to V4L2 async subdevice drivers.
-
-     If a device has mixed-use ports such as video plus audio, the
-     endpoints from the audio ports are followed to devices that must
-     bind to V4L2 subdevice drivers, and not for example, to an ALSA
-     driver or a non-V4L2 media driver. If the device were bound to
-     such a driver, imx-media would never get an async completion
-     notification because the device fwnode was added to the async
-     list, but the driver does not interface with the V4L2 async
-     framework.
-
-  2. Every port reachable in the graph is treated as a media pad,
-     owned by the V4L2 subdevice that is bound to the port's parent.
+  1. If a port owned by a device in the graph has endpoint nodes, the
+     port is treated as a media pad.
 
      This presents problems for devices that don't make this port = pad
      assumption. Examples are SMIAPP compatible cameras which define only
@@ -54,9 +40,8 @@
      possible long-term solution is to implement a subdev API that
      maps a port id to a media pad index.
 
-  3. Every endpoint of a port reachable in the graph is treated as
-     a media link, between V4L2 subdevices that are bound to the
-     port parents of the local and remote endpoints.
+  2. Every endpoint of a port owned by a device in the graph is treated
+     as a media link.
 
      Which means a port must not contain mixed-use endpoints, they
      must all refer to media links between V4L2 subdevices.
index 256039ce561e6c89f4cc4e123f6046ff59308c3e..b37e1186eb2f9fb6680a852eefbd66bd93b203c4 100644 (file)
@@ -73,8 +73,8 @@ static int vidioc_querycap(struct file *file, void *fh,
 {
        struct capture_priv *priv = video_drvdata(file);
 
-       strlcpy(cap->driver, "imx-media-capture", sizeof(cap->driver));
-       strlcpy(cap->card, "imx-media-capture", sizeof(cap->card));
+       strscpy(cap->driver, "imx-media-capture", sizeof(cap->driver));
+       strscpy(cap->card, "imx-media-capture", sizeof(cap->card));
        snprintf(cap->bus_info, sizeof(cap->bus_info),
                 "platform:%s", priv->src_sd->name);
 
index cd2c291e1e9429c7ec4944c21cd90c365e441147..4223f8d418ae8b8de25b2513843624b12d0a16fa 100644 (file)
@@ -124,7 +124,7 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
 
 static inline bool is_parallel_bus(struct v4l2_fwnode_endpoint *ep)
 {
-       return ep->bus_type != V4L2_MBUS_CSI2;
+       return ep->bus_type != V4L2_MBUS_CSI2_DPHY;
 }
 
 static inline bool is_parallel_16bit_bus(struct v4l2_fwnode_endpoint *ep)
@@ -165,6 +165,9 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
        struct v4l2_subdev *sd;
        struct media_pad *pad;
 
+       if (!IS_ENABLED(CONFIG_OF))
+               return -ENXIO;
+
        if (!priv->src_sd)
                return -EPIPE;
 
@@ -1050,7 +1053,7 @@ static int csi_link_validate(struct v4l2_subdev *sd,
                             struct v4l2_subdev_format *sink_fmt)
 {
        struct csi_priv *priv = v4l2_get_subdevdata(sd);
-       struct v4l2_fwnode_endpoint upstream_ep = {};
+       struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
        bool is_csi2;
        int ret;
 
@@ -1164,7 +1167,7 @@ static int csi_enum_mbus_code(struct v4l2_subdev *sd,
                              struct v4l2_subdev_mbus_code_enum *code)
 {
        struct csi_priv *priv = v4l2_get_subdevdata(sd);
-       struct v4l2_fwnode_endpoint upstream_ep;
+       struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
        const struct imx_media_pixfmt *incc;
        struct v4l2_mbus_framefmt *infmt;
        int ret = 0;
@@ -1403,7 +1406,7 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
 {
        struct csi_priv *priv = v4l2_get_subdevdata(sd);
        struct imx_media_video_dev *vdev = priv->vdev;
-       struct v4l2_fwnode_endpoint upstream_ep;
+       struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
        const struct imx_media_pixfmt *cc;
        struct v4l2_pix_format vdev_fmt;
        struct v4l2_mbus_framefmt *fmt;
@@ -1542,7 +1545,7 @@ static int csi_set_selection(struct v4l2_subdev *sd,
                             struct v4l2_subdev_selection *sel)
 {
        struct csi_priv *priv = v4l2_get_subdevdata(sd);
-       struct v4l2_fwnode_endpoint upstream_ep;
+       struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
        struct v4l2_mbus_framefmt *infmt;
        struct v4l2_rect *crop, *compose;
        int pad, ret;
@@ -1780,6 +1783,61 @@ static const struct v4l2_subdev_internal_ops csi_internal_ops = {
        .unregistered = csi_unregistered,
 };
 
+static int imx_csi_parse_endpoint(struct device *dev,
+                                 struct v4l2_fwnode_endpoint *vep,
+                                 struct v4l2_async_subdev *asd)
+{
+       return fwnode_device_is_available(asd->match.fwnode) ? 0 : -EINVAL;
+}
+
+static int imx_csi_async_register(struct csi_priv *priv)
+{
+       struct v4l2_async_notifier *notifier;
+       struct fwnode_handle *fwnode;
+       unsigned int port;
+       int ret;
+
+       notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
+       if (!notifier)
+               return -ENOMEM;
+
+       v4l2_async_notifier_init(notifier);
+
+       fwnode = dev_fwnode(priv->dev);
+
+       /* get this CSI's port id */
+       ret = fwnode_property_read_u32(fwnode, "reg", &port);
+       if (ret < 0)
+               goto out_free;
+
+       ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
+               priv->dev->parent, notifier, sizeof(struct v4l2_async_subdev),
+               port, imx_csi_parse_endpoint);
+       if (ret < 0)
+               goto out_cleanup;
+
+       ret = v4l2_async_subdev_notifier_register(&priv->sd, notifier);
+       if (ret < 0)
+               goto out_cleanup;
+
+       ret = v4l2_async_register_subdev(&priv->sd);
+       if (ret < 0)
+               goto out_unregister;
+
+       priv->sd.subdev_notifier = notifier;
+
+       return 0;
+
+out_unregister:
+       v4l2_async_notifier_unregister(notifier);
+out_cleanup:
+       v4l2_async_notifier_cleanup(notifier);
+out_free:
+       kfree(notifier);
+
+       return ret;
+}
+
 static int imx_csi_probe(struct platform_device *pdev)
 {
        struct ipu_client_platformdata *pdata;
@@ -1849,7 +1907,7 @@ static int imx_csi_probe(struct platform_device *pdev)
                        goto free;
        }
 
-       ret = v4l2_async_register_subdev(&priv->sd);
+       ret = imx_csi_async_register(priv);
        if (ret)
                goto free;
 
index b0be80f05767869b9947a64dabd657ea18a129c4..4b344a4a3706d927465543836025824e739a3cc2 100644 (file)
 
 static inline struct imx_media_dev *notifier2dev(struct v4l2_async_notifier *n)
 {
-       return container_of(n, struct imx_media_dev, subdev_notifier);
+       return container_of(n, struct imx_media_dev, notifier);
 }
 
 /*
- * Find an asd by fwnode or device name. This is called during
- * driver load to form the async subdev list and bind them.
- */
-static struct v4l2_async_subdev *
-find_async_subdev(struct imx_media_dev *imxmd,
-                 struct fwnode_handle *fwnode,
-                 const char *devname)
-{
-       struct imx_media_async_subdev *imxasd;
-       struct v4l2_async_subdev *asd;
-
-       list_for_each_entry(imxasd, &imxmd->asd_list, list) {
-               asd = &imxasd->asd;
-               switch (asd->match_type) {
-               case V4L2_ASYNC_MATCH_FWNODE:
-                       if (fwnode && asd->match.fwnode == fwnode)
-                               return asd;
-                       break;
-               case V4L2_ASYNC_MATCH_DEVNAME:
-                       if (devname && !strcmp(asd->match.device_name,
-                                              devname))
-                               return asd;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       return NULL;
-}
-
-
-/*
- * Adds a subdev to the async subdev list. If fwnode is non-NULL, adds
- * the async as a V4L2_ASYNC_MATCH_FWNODE match type, otherwise as
- * a V4L2_ASYNC_MATCH_DEVNAME match type using the dev_name of the
- * given platform_device. This is called during driver load when
+ * Adds a subdev to the root notifier's async subdev list. If fwnode is
+ * non-NULL, adds the async as a V4L2_ASYNC_MATCH_FWNODE match type,
+ * otherwise as a V4L2_ASYNC_MATCH_DEVNAME match type using the dev_name
+ * of the given platform_device. This is called during driver load when
  * forming the async subdev list.
  */
 int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
@@ -80,47 +47,43 @@ int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
        struct imx_media_async_subdev *imxasd;
        struct v4l2_async_subdev *asd;
        const char *devname = NULL;
-       int ret = 0;
-
-       mutex_lock(&imxmd->mutex);
+       int ret;
 
-       if (pdev)
+       if (fwnode) {
+               asd = v4l2_async_notifier_add_fwnode_subdev(
+                       &imxmd->notifier, fwnode, sizeof(*imxasd));
+       } else {
                devname = dev_name(&pdev->dev);
-
-       /* return -EEXIST if this asd already added */
-       if (find_async_subdev(imxmd, fwnode, devname)) {
-               dev_dbg(imxmd->md.dev, "%s: already added %s\n",
-                       __func__, np ? np->name : devname);
-               ret = -EEXIST;
-               goto out;
+               asd = v4l2_async_notifier_add_devname_subdev(
+                       &imxmd->notifier, devname, sizeof(*imxasd));
        }
 
-       imxasd = devm_kzalloc(imxmd->md.dev, sizeof(*imxasd), GFP_KERNEL);
-       if (!imxasd) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       asd = &imxasd->asd;
-
-       if (fwnode) {
-               asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-               asd->match.fwnode = fwnode;
-       } else {
-               asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
-               asd->match.device_name = devname;
-               imxasd->pdev = pdev;
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               if (ret == -EEXIST) {
+                       if (np)
+                               dev_dbg(imxmd->md.dev, "%s: already added %pOFn\n",
+                                       __func__, np);
+                       else
+                               dev_dbg(imxmd->md.dev, "%s: already added %s\n",
+                                       __func__, devname);
+               }
+               return ret;
        }
 
-       list_add_tail(&imxasd->list, &imxmd->asd_list);
+       imxasd = to_imx_media_asd(asd);
 
-       imxmd->subdev_notifier.num_subdevs++;
+       if (devname)
+               imxasd->pdev = pdev;
 
-       dev_dbg(imxmd->md.dev, "%s: added %s, match type %s\n",
-               __func__, np ? np->name : devname, np ? "FWNODE" : "DEVNAME");
+       if (np)
+               dev_dbg(imxmd->md.dev, "%s: added %pOFn, match type FWNODE\n",
+                       __func__, np);
+       else
+               dev_dbg(imxmd->md.dev, "%s: added %s, match type DEVNAME\n",
+                       __func__, devname);
 
-out:
-       mutex_unlock(&imxmd->mutex);
-       return ret;
+       return 0;
 }
 
 /*
@@ -175,7 +138,7 @@ out:
 }
 
 /*
- * create the media links for all subdevs that registered async.
+ * Create the media links for all subdevs that registered.
  * Called after all async subdevs have bound.
  */
 static int imx_media_create_links(struct v4l2_async_notifier *notifier)
@@ -184,14 +147,7 @@ static int imx_media_create_links(struct v4l2_async_notifier *notifier)
        struct v4l2_subdev *sd;
        int ret;
 
-       /*
-        * Only links are created between subdevices that are known
-        * to the async notifier. If there are other non-async subdevices,
-        * they were created internally by some subdevice (smiapp is one
-        * example). In those cases it is expected the subdevice is
-        * responsible for creating those internal links.
-        */
-       list_for_each_entry(sd, &notifier->done, async_list) {
+       list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
                switch (sd->grp_id) {
                case IMX_MEDIA_GRP_ID_VDIC:
                case IMX_MEDIA_GRP_ID_IC_PRP:
@@ -211,7 +167,10 @@ static int imx_media_create_links(struct v4l2_async_notifier *notifier)
                                imx_media_create_csi_of_links(imxmd, sd);
                        break;
                default:
-                       /* this is an external fwnode subdev */
+                       /*
+                        * if this subdev has fwnode links, create media
+                        * links for them.
+                        */
                        imx_media_create_of_links(imxmd, sd);
                        break;
                }
@@ -391,7 +350,7 @@ static int imx_media_inherit_controls(struct imx_media_dev *imxmd,
 
                ret = v4l2_ctrl_add_handler(vfd->ctrl_handler,
                                            sd->ctrl_handler,
-                                           NULL);
+                                           NULL, true);
                if (ret)
                        return ret;
        }
@@ -487,10 +446,8 @@ static int imx_media_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *node = dev->of_node;
-       struct imx_media_async_subdev *imxasd;
-       struct v4l2_async_subdev **subdevs;
        struct imx_media_dev *imxmd;
-       int num_subdevs, i, ret;
+       int ret;
 
        imxmd = devm_kzalloc(dev, sizeof(*imxmd), GFP_KERNEL);
        if (!imxmd)
@@ -498,14 +455,14 @@ static int imx_media_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, imxmd);
 
-       strlcpy(imxmd->md.model, "imx-media", sizeof(imxmd->md.model));
+       strscpy(imxmd->md.model, "imx-media", sizeof(imxmd->md.model));
        imxmd->md.ops = &imx_media_md_ops;
        imxmd->md.dev = dev;
 
        mutex_init(&imxmd->mutex);
 
        imxmd->v4l2_dev.mdev = &imxmd->md;
-       strlcpy(imxmd->v4l2_dev.name, "imx-media",
+       strscpy(imxmd->v4l2_dev.name, "imx-media",
                sizeof(imxmd->v4l2_dev.name));
 
        media_device_init(&imxmd->md);
@@ -519,47 +476,34 @@ static int imx_media_probe(struct platform_device *pdev)
 
        dev_set_drvdata(imxmd->v4l2_dev.dev, imxmd);
 
-       INIT_LIST_HEAD(&imxmd->asd_list);
        INIT_LIST_HEAD(&imxmd->vdev_list);
 
+       v4l2_async_notifier_init(&imxmd->notifier);
+
        ret = imx_media_add_of_subdevs(imxmd, node);
        if (ret) {
                v4l2_err(&imxmd->v4l2_dev,
                         "add_of_subdevs failed with %d\n", ret);
-               goto unreg_dev;
+               goto notifier_cleanup;
        }
 
        ret = imx_media_add_internal_subdevs(imxmd);
        if (ret) {
                v4l2_err(&imxmd->v4l2_dev,
                         "add_internal_subdevs failed with %d\n", ret);
-               goto unreg_dev;
+               goto notifier_cleanup;
        }
 
-       num_subdevs = imxmd->subdev_notifier.num_subdevs;
-
        /* no subdevs? just bail */
-       if (num_subdevs == 0) {
+       if (list_empty(&imxmd->notifier.asd_list)) {
                ret = -ENODEV;
-               goto unreg_dev;
+               goto notifier_cleanup;
        }
 
-       subdevs = devm_kcalloc(imxmd->md.dev, num_subdevs, sizeof(*subdevs),
-                              GFP_KERNEL);
-       if (!subdevs) {
-               ret = -ENOMEM;
-               goto unreg_dev;
-       }
-
-       i = 0;
-       list_for_each_entry(imxasd, &imxmd->asd_list, list)
-               subdevs[i++] = &imxasd->asd;
-
        /* prepare the async subdev notifier and register it */
-       imxmd->subdev_notifier.subdevs = subdevs;
-       imxmd->subdev_notifier.ops = &imx_media_subdev_ops;
+       imxmd->notifier.ops = &imx_media_subdev_ops;
        ret = v4l2_async_notifier_register(&imxmd->v4l2_dev,
-                                          &imxmd->subdev_notifier);
+                                          &imxmd->notifier);
        if (ret) {
                v4l2_err(&imxmd->v4l2_dev,
                         "v4l2_async_notifier_register failed with %d\n", ret);
@@ -570,7 +514,8 @@ static int imx_media_probe(struct platform_device *pdev)
 
 del_int:
        imx_media_remove_internal_subdevs(imxmd);
-unreg_dev:
+notifier_cleanup:
+       v4l2_async_notifier_cleanup(&imxmd->notifier);
        v4l2_device_unregister(&imxmd->v4l2_dev);
 cleanup:
        media_device_cleanup(&imxmd->md);
@@ -584,8 +529,9 @@ static int imx_media_remove(struct platform_device *pdev)
 
        v4l2_info(&imxmd->v4l2_dev, "Removing imx-media\n");
 
-       v4l2_async_notifier_unregister(&imxmd->subdev_notifier);
+       v4l2_async_notifier_unregister(&imxmd->notifier);
        imx_media_remove_internal_subdevs(imxmd);
+       v4l2_async_notifier_cleanup(&imxmd->notifier);
        v4l2_device_unregister(&imxmd->v4l2_dev);
        media_device_unregister(&imxmd->md);
        media_device_cleanup(&imxmd->md);
index 6df189135db88c84b0a9acdd3e613452423440f2..8cf773eef9da16e3f08f38896f45e78a3d41c5a6 100644 (file)
@@ -463,7 +463,7 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim)
 {
        /* add the FIM controls to the calling subdev ctrl handler */
        return v4l2_ctrl_add_handler(fim->sd->ctrl_handler,
-                                    &fim->ctrl_handler, NULL);
+                                    &fim->ctrl_handler, NULL, false);
 }
 EXPORT_SYMBOL_GPL(imx_media_fim_add_controls);
 
index daf66c2d69abc9b07abfd51f666c012d4a1f7451..0fdc45dbfb7697ff4e2319b88fe155ffa1a19c0f 100644 (file)
@@ -350,8 +350,11 @@ remove:
 void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd)
 {
        struct imx_media_async_subdev *imxasd;
+       struct v4l2_async_subdev *asd;
+
+       list_for_each_entry(asd, &imxmd->notifier.asd_list, asd_list) {
+               imxasd = to_imx_media_asd(asd);
 
-       list_for_each_entry(imxasd, &imxmd->asd_list, list) {
                if (!imxasd->pdev)
                        continue;
 
index acde372c6795b309aa474e3238bf23e37a604750..b2e840f96c50d159e5dc0ade4ffb7b595b4c240e 100644 (file)
 #include <video/imx-ipu-v3.h>
 #include "imx-media.h"
 
-static int of_get_port_count(const struct device_node *np)
+static int of_add_csi(struct imx_media_dev *imxmd, struct device_node *csi_np)
 {
-       struct device_node *ports, *child;
-       int num = 0;
-
-       /* check if this node has a ports subnode */
-       ports = of_get_child_by_name(np, "ports");
-       if (ports)
-               np = ports;
-
-       for_each_child_of_node(np, child)
-               if (of_node_cmp(child->name, "port") == 0)
-                       num++;
-
-       of_node_put(ports);
-       return num;
-}
-
-/*
- * find the remote device node given local endpoint node
- */
-static bool of_get_remote(struct device_node *epnode,
-                         struct device_node **remote_node)
-{
-       struct device_node *rp, *rpp;
-       struct device_node *remote;
-       bool is_csi_port;
-
-       rp = of_graph_get_remote_port(epnode);
-       rpp = of_graph_get_remote_port_parent(epnode);
-
-       if (of_device_is_compatible(rpp, "fsl,imx6q-ipu")) {
-               /* the remote is one of the CSI ports */
-               remote = rp;
-               of_node_put(rpp);
-               is_csi_port = true;
-       } else {
-               remote = rpp;
-               of_node_put(rp);
-               is_csi_port = false;
-       }
-
-       if (!of_device_is_available(remote)) {
-               of_node_put(remote);
-               *remote_node = NULL;
-       } else {
-               *remote_node = remote;
-       }
-
-       return is_csi_port;
-}
-
-static int
-of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
-               bool is_csi_port)
-{
-       int i, num_ports, ret;
+       int ret;
 
-       if (!of_device_is_available(sd_np)) {
-               dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__,
-                       sd_np->name);
+       if (!of_device_is_available(csi_np)) {
+               dev_dbg(imxmd->md.dev, "%s: %pOFn not enabled\n", __func__,
+                       csi_np);
                /* unavailable is not an error */
                return 0;
        }
 
-       /* register this subdev with async notifier */
-       ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(sd_np),
-                                        NULL);
+       /* add CSI fwnode to async notifier */
+       ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np), NULL);
        if (ret) {
                if (ret == -EEXIST) {
                        /* already added, everything is fine */
@@ -98,42 +43,7 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
                return ret;
        }
 
-       /*
-        * the ipu-csi has one sink port. The source pads are not
-        * represented in the device tree by port nodes, but are
-        * described by the internal pads and links later.
-        */
-       num_ports = is_csi_port ? 1 : of_get_port_count(sd_np);
-
-       for (i = 0; i < num_ports; i++) {
-               struct device_node *epnode = NULL, *port, *remote_np;
-
-               port = is_csi_port ? sd_np : of_graph_get_port_by_id(sd_np, i);
-               if (!port)
-                       continue;
-
-               for_each_child_of_node(port, epnode) {
-                       bool remote_is_csi;
-
-                       remote_is_csi = of_get_remote(epnode, &remote_np);
-                       if (!remote_np)
-                               continue;
-
-                       ret = of_parse_subdev(imxmd, remote_np, remote_is_csi);
-                       of_node_put(remote_np);
-                       if (ret)
-                               break;
-               }
-
-               if (port != sd_np)
-                       of_node_put(port);
-               if (ret) {
-                       of_node_put(epnode);
-                       break;
-               }
-       }
-
-       return ret;
+       return 0;
 }
 
 int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
@@ -147,7 +57,7 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
                if (!csi_np)
                        break;
 
-               ret = of_parse_subdev(imxmd, csi_np, true);
+               ret = of_add_csi(imxmd, csi_np);
                of_node_put(csi_np);
                if (ret)
                        return ret;
index 8aa13403b09d15f639042b095c3295c7d9df7cc2..0eaa353d5cb3976893f460c8a114442e87541012 100644 (file)
@@ -88,7 +88,7 @@ static const struct imx_media_pixfmt rgb_formats[] = {
                .cs     = IPUV3_COLORSPACE_RGB,
                .bpp    = 24,
        }, {
-               .fourcc = V4L2_PIX_FMT_RGB32,
+               .fourcc = V4L2_PIX_FMT_XRGB32,
                .codes  = {MEDIA_BUS_FMT_ARGB8888_1X32},
                .cs     = IPUV3_COLORSPACE_RGB,
                .bpp    = 32,
@@ -212,7 +212,7 @@ static const struct imx_media_pixfmt ipu_yuv_formats[] = {
 
 static const struct imx_media_pixfmt ipu_rgb_formats[] = {
        {
-               .fourcc = V4L2_PIX_FMT_RGB32,
+               .fourcc = V4L2_PIX_FMT_XRGB32,
                .codes  = {MEDIA_BUS_FMT_ARGB8888_1X32},
                .cs     = IPUV3_COLORSPACE_RGB,
                .bpp    = 32,
index 57bd094cf765c52d8ea1c8e2b464dcd2711ff6dc..bc7feb81937ceea79cc1fae19039149318a000f3 100644 (file)
@@ -119,12 +119,11 @@ struct imx_media_internal_sd_platformdata {
        int ipu_id;
 };
 
-
 struct imx_media_async_subdev {
+       /* the base asd - must be first in this struct */
        struct v4l2_async_subdev asd;
        /* the platform device of IPU-internal subdevs */
        struct platform_device *pdev;
-       struct list_head list;
 };
 
 static inline struct imx_media_async_subdev *
@@ -149,8 +148,7 @@ struct imx_media_dev {
        struct ipu_soc *ipu[2];
 
        /* for async subdev registration */
-       struct list_head asd_list;
-       struct v4l2_async_notifier subdev_notifier;
+       struct v4l2_async_notifier notifier;
 };
 
 enum codespace_sel {
index ceeeb3069a0248d361753050fd595e889c25c58d..6a1cee55a49b68a09f8dbd7c8a5939e4b39f99d9 100644 (file)
@@ -551,35 +551,34 @@ static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
        .registered = csi2_registered,
 };
 
-static int csi2_parse_endpoints(struct csi2_dev *csi2)
+static int csi2_parse_endpoint(struct device *dev,
+                              struct v4l2_fwnode_endpoint *vep,
+                              struct v4l2_async_subdev *asd)
 {
-       struct device_node *node = csi2->dev->of_node;
-       struct device_node *epnode;
-       struct v4l2_fwnode_endpoint ep;
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
+       struct csi2_dev *csi2 = sd_to_dev(sd);
 
-       epnode = of_graph_get_endpoint_by_regs(node, 0, -1);
-       if (!epnode) {
-               v4l2_err(&csi2->sd, "failed to get sink endpoint node\n");
+       if (!fwnode_device_is_available(asd->match.fwnode)) {
+               v4l2_err(&csi2->sd, "remote is not available\n");
                return -EINVAL;
        }
 
-       v4l2_fwnode_endpoint_parse(of_fwnode_handle(epnode), &ep);
-       of_node_put(epnode);
-
-       if (ep.bus_type != V4L2_MBUS_CSI2) {
+       if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
                v4l2_err(&csi2->sd, "invalid bus type, must be MIPI CSI2\n");
                return -EINVAL;
        }
 
-       csi2->bus = ep.bus.mipi_csi2;
+       csi2->bus = vep->bus.mipi_csi2;
 
        dev_dbg(csi2->dev, "data lanes: %d\n", csi2->bus.num_data_lanes);
        dev_dbg(csi2->dev, "flags: 0x%08x\n", csi2->bus.flags);
+
        return 0;
 }
 
 static int csi2_probe(struct platform_device *pdev)
 {
+       unsigned int sink_port = 0;
        struct csi2_dev *csi2;
        struct resource *res;
        int ret;
@@ -597,14 +596,10 @@ static int csi2_probe(struct platform_device *pdev)
        csi2->sd.dev = &pdev->dev;
        csi2->sd.owner = THIS_MODULE;
        csi2->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
-       strcpy(csi2->sd.name, DEVICE_NAME);
+       strscpy(csi2->sd.name, DEVICE_NAME, sizeof(csi2->sd.name));
        csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
        csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2;
 
-       ret = csi2_parse_endpoints(csi2);
-       if (ret)
-               return ret;
-
        csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref");
        if (IS_ERR(csi2->pllref_clk)) {
                v4l2_err(&csi2->sd, "failed to get pll reference clock\n");
@@ -654,7 +649,9 @@ static int csi2_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, &csi2->sd);
 
-       ret = v4l2_async_register_subdev(&csi2->sd);
+       ret = v4l2_async_register_fwnode_subdev(
+               &csi2->sd, sizeof(struct v4l2_async_subdev),
+               &sink_port, 1, csi2_parse_endpoint);
        if (ret)
                goto dphy_off;
 
index 77f1e0243d6ef791cfe14c6e3b5d8e83af98ac11..1676c166dc8394764cab449662e61239617c98d1 100644 (file)
@@ -223,7 +223,6 @@ static int imx074_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
        case V4L2_SEL_TGT_CROP:
                return 0;
        default:
@@ -263,7 +262,7 @@ static int imx074_s_power(struct v4l2_subdev *sd, int on)
 static int imx074_g_mbus_config(struct v4l2_subdev *sd,
                                struct v4l2_mbus_config *cfg)
 {
-       cfg->type = V4L2_MBUS_CSI2;
+       cfg->type = V4L2_MBUS_CSI2_DPHY;
        cfg->flags = V4L2_MBUS_CSI2_2_LANE |
                V4L2_MBUS_CSI2_CHANNEL_0 |
                V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
index 4802d30e47dea151682cf9443bfb584e682ccc32..4ff179302b4f4ed4fab6d183d5bd5ba60a511fd3 100644 (file)
@@ -330,7 +330,6 @@ static int mt9t031_get_selection(struct v4l2_subdev *sd,
 
        switch (sel->target) {
        case V4L2_SEL_TGT_CROP_BOUNDS:
-       case V4L2_SEL_TGT_CROP_DEFAULT:
                sel->r.left = MT9T031_COLUMN_SKIP;
                sel->r.top = MT9T031_ROW_SKIP;
                sel->r.width = MT9T031_MAX_WIDTH;
index dddd27335cb433bf956ceb8504620d119288d3ca..841cc0b3ce13484a1ee905a96421e97cad11378e 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 config VIDEO_OMAP4
        tristate "OMAP 4 Camera support"
        depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C
index a716ce936cf6f5d9dff4233530dabdb7a62913a5..e64d489a4a76043cc2566dab9e667aa473f6798e 100644 (file)
@@ -1,4 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
 # Makefile for OMAP4 ISS driver
+#
 
 omap4-iss-objs += \
        iss.o iss_csi2.o iss_csiphy.o iss_ipipeif.o iss_ipipe.o iss_resizer.o iss_video.o
index b1036baebb0357e741e729053b164a3c99d4d618..c8be1db532ab255542d6d06d87dee2956f687175 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver
  *
  * Copyright (C) 2012, Texas Instruments
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/clk.h>
@@ -989,7 +985,7 @@ static int iss_register_entities(struct iss_device *iss)
        int ret;
 
        iss->media_dev.dev = iss->dev;
-       strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
+       strscpy(iss->media_dev.model, "TI OMAP4 ISS",
                sizeof(iss->media_dev.model));
        iss->media_dev.hw_revision = iss->revision;
        iss->media_dev.ops = &iss_media_ops;
index 760ee27da7049cc81e6652056f0daa8e3d9ba413..b88f9529683c14d246f255c2ee39352357e625ee 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver
  *
  * Copyright (C) 2012 Texas Instruments.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef _OMAP4_ISS_H_
index f6acc541e8a200b9d8110e41c5e30badbcfb7bbe..059cf5bd3c36451b46ea4aad029724318e366fb5 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver - CSI PHY module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/delay.h>
index 24ab378d469ff4a6ff7db84394c19c8fe5e14588..3f7fd9cff41d9a7ab84aa6013c9c7a04706718f3 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - CSI2 module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef OMAP4_ISS_CSI2_H
index 748607f8918f7021a2319ec21d05b6e18533f895..96f2ce0451384dc4b0ba3b9f23f04c05e203264f 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver - CSI PHY module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/delay.h>
index a0f2d974daeb64e5f94989cae8df4764b81c7013..44408e4fcf3b1dc8769ab8c9b8a9a809b74e517d 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - CSI PHY module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef OMAP4_ISS_CSI_PHY_H
index d86ef8a031f2878726c57d834e159a957609e990..26be078b69f3e55ca0c14a522e11911d769d61e0 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver - ISP IPIPE module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/module.h>
@@ -507,7 +503,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
 
        v4l2_subdev_init(sd, &ipipe_v4l2_ops);
        sd->internal_ops = &ipipe_v4l2_internal_ops;
-       strlcpy(sd->name, "OMAP4 ISS ISP IPIPE", sizeof(sd->name));
+       strscpy(sd->name, "OMAP4 ISS ISP IPIPE", sizeof(sd->name));
        sd->grp_id = BIT(16);   /* group ID for iss subdevs */
        v4l2_set_subdevdata(sd, ipipe);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index d5b441d9cb3130870674634f3594222f6fe5b526..53b42aac1696862618a5871fbd05a44f84019ee3 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - ISP IPIPE module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef OMAP4_ISS_IPIPE_H
index cb88b2bd0d82bee09659f3668c1c13dfca2abc29..c2978d02e797110f8b23176180fbe41659e4b1c7 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver - ISP IPIPEIF module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/module.h>
@@ -738,7 +734,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 
        v4l2_subdev_init(sd, &ipipeif_v4l2_ops);
        sd->internal_ops = &ipipeif_v4l2_internal_ops;
-       strlcpy(sd->name, "OMAP4 ISS ISP IPIPEIF", sizeof(sd->name));
+       strscpy(sd->name, "OMAP4 ISS ISP IPIPEIF", sizeof(sd->name));
        sd->grp_id = BIT(16);   /* group ID for iss subdevs */
        v4l2_set_subdevdata(sd, ipipeif);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index bad32b1d6ad893169c2f9a1092550372f71ede9e..69792333a62ee17ea2718fccfc465f7b7254c055 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - ISP IPIPEIF module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef OMAP4_ISS_IPIPEIF_H
index cb415e898acaf91f1798f6d03d4405d16ce2bbf1..09a7375c89ac023262a66cc4d03f382916678d9e 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - Register defines
  *
  * Copyright (C) 2012 Texas Instruments.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef _OMAP4_ISS_REGS_H_
index 4bbfa20b3c380ffd3933c7466c977b6a433755a7..3b6875cbca9be655dd8765c6ce639eb3d92036fa 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver - ISP RESIZER module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/module.h>
@@ -781,7 +777,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 
        v4l2_subdev_init(sd, &resizer_v4l2_ops);
        sd->internal_ops = &resizer_v4l2_internal_ops;
-       strlcpy(sd->name, "OMAP4 ISS ISP resizer", sizeof(sd->name));
+       strscpy(sd->name, "OMAP4 ISS ISP resizer", sizeof(sd->name));
        sd->grp_id = BIT(16);   /* group ID for iss subdevs */
        v4l2_set_subdevdata(sd, resizer);
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
index 8b7c5fe9ffeddb1652d3b51df831df79e4f87b78..cb937fccc21ff72e8f3c509a87ca0d4ebd06a354 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - ISP RESIZER module
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef OMAP4_ISS_RESIZER_H
index 16478fe9e3f8ad3e07cdfbc84db734d4834f6530..c2c5a9cd8642894a889e02e271060ce30244f11c 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * TI OMAP4 ISS V4L2 Driver - Generic video node
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/clk.h>
@@ -534,9 +530,9 @@ iss_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
 {
        struct iss_video *video = video_drvdata(file);
 
-       strlcpy(cap->driver, ISS_VIDEO_DRIVER_NAME, sizeof(cap->driver));
-       strlcpy(cap->card, video->video.name, sizeof(cap->card));
-       strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
+       strscpy(cap->driver, ISS_VIDEO_DRIVER_NAME, sizeof(cap->driver));
+       strscpy(cap->card, video->video.name, sizeof(cap->card));
+       strscpy(cap->bus_info, "media", sizeof(cap->bus_info));
 
        if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
                cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
@@ -573,7 +569,7 @@ iss_video_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
 
                if (index == 0) {
                        f->pixelformat = info->pixelformat;
-                       strlcpy(f->description, info->description,
+                       strscpy(f->description, info->description,
                                sizeof(f->description));
                        return 0;
                }
@@ -806,9 +802,10 @@ iss_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
 static int
 iss_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 {
+       struct iss_video *video = video_drvdata(file);
        struct iss_video_fh *vfh = to_iss_video_fh(fh);
 
-       return vb2_qbuf(&vfh->queue, b);
+       return vb2_qbuf(&vfh->queue, video->video.v4l2_dev->mdev, b);
 }
 
 static int
@@ -1053,7 +1050,7 @@ iss_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
        if (input->index > 0)
                return -EINVAL;
 
-       strlcpy(input->name, "camera", sizeof(input->name));
+       strscpy(input->name, "camera", sizeof(input->name));
        input->type = V4L2_INPUT_TYPE_CAMERA;
 
        return 0;
index d7e05d04512c5176df8d310e65bd735a1df6f826..f22489edb5624af2c96624d43ae2da525d71bda6 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * TI OMAP4 ISS V4L2 Driver - Generic video node
  *
  * Copyright (C) 2012 Texas Instruments, Inc.
  *
  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef OMAP4_ISS_VIDEO_H
diff --git a/drivers/staging/media/sunxi/Kconfig b/drivers/staging/media/sunxi/Kconfig
new file mode 100644 (file)
index 0000000..c78d922
--- /dev/null
@@ -0,0 +1,15 @@
+config VIDEO_SUNXI
+       bool "Allwinner sunXi family Video Devices"
+       depends on ARCH_SUNXI || COMPILE_TEST
+       help
+         If you have an Allwinner SoC based on the sunXi family, say Y.
+
+         Note that this option doesn't include new drivers in the
+         kernel: saying N will just cause Kconfig to skip all the
+         questions about Allwinner media devices.
+
+if VIDEO_SUNXI
+
+source "drivers/staging/media/sunxi/cedrus/Kconfig"
+
+endif
diff --git a/drivers/staging/media/sunxi/Makefile b/drivers/staging/media/sunxi/Makefile
new file mode 100644 (file)
index 0000000..cee2846
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_SUNXI_CEDRUS)       += cedrus/
diff --git a/drivers/staging/media/sunxi/cedrus/Kconfig b/drivers/staging/media/sunxi/cedrus/Kconfig
new file mode 100644 (file)
index 0000000..a7a34e8
--- /dev/null
@@ -0,0 +1,14 @@
+config VIDEO_SUNXI_CEDRUS
+       tristate "Allwinner Cedrus VPU driver"
+       depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER
+       depends on HAS_DMA
+       depends on OF
+       select SUNXI_SRAM
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_MEM2MEM_DEV
+       help
+         Support for the VPU found in Allwinner SoCs, also known as the Cedar
+         video engine.
+
+         To compile this driver as a module, choose M here: the module
+         will be called sunxi-cedrus.
diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile
new file mode 100644 (file)
index 0000000..e9dc68b
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
+
+sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o cedrus_mpeg2.o
diff --git a/drivers/staging/media/sunxi/cedrus/TODO b/drivers/staging/media/sunxi/cedrus/TODO
new file mode 100644 (file)
index 0000000..ec277ec
--- /dev/null
@@ -0,0 +1,7 @@
+Before this stateless decoder driver can leave the staging area:
+* The Request API needs to be stabilized;
+* The codec-specific controls need to be thoroughly reviewed to ensure they
+  cover all intended uses cases;
+* Userspace support for the Request API needs to be reviewed;
+* Another stateless decoder driver should be submitted;
+* At least one stateless encoder driver should be submitted.
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
new file mode 100644 (file)
index 0000000..8255845
--- /dev/null
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "cedrus.h"
+#include "cedrus_video.h"
+#include "cedrus_dec.h"
+#include "cedrus_hw.h"
+
+static const struct cedrus_control cedrus_controls[] = {
+       {
+               .id             = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
+               .elem_size      = sizeof(struct v4l2_ctrl_mpeg2_slice_params),
+               .codec          = CEDRUS_CODEC_MPEG2,
+               .required       = true,
+       },
+       {
+               .id             = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
+               .elem_size      = sizeof(struct v4l2_ctrl_mpeg2_quantization),
+               .codec          = CEDRUS_CODEC_MPEG2,
+               .required       = false,
+       },
+};
+
+#define CEDRUS_CONTROLS_COUNT  ARRAY_SIZE(cedrus_controls)
+
+void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id)
+{
+       unsigned int i;
+
+       for (i = 0; ctx->ctrls[i]; i++)
+               if (ctx->ctrls[i]->id == id)
+                       return ctx->ctrls[i]->p_cur.p;
+
+       return NULL;
+}
+
+static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx)
+{
+       struct v4l2_ctrl_handler *hdl = &ctx->hdl;
+       struct v4l2_ctrl *ctrl;
+       unsigned int ctrl_size;
+       unsigned int i;
+
+       v4l2_ctrl_handler_init(hdl, CEDRUS_CONTROLS_COUNT);
+       if (hdl->error) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Failed to initialize control handler\n");
+               return hdl->error;
+       }
+
+       ctrl_size = sizeof(ctrl) * CEDRUS_CONTROLS_COUNT + 1;
+
+       ctx->ctrls = kzalloc(ctrl_size, GFP_KERNEL);
+       memset(ctx->ctrls, 0, ctrl_size);
+
+       for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) {
+               struct v4l2_ctrl_config cfg = { 0 };
+
+               cfg.elem_size = cedrus_controls[i].elem_size;
+               cfg.id = cedrus_controls[i].id;
+
+               ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
+               if (hdl->error) {
+                       v4l2_err(&dev->v4l2_dev,
+                                "Failed to create new custom control\n");
+
+                       v4l2_ctrl_handler_free(hdl);
+                       kfree(ctx->ctrls);
+                       return hdl->error;
+               }
+
+               ctx->ctrls[i] = ctrl;
+       }
+
+       ctx->fh.ctrl_handler = hdl;
+       v4l2_ctrl_handler_setup(hdl);
+
+       return 0;
+}
+
+static int cedrus_request_validate(struct media_request *req)
+{
+       struct media_request_object *obj;
+       struct v4l2_ctrl_handler *parent_hdl, *hdl;
+       struct cedrus_ctx *ctx = NULL;
+       struct v4l2_ctrl *ctrl_test;
+       unsigned int count;
+       unsigned int i;
+
+       count = vb2_request_buffer_cnt(req);
+       if (!count) {
+               v4l2_info(&ctx->dev->v4l2_dev,
+                         "No buffer was provided with the request\n");
+               return -ENOENT;
+       } else if (count > 1) {
+               v4l2_info(&ctx->dev->v4l2_dev,
+                         "More than one buffer was provided with the request\n");
+               return -EINVAL;
+       }
+
+       list_for_each_entry(obj, &req->objects, list) {
+               struct vb2_buffer *vb;
+
+               if (vb2_request_object_is_buffer(obj)) {
+                       vb = container_of(obj, struct vb2_buffer, req_obj);
+                       ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+                       break;
+               }
+       }
+
+       if (!ctx)
+               return -ENOENT;
+
+       parent_hdl = &ctx->hdl;
+
+       hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
+       if (!hdl) {
+               v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control(s)\n");
+               return -ENOENT;
+       }
+
+       for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) {
+               if (cedrus_controls[i].codec != ctx->current_codec ||
+                   !cedrus_controls[i].required)
+                       continue;
+
+               ctrl_test = v4l2_ctrl_request_hdl_ctrl_find(hdl,
+                                                           cedrus_controls[i].id);
+               if (!ctrl_test) {
+                       v4l2_info(&ctx->dev->v4l2_dev,
+                                 "Missing required codec control\n");
+                       return -ENOENT;
+               }
+       }
+
+       v4l2_ctrl_request_hdl_put(hdl);
+
+       return vb2_request_validate(req);
+}
+
+static int cedrus_open(struct file *file)
+{
+       struct cedrus_dev *dev = video_drvdata(file);
+       struct cedrus_ctx *ctx = NULL;
+       int ret;
+
+       if (mutex_lock_interruptible(&dev->dev_mutex))
+               return -ERESTARTSYS;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx) {
+               mutex_unlock(&dev->dev_mutex);
+               return -ENOMEM;
+       }
+
+       v4l2_fh_init(&ctx->fh, video_devdata(file));
+       file->private_data = &ctx->fh;
+       ctx->dev = dev;
+
+       ret = cedrus_init_ctrls(dev, ctx);
+       if (ret)
+               goto err_free;
+
+       ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
+                                           &cedrus_queue_init);
+       if (IS_ERR(ctx->fh.m2m_ctx)) {
+               ret = PTR_ERR(ctx->fh.m2m_ctx);
+               goto err_ctrls;
+       }
+
+       v4l2_fh_add(&ctx->fh);
+
+       mutex_unlock(&dev->dev_mutex);
+
+       return 0;
+
+err_ctrls:
+       v4l2_ctrl_handler_free(&ctx->hdl);
+err_free:
+       kfree(ctx);
+       mutex_unlock(&dev->dev_mutex);
+
+       return ret;
+}
+
+static int cedrus_release(struct file *file)
+{
+       struct cedrus_dev *dev = video_drvdata(file);
+       struct cedrus_ctx *ctx = container_of(file->private_data,
+                                             struct cedrus_ctx, fh);
+
+       mutex_lock(&dev->dev_mutex);
+
+       v4l2_fh_del(&ctx->fh);
+       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+
+       v4l2_ctrl_handler_free(&ctx->hdl);
+       kfree(ctx->ctrls);
+
+       v4l2_fh_exit(&ctx->fh);
+
+       kfree(ctx);
+
+       mutex_unlock(&dev->dev_mutex);
+
+       return 0;
+}
+
+static const struct v4l2_file_operations cedrus_fops = {
+       .owner          = THIS_MODULE,
+       .open           = cedrus_open,
+       .release        = cedrus_release,
+       .poll           = v4l2_m2m_fop_poll,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap           = v4l2_m2m_fop_mmap,
+};
+
+static const struct video_device cedrus_video_device = {
+       .name           = CEDRUS_NAME,
+       .vfl_dir        = VFL_DIR_M2M,
+       .fops           = &cedrus_fops,
+       .ioctl_ops      = &cedrus_ioctl_ops,
+       .minor          = -1,
+       .release        = video_device_release_empty,
+       .device_caps    = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
+};
+
+static const struct v4l2_m2m_ops cedrus_m2m_ops = {
+       .device_run     = cedrus_device_run,
+};
+
+static const struct media_device_ops cedrus_m2m_media_ops = {
+       .req_validate   = cedrus_request_validate,
+       .req_queue      = vb2_m2m_request_queue,
+};
+
+static int cedrus_probe(struct platform_device *pdev)
+{
+       struct cedrus_dev *dev;
+       struct video_device *vfd;
+       int ret;
+
+       dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       dev->vfd = cedrus_video_device;
+       dev->dev = &pdev->dev;
+       dev->pdev = pdev;
+
+       ret = cedrus_hw_probe(dev);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to probe hardware\n");
+               return ret;
+       }
+
+       dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
+
+       mutex_init(&dev->dev_mutex);
+       spin_lock_init(&dev->irq_lock);
+
+       ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to register V4L2 device\n");
+               return ret;
+       }
+
+       vfd = &dev->vfd;
+       vfd->lock = &dev->dev_mutex;
+       vfd->v4l2_dev = &dev->v4l2_dev;
+
+       snprintf(vfd->name, sizeof(vfd->name), "%s", cedrus_video_device.name);
+       video_set_drvdata(vfd, dev);
+
+       dev->m2m_dev = v4l2_m2m_init(&cedrus_m2m_ops);
+       if (IS_ERR(dev->m2m_dev)) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Failed to initialize V4L2 M2M device\n");
+               ret = PTR_ERR(dev->m2m_dev);
+
+               goto err_video;
+       }
+
+       dev->mdev.dev = &pdev->dev;
+       strscpy(dev->mdev.model, CEDRUS_NAME, sizeof(dev->mdev.model));
+
+       media_device_init(&dev->mdev);
+       dev->mdev.ops = &cedrus_m2m_media_ops;
+       dev->v4l2_dev.mdev = &dev->mdev;
+
+       ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
+                                                MEDIA_ENT_F_PROC_VIDEO_DECODER);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Failed to initialize V4L2 M2M media controller\n");
+               goto err_m2m;
+       }
+
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+               goto err_v4l2;
+       }
+
+       v4l2_info(&dev->v4l2_dev,
+                 "Device registered as /dev/video%d\n", vfd->num);
+
+       ret = media_device_register(&dev->mdev);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to register media device\n");
+               goto err_m2m_mc;
+       }
+
+       platform_set_drvdata(pdev, dev);
+
+       return 0;
+
+err_m2m_mc:
+       v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+err_m2m:
+       v4l2_m2m_release(dev->m2m_dev);
+err_video:
+       video_unregister_device(&dev->vfd);
+err_v4l2:
+       v4l2_device_unregister(&dev->v4l2_dev);
+
+       return ret;
+}
+
+static int cedrus_remove(struct platform_device *pdev)
+{
+       struct cedrus_dev *dev = platform_get_drvdata(pdev);
+
+       if (media_devnode_is_registered(dev->mdev.devnode)) {
+               media_device_unregister(&dev->mdev);
+               v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+               media_device_cleanup(&dev->mdev);
+       }
+
+       v4l2_m2m_release(dev->m2m_dev);
+       video_unregister_device(&dev->vfd);
+       v4l2_device_unregister(&dev->v4l2_dev);
+
+       cedrus_hw_remove(dev);
+
+       return 0;
+}
+
+static const struct cedrus_variant sun4i_a10_cedrus_variant = {
+       /* No particular capability. */
+};
+
+static const struct cedrus_variant sun5i_a13_cedrus_variant = {
+       /* No particular capability. */
+};
+
+static const struct cedrus_variant sun7i_a20_cedrus_variant = {
+       /* No particular capability. */
+};
+
+static const struct cedrus_variant sun8i_a33_cedrus_variant = {
+       .capabilities   = CEDRUS_CAPABILITY_UNTILED,
+};
+
+static const struct cedrus_variant sun8i_h3_cedrus_variant = {
+       .capabilities   = CEDRUS_CAPABILITY_UNTILED,
+};
+
+static const struct of_device_id cedrus_dt_match[] = {
+       {
+               .compatible = "allwinner,sun4i-a10-video-engine",
+               .data = &sun4i_a10_cedrus_variant,
+       },
+       {
+               .compatible = "allwinner,sun5i-a13-video-engine",
+               .data = &sun5i_a13_cedrus_variant,
+       },
+       {
+               .compatible = "allwinner,sun7i-a20-video-engine",
+               .data = &sun7i_a20_cedrus_variant,
+       },
+       {
+               .compatible = "allwinner,sun8i-a33-video-engine",
+               .data = &sun8i_a33_cedrus_variant,
+       },
+       {
+               .compatible = "allwinner,sun8i-h3-video-engine",
+               .data = &sun8i_h3_cedrus_variant,
+       },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cedrus_dt_match);
+
+static struct platform_driver cedrus_driver = {
+       .probe          = cedrus_probe,
+       .remove         = cedrus_remove,
+       .driver         = {
+               .name           = CEDRUS_NAME,
+               .owner          = THIS_MODULE,
+               .of_match_table = of_match_ptr(cedrus_dt_match),
+       },
+};
+module_platform_driver(cedrus_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Florent Revest <florent.revest@free-electrons.com>");
+MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
+MODULE_DESCRIPTION("Cedrus VPU driver");
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
new file mode 100644 (file)
index 0000000..3f61248
--- /dev/null
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#ifndef _CEDRUS_H_
+#define _CEDRUS_H_
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include <linux/platform_device.h>
+
+#define CEDRUS_NAME                    "cedrus"
+
+#define CEDRUS_CAPABILITY_UNTILED      BIT(0)
+
+enum cedrus_codec {
+       CEDRUS_CODEC_MPEG2,
+
+       CEDRUS_CODEC_LAST,
+};
+
+enum cedrus_irq_status {
+       CEDRUS_IRQ_NONE,
+       CEDRUS_IRQ_ERROR,
+       CEDRUS_IRQ_OK,
+};
+
+struct cedrus_control {
+       u32                     id;
+       u32                     elem_size;
+       enum cedrus_codec       codec;
+       unsigned char           required:1;
+};
+
+struct cedrus_mpeg2_run {
+       const struct v4l2_ctrl_mpeg2_slice_params       *slice_params;
+       const struct v4l2_ctrl_mpeg2_quantization       *quantization;
+};
+
+struct cedrus_run {
+       struct vb2_v4l2_buffer  *src;
+       struct vb2_v4l2_buffer  *dst;
+
+       union {
+               struct cedrus_mpeg2_run mpeg2;
+       };
+};
+
+struct cedrus_buffer {
+       struct v4l2_m2m_buffer          m2m_buf;
+};
+
+struct cedrus_ctx {
+       struct v4l2_fh                  fh;
+       struct cedrus_dev               *dev;
+
+       struct v4l2_pix_format          src_fmt;
+       struct v4l2_pix_format          dst_fmt;
+       enum cedrus_codec               current_codec;
+
+       struct v4l2_ctrl_handler        hdl;
+       struct v4l2_ctrl                **ctrls;
+
+       struct vb2_buffer               *dst_bufs[VIDEO_MAX_FRAME];
+};
+
+struct cedrus_dec_ops {
+       void (*irq_clear)(struct cedrus_ctx *ctx);
+       void (*irq_disable)(struct cedrus_ctx *ctx);
+       enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
+       void (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
+       int (*start)(struct cedrus_ctx *ctx);
+       void (*stop)(struct cedrus_ctx *ctx);
+       void (*trigger)(struct cedrus_ctx *ctx);
+};
+
+struct cedrus_variant {
+       unsigned int    capabilities;
+};
+
+struct cedrus_dev {
+       struct v4l2_device      v4l2_dev;
+       struct video_device     vfd;
+       struct media_device     mdev;
+       struct media_pad        pad[2];
+       struct platform_device  *pdev;
+       struct device           *dev;
+       struct v4l2_m2m_dev     *m2m_dev;
+       struct cedrus_dec_ops   *dec_ops[CEDRUS_CODEC_LAST];
+
+       /* Device file mutex */
+       struct mutex            dev_mutex;
+       /* Interrupt spinlock */
+       spinlock_t              irq_lock;
+
+       void __iomem            *base;
+
+       struct clk              *mod_clk;
+       struct clk              *ahb_clk;
+       struct clk              *ram_clk;
+
+       struct reset_control    *rstc;
+
+       unsigned int            capabilities;
+};
+
+extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
+
+static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
+{
+       writel(val, dev->base + reg);
+}
+
+static inline u32 cedrus_read(struct cedrus_dev *dev, u32 reg)
+{
+       return readl(dev->base + reg);
+}
+
+static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
+                                        struct v4l2_pix_format *pix_fmt,
+                                        unsigned int plane)
+{
+       dma_addr_t addr = vb2_dma_contig_plane_dma_addr(buf, 0);
+
+       return addr + (pix_fmt ? (dma_addr_t)pix_fmt->bytesperline *
+              pix_fmt->height * plane : 0);
+}
+
+static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
+                                            unsigned int index,
+                                            unsigned int plane)
+{
+       struct vb2_buffer *buf = ctx->dst_bufs[index];
+
+       return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
+}
+
+static inline struct cedrus_buffer *
+vb2_v4l2_to_cedrus_buffer(const struct vb2_v4l2_buffer *p)
+{
+       return container_of(p, struct cedrus_buffer, m2m_buf.vb);
+}
+
+static inline struct cedrus_buffer *
+vb2_to_cedrus_buffer(const struct vb2_buffer *p)
+{
+       return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
+}
+
+void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
+
+#endif
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
new file mode 100644 (file)
index 0000000..e40180a
--- /dev/null
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "cedrus.h"
+#include "cedrus_dec.h"
+#include "cedrus_hw.h"
+
+void cedrus_device_run(void *priv)
+{
+       struct cedrus_ctx *ctx = priv;
+       struct cedrus_dev *dev = ctx->dev;
+       struct cedrus_run run = { 0 };
+       struct media_request *src_req;
+       unsigned long flags;
+
+       run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+       run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+       /* Apply request(s) controls if needed. */
+       src_req = run.src->vb2_buf.req_obj.req;
+
+       if (src_req)
+               v4l2_ctrl_request_setup(src_req, &ctx->hdl);
+
+       spin_lock_irqsave(&ctx->dev->irq_lock, flags);
+
+       switch (ctx->src_fmt.pixelformat) {
+       case V4L2_PIX_FMT_MPEG2_SLICE:
+               run.mpeg2.slice_params = cedrus_find_control_data(ctx,
+                       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
+               run.mpeg2.quantization = cedrus_find_control_data(ctx,
+                       V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
+               break;
+
+       default:
+               break;
+       }
+
+       dev->dec_ops[ctx->current_codec]->setup(ctx, &run);
+
+       spin_unlock_irqrestore(&ctx->dev->irq_lock, flags);
+
+       /* Complete request(s) controls if needed. */
+
+       if (src_req)
+               v4l2_ctrl_request_complete(src_req, &ctx->hdl);
+
+       spin_lock_irqsave(&ctx->dev->irq_lock, flags);
+
+       dev->dec_ops[ctx->current_codec]->trigger(ctx);
+
+       spin_unlock_irqrestore(&ctx->dev->irq_lock, flags);
+}
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.h b/drivers/staging/media/sunxi/cedrus/cedrus_dec.h
new file mode 100644 (file)
index 0000000..4f423d3
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#ifndef _CEDRUS_DEC_H_
+#define _CEDRUS_DEC_H_
+
+extern const struct v4l2_ioctl_ops cedrus_ioctl_ops;
+
+void cedrus_device_work(struct work_struct *work);
+void cedrus_device_run(void *priv);
+
+int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
+                     struct vb2_queue *dst_vq);
+
+#endif
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
new file mode 100644 (file)
index 0000000..32adbcb
--- /dev/null
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/soc/sunxi/sunxi_sram.h>
+
+#include <media/videobuf2-core.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "cedrus.h"
+#include "cedrus_hw.h"
+#include "cedrus_regs.h"
+
+int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
+{
+       u32 reg = 0;
+
+       /*
+        * FIXME: This is only valid on 32-bits DDR's, we should test
+        * it on the A13/A33.
+        */
+       reg |= VE_MODE_REC_WR_MODE_2MB;
+       reg |= VE_MODE_DDR_MODE_BW_128;
+
+       switch (codec) {
+       case CEDRUS_CODEC_MPEG2:
+               reg |= VE_MODE_DEC_MPEG;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       cedrus_write(dev, VE_MODE, reg);
+
+       return 0;
+}
+
+void cedrus_engine_disable(struct cedrus_dev *dev)
+{
+       cedrus_write(dev, VE_MODE, VE_MODE_DISABLED);
+}
+
+void cedrus_dst_format_set(struct cedrus_dev *dev,
+                          struct v4l2_pix_format *fmt)
+{
+       unsigned int width = fmt->width;
+       unsigned int height = fmt->height;
+       u32 chroma_size;
+       u32 reg;
+
+       switch (fmt->pixelformat) {
+       case V4L2_PIX_FMT_NV12:
+               chroma_size = ALIGN(width, 16) * ALIGN(height, 16) / 2;
+
+               reg = VE_PRIMARY_OUT_FMT_NV12;
+               cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg);
+
+               reg = VE_CHROMA_BUF_LEN_SDRT(chroma_size / 2);
+               cedrus_write(dev, VE_CHROMA_BUF_LEN, reg);
+
+               reg = chroma_size / 2;
+               cedrus_write(dev, VE_PRIMARY_CHROMA_BUF_LEN, reg);
+
+               reg = VE_PRIMARY_FB_LINE_STRIDE_LUMA(ALIGN(width, 16)) |
+                     VE_PRIMARY_FB_LINE_STRIDE_CHROMA(ALIGN(width, 16) / 2);
+               cedrus_write(dev, VE_PRIMARY_FB_LINE_STRIDE, reg);
+
+               break;
+       case V4L2_PIX_FMT_SUNXI_TILED_NV12:
+       default:
+               reg = VE_PRIMARY_OUT_FMT_TILED_32_NV12;
+               cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg);
+
+               reg = VE_SECONDARY_OUT_FMT_TILED_32_NV12;
+               cedrus_write(dev, VE_CHROMA_BUF_LEN, reg);
+
+               break;
+       }
+}
+
+static irqreturn_t cedrus_bh(int irq, void *data)
+{
+       struct cedrus_dev *dev = data;
+       struct cedrus_ctx *ctx;
+
+       ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+       if (!ctx) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Instance released before the end of transaction\n");
+               return IRQ_HANDLED;
+       }
+
+       v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t cedrus_irq(int irq, void *data)
+{
+       struct cedrus_dev *dev = data;
+       struct cedrus_ctx *ctx;
+       struct vb2_v4l2_buffer *src_buf, *dst_buf;
+       enum vb2_buffer_state state;
+       enum cedrus_irq_status status;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->irq_lock, flags);
+
+       ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+       if (!ctx) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Instance released before the end of transaction\n");
+               spin_unlock_irqrestore(&dev->irq_lock, flags);
+
+               return IRQ_NONE;
+       }
+
+       status = dev->dec_ops[ctx->current_codec]->irq_status(ctx);
+       if (status == CEDRUS_IRQ_NONE) {
+               spin_unlock_irqrestore(&dev->irq_lock, flags);
+               return IRQ_NONE;
+       }
+
+       dev->dec_ops[ctx->current_codec]->irq_disable(ctx);
+       dev->dec_ops[ctx->current_codec]->irq_clear(ctx);
+
+       src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+       dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+
+       if (!src_buf || !dst_buf) {
+               v4l2_err(&dev->v4l2_dev,
+                        "Missing source and/or destination buffers\n");
+               spin_unlock_irqrestore(&dev->irq_lock, flags);
+
+               return IRQ_HANDLED;
+       }
+
+       if (status == CEDRUS_IRQ_ERROR)
+               state = VB2_BUF_STATE_ERROR;
+       else
+               state = VB2_BUF_STATE_DONE;
+
+       v4l2_m2m_buf_done(src_buf, state);
+       v4l2_m2m_buf_done(dst_buf, state);
+
+       spin_unlock_irqrestore(&dev->irq_lock, flags);
+
+       return IRQ_WAKE_THREAD;
+}
+
+int cedrus_hw_probe(struct cedrus_dev *dev)
+{
+       const struct cedrus_variant *variant;
+       struct resource *res;
+       int irq_dec;
+       int ret;
+
+       variant = of_device_get_match_data(dev->dev);
+       if (!variant)
+               return -EINVAL;
+
+       dev->capabilities = variant->capabilities;
+
+       irq_dec = platform_get_irq(dev->pdev, 0);
+       if (irq_dec <= 0) {
+               v4l2_err(&dev->v4l2_dev, "Failed to get IRQ\n");
+
+               return irq_dec;
+       }
+       ret = devm_request_threaded_irq(dev->dev, irq_dec, cedrus_irq,
+                                       cedrus_bh, 0, dev_name(dev->dev),
+                                       dev);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to request IRQ\n");
+
+               return ret;
+       }
+
+       /*
+        * The VPU is only able to handle bus addresses so we have to subtract
+        * the RAM offset to the physcal addresses.
+        *
+        * This information will eventually be obtained from device-tree.
+        */
+
+#ifdef PHYS_PFN_OFFSET
+       dev->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
+#endif
+
+       ret = of_reserved_mem_device_init(dev->dev);
+       if (ret && ret != -ENODEV) {
+               v4l2_err(&dev->v4l2_dev, "Failed to reserve memory\n");
+
+               return ret;
+       }
+
+       ret = sunxi_sram_claim(dev->dev);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to claim SRAM\n");
+
+               goto err_mem;
+       }
+
+       dev->ahb_clk = devm_clk_get(dev->dev, "ahb");
+       if (IS_ERR(dev->ahb_clk)) {
+               v4l2_err(&dev->v4l2_dev, "Failed to get AHB clock\n");
+
+               ret = PTR_ERR(dev->ahb_clk);
+               goto err_sram;
+       }
+
+       dev->mod_clk = devm_clk_get(dev->dev, "mod");
+       if (IS_ERR(dev->mod_clk)) {
+               v4l2_err(&dev->v4l2_dev, "Failed to get MOD clock\n");
+
+               ret = PTR_ERR(dev->mod_clk);
+               goto err_sram;
+       }
+
+       dev->ram_clk = devm_clk_get(dev->dev, "ram");
+       if (IS_ERR(dev->ram_clk)) {
+               v4l2_err(&dev->v4l2_dev, "Failed to get RAM clock\n");
+
+               ret = PTR_ERR(dev->ram_clk);
+               goto err_sram;
+       }
+
+       dev->rstc = devm_reset_control_get(dev->dev, NULL);
+       if (IS_ERR(dev->rstc)) {
+               v4l2_err(&dev->v4l2_dev, "Failed to get reset control\n");
+
+               ret = PTR_ERR(dev->rstc);
+               goto err_sram;
+       }
+
+       res = platform_get_resource(dev->pdev, IORESOURCE_MEM, 0);
+       dev->base = devm_ioremap_resource(dev->dev, res);
+       if (!dev->base) {
+               v4l2_err(&dev->v4l2_dev, "Failed to map registers\n");
+
+               ret = -ENOMEM;
+               goto err_sram;
+       }
+
+       ret = clk_set_rate(dev->mod_clk, CEDRUS_CLOCK_RATE_DEFAULT);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to set clock rate\n");
+
+               goto err_sram;
+       }
+
+       ret = clk_prepare_enable(dev->ahb_clk);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to enable AHB clock\n");
+
+               goto err_sram;
+       }
+
+       ret = clk_prepare_enable(dev->mod_clk);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to enable MOD clock\n");
+
+               goto err_ahb_clk;
+       }
+
+       ret = clk_prepare_enable(dev->ram_clk);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to enable RAM clock\n");
+
+               goto err_mod_clk;
+       }
+
+       ret = reset_control_reset(dev->rstc);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to apply reset\n");
+
+               goto err_ram_clk;
+       }
+
+       return 0;
+
+err_ram_clk:
+       clk_disable_unprepare(dev->ram_clk);
+err_mod_clk:
+       clk_disable_unprepare(dev->mod_clk);
+err_ahb_clk:
+       clk_disable_unprepare(dev->ahb_clk);
+err_sram:
+       sunxi_sram_release(dev->dev);
+err_mem:
+       of_reserved_mem_device_release(dev->dev);
+
+       return ret;
+}
+
+void cedrus_hw_remove(struct cedrus_dev *dev)
+{
+       reset_control_assert(dev->rstc);
+
+       clk_disable_unprepare(dev->ram_clk);
+       clk_disable_unprepare(dev->mod_clk);
+       clk_disable_unprepare(dev->ahb_clk);
+
+       sunxi_sram_release(dev->dev);
+
+       of_reserved_mem_device_release(dev->dev);
+}
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
new file mode 100644 (file)
index 0000000..b43c77d
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#ifndef _CEDRUS_HW_H_
+#define _CEDRUS_HW_H_
+
+#define CEDRUS_CLOCK_RATE_DEFAULT      320000000
+
+int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec);
+void cedrus_engine_disable(struct cedrus_dev *dev);
+
+void cedrus_dst_format_set(struct cedrus_dev *dev,
+                          struct v4l2_pix_format *fmt);
+
+int cedrus_hw_probe(struct cedrus_dev *dev);
+void cedrus_hw_remove(struct cedrus_dev *dev);
+
+#endif
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
new file mode 100644 (file)
index 0000000..9abd39c
--- /dev/null
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ */
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "cedrus.h"
+#include "cedrus_hw.h"
+#include "cedrus_regs.h"
+
+/* Default MPEG-2 quantization coefficients, from the specification. */
+
+static const u8 intra_quantization_matrix_default[64] = {
+       8,  16, 16, 19, 16, 19, 22, 22,
+       22, 22, 22, 22, 26, 24, 26, 27,
+       27, 27, 26, 26, 26, 26, 27, 27,
+       27, 29, 29, 29, 34, 34, 34, 29,
+       29, 29, 27, 27, 29, 29, 32, 32,
+       34, 34, 37, 38, 37, 35, 35, 34,
+       35, 38, 38, 40, 40, 40, 48, 48,
+       46, 46, 56, 56, 58, 69, 69, 83
+};
+
+static const u8 non_intra_quantization_matrix_default[64] = {
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16,
+       16, 16, 16, 16, 16, 16, 16, 16
+};
+
+static enum cedrus_irq_status cedrus_mpeg2_irq_status(struct cedrus_ctx *ctx)
+{
+       struct cedrus_dev *dev = ctx->dev;
+       u32 reg;
+
+       reg = cedrus_read(dev, VE_DEC_MPEG_STATUS);
+       reg &= VE_DEC_MPEG_STATUS_CHECK_MASK;
+
+       if (!reg)
+               return CEDRUS_IRQ_NONE;
+
+       if (reg & VE_DEC_MPEG_STATUS_CHECK_ERROR ||
+           !(reg & VE_DEC_MPEG_STATUS_SUCCESS))
+               return CEDRUS_IRQ_ERROR;
+
+       return CEDRUS_IRQ_OK;
+}
+
+static void cedrus_mpeg2_irq_clear(struct cedrus_ctx *ctx)
+{
+       struct cedrus_dev *dev = ctx->dev;
+
+       cedrus_write(dev, VE_DEC_MPEG_STATUS, VE_DEC_MPEG_STATUS_CHECK_MASK);
+}
+
+static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx)
+{
+       struct cedrus_dev *dev = ctx->dev;
+       u32 reg = cedrus_read(dev, VE_DEC_MPEG_CTRL);
+
+       reg &= ~VE_DEC_MPEG_CTRL_IRQ_MASK;
+
+       cedrus_write(dev, VE_DEC_MPEG_CTRL, reg);
+}
+
+static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+{
+       const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
+       const struct v4l2_mpeg2_sequence *sequence;
+       const struct v4l2_mpeg2_picture *picture;
+       const struct v4l2_ctrl_mpeg2_quantization *quantization;
+       dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
+       dma_addr_t fwd_luma_addr, fwd_chroma_addr;
+       dma_addr_t bwd_luma_addr, bwd_chroma_addr;
+       struct cedrus_dev *dev = ctx->dev;
+       const u8 *matrix;
+       unsigned int i;
+       u32 reg;
+
+       slice_params = run->mpeg2.slice_params;
+       sequence = &slice_params->sequence;
+       picture = &slice_params->picture;
+
+       quantization = run->mpeg2.quantization;
+
+       /* Activate MPEG engine. */
+       cedrus_engine_enable(dev, CEDRUS_CODEC_MPEG2);
+
+       /* Set intra quantization matrix. */
+
+       if (quantization && quantization->load_intra_quantiser_matrix)
+               matrix = quantization->intra_quantiser_matrix;
+       else
+               matrix = intra_quantization_matrix_default;
+
+       for (i = 0; i < 64; i++) {
+               reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
+               reg |= VE_DEC_MPEG_IQMINPUT_FLAG_INTRA;
+
+               cedrus_write(dev, VE_DEC_MPEG_IQMINPUT, reg);
+       }
+
+       /* Set non-intra quantization matrix. */
+
+       if (quantization && quantization->load_non_intra_quantiser_matrix)
+               matrix = quantization->non_intra_quantiser_matrix;
+       else
+               matrix = non_intra_quantization_matrix_default;
+
+       for (i = 0; i < 64; i++) {
+               reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]);
+               reg |= VE_DEC_MPEG_IQMINPUT_FLAG_NON_INTRA;
+
+               cedrus_write(dev, VE_DEC_MPEG_IQMINPUT, reg);
+       }
+
+       /* Set MPEG picture header. */
+
+       reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(picture->picture_coding_type);
+       reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, picture->f_code[0][0]);
+       reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, picture->f_code[0][1]);
+       reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, picture->f_code[1][0]);
+       reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, picture->f_code[1][1]);
+       reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(picture->intra_dc_precision);
+       reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(picture->picture_structure);
+       reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(picture->top_field_first);
+       reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(picture->frame_pred_frame_dct);
+       reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(picture->concealment_motion_vectors);
+       reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(picture->q_scale_type);
+       reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(picture->intra_vlc_format);
+       reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(picture->alternate_scan);
+       reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_FORWARD_VECTOR(0);
+       reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_BACKWARD_VECTOR(0);
+
+       cedrus_write(dev, VE_DEC_MPEG_MP12HDR, reg);
+
+       /* Set frame dimensions. */
+
+       reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(sequence->horizontal_size);
+       reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(sequence->vertical_size);
+
+       cedrus_write(dev, VE_DEC_MPEG_PICCODEDSIZE, reg);
+
+       reg = VE_DEC_MPEG_PICBOUNDSIZE_WIDTH(ctx->src_fmt.width);
+       reg |= VE_DEC_MPEG_PICBOUNDSIZE_HEIGHT(ctx->src_fmt.height);
+
+       cedrus_write(dev, VE_DEC_MPEG_PICBOUNDSIZE, reg);
+
+       /* Forward and backward prediction reference buffers. */
+
+       fwd_luma_addr = cedrus_dst_buf_addr(ctx,
+                                           slice_params->forward_ref_index,
+                                           0);
+       fwd_chroma_addr = cedrus_dst_buf_addr(ctx,
+                                             slice_params->forward_ref_index,
+                                             1);
+
+       cedrus_write(dev, VE_DEC_MPEG_FWD_REF_LUMA_ADDR, fwd_luma_addr);
+       cedrus_write(dev, VE_DEC_MPEG_FWD_REF_CHROMA_ADDR, fwd_chroma_addr);
+
+       bwd_luma_addr = cedrus_dst_buf_addr(ctx,
+                                           slice_params->backward_ref_index,
+                                           0);
+       bwd_chroma_addr = cedrus_dst_buf_addr(ctx,
+                                             slice_params->backward_ref_index,
+                                             1);
+
+       cedrus_write(dev, VE_DEC_MPEG_BWD_REF_LUMA_ADDR, bwd_luma_addr);
+       cedrus_write(dev, VE_DEC_MPEG_BWD_REF_CHROMA_ADDR, bwd_chroma_addr);
+
+       /* Destination luma and chroma buffers. */
+
+       dst_luma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 0);
+       dst_chroma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 1);
+
+       cedrus_write(dev, VE_DEC_MPEG_REC_LUMA, dst_luma_addr);
+       cedrus_write(dev, VE_DEC_MPEG_REC_CHROMA, dst_chroma_addr);
+
+       /* Source offset and length in bits. */
+
+       cedrus_write(dev, VE_DEC_MPEG_VLD_OFFSET,
+                    slice_params->data_bit_offset);
+
+       reg = slice_params->bit_size - slice_params->data_bit_offset;
+       cedrus_write(dev, VE_DEC_MPEG_VLD_LEN, reg);
+
+       /* Source beginning and end addresses. */
+
+       src_buf_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, 0);
+
+       reg = VE_DEC_MPEG_VLD_ADDR_BASE(src_buf_addr);
+       reg |= VE_DEC_MPEG_VLD_ADDR_VALID_PIC_DATA;
+       reg |= VE_DEC_MPEG_VLD_ADDR_LAST_PIC_DATA;
+       reg |= VE_DEC_MPEG_VLD_ADDR_FIRST_PIC_DATA;
+
+       cedrus_write(dev, VE_DEC_MPEG_VLD_ADDR, reg);
+
+       reg = src_buf_addr + DIV_ROUND_UP(slice_params->bit_size, 8);
+       cedrus_write(dev, VE_DEC_MPEG_VLD_END_ADDR, reg);
+
+       /* Macroblock address: start at the beginning. */
+       reg = VE_DEC_MPEG_MBADDR_Y(0) | VE_DEC_MPEG_MBADDR_X(0);
+       cedrus_write(dev, VE_DEC_MPEG_MBADDR, reg);
+
+       /* Clear previous errors. */
+       cedrus_write(dev, VE_DEC_MPEG_ERROR, 0);
+
+       /* Clear correct macroblocks register. */
+       cedrus_write(dev, VE_DEC_MPEG_CRTMBADDR, 0);
+
+       /* Enable appropriate interruptions and components. */
+
+       reg = VE_DEC_MPEG_CTRL_IRQ_MASK | VE_DEC_MPEG_CTRL_MC_NO_WRITEBACK |
+             VE_DEC_MPEG_CTRL_MC_CACHE_EN;
+
+       cedrus_write(dev, VE_DEC_MPEG_CTRL, reg);
+}
+
+static void cedrus_mpeg2_trigger(struct cedrus_ctx *ctx)
+{
+       struct cedrus_dev *dev = ctx->dev;
+       u32 reg;
+
+       /* Trigger MPEG engine. */
+       reg = VE_DEC_MPEG_TRIGGER_HW_MPEG_VLD | VE_DEC_MPEG_TRIGGER_MPEG2 |
+             VE_DEC_MPEG_TRIGGER_MB_BOUNDARY;
+
+       cedrus_write(dev, VE_DEC_MPEG_TRIGGER, reg);
+}
+
+struct cedrus_dec_ops cedrus_dec_ops_mpeg2 = {
+       .irq_clear      = cedrus_mpeg2_irq_clear,
+       .irq_disable    = cedrus_mpeg2_irq_disable,
+       .irq_status     = cedrus_mpeg2_irq_status,
+       .setup          = cedrus_mpeg2_setup,
+       .trigger        = cedrus_mpeg2_trigger,
+};
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
new file mode 100644 (file)
index 0000000..de2d6b6
--- /dev/null
@@ -0,0 +1,235 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (c) 2013-2016 Jens Kuske <jenskuske@gmail.com>
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ */
+
+#ifndef _CEDRUS_REGS_H_
+#define _CEDRUS_REGS_H_
+
+/*
+ * Common acronyms and contractions used in register descriptions:
+ * * VLD : Variable-Length Decoder
+ * * IQ: Inverse Quantization
+ * * IDCT: Inverse Discrete Cosine Transform
+ * * MC: Motion Compensation
+ * * STCD: Start Code Detect
+ * * SDRT: Scale Down and Rotate
+ */
+
+#define VE_ENGINE_DEC_MPEG                     0x100
+#define VE_ENGINE_DEC_H264                     0x200
+
+#define VE_MODE                                        0x00
+
+#define VE_MODE_REC_WR_MODE_2MB                        (0x01 << 20)
+#define VE_MODE_REC_WR_MODE_1MB                        (0x00 << 20)
+#define VE_MODE_DDR_MODE_BW_128                        (0x03 << 16)
+#define VE_MODE_DDR_MODE_BW_256                        (0x02 << 16)
+#define VE_MODE_DISABLED                       (0x07 << 0)
+#define VE_MODE_DEC_H265                       (0x04 << 0)
+#define VE_MODE_DEC_H264                       (0x01 << 0)
+#define VE_MODE_DEC_MPEG                       (0x00 << 0)
+
+#define VE_PRIMARY_CHROMA_BUF_LEN              0xc4
+#define VE_PRIMARY_FB_LINE_STRIDE              0xc8
+
+#define VE_PRIMARY_FB_LINE_STRIDE_CHROMA(s)    (((s) << 16) & GENMASK(31, 16))
+#define VE_PRIMARY_FB_LINE_STRIDE_LUMA(s)      (((s) << 0) & GENMASK(15, 0))
+
+#define VE_CHROMA_BUF_LEN                      0xe8
+
+#define VE_SECONDARY_OUT_FMT_TILED_32_NV12     (0x00 << 30)
+#define VE_SECONDARY_OUT_FMT_EXT               (0x01 << 30)
+#define VE_SECONDARY_OUT_FMT_YU12              (0x02 << 30)
+#define VE_SECONDARY_OUT_FMT_YV12              (0x03 << 30)
+#define VE_CHROMA_BUF_LEN_SDRT(l)              ((l) & GENMASK(27, 0))
+
+#define VE_PRIMARY_OUT_FMT                     0xec
+
+#define VE_PRIMARY_OUT_FMT_TILED_32_NV12       (0x00 << 4)
+#define VE_PRIMARY_OUT_FMT_TILED_128_NV12      (0x01 << 4)
+#define VE_PRIMARY_OUT_FMT_YU12                        (0x02 << 4)
+#define VE_PRIMARY_OUT_FMT_YV12                        (0x03 << 4)
+#define VE_PRIMARY_OUT_FMT_NV12                        (0x04 << 4)
+#define VE_PRIMARY_OUT_FMT_NV21                        (0x05 << 4)
+#define VE_SECONDARY_OUT_FMT_EXT_TILED_32_NV12 (0x00 << 0)
+#define VE_SECONDARY_OUT_FMT_EXT_TILED_128_NV12        (0x01 << 0)
+#define VE_SECONDARY_OUT_FMT_EXT_YU12          (0x02 << 0)
+#define VE_SECONDARY_OUT_FMT_EXT_YV12          (0x03 << 0)
+#define VE_SECONDARY_OUT_FMT_EXT_NV12          (0x04 << 0)
+#define VE_SECONDARY_OUT_FMT_EXT_NV21          (0x05 << 0)
+
+#define VE_VERSION                             0xf0
+
+#define VE_VERSION_SHIFT                       16
+
+#define VE_DEC_MPEG_MP12HDR                    (VE_ENGINE_DEC_MPEG + 0x00)
+
+#define VE_DEC_MPEG_MP12HDR_SLICE_TYPE(t)      (((t) << 28) & GENMASK(30, 28))
+#define VE_DEC_MPEG_MP12HDR_F_CODE_SHIFT(x, y) (24 - 4 * (y) - 8 * (x))
+#define VE_DEC_MPEG_MP12HDR_F_CODE(__x, __y, __v) \
+       (((__v) & GENMASK(3, 0)) << VE_DEC_MPEG_MP12HDR_F_CODE_SHIFT(__x, __y))
+
+#define VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(p) \
+       (((p) << 10) & GENMASK(11, 10))
+#define VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(s) \
+       (((s) << 8) & GENMASK(9, 8))
+#define VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(v) \
+       ((v) ? BIT(7) : 0)
+#define VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(v) \
+       ((v) ? BIT(6) : 0)
+#define VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(v) \
+       ((v) ? BIT(5) : 0)
+#define VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(v) \
+       ((v) ? BIT(4) : 0)
+#define VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(v) \
+       ((v) ? BIT(3) : 0)
+#define VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(v) \
+       ((v) ? BIT(2) : 0)
+#define VE_DEC_MPEG_MP12HDR_FULL_PEL_FORWARD_VECTOR(v) \
+       ((v) ? BIT(1) : 0)
+#define VE_DEC_MPEG_MP12HDR_FULL_PEL_BACKWARD_VECTOR(v) \
+       ((v) ? BIT(0) : 0)
+
+#define VE_DEC_MPEG_PICCODEDSIZE               (VE_ENGINE_DEC_MPEG + 0x08)
+
+#define VE_DEC_MPEG_PICCODEDSIZE_WIDTH(w) \
+       ((DIV_ROUND_UP((w), 16) << 8) & GENMASK(15, 8))
+#define VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(h) \
+       ((DIV_ROUND_UP((h), 16) << 0) & GENMASK(7, 0))
+
+#define VE_DEC_MPEG_PICBOUNDSIZE               (VE_ENGINE_DEC_MPEG + 0x0c)
+
+#define VE_DEC_MPEG_PICBOUNDSIZE_WIDTH(w)      (((w) << 16) & GENMASK(27, 16))
+#define VE_DEC_MPEG_PICBOUNDSIZE_HEIGHT(h)     (((h) << 0) & GENMASK(11, 0))
+
+#define VE_DEC_MPEG_MBADDR                     (VE_ENGINE_DEC_MPEG + 0x10)
+
+#define VE_DEC_MPEG_MBADDR_X(w)                        (((w) << 8) & GENMASK(15, 8))
+#define VE_DEC_MPEG_MBADDR_Y(h)                        (((h) << 0) & GENMASK(0, 7))
+
+#define VE_DEC_MPEG_CTRL                       (VE_ENGINE_DEC_MPEG + 0x14)
+
+#define VE_DEC_MPEG_CTRL_MC_CACHE_EN           BIT(31)
+#define VE_DEC_MPEG_CTRL_SW_VLD                        BIT(27)
+#define VE_DEC_MPEG_CTRL_SW_IQ_IS              BIT(17)
+#define VE_DEC_MPEG_CTRL_QP_AC_DC_OUT_EN       BIT(14)
+#define VE_DEC_MPEG_CTRL_ROTATE_SCALE_OUT_EN   BIT(8)
+#define VE_DEC_MPEG_CTRL_MC_NO_WRITEBACK       BIT(7)
+#define VE_DEC_MPEG_CTRL_ROTATE_IRQ_EN         BIT(6)
+#define VE_DEC_MPEG_CTRL_VLD_DATA_REQ_IRQ_EN   BIT(5)
+#define VE_DEC_MPEG_CTRL_ERROR_IRQ_EN          BIT(4)
+#define VE_DEC_MPEG_CTRL_FINISH_IRQ_EN         BIT(3)
+#define VE_DEC_MPEG_CTRL_IRQ_MASK \
+       (VE_DEC_MPEG_CTRL_FINISH_IRQ_EN | VE_DEC_MPEG_CTRL_ERROR_IRQ_EN | \
+        VE_DEC_MPEG_CTRL_VLD_DATA_REQ_IRQ_EN)
+
+#define VE_DEC_MPEG_TRIGGER                    (VE_ENGINE_DEC_MPEG + 0x18)
+
+#define VE_DEC_MPEG_TRIGGER_MB_BOUNDARY                BIT(31)
+
+#define VE_DEC_MPEG_TRIGGER_CHROMA_FMT_420     (0x00 << 27)
+#define VE_DEC_MPEG_TRIGGER_CHROMA_FMT_411     (0x01 << 27)
+#define VE_DEC_MPEG_TRIGGER_CHROMA_FMT_422     (0x02 << 27)
+#define VE_DEC_MPEG_TRIGGER_CHROMA_FMT_444     (0x03 << 27)
+#define VE_DEC_MPEG_TRIGGER_CHROMA_FMT_422T    (0x04 << 27)
+
+#define VE_DEC_MPEG_TRIGGER_MPEG1              (0x01 << 24)
+#define VE_DEC_MPEG_TRIGGER_MPEG2              (0x02 << 24)
+#define VE_DEC_MPEG_TRIGGER_JPEG               (0x03 << 24)
+#define VE_DEC_MPEG_TRIGGER_MPEG4              (0x04 << 24)
+#define VE_DEC_MPEG_TRIGGER_VP62               (0x05 << 24)
+
+#define VE_DEC_MPEG_TRIGGER_VP62_AC_GET_BITS   BIT(7)
+
+#define VE_DEC_MPEG_TRIGGER_STCD_VC1           (0x02 << 4)
+#define VE_DEC_MPEG_TRIGGER_STCD_MPEG2         (0x01 << 4)
+#define VE_DEC_MPEG_TRIGGER_STCD_AVC           (0x00 << 4)
+
+#define VE_DEC_MPEG_TRIGGER_HW_MPEG_VLD                (0x0f << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_JPEG_VLD                (0x0e << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_MB              (0x0d << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_ROTATE          (0x0c << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_VP6_VLD         (0x0b << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_MAF             (0x0a << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_STCD_END                (0x09 << 0)
+#define VE_DEC_MPEG_TRIGGER_HW_STCD_BEGIN      (0x08 << 0)
+#define VE_DEC_MPEG_TRIGGER_SW_MC              (0x07 << 0)
+#define VE_DEC_MPEG_TRIGGER_SW_IQ              (0x06 << 0)
+#define VE_DEC_MPEG_TRIGGER_SW_IDCT            (0x05 << 0)
+#define VE_DEC_MPEG_TRIGGER_SW_SCALE           (0x04 << 0)
+#define VE_DEC_MPEG_TRIGGER_SW_VP6             (0x03 << 0)
+#define VE_DEC_MPEG_TRIGGER_SW_VP62_AC_GET_BITS        (0x02 << 0)
+
+#define VE_DEC_MPEG_STATUS                     (VE_ENGINE_DEC_MPEG + 0x1c)
+
+#define VE_DEC_MPEG_STATUS_START_DETECT_BUSY   BIT(27)
+#define VE_DEC_MPEG_STATUS_VP6_BIT             BIT(26)
+#define VE_DEC_MPEG_STATUS_VP6_BIT_BUSY                BIT(25)
+#define VE_DEC_MPEG_STATUS_MAF_BUSY            BIT(23)
+#define VE_DEC_MPEG_STATUS_VP6_MVP_BUSY                BIT(22)
+#define VE_DEC_MPEG_STATUS_JPEG_BIT_END                BIT(21)
+#define VE_DEC_MPEG_STATUS_JPEG_RESTART_ERROR  BIT(20)
+#define VE_DEC_MPEG_STATUS_JPEG_MARKER         BIT(19)
+#define VE_DEC_MPEG_STATUS_ROTATE_BUSY         BIT(18)
+#define VE_DEC_MPEG_STATUS_DEBLOCKING_BUSY     BIT(17)
+#define VE_DEC_MPEG_STATUS_SCALE_DOWN_BUSY     BIT(16)
+#define VE_DEC_MPEG_STATUS_IQIS_BUF_EMPTY      BIT(15)
+#define VE_DEC_MPEG_STATUS_IDCT_BUF_EMPTY      BIT(14)
+#define VE_DEC_MPEG_STATUS_VE_BUSY             BIT(13)
+#define VE_DEC_MPEG_STATUS_MC_BUSY             BIT(12)
+#define VE_DEC_MPEG_STATUS_IDCT_BUSY           BIT(11)
+#define VE_DEC_MPEG_STATUS_IQIS_BUSY           BIT(10)
+#define VE_DEC_MPEG_STATUS_DCAC_BUSY           BIT(9)
+#define VE_DEC_MPEG_STATUS_VLD_BUSY            BIT(8)
+#define VE_DEC_MPEG_STATUS_ROTATE_SUCCESS      BIT(3)
+#define VE_DEC_MPEG_STATUS_VLD_DATA_REQ                BIT(2)
+#define VE_DEC_MPEG_STATUS_ERROR               BIT(1)
+#define VE_DEC_MPEG_STATUS_SUCCESS             BIT(0)
+#define VE_DEC_MPEG_STATUS_CHECK_MASK \
+       (VE_DEC_MPEG_STATUS_SUCCESS | VE_DEC_MPEG_STATUS_ERROR | \
+        VE_DEC_MPEG_STATUS_VLD_DATA_REQ)
+#define VE_DEC_MPEG_STATUS_CHECK_ERROR \
+       (VE_DEC_MPEG_STATUS_ERROR | VE_DEC_MPEG_STATUS_VLD_DATA_REQ)
+
+#define VE_DEC_MPEG_VLD_ADDR                   (VE_ENGINE_DEC_MPEG + 0x28)
+
+#define VE_DEC_MPEG_VLD_ADDR_FIRST_PIC_DATA    BIT(30)
+#define VE_DEC_MPEG_VLD_ADDR_LAST_PIC_DATA     BIT(29)
+#define VE_DEC_MPEG_VLD_ADDR_VALID_PIC_DATA    BIT(28)
+#define VE_DEC_MPEG_VLD_ADDR_BASE(a)                                   \
+       ({                                                              \
+               u32 _tmp = (a);                                         \
+               u32 _lo = _tmp & GENMASK(27, 4);                        \
+               u32 _hi = (_tmp >> 28) & GENMASK(3, 0);                 \
+               (_lo | _hi);                                            \
+       })
+
+#define VE_DEC_MPEG_VLD_OFFSET                 (VE_ENGINE_DEC_MPEG + 0x2c)
+#define VE_DEC_MPEG_VLD_LEN                    (VE_ENGINE_DEC_MPEG + 0x30)
+#define VE_DEC_MPEG_VLD_END_ADDR               (VE_ENGINE_DEC_MPEG + 0x34)
+
+#define VE_DEC_MPEG_REC_LUMA                   (VE_ENGINE_DEC_MPEG + 0x48)
+#define VE_DEC_MPEG_REC_CHROMA                 (VE_ENGINE_DEC_MPEG + 0x4c)
+#define VE_DEC_MPEG_FWD_REF_LUMA_ADDR          (VE_ENGINE_DEC_MPEG + 0x50)
+#define VE_DEC_MPEG_FWD_REF_CHROMA_ADDR                (VE_ENGINE_DEC_MPEG + 0x54)
+#define VE_DEC_MPEG_BWD_REF_LUMA_ADDR          (VE_ENGINE_DEC_MPEG + 0x58)
+#define VE_DEC_MPEG_BWD_REF_CHROMA_ADDR                (VE_ENGINE_DEC_MPEG + 0x5c)
+
+#define VE_DEC_MPEG_IQMINPUT                   (VE_ENGINE_DEC_MPEG + 0x80)
+
+#define VE_DEC_MPEG_IQMINPUT_FLAG_INTRA                (0x01 << 14)
+#define VE_DEC_MPEG_IQMINPUT_FLAG_NON_INTRA    (0x00 << 14)
+#define VE_DEC_MPEG_IQMINPUT_WEIGHT(i, v) \
+       (((v) & GENMASK(7, 0)) | (((i) << 8) & GENMASK(13, 8)))
+
+#define VE_DEC_MPEG_ERROR                      (VE_ENGINE_DEC_MPEG + 0xc4)
+#define VE_DEC_MPEG_CRTMBADDR                  (VE_ENGINE_DEC_MPEG + 0xc8)
+#define VE_DEC_MPEG_ROT_LUMA                   (VE_ENGINE_DEC_MPEG + 0xcc)
+#define VE_DEC_MPEG_ROT_CHROMA                 (VE_ENGINE_DEC_MPEG + 0xd0)
+
+#endif
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
new file mode 100644 (file)
index 0000000..5c5fce6
--- /dev/null
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "cedrus.h"
+#include "cedrus_video.h"
+#include "cedrus_dec.h"
+#include "cedrus_hw.h"
+
+#define CEDRUS_DECODE_SRC      BIT(0)
+#define CEDRUS_DECODE_DST      BIT(1)
+
+#define CEDRUS_MIN_WIDTH       16U
+#define CEDRUS_MIN_HEIGHT      16U
+#define CEDRUS_MAX_WIDTH       3840U
+#define CEDRUS_MAX_HEIGHT      2160U
+
+static struct cedrus_format cedrus_formats[] = {
+       {
+               .pixelformat    = V4L2_PIX_FMT_MPEG2_SLICE,
+               .directions     = CEDRUS_DECODE_SRC,
+       },
+       {
+               .pixelformat    = V4L2_PIX_FMT_SUNXI_TILED_NV12,
+               .directions     = CEDRUS_DECODE_DST,
+       },
+       {
+               .pixelformat    = V4L2_PIX_FMT_NV12,
+               .directions     = CEDRUS_DECODE_DST,
+               .capabilities   = CEDRUS_CAPABILITY_UNTILED,
+       },
+};
+
+#define CEDRUS_FORMATS_COUNT   ARRAY_SIZE(cedrus_formats)
+
+static inline struct cedrus_ctx *cedrus_file2ctx(struct file *file)
+{
+       return container_of(file->private_data, struct cedrus_ctx, fh);
+}
+
+static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
+                                               unsigned int capabilities)
+{
+       struct cedrus_format *fmt;
+       unsigned int i;
+
+       for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
+               fmt = &cedrus_formats[i];
+
+               if (fmt->capabilities && (fmt->capabilities & capabilities) !=
+                   fmt->capabilities)
+                       continue;
+
+               if (fmt->pixelformat == pixelformat &&
+                   (fmt->directions & directions) != 0)
+                       break;
+       }
+
+       if (i == CEDRUS_FORMATS_COUNT)
+               return NULL;
+
+       return &cedrus_formats[i];
+}
+
+static bool cedrus_check_format(u32 pixelformat, u32 directions,
+                               unsigned int capabilities)
+{
+       return cedrus_find_format(pixelformat, directions, capabilities);
+}
+
+static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
+{
+       unsigned int width = pix_fmt->width;
+       unsigned int height = pix_fmt->height;
+       unsigned int sizeimage = pix_fmt->sizeimage;
+       unsigned int bytesperline = pix_fmt->bytesperline;
+
+       pix_fmt->field = V4L2_FIELD_NONE;
+
+       /* Limit to hardware min/max. */
+       width = clamp(width, CEDRUS_MIN_WIDTH, CEDRUS_MAX_WIDTH);
+       height = clamp(height, CEDRUS_MIN_HEIGHT, CEDRUS_MAX_HEIGHT);
+
+       switch (pix_fmt->pixelformat) {
+       case V4L2_PIX_FMT_MPEG2_SLICE:
+               /* Zero bytes per line for encoded source. */
+               bytesperline = 0;
+
+               break;
+
+       case V4L2_PIX_FMT_SUNXI_TILED_NV12:
+               /* 32-aligned stride. */
+               bytesperline = ALIGN(width, 32);
+
+               /* 32-aligned height. */
+               height = ALIGN(height, 32);
+
+               /* Luma plane size. */
+               sizeimage = bytesperline * height;
+
+               /* Chroma plane size. */
+               sizeimage += bytesperline * height / 2;
+
+               break;
+
+       case V4L2_PIX_FMT_NV12:
+               /* 16-aligned stride. */
+               bytesperline = ALIGN(width, 16);
+
+               /* 16-aligned height. */
+               height = ALIGN(height, 16);
+
+               /* Luma plane size. */
+               sizeimage = bytesperline * height;
+
+               /* Chroma plane size. */
+               sizeimage += bytesperline * height / 2;
+
+               break;
+       }
+
+       pix_fmt->width = width;
+       pix_fmt->height = height;
+
+       pix_fmt->bytesperline = bytesperline;
+       pix_fmt->sizeimage = sizeimage;
+}
+
+static int cedrus_querycap(struct file *file, void *priv,
+                          struct v4l2_capability *cap)
+{
+       strscpy(cap->driver, CEDRUS_NAME, sizeof(cap->driver));
+       strscpy(cap->card, CEDRUS_NAME, sizeof(cap->card));
+       snprintf(cap->bus_info, sizeof(cap->bus_info),
+                "platform:%s", CEDRUS_NAME);
+
+       return 0;
+}
+
+static int cedrus_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
+                          u32 direction)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+       struct cedrus_dev *dev = ctx->dev;
+       unsigned int capabilities = dev->capabilities;
+       struct cedrus_format *fmt;
+       unsigned int i, index;
+
+       /* Index among formats that match the requested direction. */
+       index = 0;
+
+       for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
+               fmt = &cedrus_formats[i];
+
+               if (fmt->capabilities && (fmt->capabilities & capabilities) !=
+                   fmt->capabilities)
+                       continue;
+
+               if (!(cedrus_formats[i].directions & direction))
+                       continue;
+
+               if (index == f->index)
+                       break;
+
+               index++;
+       }
+
+       /* Matched format. */
+       if (i < CEDRUS_FORMATS_COUNT) {
+               f->pixelformat = cedrus_formats[i].pixelformat;
+
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int cedrus_enum_fmt_vid_cap(struct file *file, void *priv,
+                                  struct v4l2_fmtdesc *f)
+{
+       return cedrus_enum_fmt(file, f, CEDRUS_DECODE_DST);
+}
+
+static int cedrus_enum_fmt_vid_out(struct file *file, void *priv,
+                                  struct v4l2_fmtdesc *f)
+{
+       return cedrus_enum_fmt(file, f, CEDRUS_DECODE_SRC);
+}
+
+static int cedrus_g_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+
+       /* Fall back to dummy default by lack of hardware configuration. */
+       if (!ctx->dst_fmt.width || !ctx->dst_fmt.height) {
+               f->fmt.pix.pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12;
+               cedrus_prepare_format(&f->fmt.pix);
+
+               return 0;
+       }
+
+       f->fmt.pix = ctx->dst_fmt;
+
+       return 0;
+}
+
+static int cedrus_g_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+
+       /* Fall back to dummy default by lack of hardware configuration. */
+       if (!ctx->dst_fmt.width || !ctx->dst_fmt.height) {
+               f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
+               f->fmt.pix.sizeimage = SZ_1K;
+               cedrus_prepare_format(&f->fmt.pix);
+
+               return 0;
+       }
+
+       f->fmt.pix = ctx->src_fmt;
+
+       return 0;
+}
+
+static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+       struct cedrus_dev *dev = ctx->dev;
+       struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
+
+       if (!cedrus_check_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
+                                dev->capabilities))
+               return -EINVAL;
+
+       cedrus_prepare_format(pix_fmt);
+
+       return 0;
+}
+
+static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+       struct cedrus_dev *dev = ctx->dev;
+       struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
+
+       if (!cedrus_check_format(pix_fmt->pixelformat, CEDRUS_DECODE_SRC,
+                                dev->capabilities))
+               return -EINVAL;
+
+       /* Source image size has to be provided by userspace. */
+       if (pix_fmt->sizeimage == 0)
+               return -EINVAL;
+
+       cedrus_prepare_format(pix_fmt);
+
+       return 0;
+}
+
+static int cedrus_s_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+       struct cedrus_dev *dev = ctx->dev;
+       int ret;
+
+       ret = cedrus_try_fmt_vid_cap(file, priv, f);
+       if (ret)
+               return ret;
+
+       ctx->dst_fmt = f->fmt.pix;
+
+       cedrus_dst_format_set(dev, &ctx->dst_fmt);
+
+       return 0;
+}
+
+static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *f)
+{
+       struct cedrus_ctx *ctx = cedrus_file2ctx(file);
+       int ret;
+
+       ret = cedrus_try_fmt_vid_out(file, priv, f);
+       if (ret)
+               return ret;
+
+       ctx->src_fmt = f->fmt.pix;
+
+       /* Propagate colorspace information to capture. */
+       ctx->dst_fmt.colorspace = f->fmt.pix.colorspace;
+       ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func;
+       ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+       ctx->dst_fmt.quantization = f->fmt.pix.quantization;
+
+       return 0;
+}
+
+const struct v4l2_ioctl_ops cedrus_ioctl_ops = {
+       .vidioc_querycap                = cedrus_querycap,
+
+       .vidioc_enum_fmt_vid_cap        = cedrus_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap           = cedrus_g_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap         = cedrus_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap           = cedrus_s_fmt_vid_cap,
+
+       .vidioc_enum_fmt_vid_out        = cedrus_enum_fmt_vid_out,
+       .vidioc_g_fmt_vid_out           = cedrus_g_fmt_vid_out,
+       .vidioc_try_fmt_vid_out         = cedrus_try_fmt_vid_out,
+       .vidioc_s_fmt_vid_out           = cedrus_s_fmt_vid_out,
+
+       .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
+       .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
+       .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
+       .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
+       .vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
+       .vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
+       .vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
+
+       .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
+       .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
+
+       .vidioc_subscribe_event         = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
+};
+
+static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
+                             unsigned int *nplanes, unsigned int sizes[],
+                             struct device *alloc_devs[])
+{
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+       struct cedrus_dev *dev = ctx->dev;
+       struct v4l2_pix_format *pix_fmt;
+       u32 directions;
+
+       if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+               directions = CEDRUS_DECODE_SRC;
+               pix_fmt = &ctx->src_fmt;
+       } else {
+               directions = CEDRUS_DECODE_DST;
+               pix_fmt = &ctx->dst_fmt;
+       }
+
+       if (!cedrus_check_format(pix_fmt->pixelformat, directions,
+                                dev->capabilities))
+               return -EINVAL;
+
+       if (*nplanes) {
+               if (sizes[0] < pix_fmt->sizeimage)
+                       return -EINVAL;
+       } else {
+               sizes[0] = pix_fmt->sizeimage;
+               *nplanes = 1;
+       }
+
+       return 0;
+}
+
+static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state)
+{
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+       struct vb2_v4l2_buffer *vbuf;
+       unsigned long flags;
+
+       for (;;) {
+               spin_lock_irqsave(&ctx->dev->irq_lock, flags);
+
+               if (V4L2_TYPE_IS_OUTPUT(vq->type))
+                       vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+               else
+                       vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+
+               spin_unlock_irqrestore(&ctx->dev->irq_lock, flags);
+
+               if (!vbuf)
+                       return;
+
+               v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
+                                          &ctx->hdl);
+               v4l2_m2m_buf_done(vbuf, state);
+       }
+}
+
+static int cedrus_buf_init(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+
+       if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+               ctx->dst_bufs[vb->index] = vb;
+
+       return 0;
+}
+
+static void cedrus_buf_cleanup(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+
+       if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+               ctx->dst_bufs[vb->index] = NULL;
+}
+
+static int cedrus_buf_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_queue *vq = vb->vb2_queue;
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+       struct v4l2_pix_format *pix_fmt;
+
+       if (V4L2_TYPE_IS_OUTPUT(vq->type))
+               pix_fmt = &ctx->src_fmt;
+       else
+               pix_fmt = &ctx->dst_fmt;
+
+       if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage)
+               return -EINVAL;
+
+       vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
+
+       return 0;
+}
+
+static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+       struct cedrus_dev *dev = ctx->dev;
+       int ret = 0;
+
+       switch (ctx->src_fmt.pixelformat) {
+       case V4L2_PIX_FMT_MPEG2_SLICE:
+               ctx->current_codec = CEDRUS_CODEC_MPEG2;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       if (V4L2_TYPE_IS_OUTPUT(vq->type) &&
+           dev->dec_ops[ctx->current_codec]->start)
+               ret = dev->dec_ops[ctx->current_codec]->start(ctx);
+
+       if (ret)
+               cedrus_queue_cleanup(vq, VB2_BUF_STATE_QUEUED);
+
+       return ret;
+}
+
+static void cedrus_stop_streaming(struct vb2_queue *vq)
+{
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
+       struct cedrus_dev *dev = ctx->dev;
+
+       if (V4L2_TYPE_IS_OUTPUT(vq->type) &&
+           dev->dec_ops[ctx->current_codec]->stop)
+               dev->dec_ops[ctx->current_codec]->stop(ctx);
+
+       cedrus_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
+}
+
+static void cedrus_buf_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static void cedrus_buf_request_complete(struct vb2_buffer *vb)
+{
+       struct cedrus_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+       v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
+}
+
+static struct vb2_ops cedrus_qops = {
+       .queue_setup            = cedrus_queue_setup,
+       .buf_prepare            = cedrus_buf_prepare,
+       .buf_init               = cedrus_buf_init,
+       .buf_cleanup            = cedrus_buf_cleanup,
+       .buf_queue              = cedrus_buf_queue,
+       .buf_request_complete   = cedrus_buf_request_complete,
+       .start_streaming        = cedrus_start_streaming,
+       .stop_streaming         = cedrus_stop_streaming,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+};
+
+int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
+                     struct vb2_queue *dst_vq)
+{
+       struct cedrus_ctx *ctx = priv;
+       int ret;
+
+       src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+       src_vq->drv_priv = ctx;
+       src_vq->buf_struct_size = sizeof(struct cedrus_buffer);
+       src_vq->min_buffers_needed = 1;
+       src_vq->ops = &cedrus_qops;
+       src_vq->mem_ops = &vb2_dma_contig_memops;
+       src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       src_vq->lock = &ctx->dev->dev_mutex;
+       src_vq->dev = ctx->dev->dev;
+       src_vq->supports_requests = true;
+
+       ret = vb2_queue_init(src_vq);
+       if (ret)
+               return ret;
+
+       dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+       dst_vq->drv_priv = ctx;
+       dst_vq->buf_struct_size = sizeof(struct cedrus_buffer);
+       dst_vq->min_buffers_needed = 1;
+       dst_vq->ops = &cedrus_qops;
+       dst_vq->mem_ops = &vb2_dma_contig_memops;
+       dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+       dst_vq->lock = &ctx->dev->dev_mutex;
+       dst_vq->dev = ctx->dev->dev;
+
+       return vb2_queue_init(dst_vq);
+}
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.h b/drivers/staging/media/sunxi/cedrus/cedrus_video.h
new file mode 100644 (file)
index 0000000..0e4f7a8
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cedrus VPU driver
+ *
+ * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+ * Copyright (C) 2018 Bootlin
+ *
+ * Based on the vim2m driver, that is:
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ */
+
+#ifndef _CEDRUS_VIDEO_H_
+#define _CEDRUS_VIDEO_H_
+
+struct cedrus_format {
+       u32             pixelformat;
+       u32             directions;
+       unsigned int    capabilities;
+};
+
+extern const struct v4l2_ioctl_ops cedrus_ioctl_ops;
+
+int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
+                     struct vb2_queue *dst_vq);
+
+#endif
index a6b9ebd20263c37d4a2363a6be56ff78666059c1..94dadbba7cd5f960922ec9d19c3ba828adf5eeda 100644 (file)
@@ -706,7 +706,7 @@ zoran_register_i2c (struct zoran *zr)
 {
        zr->i2c_algo = zoran_i2c_bit_data_template;
        zr->i2c_algo.data = zr;
-       strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
+       strscpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
                sizeof(zr->i2c_adapter.name));
        i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
        zr->i2c_adapter.algo_data = &zr->i2c_algo;
@@ -1048,7 +1048,7 @@ static int zr36057_init (struct zoran *zr)
        *zr->video_dev = zoran_template;
        zr->video_dev->v4l2_dev = &zr->v4l2_dev;
        zr->video_dev->lock = &zr->lock;
-       strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
+       strscpy(zr->video_dev->name, ZR_DEVNAME(zr), sizeof(zr->video_dev->name));
        /* It's not a mem2mem device, but you can both capture and output from
           one and the same device. This should really be split up into two
           device nodes, but that's a job for another day. */
@@ -1145,7 +1145,7 @@ static struct videocodec_master *zoran_setup_videocodec(struct zoran *zr,
        m->type = 0;
 
        m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
-       strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
+       strscpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
        m->data = zr;
 
        switch (type)
index d7842224fff6351e5d9a9befa01760f965969fc5..27c76e2eeb413599999d053b01437ac08dd5726e 100644 (file)
@@ -692,7 +692,7 @@ static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num,
                case BUZ_STATE_DONE:
                        dprintk(2,
                                KERN_WARNING
-                               "%s: %s - queing frame in BUZ_STATE_DONE state!?\n",
+                               "%s: %s - queuing frame in BUZ_STATE_DONE state!?\n",
                                ZR_DEVNAME(zr), __func__);
                        /* fall through */
                case BUZ_STATE_USER:
@@ -1510,8 +1510,8 @@ static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability
        struct zoran_fh *fh = __fh;
        struct zoran *zr = fh->zr;
 
-       strlcpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
-       strlcpy(cap->driver, "zoran", sizeof(cap->driver));
+       strscpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
+       strscpy(cap->driver, "zoran", sizeof(cap->driver));
        snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
                 pci_name(zr->pci_dev));
        cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
index 4569838f27a02437d3bc353c3b629244a72fe9cd..ea64aabda94ed5d8f25c032c2416c7a53b079560 100644 (file)
@@ -447,7 +447,7 @@ static int comp_probe(struct most_interface *iface, int channel_id,
        c = kzalloc(sizeof(*c), GFP_KERNEL);
        if (!c) {
                retval = -ENOMEM;
-               goto error_alloc_channel;
+               goto err_remove_ida;
        }
 
        c->devno = MKDEV(comp.major, current_minor);
@@ -463,7 +463,7 @@ static int comp_probe(struct most_interface *iface, int channel_id,
        retval = kfifo_alloc(&c->fifo, cfg->num_buffers, GFP_KERNEL);
        if (retval) {
                pr_info("failed to alloc channel kfifo");
-               goto error_alloc_kfifo;
+               goto err_del_cdev_and_free_channel;
        }
        init_waitqueue_head(&c->wq);
        mutex_init(&c->io_mutex);
@@ -475,18 +475,18 @@ static int comp_probe(struct most_interface *iface, int channel_id,
        if (IS_ERR(c->dev)) {
                retval = PTR_ERR(c->dev);
                pr_info("failed to create new device node %s\n", name);
-               goto error_create_device;
+               goto err_free_kfifo_and_del_list;
        }
        kobject_uevent(&c->dev->kobj, KOBJ_ADD);
        return 0;
 
-error_create_device:
+err_free_kfifo_and_del_list:
        kfifo_free(&c->fifo);
        list_del(&c->list);
-error_alloc_kfifo:
+err_del_cdev_and_free_channel:
        cdev_del(&c->cdev);
        kfree(c);
-error_alloc_channel:
+err_remove_ida:
        ida_simple_remove(&comp.minor_id, current_minor);
        return retval;
 }
index f4c464625a67b7869c2a419cb829aee2ca0468c0..6a18cf73c85eaf7463cb5a7da4f684d03f98d832 100644 (file)
@@ -442,6 +442,24 @@ static ssize_t set_dbr_size_store(struct device *dev,
        return count;
 }
 
+#define to_dev_attr(a) container_of(a, struct device_attribute, attr)
+static umode_t channel_attr_is_visible(struct kobject *kobj,
+                                      struct attribute *attr, int index)
+{
+       struct device_attribute *dev_attr = to_dev_attr(attr);
+       struct device *dev = kobj_to_dev(kobj);
+       struct most_channel *c = to_channel(dev);
+
+       if (!strcmp(dev_attr->attr.name, "set_dbr_size") &&
+           (c->iface->interface != ITYPE_MEDIALB_DIM2))
+               return 0;
+       if (!strcmp(dev_attr->attr.name, "set_packets_per_xact") &&
+           (c->iface->interface != ITYPE_USB))
+               return 0;
+
+       return attr->mode;
+}
+
 #define DEV_ATTR(_name)  (&dev_attr_##_name.attr)
 
 static DEVICE_ATTR_RO(available_directions);
@@ -479,6 +497,7 @@ static struct attribute *channel_attrs[] = {
 
 static struct attribute_group channel_attr_group = {
        .attrs = channel_attrs,
+       .is_visible = channel_attr_is_visible,
 };
 
 static const struct attribute_group *channel_attr_groups[] = {
@@ -1216,7 +1235,7 @@ int most_start_channel(struct most_interface *iface, int id,
        if (c->iface->configure(c->iface, c->channel_id, &c->cfg)) {
                pr_info("channel configuration failed. Go check settings...\n");
                ret = -EINVAL;
-               goto error;
+               goto err_put_module;
        }
 
        init_waitqueue_head(&c->hdm_fifo_wq);
@@ -1229,12 +1248,12 @@ int most_start_channel(struct most_interface *iface, int id,
                                           most_write_completion);
        if (unlikely(!num_buffer)) {
                ret = -ENOMEM;
-               goto error;
+               goto err_put_module;
        }
 
        ret = run_enqueue_thread(c, id);
        if (ret)
-               goto error;
+               goto err_put_module;
 
        c->is_starving = 0;
        c->pipe0.num_buffers = c->cfg.num_buffers / 2;
@@ -1249,7 +1268,7 @@ out:
        mutex_unlock(&c->start_mutex);
        return 0;
 
-error:
+err_put_module:
        module_put(iface->mod);
        mutex_unlock(&c->start_mutex);
        return ret;
@@ -1430,7 +1449,7 @@ int most_register_interface(struct most_interface *iface)
 
                c = kzalloc(sizeof(*c), GFP_KERNEL);
                if (!c)
-                       goto free_instance;
+                       goto err_free_resources;
                if (!name_suffix)
                        snprintf(c->name, STRING_SIZE, "ch%d", i);
                else
@@ -1439,10 +1458,6 @@ int most_register_interface(struct most_interface *iface)
                c->dev.parent = &iface->dev;
                c->dev.groups = channel_attr_groups;
                c->dev.release = release_channel;
-               if (device_register(&c->dev)) {
-                       pr_err("registering c->dev failed\n");
-                       goto free_instance_nodev;
-               }
                iface->p->channel[i] = c;
                c->is_starving = 0;
                c->iface = iface;
@@ -1465,15 +1480,19 @@ int most_register_interface(struct most_interface *iface)
                mutex_init(&c->start_mutex);
                mutex_init(&c->nq_mutex);
                list_add_tail(&c->list, &iface->p->channel_list);
+               if (device_register(&c->dev)) {
+                       pr_err("registering c->dev failed\n");
+                       goto err_free_most_channel;
+               }
        }
        pr_info("registered new device mdev%d (%s)\n",
                id, iface->description);
        return 0;
 
-free_instance_nodev:
+err_free_most_channel:
        kfree(c);
 
-free_instance:
+err_free_resources:
        while (i > 0) {
                c = iface->p->channel[--i];
                device_unregister(&c->dev);
@@ -1594,20 +1613,20 @@ static int __init most_init(void)
        err = driver_register(&mc.drv);
        if (err) {
                pr_info("Cannot register core driver\n");
-               goto exit_bus;
+               goto err_unregister_bus;
        }
        mc.dev.init_name = "most_bus";
        mc.dev.release = release_most_sub;
        if (device_register(&mc.dev)) {
                err = -ENOMEM;
-               goto exit_driver;
+               goto err_unregister_driver;
        }
 
        return 0;
 
-exit_driver:
+err_unregister_driver:
        driver_unregister(&mc.drv);
-exit_bus:
+err_unregister_bus:
        bus_unregister(&mc.bus);
        return err;
 }
index 30d816b7e16567f843d67d4ed0c41e1becbd39af..e20584b1b1128e464e4ff761c810cd96af8a2ab1 100644 (file)
@@ -75,7 +75,7 @@ static struct core_component comp;
 static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo)
 {
        u8 *buff = mbo->virt_address;
-       const u8 broadcast[] = { 0x03, 0xFF };
+       static const u8 broadcast[] = { 0x03, 0xFF };
        const u8 *dest_addr = skb->data + 4;
        const u8 *eth_type = skb->data + 12;
        unsigned int payload_len = skb->len - ETH_HLEN;
index bc820f90bcb14fe14dd4aad4f77164beb5dd790c..c0293d8d59348b25295e7ce2807361602b919a21 100644 (file)
@@ -568,19 +568,19 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
        mutex_lock(&mdev->io_mutex);
        if (!mdev->usb_device) {
                retval = -ENODEV;
-               goto _exit;
+               goto unlock_io_mutex;
        }
 
        urb = usb_alloc_urb(NO_ISOCHRONOUS_URB, GFP_ATOMIC);
        if (!urb) {
                retval = -ENOMEM;
-               goto _exit;
+               goto unlock_io_mutex;
        }
 
        if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] &&
            hdm_add_padding(mdev, channel, mbo)) {
                retval = -EIO;
-               goto _error;
+               goto err_free_urb;
        }
 
        urb->transfer_dma = mbo->bus_address;
@@ -615,15 +615,15 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
        if (retval) {
                dev_err(&mdev->usb_device->dev,
                        "URB submit failed with error %d.\n", retval);
-               goto _error_1;
+               goto err_unanchor_urb;
        }
-       goto _exit;
+       goto unlock_io_mutex;
 
-_error_1:
+err_unanchor_urb:
        usb_unanchor_urb(urb);
-_error:
+err_free_urb:
        usb_free_urb(urb);
-_exit:
+unlock_io_mutex:
        mutex_unlock(&mdev->io_mutex);
        return retval;
 }
@@ -1015,6 +1015,13 @@ static const struct attribute_group *dci_attr_groups[] = {
        NULL,
 };
 
+static void release_dci(struct device *dev)
+{
+       struct most_dci_obj *dci = to_dci_obj(dev);
+
+       kfree(dci);
+}
+
 /**
  * hdm_probe - probe function of USB device driver
  * @interface: Interface of the attached USB device
@@ -1041,7 +1048,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
        int ret = 0;
 
        if (!mdev)
-               goto exit_ENOMEM;
+               goto err_out_of_memory;
 
        usb_set_intfdata(interface, mdev);
        num_endpoints = usb_iface_desc->desc.bNumEndpoints;
@@ -1073,22 +1080,22 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
 
        mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL);
        if (!mdev->conf)
-               goto exit_free;
+               goto err_free_mdev;
 
        mdev->cap = kcalloc(num_endpoints, sizeof(*mdev->cap), GFP_KERNEL);
        if (!mdev->cap)
-               goto exit_free1;
+               goto err_free_conf;
 
        mdev->iface.channel_vector = mdev->cap;
        mdev->ep_address =
                kcalloc(num_endpoints, sizeof(*mdev->ep_address), GFP_KERNEL);
        if (!mdev->ep_address)
-               goto exit_free2;
+               goto err_free_cap;
 
        mdev->busy_urbs =
                kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL);
        if (!mdev->busy_urbs)
-               goto exit_free3;
+               goto err_free_ep_address;
 
        tmp_cap = mdev->cap;
        for (i = 0; i < num_endpoints; i++) {
@@ -1129,7 +1136,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
 
        ret = most_register_interface(&mdev->iface);
        if (ret)
-               goto exit_free4;
+               goto err_free_busy_urbs;
 
        mutex_lock(&mdev->io_mutex);
        if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
@@ -1140,35 +1147,36 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
                        mutex_unlock(&mdev->io_mutex);
                        most_deregister_interface(&mdev->iface);
                        ret = -ENOMEM;
-                       goto exit_free4;
+                       goto err_free_busy_urbs;
                }
 
                mdev->dci->dev.init_name = "dci";
                mdev->dci->dev.parent = &mdev->iface.dev;
                mdev->dci->dev.groups = dci_attr_groups;
+               mdev->dci->dev.release = release_dci;
                if (device_register(&mdev->dci->dev)) {
                        mutex_unlock(&mdev->io_mutex);
                        most_deregister_interface(&mdev->iface);
                        ret = -ENOMEM;
-                       goto exit_free5;
+                       goto err_free_dci;
                }
                mdev->dci->usb_device = mdev->usb_device;
        }
        mutex_unlock(&mdev->io_mutex);
        return 0;
-exit_free5:
+err_free_dci:
        kfree(mdev->dci);
-exit_free4:
+err_free_busy_urbs:
        kfree(mdev->busy_urbs);
-exit_free3:
+err_free_ep_address:
        kfree(mdev->ep_address);
-exit_free2:
+err_free_cap:
        kfree(mdev->cap);
-exit_free1:
+err_free_conf:
        kfree(mdev->conf);
-exit_free:
+err_free_mdev:
        kfree(mdev);
-exit_ENOMEM:
+err_out_of_memory:
        if (ret == 0 || ret == -ENOMEM) {
                ret = -ENOMEM;
                dev_err(dev, "out of memory\n");
@@ -1198,7 +1206,6 @@ static void hdm_disconnect(struct usb_interface *interface)
        cancel_work_sync(&mdev->poll_work_obj);
 
        device_unregister(&mdev->dci->dev);
-       kfree(mdev->dci);
        most_deregister_interface(&mdev->iface);
 
        kfree(mdev->busy_urbs);
index cf342eb58e10a34d0e5a9b774c10e3492ce45c2e..ad7e28ab9a4fb79ff864cc746031023be204bb0b 100644 (file)
@@ -530,7 +530,7 @@ static int comp_disconnect_channel(struct most_interface *iface,
        return 0;
 }
 
-static struct core_component comp_info = {
+static struct core_component comp = {
        .name = "video",
        .probe_channel = comp_probe_channel,
        .disconnect_channel = comp_disconnect_channel,
@@ -565,7 +565,7 @@ static void __exit comp_exit(void)
        }
        spin_unlock_irq(&list_lock);
 
-       most_deregister_component(&comp_info);
+       most_deregister_component(&comp);
        BUG_ON(!list_empty(&video_devices));
 }
 
index 6d9fe175ea52d7b571e791a4a26849dc55f15c0b..73dbc7fe38a20e68ab0118550095a9d00aab45d8 100644 (file)
@@ -47,7 +47,6 @@
 #define GDMA_REG_CTRL1_REQ_MASK                0x3f
 #define GDMA_REG_CTRL1_SRC_REQ_SHIFT   16
 #define GDMA_REG_CTRL1_DST_REQ_SHIFT   8
-#define GDMA_REG_CTRL1_CONTINOUS       BIT(14)
 #define GDMA_REG_CTRL1_NEXT_MASK       0x1f
 #define GDMA_REG_CTRL1_NEXT_SHIFT      3
 #define GDMA_REG_CTRL1_COHERENT                BIT(2)
index 2c07b559bed721b5fdebe4e81e518d3aa782fb5f..53767b17bad98010ffb447f3f4432e50749492c1 100644 (file)
@@ -286,7 +286,6 @@ static struct platform_driver gsw_driver = {
        .remove = mt7621_gsw_remove,
        .driver = {
                .name = "mt7621-gsw",
-               .owner = THIS_MODULE,
                .of_match_table = mediatek_gsw_match,
        },
 };
index 2c6e1800a3fd2a018c56ccca95054f345a06db1c..ee851281b657aaed8c50e72b5342e5de12c55b4f 100644 (file)
@@ -70,7 +70,7 @@ int mtk_connect_phy_node(struct mtk_eth *eth, struct mtk_mac *mac,
        _port = of_get_property(phy_node, "reg", NULL);
 
        if (!_port || (be32_to_cpu(*_port) >= 0x20)) {
-               pr_err("%s: invalid port id\n", phy_node->name);
+               pr_err("%pOFn: invalid port id\n", phy_node);
                return -EINVAL;
        }
        port = be32_to_cpu(*_port);
@@ -249,7 +249,7 @@ int mtk_mdio_init(struct mtk_eth *eth)
        eth->mii_bus->priv = eth;
        eth->mii_bus->parent = eth->dev;
 
-       snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
+       snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
        err = of_mdiobus_register(eth->mii_bus, mii_np);
        if (err)
                goto err_free_bus;
index 7135075585687f0651e17d661efeaa307b738019..363d3c978e0247082ad83b2af71f9f9df018cfb5 100644 (file)
@@ -2167,7 +2167,6 @@ static struct platform_driver mtk_driver = {
        .remove = mtk_remove,
        .driver = {
                .name = "mtk_soc_eth",
-               .owner = THIS_MODULE,
                .of_match_table = of_mtk_match,
        },
 };
index 6e518dce9029afde7b682e5ddb536942b774ef4b..829d3d0e895ee3306c1080ecbfe1a32a0b903aa1 100644 (file)
@@ -5,7 +5,8 @@
  * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  * Without the prior written permission of MediaTek inc. and/or its licensors,
  * any reproduction, modification, use or disclosure of MediaTek Software,
- * and information contained herein, in whole or in part, shall be strictly prohibited.
+ * and information contained herein, in whole or in part, shall be strictly
+ * prohibited.
  *
  * MediaTek Inc. (C) 2010. All rights reserved.
  *
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO
+ * SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY
+ * ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY
+ * THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK
+ * SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO
+ * RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN
+ * FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED
+ * HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK
+ * SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE
+ * PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  *
- * The following software/firmware and/or related documentation ("MediaTek Software")
- * have been modified by MediaTek Inc. All revisions are subject to any receiver's
- * applicable license agreements with MediaTek Inc.
+ * The following software/firmware and/or related documentation
+ * ("MediaTek Software") have been modified by MediaTek Inc. All revisions
+ * are subject to any receiver's applicable license agreements with MediaTek
+ * Inc.
  */
 
 #include <linux/version.h>
@@ -66,23 +69,6 @@ u32 sdio_pro_enable;   /* make sure gpt is enabled */
 u32 sdio_pro_time;     /* no more than 30s */
 struct sdio_profile sdio_perfomance = {0};
 
-#if 0 /* --- chhung */
-void msdc_init_gpt(void)
-{
-       GPT_CONFIG config;
-
-       config.num  = GPT6;
-       config.mode = GPT_FREE_RUN;
-       config.clkSrc = GPT_CLK_SRC_SYS;
-       config.clkDiv = GPT_CLK_DIV_1;   /* 13MHz GPT6 */
-
-       if (GPT_Config(config) == FALSE)
-               return;
-
-       GPT_Start(GPT6);
-}
-#endif /* end of --- */
-
 u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32)
 {
        u32 ret = 0;
@@ -91,7 +77,8 @@ u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32)
                ret = new_L32 - old_L32;
        } else if (new_H32 == (old_H32 + 1)) {
                if (new_L32 > old_L32)
-                       pr_debug("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32);
+                       pr_debug("msdc old_L<0x%x> new_L<0x%x>\n",
+                                old_L32, new_L32);
                ret = (0xffffffff - old_L32);
                ret += new_L32;
        } else {
@@ -113,27 +100,33 @@ void msdc_sdio_profile(struct sdio_profile *result)
 
        /* CMD52 Dump */
        cmd = &result->cmd52_rx;
-       pr_debug("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc,
-                cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count);
+       pr_debug("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n",
+                cmd->count, cmd->tot_tc, cmd->max_tc, cmd->min_tc,
+                cmd->tot_tc / cmd->count);
        cmd = &result->cmd52_tx;
-       pr_debug("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc,
-                cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count);
+       pr_debug("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n",
+                cmd->count, cmd->tot_tc, cmd->max_tc, cmd->min_tc,
+                cmd->tot_tc / cmd->count);
 
        /* CMD53 Rx bytes + block mode */
        for (i = 0; i < 512; i++) {
                cmd = &result->cmd53_rx_byte[i];
                if (cmd->count) {
-                       pr_debug("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
-                                cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
-                                cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+                       pr_debug("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n",
+                                cmd->count, i, cmd->tot_tc, cmd->max_tc,
+                                cmd->min_tc, cmd->tot_tc / cmd->count,
+                                cmd->tot_bytes,
+                                (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
                }
        }
        for (i = 0; i < 100; i++) {
                cmd = &result->cmd53_rx_blk[i];
                if (cmd->count) {
-                       pr_debug("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
-                                cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
-                                cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+                       pr_debug("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n",
+                                cmd->count, i, cmd->tot_tc, cmd->max_tc,
+                                cmd->min_tc, cmd->tot_tc / cmd->count,
+                                cmd->tot_bytes,
+                                (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
                }
        }
 
@@ -141,17 +134,21 @@ void msdc_sdio_profile(struct sdio_profile *result)
        for (i = 0; i < 512; i++) {
                cmd = &result->cmd53_tx_byte[i];
                if (cmd->count) {
-                       pr_debug("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
-                                cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
-                                cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+                       pr_debug("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n",
+                                cmd->count, i, cmd->tot_tc, cmd->max_tc,
+                                cmd->min_tc, cmd->tot_tc / cmd->count,
+                                cmd->tot_bytes,
+                                (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
                }
        }
        for (i = 0; i < 100; i++) {
                cmd = &result->cmd53_tx_blk[i];
                if (cmd->count) {
-                       pr_debug("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
-                                cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
-                                cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+                       pr_debug("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n",
+                                cmd->count, i, cmd->tot_tc, cmd->max_tc,
+                                cmd->min_tc, cmd->tot_tc / cmd->count,
+                                cmd->tot_bytes,
+                                (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
                }
        }
 
@@ -222,7 +219,8 @@ static int msdc_debug_proc_read(struct seq_file *s, void *p)
 
        seq_puts(s, "Index<3> + SDIO_PROFILE + TIME\n");
        seq_puts(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n");
-       seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time);
+       seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n",
+                  sdio_pro_enable, sdio_pro_time);
        seq_puts(s, "=========================================\n\n");
 
        return 0;
@@ -249,7 +247,9 @@ static ssize_t msdc_debug_proc_write(struct file *file,
        cmd_buf[count] = '\0';
        pr_debug("msdc Write %s\n", cmd_buf);
 
-       sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2);
+       ret = sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2);
+       if (ret != 3)
+               return -EINVAL;
 
        if (cmd == SD_TOOL_ZONE) {
                id = p1;
@@ -266,10 +266,8 @@ static ssize_t msdc_debug_proc_write(struct file *file,
                }
        } else if (cmd == SD_TOOL_SDIO_PROFILE) {
                if (p1 == 1) { /* enable profile */
-                       if (gpt_enable == 0) {
-                               // msdc_init_gpt(); /* --- by chhung */
+                       if (gpt_enable == 0)
                                gpt_enable = 1;
-                       }
                        sdio_pro_enable = 1;
                        if (p2 == 0)
                                p2 = 1;
index 2f2c56b739874d8df0e19e02a3d1b7952b24ce46..2d447b2d92aeceae49c2311e228a607b02f90c5d 100644 (file)
@@ -5,7 +5,8 @@
  * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  * Without the prior written permission of MediaTek inc. and/or its licensors,
  * any reproduction, modification, use or disclosure of MediaTek Software,
- * and information contained herein, in whole or in part, shall be strictly prohibited.
+ * and information contained herein, in whole or in part, shall be strictly
+ * prohibited.
  *
  * MediaTek Inc. (C) 2010. All rights reserved.
  *
  * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY
+ * ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY
+ * THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK
+ * SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO
+ * RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN
+ * FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED
+ * HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK
+ * SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE
+ * PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  *
- * The following software/firmware and/or related documentation ("MediaTek Software")
- * have been modified by MediaTek Inc. All revisions are subject to any receiver's
- * applicable license agreements with MediaTek Inc.
+ * The following software/firmware and/or related documentation
+ * ("MediaTek Software") have been modified by MediaTek Inc. All revisions are
+ * subject to any receiver's applicable license agreements with MediaTek Inc.
  */
 #ifndef __MT_MSDC_DEUBG__
 #define __MT_MSDC_DEUBG__
@@ -74,75 +76,25 @@ enum msdc_dbg {
 };
 
 /* Debug message event */
-#define DBG_EVT_NONE        (0)       /* No event */
-#define DBG_EVT_DMA         (1 << 0)  /* DMA related event */
-#define DBG_EVT_CMD         (1 << 1)  /* MSDC CMD related event */
-#define DBG_EVT_RSP         (1 << 2)  /* MSDC CMD RSP related event */
-#define DBG_EVT_INT         (1 << 3)  /* MSDC INT event */
-#define DBG_EVT_CFG         (1 << 4)  /* MSDC CFG event */
-#define DBG_EVT_FUC         (1 << 5)  /* Function event */
-#define DBG_EVT_OPS         (1 << 6)  /* Read/Write operation event */
-#define DBG_EVT_FIO         (1 << 7)  /* FIFO operation event */
-#define DBG_EVT_WRN         (1 << 8)  /* Warning event */
-#define DBG_EVT_PWR         (1 << 9)  /* Power event */
+#define DBG_EVT_NONE        (0)     /* No event */
+#define DBG_EVT_DMA         BIT(0)  /* DMA related event */
+#define DBG_EVT_CMD         BIT(1)  /* MSDC CMD related event */
+#define DBG_EVT_RSP         BIT(2)  /* MSDC CMD RSP related event */
+#define DBG_EVT_INT         BIT(3)  /* MSDC INT event */
+#define DBG_EVT_CFG         BIT(4)  /* MSDC CFG event */
+#define DBG_EVT_FUC         BIT(5)  /* Function event */
+#define DBG_EVT_OPS         BIT(6)  /* Read/Write operation event */
+#define DBG_EVT_FIO         BIT(7)  /* FIFO operation event */
+#define DBG_EVT_WRN         BIT(8)  /* Warning event */
+#define DBG_EVT_PWR         BIT(9)  /* Power event */
 #define DBG_EVT_ALL         (0xffffffff)
 
 #define DBG_EVT_MASK        (DBG_EVT_ALL)
 
 extern unsigned int sd_debug_zone[4];
 #define TAG "msdc"
-#if 0 /* +++ chhung */
-#define BUG_ON(x) \
-do { \
-       if (x) { \
-               printk("[BUG] %s LINE:%d FILE:%s\n", #x, __LINE__, __FILE__); \
-               while (1)                                               \
-                       ;                                               \
-       } \
-} while (0)
-#endif /* end of +++ */
-
-#define N_MSG(evt, fmt, args...)
-/*
-do {    \
-    if ((DBG_EVT_##evt) & sd_debug_zone[host->id]) { \
-        printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
-            host->id,  ##args , __FUNCTION__, __LINE__, current->comm, current->pid);  \
-    } \
-} while(0)
-*/
-
-#define ERR_MSG(fmt, args...) \
-do { \
-       printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
-              host->id,  ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \
-} while (0);
-
-#if 1
-//defined CONFIG_MTK_MMC_CD_POLL
-#define INIT_MSG(fmt, args...)
-#define IRQ_MSG(fmt, args...)
-#else
-#define INIT_MSG(fmt, args...) \
-do { \
-       printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
-              host->id,  ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \
-} while (0);
-
-/* PID in ISR in not corrent */
-#define IRQ_MSG(fmt, args...) \
-do { \
-       printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n",     \
-              host->id,  ##args, __FUNCTION__, __LINE__);      \
-} while (0);
-#endif
-
 void msdc_debug_proc_init(void);
 
-#if 0 /* --- chhung */
-void msdc_init_gpt(void);
-extern void GPT_GetCounter64(UINT32 *cntL32, UINT32 *cntH32);
-#endif /* end of --- */
 u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32);
 void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks);
 
index 04d23cc7cd4a64f3a614299d3ae95045fabfcffd..0379f9c96f2a99357d128a20b94feac63c24ae5c 100644 (file)
 #define GPIO_PULL_DOWN      (0)
 #define GPIO_PULL_UP        (1)
 
-#if 0 /* --- by chhung */
-#define MSDC_CLKSRC_REG     (0xf100000C)
-#define PDN_REG           (0xF1000010)
-#endif /* end of --- */
-
 #define DEFAULT_DEBOUNCE    (8)       /* 8 cycles */
 #define DEFAULT_DTOC        (40)      /* data timeout counter. 65536x40 sclk. */
 
@@ -100,26 +95,6 @@ static int cd_active_low = 1;
 //#define PERI_MSDC2_PDN    (17)
 //#define PERI_MSDC3_PDN    (18)
 
-#if 0 /* --- by chhung */
-/* gate means clock power down */
-static int g_clk_gate = 0;
-#define msdc_gate_clock(id) \
-       do {                                           \
-               g_clk_gate &= ~(1 << ((id) + PERI_MSDC0_PDN));  \
-       } while (0)
-/* not like power down register. 1 means clock on. */
-#define msdc_ungate_clock(id) \
-       do {                                        \
-               g_clk_gate |= 1 << ((id) + PERI_MSDC0_PDN);     \
-       } while (0)
-
-// do we need sync object or not
-void msdc_clk_status(int *status)
-{
-       *status = g_clk_gate;
-}
-#endif /* end of --- */
-
 /* +++ by chhung */
 struct msdc_hw msdc0_hw = {
        .clk_src        = 0,
@@ -169,11 +144,6 @@ static void msdc_clr_fifo(struct msdc_host *host)
                sdr_clr_bits(host->base + MSDC_INTEN, val);     \
        } while (0)
 
-#define msdc_irq_restore(val) \
-       do {                                    \
-               sdr_set_bits(host->base + MSDC_INTEN, val);     \
-       } while (0)
-
 /* clock source for host: global */
 #if defined(CONFIG_SOC_MT7620)
 static u32 hclks[] = {48000000}; /* +/- by chhung */
@@ -181,34 +151,6 @@ static u32 hclks[] = {48000000}; /* +/- by chhung */
 static u32 hclks[] = {50000000}; /* +/- by chhung */
 #endif
 
-//============================================
-// the power for msdc host controller: global
-//    always keep the VMC on.
-//============================================
-#define msdc_vcore_on(host) \
-       do {                                                            \
-               INIT_MSG("[+]VMC ref. count<%d>", ++host->pwr_ref);     \
-               (void)hwPowerOn(MT65XX_POWER_LDO_VMC, VOL_3300, "SD");  \
-       } while (0)
-#define msdc_vcore_off(host) \
-       do {                                                            \
-               INIT_MSG("[-]VMC ref. count<%d>", --host->pwr_ref);     \
-               (void)hwPowerDown(MT65XX_POWER_LDO_VMC, "SD");          \
-       } while (0)
-
-//====================================
-// the vdd output for card: global
-//   always keep the VMCH on.
-//====================================
-#define msdc_vdd_on(host) \
-       do {                                                            \
-               (void)hwPowerOn(MT65XX_POWER_LDO_VMCH, VOL_3300, "SD"); \
-       } while (0)
-#define msdc_vdd_off(host) \
-       do {                                                    \
-               (void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \
-       } while (0)
-
 #define sdc_is_busy()          (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY)
 #define sdc_is_cmd_busy()      (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY)
 
@@ -232,144 +174,6 @@ static unsigned int msdc_do_command(struct msdc_host   *host,
 
 static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd);
 
-#ifdef MT6575_SD_DEBUG
-static void msdc_dump_card_status(struct msdc_host *host, u32 status)
-{
-/* N_MSG is currently a no-op */
-#if 0
-       static char *state[] = {
-               "Idle",                 /* 0 */
-               "Ready",                /* 1 */
-               "Ident",                /* 2 */
-               "Stby",                 /* 3 */
-               "Tran",                 /* 4 */
-               "Data",                 /* 5 */
-               "Rcv",                  /* 6 */
-               "Prg",                  /* 7 */
-               "Dis",                  /* 8 */
-               "Reserved",             /* 9 */
-               "Reserved",             /* 10 */
-               "Reserved",             /* 11 */
-               "Reserved",             /* 12 */
-               "Reserved",             /* 13 */
-               "Reserved",             /* 14 */
-               "I/O mode",             /* 15 */
-       };
-#endif
-       if (status & R1_OUT_OF_RANGE)
-               N_MSG(RSP, "[CARD_STATUS] Out of Range");
-       if (status & R1_ADDRESS_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] Address Error");
-       if (status & R1_BLOCK_LEN_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] Block Len Error");
-       if (status & R1_ERASE_SEQ_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] Erase Seq Error");
-       if (status & R1_ERASE_PARAM)
-               N_MSG(RSP, "[CARD_STATUS] Erase Param");
-       if (status & R1_WP_VIOLATION)
-               N_MSG(RSP, "[CARD_STATUS] WP Violation");
-       if (status & R1_CARD_IS_LOCKED)
-               N_MSG(RSP, "[CARD_STATUS] Card is Locked");
-       if (status & R1_LOCK_UNLOCK_FAILED)
-               N_MSG(RSP, "[CARD_STATUS] Lock/Unlock Failed");
-       if (status & R1_COM_CRC_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] Command CRC Error");
-       if (status & R1_ILLEGAL_COMMAND)
-               N_MSG(RSP, "[CARD_STATUS] Illegal Command");
-       if (status & R1_CARD_ECC_FAILED)
-               N_MSG(RSP, "[CARD_STATUS] Card ECC Failed");
-       if (status & R1_CC_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] CC Error");
-       if (status & R1_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] Error");
-       if (status & R1_UNDERRUN)
-               N_MSG(RSP, "[CARD_STATUS] Underrun");
-       if (status & R1_OVERRUN)
-               N_MSG(RSP, "[CARD_STATUS] Overrun");
-       if (status & R1_CID_CSD_OVERWRITE)
-               N_MSG(RSP, "[CARD_STATUS] CID/CSD Overwrite");
-       if (status & R1_WP_ERASE_SKIP)
-               N_MSG(RSP, "[CARD_STATUS] WP Eraser Skip");
-       if (status & R1_CARD_ECC_DISABLED)
-               N_MSG(RSP, "[CARD_STATUS] Card ECC Disabled");
-       if (status & R1_ERASE_RESET)
-               N_MSG(RSP, "[CARD_STATUS] Erase Reset");
-       if (status & R1_READY_FOR_DATA)
-               N_MSG(RSP, "[CARD_STATUS] Ready for Data");
-       if (status & R1_SWITCH_ERROR)
-               N_MSG(RSP, "[CARD_STATUS] Switch error");
-       if (status & R1_APP_CMD)
-               N_MSG(RSP, "[CARD_STATUS] App Command");
-
-       N_MSG(RSP, "[CARD_STATUS] '%s' State", state[R1_CURRENT_STATE(status)]);
-}
-
-static void msdc_dump_ocr_reg(struct msdc_host *host, u32 resp)
-{
-       if (resp & (1 << 7))
-               N_MSG(RSP, "[OCR] Low Voltage Range");
-       if (resp & (1 << 15))
-               N_MSG(RSP, "[OCR] 2.7-2.8 volt");
-       if (resp & (1 << 16))
-               N_MSG(RSP, "[OCR] 2.8-2.9 volt");
-       if (resp & (1 << 17))
-               N_MSG(RSP, "[OCR] 2.9-3.0 volt");
-       if (resp & (1 << 18))
-               N_MSG(RSP, "[OCR] 3.0-3.1 volt");
-       if (resp & (1 << 19))
-               N_MSG(RSP, "[OCR] 3.1-3.2 volt");
-       if (resp & (1 << 20))
-               N_MSG(RSP, "[OCR] 3.2-3.3 volt");
-       if (resp & (1 << 21))
-               N_MSG(RSP, "[OCR] 3.3-3.4 volt");
-       if (resp & (1 << 22))
-               N_MSG(RSP, "[OCR] 3.4-3.5 volt");
-       if (resp & (1 << 23))
-               N_MSG(RSP, "[OCR] 3.5-3.6 volt");
-       if (resp & (1 << 24))
-               N_MSG(RSP, "[OCR] Switching to 1.8V Accepted (S18A)");
-       if (resp & (1 << 30))
-               N_MSG(RSP, "[OCR] Card Capacity Status (CCS)");
-       if (resp & (1 << 31))
-               N_MSG(RSP, "[OCR] Card Power Up Status (Idle)");
-       else
-               N_MSG(RSP, "[OCR] Card Power Up Status (Busy)");
-}
-
-static void msdc_dump_rca_resp(struct msdc_host *host, u32 resp)
-{
-       u32 status = (((resp >> 15) & 0x1) << 23) |
-                    (((resp >> 14) & 0x1) << 22) |
-                    (((resp >> 13) & 0x1) << 19) |
-                    (resp & 0x1fff);
-
-       N_MSG(RSP, "[RCA] 0x%.4x", resp >> 16);
-       msdc_dump_card_status(host, status);
-}
-
-static void msdc_dump_io_resp(struct msdc_host *host, u32 resp)
-{
-       u32 flags = (resp >> 8) & 0xFF;
-#if 0
-       char *state[] = {"DIS", "CMD", "TRN", "RFU"};
-#endif
-       if (flags & (1 << 7))
-               N_MSG(RSP, "[IO] COM_CRC_ERR");
-       if (flags & (1 << 6))
-               N_MSG(RSP, "[IO] Illegal command");
-       if (flags & (1 << 3))
-               N_MSG(RSP, "[IO] Error");
-       if (flags & (1 << 2))
-               N_MSG(RSP, "[IO] RFU");
-       if (flags & (1 << 1))
-               N_MSG(RSP, "[IO] Function number error");
-       if (flags & (1 << 0))
-               N_MSG(RSP, "[IO] Out of range");
-
-       N_MSG(RSP, "[IO] State: %s, Data:0x%x", state[(resp >> 12) & 0x3], resp & 0xFF);
-}
-#endif
-
 static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
 {
        u32 timeout, clk_ns;
@@ -384,9 +188,6 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
        timeout = timeout > 255 ? 255 : timeout;
 
        sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, timeout);
-
-       N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles",
-             ns, clks, timeout + 1);
 }
 
 static void msdc_tasklet_card(struct work_struct *work)
@@ -395,7 +196,6 @@ static void msdc_tasklet_card(struct work_struct *work)
                                struct msdc_host, card_delaywork.work);
        u32 inserted;
        u32 status = 0;
-    //u32 change = 0;
 
        spin_lock(&host->lock);
 
@@ -405,16 +205,7 @@ static void msdc_tasklet_card(struct work_struct *work)
        else
                inserted = (status & MSDC_PS_CDSTS) ? 1 : 0;
 
-#if 0
-       change = host->card_inserted ^ inserted;
-       host->card_inserted = inserted;
-
-       if (change && !host->suspend) {
-               if (inserted)
-                       host->mmc->f_max = HOST_MAX_MCLK;  // work around
-               mmc_detect_change(host->mmc, msecs_to_jiffies(20));
-       }
-#else  /* Make sure: handle the last interrupt */
+       /* Make sure: handle the last interrupt */
        host->card_inserted = inserted;
 
        if (!host->suspend) {
@@ -422,24 +213,14 @@ static void msdc_tasklet_card(struct work_struct *work)
                mmc_detect_change(host->mmc, msecs_to_jiffies(20));
        }
 
-       IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed");
-#endif
-
        spin_unlock(&host->lock);
 }
 
-#if 0 /* --- by chhung */
-/* For E2 only */
-static u8 clk_src_bit[4] = {
-       0, 3, 5, 7
-};
-
 static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc)
 {
        u32 val;
 
        BUG_ON(clksrc > 3);
-       INIT_MSG("set clock source to <%d>", clksrc);
 
        val = readl(host->base + MSDC_CLKSRC_REG);
        if (readl(host->base + MSDC_ECO_VER) >= 4) {
@@ -466,7 +247,6 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz)
        //u8  clksrc = hw->clk_src;
 
        if (!hz) { // set mmc system clock to 0 ?
-               //ERR_MSG("set mclk to 0!!!");
                msdc_reset_hw(host);
                return;
        }
@@ -509,11 +289,7 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz)
        host->mclk = hz;
        msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); // need?
 
-       INIT_MSG("================");
-       INIT_MSG("!!! Set<%dKHz> Source<%dKHz> -> sclk<%dKHz>", hz / 1000, hclk / 1000, sclk / 1000);
-       INIT_MSG("================");
-
-       msdc_irq_restore(flags);
+       sdr_set_bits(host->base + MSDC_INTEN, flags);
 }
 
 /* Fix me. when need to abort */
@@ -521,7 +297,7 @@ static void msdc_abort_data(struct msdc_host *host)
 {
        struct mmc_command *stop = host->mrq->stop;
 
-       ERR_MSG("Need to Abort.");
+       dev_err(mmc_dev(host->mmc), "%d -> Need to Abort.\n", host->id);
 
        msdc_reset_hw(host);
        msdc_clr_fifo(host);
@@ -530,7 +306,8 @@ static void msdc_abort_data(struct msdc_host *host)
        // need to check FIFO count 0 ?
 
        if (stop) {  /* try to stop, but may not success */
-               ERR_MSG("stop when abort CMD<%d>", stop->opcode);
+               dev_err(mmc_dev(host->mmc), "%d -> stop when abort CMD<%d>\n",
+                       host->id, stop->opcode);
                (void)msdc_do_command(host, stop, 0, CMD_TIMEOUT);
        }
 
@@ -539,126 +316,6 @@ static void msdc_abort_data(struct msdc_host *host)
        //}
 }
 
-#if 0 /* --- by chhung */
-static void msdc_pin_config(struct msdc_host *host, int mode)
-{
-       struct msdc_hw *hw = host->hw;
-       int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN;
-
-       /* Config WP pin */
-       if (hw->flags & MSDC_WP_PIN_EN) {
-               if (hw->config_gpio_pin) /* NULL */
-                       hw->config_gpio_pin(MSDC_WP_PIN, pull);
-       }
-
-       switch (mode) {
-       case MSDC_PIN_PULL_UP:
-               //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */
-               //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */
-               sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1);
-               sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
-               sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1);
-               sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
-               break;
-       case MSDC_PIN_PULL_DOWN:
-               //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */
-               //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */
-               sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
-               sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1);
-               sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
-               sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1);
-               break;
-       case MSDC_PIN_PULL_NONE:
-       default:
-               //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */
-               //sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */
-               sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
-               sdr_set_field(host->base + MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
-               sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
-               sdr_set_field(host->base + MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
-               break;
-       }
-
-       N_MSG(CFG, "Pins mode(%d), down(%d), up(%d)",
-             mode, MSDC_PIN_PULL_DOWN, MSDC_PIN_PULL_UP);
-}
-
-void msdc_pin_reset(struct msdc_host *host, int mode)
-{
-       struct msdc_hw *hw = (struct msdc_hw *)host->hw;
-       int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN;
-
-       /* Config reset pin */
-       if (hw->flags & MSDC_RST_PIN_EN) {
-               if (hw->config_gpio_pin) /* NULL */
-                       hw->config_gpio_pin(MSDC_RST_PIN, pull);
-
-               if (mode == MSDC_PIN_PULL_UP)
-                       sdr_clr_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST);
-               else
-                       sdr_set_bits(host->base + EMMC_IOCON, EMMC_IOCON_BOOTRST);
-       }
-}
-
-static void msdc_core_power(struct msdc_host *host, int on)
-{
-       N_MSG(CFG, "Turn %s %s power (copower: %d -> %d)",
-               on ? "on" : "off", "core", host->core_power, on);
-
-       if (on && host->core_power == 0) {
-               msdc_vcore_on(host);
-               host->core_power = 1;
-               msleep(1);
-       } else if (!on && host->core_power == 1) {
-               msdc_vcore_off(host);
-               host->core_power = 0;
-               msleep(1);
-       }
-}
-
-static void msdc_host_power(struct msdc_host *host, int on)
-{
-       N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "host");
-
-       if (on) {
-               //msdc_core_power(host, 1); // need do card detection.
-               msdc_pin_reset(host, MSDC_PIN_PULL_UP);
-       } else {
-               msdc_pin_reset(host, MSDC_PIN_PULL_DOWN);
-               //msdc_core_power(host, 0);
-       }
-}
-
-static void msdc_card_power(struct msdc_host *host, int on)
-{
-       N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "card");
-
-       if (on) {
-               msdc_pin_config(host, MSDC_PIN_PULL_UP);
-               //msdc_vdd_on(host);  // need todo card detection.
-               msleep(1);
-       } else {
-               //msdc_vdd_off(host);
-               msdc_pin_config(host, MSDC_PIN_PULL_DOWN);
-               msleep(1);
-       }
-}
-
-static void msdc_set_power_mode(struct msdc_host *host, u8 mode)
-{
-       N_MSG(CFG, "Set power mode(%d)", mode);
-
-       if (host->power_mode == MMC_POWER_OFF && mode != MMC_POWER_OFF) {
-               msdc_host_power(host, 1);
-               msdc_card_power(host, 1);
-       } else if (host->power_mode != MMC_POWER_OFF && mode == MMC_POWER_OFF) {
-               msdc_card_power(host, 0);
-               msdc_host_power(host, 0);
-       }
-       host->power_mode = mode;
-}
-#endif /* end of --- */
-
 #ifdef CONFIG_PM
 /*
    register as callback function of WIFI(combo_sdio_register_pm) .
@@ -669,12 +326,6 @@ static void msdc_pm(pm_message_t state, void *data)
        struct msdc_host *host = (struct msdc_host *)data;
        int evt = state.event;
 
-       if (evt == PM_EVENT_USER_RESUME || evt == PM_EVENT_USER_SUSPEND) {
-               INIT_MSG("USR_%s: suspend<%d> power<%d>",
-                       evt == PM_EVENT_USER_RESUME ? "EVENT_USER_RESUME" : "EVENT_USER_SUSPEND",
-                       host->suspend, host->power_mode);
-       }
-
        if (evt == PM_EVENT_SUSPEND || evt == PM_EVENT_USER_SUSPEND) {
                if (host->suspend) /* already suspend */  /* default 0*/
                        return;
@@ -687,14 +338,14 @@ static void msdc_pm(pm_message_t state, void *data)
                host->pm_state = state;  /* default PMSG_RESUME */
 
        } else if (evt == PM_EVENT_RESUME || evt == PM_EVENT_USER_RESUME) {
-               if (!host->suspend) {
-                       //ERR_MSG("warning: already resume");
+               if (!host->suspend)
                        return;
-               }
 
                /* No PM resume when USR suspend */
                if (evt == PM_EVENT_RESUME && host->pm_state.event == PM_EVENT_USER_SUSPEND) {
-                       ERR_MSG("PM Resume when in USR Suspend");               /* won't happen. */
+                       dev_err(mmc_dev(host->mmc),
+                               "%d -> PM Resume when in USR Suspend\n",
+                               host->id); /* won't happen. */
                        return;
                }
 
@@ -802,8 +453,6 @@ static unsigned int msdc_command_start(struct msdc_host   *host,
                rawcmd &= ~(0x0FFF << 16);
        }
 
-       N_MSG(CMD, "CMD<%d><0x%.8x> Arg<0x%.8x>", opcode, rawcmd, cmd->arg);
-
        tmo = jiffies + timeout;
 
        if (opcode == MMC_SEND_STATUS) {
@@ -812,7 +461,9 @@ static unsigned int msdc_command_start(struct msdc_host   *host,
                                break;
 
                        if (time_after(jiffies, tmo)) {
-                               ERR_MSG("XXX cmd_busy timeout: before CMD<%d>", opcode);
+                               dev_err(mmc_dev(host->mmc),
+                                       "%d -> XXX cmd_busy timeout: before CMD<%d>\n",
+                                       host->id, opcode);
                                cmd->error = -ETIMEDOUT;
                                msdc_reset_hw(host);
                                goto end;
@@ -823,7 +474,9 @@ static unsigned int msdc_command_start(struct msdc_host   *host,
                        if (!sdc_is_busy())
                                break;
                        if (time_after(jiffies, tmo)) {
-                               ERR_MSG("XXX sdc_busy timeout: before CMD<%d>", opcode);
+                               dev_err(mmc_dev(host->mmc),
+                                       "%d -> XXX sdc_busy timeout: before CMD<%d>\n",
+                                       host->id, opcode);
                                cmd->error = -ETIMEDOUT;
                                msdc_reset_hw(host);
                                goto end;
@@ -862,7 +515,9 @@ static unsigned int msdc_command_resp(struct msdc_host   *host,
 
        spin_unlock(&host->lock);
        if (!wait_for_completion_timeout(&host->cmd_done, 10 * timeout)) {
-               ERR_MSG("XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>", opcode, cmd->arg);
+               dev_err(mmc_dev(host->mmc),
+                       "%d -> XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>\n",
+                       host->id, opcode, cmd->arg);
                cmd->error = -ETIMEDOUT;
                msdc_reset_hw(host);
        }
@@ -872,40 +527,6 @@ static unsigned int msdc_command_resp(struct msdc_host   *host,
        host->cmd = NULL;
 
 //end:
-#ifdef MT6575_SD_DEBUG
-       switch (resp) {
-       case RESP_NONE:
-               N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)", opcode, cmd->error, resp);
-               break;
-       case RESP_R2:
-               N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= %.8x %.8x %.8x %.8x",
-                       opcode, cmd->error, resp, cmd->resp[0], cmd->resp[1],
-                       cmd->resp[2], cmd->resp[3]);
-               break;
-       default: /* Response types 1, 3, 4, 5, 6, 7(1b) */
-               N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= 0x%.8x",
-                       opcode, cmd->error, resp, cmd->resp[0]);
-               if (cmd->error == 0) {
-                       switch (resp) {
-                       case RESP_R1:
-                       case RESP_R1B:
-                               msdc_dump_card_status(host, cmd->resp[0]);
-                               break;
-                       case RESP_R3:
-                               msdc_dump_ocr_reg(host, cmd->resp[0]);
-                               break;
-                       case RESP_R5:
-                               msdc_dump_io_resp(host, cmd->resp[0]);
-                               break;
-                       case RESP_R6:
-                               msdc_dump_rca_resp(host, cmd->resp[0]);
-                               break;
-                       }
-               }
-               break;
-       }
-#endif
-
        /* do we need to save card's RCA when SD_SEND_RELATIVE_ADDR */
 
        if (!tune)
@@ -947,20 +568,9 @@ static unsigned int msdc_do_command(struct msdc_host   *host,
 
 end:
 
-       N_MSG(CMD, "        return<%d> resp<0x%.8x>", cmd->error, cmd->resp[0]);
        return cmd->error;
 }
 
-#if 0 /* --- by chhung */
-// DMA resume / start / stop
-static void msdc_dma_resume(struct msdc_host *host)
-{
-       sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1);
-
-       N_MSG(DMA, "DMA resume");
-}
-#endif /* end of --- */
-
 static void msdc_dma_start(struct msdc_host *host)
 {
        u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR;
@@ -968,8 +578,6 @@ static void msdc_dma_start(struct msdc_host *host)
        sdr_set_bits(host->base + MSDC_INTEN, wints);
        //dsb(); /* --- by chhung */
        sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
-
-       N_MSG(DMA, "DMA start");
 }
 
 static void msdc_dma_stop(struct msdc_host *host)
@@ -977,7 +585,6 @@ static void msdc_dma_stop(struct msdc_host *host)
        //u32 retries=500;
        u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR;
 
-       N_MSG(DMA, "DMA status: 0x%.8x", readl(host->base + MSDC_DMA_CFG));
        //while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS);
 
        sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1);
@@ -986,8 +593,6 @@ static void msdc_dma_stop(struct msdc_host *host)
 
        //dsb(); /* --- by chhung */
        sdr_clr_bits(host->base + MSDC_INTEN, wints); /* Not just xfer_comp */
-
-       N_MSG(DMA, "DMA stop");
 }
 
 /* calc checksum */
@@ -1010,8 +615,6 @@ static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
 
        BUG_ON(sglen > MAX_BD_NUM); /* not support currently */
 
-       N_MSG(DMA, "DMA sglen<%d> xfersz<%d>", sglen, host->xfer_size);
-
        gpd = dma->gpd;
        bd  = dma->bd;
 
@@ -1044,10 +647,6 @@ static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
        sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1);
 
        writel(PHYSADDR((u32)dma->gpd_addr), host->base + MSDC_DMA_SA);
-
-       N_MSG(DMA, "DMA_CTRL = 0x%x", readl(host->base + MSDC_DMA_CTRL));
-       N_MSG(DMA, "DMA_CFG  = 0x%x", readl(host->base + MSDC_DMA_CFG));
-       N_MSG(DMA, "DMA_SA   = 0x%x", readl(host->base + MSDC_DMA_SA));
 }
 
 static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -1062,21 +661,14 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
 #define SND_DAT 0
 #define SND_CMD 1
 
-       BUG_ON(mmc == NULL);
-       BUG_ON(mrq == NULL);
+       BUG_ON(!mmc);
+       BUG_ON(!mrq);
 
        host->error = 0;
 
        cmd  = mrq->cmd;
        data = mrq->cmd->data;
 
-#if 0 /* --- by chhung */
-       //if(host->id ==1){
-       N_MSG(OPS, "enable clock!");
-       msdc_ungate_clock(host->id);
-       //}
-#endif /* end of --- */
-
        if (!data) {
                send_type = SND_CMD;
                if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0)
@@ -1125,15 +717,22 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
                spin_unlock(&host->lock);
                if (!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)) {
-                       ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz);
-                       ERR_MSG("    DMA_SA   = 0x%x",
-                               readl(host->base + MSDC_DMA_SA));
-                       ERR_MSG("    DMA_CA   = 0x%x",
-                               readl(host->base + MSDC_DMA_CA));
-                       ERR_MSG("    DMA_CTRL = 0x%x",
-                               readl(host->base + MSDC_DMA_CTRL));
-                       ERR_MSG("    DMA_CFG  = 0x%x",
-                               readl(host->base + MSDC_DMA_CFG));
+                       dev_err(mmc_dev(host->mmc),
+                               "%d -> XXX CMD<%d> wait xfer_done<%d> timeout!!\n",
+                               host->id, cmd->opcode,
+                               data->blocks * data->blksz);
+                       dev_err(mmc_dev(host->mmc),
+                               "%d ->     DMA_SA   = 0x%x\n",
+                               host->id, readl(host->base + MSDC_DMA_SA));
+                       dev_err(mmc_dev(host->mmc),
+                               "%d ->     DMA_CA   = 0x%x\n",
+                               host->id, readl(host->base + MSDC_DMA_CA));
+                       dev_err(mmc_dev(host->mmc),
+                               "%d ->     DMA_CTRL = 0x%x\n",
+                               host->id, readl(host->base + MSDC_DMA_CTRL));
+                       dev_err(mmc_dev(host->mmc),
+                               "%d ->     DMA_CFG  = 0x%x\n",
+                               host->id, readl(host->base + MSDC_DMA_CFG));
                        data->error = -ETIMEDOUT;
 
                        msdc_reset_hw(host);
@@ -1151,48 +750,13 @@ static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
        }
 
 done:
-       if (data != NULL) {
+       if (data) {
                host->data = NULL;
                dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len,
                             mmc_get_dma_dir(data));
                host->blksz = 0;
-
-#if 0 // don't stop twice!
-               if (host->hw->flags & MSDC_REMOVABLE && data->error) {
-                       msdc_abort_data(host);
-                       /* reset in IRQ, stop command has issued. -> No need */
-               }
-#endif
-
-               N_MSG(OPS, "CMD<%d> data<%s %s> blksz<%d> block<%d> error<%d>", cmd->opcode, (dma ? "dma" : "pio"),
-                       (read ? "read " : "write"), data->blksz, data->blocks, data->error);
        }
 
-#if 0 /* --- by chhung */
-#if 1
-       //if(host->id==1) {
-       if (send_type == SND_CMD) {
-               if (cmd->opcode == MMC_SEND_STATUS) {
-                       if ((cmd->resp[0] & CARD_READY_FOR_DATA) || (CARD_CURRENT_STATE(cmd->resp[0]) != 7)) {
-                               N_MSG(OPS, "disable clock, CMD13 IDLE");
-                               msdc_gate_clock(host->id);
-                       }
-               } else {
-                       N_MSG(OPS, "disable clock, CMD<%d>", cmd->opcode);
-                       msdc_gate_clock(host->id);
-               }
-       } else {
-               if (read) {
-                       N_MSG(OPS, "disable clock!!! Read CMD<%d>", cmd->opcode);
-                       msdc_gate_clock(host->id);
-               }
-       }
-       //}
-#else
-       msdc_gate_clock(host->id);
-#endif
-#endif /* end of --- */
-
        if (mrq->cmd->error)
                host->error = 0x001;
        if (mrq->data && mrq->data->error)
@@ -1200,8 +764,6 @@ done:
        if (mrq->stop && mrq->stop->error)
                host->error |= 0x100;
 
-       //if (host->error) ERR_MSG("host->error<%d>", host->error);
-
        return host->error;
 }
 
@@ -1213,11 +775,7 @@ static int msdc_app_cmd(struct mmc_host *mmc, struct msdc_host *host)
 
        memset(&cmd, 0, sizeof(struct mmc_command));
        cmd.opcode = MMC_APP_CMD;
-#if 0   /* bug: we meet mmc->card is null when ACMD6 */
-       cmd.arg = mmc->card->rca << 16;
-#else
        cmd.arg = host->app_cmd_arg;
-#endif
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 
        memset(&mrq, 0, sizeof(struct mmc_request));
@@ -1260,19 +818,27 @@ static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
                        if (host->app_cmd) {
                                result = msdc_app_cmd(host->mmc, host);
                                if (result) {
-                                       ERR_MSG("TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>",
-                                               host->mrq->cmd->opcode, cur_rrdly, cur_rsmpl);
+                                       dev_err(mmc_dev(host->mmc),
+                                               "%d -> TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>\n",
+                                               host->id,
+                                               host->mrq->cmd->opcode,
+                                               cur_rrdly, cur_rsmpl);
                                        continue;
                                }
                        }
                        result = msdc_do_command(host, cmd, 0, CMD_TIMEOUT); // not tune.
-                       ERR_MSG("TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>", cmd->opcode,
-                               (result == 0) ? "PASS" : "FAIL", cur_rrdly, cur_rsmpl);
+                       dev_err(mmc_dev(host->mmc),
+                               "%d -> TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>\n",
+                               host->id, cmd->opcode,
+                               (result == 0) ? "PASS" : "FAIL", cur_rrdly,
+                               cur_rsmpl);
 
                        if (result == 0)
                                return 0;
                        if (result != -EIO) {
-                               ERR_MSG("TUNE_CMD<%d> Error<%d> not -EIO", cmd->opcode, result);
+                               dev_err(mmc_dev(host->mmc),
+                                       "%d -> TUNE_CMD<%d> Error<%d> not -EIO\n",
+                                       host->id, cmd->opcode, result);
                                return result;
                        }
 
@@ -1325,7 +891,10 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
                        if (host->app_cmd) {
                                result = msdc_app_cmd(host->mmc, host);
                                if (result) {
-                                       ERR_MSG("TUNE_BREAD app_cmd<%d> failed", host->mrq->cmd->opcode);
+                                       dev_err(mmc_dev(host->mmc),
+                                               "%d -> TUNE_BREAD app_cmd<%d> failed\n",
+                                               host->id,
+                                               host->mrq->cmd->opcode);
                                        continue;
                                }
                        }
@@ -1336,10 +905,13 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
                                      &dcrc); /* RO */
                        if (!ddr)
                                dcrc &= ~SDC_DCRC_STS_NEG;
-                       ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>",
-                               (result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc,
-                               readl(host->base + MSDC_DAT_RDDLY0),
-                               readl(host->base + MSDC_DAT_RDDLY1), cur_dsmpl);
+                       dev_err(mmc_dev(host->mmc),
+                               "%d -> TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>\n",
+                               host->id,
+                               (result == 0 && dcrc == 0) ? "PASS" : "FAIL",
+                               dcrc, readl(host->base + MSDC_DAT_RDDLY0),
+                               readl(host->base + MSDC_DAT_RDDLY1),
+                               cur_dsmpl);
 
                        /* Fix me: result is 0, but dcrc is still exist */
                        if (result == 0 && dcrc == 0) {
@@ -1348,8 +920,11 @@ static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
                                /* there is a case: command timeout, and data phase not processed */
                                if (mrq->data->error != 0 &&
                                    mrq->data->error != -EIO) {
-                                       ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>",
-                                               result, mrq->cmd->error, mrq->data->error);
+                                       dev_err(mmc_dev(host->mmc),
+                                               "%d -> TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>\n",
+                                               host->id, result,
+                                               mrq->cmd->error,
+                                               mrq->data->error);
                                        goto done;
                                }
                        }
@@ -1458,13 +1033,18 @@ static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
                                if (host->app_cmd) {
                                        result = msdc_app_cmd(host->mmc, host);
                                        if (result) {
-                                               ERR_MSG("TUNE_BWRITE app_cmd<%d> failed", host->mrq->cmd->opcode);
+                                               dev_err(mmc_dev(host->mmc),
+                                                       "%d -> TUNE_BWRITE app_cmd<%d> failed\n",
+                                                       host->id,
+                                                       host->mrq->cmd->opcode);
                                                continue;
                                        }
                                }
                                result = msdc_do_request(mmc, mrq);
 
-                               ERR_MSG("TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>",
+                               dev_err(mmc_dev(host->mmc),
+                                       "%d -> TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>\n",
+                                       host->id,
                                        result == 0 ? "PASS" : "FAIL",
                                        cur_dsmpl, cur_wrrdly, cur_rxdly0);
 
@@ -1473,8 +1053,11 @@ static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
                                } else {
                                        /* there is a case: command timeout, and data phase not processed */
                                        if (mrq->data->error != -EIO) {
-                                               ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>",
-                                                       result, mrq->cmd->error, mrq->data->error);
+                                               dev_err(mmc_dev(host->mmc),
+                                                       "%d -> TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>\n",
+                                                       host->id, result,
+                                                       mrq->cmd->error,
+                                                       mrq->data->error);
                                                goto done;
                                        }
                                }
@@ -1508,7 +1091,8 @@ static int msdc_get_card_status(struct mmc_host *mmc, struct msdc_host *host, u3
        if (mmc->card) {
                cmd.arg = mmc->card->rca << 16;
        } else {
-               ERR_MSG("cmd13 mmc card is null");
+               dev_err(mmc_dev(host->mmc), "%d -> cmd13 mmc card is null\n",
+                       host->id);
                cmd.arg = host->app_cmd_arg;
        }
        cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
@@ -1535,7 +1119,8 @@ static int msdc_check_busy(struct mmc_host *mmc, struct msdc_host *host)
                if (err)
                        return err;
                /* need cmd12? */
-               ERR_MSG("cmd<13> resp<0x%x>", status);
+               dev_err(mmc_dev(host->mmc), "%d -> cmd<13> resp<0x%x>\n",
+                       host->id, status);
        } while (R1_CURRENT_STATE(status) == 7);
 
        return err;
@@ -1559,7 +1144,9 @@ static int msdc_tune_request(struct mmc_host *mmc, struct mmc_request *mrq)
        } else {
                ret = msdc_check_busy(mmc, host);
                if (ret) {
-                       ERR_MSG("XXX cmd13 wait program done failed");
+                       dev_err(mmc_dev(host->mmc),
+                               "%d -> XXX cmd13 wait program done failed\n",
+                               host->id);
                        return ret;
                }
                /* CRC and TO */
@@ -1575,22 +1162,10 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
        struct msdc_host *host = mmc_priv(mmc);
 
-       //=== for sdio profile ===
-#if 0 /* --- by chhung */
-       u32 old_H32, old_L32, new_H32, new_L32;
-       u32 ticks = 0, opcode = 0, sizes = 0, bRx = 0;
-#endif /* end of --- */
-
        WARN_ON(host->mrq);
 
        /* start to process */
        spin_lock(&host->lock);
-#if 0 /* --- by chhung */
-       if (sdio_pro_enable) {  //=== for sdio profile ===
-               if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53)
-                       GPT_GetCounter64(&old_L32, &old_H32);
-       }
-#endif /* end of --- */
 
        host->mrq = mrq;
 
@@ -1610,26 +1185,6 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        host->mrq = NULL;
 
-#if 0 /* --- by chhung */
-       //=== for sdio profile ===
-       if (sdio_pro_enable) {
-               if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) {
-                       GPT_GetCounter64(&new_L32, &new_H32);
-                       ticks = msdc_time_calc(old_L32, old_H32, new_L32, new_H32);
-
-                       opcode = mrq->cmd->opcode;
-                       if (mrq->cmd->data) {
-                               sizes = mrq->cmd->data->blocks * mrq->cmd->data->blksz;
-                               bRx = mrq->cmd->data->flags & MMC_DATA_READ ? 1 : 0;
-                       } else {
-                               bRx = mrq->cmd->arg     & 0x80000000 ? 1 : 0;
-                       }
-
-                       if (!mrq->cmd->error)
-                               msdc_performance(opcode, sizes, bRx, ticks);
-               }
-       }
-#endif /* end of --- */
        spin_unlock(&host->lock);
 
        mmc_request_done(mmc, mrq);
@@ -1659,8 +1214,6 @@ static void msdc_set_buswidth(struct msdc_host *host, u32 width)
        }
 
        writel(val, host->base + SDC_CFG);
-
-       N_MSG(CFG, "Bus Width = %d", width);
 }
 
 /* ops.set_ios */
@@ -1698,7 +1251,6 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        switch (ios->power_mode) {
        case MMC_POWER_OFF:
        case MMC_POWER_UP:
-               // msdc_set_power_mode(host, ios->power_mode); /* --- by chhung */
                break;
        case MMC_POWER_ON:
                host->power_mode = MMC_POWER_ON;
@@ -1711,7 +1263,6 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        if (host->mclk != ios->clock) {
                if (ios->clock > 25000000) {
                        //if (!(host->hw->flags & MSDC_REMOVABLE)) {
-                       INIT_MSG("SD data latch edge<%d>", MSDC_SMPL_FALLING);
                        sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL,
                                      MSDC_SMPL_FALLING);
                        sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL,
@@ -1764,7 +1315,6 @@ static int msdc_ops_get_cd(struct mmc_host *mmc)
                return 1;
 #else
                host->card_inserted = (host->pm_state.event == PM_EVENT_USER_RESUME) ? 1 : 0;
-               INIT_MSG("sdio ops_get_cd<%d>", host->card_inserted);
                return host->card_inserted;
 #endif
        }
@@ -1772,9 +1322,6 @@ static int msdc_ops_get_cd(struct mmc_host *mmc)
        /* MSDC_CD_PIN_EN set for card */
        if (host->hw->flags & MSDC_CD_PIN_EN) {
                spin_lock_irqsave(&host->lock, flags);
-#if 0
-               present = host->card_inserted;  /* why not read from H/W: Fix me*/
-#else
                // CD
                present = readl(host->base + MSDC_PS) & MSDC_PS_CDSTS;
                if (cd_active_low)
@@ -1782,13 +1329,11 @@ static int msdc_ops_get_cd(struct mmc_host *mmc)
                else
                        present = present ? 1 : 0;
                host->card_inserted = present;
-#endif
                spin_unlock_irqrestore(&host->lock, flags);
        } else {
                present = 0; /* TODO? Check DAT3 pins for card detection */
        }
 
-       INIT_MSG("ops_get_cd return<%d>", present);
        return present;
 }
 
@@ -1823,19 +1368,12 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
        if (intsts & MSDC_INT_CDSC) {
                if (host->mmc->caps & MMC_CAP_NEEDS_POLL)
                        return IRQ_HANDLED;
-               IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts);
                schedule_delayed_work(&host->card_delaywork, HZ);
                /* tuning when plug card ? */
        }
 
-       /* sdio interrupt */
-       if (intsts & MSDC_INT_SDIOIRQ) {
-               IRQ_MSG("XXX MSDC_INT_SDIOIRQ");  /* seems not sdio irq */
-               //mmc_signal_sdio_irq(host->mmc);
-       }
-
        /* transfer complete interrupt */
-       if (data != NULL) {
+       if (data) {
                if (inten & MSDC_INT_XFER_COMPL) {
                        data->bytes_xfered = host->xfer_size;
                        complete(&host->xfer_done);
@@ -1847,13 +1385,10 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
                        msdc_clr_fifo(host);
                        msdc_clr_int();
 
-                       if (intsts & MSDC_INT_DATTMO) {
-                               IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode);
+                       if (intsts & MSDC_INT_DATTMO)
                                data->error = -ETIMEDOUT;
-                       } else if (intsts & MSDC_INT_DATCRCERR) {
-                               IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, readl(host->base + SDC_DCRC_STS));
+                       else if (intsts & MSDC_INT_DATCRCERR)
                                data->error = -EIO;
-                       }
 
                        //if(readl(MSDC_INTEN) & MSDC_INT_XFER_COMPL) {
                        complete(&host->xfer_done); /* Read CRC come fast, XFER_COMPL not enabled */
@@ -1861,7 +1396,7 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
        }
 
        /* command interrupts */
-       if ((cmd != NULL) && (intsts & cmdsts)) {
+       if (cmd && (intsts & cmdsts)) {
                if ((intsts & MSDC_INT_CMDRDY) || (intsts & MSDC_INT_ACMDRDY) ||
                        (intsts & MSDC_INT_ACMD19_DONE)) {
                        u32 *rsp = &cmd->resp[0];
@@ -1883,16 +1418,8 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
                                break;
                        }
                } else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) {
-                       if (intsts & MSDC_INT_ACMDCRCERR)
-                               IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR", cmd->opcode);
-                       else
-                               IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR", cmd->opcode);
                        cmd->error = -EIO;
                } else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) {
-                       if (intsts & MSDC_INT_ACMDTMO)
-                               IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO", cmd->opcode);
-                       else
-                               IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO", cmd->opcode);
                        cmd->error = -ETIMEDOUT;
                        msdc_reset_hw(host);
                        msdc_clr_fifo(host);
@@ -1903,36 +1430,8 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
 
        /* mmc irq interrupts */
        if (intsts & MSDC_INT_MMCIRQ)
-               printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n",
-                      host->id, readl(host->base + SDC_CSTS));
-
-#ifdef MT6575_SD_DEBUG
-       {
-/*        msdc_int_reg *int_reg = (msdc_int_reg*)&intsts;*/
-               N_MSG(INT, "IRQ_EVT(0x%x): MMCIRQ(%d) CDSC(%d), ACRDY(%d), ACTMO(%d), ACCRE(%d) AC19DN(%d)",
-                       intsts,
-                       int_reg->mmcirq,
-                       int_reg->cdsc,
-                       int_reg->atocmdrdy,
-                       int_reg->atocmdtmo,
-                       int_reg->atocmdcrc,
-                       int_reg->atocmd19done);
-               N_MSG(INT, "IRQ_EVT(0x%x): SDIO(%d) CMDRDY(%d), CMDTMO(%d), RSPCRC(%d), CSTA(%d)",
-                       intsts,
-                       int_reg->sdioirq,
-                       int_reg->cmdrdy,
-                       int_reg->cmdtmo,
-                       int_reg->rspcrc,
-                       int_reg->csta);
-               N_MSG(INT, "IRQ_EVT(0x%x): XFCMP(%d) DXDONE(%d), DATTMO(%d), DATCRC(%d), DMAEMP(%d)",
-                       intsts,
-                       int_reg->xfercomp,
-                       int_reg->dxferdone,
-                       int_reg->dattmo,
-                       int_reg->datcrc,
-                       int_reg->dmaqempty);
-       }
-#endif
+               dev_info(mmc_dev(host->mmc), "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n",
+                       host->id, readl(host->base + SDC_CSTS));
 
        return IRQ_HANDLED;
 }
@@ -1958,14 +1457,11 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
                return;
        }
 
-       N_MSG(CFG, "CD IRQ Enable(%d)", enable);
-
        if (enable) {
                /* card detection circuit relies on the core power so that the core power
                 * shouldn't be turned off. Here adds a reference count to keep
                 * the core power alive.
                 */
-               //msdc_vcore_on(host); //did in msdc_init_hw()
 
                if (hw->config_gpio_pin) /* NULL */
                        hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP);
@@ -1988,7 +1484,6 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
                /* Here decreases a reference count to core power since card
                 * detection circuit is shutdown.
                 */
-               //msdc_vcore_off(host);
        }
 }
 
@@ -1996,14 +1491,6 @@ static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
 static void msdc_init_hw(struct msdc_host *host)
 {
 
-       /* Power on */
-#if 0 /* --- by chhung */
-       msdc_vcore_on(host);
-       msdc_pin_reset(host, MSDC_PIN_PULL_UP);
-       msdc_select_clksrc(host, hw->clk_src);
-       enable_clock(PERI_MSDC0_PDN + host->id, "SD");
-       msdc_vdd_on(host);
-#endif /* end of --- */
        /* Configure to MMC/SD mode */
        sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC);
 
@@ -2035,10 +1522,6 @@ static void msdc_init_hw(struct msdc_host *host)
 
        writel(0x00000000, host->base + MSDC_DAT_RDDLY1);
        writel(0x00000000, host->base + MSDC_IOCON);
-#if 0 // use MT7620 default value: 0x403c004f
-       /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/
-       writel(0x003C000F, host->base + MSDC_PATCH_BIT0);
-#endif
 
        if (readl(host->base + MSDC_ECO_VER) >= 4) {
                if (host->id == 1) {
@@ -2094,8 +1577,6 @@ static void msdc_init_hw(struct msdc_host *host)
        sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC);
 
        msdc_set_buswidth(host, MMC_BUS_WIDTH_1);
-
-       N_MSG(FUC, "init hardware done!");
 }
 
 /* called by msdc_drv_remove */
@@ -2107,7 +1588,6 @@ static void msdc_deinit_hw(struct msdc_host *host)
 
        /* Disable card detection */
        msdc_enable_cd_irq(host, 0);
-       // msdc_set_power_mode(host, MMC_POWER_OFF);   /* make sure power down */ /* --- by chhung */
 }
 
 /* init gpd and bd list in msdc_drv_probe */
@@ -2289,7 +1769,8 @@ static int msdc_drv_remove(struct platform_device *pdev)
        host = mmc_priv(mmc);
        BUG_ON(!host);
 
-       ERR_MSG("removed !!!");
+       dev_err(mmc_dev(host->mmc), "%d -> removed !!!\n",
+               host->id);
 
        platform_set_drvdata(pdev, NULL);
        mmc_remove_host(host->mmc);
@@ -2313,6 +1794,7 @@ static int msdc_drv_remove(struct platform_device *pdev)
 static void msdc_drv_pm(struct platform_device *pdev, pm_message_t state)
 {
        struct mmc_host *mmc = platform_get_drvdata(pdev);
+
        if (mmc) {
                struct msdc_host *host = mmc_priv(mmc);
                msdc_pm(state, (void *)host);
@@ -2370,7 +1852,7 @@ static int __init mt_msdc_init(void)
 
        ret = platform_driver_register(&mt_msdc_driver);
        if (ret) {
-               printk(KERN_ERR DRV_NAME ": Can't register driver");
+               pr_err("%s: Can't register driver", DRV_NAME);
                return ret;
        }
 
index a49e2795af6bbc6dae5cd5a0fdcddf327f76f671..8371a9cdb1648e92d5247e51fbfc6562c3b8c48c 100644 (file)
 #define RALINK_PCIE_CLK_EN             BIT(21)
 
 #define MEMORY_BASE 0x0
-static int pcie_link_status = 0;
+static int pcie_link_status;
 
 /**
  * struct mt7621_pcie_port - PCIe port information
@@ -214,7 +214,7 @@ write_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg, u32 val)
        pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
 }
 
-void
+static void
 set_pcie_phy(struct mt7621_pcie *pcie, u32 offset,
             int start_b, int bits, int val)
 {
@@ -225,7 +225,7 @@ set_pcie_phy(struct mt7621_pcie *pcie, u32 offset,
        pcie_write(pcie, reg, offset);
 }
 
-void
+static void
 bypass_pipe_rst(struct mt7621_pcie *pcie)
 {
        /* PCIe Port 0 */
@@ -239,7 +239,7 @@ bypass_pipe_rst(struct mt7621_pcie *pcie)
        set_pcie_phy(pcie, (RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c),  4, 1, 0x01);        // rg_pe1_pipe_cmd_frc[4]
 }
 
-void
+static void
 set_phy_for_ssc(struct mt7621_pcie *pcie)
 {
        unsigned long reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
@@ -387,15 +387,8 @@ static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie)
        struct device *dev = pcie->dev;
        struct device_node *node = dev->of_node;
        struct resource regs;
-       const char *type;
        int err;
 
-       type = of_get_property(node, "device_type", NULL);
-       if (!type || strcmp(type, "pci") != 0) {
-               dev_err(dev, "invalid \"device_type\" %s\n", type);
-               return -EINVAL;
-       }
-
        err = of_address_to_resource(node, 0, &regs);
        if (err) {
                dev_err(dev, "missing \"reg\" property\n");
@@ -481,12 +474,12 @@ static int mt7621_pci_probe(struct platform_device *pdev)
 
        ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST);
 
-       *(unsigned int *)(0xbe000060) &= ~(0x3<<10 | 0x3<<3);
-       *(unsigned int *)(0xbe000060) |= 0x1<<10 | 0x1<<3;
+       *(unsigned int *)(0xbe000060) &= ~(0x3 << 10 | 0x3 << 3);
+       *(unsigned int *)(0xbe000060) |=  BIT(10) | BIT(3);
        mdelay(100);
-       *(unsigned int *)(0xbe000600) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3)
+       *(unsigned int *)(0xbe000600) |= BIT(19) | BIT(8) | BIT(7); // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3)
        mdelay(100);
-       *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7);          // clear DATA
+       *(unsigned int *)(0xbe000620) &= ~(BIT(19) | BIT(8) | BIT(7));          // clear DATA
 
        mdelay(100);
 
@@ -496,18 +489,15 @@ static int mt7621_pci_probe(struct platform_device *pdev)
 
        DEASSERT_SYSRST_PCIE(val);
 
-       if ((*(unsigned int *)(0xbe00000c)&0xFFFF) == 0x0101) // MT7621 E2
+       if ((*(unsigned int *)(0xbe00000c) & 0xFFFF) == 0x0101) // MT7621 E2
                bypass_pipe_rst(pcie);
        set_phy_for_ssc(pcie);
 
-       val = read_config(pcie, 0, 0x70c);
-       printk("Port 0 N_FTS = %x\n", (unsigned int)val);
-
-       val = read_config(pcie, 1, 0x70c);
-       printk("Port 1 N_FTS = %x\n", (unsigned int)val);
-
-       val = read_config(pcie, 2, 0x70c);
-       printk("Port 2 N_FTS = %x\n", (unsigned int)val);
+       list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+               u32 slot = port->slot;
+               val = read_config(pcie, slot, 0x70c);
+               dev_info(dev, "Port %d N_FTS = %x\n", (unsigned int)val, slot);
+       }
 
        rt_sysc_m32(0, RALINK_PCIE_RST, RALINK_RSTCTRL);
        rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1);
@@ -520,18 +510,18 @@ static int mt7621_pci_probe(struct platform_device *pdev)
        rt_sysc_m32(RALINK_PCIE_RST, 0, RALINK_RSTCTRL);
 
        /* Use GPIO control instead of PERST_N */
-       *(unsigned int *)(0xbe000620) |= 0x1<<19 | 0x1<<8 | 0x1<<7;             // set DATA
+       *(unsigned int *)(0xbe000620) |= BIT(19) | BIT(8) | BIT(7);             // set DATA
        mdelay(1000);
 
        if ((pcie_read(pcie, RT6855_PCIE0_OFFSET + RALINK_PCI_STATUS) & 0x1) == 0) {
                printk("PCIE0 no card, disable it(RST&CLK)\n");
                ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST);
                rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
-               pcie_link_status &= ~(1<<0);
+               pcie_link_status &= ~(BIT(0));
        } else {
-               pcie_link_status |= 1<<0;
+               pcie_link_status |=  BIT(0);
                val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR);
-               val |= (1<<20); // enable pcie1 interrupt
+               val |= BIT(20); // enable pcie1 interrupt
                pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR);
        }
 
@@ -539,11 +529,11 @@ static int mt7621_pci_probe(struct platform_device *pdev)
                printk("PCIE1 no card, disable it(RST&CLK)\n");
                ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST);
                rt_sysc_m32(RALINK_PCIE1_CLK_EN, 0, RALINK_CLKCFG1);
-               pcie_link_status &= ~(1<<1);
+               pcie_link_status &= ~(BIT(1));
        } else {
-               pcie_link_status |= 1<<1;
+               pcie_link_status |= BIT(1);
                val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR);
-               val |= (1<<21); // enable pcie1 interrupt
+               val |= BIT(21); // enable pcie1 interrupt
                pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR);
        }
 
@@ -551,11 +541,11 @@ static int mt7621_pci_probe(struct platform_device *pdev)
                printk("PCIE2 no card, disable it(RST&CLK)\n");
                ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST);
                rt_sysc_m32(RALINK_PCIE2_CLK_EN, 0, RALINK_CLKCFG1);
-               pcie_link_status &= ~(1<<2);
+               pcie_link_status &= ~(BIT(2));
        } else {
-               pcie_link_status |= 1<<2;
+               pcie_link_status |=  BIT(2);
                val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR);
-               val |= (1<<22); // enable pcie2 interrupt
+               val |= BIT(22); // enable pcie2 interrupt
                pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR);
        }
 
@@ -654,26 +644,26 @@ pcie(2/1/0) link status   pcie2_num       pcie1_num       pcie0_num
        switch (pcie_link_status) {
        case 7:
                val = read_config(pcie, 2, 0x4);
-               write_config(pcie, 2, 0x4, val|0x4);
+               write_config(pcie, 2, 0x4, val | 0x4);
                val = read_config(pcie, 2, 0x70c);
-               val &= ~(0xff)<<8;
-               val |= 0x50<<8;
+               val &= ~(0xff) << 8;
+               val |= 0x50 << 8;
                write_config(pcie, 2, 0x70c, val);
        case 3:
        case 5:
        case 6:
                val = read_config(pcie, 1, 0x4);
-               write_config(pcie, 1, 0x4, val|0x4);
+               write_config(pcie, 1, 0x4, val | 0x4);
                val = read_config(pcie, 1, 0x70c);
-               val &= ~(0xff)<<8;
-               val |= 0x50<<8;
+               val &= ~(0xff) << 8;
+               val |= 0x50 << 8;
                write_config(pcie, 1, 0x70c, val);
        default:
                val = read_config(pcie, 0, 0x4);
-               write_config(pcie, 0, 0x4, val|0x4); //bus master enable
+               write_config(pcie, 0, 0x4, val | 0x4); //bus master enable
                val = read_config(pcie, 0, 0x70c);
-               val &= ~(0xff)<<8;
-               val |= 0x50<<8;
+               val &= ~(0xff) << 8;
+               val |= 0x50 << 8;
                write_config(pcie, 0, 0x70c, val);
        }
 
index cff5e790b196640feb4b1af3ac53d8a05444fdee..9c766f5b812fc03f14056fed3c2e4714904f2625 100644 (file)
@@ -377,29 +377,6 @@ struct octeon_hcd {
        struct cvmx_usb_tx_fifo nonperiodic;
 };
 
-/* This macro spins on a register waiting for it to reach a condition. */
-#define CVMX_WAIT_FOR_FIELD32(address, _union, cond, timeout_usec)         \
-       ({int result;                                                       \
-       do {                                                                \
-               u64 done = cvmx_get_cycle() + (u64)timeout_usec *           \
-                          octeon_get_clock_rate() / 1000000;               \
-               union _union c;                                             \
-                                                                           \
-               while (1) {                                                 \
-                       c.u32 = cvmx_usb_read_csr32(usb, address);          \
-                                                                           \
-                       if (cond) {                                         \
-                               result = 0;                                 \
-                               break;                                      \
-                       } else if (cvmx_get_cycle() > done) {               \
-                               result = -1;                                \
-                               break;                                      \
-                       } else                                              \
-                               __delay(100);                               \
-               }                                                           \
-       } while (0);                                                        \
-       result; })
-
 /*
  * This macro logically sets a single field in a CSR. It does the sequence
  * read, modify, and write
@@ -593,6 +570,33 @@ static inline int cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
        return 0; /* Data0 */
 }
 
+/* Loops through register until txfflsh or rxfflsh become zero.*/
+static int cvmx_wait_tx_rx(struct octeon_hcd *usb, int fflsh_type)
+{
+       int result;
+       u64 address = CVMX_USBCX_GRSTCTL(usb->index);
+       u64 done = cvmx_get_cycle() + 100 *
+                  (u64)octeon_get_clock_rate / 1000000;
+       union cvmx_usbcx_grstctl c;
+
+       while (1) {
+               c.u32 = cvmx_usb_read_csr32(usb, address);
+               if (fflsh_type == 0 && c.s.txfflsh == 0) {
+                       result = 0;
+                       break;
+               } else if (fflsh_type == 1 && c.s.rxfflsh == 0) {
+                       result = 0;
+                       break;
+               } else if (cvmx_get_cycle() > done) {
+                       result = -1;
+                       break;
+               }
+
+               __delay(100);
+       }
+       return result;
+}
+
 static void cvmx_fifo_setup(struct octeon_hcd *usb)
 {
        union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
@@ -634,12 +638,10 @@ static void cvmx_fifo_setup(struct octeon_hcd *usb)
                        cvmx_usbcx_grstctl, txfnum, 0x10);
        USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
                        cvmx_usbcx_grstctl, txfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                             cvmx_usbcx_grstctl, c.s.txfflsh == 0, 100);
+       cvmx_wait_tx_rx(usb, 0);
        USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
                        cvmx_usbcx_grstctl, rxfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                             cvmx_usbcx_grstctl, c.s.rxfflsh == 0, 100);
+       cvmx_wait_tx_rx(usb, 1);
 }
 
 /**
@@ -2768,7 +2770,7 @@ static int cvmx_usb_poll_channel(struct octeon_hcd *usb, int channel)
            (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
                pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING;
 
-       if (unlikely(WARN_ON_ONCE(bytes_this_transfer < 0))) {
+       if (WARN_ON_ONCE(bytes_this_transfer < 0)) {
                /*
                 * In some rare cases the DMA engine seems to get stuck and
                 * keeps substracting same byte count over and over again. In
index c91a56f77bcb2281e4b30b13c63e0e84c736a97e..192cc8d0853fdd00fda2eb92458026a3950b2bf0 100644 (file)
@@ -2,6 +2,7 @@ config FB_OLPC_DCON
        tristate "One Laptop Per Child Display CONtroller support"
        depends on OLPC && FB
        depends on I2C
+       depends on BACKLIGHT_LCD_SUPPORT
        depends on (GPIO_CS5535 || GPIO_CS5535=n)
        select BACKLIGHT_CLASS_DEVICE
        help
index 2744c9f0920eeaaf69a1e5cf54e1936e46b864db..6b714f740ac3e198a4decfadb6855b7e4ae4db4d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Mainly by David Woodhouse, somewhat modified by Jordan Crouse
  *
@@ -5,10 +6,6 @@
  * Copyright © 2006-2007  Advanced Micro Devices, Inc.
  * Copyright © 2009       VIA Technology, Inc.
  * Copyright (c) 2010-2011  Andres Salomon <dilinger@queued.net>
- *
- * 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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 633c58ce24eef258edaaca8e1f2e438a4ddfaa60..ff145d493e1b5262fe111836bf45b6c7c6322eff 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Mainly by David Woodhouse, somewhat modified by Jordan Crouse
  *
@@ -5,10 +6,6 @@
  * Copyright © 2006-2007  Advanced Micro Devices, Inc.
  * Copyright © 2009       VIA Technology, Inc.
  * Copyright (c) 2010  Andres Salomon <dilinger@queued.net>
- *
- * 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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 64584425b01cf06707fd27581cb0b481ba1ac9bc..838daa2be3ef630addc004987ddee3daadd3b909 100644 (file)
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2009,2010       One Laptop per Child
- *
- * 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.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 085272fb393f5537ff51b4893e6d3c12cc820895..4fa6c0237e597be81add3acf68f4cf28fcb980aa 100644 (file)
@@ -853,7 +853,6 @@ int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
 #ifdef DEBUG_FIFO_ACCESS
        int i;
 #endif
-       char spi_address = REG_FIFO | WRITE_BIT;
        u8 local_buffer[FIFO_SIZE + 1];
 
        if (size > FIFO_SIZE) {
@@ -862,7 +861,7 @@ int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
                return -EMSGSIZE;
        }
 
-       local_buffer[0] = spi_address;
+       local_buffer[0] = REG_FIFO | WRITE_BIT;
        memcpy(&local_buffer[1], buffer, size);
 
 #ifdef DEBUG_FIFO_ACCESS
index 4e606b03ec034be2c5b3c2714f409fd39056dcad..7da911c2ab8905faed426d5d02314939b38c3300 100644 (file)
@@ -28,7 +28,7 @@ r8188eu-y :=                          \
                hal/hal_intf.o          \
                hal/hal_com.o           \
                hal/odm.o               \
-               hal/odm_HWConfig.o      \
+               hal/odm_hwconfig.o      \
                hal/odm_rtl8188e.o      \
                hal/rtl8188e_cmd.o      \
                hal/rtl8188e_dm.o       \
index 7581e25f231db54050065afca8a3645e8be68e77..5faa0a9bba255510661ba9dcfaa3db0d4949b3be 100644 (file)
@@ -1,5 +1,5 @@
 TODO:
-- find and remove remaining code valid only for 5 HGz. Most of the obvious
+- find and remove remaining code valid only for 5 GHz. Most of the obvious
   ones have been removed, but things like channel > 14 still exist.
 - find and remove any code for other chips that is left over
 - convert any remaining unusual variable types
index 676d549ef78691fed257d389602424ea2704d46a..1c319c2ca86d73707fc046b7bd95d822852fcdcc 100644 (file)
@@ -36,7 +36,7 @@ void free_mlme_ap_info(struct adapter *padapter)
        struct sta_priv *pstapriv = &padapter->stapriv;
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
+       struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
 
        pmlmepriv->update_bcn = false;
        pmlmeext->bstart_bss = false;
@@ -337,8 +337,6 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
        unsigned char sta_band = 0, raid, shortGIrate = false;
        unsigned int tx_ra_bitmap = 0;
        struct ht_priv  *psta_ht = NULL;
-       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 
        if (psta)
                psta_ht = &psta->htpriv;
@@ -363,20 +361,13 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
                shortGIrate = psta_ht->sgi;
        }
 
-       if (pcur_network->Configuration.DSConfig > 14) {
-               /*  5G band */
-               if (tx_ra_bitmap & 0xffff000)
-                       sta_band |= WIRELESS_11_5N | WIRELESS_11A;
-               else
-                       sta_band |= WIRELESS_11A;
-       } else {
-               if (tx_ra_bitmap & 0xffff000)
-                       sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
-               else if (tx_ra_bitmap & 0xff0)
-                       sta_band |= WIRELESS_11G | WIRELESS_11B;
-               else
-                       sta_band |= WIRELESS_11B;
-       }
+       if (tx_ra_bitmap & 0xffff000)
+               sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
+       else if (tx_ra_bitmap & 0xff0)
+               sta_band |= WIRELESS_11G | WIRELESS_11B;
+       else
+               sta_band |= WIRELESS_11B;
+
 
        psta->wireless_mode = sta_band;
 
index 59039211dad279c97fe6e2b430d7182f0f70c959..9b2a497aa413933e91c36fec9dcaa05ee3952b15 100644 (file)
@@ -243,11 +243,11 @@ u8 rtw_sitesurvey_cmd(struct adapter  *padapter, struct ndis_802_11_ssid *ssid,
        if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
        if (!ph2c)
                return _FAIL;
 
-       psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
+       psurveyPara = kzalloc(sizeof(*psurveyPara), GFP_ATOMIC);
        if (!psurveyPara) {
                kfree(ph2c);
                return _FAIL;
@@ -325,7 +325,7 @@ u8 rtw_createbss_cmd(struct adapter  *padapter)
        else
                RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
 
-       pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+       pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC);
        if (!pcmd) {
                res = _FAIL;
                goto exit;
@@ -367,7 +367,7 @@ u8 rtw_joinbss_cmd(struct adapter  *padapter, struct wlan_network *pnetwork)
        else
                RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid));
 
-       pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+       pcmd = kzalloc(sizeof(*pcmd), GFP_ATOMIC);
        if (!pcmd) {
                res = _FAIL;
                goto exit;
@@ -527,8 +527,8 @@ u8 rtw_setopmode_cmd(struct adapter  *padapter, enum ndis_802_11_network_infra n
 
        struct  cmd_priv   *pcmdpriv = &padapter->cmdpriv;
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
-       psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL);
+       psetop = kzalloc(sizeof(*psetop), GFP_KERNEL);
        if (!ph2c || !psetop) {
                kfree(ph2c);
                kfree(psetop);
@@ -552,9 +552,9 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key)
        struct security_priv *psecuritypriv = &padapter->securitypriv;
        struct sta_info *sta = (struct sta_info *)psta;
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
-       psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
-       psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL);
+       psetstakey_para = kzalloc(sizeof(*psetstakey_para), GFP_KERNEL);
+       psetstakey_rsp = kzalloc(sizeof(*psetstakey_rsp), GFP_KERNEL);
 
        if (!ph2c || !psetstakey_para || !psetstakey_rsp) {
                kfree(ph2c);
@@ -597,20 +597,20 @@ u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue)
        if (!enqueue) {
                clear_cam_entry(padapter, entry);
        } else {
-               ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+               ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
                if (!ph2c) {
                        res = _FAIL;
                        goto exit;
                }
 
-               psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_ATOMIC);
+               psetstakey_para = kzalloc(sizeof(*psetstakey_para), GFP_ATOMIC);
                if (!psetstakey_para) {
                        kfree(ph2c);
                        res = _FAIL;
                        goto exit;
                }
 
-               psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_ATOMIC);
+               psetstakey_rsp = kzalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC);
                if (!psetstakey_rsp) {
                        kfree(ph2c);
                        kfree(psetstakey_para);
@@ -642,13 +642,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
        struct addBaReq_parm *paddbareq_parm;
        u8      res = _SUCCESS;
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
        if (!ph2c) {
                res = _FAIL;
                goto exit;
        }
 
-       paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
+       paddbareq_parm = kzalloc(sizeof(*paddbareq_parm), GFP_ATOMIC);
        if (!paddbareq_parm) {
                kfree(ph2c);
                res = _FAIL;
@@ -677,13 +677,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
        struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
        u8      res = _SUCCESS;
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
        if (!ph2c) {
                res = _FAIL;
                goto exit;
        }
 
-       pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
+       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
        if (!pdrvextra_cmd_parm) {
                kfree(ph2c);
                res = _FAIL;
@@ -719,7 +719,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
        }
 
        /* prepare cmd parameter */
-       setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), GFP_KERNEL);
+       setChannelPlan_param = kzalloc(sizeof(*setChannelPlan_param), GFP_KERNEL);
        if (!setChannelPlan_param) {
                res = _FAIL;
                goto exit;
@@ -728,7 +728,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
 
        if (enqueue) {
                /* need enqueue, prepare cmd_obj and enqueue */
-               pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+               pcmdobj = kzalloc(sizeof(*pcmdobj), GFP_KERNEL);
                if (!pcmdobj) {
                        kfree(setChannelPlan_param);
                        res = _FAIL;
@@ -745,7 +745,6 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
                kfree(setChannelPlan_param);
        }
 
-       /* do something based on res... */
        if (res == _SUCCESS)
                padapter->mlmepriv.ChannelPlan = chplan;
 
@@ -884,13 +883,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
        u8      res = _SUCCESS;
 
        if (enqueue) {
-               ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+               ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
                if (!ph2c) {
                        res = _FAIL;
                        goto exit;
                }
 
-               pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
+               pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
                if (!pdrvextra_cmd_parm) {
                        kfree(ph2c);
                        res = _FAIL;
@@ -926,13 +925,13 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time)
 
        u8      res = _SUCCESS;
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
        if (!ph2c) {
                res = _FAIL;
                goto exit;
        }
 
-       pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
+       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
        if (!pdrvextra_cmd_parm) {
                kfree(ph2c);
                res = _FAIL;
@@ -967,13 +966,13 @@ u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue)
                return res;
 
        if (enqueue) {
-               ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+               ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL);
                if (!ph2c) {
                        res = _FAIL;
                        goto exit;
                }
 
-               pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
+               pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_KERNEL);
                if (!pdrvextra_cmd_parm) {
                        kfree(ph2c);
                        res = _FAIL;
@@ -1000,8 +999,8 @@ u8 rtw_ps_cmd(struct adapter *padapter)
        struct drvextra_cmd_parm        *pdrvextra_cmd_parm;
        struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
 
-       ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
-       pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
+       ppscmd = kzalloc(sizeof(*ppscmd), GFP_ATOMIC);
+       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
        if (!ppscmd || !pdrvextra_cmd_parm) {
                kfree(ppscmd);
                kfree(pdrvextra_cmd_parm);
@@ -1064,13 +1063,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *padapter)
        struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
        u8      res = _SUCCESS;
 
-       ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+       ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC);
        if (!ph2c) {
                res = _FAIL;
                goto exit;
        }
 
-       pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
+       pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
        if (!pdrvextra_cmd_parm) {
                kfree(ph2c);
                res = _FAIL;
index 67461fdf315c58e3cd0f073d66a71a9a8c5ee91c..6c2fe1a112ace441103bbf73093c90e149e79659 100644 (file)
@@ -153,13 +153,11 @@ int proc_get_best_channel(char *page, char **start,
        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
        int len = 0;
-       u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
+       u32 i, best_channel_24G = 1, index_24G = 0;
 
        for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
                if (pmlmeext->channel_set[i].ChannelNum == 1)
                        index_24G = i;
-               if (pmlmeext->channel_set[i].ChannelNum == 36)
-                       index_5G = i;
        }
 
        for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
@@ -171,32 +169,11 @@ int proc_get_best_channel(char *page, char **start,
                        }
                }
 
-               /*  5G */
-               if (pmlmeext->channel_set[i].ChannelNum >= 36 &&
-                   pmlmeext->channel_set[i].ChannelNum < 140) {
-                       /*  Find primary channel */
-                       if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) &&
-                           (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
-                               index_5G = i;
-                               best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
-                       }
-               }
-
-               if (pmlmeext->channel_set[i].ChannelNum >= 149 &&
-                   pmlmeext->channel_set[i].ChannelNum < 165) {
-                       /*  find primary channel */
-                       if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) &&
-                           (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
-                               index_5G = i;
-                               best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
-                       }
-               }
                /*  debug */
                len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n",
                                        pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count);
        }
 
-       len += snprintf(page + len, count - len, "best_channel_5G = %d\n", best_channel_5G);
        len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G);
 
        *eof = 1;
index 0fd306a808c4019771c9a0a321d16aa98724989e..b7be71f904ed831c7a462b6c2ba68db4f7389e90 100644 (file)
@@ -22,13 +22,9 @@ enum{
        };
 
 /*
- * Function:   efuse_power_switch
- *
- * Overview:   When we want to enable write operation, we should change to
- *                             pwr on state. When we stop write, we should switch to 500k mode
- *                             and disable LDO 2.5V.
+ * When we want to enable write operation, we should change to pwr on state.
+ * When we stop write, we should switch to 500k mode and disable LDO 2.5V.
  */
-
 void efuse_power_switch(struct adapter *pAdapter, u8 write, u8 pwrstate)
 {
        u8 tempval;
@@ -41,7 +37,7 @@ void efuse_power_switch(struct adapter *pAdapter, u8 write, u8 pwrstate)
                tmpv16 = usb_read16(pAdapter, REG_SYS_ISO_CTRL);
                if (!(tmpv16 & PWC_EV12V)) {
                        tmpv16 |= PWC_EV12V;
-                        usb_write16(pAdapter, REG_SYS_ISO_CTRL, tmpv16);
+                       usb_write16(pAdapter, REG_SYS_ISO_CTRL, tmpv16);
                }
                /*  Reset: 0x0000h[28], default valid */
                tmpv16 =  usb_read16(pAdapter, REG_SYS_FUNC_EN);
@@ -86,16 +82,20 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8  *pbuf)
        u16     **eFuseWord = NULL;
        u16     efuse_utilized = 0;
        u8 u1temp = 0;
+       void **tmp = NULL;
 
        efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
        if (!efuseTbl)
                return;
 
-       eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
-       if (!eFuseWord) {
+       tmp = kzalloc(EFUSE_MAX_SECTION_88E * (sizeof(void *) + EFUSE_MAX_WORD_UNIT * sizeof(u16)), GFP_KERNEL);
+       if (!tmp) {
                DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
                goto eFuseWord_failed;
        }
+       for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
+               tmp[i] = ((char *)(tmp + EFUSE_MAX_SECTION_88E)) + i * EFUSE_MAX_WORD_UNIT * sizeof(u16);
+       eFuseWord = (u16 **)tmp;
 
        /*  0. Refresh efuse init map as all oxFF. */
        for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
@@ -360,15 +360,13 @@ u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_e
 
 static u16 Efuse_GetCurrentSize(struct adapter *pAdapter)
 {
-       int     bContinual = true;
        u16     efuse_addr = 0;
        u8 hoffset = 0, hworden = 0;
        u8 efuse_data, word_cnts = 0;
 
        rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
 
-       while (bContinual &&
-              efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) &&
+       while (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) &&
               AVAILABLE_EFUSE_ADDR(efuse_addr)) {
                if (efuse_data != 0xFF) {
                        if ((efuse_data&0x1F) == 0x0F) {                /* extended header */
@@ -390,7 +388,7 @@ static u16 Efuse_GetCurrentSize(struct adapter *pAdapter)
                        /* read next header */
                        efuse_addr = efuse_addr + (word_cnts*2)+1;
                } else {
-                       bContinual = false;
+                       break;
                }
        }
 
@@ -453,7 +451,7 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
                                                                bDataEmpty = false;
                                                }
                                        }
-                                       if (bDataEmpty == false) {
+                                       if (!bDataEmpty) {
                                                ReadState = PG_STATE_DATA;
                                        } else {/* read next header */
                                                efuse_addr = efuse_addr + (word_cnts*2)+1;
@@ -512,7 +510,7 @@ static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, st
 
 static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
 {
-       bool bRet = false;
+       bool ret = false;
        u16 efuse_addr = *pAddr;
        u16 efuse_max_available_len =
                EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E;
@@ -564,7 +562,7 @@ static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuse
                                if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr))
                                        return false;
                        } else {
-                               bRet = true;
+                               ret = true;
                                break;
                        }
                } else if ((tmp_header & 0x1F) == 0x0F) {               /* wrong extended header */
@@ -574,12 +572,12 @@ static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuse
        }
 
        *pAddr = efuse_addr;
-       return bRet;
+       return ret;
 }
 
 static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
 {
-       bool bRet = false;
+       bool ret = false;
        u8 pg_header = 0, tmp_header = 0;
        u16     efuse_addr = *pAddr;
        u8 repeatcnt = 0;
@@ -597,7 +595,7 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse
        }
 
        if (pg_header == tmp_header) {
-               bRet = true;
+               ret = true;
        } else {
                struct pgpkt    fixPkt;
 
@@ -609,7 +607,7 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse
        }
 
        *pAddr = efuse_addr;
-       return bRet;
+       return ret;
 }
 
 static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
@@ -639,14 +637,14 @@ hal_EfusePgPacketWriteHeader(
                                u16                             *pAddr,
                                struct pgpkt *pTargetPkt)
 {
-       bool bRet = false;
+       bool ret = false;
 
        if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
-               bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
+               ret = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
        else
-               bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
+               ret = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
 
-       return bRet;
+       return ret;
 }
 
 static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
@@ -678,19 +676,19 @@ static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
 
 static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr)
 {
-       bool bRet = false;
+       bool ret = false;
        u8 i, efuse_data;
 
        for (i = 0; i < (word_cnts*2); i++) {
                if (efuse_OneByteRead(pAdapter, (startAddr+i), &efuse_data) && (efuse_data != 0xFF))
-                       bRet = true;
+                       ret = true;
        }
-       return bRet;
+       return ret;
 }
 
 static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
 {
-       bool bRet = false;
+       bool ret = false;
        u8 i, efuse_data = 0, cur_header = 0;
        u8 matched_wden = 0, badworden = 0;
        u16 startAddr = 0;
@@ -703,7 +701,7 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u
 
        while (1) {
                if (startAddr >= efuse_max_available_len) {
-                       bRet = false;
+                       ret = false;
                        break;
                }
 
@@ -713,7 +711,7 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u
                                startAddr++;
                                efuse_OneByteRead(pAdapter, startAddr, &efuse_data);
                                if (ALL_WORDS_DISABLED(efuse_data)) {
-                                       bRet = false;
+                                       ret = false;
                                        break;
                                } else {
                                        curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
@@ -740,7 +738,7 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u
                                        PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data);
 
                                        if (!PgWriteSuccess) {
-                                               bRet = false;   /*  write fail, return */
+                                               ret = false;    /*  write fail, return */
                                                break;
                                        }
                                }
@@ -756,11 +754,11 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u
                } else {
                        /*  not used header, 0xff */
                        *pAddr = startAddr;
-                       bRet = true;
+                       ret = true;
                        break;
                }
        }
-       return bRet;
+       return ret;
 }
 
 static bool
@@ -868,9 +866,7 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data)
        return result;
 }
 
-/*
- * Overview:   Read allowed word in current efuse section data.
- */
+/* Read allowed word in current efuse section data. */
 void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
 {
        if (!(word_en & BIT(0))) {
@@ -891,9 +887,7 @@ void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
        }
 }
 
-/*
- * Overview:   Read All Efuse content
- */
+/* Read All Efuse content */
 static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse)
 {
        efuse_power_switch(pAdapter, false, true);
@@ -903,12 +897,8 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse)
        efuse_power_switch(pAdapter, false, false);
 }
 
-/*
- * Overview:   Transfer current EFUSE content to shadow init and modify map.
- */
-void EFUSE_ShadowMapUpdate(
-       struct adapter *pAdapter,
-       u8 efuseType)
+/* Transfer current EFUSE content to shadow init and modify map. */
+void EFUSE_ShadowMapUpdate(struct adapter *pAdapter, u8 efuseType)
 {
        struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
 
index 7d5cbaf50f1c9047efce00fddb15ae93ff90c2d5..5c4ff81987bd7dbef318326bbe68e9ae84176c8c 100644 (file)
@@ -100,19 +100,13 @@ bool rtw_is_cckratesonly_included(u8 *rate)
 
 int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
 {
-       if (channel > 14) {
-               if (rtw_is_cckrates_included(rate))
-                       return WIRELESS_INVALID;
-               else
-                       return WIRELESS_11A;
-       } else {  /*  could be pure B, pure G, or B/G */
-               if (rtw_is_cckratesonly_included(rate))
-                       return WIRELESS_11B;
-               else if (rtw_is_cckrates_included(rate))
-                       return  WIRELESS_11BG;
-               else
-                       return WIRELESS_11G;
-       }
+       /*  could be pure B, pure G, or B/G */
+       if (rtw_is_cckratesonly_included(rate))
+               return WIRELESS_11B;
+       else if (rtw_is_cckrates_included(rate))
+               return  WIRELESS_11BG;
+       else
+               return WIRELESS_11G;
 }
 
 u8 *rtw_set_fixed_ie(void *pbuf, unsigned int len, void *source,
@@ -252,7 +246,7 @@ int rtw_generate_ie(struct registry_priv *pregistrypriv)
                wireless_mode = pregistrypriv->wireless_mode;
        }
 
-               rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode);
+       rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode);
 
        rateLen = rtw_get_rateset_len(pdev_network->SupportedRates);
 
@@ -290,7 +284,7 @@ unsigned char *rtw_get_wpa_ie(unsigned char *pie, uint *wpa_ie_len, int limit)
 
                if (pbuf) {
                        /* check if oui matches... */
-                       if (!memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type)) == false)
+                       if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type)))
                                goto check_next_ie;
 
                        /* check version... */
index c040f185074b34525b973b1f4a0573feb17f2814..0b3eb0b40975f9bd0d7f30bef1352bec6eeb80ee 100644 (file)
@@ -17,11 +17,11 @@ u8 rtw_do_join(struct adapter *padapter)
 {
        struct list_head *plist, *phead;
        u8 *pibss = NULL;
-       struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
-       struct __queue *queue   = &(pmlmepriv->scanned_queue);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct __queue *queue = &pmlmepriv->scanned_queue;
        u8 ret = _SUCCESS;
 
-       spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
+       spin_lock_bh(&pmlmepriv->scanned_queue.lock);
        phead = get_list_head(queue);
        plist = phead->next;
 
@@ -36,7 +36,7 @@ u8 rtw_do_join(struct adapter *padapter)
        pmlmepriv->to_join = true;
 
        if (list_empty(&queue->queue)) {
-               spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
+               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
                _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
 
                /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
@@ -60,18 +60,18 @@ u8 rtw_do_join(struct adapter *padapter)
        } else {
                int select_ret;
 
-               spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
+               spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
                select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
                if (select_ret == _SUCCESS) {
                        pmlmepriv->to_join = false;
                        mod_timer(&pmlmepriv->assoc_timer,
                                  jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
                } else {
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
+                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
                                /*  submit createbss_cmd to change to a ADHOC_MASTER */
 
                                /* pmlmepriv->lock has been acquired by caller... */
-                               struct wlan_bssid_ex    *pdev_network = &(padapter->registrypriv.dev_network);
+                               struct wlan_bssid_ex    *pdev_network = &padapter->registrypriv.dev_network;
 
                                pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
 
@@ -136,16 +136,16 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
        spin_lock_bh(&pmlmepriv->lock);
 
        DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
                goto handle_tkip_countermeasure;
        else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
                goto release_mlme_lock;
 
-       if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
+       if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
 
                if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
-                       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)
+                       if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE))
                                goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
                } else {
                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n"));
@@ -154,12 +154,12 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
 
                        rtw_disassoc_cmd(padapter, 0, true);
 
-                       if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+                       if (check_fwstate(pmlmepriv, _FW_LINKED))
                                rtw_indicate_disconnect(padapter);
 
                        rtw_free_assoc_resources(padapter);
 
-                       if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
+                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
                                _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
                                set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
                        }
@@ -172,7 +172,7 @@ handle_tkip_countermeasure:
        if (padapter->securitypriv.btkip_countermeasure) {
                cur_time = jiffies;
 
-               if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
+               if (cur_time - padapter->securitypriv.btkip_countermeasure_time > 60 * HZ) {
                        padapter->securitypriv.btkip_countermeasure = false;
                        padapter->securitypriv.btkip_countermeasure_time = 0;
                } else {
@@ -220,18 +220,18 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
        spin_lock_bh(&pmlmepriv->lock);
 
        DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
                goto handle_tkip_countermeasure;
-       else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
+       else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
                goto release_mlme_lock;
 
-       if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
+       if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
                         ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
 
-               if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
-                   (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
-                       if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) {
+               if (pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength &&
+                   !memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength)) {
+                       if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
                                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
                                         ("Set SSID is the same ssid, fw_state = 0x%08x\n",
                                          get_fwstate(pmlmepriv)));
@@ -240,12 +240,12 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
                                        /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
                                        rtw_disassoc_cmd(padapter, 0, true);
 
-                                       if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+                                       if (check_fwstate(pmlmepriv, _FW_LINKED))
                                                rtw_indicate_disconnect(padapter);
 
                                        rtw_free_assoc_resources(padapter);
 
-                                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
+                                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
                                                _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
                                                set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
                                        }
@@ -262,12 +262,12 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
 
                        rtw_disassoc_cmd(padapter, 0, true);
 
-                       if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+                       if (check_fwstate(pmlmepriv, _FW_LINKED))
                                rtw_indicate_disconnect(padapter);
 
                        rtw_free_assoc_resources(padapter);
 
-                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
+                       if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
                                _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
                                set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
                        }
@@ -279,7 +279,7 @@ handle_tkip_countermeasure:
        if (padapter->securitypriv.btkip_countermeasure) {
                cur_time = jiffies;
 
-               if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
+               if (cur_time - padapter->securitypriv.btkip_countermeasure_time > 60 * HZ) {
                        padapter->securitypriv.btkip_countermeasure = false;
                        padapter->securitypriv.btkip_countermeasure_time = 0;
                } else {
@@ -291,7 +291,7 @@ handle_tkip_countermeasure:
        memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
        pmlmepriv->assoc_by_bssid = false;
 
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
                pmlmepriv->to_join = true;
        else
                status = rtw_do_join(padapter);
@@ -308,9 +308,9 @@ exit:
 u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
        enum ndis_802_11_network_infra networktype)
 {
-       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
-       struct  wlan_network    *cur_network = &pmlmepriv->cur_network;
-       enum ndis_802_11_network_infra *pold_state = &(cur_network->network.InfrastructureMode);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       struct wlan_network *cur_network = &pmlmepriv->cur_network;
+       enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode;
 
        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
                 ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d fw_state = 0x%08x\n",
@@ -331,16 +331,17 @@ u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
 #endif
                }
 
-               if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
-                   (*pold_state == Ndis802_11IBSS))
+               if (check_fwstate(pmlmepriv, _FW_LINKED) ||
+                   *pold_state == Ndis802_11IBSS)
                        rtw_disassoc_cmd(padapter, 0, true);
 
-               if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
-                   (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
+               if (check_fwstate(pmlmepriv, _FW_LINKED) ||
+                   check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
                        rtw_free_assoc_resources(padapter);
 
-               if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
-                       if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
+               if (*pold_state == Ndis802_11Infrastructure ||
+                   *pold_state == Ndis802_11IBSS) {
+                       if (check_fwstate(pmlmepriv, _FW_LINKED))
                                rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether  issue dis-assoc_cmd or not */
               }
 
@@ -394,8 +395,8 @@ u8 rtw_set_802_11_disassociate(struct adapter *padapter)
 
 u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
 {
-       struct  mlme_priv               *pmlmepriv = &padapter->mlmepriv;
-       u8      res = true;
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+       u8 res = true;
 
        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+%s(), fw_state =%x\n", __func__, get_fwstate(pmlmepriv)));
 
@@ -409,14 +410,14 @@ u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_s
                goto exit;
        }
 
-       if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
-           (pmlmepriv->LinkDetectInfo.bBusyTraffic)) {
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ||
+           pmlmepriv->LinkDetectInfo.bBusyTraffic) {
                /*  Scan or linking is in progress, do nothing. */
                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("%s fail since fw_state = %x\n", __func__, get_fwstate(pmlmepriv)));
                res = true;
 
                if (check_fwstate(pmlmepriv,
-                               (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)) == true)
+                                 _FW_UNDER_SURVEY | _FW_UNDER_LINKING))
                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
                else
                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy == true\n\n"));
@@ -444,7 +445,8 @@ u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11
        int res;
        u8 ret;
 
-       RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode));
+       RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
+                ("set_802_11_auth.mode(): mode =%x\n", authmode));
 
        psecuritypriv->ndisauthtype = authmode;
 
@@ -467,9 +469,9 @@ u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11
 
 u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
 {
-       int             keyid, res;
-       struct security_priv *psecuritypriv = &(padapter->securitypriv);
-       u8              ret = _SUCCESS;
+       int keyid, res;
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+       u8 ret = _SUCCESS;
 
        keyid = wep->KeyIndex & 0x3fffffff;
 
@@ -497,7 +499,8 @@ u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
                 ("rtw_set_802_11_add_wep:before memcpy, wep->KeyLength = 0x%x wep->KeyIndex = 0x%x  keyid =%x\n",
                 wep->KeyLength, wep->KeyIndex, keyid));
 
-       memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
+       memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0],
+              &wep->KeyMaterial, wep->KeyLength);
 
        psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
 
@@ -527,31 +530,27 @@ exit:
        return ret;
 }
 
-/*
-* rtw_get_cur_max_rate -
-* @adapter: pointer to struct adapter structure
-*
-* Return 0 or 100Kbps
-*/
+/* Return 0 or 100Kbps */
 u16 rtw_get_cur_max_rate(struct adapter *adapter)
 {
-       int     i = 0;
-       u8      *p;
-       u16     rate = 0, max_rate = 0;
-       struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
+       int i = 0;
+       u8 *p;
+       u16 rate = 0, max_rate = 0;
+       struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
        struct registry_priv *pregistrypriv = &adapter->registrypriv;
-       struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
-       struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
-       u8      bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
-       u32     ht_ielen = 0;
+       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+       struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+       u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
+       u32 ht_ielen = 0;
 
-       if ((!check_fwstate(pmlmepriv, _FW_LINKED)) &&
-           (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
+       if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
+           !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
                return 0;
 
-       if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
-               p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->ie_length-12);
+       if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11_5N)) {
+               p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_,
+                              &ht_ielen, pcur_bss->ie_length - 12);
                if (p && ht_ielen > 0) {
                        /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */
                        bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0;
@@ -561,33 +560,28 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
 
                        max_rate = rtw_mcs_rate(
                                RF_1T1R,
-                               bw_40MHz & (pregistrypriv->cbw40_enable),
+                               bw_40MHz & pregistrypriv->cbw40_enable,
                                short_GI_20,
                                short_GI_40,
                                pmlmeinfo->HT_caps.mcs.rx_mask
                        );
                }
        } else {
-               while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
-                       rate = pcur_bss->SupportedRates[i]&0x7F;
+               while (pcur_bss->SupportedRates[i] != 0 &&
+                      pcur_bss->SupportedRates[i] != 0xFF) {
+                       rate = pcur_bss->SupportedRates[i] & 0x7F;
                        if (rate > max_rate)
                                max_rate = rate;
                        i++;
                }
 
-               max_rate = max_rate*10/2;
+               max_rate *= 5;
        }
 
        return max_rate;
 }
 
-/*
-* rtw_set_country -
-* @adapter: pointer to struct adapter structure
-* @country_code: string of country code
-*
-* Return _SUCCESS or _FAIL
-*/
+/* Return _SUCCESS or _FAIL */
 int rtw_set_country(struct adapter *adapter, const char *country_code)
 {
        int i;
index cbef871a76798cf88e88ce30794abdcd669f95a2..a2e7789aecbd69288e2a5488f4e8e1e2011708e3 100644 (file)
@@ -18,7 +18,7 @@ static void BlinkTimerCallback(struct timer_list *t)
        struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer);
        struct adapter *padapter = pLed->padapter;
 
-       if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped))
+       if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
                return;
 
        schedule_work(&pLed->BlinkWorkItem);
@@ -95,10 +95,12 @@ static void SwLedBlink1(struct LED_871x *pLed)
        /*  Change LED according to BlinkingLedState specified. */
        if (pLed->BlinkingLedState == RTW_LED_ON) {
                SwLedOn(padapter, pLed);
-               RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+               RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
+                        ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
        } else {
                SwLedOff(padapter, pLed);
-               RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+               RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
+                        ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
        }
 
        if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
@@ -245,131 +247,134 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
        case LED_CTL_POWER_ON:
        case LED_CTL_START_TO_LINK:
        case LED_CTL_NO_LINK:
-               if (!pLed->bLedNoLinkBlinkInProgress) {
-                       if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
-                               return;
-                       if (pLed->bLedLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedBlinkInProgress = false;
-                       }
-
-                       pLed->bLedNoLinkBlinkInProgress = true;
-                       pLed->CurrLedState = LED_BLINK_SLOWLY;
-                       if (pLed->bLedOn)
-                               pLed->BlinkingLedState = RTW_LED_OFF;
-                       else
-                               pLed->BlinkingLedState = RTW_LED_ON;
-                       mod_timer(&pLed->BlinkTimer, jiffies +
-                                 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
+               if (pLed->bLedNoLinkBlinkInProgress)
+                       break;
+               if (pLed->CurrLedState == LED_BLINK_SCAN ||
+                   IS_LED_WPS_BLINKING(pLed))
+                       return;
+               if (pLed->bLedLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedLinkBlinkInProgress = false;
+               }
+               if (pLed->bLedBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedBlinkInProgress = false;
                }
+               pLed->bLedNoLinkBlinkInProgress = true;
+               pLed->CurrLedState = LED_BLINK_SLOWLY;
+               if (pLed->bLedOn)
+                       pLed->BlinkingLedState = RTW_LED_OFF;
+               else
+                       pLed->BlinkingLedState = RTW_LED_ON;
+               mod_timer(&pLed->BlinkTimer, jiffies +
+                         msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
                break;
        case LED_CTL_LINK:
-               if (!pLed->bLedLinkBlinkInProgress) {
-                       if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
-                               return;
-                       if (pLed->bLedNoLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedNoLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedBlinkInProgress = false;
-                       }
-                       pLed->bLedLinkBlinkInProgress = true;
-                       pLed->CurrLedState = LED_BLINK_NORMAL;
-                       if (pLed->bLedOn)
-                               pLed->BlinkingLedState = RTW_LED_OFF;
-                       else
-                               pLed->BlinkingLedState = RTW_LED_ON;
-                       mod_timer(&pLed->BlinkTimer, jiffies +
-                                 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
+               if (pLed->bLedLinkBlinkInProgress)
+                       break;
+               if (pLed->CurrLedState == LED_BLINK_SCAN ||
+                   IS_LED_WPS_BLINKING(pLed))
+                       return;
+               if (pLed->bLedNoLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedNoLinkBlinkInProgress = false;
+               }
+               if (pLed->bLedBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedBlinkInProgress = false;
                }
+               pLed->bLedLinkBlinkInProgress = true;
+               pLed->CurrLedState = LED_BLINK_NORMAL;
+               if (pLed->bLedOn)
+                       pLed->BlinkingLedState = RTW_LED_OFF;
+               else
+                       pLed->BlinkingLedState = RTW_LED_ON;
+               mod_timer(&pLed->BlinkTimer, jiffies +
+                         msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
                break;
        case LED_CTL_SITE_SURVEY:
-               if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
-                       ;
-               } else if (!pLed->bLedScanBlinkInProgress) {
-                       if (IS_LED_WPS_BLINKING(pLed))
-                               return;
-                       if (pLed->bLedNoLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedNoLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                                pLed->bLedLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedBlinkInProgress = false;
-                       }
-                       pLed->bLedScanBlinkInProgress = true;
-                       pLed->CurrLedState = LED_BLINK_SCAN;
-                       pLed->BlinkTimes = 24;
-                       if (pLed->bLedOn)
-                               pLed->BlinkingLedState = RTW_LED_OFF;
-                       else
-                               pLed->BlinkingLedState = RTW_LED_ON;
-                       mod_timer(&pLed->BlinkTimer, jiffies +
-                                 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
+               if (pmlmepriv->LinkDetectInfo.bBusyTraffic &&
+                   check_fwstate(pmlmepriv, _FW_LINKED))
+                       break;
+               if (pLed->bLedScanBlinkInProgress)
+                       break;
+               if (IS_LED_WPS_BLINKING(pLed))
+                       return;
+               if (pLed->bLedNoLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedNoLinkBlinkInProgress = false;
+               }
+               if (pLed->bLedLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedLinkBlinkInProgress = false;
+               }
+               if (pLed->bLedBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedBlinkInProgress = false;
                }
+               pLed->bLedScanBlinkInProgress = true;
+               pLed->CurrLedState = LED_BLINK_SCAN;
+               pLed->BlinkTimes = 24;
+               if (pLed->bLedOn)
+                       pLed->BlinkingLedState = RTW_LED_OFF;
+               else
+                       pLed->BlinkingLedState = RTW_LED_ON;
+               mod_timer(&pLed->BlinkTimer, jiffies +
+                         msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
                break;
        case LED_CTL_TX:
        case LED_CTL_RX:
-               if (!pLed->bLedBlinkInProgress) {
-                       if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
-                               return;
-                       if (pLed->bLedNoLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedNoLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedLinkBlinkInProgress = false;
-                       }
-                       pLed->bLedBlinkInProgress = true;
-                       pLed->CurrLedState = LED_BLINK_TXRX;
-                       pLed->BlinkTimes = 2;
-                       if (pLed->bLedOn)
-                               pLed->BlinkingLedState = RTW_LED_OFF;
-                       else
-                               pLed->BlinkingLedState = RTW_LED_ON;
-                       mod_timer(&pLed->BlinkTimer, jiffies +
-                                 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
+               if (pLed->bLedBlinkInProgress)
+                       break;
+               if (pLed->CurrLedState == LED_BLINK_SCAN ||
+                   IS_LED_WPS_BLINKING(pLed))
+                       return;
+               if (pLed->bLedNoLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedNoLinkBlinkInProgress = false;
+               }
+               if (pLed->bLedLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedLinkBlinkInProgress = false;
                }
+               pLed->bLedBlinkInProgress = true;
+               pLed->CurrLedState = LED_BLINK_TXRX;
+               pLed->BlinkTimes = 2;
+               if (pLed->bLedOn)
+                       pLed->BlinkingLedState = RTW_LED_OFF;
+               else
+                       pLed->BlinkingLedState = RTW_LED_ON;
+               mod_timer(&pLed->BlinkTimer, jiffies +
+                         msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
                break;
        case LED_CTL_START_WPS: /* wait until xinpin finish */
        case LED_CTL_START_WPS_BOTTON:
-               if (!pLed->bLedWPSBlinkInProgress) {
-                       if (pLed->bLedNoLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedNoLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedLinkBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                                pLed->bLedLinkBlinkInProgress = false;
-                       }
-                       if (pLed->bLedBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedBlinkInProgress = false;
-                       }
-                       if (pLed->bLedScanBlinkInProgress) {
-                               del_timer_sync(&pLed->BlinkTimer);
-                               pLed->bLedScanBlinkInProgress = false;
-                       }
-                       pLed->bLedWPSBlinkInProgress = true;
-                       pLed->CurrLedState = LED_BLINK_WPS;
-                       if (pLed->bLedOn)
-                               pLed->BlinkingLedState = RTW_LED_OFF;
-                       else
-                               pLed->BlinkingLedState = RTW_LED_ON;
-                       mod_timer(&pLed->BlinkTimer, jiffies +
-                                 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
+               if (pLed->bLedWPSBlinkInProgress)
+                       break;
+               if (pLed->bLedNoLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedNoLinkBlinkInProgress = false;
+               }
+               if (pLed->bLedLinkBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedLinkBlinkInProgress = false;
                }
+               if (pLed->bLedBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedBlinkInProgress = false;
+               }
+               if (pLed->bLedScanBlinkInProgress) {
+                       del_timer_sync(&pLed->BlinkTimer);
+                       pLed->bLedScanBlinkInProgress = false;
+               }
+               pLed->bLedWPSBlinkInProgress = true;
+               pLed->CurrLedState = LED_BLINK_WPS;
+               if (pLed->bLedOn)
+                       pLed->BlinkingLedState = RTW_LED_OFF;
+               else
+                       pLed->BlinkingLedState = RTW_LED_ON;
+               mod_timer(&pLed->BlinkTimer, jiffies +
+                         msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
                break;
        case LED_CTL_STOP_WPS:
                if (pLed->bLedNoLinkBlinkInProgress) {
@@ -378,7 +383,7 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                }
                if (pLed->bLedLinkBlinkInProgress) {
                        del_timer_sync(&pLed->BlinkTimer);
-                        pLed->bLedLinkBlinkInProgress = false;
+                       pLed->bLedLinkBlinkInProgress = false;
                }
                if (pLed->bLedBlinkInProgress) {
                        del_timer_sync(&pLed->BlinkTimer);
@@ -446,7 +451,8 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
                break;
        }
 
-       RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState));
+       RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
+                ("Led %d\n", pLed->CurrLedState));
 }
 
 /*  */
@@ -457,7 +463,7 @@ void BlinkHandler(struct LED_871x *pLed)
 {
        struct adapter *padapter = pLed->padapter;
 
-       if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped))
+       if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
                return;
 
        SwLedBlink1(pLed);
@@ -465,8 +471,8 @@ void BlinkHandler(struct LED_871x *pLed)
 
 void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction)
 {
-       if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) ||
-          (!padapter->hw_init_completed))
+       if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
+           !padapter->hw_init_completed)
                return;
 
        if ((padapter->pwrctrlpriv.rf_pwrstate != rf_on &&
index eca06f05c0c4fa194526a246e7351a9a6b4f100a..b9bd864f323c931a30a50734c0f84327aeb108f0 100644 (file)
@@ -20,7 +20,7 @@
 #include <rtw_ioctl_set.h>
 #include <linux/vmalloc.h>
 
-extern unsigned char   MCS_rate_1R[16];
+extern const u8 MCS_rate_1R[16];
 
 int rtw_init_mlme_priv(struct adapter *padapter)
 {
@@ -228,7 +228,7 @@ int rtw_if_up(struct adapter *padapter)
        int res;
 
        if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
-           (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false)) {
+           !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
                RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
                         ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
                         padapter->bDriverStopped, padapter->bSurpriseRemoved));
@@ -305,7 +305,7 @@ static int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
 
 int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
 {
-        u16 s_cap, d_cap;
+       u16 s_cap, d_cap;
        __le16 le_scap, le_dcap;
 
        memcpy((u8 *)&le_scap, rtw_get_capability_from_ie(src->ies), 2);
@@ -540,7 +540,7 @@ static int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *
 /* TODO: Perry: For Power Management */
 void rtw_atimdone_event_callback(struct adapter *adapter, u8 *pbuf)
 {
-       RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_evet\n"));
+       RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_event\n"));
 }
 
 void rtw_survey_event_callback(struct adapter  *adapter, u8 *pbuf)
@@ -578,7 +578,7 @@ void rtw_survey_event_callback(struct adapter       *adapter, u8 *pbuf)
        }
 
        /*  lock pmlmepriv->lock when you accessing network_q */
-       if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false) {
+       if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
                if (pnetwork->Ssid.Ssid[0] == 0)
                        pnetwork->Ssid.SsidLength = 0;
                rtw_add_network(adapter, pnetwork);
@@ -615,7 +615,7 @@ void rtw_surveydone_event_callback(struct adapter   *adapter, u8 *pbuf)
 
        if (pmlmepriv->to_join) {
                if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
-                       if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
+                       if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
                                set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
 
                                if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
@@ -828,29 +828,6 @@ inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted)
        rtw_os_indicate_scan_done(padapter, aborted);
 }
 
-void rtw_scan_abort(struct adapter *adapter)
-{
-       unsigned long start;
-       struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
-       struct mlme_ext_priv    *pmlmeext = &(adapter->mlmeextpriv);
-
-       start = jiffies;
-       pmlmeext->scan_abort = true;
-       while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
-              jiffies_to_msecs(jiffies - start) <= 200) {
-               if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
-                       break;
-               DBG_88E(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
-               msleep(20);
-       }
-       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
-               if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
-                       DBG_88E(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
-               rtw_indicate_scan_done(adapter, true);
-       }
-       pmlmeext->scan_abort = false;
-}
-
 static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork)
 {
        int i;
@@ -865,7 +842,7 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str
        if (psta) { /* update ptarget_sta */
                DBG_88E("%s\n", __func__);
                psta->aid  = pnetwork->join_res;
-                       psta->mac_id = 0;
+               psta->mac_id = 0;
                /* sta mode */
                rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
                /* security related */
@@ -1061,12 +1038,12 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
                        }
 
                        /* s4. indicate connect */
-                               if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
-                                       rtw_indicate_connect(adapter);
-                               } else {
-                                       /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
-                                       RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
-                               }
+                       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
+                               rtw_indicate_connect(adapter);
+                       } else {
+                               /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
+                               RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
+                       }
 
                        /* s5. Cancel assoc_timer */
                        del_timer_sync(&pmlmepriv->assoc_timer);
@@ -1161,7 +1138,7 @@ void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
        struct wlan_network     *cur_network = &(pmlmepriv->cur_network);
        struct wlan_network     *ptarget_wlan = NULL;
 
-       if (rtw_access_ctrl(adapter, pstassoc->macaddr) == false)
+       if (!rtw_access_ctrl(adapter, pstassoc->macaddr))
                return;
 
 #if defined(CONFIG_88EU_AP_MODE)
@@ -1437,17 +1414,17 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
        /* check ssid, if needed */
        if (pmlmepriv->assoc_ssid.SsidLength) {
                if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength ||
-                   !memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength) == false)
+                   memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength))
                        goto exit;
        }
 
-       if (rtw_is_desired_network(adapter, competitor)  == false)
+       if (!rtw_is_desired_network(adapter, competitor))
                goto exit;
 
        if (pmlmepriv->to_roaming) {
                since_scan = jiffies - competitor->last_scanned;
                if (jiffies_to_msecs(since_scan) >= RTW_SCAN_RESULT_EXPIRE ||
-                   is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) == false)
+                   !is_same_ess(&competitor->network, &pmlmepriv->cur_network.network))
                        goto exit;
        }
 
@@ -1819,18 +1796,8 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter)
        case WIRELESS_11BG_24N:
                pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
                break;
-       case WIRELESS_11A:
-       case WIRELESS_11A_5N:
-               pdev_network->NetworkTypeInUse = Ndis802_11OFDM5;
-               break;
-       case WIRELESS_11ABGN:
-               if (pregistrypriv->channel > 14)
-                       pdev_network->NetworkTypeInUse = Ndis802_11OFDM5;
-               else
-                       pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
-               break;
        default:
-               /*  TODO */
+               pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
                break;
        }
 
index 1115050077e423dfc4ae7c73f970fc1eb64d56a5..6790b840aef84d9f26255d02ea0c79439ba447d8 100644 (file)
@@ -39,7 +39,10 @@ extern unsigned char REALTEK_96B_IE[];
 /********************************************************
 MCS rate definitions
 *********************************************************/
-unsigned char  MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+const u8 MCS_rate_1R[16] = {
+       0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
 
 /********************************************************
 ChannelPlan definitions
@@ -1513,7 +1516,7 @@ static int issue_deauth_ex(struct adapter *padapter, u8 *da,
                        break;
 
                if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
-                       msleep(wait_ms);
+                       mdelay(wait_ms);
        } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
 
        if (ret != _FAIL) {
@@ -2401,10 +2404,7 @@ static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid
                        p++;
 
                        for (j = 0; j < noc; j++) {
-                               if (fcn <= 14)
-                                       channel = fcn + j; /*  2.4 GHz */
-                               else
-                                       channel = fcn + j*4; /*  5 GHz */
+                               channel = fcn + j;
 
                                chplan_ap.Channel[i++] = channel;
                        }
@@ -2481,14 +2481,6 @@ static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid
                                j++;
                }
 
-               /*  keep original STA 5G channel plan */
-               while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
-                       chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
-                       chplan_new[k].ScanType = chplan_sta[i].ScanType;
-                       i++;
-                       k++;
-               }
-
                pmlmeext->update_channel_plan_by_ap_done = 1;
        }
 
@@ -2982,11 +2974,11 @@ static unsigned int OnAssocReq(struct adapter *padapter,
        /*  checking SSID */
        p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
                pkt_len - WLAN_HDR_A3_LEN - ie_offset);
-       if (!p)
-               status = _STATS_FAILURE_;
 
-       if (ie_len == 0) { /*  broadcast ssid, however it is not allowed in assocreq */
+       if (!p || ie_len == 0) {
+               /*  broadcast ssid, however it is not allowed in assocreq */
                status = _STATS_FAILURE_;
+               goto OnAssocReqFail;
        } else {
                /*  check if ssid match */
                if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
@@ -3844,24 +3836,20 @@ Following are the initialization functions for WiFi MLME
 *****************************************************************************/
 
 static struct mlme_handler mlme_sta_tbl[] = {
-       {WIFI_ASSOCREQ,         "OnAssocReq",   &OnAssocReq},
-       {WIFI_ASSOCRSP,         "OnAssocRsp",   &OnAssocRsp},
-       {WIFI_REASSOCREQ,       "OnReAssocReq", &OnAssocReq},
-       {WIFI_REASSOCRSP,       "OnReAssocRsp", &OnAssocRsp},
-       {WIFI_PROBEREQ,         "OnProbeReq",   &OnProbeReq},
-       {WIFI_PROBERSP,         "OnProbeRsp",           &OnProbeRsp},
-
-       /*----------------------------------------------------------
-                                       below 2 are reserved
-       -----------------------------------------------------------*/
-       {0,                                     "DoReserved",           &DoReserved},
-       {0,                                     "DoReserved",           &DoReserved},
-       {WIFI_BEACON,           "OnBeacon",             &OnBeacon},
-       {WIFI_ATIM,                     "OnATIM",               &OnAtim},
-       {WIFI_DISASSOC,         "OnDisassoc",           &OnDisassoc},
-       {WIFI_AUTH,                     "OnAuth",               &OnAuthClient},
-       {WIFI_DEAUTH,           "OnDeAuth",             &OnDeAuth},
-       {WIFI_ACTION,           "OnAction",             &OnAction},
+       {WIFI_ASSOCREQ,   "OnAssocReq",   &OnAssocReq},
+       {WIFI_ASSOCRSP,   "OnAssocRsp",   &OnAssocRsp},
+       {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
+       {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
+       {WIFI_PROBEREQ,   "OnProbeReq",   &OnProbeReq},
+       {WIFI_PROBERSP,   "OnProbeRsp",   &OnProbeRsp},
+       {0,               "DoReserved",   &DoReserved},
+       {0,               "DoReserved",   &DoReserved},
+       {WIFI_BEACON,     "OnBeacon",     &OnBeacon},
+       {WIFI_ATIM,       "OnATIM",       &OnAtim},
+       {WIFI_DISASSOC,   "OnDisassoc",   &OnDisassoc},
+       {WIFI_AUTH,       "OnAuth",       &OnAuthClient},
+       {WIFI_DEAUTH,     "OnDeAuth",     &OnDeAuth},
+       {WIFI_ACTION,     "OnAction",     &OnAction},
 };
 
 int init_hw_mlme_ext(struct adapter *padapter)
@@ -3969,7 +3957,7 @@ static void init_channel_list(struct adapter *padapter,
                        if (!has_channel(channel_set, chanset_size, ch))
                                continue;
 
-                       if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
+                       if (!padapter->registrypriv.ht_enable && o->inc == 8)
                                continue;
 
                        if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
index 5ab6fc22a1566ebce63e3558305b053abbf0c5bd..9764e85c000c8be96fa5f94086173f43451b583f 100644 (file)
@@ -292,7 +292,7 @@ void rtw_set_rpwm(struct adapter *padapter, u8 pslv)
                        pslv = PS_STATE_S3;
        }
 
-       if ((pwrpriv->rpwm == pslv)) {
+       if (pwrpriv->rpwm == pslv) {
                RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
                         ("%s: Already set rpwm[0x%02X], new=0x%02X!\n", __func__, pwrpriv->rpwm, pslv));
                return;
@@ -344,7 +344,7 @@ static u8 PS_RDY_CHECK(struct adapter *padapter)
        if (delta_time < LPS_DELAY_TIME)
                return false;
 
-       if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) ||
+       if ((!check_fwstate(pmlmepriv, _FW_LINKED)) ||
            (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) ||
            (check_fwstate(pmlmepriv, WIFI_AP_STATE)) ||
            (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
@@ -352,7 +352,8 @@ static u8 PS_RDY_CHECK(struct adapter *padapter)
                return false;
        if (pwrpriv->bInSuspend)
                return false;
-       if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == false)) {
+       if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X &&
+           !padapter->securitypriv.binstallGrpkey) {
                DBG_88E("Group handshake still in progress !!!\n");
                return false;
        }
@@ -438,7 +439,7 @@ void LPS_Enter(struct adapter *padapter)
 {
        struct pwrctrl_priv     *pwrpriv = &padapter->pwrctrlpriv;
 
-       if (PS_RDY_CHECK(padapter) == false)
+       if (!PS_RDY_CHECK(padapter))
                return;
 
        if (pwrpriv->bLeisurePs) {
index 17b4b9257b49588aa505566656e356ce6805018e..dc447cc78c328776b9ab1444aec1047a74fdecd1 100644 (file)
@@ -233,7 +233,7 @@ static int recvframe_chkmic(struct adapter *adapter,
 
                /* calculate mic code */
                if (stainfo) {
-                       if (IS_MCAST(prxattrib->ra)) {
+                       if (is_multicast_ether_addr(prxattrib->ra)) {
                                if (!psecuritypriv) {
                                        res = _FAIL;
                                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
@@ -321,11 +321,11 @@ static int recvframe_chkmic(struct adapter *adapter,
 
                                /*  double check key_index for some timing issue , */
                                /*  cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
-                               if ((IS_MCAST(prxattrib->ra) == true)  && (prxattrib->key_index != pmlmeinfo->key_index))
+                               if (is_multicast_ether_addr(prxattrib->ra) && prxattrib->key_index != pmlmeinfo->key_index)
                                        brpt_micerror = false;
 
                                if ((prxattrib->bdecrypted) && (brpt_micerror)) {
-                                       rtw_handle_tkip_mic_err(adapter, (u8)IS_MCAST(prxattrib->ra));
+                                       rtw_handle_tkip_mic_err(adapter, (u8)is_multicast_ether_addr(prxattrib->ra));
                                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted=%d ", prxattrib->bdecrypted));
                                        DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
                                } else {
@@ -335,7 +335,7 @@ static int recvframe_chkmic(struct adapter *adapter,
                                res = _FAIL;
                        } else {
                                /* mic checked ok */
-                               if ((!psecuritypriv->bcheck_grpkey) && (IS_MCAST(prxattrib->ra))) {
+                               if (!psecuritypriv->bcheck_grpkey && is_multicast_ether_addr(prxattrib->ra)) {
                                        psecuritypriv->bcheck_grpkey = true;
                                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("psecuritypriv->bcheck_grpkey = true"));
                                }
@@ -488,7 +488,7 @@ static struct recv_frame *portctrl(struct adapter *adapter,
                prtnframe = precv_frame;
        }
 
-               return prtnframe;
+       return prtnframe;
 }
 
 static int recv_decache(struct recv_frame *precv_frame, u8 bretry,
@@ -648,7 +648,7 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
        u8 *mybssid  = get_bssid(pmlmepriv);
        u8 *myhwaddr = myid(&adapter->eeprompriv);
        u8 *sta_addr = NULL;
-       int bmcast = IS_MCAST(pattrib->dst);
+       bool mcast = is_multicast_ether_addr(pattrib->dst);
 
        if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
            (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
@@ -659,7 +659,7 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
                        goto exit;
                }
 
-               if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
+               if (memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && !mcast) {
                        ret = _FAIL;
                        goto exit;
                }
@@ -681,9 +681,9 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
                }
                sta_addr = pattrib->bssid;
        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-               if (bmcast) {
+               if (mcast) {
                        /*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
-                       if (!IS_MCAST(pattrib->bssid)) {
+                       if (!is_multicast_ether_addr(pattrib->bssid)) {
                                        ret = _FAIL;
                                        goto exit;
                        }
@@ -700,7 +700,7 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
                ret  = _FAIL;
        }
 
-       if (bmcast)
+       if (mcast)
                *psta = rtw_get_bcmc_stainfo(adapter);
        else
                *psta = rtw_get_stainfo(pstapriv, sta_addr); /*  get ap_info */
@@ -727,7 +727,7 @@ static int ap2sta_data_frame(
        struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
        u8 *mybssid  = get_bssid(pmlmepriv);
        u8 *myhwaddr = myid(&adapter->eeprompriv);
-       int bmcast = IS_MCAST(pattrib->dst);
+       bool mcast = is_multicast_ether_addr(pattrib->dst);
 
        if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) &&
            (check_fwstate(pmlmepriv, _FW_LINKED) == true ||
@@ -740,7 +740,7 @@ static int ap2sta_data_frame(
                }
 
                /*  da should be for me */
-               if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
+               if (memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && !mcast) {
                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
                                 (" %s:  compare DA fail; DA=%pM\n", __func__, (pattrib->dst)));
                        ret = _FAIL;
@@ -755,7 +755,7 @@ static int ap2sta_data_frame(
                                 (" %s:  compare BSSID fail ; BSSID=%pM\n", __func__, (pattrib->bssid)));
                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("mybssid=%pM\n", (mybssid)));
 
-                       if (!bmcast) {
+                       if (!mcast) {
                                DBG_88E("issue_deauth to the nonassociated ap=%pM for the reason(7)\n", (pattrib->bssid));
                                issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
                        }
@@ -764,7 +764,7 @@ static int ap2sta_data_frame(
                        goto exit;
                }
 
-               if (bmcast)
+               if (mcast)
                        *psta = rtw_get_bcmc_stainfo(adapter);
                else
                        *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get ap_info */
@@ -789,7 +789,7 @@ static int ap2sta_data_frame(
                ret = RTW_RX_HANDLED;
                goto exit;
        } else {
-               if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
+               if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && !mcast) {
                        *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
                        if (*psta == NULL) {
                                DBG_88E("issue_deauth to the ap =%pM for the reason(7)\n", (pattrib->bssid));
@@ -1129,9 +1129,9 @@ static int validate_recv_data_frame(struct adapter *adapter,
 
        if (pattrib->privacy) {
                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("%s:pattrib->privacy=%x\n", __func__, pattrib->privacy));
-               RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n ^^^^^^^^^^^IS_MCAST(pattrib->ra(0x%02x))=%d^^^^^^^^^^^^^^^6\n", pattrib->ra[0], IS_MCAST(pattrib->ra)));
+               RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n ^^^^^^^^^^^is_multicast_ether_addr(pattrib->ra(0x%02x))=%d^^^^^^^^^^^^^^^6\n", pattrib->ra[0], is_multicast_ether_addr(pattrib->ra)));
 
-               GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
+               GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, is_multicast_ether_addr(pattrib->ra));
 
                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt=%d\n", pattrib->encrypt));
 
@@ -1283,8 +1283,8 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
        psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
        /* convert hdr + possible LLC headers into Ethernet header */
        if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
-            (!memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == false) &&
-            (!memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == false)) ||
+            memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) &&
+            memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) ||
             !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
                /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
                bsnaphdr = true;
@@ -1971,7 +1971,8 @@ static int recv_func(struct adapter *padapter, struct recv_frame *rframe)
        if (ret == _SUCCESS) {
                /* check if need to enqueue into uc_swdec_pending_queue*/
                if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
-                   !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 &&
+                   !is_multicast_ether_addr(prxattrib->ra) &&
+                   prxattrib->encrypt > 0 &&
                    prxattrib->bdecrypted == 0 &&
                    !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) &&
                    !psecuritypriv->busetkipkey) {
@@ -2041,7 +2042,7 @@ static void rtw_signal_stat_timer_hdl(struct timer_list *t)
        }
 
        /* update value of signal_strength, rssi, signal_qual */
-       if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == false) {
+       if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
                tmp_s = avg_signal_strength +
                        (_alpha - 1) * recvpriv->signal_strength;
                tmp_s = DIV_ROUND_UP(tmp_s, _alpha);
index 2a48b09ea9ae36d5508e97c9338198bb49248316..f7407632e80bdda9d9e49d1548f9900c35038458 100644 (file)
@@ -353,7 +353,7 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod
 
        /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
        if (header[1]&1) {   /* ToDS == 1 */
-                       rtw_secmicappend(&micdata, &header[16], 6);  /* DA */
+               rtw_secmicappend(&micdata, &header[16], 6);  /* DA */
                if (header[1]&2)  /* From Ds == 1 */
                        rtw_secmicappend(&micdata, &header[24], 6);
                else
@@ -608,7 +608,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
                if (stainfo != NULL) {
                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
 
-                       if (IS_MCAST(pattrib->ra))
+                       if (is_multicast_ether_addr(pattrib->ra))
                                prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
                        else
                                prwskey = &stainfo->dot118021x_UncstKey.skey[0];
@@ -678,7 +678,7 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
        if (prxattrib->encrypt == _TKIP_) {
                stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
                if (stainfo) {
-                       if (IS_MCAST(prxattrib->ra)) {
+                       if (is_multicast_ether_addr(prxattrib->ra)) {
                                if (!psecuritypriv->binstallGrpkey) {
                                        res = _FAIL;
                                        DBG_88E("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
@@ -1250,7 +1250,7 @@ u32       rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
                if (stainfo) {
                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("%s: stainfo!= NULL!!!\n", __func__));
 
-                       if (IS_MCAST(pattrib->ra))
+                       if (is_multicast_ether_addr(pattrib->ra))
                                prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
                        else
                                prwskey = &stainfo->dot118021x_UncstKey.skey[0];
@@ -1273,8 +1273,7 @@ u32       rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
                }
        }
 
-
-               return res;
+       return res;
 }
 
 u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
@@ -1296,7 +1295,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
                        struct security_priv *psecuritypriv = &padapter->securitypriv;
                        char iv[8], icv[8];
 
-                       if (IS_MCAST(prxattrib->ra)) {
+                       if (is_multicast_ether_addr(prxattrib->ra)) {
                                /* in concurrent we should use sw descrypt in group key, so we remove this message */
                                if (!psecuritypriv->binstallGrpkey) {
                                        res = _FAIL;
index b9406583e501dff5e2a32206050aac62f826341e..3e05e2c7f61b9a7b829adffcfc8fd922dd86fc7e 100644 (file)
@@ -107,26 +107,20 @@ unsigned char networktype_to_raid(unsigned char network_type)
 u8 judge_network_type(struct adapter *padapter, unsigned char *rate, int ratelen)
 {
        u8 network_type = 0;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
+       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 
-       if (pmlmeext->cur_channel > 14) {
-               if (pmlmeinfo->HT_enable)
-                       network_type = WIRELESS_11_5N;
+       if (pmlmeinfo->HT_enable)
+               network_type = WIRELESS_11_24N;
 
-               network_type |= WIRELESS_11A;
-       } else {
-               if (pmlmeinfo->HT_enable)
-                       network_type = WIRELESS_11_24N;
-
-               if ((cckratesonly_included(rate, ratelen)) == true)
-                       network_type |= WIRELESS_11B;
-               else if ((cckrates_included(rate, ratelen)) == true)
-                       network_type |= WIRELESS_11BG;
-               else
-                       network_type |= WIRELESS_11G;
-       }
-       return  network_type;
+       if (cckratesonly_included(rate, ratelen))
+               network_type |= WIRELESS_11B;
+       else if (cckrates_included(rate, ratelen))
+               network_type |= WIRELESS_11BG;
+       else
+               network_type |= WIRELESS_11G;
+
+       return network_type;
 }
 
 static unsigned char ratetbl_val_2wifirate(unsigned char rate)
@@ -460,9 +454,9 @@ void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
 
 void clear_cam_entry(struct adapter *padapter, u8 entry)
 {
-       unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-       unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+       u8 null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+       u8 null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
        write_cam(padapter, entry, 0, null_sta, null_key);
 }
@@ -852,7 +846,7 @@ int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
        unsigned char   ht_info_infos_0;
        int ssid_len;
 
-       if (is_client_associated_to_ap(Adapter) == false)
+       if (!is_client_associated_to_ap(Adapter))
                return true;
 
        len = packet_len - sizeof(struct ieee80211_hdr_3addr);
@@ -862,7 +856,7 @@ int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
                return _FAIL;
        }
 
-       if (!memcmp(cur_network->network.MacAddress, pbssid, 6) == false) {
+       if (memcmp(cur_network->network.MacAddress, pbssid, 6)) {
                DBG_88E("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n%pM %pM\n",
                        (pbssid), (cur_network->network.MacAddress));
                return true;
@@ -1419,32 +1413,25 @@ void update_wireless_mode(struct adapter *padapter)
 {
        int ratelen, network_type = 0;
        u32 SIFS_Timer;
-       struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
-       struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
-       struct wlan_bssid_ex    *cur_network = &(pmlmeinfo->network);
-       unsigned char           *rate = cur_network->SupportedRates;
+       struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+       struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+       struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
+       unsigned char *rate = cur_network->SupportedRates;
 
        ratelen = rtw_get_rateset_len(cur_network->SupportedRates);
 
-       if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
+       if (pmlmeinfo->HT_info_enable && pmlmeinfo->HT_caps_enable)
                pmlmeinfo->HT_enable = 1;
 
-       if (pmlmeext->cur_channel > 14) {
-               if (pmlmeinfo->HT_enable)
-                       network_type = WIRELESS_11_5N;
+       if (pmlmeinfo->HT_enable)
+               network_type = WIRELESS_11_24N;
 
-               network_type |= WIRELESS_11A;
-       } else {
-               if (pmlmeinfo->HT_enable)
-                       network_type = WIRELESS_11_24N;
-
-               if ((cckratesonly_included(rate, ratelen)) == true)
-                       network_type |= WIRELESS_11B;
-               else if ((cckrates_included(rate, ratelen)) == true)
-                       network_type |= WIRELESS_11BG;
-               else
-                       network_type |= WIRELESS_11G;
-       }
+       if (cckratesonly_included(rate, ratelen))
+               network_type |= WIRELESS_11B;
+       else if (cckrates_included(rate, ratelen))
+               network_type |= WIRELESS_11BG;
+       else
+               network_type |= WIRELESS_11G;
 
        pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
 
index 2130d78e0d9fad3da294f4cd078b71f94e10e54e..0a3e710590ed0239a78e52727f52b3f40e2917ca 100644 (file)
@@ -77,8 +77,6 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
                goto exit;
        }
        pxmitpriv->pxmit_frame_buf = PTR_ALIGN(pxmitpriv->pallocated_frame_buf, 4);
-       /* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
-       /*                                              ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */
 
        pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
 
@@ -115,8 +113,6 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
        }
 
        pxmitpriv->pxmitbuf = PTR_ALIGN(pxmitpriv->pallocated_xmitbuf, 4);
-       /* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
-       /*                                              ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */
 
        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 
@@ -254,10 +250,12 @@ static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *
        else /* no frag */
                sz = pattrib->last_txcmdsz;
 
-       /*  (1) RTS_Threshold is compared to the MPDU, not MSDU. */
-       /*  (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
-       /*              Other fragments are protected by previous fragment. */
-       /*              So we only need to check the length of first fragment. */
+       /* (1) RTS_Threshold is compared to the MPDU, not MSDU.
+        * (2) If there are more than one frag in this MSDU,
+        *     only the first frag uses protection frame.
+        * Other fragments are protected by previous fragment.
+        * So we only need to check the length of first fragment.
+        */
        if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
                if (sz > padapter->registrypriv.rts_thresh) {
                        pattrib->vcs_mode = RTS_CTS;
@@ -321,13 +319,6 @@ static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *
 
 static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
 {
-       /*if (psta->rtsen)
-               pattrib->vcs_mode = RTS_CTS;
-       else if (psta->cts2self)
-               pattrib->vcs_mode = CTS_TO_SELF;
-       else
-               pattrib->vcs_mode = NONE_VCS;*/
-
        pattrib->mdata = 0;
        pattrib->eosp = 0;
        pattrib->triggered = 0;
@@ -344,9 +335,9 @@ static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *
        pattrib->retry_ctrl = false;
 }
 
-u8     qos_acm(u8 acm_mask, u8 priority)
+u8 qos_acm(u8 acm_mask, u8 priority)
 {
-       u8      change_priority = priority;
+       u8 change_priority = priority;
 
        switch (priority) {
        case 0:
@@ -368,7 +359,8 @@ u8  qos_acm(u8 acm_mask, u8 priority)
                        change_priority = 5;
                break;
        default:
-               DBG_88E("qos_acm(): invalid pattrib->priority: %d!!!\n", priority);
+               DBG_88E("%s(): invalid pattrib->priority: %d!!!\n",
+                       __func__, priority);
                break;
        }
 
@@ -383,8 +375,10 @@ static void set_qos(struct sk_buff *skb, struct pkt_attrib *pattrib)
                skb_copy_bits(skb, ETH_HLEN, &ip_hdr, sizeof(ip_hdr));
                pattrib->priority = ip_hdr.tos >> 5;
        } else if (pattrib->ether_type == ETH_P_PAE) {
-               /*  "When priority processing of data frames is supported, */
-               /*  a STA's SME should send EAPOL-Key frames at the highest priority." */
+               /* When priority processing of data frames is supported,
+                * a STA's SME should send EAPOL-Key frames at the highest
+                * priority.
+                */
                pattrib->priority = 7;
        } else {
                pattrib->priority = 0;
@@ -399,7 +393,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
        struct sta_info *psta = NULL;
        struct ethhdr etherhdr;
 
-       int bmcast;
+       bool mcast;
        struct sta_priv         *pstapriv = &padapter->stapriv;
        struct security_priv    *psecuritypriv = &padapter->securitypriv;
        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
@@ -430,8 +424,10 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
        pattrib->pktlen = pkt->len - ETH_HLEN;
 
        if (pattrib->ether_type == ETH_P_IP) {
-               /*  The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
-               /*  to prevent DHCP protocol fail */
+               /* The following is for DHCP and ARP packet, we use
+                * cck1M to tx these packets and let LPS awake some
+                * time to prevent DHCP protocol fail.
+                */
                u8 tmp[24];
 
                skb_copy_bits(pkt, ETH_HLEN, tmp, 24);
@@ -460,10 +456,10 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
        if ((pattrib->ether_type == ETH_P_ARP) || (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
 
-       bmcast = IS_MCAST(pattrib->ra);
+       mcast = is_multicast_ether_addr(pattrib->ra);
 
        /*  get sta_info */
-       if (bmcast) {
+       if (mcast) {
                psta = rtw_get_bcmc_stainfo(padapter);
        } else {
                psta = rtw_get_stainfo(pstapriv, pattrib->ra);
@@ -494,7 +490,8 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
        pattrib->subtype = WIFI_DATA_TYPE;
        pattrib->priority = 0;
 
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
+       if (check_fwstate(pmlmepriv, WIFI_AP_STATE |
+                         WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
                if (psta->qos_option)
                        set_qos(pkt, pattrib);
        } else {
@@ -517,7 +514,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
                        goto exit;
                }
        } else {
-               GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
+               GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, mcast);
 
                switch (psecuritypriv->dot11AuthAlgrthm) {
                case dot11AuthAlgrthm_Open:
@@ -526,7 +523,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
                        pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
                        break;
                case dot11AuthAlgrthm_8021X:
-                       if (bmcast)
+                       if (mcast)
                                pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
                        else
                                pattrib->key_idx = 0;
@@ -596,7 +593,6 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
        u8 hw_hdr_offset = 0;
-       int bmcst = IS_MCAST(pattrib->ra);
 
        if (pattrib->psta)
                stainfo = pattrib->psta;
@@ -605,7 +601,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
 
        hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
 
-       if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */
+       if (pattrib->encrypt == _TKIP_) {
                /* encode mic code */
                if (stainfo) {
                        u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
@@ -614,30 +610,27 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
 
                        pframe = pxmitframe->buf_addr + hw_hdr_offset;
 
-                       if (bmcst) {
+                       if (is_multicast_ether_addr(pattrib->ra)) {
                                if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16))
                                        return _FAIL;
                                /* start to calculate the mic code */
                                rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
                        } else {
-                               if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16)) {
-                                       /* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey == 0\n"); */
-                                       /* msleep(10); */
+                               if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16))
                                        return _FAIL;
-                               }
                                /* start to calculate the mic code */
                                rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
                        }
 
-                       if (pframe[1]&1) {   /* ToDS == 1 */
+                       if (pframe[1] & 1) {   /* ToDS == 1 */
                                rtw_secmicappend(&micdata, &pframe[16], 6);  /* DA */
-                               if (pframe[1]&2)  /* From Ds == 1 */
+                               if (pframe[1] & 2)  /* From Ds == 1 */
                                        rtw_secmicappend(&micdata, &pframe[24], 6);
                                else
                                rtw_secmicappend(&micdata, &pframe[10], 6);
                        } else {        /* ToDS == 0 */
                                rtw_secmicappend(&micdata, &pframe[4], 6);   /* DA */
-                               if (pframe[1]&2)  /* From Ds == 1 */
+                               if (pframe[1] & 2)  /* From Ds == 1 */
                                        rtw_secmicappend(&micdata, &pframe[16], 6);
                                else
                                        rtw_secmicappend(&micdata, &pframe[10], 6);
@@ -654,23 +647,31 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
                                payload = (u8 *)round_up((size_t)(payload), 4);
                                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
                                         ("=== curfragnum=%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
-                                        curfragnum, *payload, *(payload+1),
-                                        *(payload+2), *(payload+3),
-                                        *(payload+4), *(payload+5),
-                                        *(payload+6), *(payload+7)));
+                                        curfragnum, *payload, *(payload + 1),
+                                        *(payload + 2), *(payload + 3),
+                                        *(payload + 4), *(payload + 5),
+                                        *(payload + 6), *(payload + 7)));
 
-                               payload = payload+pattrib->hdrlen+pattrib->iv_len;
+                               payload += pattrib->hdrlen + pattrib->iv_len;
                                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
                                         ("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",
                                         curfragnum, pattrib->hdrlen, pattrib->iv_len));
-                               if ((curfragnum+1) == pattrib->nr_frags) {
-                                       length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
+                               if (curfragnum + 1 == pattrib->nr_frags) {
+                                       length = pattrib->last_txcmdsz -
+                                                pattrib->hdrlen -
+                                                pattrib->iv_len -
+                                                ((pattrib->bswenc) ?
+                                                 pattrib->icv_len : 0);
                                        rtw_secmicappend(&micdata, payload, length);
-                                       payload = payload+length;
+                                       payload += length;
                                } else {
-                                       length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
+                                       length = pxmitpriv->frag_len -
+                                                pattrib->hdrlen -
+                                                pattrib->iv_len -
+                                                ((pattrib->bswenc) ?
+                                                 pattrib->icv_len : 0);
                                        rtw_secmicappend(&micdata, payload, length);
-                                       payload = payload+length+pattrib->icv_len;
+                                       payload += length + pattrib->icv_len;
                                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum=%d length=%d pattrib->icv_len=%d", curfragnum, length, pattrib->icv_len));
                                }
                        }
@@ -686,8 +687,8 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
                        pattrib->last_txcmdsz += 8;
 
                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("\n ======== last pkt ========\n"));
-                       payload = payload-pattrib->last_txcmdsz+8;
-                       for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; curfragnum = curfragnum+8)
+                       payload -= pattrib->last_txcmdsz + 8;
+                       for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; curfragnum += 8)
                                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
                                         (" %.2x,  %.2x,  %.2x,  %.2x,  %.2x,  %.2x,  %.2x,  %.2x ",
                                         *(payload + curfragnum), *(payload + curfragnum + 1),
@@ -743,12 +744,10 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr
 
        struct sta_info *psta;
 
-       int bmcst = IS_MCAST(pattrib->ra);
-
        if (pattrib->psta) {
                psta = pattrib->psta;
        } else {
-               if (bmcst)
+               if (is_multicast_ether_addr(pattrib->ra))
                        psta = rtw_get_bcmc_stainfo(padapter);
                else
                        psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
@@ -836,11 +835,11 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr
                                if (SN_LESS(pattrib->seqnum, tx_seq)) {
                                        pattrib->ampdu_en = false;/* AGG BK */
                                } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
-                                       psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
+                                       psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff;
 
                                        pattrib->ampdu_en = true;/* AGG EN */
                                } else {
-                                       psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
+                                       psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff;
                                        pattrib->ampdu_en = true;/* AGG EN */
                                }
                        }
@@ -856,9 +855,9 @@ s32 rtw_txframes_pending(struct adapter *padapter)
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 
        return (!list_empty(&pxmitpriv->be_pending.queue) ||
-                       !list_empty(&pxmitpriv->bk_pending.queue) ||
-                       !list_empty(&pxmitpriv->vi_pending.queue) ||
-                       !list_empty(&pxmitpriv->vo_pending.queue));
+               !list_empty(&pxmitpriv->bk_pending.queue) ||
+               !list_empty(&pxmitpriv->vi_pending.queue) ||
+               !list_empty(&pxmitpriv->vo_pending.queue));
 }
 
 s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib)
@@ -914,7 +913,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
        u8 *pbuf_start;
-       s32 bmcst = IS_MCAST(pattrib->ra);
+       bool mcast = is_multicast_ether_addr(pattrib->ra);
        s32 res = _SUCCESS;
        size_t remainder = pkt->len - ETH_HLEN;
 
@@ -964,13 +963,13 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
                                WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
                                break;
                        case _TKIP_:
-                               if (bmcst)
+                               if (mcast)
                                        TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
                                else
                                        TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
                                break;
                        case _AES_:
-                               if (bmcst)
+                               if (mcast)
                                        AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
                                else
                                        AES_IV(pattrib->iv, psta->dot11txpn, 0);
@@ -981,7 +980,10 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
 
                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
                                 ("%s: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
-                                 __func__, padapter->securitypriv.dot11PrivacyKeyIndex, pattrib->iv[3], *pframe, *(pframe+1), *(pframe+2), *(pframe+3)));
+                                 __func__,
+                                 padapter->securitypriv.dot11PrivacyKeyIndex,
+                                 pattrib->iv[3], *pframe, *(pframe + 1),
+                                 *(pframe + 2), *(pframe + 3)));
 
                        pframe += pattrib->iv_len;
 
@@ -997,7 +999,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
                if ((pattrib->icv_len > 0) && (pattrib->bswenc))
                        mpdu_len -= pattrib->icv_len;
 
-               mem_sz = min_t(size_t, bmcst ? pattrib->pktlen : mpdu_len, remainder);
+               mem_sz = min_t(size_t, mcast ? pattrib->pktlen : mpdu_len, remainder);
                skb_copy_bits(pkt, pkt->len - remainder, pframe, mem_sz);
                remainder -= mem_sz;
 
@@ -1010,7 +1012,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
 
                frg_inx++;
 
-               if (bmcst || remainder == 0) {
+               if (mcast || remainder == 0) {
                        pattrib->nr_frags = frg_inx;
 
                        pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) +
@@ -1041,7 +1043,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
 
        xmitframe_swencrypt(padapter, pxmitframe);
 
-       if (!bmcst)
+       if (!mcast)
                update_attrib_vcs_info(padapter, pxmitframe);
        else
                pattrib->vcs_mode = NONE_VCS;
@@ -1121,7 +1123,7 @@ void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe,
        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 
-       if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) {
+       if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
                pxmitpriv->tx_bytes += sz;
                pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num;
 
@@ -1147,7 +1149,6 @@ struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
                list_del_init(&pxmitbuf->list);
                pxmitpriv->free_xmit_extbuf_cnt--;
                pxmitbuf->priv_data = NULL;
-               /* pxmitbuf->ext_tag = true; */
                if (pxmitbuf->sctx) {
                        DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
                        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
@@ -1184,8 +1185,6 @@ struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
        struct xmit_buf *pxmitbuf;
        struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 
-       /* DBG_88E("+rtw_alloc_xmitbuf\n"); */
-
        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
        pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
                                            struct xmit_buf, list);
@@ -1276,7 +1275,6 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)
                pxframe->pxmitbuf = NULL;
 
                memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
-               /* pxframe->attrib.psta = NULL; */
 
                pxframe->frame_tag = DATA_FRAMETAG;
 
@@ -1350,7 +1348,6 @@ s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitfram
        if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
                RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
                         ("%s: drop xmit pkt for classifier fail\n", __func__));
-/*             pxmitframe->pkt = NULL; */
                return _FAIL;
        }
 
@@ -1429,7 +1426,8 @@ exit:
        return pxmitframe;
 }
 
-struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, int up, u8 *ac)
+struct tx_servq *rtw_get_sta_pending(struct adapter *padapter,
+                                    struct sta_info *psta, int up, u8 *ac)
 {
        struct tx_servq *ptxservq;
 
@@ -1438,26 +1436,30 @@ struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *
        case 2:
                ptxservq = &psta->sta_xmitpriv.bk_q;
                *(ac) = 3;
-               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s : BK\n", __func__));
+               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
+                        ("%s : BK\n", __func__));
                break;
        case 4:
        case 5:
                ptxservq = &psta->sta_xmitpriv.vi_q;
                *(ac) = 1;
-               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s : VI\n", __func__));
+               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
+                        ("%s : VI\n", __func__));
                break;
        case 6:
        case 7:
                ptxservq = &psta->sta_xmitpriv.vo_q;
                *(ac) = 0;
-               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s : VO\n", __func__));
+               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
+                        ("%s : VO\n", __func__));
                break;
        case 0:
        case 3:
        default:
                ptxservq = &psta->sta_xmitpriv.be_q;
                *(ac) = 2;
-               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s : BE\n", __func__));
+               RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
+                        ("%s : BE\n", __func__));
        break;
        }
 
@@ -1617,7 +1619,7 @@ s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
        spin_unlock_bh(&pxmitpriv->lock);
 #endif
 
-       if (rtw_hal_xmit(padapter, pxmitframe) == false)
+       if (!rtw_hal_xmit(padapter, pxmitframe))
                return 1;
 
        return 0;
@@ -1632,9 +1634,9 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
        struct sta_priv *pstapriv = &padapter->stapriv;
        struct pkt_attrib *pattrib = &pxmitframe->attrib;
        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-       int bmcst = IS_MCAST(pattrib->ra);
+       bool mcast = is_multicast_ether_addr(pattrib->ra);
 
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false)
+       if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
                return ret;
 
        if (pattrib->psta)
@@ -1646,12 +1648,12 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
                return ret;
 
        if (pattrib->triggered == 1) {
-               if (bmcst)
+               if (mcast)
                        pattrib->qsel = 0x11;/* HIQ */
                return ret;
        }
 
-       if (bmcst) {
+       if (mcast) {
                spin_lock_bh(&psta->sleep_q.lock);
 
                if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */
@@ -1676,10 +1678,10 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
 
        spin_lock_bh(&psta->sleep_q.lock);
 
-       if (psta->state&WIFI_SLEEP_STATE) {
+       if (psta->state & WIFI_SLEEP_STATE) {
                u8 wmmps_ac = 0;
 
-               if (pstapriv->sta_dz_bitmap&BIT(psta->aid)) {
+               if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
                        list_del_init(&pxmitframe->list);
 
                        list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
@@ -1773,21 +1775,26 @@ void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
 
        pstapriv->sta_dz_bitmap |= BIT(psta->aid);
 
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
+       dequeue_xmitframes_to_sleeping_queue(padapter, psta,
+                                            &pstaxmitpriv->vo_q.sta_pending);
        list_del_init(&pstaxmitpriv->vo_q.tx_pending);
 
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
+       dequeue_xmitframes_to_sleeping_queue(padapter, psta,
+                                            &pstaxmitpriv->vi_q.sta_pending);
        list_del_init(&pstaxmitpriv->vi_q.tx_pending);
 
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
+       dequeue_xmitframes_to_sleeping_queue(padapter, psta,
+                                            &pstaxmitpriv->be_q.sta_pending);
        list_del_init(&pstaxmitpriv->be_q.tx_pending);
 
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
+       dequeue_xmitframes_to_sleeping_queue(padapter, psta,
+                                            &pstaxmitpriv->bk_q.sta_pending);
        list_del_init(&pstaxmitpriv->bk_q.tx_pending);
 
        /* for BC/MC Frames */
        pstaxmitpriv = &psta_bmc->sta_xmitpriv;
-       dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
+       dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc,
+                                            &pstaxmitpriv->be_q.sta_pending);
        list_del_init(&pstaxmitpriv->be_q.tx_pending);
 
        spin_unlock_bh(&pxmitpriv->lock);
@@ -1863,7 +1870,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
 
                update_mask = BIT(0);
 
-               if (psta->state&WIFI_SLEEP_STATE)
+               if (psta->state & WIFI_SLEEP_STATE)
                        psta->state ^= WIFI_SLEEP_STATE;
 
                if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
@@ -1881,7 +1888,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
        if (!psta_bmc)
                return;
 
-       if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) { /* no any sta in ps mode */
+       if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */
                spin_lock_bh(&psta_bmc->sleep_q.lock);
 
                xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
index 1862c1396c856142c752c12b2a8fcffc623287c9..11e0bb9c67d75f0ce681b0a7861670ddcd47b2a0 100644 (file)
@@ -1,9 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-******************************************************************************/
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ ******************************************************************************/
 
 #include "odm_precomp.h"
 
index 1b8341f409955f2cdb4fad988ebe57c291d9c3ff..486ee4bd474468637e62fef3b457eecd23e8a769 100644 (file)
@@ -98,9 +98,9 @@ static void rtl88e_firmware_selfreset(struct adapter *adapt)
 {
        u8 u1b_tmp;
 
-       u1b_tmp = usb_read8(adapt, REG_SYS_FUNC_EN+1);
-       usb_write8(adapt, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
-       usb_write8(adapt, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2)));
+       u1b_tmp = usb_read8(adapt, REG_SYS_FUNC_EN + 1);
+       usb_write8(adapt, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
+       usb_write8(adapt, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
 }
 
 static int _rtl88e_fw_free_to_go(struct adapter *adapt)
index 464c11710398cfa626d006525d46d05ec75bc1bc..6dbd7d261f1e0eaeb464eb2037fc2698d6839e82 100644 (file)
@@ -418,14 +418,16 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
        } else {
                pRaInfo->LowestRate = 0;
        }
-               if (pRaInfo->HighestRate > 0x13)
-                       pRaInfo->PTModeSS = 3;
-               else if (pRaInfo->HighestRate > 0x0b)
-                       pRaInfo->PTModeSS = 2;
-               else if (pRaInfo->HighestRate > 0x0b)
-                       pRaInfo->PTModeSS = 1;
-               else
-                       pRaInfo->PTModeSS = 0;
+
+       if (pRaInfo->HighestRate > 0x13)
+               pRaInfo->PTModeSS = 3;
+       else if (pRaInfo->HighestRate > 0x0b)
+               pRaInfo->PTModeSS = 2;
+       else if (pRaInfo->HighestRate > 0x0b)
+               pRaInfo->PTModeSS = 1;
+       else
+               pRaInfo->PTModeSS = 0;
+
        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
                     ("ODM_ARFBRefresh_8188E(): PTModeSS =%d\n", pRaInfo->PTModeSS));
 
index 7202e1767fc076c15d975e87d55c691c7e9398c2..ff481fbd074cb7b5873f08c044a320ac3e674caa 100644 (file)
@@ -45,9 +45,8 @@ void dump_chip_info(struct HAL_VERSION        chip_vers)
 #define        CHAN_PLAN_HW    0x80
 
 /* return the final channel plan decision */
-u8 hal_com_get_channel_plan(struct adapter *padapter, u8 hw_channel_plan,
-                           u8 sw_channel_plan, u8 def_channel_plan,
-                           bool load_fail)
+u8 hal_com_get_channel_plan(u8 hw_channel_plan, u8 sw_channel_plan,
+                           u8 def_channel_plan, bool load_fail)
 {
        u8 sw_cfg;
        u8 chnlplan;
@@ -119,7 +118,7 @@ u8 MRateToHwRate(u8 rate)
        return ret;
 }
 
-void HalSetBrateCfg(struct adapter *adapt, u8 *brates, u16 *rate_cfg)
+void hal_set_brate_cfg(u8 *brates, u16 *rate_cfg)
 {
        u8 i, is_brate, brate;
 
@@ -263,10 +262,10 @@ static void three_out_pipe(struct adapter *adapter, bool wifi_cfg)
        }
 }
 
-bool Hal_MappingOutPipe(struct adapter *adapter, u8 numoutpipe)
+bool hal_mapping_out_pipe(struct adapter *adapter, u8 numoutpipe)
 {
        struct registry_priv *pregistrypriv = &adapter->registrypriv;
-       bool  wifi_cfg = (pregistrypriv->wifi_spec) ? true : false;
+       bool wifi_cfg = (pregistrypriv->wifi_spec) ? true : false;
        bool result = true;
 
        switch (numoutpipe) {
index 9d567838a43a52f78ee7fbe9da805ce57ab7af76..4ab490c1c13b5432aac5869c9ddae15d9893e24f 100644 (file)
@@ -418,7 +418,7 @@ void odm_DIG(struct odm_dm_struct *pDM_Odm)
 
        /* 1 Modify DIG lower bound, deal with abnormally large false alarm */
        if (pFalseAlmCnt->Cnt_all > 10000) {
-               ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("dm_DIG(): Abnornally false alarm case.\n"));
+               ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("dm_DIG(): Abnormally false alarm case.\n"));
 
                if (pDM_DigTable->LargeFAHit != 3)
                        pDM_DigTable->LargeFAHit++;
@@ -768,22 +768,7 @@ u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, u32 ra_mask, u
        return rate_bitmap;
 }
 
-/*-----------------------------------------------------------------------------
- * Function:   odm_RefreshRateAdaptiveMask()
- *
- * Overview:   Update rate table mask according to rssi
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     05/27/2009      hpfan   Create Version 0.
- *
- *---------------------------------------------------------------------------*/
+/* Update rate table mask according to rssi */
 void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm)
 {
        if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK))
@@ -1074,7 +1059,7 @@ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm)
        struct mlme_ext_priv    *pmlmeext = &(Adapter->mlmeextpriv);
        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
 
-       if ((pregpriv->wifi_spec == 1))/*  (pmlmeinfo->HT_enable == 0)) */
+       if (pregpriv->wifi_spec == 1) /*  (pmlmeinfo->HT_enable == 0)) */
                goto dm_CheckEdcaTurbo_EXIT;
 
        if (pmlmeinfo->assoc_AP_vendor >=  HT_IOT_PEER_MAX)
diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c
deleted file mode 100644 (file)
index 0464dc4..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- ******************************************************************************/
-
-/*  include files */
-
-#include "odm_precomp.h"
-
-#define READ_AND_CONFIG     READ_AND_CONFIG_MP
-
-#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig##txt##ic(dm_odm))
-#define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC##txt##ic(dm_odm))
-
-static u8 odm_QueryRxPwrPercentage(s8 AntPower)
-{
-       if ((AntPower <= -100) || (AntPower >= 20))
-               return  0;
-       else if (AntPower >= 0)
-               return  100;
-       else
-               return 100+AntPower;
-}
-
-/*  2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. */
-/*  IF other SW team do not support the feature, remove this section.?? */
-static s32 odm_SignalScaleMapping_92CSeries(struct odm_dm_struct *dm_odm, s32 CurrSig)
-{
-       s32 RetSig = 0;
-
-       if (CurrSig >= 51 && CurrSig <= 100)
-               RetSig = 100;
-       else if (CurrSig >= 41 && CurrSig <= 50)
-               RetSig = 80 + ((CurrSig - 40)*2);
-       else if (CurrSig >= 31 && CurrSig <= 40)
-               RetSig = 66 + (CurrSig - 30);
-       else if (CurrSig >= 21 && CurrSig <= 30)
-               RetSig = 54 + (CurrSig - 20);
-       else if (CurrSig >= 10 && CurrSig <= 20)
-               RetSig = 42 + (((CurrSig - 10) * 2) / 3);
-       else if (CurrSig >= 5 && CurrSig <= 9)
-               RetSig = 22 + (((CurrSig - 5) * 3) / 2);
-       else if (CurrSig >= 1 && CurrSig <= 4)
-               RetSig = 6 + (((CurrSig - 1) * 3) / 2);
-       else
-               RetSig = CurrSig;
-       return RetSig;
-}
-
-static s32 odm_SignalScaleMapping(struct odm_dm_struct *dm_odm, s32 CurrSig)
-{
-       return odm_SignalScaleMapping_92CSeries(dm_odm, CurrSig);
-}
-
-static u8 odm_EVMdbToPercentage(s8 Value)
-{
-       /*  -33dB~0dB to 0%~99% */
-       s8 ret_val;
-
-       ret_val = Value;
-
-       if (ret_val >= 0)
-               ret_val = 0;
-       if (ret_val <= -33)
-               ret_val = -33;
-
-       ret_val = 0 - ret_val;
-       ret_val *= 3;
-
-       if (ret_val == 99)
-               ret_val = 100;
-       return ret_val;
-}
-
-static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm,
-                       struct odm_phy_status_info *pPhyInfo,
-                       u8 *pPhyStatus,
-                       struct odm_per_pkt_info *pPktinfo)
-{
-       struct sw_ant_switch *pDM_SWAT_Table = &dm_odm->DM_SWAT_Table;
-       u8 i, Max_spatial_stream;
-       s8 rx_pwr[4], rx_pwr_all = 0;
-       u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT;
-       u8 RSSI, total_rssi = 0;
-       u8 isCCKrate = 0;
-       u8 rf_rx_num = 0;
-       u8 cck_highpwr = 0;
-       u8 LNA_idx, VGA_idx;
-
-       struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus;
-
-       isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false;
-
-       pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1;
-       pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
-
-       if (isCCKrate) {
-               u8 cck_agc_rpt;
-
-               dm_odm->PhyDbgInfo.NumQryPhyStatusCCK++;
-               /*  (1)Hardware does not provide RSSI for CCK */
-               /*  (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */
-
-               cck_highpwr = dm_odm->bCckHighPower;
-
-               cck_agc_rpt =  pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
-
-               /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */
-               /* The RSSI formula should be modified according to the gain table */
-               /* In 88E, cck_highpwr is always set to 1 */
-               LNA_idx = (cck_agc_rpt & 0xE0) >> 5;
-               VGA_idx = cck_agc_rpt & 0x1F;
-               switch (LNA_idx) {
-               case 7:
-                       if (VGA_idx <= 27)
-                               rx_pwr_all = -100 + 2*(27-VGA_idx); /* VGA_idx = 27~2 */
-                       else
-                               rx_pwr_all = -100;
-                       break;
-               case 6:
-                       rx_pwr_all = -48 + 2*(2-VGA_idx); /* VGA_idx = 2~0 */
-                       break;
-               case 5:
-                       rx_pwr_all = -42 + 2*(7-VGA_idx); /* VGA_idx = 7~5 */
-                       break;
-               case 4:
-                       rx_pwr_all = -36 + 2*(7-VGA_idx); /* VGA_idx = 7~4 */
-                       break;
-               case 3:
-                       rx_pwr_all = -24 + 2*(7-VGA_idx); /* VGA_idx = 7~0 */
-                       break;
-               case 2:
-                       if (cck_highpwr)
-                               rx_pwr_all = -12 + 2*(5-VGA_idx); /* VGA_idx = 5~0 */
-                       else
-                               rx_pwr_all = -6 + 2*(5-VGA_idx);
-                       break;
-               case 1:
-                       rx_pwr_all = 8-2*VGA_idx;
-                       break;
-               case 0:
-                       rx_pwr_all = 14-2*VGA_idx;
-                       break;
-               default:
-                       break;
-               }
-               rx_pwr_all += 6;
-               PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all);
-               if (!cck_highpwr) {
-                       if (PWDB_ALL >= 80)
-                               PWDB_ALL = ((PWDB_ALL-80)<<1)+((PWDB_ALL-80)>>1)+80;
-                       else if ((PWDB_ALL <= 78) && (PWDB_ALL >= 20))
-                               PWDB_ALL += 3;
-                       if (PWDB_ALL > 100)
-                               PWDB_ALL = 100;
-               }
-
-               pPhyInfo->RxPWDBAll = PWDB_ALL;
-               pPhyInfo->BTRxRSSIPercentage = PWDB_ALL;
-               pPhyInfo->RecvSignalPower = rx_pwr_all;
-               /*  (3) Get Signal Quality (EVM) */
-               if (pPktinfo->bPacketMatchBSSID) {
-                       u8 SQ, SQ_rpt;
-
-                       if (pPhyInfo->RxPWDBAll > 40 && !dm_odm->bInHctTest) {
-                               SQ = 100;
-                       } else {
-                               SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all;
-
-                               if (SQ_rpt > 64)
-                                       SQ = 0;
-                               else if (SQ_rpt < 20)
-                                       SQ = 100;
-                               else
-                                       SQ = ((64-SQ_rpt) * 100) / 44;
-                       }
-                       pPhyInfo->SignalQuality = SQ;
-                       pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ;
-                       pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
-               }
-       } else { /* is OFDM rate */
-               dm_odm->PhyDbgInfo.NumQryPhyStatusOFDM++;
-
-               /*  (1)Get RSSI for HT rate */
-
-                for (i = RF_PATH_A; i < RF_PATH_MAX; i++) {
-                       /*  2008/01/30 MH we will judge RF RX path now. */
-                       if (dm_odm->RFPathRxEnable & BIT(i))
-                               rf_rx_num++;
-
-                       rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F)*2) - 110;
-
-                       pPhyInfo->RxPwr[i] = rx_pwr[i];
-
-                       /* Translate DBM to percentage. */
-                       RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]);
-                       total_rssi += RSSI;
-
-                       /* Modification for ext-LNA board */
-                       if (dm_odm->BoardType == ODM_BOARD_HIGHPWR) {
-                               if ((pPhyStaRpt->path_agc[i].trsw) == 1)
-                                       RSSI = (RSSI > 94) ? 100 : (RSSI + 6);
-                               else
-                                       RSSI = (RSSI <= 16) ? (RSSI >> 3) : (RSSI - 16);
-
-                               if ((RSSI <= 34) && (RSSI >= 4))
-                                       RSSI -= 4;
-                       }
-
-                       pPhyInfo->RxMIMOSignalStrength[i] = (u8)RSSI;
-
-                       /* Get Rx snr value in DB */
-                       pPhyInfo->RxSNR[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2);
-                       dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2);
-               }
-               /*  (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */
-               rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110;
-
-               PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all);
-               PWDB_ALL_BT = PWDB_ALL;
-
-               pPhyInfo->RxPWDBAll = PWDB_ALL;
-               pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT;
-               pPhyInfo->RxPower = rx_pwr_all;
-               pPhyInfo->RecvSignalPower = rx_pwr_all;
-
-               /*  (3)EVM of HT rate */
-               if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15)
-                       Max_spatial_stream = 2; /* both spatial stream make sense */
-               else
-                       Max_spatial_stream = 1; /* only spatial stream 1 makes sense */
-
-               for (i = 0; i < Max_spatial_stream; i++) {
-                       /*  Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
-                       /*  fill most significant bit to "zero" when doing shifting operation which may change a negative */
-                       /*  value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore. */
-                       EVM = odm_EVMdbToPercentage((pPhyStaRpt->stream_rxevm[i]));     /* dbm */
-
-                       if (pPktinfo->bPacketMatchBSSID) {
-                               if (i == RF_PATH_A) /*  Fill value in RFD, Get the first spatial stream only */
-                                       pPhyInfo->SignalQuality = (u8)(EVM & 0xff);
-                               pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff);
-                       }
-               }
-       }
-       /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
-       /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
-       if (isCCKrate) {
-               pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(dm_odm, PWDB_ALL));/* PWDB_ALL; */
-       } else {
-               if (rf_rx_num != 0)
-                       pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(dm_odm, total_rssi /= rf_rx_num));
-       }
-
-       /* For 92C/92D HW (Hybrid) Antenna Diversity */
-       pDM_SWAT_Table->antsel = pPhyStaRpt->ant_sel;
-       /* For 88E HW Antenna Diversity */
-       dm_odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->ant_sel;
-       dm_odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->ant_sel_b;
-       dm_odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antsel_rx_keep_2;
-}
-
-static void odm_Process_RSSIForDM(struct odm_dm_struct *dm_odm,
-                                 struct odm_phy_status_info *pPhyInfo,
-                                 struct odm_per_pkt_info *pPktinfo)
-{
-       s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK;
-       s32 UndecoratedSmoothedOFDM, RSSI_Ave;
-       u8 isCCKrate = 0;
-       u8 RSSI_max, RSSI_min, i;
-       u32 OFDM_pkt = 0;
-       u32 Weighting = 0;
-       struct sta_info *pEntry;
-       u8 antsel_tr_mux;
-       struct fast_ant_train *pDM_FatTable = &dm_odm->DM_FatTable;
-
-       if (pPktinfo->StationID == 0xFF)
-               return;
-       pEntry = dm_odm->pODM_StaInfo[pPktinfo->StationID];
-       if (!IS_STA_VALID(pEntry))
-               return;
-       if ((!pPktinfo->bPacketMatchBSSID))
-               return;
-
-       isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false;
-
-       /* Smart Antenna Debug Message------------------  */
-
-       if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV) {
-               if (pDM_FatTable->FAT_State == FAT_TRAINING_STATE) {
-                       if (pPktinfo->bPacketToSelf) {
-                               antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2<<2) |
-                                               (pDM_FatTable->antsel_rx_keep_1<<1) |
-                                               pDM_FatTable->antsel_rx_keep_0;
-                               pDM_FatTable->antSumRSSI[antsel_tr_mux] += pPhyInfo->RxPWDBAll;
-                               pDM_FatTable->antRSSIcnt[antsel_tr_mux]++;
-                       }
-               }
-       } else if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) {
-               if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
-                       antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2<<2) |
-                                       (pDM_FatTable->antsel_rx_keep_1<<1) | pDM_FatTable->antsel_rx_keep_0;
-                       rtl88eu_dm_ant_sel_statistics(dm_odm, antsel_tr_mux, pPktinfo->StationID, pPhyInfo->RxPWDBAll);
-               }
-       }
-       /* Smart Antenna Debug Message------------------ */
-
-       UndecoratedSmoothedCCK =  pEntry->rssi_stat.UndecoratedSmoothedCCK;
-       UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM;
-       UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB;
-
-       if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
-               if (!isCCKrate) { /* ofdm rate */
-                       if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) {
-                               RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
-                       } else {
-                               if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) {
-                                       RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
-                                       RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
-                               } else {
-                                       RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
-                                       RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
-                               }
-                               if ((RSSI_max - RSSI_min) < 3)
-                                       RSSI_Ave = RSSI_max;
-                               else if ((RSSI_max - RSSI_min) < 6)
-                                       RSSI_Ave = RSSI_max - 1;
-                               else if ((RSSI_max - RSSI_min) < 10)
-                                       RSSI_Ave = RSSI_max - 2;
-                               else
-                                       RSSI_Ave = RSSI_max - 3;
-                       }
-
-                       /* 1 Process OFDM RSSI */
-                       if (UndecoratedSmoothedOFDM <= 0) {     /*  initialize */
-                               UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll;
-                       } else {
-                               if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) {
-                                       UndecoratedSmoothedOFDM =
-                                                       (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) +
-                                                       (RSSI_Ave)) / (Rx_Smooth_Factor);
-                                       UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1;
-                               } else {
-                                       UndecoratedSmoothedOFDM =
-                                                       (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) +
-                                                       (RSSI_Ave)) / (Rx_Smooth_Factor);
-                               }
-                       }
-
-                       pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap<<1) | BIT(0);
-
-               } else {
-                       RSSI_Ave = pPhyInfo->RxPWDBAll;
-
-                       /* 1 Process CCK RSSI */
-                       if (UndecoratedSmoothedCCK <= 0) {      /*  initialize */
-                               UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll;
-                       } else {
-                               if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) {
-                                       UndecoratedSmoothedCCK =
-                                                       ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor-1)) +
-                                                       pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor;
-                                       UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
-                               } else {
-                                       UndecoratedSmoothedCCK =
-                                                       ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor-1)) +
-                                                       pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor;
-                               }
-                       }
-                       pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1;
-               }
-               /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
-               if (pEntry->rssi_stat.ValidBit >= 64)
-                       pEntry->rssi_stat.ValidBit = 64;
-               else
-                       pEntry->rssi_stat.ValidBit++;
-
-               for (i = 0; i < pEntry->rssi_stat.ValidBit; i++)
-                       OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap>>i) & BIT(0);
-
-               if (pEntry->rssi_stat.ValidBit == 64) {
-                       Weighting = min_t(u32, OFDM_pkt << 4, 64);
-                       UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6;
-               } else {
-                       if (pEntry->rssi_stat.ValidBit != 0)
-                               UndecoratedSmoothedPWDB = (OFDM_pkt * UndecoratedSmoothedOFDM +
-                                                         (pEntry->rssi_stat.ValidBit-OFDM_pkt) *
-                                                         UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit;
-                       else
-                               UndecoratedSmoothedPWDB = 0;
-               }
-               pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
-               pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM;
-               pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
-       }
-}
-
-/*  Endianness before calling this API */
-static void ODM_PhyStatusQuery_92CSeries(struct odm_dm_struct *dm_odm,
-                                        struct odm_phy_status_info *pPhyInfo,
-                                        u8 *pPhyStatus,
-                                        struct odm_per_pkt_info *pPktinfo)
-{
-       odm_RxPhyStatus92CSeries_Parsing(dm_odm, pPhyInfo, pPhyStatus,
-                                        pPktinfo);
-       if (dm_odm->RSSI_test) {
-               ;/*  Select the packets to do RSSI checking for antenna switching. */
-       } else {
-               odm_Process_RSSIForDM(dm_odm, pPhyInfo, pPktinfo);
-       }
-}
-
-void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm,
-                       struct odm_phy_status_info *pPhyInfo,
-                       u8 *pPhyStatus, struct odm_per_pkt_info *pPktinfo)
-{
-       ODM_PhyStatusQuery_92CSeries(dm_odm, pPhyInfo, pPhyStatus, pPktinfo);
-}
diff --git a/drivers/staging/rtl8188eu/hal/odm_hwconfig.c b/drivers/staging/rtl8188eu/hal/odm_hwconfig.c
new file mode 100644 (file)
index 0000000..82d6b2e
--- /dev/null
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ ******************************************************************************/
+
+/*  include files */
+
+#include "odm_precomp.h"
+
+#define READ_AND_CONFIG     READ_AND_CONFIG_MP
+
+#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig##txt##ic(dm_odm))
+#define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC##txt##ic(dm_odm))
+
+static u8 odm_query_rxpwrpercentage(s8 antpower)
+{
+       if ((antpower <= -100) || (antpower >= 20))
+               return 0;
+       else if (antpower >= 0)
+               return 100;
+       else
+               return 100 + antpower;
+}
+
+/*  2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. */
+/*  IF other SW team do not support the feature, remove this section.?? */
+static s32 odm_signal_scale_mapping(struct odm_dm_struct *dm_odm, s32 currsig)
+{
+       s32 retsig = 0;
+
+       if (currsig >= 51 && currsig <= 100)
+               retsig = 100;
+       else if (currsig >= 41 && currsig <= 50)
+               retsig = 80 + ((currsig - 40) * 2);
+       else if (currsig >= 31 && currsig <= 40)
+               retsig = 66 + (currsig - 30);
+       else if (currsig >= 21 && currsig <= 30)
+               retsig = 54 + (currsig - 20);
+       else if (currsig >= 10 && currsig <= 20)
+               retsig = 42 + (((currsig - 10) * 2) / 3);
+       else if (currsig >= 5 && currsig <= 9)
+               retsig = 22 + (((currsig - 5) * 3) / 2);
+       else if (currsig >= 1 && currsig <= 4)
+               retsig = 6 + (((currsig - 1) * 3) / 2);
+       else
+               retsig = currsig;
+
+       return retsig;
+}
+
+static u8 odm_evm_db_to_percentage(s8 value)
+{
+       /*  -33dB~0dB to 0%~99% */
+       s8 ret_val;
+
+       ret_val = value;
+
+       if (ret_val >= 0)
+               ret_val = 0;
+       if (ret_val <= -33)
+               ret_val = -33;
+
+       ret_val = 0 - ret_val;
+       ret_val *= 3;
+
+       if (ret_val == 99)
+               ret_val = 100;
+       return ret_val;
+}
+
+static void odm_RxPhyStatus92CSeries_Parsing(struct odm_dm_struct *dm_odm,
+                       struct odm_phy_status_info *pPhyInfo,
+                       u8 *pPhyStatus,
+                       struct odm_per_pkt_info *pPktinfo)
+{
+       struct sw_ant_switch *pDM_SWAT_Table = &dm_odm->DM_SWAT_Table;
+       u8 i, Max_spatial_stream;
+       s8 rx_pwr[4], rx_pwr_all = 0;
+       u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT;
+       u8 RSSI, total_rssi = 0;
+       u8 isCCKrate = 0;
+       u8 rf_rx_num = 0;
+       u8 cck_highpwr = 0;
+       u8 LNA_idx, VGA_idx;
+
+       struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus;
+
+       isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false;
+
+       pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1;
+       pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
+
+       if (isCCKrate) {
+               u8 cck_agc_rpt;
+
+               dm_odm->PhyDbgInfo.NumQryPhyStatusCCK++;
+               /*  (1)Hardware does not provide RSSI for CCK */
+               /*  (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */
+
+               cck_highpwr = dm_odm->bCckHighPower;
+
+               cck_agc_rpt =  pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
+
+               /* 2011.11.28 LukeLee: 88E use different LNA & VGA gain table */
+               /* The RSSI formula should be modified according to the gain table */
+               /* In 88E, cck_highpwr is always set to 1 */
+               LNA_idx = (cck_agc_rpt & 0xE0) >> 5;
+               VGA_idx = cck_agc_rpt & 0x1F;
+               switch (LNA_idx) {
+               case 7:
+                       if (VGA_idx <= 27)
+                               rx_pwr_all = -100 + 2 * (27-VGA_idx); /* VGA_idx = 27~2 */
+                       else
+                               rx_pwr_all = -100;
+                       break;
+               case 6:
+                       rx_pwr_all = -48 + 2 * (2-VGA_idx); /* VGA_idx = 2~0 */
+                       break;
+               case 5:
+                       rx_pwr_all = -42 + 2 * (7-VGA_idx); /* VGA_idx = 7~5 */
+                       break;
+               case 4:
+                       rx_pwr_all = -36 + 2 * (7-VGA_idx); /* VGA_idx = 7~4 */
+                       break;
+               case 3:
+                       rx_pwr_all = -24 + 2 * (7-VGA_idx); /* VGA_idx = 7~0 */
+                       break;
+               case 2:
+                       if (cck_highpwr)
+                               rx_pwr_all = -12 + 2 * (5-VGA_idx); /* VGA_idx = 5~0 */
+                       else
+                               rx_pwr_all = -6 + 2 * (5-VGA_idx);
+                       break;
+               case 1:
+                       rx_pwr_all = 8-2 * VGA_idx;
+                       break;
+               case 0:
+                       rx_pwr_all = 14-2 * VGA_idx;
+                       break;
+               default:
+                       break;
+               }
+               rx_pwr_all += 6;
+               PWDB_ALL = odm_query_rxpwrpercentage(rx_pwr_all);
+               if (!cck_highpwr) {
+                       if (PWDB_ALL >= 80)
+                               PWDB_ALL = ((PWDB_ALL-80)<<1) + ((PWDB_ALL-80)>>1) + 80;
+                       else if ((PWDB_ALL <= 78) && (PWDB_ALL >= 20))
+                               PWDB_ALL += 3;
+                       if (PWDB_ALL > 100)
+                               PWDB_ALL = 100;
+               }
+
+               pPhyInfo->RxPWDBAll = PWDB_ALL;
+               pPhyInfo->BTRxRSSIPercentage = PWDB_ALL;
+               pPhyInfo->RecvSignalPower = rx_pwr_all;
+               /*  (3) Get Signal Quality (EVM) */
+               if (pPktinfo->bPacketMatchBSSID) {
+                       u8 SQ, SQ_rpt;
+
+                       if (pPhyInfo->RxPWDBAll > 40 && !dm_odm->bInHctTest) {
+                               SQ = 100;
+                       } else {
+                               SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all;
+
+                               if (SQ_rpt > 64)
+                                       SQ = 0;
+                               else if (SQ_rpt < 20)
+                                       SQ = 100;
+                               else
+                                       SQ = ((64-SQ_rpt) * 100) / 44;
+                       }
+                       pPhyInfo->SignalQuality = SQ;
+                       pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ;
+                       pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
+               }
+       } else { /* is OFDM rate */
+               dm_odm->PhyDbgInfo.NumQryPhyStatusOFDM++;
+
+               /*  (1)Get RSSI for HT rate */
+
+               for (i = RF_PATH_A; i < RF_PATH_MAX; i++) {
+                       /*  2008/01/30 MH we will judge RF RX path now. */
+                       if (dm_odm->RFPathRxEnable & BIT(i))
+                               rf_rx_num++;
+
+                       rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F) * 2) - 110;
+
+                       pPhyInfo->RxPwr[i] = rx_pwr[i];
+
+                       /* Translate DBM to percentage. */
+                       RSSI = odm_query_rxpwrpercentage(rx_pwr[i]);
+                       total_rssi += RSSI;
+
+                       /* Modification for ext-LNA board */
+                       if (dm_odm->BoardType == ODM_BOARD_HIGHPWR) {
+                               if ((pPhyStaRpt->path_agc[i].trsw) == 1)
+                                       RSSI = (RSSI > 94) ? 100 : (RSSI + 6);
+                               else
+                                       RSSI = (RSSI <= 16) ? (RSSI >> 3) : (RSSI - 16);
+
+                               if ((RSSI <= 34) && (RSSI >= 4))
+                                       RSSI -= 4;
+                       }
+
+                       pPhyInfo->RxMIMOSignalStrength[i] = (u8)RSSI;
+
+                       /* Get Rx snr value in DB */
+                       pPhyInfo->RxSNR[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2);
+                       dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2);
+               }
+               /*  (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */
+               rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110;
+
+               PWDB_ALL = odm_query_rxpwrpercentage(rx_pwr_all);
+               PWDB_ALL_BT = PWDB_ALL;
+
+               pPhyInfo->RxPWDBAll = PWDB_ALL;
+               pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT;
+               pPhyInfo->RxPower = rx_pwr_all;
+               pPhyInfo->RecvSignalPower = rx_pwr_all;
+
+               /*  (3)EVM of HT rate */
+               if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15)
+                       Max_spatial_stream = 2; /* both spatial stream make sense */
+               else
+                       Max_spatial_stream = 1; /* only spatial stream 1 makes sense */
+
+               for (i = 0; i < Max_spatial_stream; i++) {
+                       /*  Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
+                       /*  fill most significant bit to "zero" when doing shifting operation which may change a negative */
+                       /*  value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore. */
+                       EVM = odm_evm_db_to_percentage((pPhyStaRpt->stream_rxevm[i]));  /* dbm */
+
+                       if (pPktinfo->bPacketMatchBSSID) {
+                               if (i == RF_PATH_A) /*  Fill value in RFD, Get the first spatial stream only */
+                                       pPhyInfo->SignalQuality = (u8)(EVM & 0xff);
+                               pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff);
+                       }
+               }
+       }
+       /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
+       /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
+       if (isCCKrate) {
+               pPhyInfo->SignalStrength = (u8)(odm_signal_scale_mapping(dm_odm, PWDB_ALL));/* PWDB_ALL; */
+       } else {
+               if (rf_rx_num != 0)
+                       pPhyInfo->SignalStrength = (u8)(odm_signal_scale_mapping(dm_odm, total_rssi /= rf_rx_num));
+       }
+
+       /* For 92C/92D HW (Hybrid) Antenna Diversity */
+       pDM_SWAT_Table->antsel = pPhyStaRpt->ant_sel;
+       /* For 88E HW Antenna Diversity */
+       dm_odm->DM_FatTable.antsel_rx_keep_0 = pPhyStaRpt->ant_sel;
+       dm_odm->DM_FatTable.antsel_rx_keep_1 = pPhyStaRpt->ant_sel_b;
+       dm_odm->DM_FatTable.antsel_rx_keep_2 = pPhyStaRpt->antsel_rx_keep_2;
+}
+
+static void odm_Process_RSSIForDM(struct odm_dm_struct *dm_odm,
+                                 struct odm_phy_status_info *pPhyInfo,
+                                 struct odm_per_pkt_info *pPktinfo)
+{
+       s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK;
+       s32 UndecoratedSmoothedOFDM, RSSI_Ave;
+       u8 isCCKrate = 0;
+       u8 RSSI_max, RSSI_min, i;
+       u32 OFDM_pkt = 0;
+       u32 Weighting = 0;
+       struct sta_info *pEntry;
+       u8 antsel_tr_mux;
+       struct fast_ant_train *pDM_FatTable = &dm_odm->DM_FatTable;
+
+       if (pPktinfo->StationID == 0xFF)
+               return;
+       pEntry = dm_odm->pODM_StaInfo[pPktinfo->StationID];
+       if (!IS_STA_VALID(pEntry))
+               return;
+       if ((!pPktinfo->bPacketMatchBSSID))
+               return;
+
+       isCCKrate = ((pPktinfo->Rate >= DESC92C_RATE1M) && (pPktinfo->Rate <= DESC92C_RATE11M)) ? true : false;
+
+       /* Smart Antenna Debug Message------------------  */
+
+       if (dm_odm->AntDivType == CG_TRX_SMART_ANTDIV) {
+               if (pDM_FatTable->FAT_State == FAT_TRAINING_STATE) {
+                       if (pPktinfo->bPacketToSelf) {
+                               antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2<<2) |
+                                               (pDM_FatTable->antsel_rx_keep_1<<1) |
+                                               pDM_FatTable->antsel_rx_keep_0;
+                               pDM_FatTable->antSumRSSI[antsel_tr_mux] += pPhyInfo->RxPWDBAll;
+                               pDM_FatTable->antRSSIcnt[antsel_tr_mux]++;
+                       }
+               }
+       } else if ((dm_odm->AntDivType == CG_TRX_HW_ANTDIV) || (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV)) {
+               if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
+                       antsel_tr_mux = (pDM_FatTable->antsel_rx_keep_2<<2) |
+                                       (pDM_FatTable->antsel_rx_keep_1<<1) | pDM_FatTable->antsel_rx_keep_0;
+                       rtl88eu_dm_ant_sel_statistics(dm_odm, antsel_tr_mux, pPktinfo->StationID, pPhyInfo->RxPWDBAll);
+               }
+       }
+       /* Smart Antenna Debug Message------------------ */
+
+       UndecoratedSmoothedCCK =  pEntry->rssi_stat.UndecoratedSmoothedCCK;
+       UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM;
+       UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB;
+
+       if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
+               if (!isCCKrate) { /* ofdm rate */
+                       if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) {
+                               RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
+                       } else {
+                               if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) {
+                                       RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
+                                       RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
+                               } else {
+                                       RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
+                                       RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
+                               }
+                               if ((RSSI_max - RSSI_min) < 3)
+                                       RSSI_Ave = RSSI_max;
+                               else if ((RSSI_max - RSSI_min) < 6)
+                                       RSSI_Ave = RSSI_max - 1;
+                               else if ((RSSI_max - RSSI_min) < 10)
+                                       RSSI_Ave = RSSI_max - 2;
+                               else
+                                       RSSI_Ave = RSSI_max - 3;
+                       }
+
+                       /* 1 Process OFDM RSSI */
+                       if (UndecoratedSmoothedOFDM <= 0) {     /*  initialize */
+                               UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll;
+                       } else {
+                               if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) {
+                                       UndecoratedSmoothedOFDM =
+                                                       (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor-1)) +
+                                                       (RSSI_Ave)) / (Rx_Smooth_Factor);
+                                       UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1;
+                               } else {
+                                       UndecoratedSmoothedOFDM =
+                                                       (((UndecoratedSmoothedOFDM) * (Rx_Smooth_Factor-1)) +
+                                                       (RSSI_Ave)) / (Rx_Smooth_Factor);
+                               }
+                       }
+
+                       pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap<<1) | BIT(0);
+
+               } else {
+                       RSSI_Ave = pPhyInfo->RxPWDBAll;
+
+                       /* 1 Process CCK RSSI */
+                       if (UndecoratedSmoothedCCK <= 0) {      /*  initialize */
+                               UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll;
+                       } else {
+                               if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) {
+                                       UndecoratedSmoothedCCK =
+                                                       ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor-1)) +
+                                                       pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor;
+                                       UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
+                               } else {
+                                       UndecoratedSmoothedCCK =
+                                                       ((UndecoratedSmoothedCCK * (Rx_Smooth_Factor-1)) +
+                                                       pPhyInfo->RxPWDBAll) / Rx_Smooth_Factor;
+                               }
+                       }
+                       pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1;
+               }
+               /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
+               if (pEntry->rssi_stat.ValidBit >= 64)
+                       pEntry->rssi_stat.ValidBit = 64;
+               else
+                       pEntry->rssi_stat.ValidBit++;
+
+               for (i = 0; i < pEntry->rssi_stat.ValidBit; i++)
+                       OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap>>i) & BIT(0);
+
+               if (pEntry->rssi_stat.ValidBit == 64) {
+                       Weighting = min_t(u32, OFDM_pkt << 4, 64);
+                       UndecoratedSmoothedPWDB = (Weighting * UndecoratedSmoothedOFDM + (64-Weighting) * UndecoratedSmoothedCCK)>>6;
+               } else {
+                       if (pEntry->rssi_stat.ValidBit != 0)
+                               UndecoratedSmoothedPWDB = (OFDM_pkt * UndecoratedSmoothedOFDM +
+                                                         (pEntry->rssi_stat.ValidBit-OFDM_pkt) *
+                                                         UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit;
+                       else
+                               UndecoratedSmoothedPWDB = 0;
+               }
+               pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
+               pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM;
+               pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
+       }
+}
+
+/*  Endianness before calling this API */
+static void ODM_PhyStatusQuery_92CSeries(struct odm_dm_struct *dm_odm,
+                                        struct odm_phy_status_info *pPhyInfo,
+                                        u8 *pPhyStatus,
+                                        struct odm_per_pkt_info *pPktinfo)
+{
+       odm_RxPhyStatus92CSeries_Parsing(dm_odm, pPhyInfo, pPhyStatus,
+                                        pPktinfo);
+       if (dm_odm->RSSI_test) {
+               ;/*  Select the packets to do RSSI checking for antenna switching. */
+       } else {
+               odm_Process_RSSIForDM(dm_odm, pPhyInfo, pPktinfo);
+       }
+}
+
+void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm,
+                       struct odm_phy_status_info *pPhyInfo,
+                       u8 *pPhyStatus, struct odm_per_pkt_info *pPktinfo)
+{
+       ODM_PhyStatusQuery_92CSeries(dm_odm, pPhyInfo, pPhyStatus, pPktinfo);
+}
index d5001920f77c411a6d54bae22f60a1433ac2a462..251bd8aba3b122fecad9cc6ed8d34b0c01f64ce0 100644 (file)
@@ -13,7 +13,7 @@ static void dm_rx_hw_antena_div_init(struct odm_dm_struct *dm_odm)
        struct adapter *adapter = dm_odm->Adapter;
        u32 value32;
 
-       if (*(dm_odm->mp_mode) == 1) {
+       if (*dm_odm->mp_mode == 1) {
                dm_odm->AntDivType = CGCS_RX_SW_ANTDIV;
                phy_set_bb_reg(adapter, ODM_REG_IGI_A_11N, BIT(7), 0);
                phy_set_bb_reg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(31), 1);
@@ -23,7 +23,7 @@ static void dm_rx_hw_antena_div_init(struct odm_dm_struct *dm_odm)
        /* MAC Setting */
        value32 = phy_query_bb_reg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord);
        phy_set_bb_reg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord,
-                      value32|(BIT(23) | BIT(25)));
+                      value32 | (BIT(23) | BIT(25)));
        /* Pin Settings */
        phy_set_bb_reg(adapter, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
        phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
@@ -44,7 +44,7 @@ static void dm_trx_hw_antenna_div_init(struct odm_dm_struct *dm_odm)
        struct adapter *adapter = dm_odm->Adapter;
        u32     value32;
 
-       if (*(dm_odm->mp_mode) == 1) {
+       if (*dm_odm->mp_mode == 1) {
                dm_odm->AntDivType = CGCS_RX_SW_ANTDIV;
                phy_set_bb_reg(adapter, ODM_REG_IGI_A_11N, BIT(7), 0);
                phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N,
@@ -55,7 +55,7 @@ static void dm_trx_hw_antenna_div_init(struct odm_dm_struct *dm_odm)
        /* MAC Setting */
        value32 = phy_query_bb_reg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord);
        phy_set_bb_reg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord,
-                      value32|(BIT(23) | BIT(25)));
+                      value32 | (BIT(23) | BIT(25)));
        /* Pin Settings */
        phy_set_bb_reg(adapter, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
        phy_set_bb_reg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
@@ -88,11 +88,9 @@ static void dm_fast_training_init(struct odm_dm_struct *dm_odm)
        struct adapter *adapter = dm_odm->Adapter;
        u32 value32, i;
        struct fast_ant_train *dm_fat_tbl = &dm_odm->DM_FatTable;
-       u32 AntCombination = 2;
 
-       if (*(dm_odm->mp_mode) == 1) {
+       if (*dm_odm->mp_mode == 1)
                return;
-       }
 
        for (i = 0; i < 6; i++) {
                dm_fat_tbl->Bssid[i] = 0;
@@ -105,9 +103,11 @@ static void dm_fast_training_init(struct odm_dm_struct *dm_odm)
 
        /* MAC Setting */
        value32 = phy_query_bb_reg(adapter, 0x4c, bMaskDWord);
-       phy_set_bb_reg(adapter, 0x4c, bMaskDWord, value32|(BIT(23) | BIT(25)));
+       phy_set_bb_reg(adapter, 0x4c, bMaskDWord,
+                      value32 | (BIT(23) | BIT(25)));
        value32 = phy_query_bb_reg(adapter,  0x7B4, bMaskDWord);
-       phy_set_bb_reg(adapter, 0x7b4, bMaskDWord, value32|(BIT(16) | BIT(17)));
+       phy_set_bb_reg(adapter, 0x7b4, bMaskDWord,
+                      value32 | (BIT(16) | BIT(17)));
 
        /* Match MAC ADDR */
        phy_set_bb_reg(adapter, 0x7b4, 0xFFFF, 0);
@@ -120,35 +120,12 @@ static void dm_fast_training_init(struct odm_dm_struct *dm_odm)
        phy_set_bb_reg(adapter, 0xca4, bMaskDWord, 0x000000a0);
 
        /* antenna mapping table */
-       if (AntCombination == 2) {
-               if (!dm_odm->bIsMPChip) { /* testchip */
-                       phy_set_bb_reg(adapter, 0x858, BIT(10) | BIT(9) | BIT(8), 1);
-                       phy_set_bb_reg(adapter, 0x858, BIT(13) | BIT(12) | BIT(11), 2);
-               } else { /* MPchip */
-                       phy_set_bb_reg(adapter, 0x914, bMaskByte0, 1);
-                       phy_set_bb_reg(adapter, 0x914, bMaskByte1, 2);
-               }
-       } else if (AntCombination == 7) {
-               if (!dm_odm->bIsMPChip) { /* testchip */
-                       phy_set_bb_reg(adapter, 0x858, BIT(10) | BIT(9) | BIT(8), 0);
-                       phy_set_bb_reg(adapter, 0x858, BIT(13) | BIT(12) | BIT(11), 1);
-                       phy_set_bb_reg(adapter, 0x878, BIT(16), 0);
-                       phy_set_bb_reg(adapter, 0x858, BIT(15) | BIT(14), 2);
-                       phy_set_bb_reg(adapter, 0x878, BIT(19) | BIT(18) | BIT(17), 3);
-                       phy_set_bb_reg(adapter, 0x878, BIT(22) | BIT(21) | BIT(20), 4);
-                       phy_set_bb_reg(adapter, 0x878, BIT(25) | BIT(24) | BIT(23), 5);
-                       phy_set_bb_reg(adapter, 0x878, BIT(28) | BIT(27) | BIT(26), 6);
-                       phy_set_bb_reg(adapter, 0x878, BIT(31) | BIT(30) | BIT(29), 7);
-               } else { /* MPchip */
-                       phy_set_bb_reg(adapter, 0x914, bMaskByte0, 0);
-                       phy_set_bb_reg(adapter, 0x914, bMaskByte1, 1);
-                       phy_set_bb_reg(adapter, 0x914, bMaskByte2, 2);
-                       phy_set_bb_reg(adapter, 0x914, bMaskByte3, 3);
-                       phy_set_bb_reg(adapter, 0x918, bMaskByte0, 4);
-                       phy_set_bb_reg(adapter, 0x918, bMaskByte1, 5);
-                       phy_set_bb_reg(adapter, 0x918, bMaskByte2, 6);
-                       phy_set_bb_reg(adapter, 0x918, bMaskByte3, 7);
-               }
+       if (!dm_odm->bIsMPChip) { /* testchip */
+               phy_set_bb_reg(adapter, 0x858, BIT(10) | BIT(9) | BIT(8), 1);
+               phy_set_bb_reg(adapter, 0x858, BIT(13) | BIT(12) | BIT(11), 2);
+       } else { /* MPchip */
+               phy_set_bb_reg(adapter, 0x914, bMaskByte0, 1);
+               phy_set_bb_reg(adapter, 0x914, bMaskByte1, 2);
        }
 
        /* Default Ant Setting when no fast training */
@@ -157,7 +134,7 @@ static void dm_fast_training_init(struct odm_dm_struct *dm_odm)
        phy_set_bb_reg(adapter, 0x864, BIT(8) | BIT(7) | BIT(6), 1);
 
        /* Enter Traing state */
-       phy_set_bb_reg(adapter, 0x864, BIT(2) | BIT(1) | BIT(0), (AntCombination-1));
+       phy_set_bb_reg(adapter, 0x864, BIT(2) | BIT(1) | BIT(0), 1);
        phy_set_bb_reg(adapter, 0xc50, BIT(7), 1);
 }
 
@@ -219,8 +196,8 @@ static void update_tx_ant_88eu(struct odm_dm_struct *dm_odm, u8 ant, u32 mac_id)
        else
                target_ant = AUX_ANT_CG_TRX;
        dm_fat_tbl->antsel_a[mac_id] = target_ant & BIT(0);
-       dm_fat_tbl->antsel_b[mac_id] = (target_ant & BIT(1))>>1;
-       dm_fat_tbl->antsel_c[mac_id] = (target_ant & BIT(2))>>2;
+       dm_fat_tbl->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;
+       dm_fat_tbl->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;
 }
 
 void rtl88eu_dm_set_tx_ant_by_tx_info(struct odm_dm_struct *dm_odm,
@@ -273,11 +250,13 @@ static void rtl88eu_dm_hw_ant_div(struct odm_dm_struct *dm_odm)
        for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
                entry = dm_odm->pODM_StaInfo[i];
                if (IS_STA_VALID(entry)) {
-                       /* 2 Caculate RSSI per Antenna */
+                       /* 2 Calculate RSSI per Antenna */
                        main_rssi = (dm_fat_tbl->MainAnt_Cnt[i] != 0) ?
-                                    (dm_fat_tbl->MainAnt_Sum[i]/dm_fat_tbl->MainAnt_Cnt[i]) : 0;
+                                    (dm_fat_tbl->MainAnt_Sum[i] /
+                                     dm_fat_tbl->MainAnt_Cnt[i]) : 0;
                        aux_rssi = (dm_fat_tbl->AuxAnt_Cnt[i] != 0) ?
-                                   (dm_fat_tbl->AuxAnt_Sum[i]/dm_fat_tbl->AuxAnt_Cnt[i]) : 0;
+                                   (dm_fat_tbl->AuxAnt_Sum[i] /
+                                    dm_fat_tbl->AuxAnt_Cnt[i]) : 0;
                        target_ant = (main_rssi >= aux_rssi) ? MAIN_ANT : AUX_ANT;
                        /* 2 Select max_rssi for DIG */
                        local_max_rssi = max(main_rssi, aux_rssi);
index 3c7cf8720df810e8e6787a30ea3e57db2153d156..482d48e003b7c6492ce6c9b7c31dabeed941138b 100644 (file)
@@ -298,25 +298,6 @@ void rtw_hal_set_chan(struct adapter *adapt, u8 channel)
 
 #define ODM_TXPWRTRACK_MAX_IDX_88E  6
 
-static u8 get_right_chnl_for_iqk(u8 chnl)
-{
-       u8 place;
-       u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
-               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
-               100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
-               124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153,
-               155, 157, 159, 161, 163, 165
-       };
-
-       if (chnl > 14) {
-               for (place = 0; place < sizeof(channel_all); place++) {
-                       if (channel_all[place] == chnl)
-                               return ++place;
-               }
-       }
-       return 0;
-}
-
 void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type,
                                     u8 *direction, u32 *out_write_val)
 {
@@ -1215,7 +1196,7 @@ void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
 {
        struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
        s32 result[4][8];
-       u8 i, final, chn_index;
+       u8 i, final;
        bool pathaok, pathbok;
        s32 reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4;
        bool is12simular, is13simular, is23simular;
@@ -1324,12 +1305,10 @@ void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
                                       (reg_ec4 == 0));
        }
 
-       chn_index = get_right_chnl_for_iqk(adapt->HalData->CurrentChannel);
-
        if (final < 4) {
                for (i = 0; i < IQK_Matrix_REG_NUM; i++)
-                       dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
-               dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
+                       dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].Value[0][i] = result[final][i];
+               dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[0].bIQKDone = true;
        }
 
        save_adda_registers(adapt, iqk_bb_reg_92c,
index 4aa1dec0b5e4e2b8c2654259d2b6ee2f6e3cbecf..f7890a8f467323f9ab48cf8448cc373abf7f8971 100644 (file)
@@ -8,9 +8,8 @@
 #include "pwrseq.h"
 #include <rtl8188e_hal.h>
 
-/*
-    drivers should parse below arrays and do the corresponding actions
-*/
+/* drivers should parse below arrays and do the corresponding actions */
+
 /* 3 Power on  Array */
 struct wl_pwr_cfg rtl8188E_power_on_flow[RTL8188E_TRANS_CARDEMU_TO_ACT_STEPS +
                                         RTL8188E_TRANS_END_STEPS] = {
index 0700d8bd448d79a47612e2684feffe2b0214f710..02aeb12c98701cde77a35c5fde9befd13e0fc93a 100644 (file)
@@ -177,7 +177,7 @@ static void rtl8188e_config_rf_reg(struct adapter *adapt,
        u32 content = 0x1000; /*RF Content: radio_a_txt*/
        u32 maskforphyset = content & 0xE000;
 
-       rtl_rfreg_delay(adapt, RF90_PATH_A, addr | maskforphyset,
+       rtl_rfreg_delay(adapt, RF_PATH_A, addr | maskforphyset,
                        RFREG_OFFSET_MASK,
                        data);
 }
index 607170775fa54f15447673b430e4bbf20167b9b9..31e80d693f32236548218d8a8ef4cf4986d64414 100644 (file)
@@ -240,8 +240,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
        return status;
 }
 
-void
-Hal_InitPGData88E(struct adapter *padapter)
+void Hal_InitPGData88E(struct adapter *padapter)
 {
        struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
 
@@ -258,11 +257,7 @@ Hal_InitPGData88E(struct adapter *padapter)
        }
 }
 
-void
-Hal_EfuseParseIDCode88E(
-               struct adapter *padapter,
-               u8 *hwinfo
-       )
+void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo)
 {
        struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
        u16                     EEPROMId;
@@ -378,58 +373,20 @@ static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G,
        }
 }
 
-static u8 Hal_GetChnlGroup88E(u8 chnl, u8 *pGroup)
+static void Hal_GetChnlGroup88E(u8 chnl, u8 *group)
 {
-       u8 bIn24G = true;
-
-       if (chnl <= 14) {
-               bIn24G = true;
-
-               if (chnl < 3)                   /*  Channel 1-2 */
-                       *pGroup = 0;
-               else if (chnl < 6)              /*  Channel 3-5 */
-                       *pGroup = 1;
-               else     if (chnl < 9)          /*  Channel 6-8 */
-                       *pGroup = 2;
-               else if (chnl < 12)             /*  Channel 9-11 */
-                       *pGroup = 3;
-               else if (chnl < 14)             /*  Channel 12-13 */
-                       *pGroup = 4;
-               else if (chnl == 14)            /*  Channel 14 */
-                       *pGroup = 5;
-       } else {
-               /* probably, this branch is suitable only for 5 GHz */
-
-               bIn24G = false;
-
-               if (chnl <= 40)
-                       *pGroup = 0;
-               else if (chnl <= 48)
-                       *pGroup = 1;
-               else     if (chnl <= 56)
-                       *pGroup = 2;
-               else if (chnl <= 64)
-                       *pGroup = 3;
-               else if (chnl <= 104)
-                       *pGroup = 4;
-               else if (chnl <= 112)
-                       *pGroup = 5;
-               else if (chnl <= 120)
-                       *pGroup = 5;
-               else if (chnl <= 128)
-                       *pGroup = 6;
-               else if (chnl <= 136)
-                       *pGroup = 7;
-               else if (chnl <= 144)
-                       *pGroup = 8;
-               else if (chnl <= 153)
-                       *pGroup = 9;
-               else if (chnl <= 161)
-                       *pGroup = 10;
-               else if (chnl <= 177)
-                       *pGroup = 11;
-       }
-       return bIn24G;
+       if (chnl < 3)                   /*  Channel 1-2 */
+               *group = 0;
+       else if (chnl < 6)              /*  Channel 3-5 */
+               *group = 1;
+       else if (chnl < 9)              /*  Channel 6-8 */
+               *group = 2;
+       else if (chnl < 12)             /*  Channel 9-11 */
+               *group = 3;
+       else if (chnl < 14)             /*  Channel 12-13 */
+               *group = 4;
+       else if (chnl == 14)            /*  Channel 14 */
+               *group = 5;
 }
 
 void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
@@ -461,7 +418,7 @@ void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool Auto
        struct hal_data_8188e *pHalData = padapter->HalData;
        struct txpowerinfo24g pwrInfo24G;
        u8 ch, group;
-       u8 bIn24G, TxCount;
+       u8 TxCount;
 
        Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
 
@@ -469,19 +426,16 @@ void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool Auto
                pHalData->bTXPowerDataReadFromEEPORM = true;
 
        for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
-               bIn24G = Hal_GetChnlGroup88E(ch, &group);
-               if (bIn24G) {
-                       pHalData->Index24G_CCK_Base[0][ch] = pwrInfo24G.IndexCCK_Base[0][group];
-                       if (ch == 14)
-                               pHalData->Index24G_BW40_Base[0][ch] = pwrInfo24G.IndexBW40_Base[0][4];
-                       else
-                               pHalData->Index24G_BW40_Base[0][ch] = pwrInfo24G.IndexBW40_Base[0][group];
-               }
-               if (bIn24G) {
-                       DBG_88E("======= Path %d, Channel %d =======\n", 0, ch);
-                       DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", 0, ch, pHalData->Index24G_CCK_Base[0][ch]);
-                       DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", 0, ch, pHalData->Index24G_BW40_Base[0][ch]);
-               }
+               Hal_GetChnlGroup88E(ch, &group);
+               pHalData->Index24G_CCK_Base[0][ch] = pwrInfo24G.IndexCCK_Base[0][group];
+               if (ch == 14)
+                       pHalData->Index24G_BW40_Base[0][ch] = pwrInfo24G.IndexBW40_Base[0][4];
+               else
+                       pHalData->Index24G_BW40_Base[0][ch] = pwrInfo24G.IndexBW40_Base[0][group];
+
+               DBG_88E("======= Path %d, Channel %d =======\n", 0, ch);
+               DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", 0, ch, pHalData->Index24G_CCK_Base[0][ch]);
+               DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", 0, ch, pHalData->Index24G_BW40_Base[0][ch]);
        }
        for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
                pHalData->CCK_24G_Diff[0][TxCount] = pwrInfo24G.CCK_Diff[0][TxCount];
@@ -551,8 +505,7 @@ void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoL
 void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
 {
        padapter->mlmepriv.ChannelPlan =
-                hal_com_get_channel_plan(padapter,
-                                         hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
+                hal_com_get_channel_plan(hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
                                          padapter->registrypriv.channel_plan,
                                          RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
 
index 12864b648fa8c107e705d32dc43a5c8d705a7f7c..70c02c49b1770f20452f721ed22db48fb264c95f 100644 (file)
@@ -52,7 +52,7 @@ static bool HalUsbSetQueuePipeMapping8188EUsb(struct adapter *adapt, u8 NumInPip
 
        /*  All config other than above support one Bulk IN and one Interrupt IN. */
 
-       result = Hal_MappingOutPipe(adapt, NumOutPipe);
+       result = hal_mapping_out_pipe(adapt, NumOutPipe);
 
        return result;
 }
@@ -785,13 +785,13 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)
        haldata->RfRegChnlVal[0] = rtw_hal_read_rfreg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask);
        haldata->RfRegChnlVal[1] = rtw_hal_read_rfreg(Adapter, (enum rf_radio_path)1, RF_CHNLBW, bRFRegOffsetMask);
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK);
+       HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK);
        _BBTurnOnBlock(Adapter);
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY);
+       HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY);
        invalidate_cam_all(Adapter);
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11);
+       HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11);
        /*  2010/12/17 MH We need to set TX power according to EFUSE content at first. */
        phy_set_tx_power_level(Adapter, haldata->CurrentChannel);
 
@@ -816,7 +816,7 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11);
        /* Nav limit , suggest by scott */
        usb_write8(Adapter, 0x652, 0x0);
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM);
+       HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM);
        rtl8188e_InitHalDm(Adapter);
 
        /*  2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
@@ -840,8 +840,8 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM);
        /* enable tx DMA to drop the redundate data of packet */
        usb_write16(Adapter, REG_TXDMA_OFFSET_CHK, (usb_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
-               /*  2010/08/26 MH Merge from 8192CE. */
+       HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
+       /*  2010/08/26 MH Merge from 8192CE. */
        if (pwrctrlpriv->rf_pwrstate == rf_on) {
                if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) {
                        rtl88eu_phy_iq_calibrate(Adapter, true);
@@ -850,12 +850,12 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
                        haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true;
                }
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK);
+               HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK);
 
                ODM_TXPowerTrackingCheck(&haldata->odmpriv);
 
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK);
-                       rtl88eu_phy_lc_calibrate(Adapter);
+               HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK);
+               rtl88eu_phy_lc_calibrate(Adapter);
        }
 
 /* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); */
@@ -866,7 +866,7 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK);
        usb_write32(Adapter, REG_FWHW_TXQ_CTRL, usb_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
 
 exit:
-HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
+       HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
 
        DBG_88E("%s in %dms\n", __func__,
                jiffies_to_msecs(jiffies - init_start_time));
@@ -980,7 +980,7 @@ u32 rtw_hal_inirp_init(struct adapter *Adapter)
        /* issue Rx irp to receive data */
        precvbuf = precvpriv->precv_buf;
        for (i = 0; i < NR_RECVBUFF; i++) {
-               if (usb_read_port(Adapter, RECV_BULK_IN_ADDR, precvbuf) == false) {
+               if (!usb_read_port(Adapter, RECV_BULK_IN_ADDR, precvbuf)) {
                        RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("usb_rx_init: usb_read_port error\n"));
                        status = _FAIL;
                        goto exit;
@@ -1267,7 +1267,7 @@ void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val)
                        /*  Select RRSR (in Legacy-OFDM and CCK) */
                        /*  For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
                        /*  We do not use other rates. */
-                       HalSetBrateCfg(Adapter, val, &BrateCfg);
+                       hal_set_brate_cfg(val, &BrateCfg);
                        DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
 
                        /* 2011.03.30 add by Luke Lee */
index 4ae095837befbd9e4ad396b158ce3892d96cc93d..35c0946bc65d7c056e8f71af174f9bde245537b3 100644 (file)
 #include <rtw_recv.h>
 #include <hal_intf.h>
 #include <hal_com.h>
-#include <rtw_qos.h>
 #include <rtw_security.h>
 #include <rtw_pwrctrl.h>
 #include <rtw_eeprom.h>
 #include <sta_info.h>
+
+struct qos_priv {
+       /* bit mask option: u-apsd, s-apsd, ts, block ack... */
+       unsigned int qos_option;
+};
+
 #include <rtw_mlme.h>
 #include <rtw_debug.h>
 #include <rtw_rf.h>
index 428a2a92820e6e4ed0ab3bad6cbfa8ef088fc139..2f7bdade40a5996b58066af59740a27f05b4580b 100644 (file)
@@ -139,18 +139,14 @@ void dump_chip_info(struct HAL_VERSION    ChipVersion);
 
 
 /* return the final channel plan decision */
-u8 hal_com_get_channel_plan(struct adapter *padapter,
-                           u8 hw_channel_plan,
-                           u8 sw_channel_plan,
-                           u8 def_channel_plan,
-                           bool AutoLoadFail
-);
+u8 hal_com_get_channel_plan(u8 hw_channel_plan, u8 sw_channel_plan,
+                           u8 def_channel_plan, bool load_fail);
 
 u8 MRateToHwRate(u8 rate);
 
-void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg);
+void hal_set_brate_cfg(u8 *brates, u16 *rate_cfg);
 
-bool Hal_MappingOutPipe(struct adapter *pAdapter, u8 NumOutPipe);
+bool hal_mapping_out_pipe(struct adapter *adapter, u8 numoutpipe);
 
 void hal_init_macaddr(struct adapter *adapter);
 #endif /* __HAL_COMMON_H__ */
diff --git a/drivers/staging/rtl8188eu/include/odm_HWConfig.h b/drivers/staging/rtl8188eu/include/odm_HWConfig.h
deleted file mode 100644 (file)
index 8cef32d..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- ******************************************************************************/
-
-#ifndef        __HALHWOUTSRC_H__
-#define __HALHWOUTSRC_H__
-
-/*  Definition */
-/*  CCK Rates, TxHT = 0 */
-#define DESC92C_RATE1M                         0x00
-#define DESC92C_RATE2M                         0x01
-#define DESC92C_RATE5_5M                       0x02
-#define DESC92C_RATE11M                                0x03
-
-/*  OFDM Rates, TxHT = 0 */
-#define DESC92C_RATE6M                         0x04
-#define DESC92C_RATE9M                         0x05
-#define DESC92C_RATE12M                                0x06
-#define DESC92C_RATE18M                                0x07
-#define DESC92C_RATE24M                                0x08
-#define DESC92C_RATE36M                                0x09
-#define DESC92C_RATE48M                                0x0a
-#define DESC92C_RATE54M                                0x0b
-
-/*  MCS Rates, TxHT = 1 */
-#define DESC92C_RATEMCS0                       0x0c
-#define DESC92C_RATEMCS1                       0x0d
-#define DESC92C_RATEMCS2                       0x0e
-#define DESC92C_RATEMCS3                       0x0f
-#define DESC92C_RATEMCS4                       0x10
-#define DESC92C_RATEMCS5                       0x11
-#define DESC92C_RATEMCS6                       0x12
-#define DESC92C_RATEMCS7                       0x13
-#define DESC92C_RATEMCS8                       0x14
-#define DESC92C_RATEMCS9                       0x15
-#define DESC92C_RATEMCS10                      0x16
-#define DESC92C_RATEMCS11                      0x17
-#define DESC92C_RATEMCS12                      0x18
-#define DESC92C_RATEMCS13                      0x19
-#define DESC92C_RATEMCS14                      0x1a
-#define DESC92C_RATEMCS15                      0x1b
-#define DESC92C_RATEMCS15_SG                   0x1c
-#define DESC92C_RATEMCS32                      0x20
-
-/*  structure and define */
-
-struct phy_rx_agc_info {
-       #ifdef __LITTLE_ENDIAN
-               u8      gain:7, trsw:1;
-       #else
-               u8      trsw:1, gain:7;
-       #endif
-};
-
-struct phy_status_rpt {
-       struct phy_rx_agc_info path_agc[RF_PATH_MAX];
-       u8      ch_corr[2];
-       u8      cck_sig_qual_ofdm_pwdb_all;
-       u8      cck_agc_rpt_ofdm_cfosho_a;
-       u8      cck_rpt_b_ofdm_cfosho_b;
-       u8      rsvd_1;/* ch_corr_msb; */
-       u8      noise_power_db_msb;
-       u8      path_cfotail[2];
-       u8      pcts_mask[2];
-       s8      stream_rxevm[2];
-       u8      path_rxsnr[3];
-       u8      noise_power_db_lsb;
-       u8      rsvd_2[3];
-       u8      stream_csi[2];
-       u8      stream_target_csi[2];
-       s8      sig_evm;
-       u8      rsvd_3;
-
-#ifdef __LITTLE_ENDIAN
-       u8      antsel_rx_keep_2:1;     /* ex_intf_flg:1; */
-       u8      sgi_en:1;
-       u8      rxsc:2;
-       u8      idle_long:1;
-       u8      r_ant_train_en:1;
-       u8      ant_sel_b:1;
-       u8      ant_sel:1;
-#else  /*  _BIG_ENDIAN_ */
-       u8      ant_sel:1;
-       u8      ant_sel_b:1;
-       u8      r_ant_train_en:1;
-       u8      idle_long:1;
-       u8      rxsc:2;
-       u8      sgi_en:1;
-       u8      antsel_rx_keep_2:1;     /* ex_intf_flg:1; */
-#endif
-};
-
-void odm_Init_RSSIForDM(struct odm_dm_struct *pDM_Odm);
-
-void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm,
-                       struct odm_phy_status_info *pPhyInfo,
-                       u8 *pPhyStatus,
-                       struct odm_per_pkt_info *pPktinfo);
-
-void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm,
-                       u8 *pMacStatus,
-                       u8      MacID,
-                       bool    bPacketMatchBSSID,
-                       bool    bPacketToSelf,
-                       bool    bPacketBeacon);
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/odm_hwconfig.h b/drivers/staging/rtl8188eu/include/odm_hwconfig.h
new file mode 100644 (file)
index 0000000..8cef32d
--- /dev/null
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ ******************************************************************************/
+
+#ifndef        __HALHWOUTSRC_H__
+#define __HALHWOUTSRC_H__
+
+/*  Definition */
+/*  CCK Rates, TxHT = 0 */
+#define DESC92C_RATE1M                         0x00
+#define DESC92C_RATE2M                         0x01
+#define DESC92C_RATE5_5M                       0x02
+#define DESC92C_RATE11M                                0x03
+
+/*  OFDM Rates, TxHT = 0 */
+#define DESC92C_RATE6M                         0x04
+#define DESC92C_RATE9M                         0x05
+#define DESC92C_RATE12M                                0x06
+#define DESC92C_RATE18M                                0x07
+#define DESC92C_RATE24M                                0x08
+#define DESC92C_RATE36M                                0x09
+#define DESC92C_RATE48M                                0x0a
+#define DESC92C_RATE54M                                0x0b
+
+/*  MCS Rates, TxHT = 1 */
+#define DESC92C_RATEMCS0                       0x0c
+#define DESC92C_RATEMCS1                       0x0d
+#define DESC92C_RATEMCS2                       0x0e
+#define DESC92C_RATEMCS3                       0x0f
+#define DESC92C_RATEMCS4                       0x10
+#define DESC92C_RATEMCS5                       0x11
+#define DESC92C_RATEMCS6                       0x12
+#define DESC92C_RATEMCS7                       0x13
+#define DESC92C_RATEMCS8                       0x14
+#define DESC92C_RATEMCS9                       0x15
+#define DESC92C_RATEMCS10                      0x16
+#define DESC92C_RATEMCS11                      0x17
+#define DESC92C_RATEMCS12                      0x18
+#define DESC92C_RATEMCS13                      0x19
+#define DESC92C_RATEMCS14                      0x1a
+#define DESC92C_RATEMCS15                      0x1b
+#define DESC92C_RATEMCS15_SG                   0x1c
+#define DESC92C_RATEMCS32                      0x20
+
+/*  structure and define */
+
+struct phy_rx_agc_info {
+       #ifdef __LITTLE_ENDIAN
+               u8      gain:7, trsw:1;
+       #else
+               u8      trsw:1, gain:7;
+       #endif
+};
+
+struct phy_status_rpt {
+       struct phy_rx_agc_info path_agc[RF_PATH_MAX];
+       u8      ch_corr[2];
+       u8      cck_sig_qual_ofdm_pwdb_all;
+       u8      cck_agc_rpt_ofdm_cfosho_a;
+       u8      cck_rpt_b_ofdm_cfosho_b;
+       u8      rsvd_1;/* ch_corr_msb; */
+       u8      noise_power_db_msb;
+       u8      path_cfotail[2];
+       u8      pcts_mask[2];
+       s8      stream_rxevm[2];
+       u8      path_rxsnr[3];
+       u8      noise_power_db_lsb;
+       u8      rsvd_2[3];
+       u8      stream_csi[2];
+       u8      stream_target_csi[2];
+       s8      sig_evm;
+       u8      rsvd_3;
+
+#ifdef __LITTLE_ENDIAN
+       u8      antsel_rx_keep_2:1;     /* ex_intf_flg:1; */
+       u8      sgi_en:1;
+       u8      rxsc:2;
+       u8      idle_long:1;
+       u8      r_ant_train_en:1;
+       u8      ant_sel_b:1;
+       u8      ant_sel:1;
+#else  /*  _BIG_ENDIAN_ */
+       u8      ant_sel:1;
+       u8      ant_sel_b:1;
+       u8      r_ant_train_en:1;
+       u8      idle_long:1;
+       u8      rxsc:2;
+       u8      sgi_en:1;
+       u8      antsel_rx_keep_2:1;     /* ex_intf_flg:1; */
+#endif
+};
+
+void odm_Init_RSSIForDM(struct odm_dm_struct *pDM_Odm);
+
+void ODM_PhyStatusQuery(struct odm_dm_struct *pDM_Odm,
+                       struct odm_phy_status_info *pPhyInfo,
+                       u8 *pPhyStatus,
+                       struct odm_per_pkt_info *pPktinfo);
+
+void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm,
+                       u8 *pMacStatus,
+                       u8      MacID,
+                       bool    bPacketMatchBSSID,
+                       bool    bPacketToSelf,
+                       bool    bPacketBeacon);
+
+#endif
index 658a938df4c13a4cd6d81a89e6e2555d2d8287d9..6efddc8f1675e26300c324d82815534875ee85c2 100644 (file)
 /* 2 OutSrc Header Files */
 
 #include "odm.h"
-#include "odm_HWConfig.h"
+#include "odm_hwconfig.h"
 #include "odm_debug.h"
 #include "../../rtlwifi/phydm/phydm_regdefine11n.h"
 
 #include "hal8188e_rate_adaptive.h" /* for RA,Power training */
 #include "rtl8188e_hal.h"
 
-#include "odm_reg.h"
+#include "../../rtlwifi/phydm/phydm_reg.h"
 
 #include "odm_rtl8188e.h"
 
diff --git a/drivers/staging/rtl8188eu/include/odm_reg.h b/drivers/staging/rtl8188eu/include/odm_reg.h
deleted file mode 100644 (file)
index b56549b..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- ******************************************************************************/
-/*  */
-/*  File Name: odm_reg.h */
-/*  */
-/*  Description: */
-/*  */
-/*  This file is for general register definition. */
-/*  */
-/*  */
-/*  */
-#ifndef        __HAL_ODM_REG_H__
-#define __HAL_ODM_REG_H__
-
-/*  */
-/*  Register Definition */
-/*  */
-
-/* MAC REG */
-#define        ODM_BB_RESET                                    0x002
-#define        ODM_DUMMY                                               0x4fe
-#define        ODM_EDCA_VO_PARAM                       0x500
-#define        ODM_EDCA_VI_PARAM                       0x504
-#define        ODM_EDCA_BE_PARAM                       0x508
-#define        ODM_EDCA_BK_PARAM                       0x50C
-#define        ODM_TXPAUSE                                     0x522
-
-/* BB REG */
-#define        ODM_FPGA_PHY0_PAGE8                     0x800
-#define        ODM_PSD_SETTING                         0x808
-#define        ODM_AFE_SETTING                         0x818
-#define        ODM_TXAGC_B_6_18                                0x830
-#define        ODM_TXAGC_B_24_54                       0x834
-#define        ODM_TXAGC_B_MCS32_5                     0x838
-#define        ODM_TXAGC_B_MCS0_MCS3           0x83c
-#define        ODM_TXAGC_B_MCS4_MCS7           0x848
-#define        ODM_TXAGC_B_MCS8_MCS11          0x84c
-#define        ODM_ANALOG_REGISTER                     0x85c
-#define        ODM_RF_INTERFACE_OUTPUT         0x860
-#define        ODM_TXAGC_B_MCS12_MCS15 0x868
-#define        ODM_TXAGC_B_11_A_2_11           0x86c
-#define        ODM_AD_DA_LSB_MASK                      0x874
-#define        ODM_ENABLE_3_WIRE                       0x88c
-#define        ODM_PSD_REPORT                          0x8b4
-#define        ODM_R_ANT_SELECT                                0x90c
-#define        ODM_CCK_ANT_SELECT                      0xa07
-#define        ODM_CCK_PD_THRESH                       0xa0a
-#define        ODM_CCK_RF_REG1                         0xa11
-#define        ODM_CCK_MATCH_FILTER                    0xa20
-#define        ODM_CCK_RAKE_MAC                                0xa2e
-#define        ODM_CCK_CNT_RESET                       0xa2d
-#define        ODM_CCK_TX_DIVERSITY                    0xa2f
-#define        ODM_CCK_FA_CNT_MSB                      0xa5b
-#define        ODM_CCK_FA_CNT_LSB                      0xa5c
-#define        ODM_CCK_NEW_FUNCTION            0xa75
-#define        ODM_OFDM_PHY0_PAGE_C            0xc00
-#define        ODM_OFDM_RX_ANT                         0xc04
-#define        ODM_R_A_RXIQI                                   0xc14
-#define        ODM_R_A_AGC_CORE1                       0xc50
-#define        ODM_R_A_AGC_CORE2                       0xc54
-#define        ODM_R_B_AGC_CORE1                       0xc58
-#define        ODM_R_AGC_PAR                                   0xc70
-#define        ODM_R_HTSTF_AGC_PAR                     0xc7c
-#define        ODM_TX_PWR_TRAINING_A           0xc90
-#define        ODM_TX_PWR_TRAINING_B           0xc98
-#define        ODM_OFDM_FA_CNT1                                0xcf0
-#define        ODM_OFDM_PHY0_PAGE_D            0xd00
-#define        ODM_OFDM_FA_CNT2                                0xda0
-#define        ODM_OFDM_FA_CNT3                                0xda4
-#define        ODM_OFDM_FA_CNT4                                0xda8
-#define        ODM_TXAGC_A_6_18                                0xe00
-#define        ODM_TXAGC_A_24_54                       0xe04
-#define        ODM_TXAGC_A_1_MCS32                     0xe08
-#define        ODM_TXAGC_A_MCS0_MCS3           0xe10
-#define        ODM_TXAGC_A_MCS4_MCS7           0xe14
-#define        ODM_TXAGC_A_MCS8_MCS11          0xe18
-#define        ODM_TXAGC_A_MCS12_MCS15         0xe1c
-
-/* RF REG */
-#define        ODM_GAIN_SETTING                                0x00
-#define        ODM_CHANNEL                                     0x18
-
-/* Ant Detect Reg */
-#define        ODM_DPDT                                                0x300
-
-/* PSD Init */
-#define        ODM_PSDREG                                      0x808
-
-/* 92D Path Div */
-#define        PATHDIV_REG                                     0xB30
-#define        PATHDIV_TRI                                     0xBA0
-
-
-/*  */
-/*  Bitmap Definition */
-/*  */
-
-#define        BIT_FA_RESET                                    BIT(0)
-
-
-
-#endif
index fbcba79a09273a5e7bb30bd47800417f385eee87..cfe5698fbbb15cde75c96973bff6636f411278de 100644 (file)
@@ -64,8 +64,6 @@ static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
 u8 *_rtw_malloc(u32 sz);
 #define rtw_malloc(sz)                 _rtw_malloc((sz))
 
-void *rtw_malloc2d(int h, int w, int size);
-
 void _rtw_init_queue(struct __queue *pqueue);
 
 struct rtw_netdev_priv_indicator {
index e99ac3910787462dfcc795e956f376c47eb92e0f..40901d6dcaf5e2e7d3037a3b00e532fb13303632 100644 (file)
@@ -4,7 +4,6 @@
 #define IQK_DELAY_TIME_88E         10
 #define index_mapping_NUM_88E      15
 #define AVG_THERMAL_NUM_88E        4
-#define ODM_TARGET_CHNL_NUM_2G_5G   59
 
 bool rtl88eu_phy_mac_config(struct adapter *adapt);
 bool rtl88eu_phy_rf_config(struct adapter *adapt);
index 35997c521c35c7ee829acde4206e9500adfaafb8..8d9d663f064514bcd17b01f96bb4144f2e220790 100644 (file)
@@ -214,7 +214,7 @@ void hostapd_mode_unload(struct adapter *padapter);
 extern unsigned char WPA_TKIP_CIPHER[4];
 extern unsigned char RSN_TKIP_CIPHER[4];
 extern unsigned char REALTEK_96B_IE[];
-extern unsigned char   MCS_rate_1R[16];
+extern const u8 MCS_rate_1R[16];
 
 void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf);
 void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf);
@@ -311,7 +311,6 @@ void rtw_free_assoc_resources_locked(struct adapter *adapter);
 void rtw_indicate_disconnect(struct adapter *adapter);
 void rtw_indicate_connect(struct adapter *adapter);
 void rtw_indicate_scan_done(struct adapter *padapter, bool aborted);
-void rtw_scan_abort(struct adapter *adapter);
 
 int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie,
                        uint in_len);
index ade68af15e04bf2ac88fb15ed3812c101376140f..9526da3efcc4766ff3b1a9487db58f149dcf6816 100644 (file)
@@ -231,22 +231,22 @@ enum SCAN_STATE {
 };
 
 struct mlme_handler {
-       unsigned int   num;
-       char *str;
+       unsigned int num;
+       const char *str;
        unsigned int (*func)(struct adapter *adapt, struct recv_frame *frame);
 };
 
 struct action_handler {
-       unsigned int   num;
-       char *str;
+       unsigned int num;
+       const char *str;
        unsigned int (*func)(struct adapter *adapt, struct recv_frame *frame);
 };
 
-struct ss_res {
-       int     state;
-       int     bss_cnt;
-       int     channel_idx;
-       int     scan_mode;
+struct ss_res {
+       int state;
+       int bss_cnt;
+       int channel_idx;
+       int scan_mode;
        u8 ssid_num;
        u8 ch_num;
        struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
diff --git a/drivers/staging/rtl8188eu/include/rtw_qos.h b/drivers/staging/rtl8188eu/include/rtw_qos.h
deleted file mode 100644 (file)
index bf617da..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- ******************************************************************************/
-#ifndef _RTW_QOS_H_
-#define _RTW_QOS_H_
-
-#include <osdep_service.h>
-
-struct qos_priv        {
-       unsigned int      qos_option;   /* bit mask option: u-apsd,
-                                        * s-apsd, ts, block ack...
-                                        */
-};
-
-#endif /* _RTL871X_QOS_H_ */
index 259bf2cce2d5b708394b292c260149f8ab83fb56..0664d5f30a96d8be392dacaf694221833847ad24 100644 (file)
@@ -257,14 +257,6 @@ enum WIFI_REG_DOMAIN {
 
 #define GetAddr4Ptr(pbuf)      ((unsigned char *)((size_t)(pbuf) + 24))
 
-static inline int IS_MCAST(unsigned char *da)
-{
-       if ((*da) & 0x01)
-               return true;
-       else
-               return false;
-}
-
 static inline unsigned char *get_da(unsigned char *pframe)
 {
        unsigned char   *da;
index bee3c3a7a7a999e00d2acb67c6340793ee003f08..4ecd2ff48c417529ac8196728d4c69c59406024e 100644 (file)
@@ -421,7 +421,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
                                ret = -EOPNOTSUPP;
                                goto exit;
                        }
-                     memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
+                       memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
                        psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
                        rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
                }
@@ -737,7 +737,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
                RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported\n", iw_operation_mode[wrqu->mode]));
                goto exit;
        }
-       if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) {
+       if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) {
                ret = -EPERM;
                goto exit;
        }
@@ -1000,8 +1000,7 @@ static int rtw_wx_set_wap(struct net_device *dev,
        spin_unlock_bh(&queue->lock);
 
        rtw_set_802_11_authentication_mode(padapter, authmode);
-       /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
-       if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) {
+       if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
                ret = -1;
                goto exit;
        }
@@ -1317,8 +1316,8 @@ static int rtw_wx_set_essid(struct net_device *dev,
 
                RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid));
                spin_lock_bh(&queue->lock);
-              phead = get_list_head(queue);
-             pmlmepriv->pscanned = phead->next;
+               phead = get_list_head(queue);
+               pmlmepriv->pscanned = phead->next;
 
                while (phead != pmlmepriv->pscanned) {
                        pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
@@ -1354,7 +1353,7 @@ static int rtw_wx_set_essid(struct net_device *dev,
                RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
                         ("set ssid: set_802_11_auth. mode =%d\n", authmode));
                rtw_set_802_11_authentication_mode(padapter, authmode);
-               if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) {
+               if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) {
                        ret = -1;
                        goto exit;
                }
@@ -1370,7 +1369,7 @@ static int rtw_wx_get_essid(struct net_device *dev,
                              struct iw_request_info *a,
                              union iwreq_data *wrqu, char *extra)
 {
-       u32 len, ret = 0;
+       u32 len;
        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
        struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
        struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
@@ -1388,7 +1387,7 @@ static int rtw_wx_get_essid(struct net_device *dev,
        wrqu->essid.length = len;
        wrqu->essid.flags = 1;
 
-       return ret;
+       return 0;
 }
 
 static int rtw_wx_set_rate(struct net_device *dev,
@@ -1400,7 +1399,7 @@ static int rtw_wx_set_rate(struct net_device *dev,
        u32     target_rate = wrqu->bitrate.value;
        u32     fixed = wrqu->bitrate.fixed;
        u32     ratevalue = 0;
-        u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
+       u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
 
        RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n"));
        RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed));
@@ -1673,7 +1672,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
 
        memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
 
-       if (rtw_set_802_11_add_wep(padapter, &wep) == false) {
+       if (!rtw_set_802_11_add_wep(padapter, &wep)) {
                if (rf_on == pwrpriv->rf_pwrstate)
                        ret = -EOPNOTSUPP;
                goto exit;
@@ -2278,7 +2277,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
                        /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
                        /* psecuritypriv->dot11PrivacyKeyIndex = keyid", but can rtw_set_key to cam */
 
-                     memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
+                       memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
 
                        psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
 
@@ -2496,7 +2495,7 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
                        psta->htpriv.ht_option = false;
                }
 
-               if (pmlmepriv->htpriv.ht_option == false)
+               if (!pmlmepriv->htpriv.ht_option)
                        psta->htpriv.ht_option = false;
 
                update_sta_info_apmode(padapter, psta);
index 238c1d9cdc7b2236ddb94787bf0bc510a098ead9..d5ceb3beabbc715ae1cfa602c80c0c0d66ff084e 100644 (file)
@@ -78,7 +78,7 @@ void rtw_os_indicate_disconnect(struct adapter *adapter)
 {
        netif_carrier_off(adapter->pnetdev); /*  Do it first for tx broadcast pkt after disconnection issue! */
        rtw_indicate_wx_disassoc_event(adapter);
-        rtw_reset_securitypriv(adapter);
+       rtw_reset_securitypriv(adapter);
 }
 
 void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie)
index 0a9877d85c790d029e173715fa3cad24a85a03a0..dac9f98b48086de0fa32af6b313cc527a2d74559 100644 (file)
@@ -643,7 +643,7 @@ int  ips_netdrv_open(struct adapter *padapter)
        mod_timer(&padapter->mlmepriv.dynamic_chk_timer,
                  jiffies + msecs_to_jiffies(5000));
 
-        return _SUCCESS;
+       return _SUCCESS;
 
 netdev_open_error:
        DBG_88E("-ips_netdrv_open - drv_open failure, bup =%d\n", padapter->bup);
index 78daef6704aca86739a5c0c7759cee276a0327b1..105f3f21bdea7864d481d4e33954dbec90b8690b 100644 (file)
@@ -18,20 +18,6 @@ u8 *_rtw_malloc(u32 sz)
        return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 }
 
-void *rtw_malloc2d(int h, int w, int size)
-{
-       int j;
-       void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL);
-
-       if (!a)
-               goto out;
-
-       for (j = 0; j < h; j++)
-               a[j] = ((char *)(a + h)) + j * w * size;
-out:
-       return a;
-}
-
 void _rtw_init_queue(struct __queue *pqueue)
 {
        INIT_LIST_HEAD(&pqueue->queue);
index 5ddfc2ead127d24f3dc5b61a175ff79b554f36e9..d6a499692e96e01ee15227780c68551b253a62ad 100644 (file)
@@ -84,7 +84,7 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
 
                if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recvbuf2recvframe: pkt_len<=0\n"));
-                       DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__, __LINE__);
+                       DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfer_len\n", __func__, __LINE__);
                        rtw_free_recvframe(precvframe, pfree_recv_queue);
                        goto _exit_recvbuf2recvframe;
                }
@@ -606,7 +606,7 @@ static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
                if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) {
                        sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
                } else if (purb->status == -EINPROGRESS) {
-                       RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete: EINPROGESS\n"));
+                       RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete: EINPROGRESS\n"));
                        goto check_completion;
                } else if (purb->status == -ENOENT) {
                        DBG_88E("%s: -ENOENT\n", __func__);
index d8ef9b5d81a8c33689e8e460d0eea9519b300b96..017e1d628461459c5cd546bd1330dfff9f08889e 100644 (file)
@@ -14,7 +14,8 @@
 #include <xmit_osdep.h>
 #include <osdep_intf.h>
 
-int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz)
+int rtw_os_xmit_resource_alloc(struct adapter *padapter,
+                              struct xmit_buf *pxmitbuf, u32 alloc_sz)
 {
        int i;
 
@@ -45,11 +46,11 @@ void rtw_os_xmit_resource_free(struct xmit_buf *pxmitbuf)
        kfree(pxmitbuf->pallocated_buf);
 }
 
-#define WMM_XMIT_THRESHOLD     (NR_XMITFRAME*2/5)
+#define WMM_XMIT_THRESHOLD     (NR_XMITFRAME * 2 / 5)
 
 void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt)
 {
-       u16     queue;
+       u16 queue;
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 
        queue = skb_get_queue_mapping(pkt);
@@ -89,10 +90,11 @@ void rtw_os_xmit_schedule(struct adapter *padapter)
        spin_unlock_bh(&pxmitpriv->lock);
 }
 
-static void rtw_check_xmit_resource(struct adapter *padapter, struct sk_buff *pkt)
+static void rtw_check_xmit_resource(struct adapter *padapter,
+                                   struct sk_buff *pkt)
 {
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       u16     queue;
+       u16 queue;
 
        queue = skb_get_queue_mapping(pkt);
        if (padapter->registrypriv.wifi_spec) {
@@ -109,12 +111,12 @@ static void rtw_check_xmit_resource(struct adapter *padapter, struct sk_buff *pk
 
 static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
 {
-       struct  sta_priv *pstapriv = &padapter->stapriv;
+       struct sta_priv *pstapriv = &padapter->stapriv;
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
        struct list_head *phead, *plist;
        struct sk_buff *newskb;
        struct sta_info *psta = NULL;
-       s32     res;
+       s32 res;
 
        spin_lock_bh(&pstapriv->asoc_list_lock);
        phead = &pstapriv->asoc_list;
@@ -126,7 +128,7 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
 
                plist = plist->next;
 
-               /* avoid   come from STA1 and send back STA1 */
+               /* avoid come from STA1 and send back STA1 */
                if (!memcmp(psta->hwaddr, &skb->data[6], 6))
                        continue;
 
@@ -136,18 +138,24 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
                        memcpy(newskb->data, psta->hwaddr, 6);
                        res = rtw_xmit(padapter, &newskb);
                        if (res < 0) {
-                               DBG_88E("%s()-%d: rtw_xmit() return error!\n", __func__, __LINE__);
+                               DBG_88E("%s()-%d: rtw_xmit() return error!\n",
+                                       __func__, __LINE__);
                                pxmitpriv->tx_drop++;
                                dev_kfree_skb_any(newskb);
                        } else {
                                pxmitpriv->tx_pkts++;
                        }
                } else {
-                       DBG_88E("%s-%d: skb_copy() failed!\n", __func__, __LINE__);
+                       DBG_88E("%s-%d: skb_copy() failed!\n",
+                               __func__, __LINE__);
                        pxmitpriv->tx_drop++;
 
                        spin_unlock_bh(&pstapriv->asoc_list_lock);
-                       return false;   /*  Caller shall tx this multicast frame via normal way. */
+
+                       /* Caller shall tx this multicast frame
+                        * via normal way.
+                        */
+                       return false;
                }
        }
 
@@ -156,17 +164,18 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
        return true;
 }
 
-int rtw_xmit_entry(struct sk_buff *pkt, struct  net_device *pnetdev)
+int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev)
 {
        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
        s32 res = 0;
 
        RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n"));
 
-       if (rtw_if_up(padapter) == false) {
-               RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n"));
+       if (!rtw_if_up(padapter)) {
+               RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
+                        ("%s: rtw_if_up fail\n", __func__));
                goto drop_packet;
        }
 
@@ -175,7 +184,7 @@ int rtw_xmit_entry(struct sk_buff *pkt, struct  net_device *pnetdev)
        if (!rtw_mc2u_disable && check_fwstate(pmlmepriv, WIFI_AP_STATE) &&
            (IP_MCAST_MAC(pkt->data) || ICMPV6_MCAST_MAC(pkt->data)) &&
            (padapter->registrypriv.wifi_spec == 0)) {
-               if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4)) {
+               if (pxmitpriv->free_xmitframe_cnt > NR_XMITFRAME / 4) {
                        res = rtw_mlcst2unicst(padapter, pkt);
                        if (res)
                                goto exit;
@@ -187,13 +196,15 @@ int rtw_xmit_entry(struct sk_buff *pkt, struct  net_device *pnetdev)
                goto drop_packet;
 
        pxmitpriv->tx_pkts++;
-       RT_TRACE(_module_xmit_osdep_c_, _drv_info_, ("rtw_xmit_entry: tx_pkts=%d\n", (u32)pxmitpriv->tx_pkts));
+       RT_TRACE(_module_xmit_osdep_c_, _drv_info_,
+                ("%s: tx_pkts=%d\n", __func__, (u32)pxmitpriv->tx_pkts));
        goto exit;
 
 drop_packet:
        pxmitpriv->tx_drop++;
        dev_kfree_skb_any(pkt);
-       RT_TRACE(_module_xmit_osdep_c_, _drv_notice_, ("rtw_xmit_entry: drop, tx_drop=%d\n", (u32)pxmitpriv->tx_drop));
+       RT_TRACE(_module_xmit_osdep_c_, _drv_notice_,
+                ("%s: drop, tx_drop=%d\n", __func__, (u32)pxmitpriv->tx_drop));
 
 exit:
        return 0;
index 919231fec09cba4dacab0e4c18b64c4ca385c145..287d0c11fa385b67659ca995dd2fea9e65203ce7 100644 (file)
@@ -1680,19 +1680,19 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
                   (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
                   (!apset && ssidset && ssidbroad && ssidmatch) ||
                   (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) {
-                       /* if the essid is hidden replace it with the
-                        * essid provided by the user.
+                       /* Save the essid so that if it is hidden, it is
+                        * replaced with the essid provided by the user.
                         */
                        if (!ssidbroad) {
-                               strncpy(tmp_ssid, ieee->current_network.ssid,
-                                       IW_ESSID_MAX_SIZE);
+                               memcpy(tmp_ssid, ieee->current_network.ssid,
+                                      ieee->current_network.ssid_len);
                                tmp_ssid_len = ieee->current_network.ssid_len;
                        }
-                       memcpy(&ieee->current_network, net,
-                              sizeof(struct rtllib_network));
+                       memcpy(&ieee->current_network, net,
+                              sizeof(ieee->current_network));
                        if (!ssidbroad) {
-                               strncpy(ieee->current_network.ssid, tmp_ssid,
-                                       IW_ESSID_MAX_SIZE);
+                               memcpy(ieee->current_network.ssid, tmp_ssid,
+                                      tmp_ssid_len);
                                ieee->current_network.ssid_len = tmp_ssid_len;
                        }
                        netdev_info(ieee->dev,
index 2fb575a2b6abf04f575d9741b9f9668fdf245a67..130ddfe9868f6a410c66af2f49f5f2a61553c096 100644 (file)
@@ -3,42 +3,42 @@
 
 #include "dot11d.h"
 
-void Dot11d_Init(struct ieee80211_device *ieee)
+void rtl8192u_dot11d_init(struct ieee80211_device *ieee)
 {
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee);
 
-       pDot11dInfo->enabled = false;
+       dot11d_info->dot11d_enabled = false;
 
-       pDot11dInfo->state = DOT11D_STATE_NONE;
-       pDot11dInfo->country_ie_len = 0;
-       memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
-       memset(pDot11dInfo->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1);
+       dot11d_info->state = DOT11D_STATE_NONE;
+       dot11d_info->country_ie_len = 0;
+       memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
+       memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1);
        RESET_CIE_WATCHDOG(ieee);
 
-       netdev_info(ieee->dev, "Dot11d_Init()\n");
+       netdev_info(ieee->dev, "rtl8192u_dot11d_init()\n");
 }
-EXPORT_SYMBOL(Dot11d_Init);
+EXPORT_SYMBOL(rtl8192u_dot11d_init);
 
 /* Reset to the state as we are just entering a regulatory domain. */
-void Dot11d_Reset(struct ieee80211_device *ieee)
+void dot11d_reset(struct ieee80211_device *ieee)
 {
        u32 i;
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee);
        /* Clear old channel map */
-       memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
-       memset(pDot11dInfo->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1);
+       memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+       memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1);
        /* Set new channel map */
        for (i = 1; i <= 11; i++)
-               (pDot11dInfo->channel_map)[i] = 1;
+               (dot11d_info->channel_map)[i] = 1;
 
        for (i = 12; i <= 14; i++)
-               (pDot11dInfo->channel_map)[i] = 2;
+               (dot11d_info->channel_map)[i] = 2;
 
-       pDot11dInfo->state = DOT11D_STATE_NONE;
-       pDot11dInfo->country_ie_len = 0;
+       dot11d_info->state = DOT11D_STATE_NONE;
+       dot11d_info->country_ie_len = 0;
        RESET_CIE_WATCHDOG(ieee);
 }
-EXPORT_SYMBOL(Dot11d_Reset);
+EXPORT_SYMBOL(dot11d_reset);
 
 /*
  * Update country IE from Beacon or Probe Resopnse and configure PHY for
@@ -49,15 +49,15 @@ EXPORT_SYMBOL(Dot11d_Reset);
  * 1. IS_DOT11D_ENABLE() is TRUE.
  * 2. Input IE is an valid one.
  */
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
+void dot11d_update_country_ie(struct ieee80211_device *dev, u8 *pTaddr,
                            u16 CoutryIeLen, u8 *pCoutryIe)
 {
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
        u8 i, j, NumTriples, MaxChnlNum;
        struct chnl_txpower_triple *pTriple;
 
-       memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
-       memset(pDot11dInfo->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1);
+       memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+       memset(dot11d_info->max_tx_pwr_dbm_list, 0xFF, MAX_CHANNEL_NUMBER+1);
        MaxChnlNum = 0;
        NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
        pTriple = (struct chnl_txpower_triple *)(pCoutryIe + 3);
@@ -66,20 +66,20 @@ void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
                        /* It is not in a monotonically increasing order, so
                         * stop processing.
                         */
-                       netdev_err(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+                       netdev_err(dev->dev, "dot11d_update_country_ie(): Invalid country IE, skip it........1\n");
                        return;
                }
                if (MAX_CHANNEL_NUMBER < (pTriple->first_channel + pTriple->num_channels)) {
                        /* It is not a valid set of channel id, so stop
                         * processing.
                         */
-                       netdev_err(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+                       netdev_err(dev->dev, "dot11d_update_country_ie(): Invalid country IE, skip it........2\n");
                        return;
                }
 
                for (j = 0; j < pTriple->num_channels; j++) {
-                       pDot11dInfo->channel_map[pTriple->first_channel + j] = 1;
-                       pDot11dInfo->max_tx_pwr_dbm_list[pTriple->first_channel + j] = pTriple->max_tx_pwr_dbm;
+                       dot11d_info->channel_map[pTriple->first_channel + j] = 1;
+                       dot11d_info->max_tx_pwr_dbm_list[pTriple->first_channel + j] = pTriple->max_tx_pwr_dbm;
                        MaxChnlNum = pTriple->first_channel + j;
                }
 
@@ -87,90 +87,90 @@ void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
        }
        netdev_info(dev->dev, "Channel List:");
        for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
-               if (pDot11dInfo->channel_map[i] > 0)
+               if (dot11d_info->channel_map[i] > 0)
                        netdev_info(dev->dev, " %d", i);
        netdev_info(dev->dev, "\n");
 
        UPDATE_CIE_SRC(dev, pTaddr);
 
-       pDot11dInfo->country_ie_len = CoutryIeLen;
-       memcpy(pDot11dInfo->country_ie_buf, pCoutryIe, CoutryIeLen);
-       pDot11dInfo->state = DOT11D_STATE_LEARNED;
+       dot11d_info->country_ie_len = CoutryIeLen;
+       memcpy(dot11d_info->country_ie_buf, pCoutryIe, CoutryIeLen);
+       dot11d_info->state = DOT11D_STATE_LEARNED;
 }
-EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL(dot11d_update_country_ie);
 
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
+u8 dot11d_get_max_tx_pwr_in_dbm(struct ieee80211_device *dev, u8 Channel)
 {
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
        u8 MaxTxPwrInDbm = 255;
 
        if (Channel > MAX_CHANNEL_NUMBER) {
-               netdev_err(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
+               netdev_err(dev->dev, "dot11d_get_max_tx_pwr_in_dbm(): Invalid Channel\n");
                return MaxTxPwrInDbm;
        }
-       if (pDot11dInfo->channel_map[Channel])
-               MaxTxPwrInDbm = pDot11dInfo->max_tx_pwr_dbm_list[Channel];
+       if (dot11d_info->channel_map[Channel])
+               MaxTxPwrInDbm = dot11d_info->max_tx_pwr_dbm_list[Channel];
 
        return MaxTxPwrInDbm;
 }
-EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL(dot11d_get_max_tx_pwr_in_dbm);
 
-void DOT11D_ScanComplete(struct ieee80211_device *dev)
+void dot11d_scan_complete(struct ieee80211_device *dev)
 {
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
 
-       switch (pDot11dInfo->state) {
+       switch (dot11d_info->state) {
        case DOT11D_STATE_LEARNED:
-               pDot11dInfo->state = DOT11D_STATE_DONE;
+               dot11d_info->state = DOT11D_STATE_DONE;
                break;
 
        case DOT11D_STATE_DONE:
                if (GET_CIE_WATCHDOG(dev) == 0) {
                        /* Reset country IE if previous one is gone. */
-                       Dot11d_Reset(dev);
+                       dot11d_reset(dev);
                }
                break;
        case DOT11D_STATE_NONE:
                break;
        }
 }
-EXPORT_SYMBOL(DOT11D_ScanComplete);
+EXPORT_SYMBOL(dot11d_scan_complete);
 
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
+int is_legal_channel(struct ieee80211_device *dev, u8 channel)
 {
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
 
        if (channel > MAX_CHANNEL_NUMBER) {
-               netdev_err(dev->dev, "IsLegalChannel(): Invalid Channel\n");
+               netdev_err(dev->dev, "is_legal_channel(): Invalid Channel\n");
                return 0;
        }
-       if (pDot11dInfo->channel_map[channel] > 0)
+       if (dot11d_info->channel_map[channel] > 0)
                return 1;
        return 0;
 }
-EXPORT_SYMBOL(IsLegalChannel);
+EXPORT_SYMBOL(is_legal_channel);
 
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
+int to_legal_channel(struct ieee80211_device *dev, u8 channel)
 {
-       struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
+       struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
        u8 default_chn = 0;
        u32 i = 0;
 
        for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
-               if (pDot11dInfo->channel_map[i] > 0) {
+               if (dot11d_info->channel_map[i] > 0) {
                        default_chn = i;
                        break;
                }
        }
 
        if (channel > MAX_CHANNEL_NUMBER) {
-               netdev_err(dev->dev, "IsLegalChannel(): Invalid Channel\n");
+               netdev_err(dev->dev, "is_legal_channel(): Invalid Channel\n");
                return default_chn;
        }
 
-       if (pDot11dInfo->channel_map[channel] > 0)
+       if (dot11d_info->channel_map[channel] > 0)
                return channel;
 
        return default_chn;
 }
-EXPORT_SYMBOL(ToLegalChannel);
+EXPORT_SYMBOL(to_legal_channel);
index 363a6bed18ddbbbd33e5fd644c8a0efb0ffb6cf9..8b485fa180898e127da49015d96a31417fb81809 100644 (file)
@@ -17,74 +17,41 @@ enum dot11d_state {
 };
 
 struct rt_dot11d_info {
-       bool enabled; /* dot11MultiDomainCapabilityEnabled */
-
        u16 country_ie_len; /* > 0 if country_ie_buf[] contains valid country information element. */
+
+       /*  country_ie_src_addr u16 aligned for comparison and copy */
+       u8  country_ie_src_addr[ETH_ALEN]; /* Source AP of the country IE. */
        u8  country_ie_buf[MAX_IE_LEN];
-       u8  country_ie_src_addr[6]; /* Source AP of the country IE. */
        u8  country_ie_watchdog;
 
        u8  channel_map[MAX_CHANNEL_NUMBER + 1];  /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
        u8  max_tx_pwr_dbm_list[MAX_CHANNEL_NUMBER + 1];
 
        enum dot11d_state state;
+       u8  dot11d_enabled; /* dot11MultiDomainCapabilityEnabled */
 };
 
-#define eqMacAddr(a, b)                (((a)[0] == (b)[0] &&               \
-       (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && \
-       (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
-#define cpMacAddr(des, src)          ((des)[0] = (src)[0], \
-       (des)[1] = (src)[1], (des)[2] = (src)[2], \
-       (des)[3] = (src)[3], (des)[4] = (src)[4], \
-       (des)[5] = (src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((struct rt_dot11d_info *)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->enabled)
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->country_ie_len > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->country_ie_src_addr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->country_ie_src_addr, __pTa)
-
-#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->country_ie_watchdog)
-#define RESET_CIE_WATCHDOG(__pIeeeDev) (GET_CIE_WATCHDOG(__pIeeeDev) = 0)
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
-
-void
-Dot11d_Init(
-       struct ieee80211_device *dev
-       );
-
-void
-Dot11d_Reset(
-       struct ieee80211_device *dev
-       );
+#define GET_DOT11D_INFO(ieee_dev) ((struct rt_dot11d_info *)((ieee_dev)->dot11d_info))
 
-void
-Dot11d_UpdateCountryIe(
-       struct ieee80211_device *dev,
-       u8 *pTaddr,
-       u16 CoutryIeLen,
-       u8 *pCoutryIe
-       );
+#define IS_DOT11D_ENABLE(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->dot11d_enabled)
+#define IS_COUNTRY_IE_VALID(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->country_ie_len > 0)
 
-u8
-DOT11D_GetMaxTxPwrInDbm(
-       struct ieee80211_device *dev,
-       u8 Channel
-       );
+#define IS_EQUAL_CIE_SRC(ieee_dev, addr) ether_addr_equal(GET_DOT11D_INFO(ieee_dev)->country_ie_src_addr, addr)
+#define UPDATE_CIE_SRC(ieee_dev, addr) ether_addr_copy(GET_DOT11D_INFO(ieee_dev)->country_ie_src_addr, addr)
 
-void
-DOT11D_ScanComplete(
-       struct ieee80211_device *dev
-       );
+#define GET_CIE_WATCHDOG(ieee_dev) (GET_DOT11D_INFO(ieee_dev)->country_ie_watchdog)
+#define RESET_CIE_WATCHDOG(ieee_dev) (GET_CIE_WATCHDOG(ieee_dev) = 0)
+#define UPDATE_CIE_WATCHDOG(ieee_dev) (++GET_CIE_WATCHDOG(ieee_dev))
 
-int IsLegalChannel(
-       struct ieee80211_device *dev,
-       u8 channel
-);
+void rtl8192u_dot11d_init(struct ieee80211_device *dev);
+void dot11d_reset(struct ieee80211_device *dev);
+void dot11d_update_country_ie(struct ieee80211_device *dev,
+                             u8 *addr,
+                             u16 coutry_ie_len,
+                             u8 *coutry_ie);
+u8 dot11d_get_max_tx_pwr_in_dbm(struct ieee80211_device *dev, u8 channel);
+void dot11d_scan_complete(struct ieee80211_device *dev);
+int is_legal_channel(struct ieee80211_device *dev, u8 channel);
+int to_legal_channel(struct ieee80211_device *dev, u8 channel);
 
-int ToLegalChannel(
-       struct ieee80211_device *dev,
-       u8 channel
-);
 #endif /* #ifndef __INC_DOT11D_H */
index 3cfeac0d72147c64d3ae345f8e945e545115e5b0..8aa536d7990002ca16bafa94660e0c376b04b752 100644 (file)
@@ -1329,8 +1329,13 @@ typedef enum _erp_t {
 
 struct ieee80211_network {
        /* These entries are used to identify a unique network */
-       u8 bssid[ETH_ALEN];
+       u8 bssid[ETH_ALEN];   /* u16 aligned! */
        u8 channel;
+
+       // CCXv4 S59, MBSSID.
+       bool    bMBssidValid;
+       u8      MBssid[ETH_ALEN];    /* u16 aligned! */
+       u8      MBssidMask;
        /* Ensure null-terminated for any debug msgs */
        u8 ssid[IW_ESSID_MAX_SIZE + 1];
        u8 ssid_len;
@@ -1341,10 +1346,6 @@ struct ieee80211_network {
        bool    bCkipSupported;
        bool    bCcxRmEnable;
        u16     CcxRmState[2];
-       // CCXv4 S59, MBSSID.
-       bool    bMBssidValid;
-       u8      MBssidMask;
-       u8      MBssid[6];
        // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
        bool    bWithCcxVerNum;
        u8      BssCcxVerNumber;
@@ -1771,7 +1772,7 @@ struct ieee80211_device {
 
        /* map of allowed channels. 0 is dummy */
        // FIXME: remember to default to a basic channel plan depending of the PHY type
-       void *pDot11dInfo;
+       void *dot11d_info;
        bool bGlobalDomain;
        int rate;       /* current rate */
        int basic_rate;
@@ -2378,11 +2379,8 @@ u8 HTGetHighestMCSRate(struct ieee80211_device *ieee,
 extern u8 MCS_FILTER_ALL[];
 extern u16 MCS_DATA_RATE[2][2][77];
 u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame);
-//extern void HTSetConnectBwModeCallback(unsigned long data);
 void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo);
 bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee);
-u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
-u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
 u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate);
 //function in BAPROC.c
 int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb);
@@ -2395,7 +2393,7 @@ void TsInitDelBA(struct ieee80211_device *ieee,
 void BaSetupTimeOut(struct timer_list *t);
 void TxBaInactTimeout(struct timer_list *t);
 void RxBaInactTimeout(struct timer_list *t);
-void ResetBaEntry(PBA_RECORD pBA);
+void ResetBaEntry(struct ba_record *pBA);
 //function in TS.c
 bool GetTs(
        struct ieee80211_device         *ieee,
index 90a097f2cd4eca871175a9b73bab65eb80e925a4..d7975aa335b24c406142a69a19186b6e83410b1d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*******************************************************************************
  *
  *  Copyright(c) 2004 Intel Corporation. All rights reserved.
  *  James P. Ketrenos <ipw2100-admin@linux.intel.com>
  *  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
- *******************************************************************************/
+ ******************************************************************************/
 
 #include <linux/compiler.h>
-/* #include <linux/config.h> */
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -64,9 +64,9 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
        if (ieee->networks)
                return 0;
 
-       ieee->networks = kcalloc(
-               MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
-               GFP_KERNEL);
+       ieee->networks = kcalloc(MAX_NETWORK_COUNT,
+                                sizeof(struct ieee80211_network),
+                                GFP_KERNEL);
        if (!ieee->networks) {
                printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
                       ieee->dev->name);
@@ -94,7 +94,6 @@ static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
                list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
 }
 
-
 struct net_device *alloc_ieee80211(int sizeof_priv)
 {
        struct ieee80211_device *ieee;
@@ -110,7 +109,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        }
 
        ieee = netdev_priv(dev);
-       memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
+       memset(ieee, 0, sizeof(struct ieee80211_device) + sizeof_priv);
        ieee->dev = dev;
 
        err = ieee80211_networks_allocate(ieee);
@@ -121,7 +120,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        }
        ieee80211_networks_initialize(ieee);
 
-
        /* Default fragmentation threshold is maximum payload size */
        ieee->fts = DEFAULT_FTS;
        ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
@@ -159,6 +157,11 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
        if (ieee->pHTInfo == NULL) {
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
+
+               /* By this point in code ieee80211_networks_allocate() has been
+                * successfully called so the memory allocated should be freed
+                */
+               ieee80211_networks_free(ieee);
                goto failed;
        }
        HTUpdateDefaultSetting(ieee);
@@ -169,9 +172,9 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
                INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
 
        for (i = 0; i < 17; i++) {
-         ieee->last_rxseq_num[i] = -1;
-         ieee->last_rxfrag_num[i] = -1;
-         ieee->last_packet_time[i] = 0;
+               ieee->last_rxseq_num[i] = -1;
+               ieee->last_rxfrag_num[i] = -1;
+               ieee->last_packet_time[i] = 0;
        }
 
 /* These function were added to load crypte module autoly */
@@ -186,7 +189,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        return NULL;
 }
 
-
 void free_ieee80211(struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
@@ -202,6 +204,7 @@ void free_ieee80211(struct net_device *dev)
 
        for (i = 0; i < WEP_KEYS; i++) {
                struct ieee80211_crypt_data *crypt = ieee->crypt[i];
+
                if (crypt) {
                        if (crypt->ops)
                                crypt->ops->deinit(crypt->priv);
@@ -217,8 +220,7 @@ void free_ieee80211(struct net_device *dev)
 #ifdef CONFIG_IEEE80211_DEBUG
 
 u32 ieee80211_debug_level;
-static int debug = \
-       //                  IEEE80211_DL_INFO   |
+static int debug = //      IEEE80211_DL_INFO   |
        //                  IEEE80211_DL_WX     |
        //                  IEEE80211_DL_SCAN   |
        //                  IEEE80211_DL_STATE  |
@@ -247,10 +249,11 @@ static int show_debug_level(struct seq_file *m, void *v)
 }
 
 static ssize_t write_debug_level(struct file *file, const char __user *buffer,
-                            size_t count, loff_t *ppos)
+                                size_t count, loff_t *ppos)
 {
        unsigned long val;
        int err = kstrtoul_from_user(buffer, count, 0, &val);
+
        if (err)
                return err;
        ieee80211_debug_level = val;
@@ -277,7 +280,7 @@ int __init ieee80211_debug_init(void)
        ieee80211_debug_level = debug;
 
        ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
-       if (ieee80211_proc == NULL) {
+       if (!ieee80211_proc) {
                IEEE80211_ERROR("Unable to create " DRV_NAME
                                " proc directory\n");
                return -EIO;
index 28cae82d795c7c4fd1787df31f9cd44e6a561355..5147f7c01e316c2c0f4d4a3a65a1c63898966e92 100644 (file)
@@ -794,7 +794,7 @@ static u8 parse_subframe(struct sk_buff *skb,
        }
 
        if (rx_stats->bContainHTC) {
-               LLCOffset += sHTCLng;
+               LLCOffset += HTCLNG;
        }
        // Null packet, don't indicate it to upper layer
        ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
@@ -1582,7 +1582,7 @@ static inline void ieee80211_extract_country_ie(
 
                        if (!IS_COUNTRY_IE_VALID(ieee))
                        {
-                               Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
+                               dot11d_update_country_ie(ieee, addr2, info_element->len, info_element->data);
                        }
                }
 
@@ -1944,7 +1944,7 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
                                        {
                                                network->bMBssidValid = true;
                                                network->MBssidMask = 0xff << (network->MBssidMask);
-                                               cpMacAddr(network->MBssid, network->bssid);
+                                               ether_addr_copy(network->MBssid, network->bssid);
                                                network->MBssid[5] &= network->MBssidMask;
                                        }
                                        else
@@ -2439,7 +2439,7 @@ static inline void ieee80211_process_probe_response(
        //       then wireless adapter should do active scan from ch1~11 and
        //       passive scan from ch12~14
 
-       if (!IsLegalChannel(ieee, network->channel))
+       if (!is_legal_channel(ieee, network->channel))
                goto out;
        if (ieee->bGlobalDomain)
        {
@@ -2448,7 +2448,7 @@ static inline void ieee80211_process_probe_response(
                        // Case 1: Country code
                        if(IS_COUNTRY_IE_VALID(ieee) )
                        {
-                               if (!IsLegalChannel(ieee, network->channel)) {
+                               if (!is_legal_channel(ieee, network->channel)) {
                                        printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network->channel);
                                        goto out;
                                }
@@ -2469,7 +2469,7 @@ static inline void ieee80211_process_probe_response(
                        // Case 1: Country code
                        if(IS_COUNTRY_IE_VALID(ieee) )
                        {
-                               if (!IsLegalChannel(ieee, network->channel)) {
+                               if (!is_legal_channel(ieee, network->channel)) {
                                        printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network->channel);
                                        goto out;
                                }
index 212cc9ccbb9651bc65991e3d1cc012996f8fccbb..8635faf84316880297b10d9cbc7e4f7b5f106e7b 100644 (file)
@@ -464,7 +464,7 @@ out:
        } else {
                ieee->sync_scan_hurryup = 0;
                if (IS_DOT11D_ENABLE(ieee))
-                       DOT11D_ScanComplete(ieee);
+                       dot11d_scan_complete(ieee);
                mutex_unlock(&ieee->scan_mutex);
        }
 }
@@ -504,7 +504,7 @@ static void ieee80211_softmac_scan_wq(struct work_struct *work)
        return;
 out:
        if (IS_DOT11D_ENABLE(ieee))
-               DOT11D_ScanComplete(ieee);
+               dot11d_scan_complete(ieee);
        ieee->actscanning = false;
        watchdog = 0;
        ieee->scanning = 0;
@@ -2357,7 +2357,7 @@ void ieee80211_disassociate(struct ieee80211_device *ieee)
        if (ieee->data_hard_stop)
                ieee->data_hard_stop(ieee->dev);
        if (IS_DOT11D_ENABLE(ieee))
-               Dot11d_Reset(ieee);
+               dot11d_reset(ieee);
        ieee->state = IEEE80211_NOLINK;
        ieee->is_set_key = false;
        ieee->link_change(ieee->dev);
@@ -2542,8 +2542,8 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
        for (i = 0; i < 5; i++)
                ieee->seq_ctrl[i] = 0;
 
-       ieee->pDot11dInfo = kzalloc(sizeof(struct rt_dot11d_info), GFP_KERNEL);
-       if (!ieee->pDot11dInfo)
+       ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_KERNEL);
+       if (!ieee->dot11d_info)
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
        //added for  AP roaming
        ieee->LinkDetectInfo.SlotNum = 2;
@@ -2603,8 +2603,8 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 void ieee80211_softmac_free(struct ieee80211_device *ieee)
 {
        mutex_lock(&ieee->wx_mutex);
-       kfree(ieee->pDot11dInfo);
-       ieee->pDot11dInfo = NULL;
+       kfree(ieee->dot11d_info);
+       ieee->dot11d_info = NULL;
        del_timer_sync(&ieee->associate_timer);
 
        cancel_delayed_work(&ieee->associate_retry_wq);
index cc4049de975d4c890908e4f48c2bb1fe1013fecc..024fa270254640179871e7dce5649e1c2ad53a96 100644 (file)
@@ -335,14 +335,14 @@ static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee,
                        printk("===>can't get TS\n");
                        return;
                }
-               if (!pTxTs->tx_admitted_ba_record.bValid)
+               if (!pTxTs->tx_admitted_ba_record.valid)
                {
                        TsStartAddBaProcess(ieee, pTxTs);
                        goto FORCED_AGG_SETTING;
                }
                else if (!pTxTs->using_ba)
                {
-                       if (SN_LESS(pTxTs->tx_admitted_ba_record.BaStartSeqCtrl.field.SeqNum, (pTxTs->tx_cur_seq + 1) % 4096))
+                       if (SN_LESS(pTxTs->tx_admitted_ba_record.start_seq_ctrl.field.seq_num, (pTxTs->tx_cur_seq + 1) % 4096))
                                pTxTs->using_ba = true;
                        else
                                goto FORCED_AGG_SETTING;
index f2fcdec9bd17be3c164178ca3c7685f925dc3f38..fa59c712c74bf6ae12baaf6d1acc321a1afb85bd 100644 (file)
@@ -147,13 +147,13 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 
        if (network->mode >= IEEE_N_24G)//add N rate here;
        {
-               PHT_CAPABILITY_ELE ht_cap = NULL;
+               struct ht_capability_ele *ht_cap = NULL;
                bool is40M = false, isShortGI = false;
                u8 max_mcs = 0;
                if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
-                       ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
+                       ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[4];
                else
-                       ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
+                       ht_cap = (struct ht_capability_ele *)&network->bssht.bdHTCapBuf[0];
                is40M = (ht_cap->ChlWidth)?1:0;
                isShortGI = (ht_cap->ChlWidth)?
                                                ((ht_cap->ShortGI40Mhz)?1:0):
index b6a76aae4832f7b5d615fbba04c43aee917c5d13..1a727856ba53c65a9aae6f5ebfd11a0bd0dad26c 100644 (file)
@@ -2,67 +2,53 @@
 #ifndef _BATYPE_H_
 #define _BATYPE_H_
 
-#define                TOTAL_TXBA_NUM  16
-#define        TOTAL_RXBA_NUM  16
+#define        BA_SETUP_TIMEOUT               200
 
-#define        BA_SETUP_TIMEOUT        200
-#define        BA_INACT_TIMEOUT        60000
+#define        BA_POLICY_DELAYED                0
+#define        BA_POLICY_IMMEDIATE              1
 
-#define        BA_POLICY_DELAYED               0
-#define        BA_POLICY_IMMEDIATE     1
-
-#define        ADDBA_STATUS_SUCCESS                    0
+#define        ADDBA_STATUS_SUCCESS             0
 #define        ADDBA_STATUS_REFUSED            37
 #define        ADDBA_STATUS_INVALID_PARAM      38
 
-#define        DELBA_REASON_QSTA_LEAVING       36
-#define        DELBA_REASON_END_BA                     37
-#define        DELBA_REASON_UNKNOWN_BA 38
-#define        DELBA_REASON_TIMEOUT                    39
-/*  whether need define BA Action frames here?
-struct ieee80211_ADDBA_Req{
-       struct ieee80211_header_data header;
-       u8      category;
-       u8
-} __attribute__ ((packed));
-*/
-//Is this need?I put here just to make it easier to define structure BA_RECORD //WB
-typedef union _SEQUENCE_CONTROL{
-       u16 ShortData;
+#define        DELBA_REASON_END_BA             37
+#define        DELBA_REASON_UNKNOWN_BA         38
+#define        DELBA_REASON_TIMEOUT            39
+
+union sequence_control {
+       u16 short_data;
        struct {
-               u16     FragNum:4;
-               u16     SeqNum:12;
+               u16     frag_num:4;
+               u16     seq_num:12;
        } field;
-} SEQUENCE_CONTROL, *PSEQUENCE_CONTROL;
+};
 
-typedef union _BA_PARAM_SET {
-       u8 charData[2];
-       u16 shortData;
+union ba_param_set {
+       u16 short_data;
        struct {
-               u16 AMSDU_Support:1;
-               u16 BAPolicy:1;
-               u16 TID:4;
-               u16 BufferSize:10;
+               u16     amsdu_support:1;
+               u16     ba_policy:1;
+               u16     tid:4;
+               u16     buffer_size:10;
        } field;
-} BA_PARAM_SET, *PBA_PARAM_SET;
+};
 
-typedef union _DELBA_PARAM_SET {
-       u8 charData[2];
-       u16 shortData;
+union delba_param_set {
+       u16 short_data;
        struct {
-               u16 Reserved:11;
-               u16 Initiator:1;
-               u16 TID:4;
+               u16     reserved:11;
+               u16     initiator:1;
+               u16     tid:4;
        } field;
-} DELBA_PARAM_SET, *PDELBA_PARAM_SET;
-
-typedef struct _BA_RECORD {
-       struct timer_list               Timer;
-       u8                              bValid;
-       u8                              DialogToken;
-       BA_PARAM_SET            BaParamSet;
-       u16                             BaTimeoutValue;
-       SEQUENCE_CONTROL        BaStartSeqCtrl;
-} BA_RECORD, *PBA_RECORD;
+};
+
+struct ba_record {
+       struct timer_list       timer;
+       u8                      valid;
+       u8                      dialog_token;
+       union ba_param_set      param_set;
+       u16                     timeout_value;
+       union sequence_control  start_seq_ctrl;
+};
 
 #endif //end _BATYPE_H_
index 01b631c2a18087299110e618dc995e99800e0402..109445407cecb2f5a490b8b6450fa35e0e5c14ca 100644 (file)
 
 /********************************************************************************************************************
  *function:  Activate BA entry. And if Time is nozero, start timer.
- *   input:  PBA_RECORD                        pBA  //BA entry to be enabled
+ *   input:  struct ba_record          *pBA  //BA entry to be enabled
  *          u16                        Time //indicate time delay.
  *  output:  none
  ********************************************************************************************************************/
-static void ActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA, u16 Time)
+static void ActivateBAEntry(struct ieee80211_device *ieee, struct ba_record *pBA, u16 Time)
 {
-       pBA->bValid = true;
+       pBA->valid = true;
        if (Time != 0)
-               mod_timer(&pBA->Timer, jiffies + msecs_to_jiffies(Time));
+               mod_timer(&pBA->timer, jiffies + msecs_to_jiffies(Time));
 }
 
 /********************************************************************************************************************
  *function:  deactivate BA entry, including its timer.
- *   input:  PBA_RECORD                        pBA  //BA entry to be disabled
+ *   input:  struct ba_record       *pBA  //BA entry to be disabled
  *  output:  none
  ********************************************************************************************************************/
-static void DeActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA)
+static void DeActivateBAEntry(struct ieee80211_device *ieee, struct ba_record *pBA)
 {
-       pBA->bValid = false;
-       del_timer_sync(&pBA->Timer);
+       pBA->valid = false;
+       del_timer_sync(&pBA->timer);
 }
 /********************************************************************************************************************
  *function: deactivete BA entry in Tx Ts, and send DELBA.
@@ -42,18 +42,18 @@ static void DeActivateBAEntry(struct ieee80211_device *ieee, PBA_RECORD pBA)
  ********************************************************************************************************************/
 static u8 TxTsDeleteBA(struct ieee80211_device *ieee, struct tx_ts_record *pTxTs)
 {
-       PBA_RECORD              pAdmittedBa = &pTxTs->tx_admitted_ba_record;  //These two BA entries must exist in TS structure
-       PBA_RECORD              pPendingBa = &pTxTs->tx_pending_ba_record;
+       struct ba_record *pAdmittedBa = &pTxTs->tx_admitted_ba_record;  //These two BA entries must exist in TS structure
+       struct ba_record *pPendingBa = &pTxTs->tx_pending_ba_record;
        u8                      bSendDELBA = false;
 
        // Delete pending BA
-       if (pPendingBa->bValid) {
+       if (pPendingBa->valid) {
                DeActivateBAEntry(ieee, pPendingBa);
                bSendDELBA = true;
        }
 
        // Delete admitted BA
-       if (pAdmittedBa->bValid) {
+       if (pAdmittedBa->valid) {
                DeActivateBAEntry(ieee, pAdmittedBa);
                bSendDELBA = true;
        }
@@ -70,10 +70,10 @@ static u8 TxTsDeleteBA(struct ieee80211_device *ieee, struct tx_ts_record *pTxTs
  ********************************************************************************************************************/
 static u8 RxTsDeleteBA(struct ieee80211_device *ieee, struct rx_ts_record *pRxTs)
 {
-       PBA_RECORD              pBa = &pRxTs->rx_admitted_ba_record;
+       struct ba_record       *pBa = &pRxTs->rx_admitted_ba_record;
        u8                      bSendDELBA = false;
 
-       if (pBa->bValid) {
+       if (pBa->valid) {
                DeActivateBAEntry(ieee, pBa);
                bSendDELBA = true;
        }
@@ -84,28 +84,28 @@ static u8 RxTsDeleteBA(struct ieee80211_device *ieee, struct rx_ts_record *pRxTs
 /********************************************************************************************************************
  *function: reset BA entry
  *   input:
- *          PBA_RECORD         pBA //entry to be reset
+ *          struct ba_record *pBA //entry to be reset
  *  output:  none
  ********************************************************************************************************************/
-void ResetBaEntry(PBA_RECORD pBA)
+void ResetBaEntry(struct ba_record *pBA)
 {
-       pBA->bValid                     = false;
-       pBA->BaParamSet.shortData       = 0;
-       pBA->BaTimeoutValue             = 0;
-       pBA->DialogToken                = 0;
-       pBA->BaStartSeqCtrl.ShortData   = 0;
+       pBA->valid                      = false;
+       pBA->param_set.short_data       = 0;
+       pBA->timeout_value              = 0;
+       pBA->dialog_token               = 0;
+       pBA->start_seq_ctrl.short_data  = 0;
 }
 //These functions need porting here or not?
 /*******************************************************************************************************************************
  *function:  construct ADDBAREQ and ADDBARSP frame here together.
  *   input:  u8*               Dst     //ADDBA frame's destination
- *          PBA_RECORD         pBA     //BA_RECORD entry which stores the necessary information for BA.
+ *          struct ba_record  *pBA     //BA_RECORD entry which stores the necessary information for BA.
  *          u16                StatusCode  //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
  *          u8                 type    //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
  *  output:  none
  *  return:  sk_buff*          skb     //return constructed skb to xmit
  *******************************************************************************************************************************/
-static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
+static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, struct ba_record *pBA, u16 StatusCode, u8 type)
 {
        struct sk_buff *skb = NULL;
         struct rtl_80211_hdr_3addr *BAReq = NULL;
@@ -140,7 +140,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
        *tag++ = ACT_CAT_BA;
        *tag++ = type;
        // Dialog Token
-       *tag++ = pBA->DialogToken;
+       *tag++ = pBA->dialog_token;
 
        if (ACT_ADDBARSP == type) {
                // Status Code
@@ -151,16 +151,16 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
        }
        // BA Parameter Set
 
-       put_unaligned_le16(pBA->BaParamSet.shortData, tag);
+       put_unaligned_le16(pBA->param_set.short_data, tag);
        tag += 2;
        // BA Timeout Value
 
-       put_unaligned_le16(pBA->BaTimeoutValue, tag);
+       put_unaligned_le16(pBA->timeout_value, tag);
        tag += 2;
 
        if (ACT_ADDBAREQ == type) {
        // BA Start SeqCtrl
-               memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2);
+               memcpy(tag, (u8 *)&(pBA->start_seq_ctrl), 2);
                tag += 2;
        }
 
@@ -173,7 +173,7 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
 /********************************************************************************************************************
  *function:  construct DELBA frame
  *   input:  u8*               dst     //DELBA frame's destination
- *          PBA_RECORD         pBA     //BA_RECORD entry which stores the necessary information for BA
+ *          struct ba_record  *pBA     //BA_RECORD entry which stores the necessary information for BA
  *          enum tr_select     TxRxSelect  //TX RX direction
  *          u16                ReasonCode  //status code.
  *  output:  none
@@ -182,12 +182,12 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
 static struct sk_buff *ieee80211_DELBA(
        struct ieee80211_device  *ieee,
        u8                       *dst,
-       PBA_RECORD               pBA,
+       struct ba_record         *pBA,
        enum tr_select           TxRxSelect,
        u16                      ReasonCode
        )
 {
-       DELBA_PARAM_SET DelbaParamSet;
+       union delba_param_set   DelbaParamSet;
        struct sk_buff *skb = NULL;
         struct rtl_80211_hdr_3addr *Delba = NULL;
        u8 *tag = NULL;
@@ -201,8 +201,8 @@ static struct sk_buff *ieee80211_DELBA(
 
        memset(&DelbaParamSet, 0, 2);
 
-       DelbaParamSet.field.Initiator   = (TxRxSelect == TX_DIR) ? 1 : 0;
-       DelbaParamSet.field.TID = pBA->BaParamSet.field.TID;
+       DelbaParamSet.field.initiator   = (TxRxSelect == TX_DIR) ? 1 : 0;
+       DelbaParamSet.field.tid = pBA->param_set.field.tid;
 
        skb = dev_alloc_skb(len + sizeof(struct rtl_80211_hdr_3addr)); //need to add something others? FIXME
        if (!skb) {
@@ -226,7 +226,7 @@ static struct sk_buff *ieee80211_DELBA(
 
        // DELBA Parameter Set
 
-       put_unaligned_le16(DelbaParamSet.shortData, tag);
+       put_unaligned_le16(DelbaParamSet.short_data, tag);
        tag += 2;
        // Reason Code
 
@@ -243,12 +243,12 @@ static struct sk_buff *ieee80211_DELBA(
 /********************************************************************************************************************
  *function: send ADDBAReq frame out
  *   input:  u8*               dst     //ADDBAReq frame's destination
- *          PBA_RECORD         pBA     //BA_RECORD entry which stores the necessary information for BA
+ *          struct ba_record  *pBA     //BA_RECORD entry which stores the necessary information for BA
  *  output:  none
  *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
  ********************************************************************************************************************/
 static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee,
-                                   u8 *dst, PBA_RECORD pBA)
+                                   u8 *dst, struct ba_record *pBA)
 {
        struct sk_buff *skb;
        skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
@@ -266,13 +266,13 @@ static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee,
 /********************************************************************************************************************
  *function: send ADDBARSP frame out
  *   input:  u8*               dst     //DELBA frame's destination
- *          PBA_RECORD         pBA     //BA_RECORD entry which stores the necessary information for BA
+ *          struct ba_record  *pBA     //BA_RECORD entry which stores the necessary information for BA
  *          u16                StatusCode //RSP StatusCode
  *  output:  none
  *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
  ********************************************************************************************************************/
 static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst,
-                                   PBA_RECORD pBA, u16 StatusCode)
+                                   struct ba_record *pBA, u16 StatusCode)
 {
        struct sk_buff *skb;
        skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
@@ -289,7 +289,7 @@ static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst,
 /********************************************************************************************************************
  *function: send ADDBARSP frame out
  *   input:  u8*               dst     //DELBA frame's destination
- *          PBA_RECORD         pBA     //BA_RECORD entry which stores the necessary information for BA
+ *          struct ba_record  *pBA     //BA_RECORD entry which stores the necessary information for BA
  *          enum tr_select     TxRxSelect //TX or RX
  *          u16                ReasonCode //DEL ReasonCode
  *  output:  none
@@ -297,7 +297,7 @@ static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst,
  ********************************************************************************************************************/
 
 static void ieee80211_send_DELBA(struct ieee80211_device *ieee, u8 *dst,
-                                PBA_RECORD pBA, enum tr_select TxRxSelect,
+                                struct ba_record *pBA, enum tr_select TxRxSelect,
                                 u16 ReasonCode)
 {
        struct sk_buff *skb;
@@ -321,10 +321,10 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
         struct rtl_80211_hdr_3addr *req = NULL;
        u16 rc = 0;
        u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
-       PBA_RECORD pBA = NULL;
-       PBA_PARAM_SET   pBaParamSet = NULL;
+       struct ba_record *pBA = NULL;
+       union ba_param_set     *pBaParamSet = NULL;
        u16 *pBaTimeoutVal = NULL;
-       PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
+       union sequence_control *pBaStartSeqCtrl = NULL;
        struct rx_ts_record  *pTS = NULL;
 
        if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 9) {
@@ -342,9 +342,9 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
        dst = &req->addr2[0];
        tag += sizeof(struct rtl_80211_hdr_3addr);
        pDialogToken = tag + 2;  //category+action
-       pBaParamSet = (PBA_PARAM_SET)(tag + 3);   //+DialogToken
+       pBaParamSet = (union ba_param_set *)(tag + 3);   //+DialogToken
        pBaTimeoutVal = (u16 *)(tag + 5);
-       pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
+       pBaStartSeqCtrl = (union sequence_control *)(req + 7);
 
        netdev_info(ieee->dev, "====================>rx ADDBAREQ from :%pM\n", dst);
 //some other capability is not ready now.
@@ -362,7 +362,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
                        ieee,
                        (struct ts_common_info **)(&pTS),
                        dst,
-                       (u8)(pBaParamSet->field.TID),
+                       (u8)(pBaParamSet->field.tid),
                        RX_DIR,
                        true)) {
                rc = ADDBA_STATUS_REFUSED;
@@ -371,10 +371,10 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
        }
        pBA = &pTS->rx_admitted_ba_record;
        // To Determine the ADDBA Req content
-       // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
+       // We can do much more check here, including buffer_size, AMSDU_Support, Policy, StartSeqCtrl...
        // I want to check StartSeqCtrl to make sure when we start aggregation!!!
        //
-       if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) {
+       if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
                rc = ADDBA_STATUS_INVALID_PARAM;
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __func__);
                goto OnADDBAReq_Fail;
@@ -382,16 +382,16 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
                // Admit the ADDBA Request
        //
        DeActivateBAEntry(ieee, pBA);
-       pBA->DialogToken = *pDialogToken;
-       pBA->BaParamSet = *pBaParamSet;
-       pBA->BaTimeoutValue = *pBaTimeoutVal;
-       pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
+       pBA->dialog_token = *pDialogToken;
+       pBA->param_set = *pBaParamSet;
+       pBA->timeout_value = *pBaTimeoutVal;
+       pBA->start_seq_ctrl = *pBaStartSeqCtrl;
        //for half N mode we only aggregate 1 frame
        if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
-       pBA->BaParamSet.field.BufferSize = 1;
+       pBA->param_set.field.buffer_size = 1;
        else
-       pBA->BaParamSet.field.BufferSize = 32;
-       ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue);
+       pBA->param_set.field.buffer_size = 32;
+       ActivateBAEntry(ieee, pBA, pBA->timeout_value);
        ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
 
        // End of procedure.
@@ -399,11 +399,11 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
 
 OnADDBAReq_Fail:
        {
-               BA_RECORD       BA;
-               BA.BaParamSet = *pBaParamSet;
-               BA.BaTimeoutValue = *pBaTimeoutVal;
-               BA.DialogToken = *pDialogToken;
-               BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
+               struct ba_record        BA;
+               BA.param_set = *pBaParamSet;
+               BA.timeout_value = *pBaTimeoutVal;
+               BA.dialog_token = *pDialogToken;
+               BA.param_set.field.ba_policy = BA_POLICY_IMMEDIATE;
                ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
                return 0; //we send RSP out.
        }
@@ -419,11 +419,11 @@ OnADDBAReq_Fail:
 int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
         struct rtl_80211_hdr_3addr *rsp = NULL;
-       PBA_RECORD              pPendingBA, pAdmittedBA;
+       struct ba_record        *pPendingBA, *pAdmittedBA;
        struct tx_ts_record     *pTS = NULL;
        u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL;
        u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL;
-       PBA_PARAM_SET           pBaParamSet = NULL;
+       union ba_param_set       *pBaParamSet = NULL;
        u16                     ReasonCode;
 
        if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 9) {
@@ -439,7 +439,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
        tag += sizeof(struct rtl_80211_hdr_3addr);
        pDialogToken = tag + 2;
        pStatusCode = (u16 *)(tag + 3);
-       pBaParamSet = (PBA_PARAM_SET)(tag + 5);
+       pBaParamSet = (union ba_param_set *)(tag + 5);
        pBaTimeoutVal = (u16 *)(tag + 7);
 
        // Check the capability
@@ -461,7 +461,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
                        ieee,
                        (struct ts_common_info **)(&pTS),
                        dst,
-                       (u8)(pBaParamSet->field.TID),
+                       (u8)(pBaParamSet->field.tid),
                        TX_DIR,
                        false)) {
                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __func__);
@@ -478,11 +478,11 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
        // Check if related BA is waiting for setup.
        // If not, reject by sending DELBA frame.
        //
-       if (pAdmittedBA->bValid) {
+       if (pAdmittedBA->valid) {
                // Since BA is already setup, we ignore all other ADDBA Response.
                IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
                return -1;
-       } else if ((!pPendingBA->bValid) || (*pDialogToken != pPendingBA->DialogToken)) {
+       } else if ((!pPendingBA->valid) || (*pDialogToken != pPendingBA->dialog_token)) {
                IEEE80211_DEBUG(IEEE80211_DL_ERR,  "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
                ReasonCode = DELBA_REASON_UNKNOWN_BA;
                goto OnADDBARsp_Reject;
@@ -498,7 +498,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
                // We can compare the value of BA parameter set that Peer returned and Self sent.
                // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
                //
-               if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) {
+               if (pBaParamSet->field.ba_policy == BA_POLICY_DELAYED) {
                        // Since this is a kind of ADDBA failed, we delay next ADDBA process.
                        pTS->add_ba_req_delayed = true;
                        DeActivateBAEntry(ieee, pAdmittedBA);
@@ -510,10 +510,10 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
                //
                // Admitted condition
                //
-               pAdmittedBA->DialogToken = *pDialogToken;
-               pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
-               pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
-               pAdmittedBA->BaParamSet = *pBaParamSet;
+               pAdmittedBA->dialog_token = *pDialogToken;
+               pAdmittedBA->timeout_value = *pBaTimeoutVal;
+               pAdmittedBA->start_seq_ctrl = pPendingBA->start_seq_ctrl;
+               pAdmittedBA->param_set = *pBaParamSet;
                DeActivateBAEntry(ieee, pAdmittedBA);
                ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
        } else {
@@ -526,8 +526,8 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
 
 OnADDBARsp_Reject:
        {
-               BA_RECORD       BA;
-               BA.BaParamSet = *pBaParamSet;
+               struct ba_record        BA;
+               BA.param_set = *pBaParamSet;
                ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
                return 0;
        }
@@ -543,7 +543,7 @@ OnADDBARsp_Reject:
 int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
         struct rtl_80211_hdr_3addr *delba = NULL;
-       PDELBA_PARAM_SET        pDelBaParamSet = NULL;
+       union delba_param_set   *pDelBaParamSet = NULL;
        u8                      *dst = NULL;
 
        if (skb->len < sizeof(struct rtl_80211_hdr_3addr) + 6) {
@@ -563,16 +563,16 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb)
        IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
        delba = (struct rtl_80211_hdr_3addr *)skb->data;
        dst = &delba->addr2[0];
-       pDelBaParamSet = (PDELBA_PARAM_SET)&delba->payload[2];
+       pDelBaParamSet = (union delba_param_set *)&delba->payload[2];
 
-       if (pDelBaParamSet->field.Initiator == 1) {
+       if (pDelBaParamSet->field.initiator == 1) {
                struct rx_ts_record *pRxTs;
 
                if (!GetTs(
                                ieee,
                                (struct ts_common_info **)&pRxTs,
                                dst,
-                               (u8)pDelBaParamSet->field.TID,
+                               (u8)pDelBaParamSet->field.tid,
                                RX_DIR,
                                false)) {
                        IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for RXTS in %s()\n", __func__);
@@ -587,7 +587,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb)
                        ieee,
                        (struct ts_common_info **)&pTxTs,
                        dst,
-                       (u8)pDelBaParamSet->field.TID,
+                       (u8)pDelBaParamSet->field.tid,
                        TX_DIR,
                        false)) {
                        IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for TXTS in %s()\n", __func__);
@@ -615,22 +615,22 @@ TsInitAddBA(
        u8              bOverwritePending
        )
 {
-       PBA_RECORD                      pBA = &pTS->tx_pending_ba_record;
+       struct ba_record *pBA = &pTS->tx_pending_ba_record;
 
-       if (pBA->bValid && !bOverwritePending)
+       if (pBA->valid && !bOverwritePending)
                return;
 
        // Set parameters to "Pending" variable set
        DeActivateBAEntry(ieee, pBA);
 
-       pBA->DialogToken++;                                             // DialogToken: Only keep the latest dialog token
-       pBA->BaParamSet.field.AMSDU_Support = 0;        // Do not support A-MSDU with A-MPDU now!!
-       pBA->BaParamSet.field.BAPolicy = Policy;        // Policy: Delayed or Immediate
-       pBA->BaParamSet.field.TID = pTS->ts_common_info.t_spec.ts_info.uc_tsid; // TID
-       // BufferSize: This need to be set according to A-MPDU vector
-       pBA->BaParamSet.field.BufferSize = 32;          // BufferSize: This need to be set according to A-MPDU vector
-       pBA->BaTimeoutValue = 0;                                        // Timeout value: Set 0 to disable Timer
-       pBA->BaStartSeqCtrl.field.SeqNum = (pTS->tx_cur_seq + 3) % 4096;        // Block Ack will start after 3 packets later.
+       pBA->dialog_token++;                                            // DialogToken: Only keep the latest dialog token
+       pBA->param_set.field.amsdu_support = 0; // Do not support A-MSDU with A-MPDU now!!
+       pBA->param_set.field.ba_policy = Policy;        // Policy: Delayed or Immediate
+       pBA->param_set.field.tid = pTS->ts_common_info.t_spec.ts_info.uc_tsid;  // TID
+       // buffer_size: This need to be set according to A-MPDU vector
+       pBA->param_set.field.buffer_size = 32;          // buffer_size: This need to be set according to A-MPDU vector
+       pBA->timeout_value = 0;                                 // Timeout value: Set 0 to disable Timer
+       pBA->start_seq_ctrl.field.seq_num = (pTS->tx_cur_seq + 3) % 4096;       // Block Ack will start after 3 packets later.
 
        ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
 
@@ -647,7 +647,7 @@ TsInitDelBA(struct ieee80211_device *ieee, struct ts_common_info *pTsCommonInfo,
                        ieee80211_send_DELBA(
                                ieee,
                                pTsCommonInfo->addr,
-                               (pTxTs->tx_admitted_ba_record.bValid)?(&pTxTs->tx_admitted_ba_record):(&pTxTs->tx_pending_ba_record),
+                               (pTxTs->tx_admitted_ba_record.valid)?(&pTxTs->tx_admitted_ba_record):(&pTxTs->tx_pending_ba_record),
                                TxRxSelect,
                                DELBA_REASON_END_BA);
        } else if (TxRxSelect == RX_DIR) {
@@ -669,16 +669,16 @@ TsInitDelBA(struct ieee80211_device *ieee, struct ts_common_info *pTsCommonInfo,
  ********************************************************************************************************************/
 void BaSetupTimeOut(struct timer_list *t)
 {
-       struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_pending_ba_record.Timer);
+       struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_pending_ba_record.timer);
 
        pTxTs->add_ba_req_in_progress = false;
        pTxTs->add_ba_req_delayed = true;
-       pTxTs->tx_pending_ba_record.bValid = false;
+       pTxTs->tx_pending_ba_record.valid = false;
 }
 
 void TxBaInactTimeout(struct timer_list *t)
 {
-       struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_admitted_ba_record.Timer);
+       struct tx_ts_record *pTxTs = from_timer(pTxTs, t, tx_admitted_ba_record.timer);
        struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
        TxTsDeleteBA(ieee, pTxTs);
        ieee80211_send_DELBA(
@@ -691,7 +691,7 @@ void TxBaInactTimeout(struct timer_list *t)
 
 void RxBaInactTimeout(struct timer_list *t)
 {
-       struct rx_ts_record *pRxTs = from_timer(pRxTs, t, rx_admitted_ba_record.Timer);
+       struct rx_ts_record *pRxTs = from_timer(pRxTs, t, rx_admitted_ba_record.timer);
        struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
 
        RxTsDeleteBA(ieee, pRxTs);
index 7d54a7cd951489080b3b7b72258b094e945bca24..64d5359cf7e280897e0a5d377682fdd81b2b0173 100644 (file)
@@ -2,40 +2,34 @@
 #ifndef _RTL819XU_HTTYPE_H_
 #define _RTL819XU_HTTYPE_H_
 
-//------------------------------------------------------------
-// The HT Capability element is present in beacons, association request,
-//     reassociation request and probe response frames
-//------------------------------------------------------------
-
-//
-// MIMO Power Save Settings
-//
-#define MIMO_PS_STATIC                         0
-
-//
-//     There should be 128 bits to cover all of the MCS rates. However, since
-//     8190 does not support too much rates, one integer is quite enough.
-//
-
-#define sHTCLng        4
+/*
+ * The HT Capability element is present in beacons, association request,
+ * reassociation request and probe response frames
+ */
 
+/*
+ * MIMO Power Save Settings
+ */
+#define MIMO_PS_STATIC                         0
 
-#define HT_SUPPORTED_MCS_1SS_BITMAP                                    0x000000ff
-#define HT_SUPPORTED_MCS_2SS_BITMAP                                    0x0000ff00
-#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP                        HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+/*
+ * There should be 128 bits to cover all of the MCS rates. However, since
+ * 8190 does not support too much rates, one integer is quite enough.
+ */
+#define HTCLNG 4
 
-//
-// Represent Channel Width in HT Capabilities
-//
+/*
+ * Represent Channel Width in HT Capabilities
+ */
 enum ht_channel_width {
        HT_CHANNEL_WIDTH_20 = 0,
        HT_CHANNEL_WIDTH_20_40 = 1,
 };
 
-//
-// Represent Extension Channel Offset in HT Capabilities
-// This is available only in 40Mhz mode.
-//
+/*
+ * Represent Extension Channel Offset in HT Capabilities
+ * This is available only in 40Mhz mode.
+ */
 enum ht_extension_chan_offset {
        HT_EXTCHNL_OFFSET_NO_EXT = 0,
        HT_EXTCHNL_OFFSET_UPPER = 1,
@@ -43,53 +37,7 @@ enum ht_extension_chan_offset {
        HT_EXTCHNL_OFFSET_LOWER = 3,
 };
 
-typedef enum _CHNLOP {
-       CHNLOP_NONE = 0, // No Action now
-       CHNLOP_SCAN = 1, // Scan in progress
-       CHNLOP_SWBW = 2, // Bandwidth switching in progress
-       CHNLOP_SWCHNL = 3, // Software Channel switching in progress
-} CHNLOP, *PCHNLOP;
-
-// Determine if the Channel Operation is in progress
-#define CHHLOP_IN_PROGRESS(_pHTInfo)   \
-               ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
-
-/*
-typedef        union _HT_CAPABILITY{
-       u16     ShortData;
-       u8      CharData[2];
-       struct
-       {
-               u16     AdvCoding:1;
-               u16     ChlWidth:1;
-               u16     MimoPwrSave:2;
-               u16     GreenField:1;
-               u16     ShortGI20Mhz:1;
-               u16     ShortGI40Mhz:1;
-               u16     STBC:1;
-               u16     BeamForm:1;
-               u16     DelayBA:1;
-               u16     MaxAMSDUSize:1;
-               u16     DssCCk:1;
-               u16     PSMP:1;
-               u16     Rsvd:3;
-       }Field;
-}HT_CAPABILITY, *PHT_CAPABILITY;
-
-typedef        union _HT_CAPABILITY_MACPARA{
-       u8      ShortData;
-       u8      CharData[1];
-       struct
-       {
-               u8      MaxRxAMPDU:2;
-               u8      MPDUDensity:2;
-               u8      Rsvd:4;
-       }Field;
-}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA;
-*/
-
-typedef        struct _HT_CAPABILITY_ELE {
-
+struct ht_capability_ele {
        //HT capability info
        u8      AdvCoding:1;
        u8      ChlWidth:1;
@@ -114,7 +62,6 @@ typedef      struct _HT_CAPABILITY_ELE {
        //Supported MCS set
        u8      MCS[16];
 
-
        //Extended HT Capability Info
        u16     ExtHTCapInfo;
 
@@ -124,13 +71,12 @@ typedef    struct _HT_CAPABILITY_ELE {
        //Antenna Selection Capabilities
        u8      ASCap;
 
-} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
-
-//------------------------------------------------------------
-// The HT Information element is present in beacons
-// Only AP is required to include this element
-//------------------------------------------------------------
+} __packed;
 
+/*
+ * The HT Information element is present in beacons
+ * Only AP is required to include this element
+ */
 typedef struct _HT_INFORMATION_ELE {
        u8      ControlChl;
 
@@ -169,12 +115,11 @@ typedef enum _HT_AGGRE_MODE_E {
        HT_AGG_FORCE_DISABLE = 2,
 }HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
 
-//------------------------------------------------------------
-//  The Data structure is used to keep HT related variables when card is
-//  configured as non-AP STA mode.  **Note**  Current_xxx should be set
-//     to default value in HTInitializeHTInfo()
-//------------------------------------------------------------
-
+/*
+ *  The Data structure is used to keep HT related variables when card is
+ *  configured as non-AP STA mode.  **Note**  Current_xxx should be set
+ *  to default value in HTInitializeHTInfo()
+ */
 typedef struct _RT_HIGH_THROUGHPUT {
        u8                              bEnableHT;
        u8                              bCurrentHTSupport;
@@ -194,23 +139,20 @@ typedef struct _RT_HIGH_THROUGHPUT {
        // 802.11n spec version for "peer"
        HT_SPEC_VER                     ePeerHTSpecVer;
 
-
        // HT related information for "Self"
-       HT_CAPABILITY_ELE       SelfHTCap;              // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
+       struct ht_capability_ele        SelfHTCap;              // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
        HT_INFORMATION_ELE      SelfHTInfo;             // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
 
        // HT related information for "Peer"
        u8                              PeerHTCapBuf[32];
        u8                              PeerHTInfoBuf[32];
 
-
        // A-MSDU related
        u8                              bAMSDU_Support;                 // This indicates Tx A-MSDU capability
        u16                             nAMSDU_MaxSize;                 // This indicates Tx A-MSDU capability
        u8                              bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
        u16                             nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
 
-
        // AMPDU  related <2006.08.10 Emily>
        u8                              bAMPDUEnable;                           // This indicate Tx A-MPDU capability
        u8                              bCurrentAMPDUEnable;            // This indicate Tx A-MPDU capability
@@ -243,7 +185,6 @@ typedef struct _RT_HIGH_THROUGHPUT {
 
        // For Bandwidth Switching
        u8                              bSwBwInProgress;
-       CHNLOP                          ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
        u8                              SwBwStep;
        //struct timer_list             SwBwTimer;  //moved to ieee80211_device. as timer_list need include some header file here.
 
@@ -278,13 +219,11 @@ typedef struct _RT_HIGH_THROUGHPUT {
        u32                             IOTAction;
 } __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
 
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each AP"
-// when card is configured as "STA mode"
-//------------------------------------------------------------
-
+/*
+ * The Data structure is used to keep HT related variable for "each AP"
+ * when card is configured as "STA mode"
+ */
 typedef struct _BSS_HT {
-
        u8                              bdSupportHT;
 
        // HT related elements
@@ -294,7 +233,7 @@ typedef struct _BSS_HT {
        u16                                     bdHTInfoLen;
 
        HT_SPEC_VER                             bdHTSpecVer;
-       //HT_CAPABILITY_ELE                     bdHTCapEle;
+       //struct ht_capability_ele              bdHTCapEle;
        //HT_INFORMATION_ELE            bdHTInfoEle;
 
        u8                                      bdRT2RTAggregation;
@@ -304,27 +243,27 @@ typedef struct _BSS_HT {
 extern u8 MCS_FILTER_ALL[16];
 extern u8 MCS_FILTER_1SS[16];
 
-/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
-   STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
-   to add a macro to judge wireless mode. */
+/*
+ * 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
+ * STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
+ * to add a macro to judge wireless mode.
+ */
 #define PICK_RATE(_nLegacyRate, _nMcsRate)     \
-               (_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate)
+               (_nMcsRate == 0) ? (_nLegacyRate & 0x7f) : (_nMcsRate)
 /* 2007/07/12 MH We only define legacy and HT wireless mode now. */
 #define        LEGACY_WIRELESS_MODE    IEEE_MODE_MASK
 
 #define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \
-                                       ((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\
-                                               (LegacyRate):\
+                                       ((WirelessMode & (LEGACY_WIRELESS_MODE)) != 0) ?\
+                                               (LegacyRate) :\
                                                (PICK_RATE(LegacyRate, HTRate))
 
-
-
 // MCS Bw 40 {1~7, 12~15,32}
 #define        RATE_ADPT_1SS_MASK              0xFF
 #define        RATE_ADPT_2SS_MASK              0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
 #define        RATE_ADPT_MCS32_MASK            0x01
 
-#define                IS_11N_MCS_RATE(rate)           (rate&0x80)
+#define                IS_11N_MCS_RATE(rate)           (rate & 0x80)
 
 typedef enum _HT_AGGRE_SIZE {
        HT_AGG_SIZE_8K = 0,
@@ -341,13 +280,13 @@ typedef enum _HT_IOT_PEER
        HT_IOT_PEER_BROADCOM = 2,
        HT_IOT_PEER_RALINK = 3,
        HT_IOT_PEER_ATHEROS = 4,
-       HT_IOT_PEER_CISCO= 5,
+       HT_IOT_PEER_CISCO = 5,
        HT_IOT_PEER_MAX = 6
 }HT_IOT_PEER_E, *PHTIOT_PEER_E;
 
-//
-// IOT Action for different AP
-//
+/*
+ * IOT Action for different AP
+ */
 typedef enum _HT_IOT_ACTION {
        HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
        HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
index b948eae5909d235ecaef65b8bbe314a0e2722d72..c73a8058cf877a4a4d0b3011a7c2600a24cc6021 100644 (file)
@@ -130,15 +130,15 @@ void HTUpdateDefaultSetting(struct ieee80211_device *ieee)
  */
 void HTDebugHTCapability(u8 *CapIE, u8 *TitleString)
 {
-       static u8       EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};       // For 11n EWC definition, 2007.07.17, by Emily
-       PHT_CAPABILITY_ELE              pCapELE;
+       static u8                 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};     // For 11n EWC definition, 2007.07.17, by Emily
+       struct ht_capability_ele *pCapELE;
 
        if (!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap))) {
                //EWC IE
                IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __func__);
-               pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);
+               pCapELE = (struct ht_capability_ele *)(&CapIE[4]);
        } else {
-               pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);
+               pCapELE = (struct ht_capability_ele *)(&CapIE[0]);
        }
        IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString);
 
@@ -216,64 +216,7 @@ void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString)
                                pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
 }
 
-/*
- *     Return:         true if station in half n mode and AP supports 40 bw
- */
-static bool IsHTHalfNmode40Bandwidth(struct ieee80211_device *ieee)
-{
-       bool                    retValue = false;
-       PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
-
-       if (!pHTInfo->bCurrentHTSupport)                // wireless is n mode
-               retValue = false;
-       else if (!pHTInfo->bRegBW40MHz)         // station supports 40 bw
-               retValue = false;
-       else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))     // station in half n mode
-               retValue = false;
-       else if (((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
-               retValue = true;
-       else
-               retValue = false;
-
-       return retValue;
-}
-
-static bool IsHTHalfNmodeSGI(struct ieee80211_device *ieee, bool is40MHz)
-{
-       bool                    retValue = false;
-       PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
-
-       if (!pHTInfo->bCurrentHTSupport)                // wireless is n mode
-               retValue = false;
-       else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))     // station in half n mode
-               retValue = false;
-       else if (is40MHz) { // ap support 40 bw
-               if (((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
-                       retValue = true;
-               else
-                       retValue = false;
-       } else {
-               if (((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
-                       retValue = true;
-               else
-                       retValue = false;
-       }
-
-       return retValue;
-}
-
-u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8      nMcsRate)
-{
-       u8      is40MHz;
-       u8      isShortGI;
-
-       is40MHz = (IsHTHalfNmode40Bandwidth(ieee)) ? 1 : 0;
-       isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz)) ? 1 : 0;
-
-       return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)];
-}
-
-u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate)
+static u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 
@@ -530,7 +473,7 @@ void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo)
 void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 IsEncrypt)
 {
        PRT_HIGH_THROUGHPUT     pHT = ieee->pHTInfo;
-       PHT_CAPABILITY_ELE      pCapELE = NULL;
+       struct ht_capability_ele   *pCapELE = NULL;
        //u8 bIsDeclareMCS13;
 
        if (!posHTCap || !pHT) {
@@ -544,9 +487,9 @@ void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u
                u8      EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};       // For 11n EWC definition, 2007.07.17, by Emily
 
                memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
-               pCapELE = (PHT_CAPABILITY_ELE)&posHTCap[4];
+               pCapELE = (struct ht_capability_ele *)&posHTCap[4];
        } else {
-               pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
+               pCapELE = (struct ht_capability_ele *)posHTCap;
        }
 
        //HT capability info
@@ -894,11 +837,10 @@ static u8 HTFilterMCSRate(struct ieee80211_device *ieee, u8 *pSupportMCS,
        return true;
 }
 
-void HTSetConnectBwMode(struct ieee80211_device *ieee, enum ht_channel_width Bandwidth, enum ht_extension_chan_offset  Offset);
 void HTOnAssocRsp(struct ieee80211_device *ieee)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
-       PHT_CAPABILITY_ELE              pPeerHTCap = NULL;
+       struct ht_capability_ele       *pPeerHTCap = NULL;
        PHT_INFORMATION_ELE             pPeerHTInfo = NULL;
        u16     nMaxAMSDUSize = 0;
        u8      *pMcsFilter = NULL;
@@ -913,16 +855,16 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
                return;
        }
        IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
-//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE));
+//     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(struct ht_capability_ele));
 //     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE));
 
 //     HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq");
 //     HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq");
        //
        if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap)))
-               pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
+               pPeerHTCap = (struct ht_capability_ele *)(&pHTInfo->PeerHTCapBuf[4]);
        else
-               pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
+               pPeerHTCap = (struct ht_capability_ele *)(pHTInfo->PeerHTCapBuf);
 
        if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
                pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
@@ -932,7 +874,7 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
        ////////////////////////////////////////////////////////
        // Configurations:
        ////////////////////////////////////////////////////////
-       IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
+       IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, pPeerHTCap, sizeof(struct ht_capability_ele));
 //     IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE));
        // Config Supported Channel Width setting
        //
@@ -1069,7 +1011,6 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
        pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
 }
 
-void HTSetConnectBwModeCallback(struct ieee80211_device *ieee);
 /*
  *function:  initialize HT info(struct PRT_HIGH_THROUGHPUT)
  *   input:  struct ieee80211_device*  ieee
@@ -1122,7 +1063,6 @@ void HTInitializeHTInfo(struct ieee80211_device *ieee)
        memset(&pHTInfo->PeerHTInfoBuf, 0, sizeof(pHTInfo->PeerHTInfoBuf));
 
        pHTInfo->bSwBwInProgress = false;
-       pHTInfo->ChnlOp = CHNLOP_NONE;
 
        // Set default IEEE spec for Draft N
        pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
@@ -1177,7 +1117,7 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee802
 {
        PRT_HIGH_THROUGHPUT             pHTInfo = ieee->pHTInfo;
 //     u16                                             nMaxAMSDUSize;
-//     PHT_CAPABILITY_ELE              pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+//     struct ht_capability_ele       *pPeerHTCap = (struct ht_capability_ele *)pNetwork->bssht.bdHTCapBuf;
 //     PHT_INFORMATION_ELE             pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
 //     u8*     pMcsFilter;
        u8      bIOTAction = 0;
@@ -1250,8 +1190,8 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee802
 
 void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork)
 {
-       PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
-//     PHT_CAPABILITY_ELE              pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+       PRT_HIGH_THROUGHPUT             pHTInfo = ieee->pHTInfo;
+//     struct ht_capability_ele       *pPeerHTCap = (struct ht_capability_ele *)pNetwork->bssht.bdHTCapBuf;
        PHT_INFORMATION_ELE             pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
 
        if (pHTInfo->bCurrentHTSupport) {
@@ -1287,6 +1227,29 @@ u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame)
        return false;
 }
 
+static void HTSetConnectBwModeCallback(struct ieee80211_device *ieee)
+{
+       PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+       IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __func__);
+
+       if (pHTInfo->bCurBW40MHz) {
+               if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER)
+                       ieee->set_chan(ieee->dev, ieee->current_network.channel + 2);
+               else if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_LOWER)
+                       ieee->set_chan(ieee->dev, ieee->current_network.channel - 2);
+               else
+                       ieee->set_chan(ieee->dev, ieee->current_network.channel);
+
+               ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
+       } else {
+               ieee->set_chan(ieee->dev, ieee->current_network.channel);
+               ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+       }
+
+       pHTInfo->bSwBwInProgress = false;
+}
+
 /*
  * This function set bandwidth mode in protocol layer.
  */
@@ -1337,26 +1300,3 @@ void HTSetConnectBwMode(struct ieee80211_device *ieee, enum ht_channel_width Ban
 
 //     spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
 }
-
-void HTSetConnectBwModeCallback(struct ieee80211_device *ieee)
-{
-       PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
-
-       IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __func__);
-
-       if (pHTInfo->bCurBW40MHz) {
-               if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER)
-                       ieee->set_chan(ieee->dev, ieee->current_network.channel + 2);
-               else if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_LOWER)
-                       ieee->set_chan(ieee->dev, ieee->current_network.channel - 2);
-               else
-                       ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
-               ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
-       } else {
-               ieee->set_chan(ieee->dev, ieee->current_network.channel);
-               ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
-       }
-
-       pHTInfo->bSwBwInProgress = false;
-}
index 924d4b37309971e689e57020dbb52d3c116dad77..7ed140009760fb8e138b4516fc9fe8f41ad42db2 100644 (file)
@@ -78,8 +78,8 @@ struct ts_common_info {
 struct tx_ts_record {
        struct ts_common_info           ts_common_info;
        u16                             tx_cur_seq;
-       BA_RECORD                       tx_pending_ba_record;
-       BA_RECORD                       tx_admitted_ba_record;
+       struct ba_record                tx_pending_ba_record;
+       struct ba_record                tx_admitted_ba_record;
        u8                              add_ba_req_in_progress;
        u8                              add_ba_req_delayed;
        u8                              using_ba;
@@ -93,7 +93,7 @@ struct rx_ts_record {
        u16                             rx_timeout_indicate_seq;
        struct list_head                rx_pending_pkt_list;
        struct timer_list               rx_pkt_pending_timer;
-       BA_RECORD                       rx_admitted_ba_record;
+       struct ba_record                rx_admitted_ba_record;
        u16                             rx_last_seq_num;
        u8                              rx_last_frag_num;
        u8                              num;
index d46d8f468671d0e43f8b529fafee707a40c4d81c..c76715ffa08bb76bf95de73f03ddddc32b170423 100644 (file)
@@ -36,11 +36,11 @@ static void RxPktPendingTimeout(struct timer_list *t)
        bool bPktInBuf = false;
 
        spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
-       IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__func__);
+       IEEE80211_DEBUG(IEEE80211_DL_REORDER, "==================>%s()\n", __func__);
        if(pRxTs->rx_timeout_indicate_seq != 0xffff) {
                // Indicate the pending packets sequentially according to SeqNum until meet the gap.
                while(!list_empty(&pRxTs->rx_pending_pkt_list)) {
-                       pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->rx_pending_pkt_list.prev,RX_REORDER_ENTRY,List);
+                       pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->rx_pending_pkt_list.prev, RX_REORDER_ENTRY, List);
                        if(index == 0)
                                pRxTs->rx_indicate_seq = pReorderEntry->SeqNum;
 
@@ -51,7 +51,7 @@ static void RxPktPendingTimeout(struct timer_list *t)
                                if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq))
                                        pRxTs->rx_indicate_seq = (pRxTs->rx_indicate_seq + 1) % 4096;
 
-                               IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
+                               IEEE80211_DEBUG(IEEE80211_DL_REORDER, "RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
                                ieee->stats_IndicateArray[index] = pReorderEntry->prxb;
                                index++;
 
@@ -151,9 +151,9 @@ void TSInitialize(struct ieee80211_device *ieee)
                timer_setup(&pTxTS->ts_common_info.inact_timer, TsInactTimeout,
                            0);
                timer_setup(&pTxTS->ts_add_ba_timer, TsAddBaProcess, 0);
-               timer_setup(&pTxTS->tx_pending_ba_record.Timer, BaSetupTimeOut,
+               timer_setup(&pTxTS->tx_pending_ba_record.timer, BaSetupTimeOut,
                            0);
-               timer_setup(&pTxTS->tx_admitted_ba_record.Timer,
+               timer_setup(&pTxTS->tx_admitted_ba_record.timer,
                            TxBaInactTimeout, 0);
                ResetTxTsEntry(pTxTS);
                list_add_tail(&pTxTS->ts_common_info.list, &ieee->Tx_TS_Unused_List);
@@ -171,7 +171,7 @@ void TSInitialize(struct ieee80211_device *ieee)
                            0);
                timer_setup(&pRxTS->ts_common_info.inact_timer, TsInactTimeout,
                            0);
-               timer_setup(&pRxTS->rx_admitted_ba_record.Timer,
+               timer_setup(&pRxTS->rx_admitted_ba_record.timer,
                            RxBaInactTimeout, 0);
                timer_setup(&pRxTS->rx_pkt_pending_timer, RxPktPendingTimeout, 0);
                ResetRxTsEntry(pRxTS);
@@ -426,7 +426,7 @@ static void RemoveTsEntry(struct ieee80211_device *ieee, struct ts_common_info *
                while(!list_empty(&pRxTS->rx_pending_pkt_list)) {
                        spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
                        //pRxReorderEntry = list_entry(&pRxTS->rx_pending_pkt_list.prev,RX_REORDER_ENTRY,List);
-                       pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->rx_pending_pkt_list.prev,RX_REORDER_ENTRY,List);
+                       pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->rx_pending_pkt_list.prev, RX_REORDER_ENTRY, List);
                        list_del_init(&pRxReorderEntry->List);
                        {
                                int i = 0;
@@ -529,7 +529,7 @@ void TsStartAddBaProcess(struct ieee80211_device *ieee, struct tx_ts_record *pTx
                        mod_timer(&pTxTS->ts_add_ba_timer,
                                  jiffies + msecs_to_jiffies(TS_ADDBA_DELAY));
                } else {
-                       IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
+                       IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
                        mod_timer(&pTxTS->ts_add_ba_timer, jiffies+10); //set 10 ticks
                }
        } else {
index 643d465e71051b71ec9da6fa6ad32795da2d951c..0cdd00a4f7b82d9ee84eacebfab3579600ebde7a 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  *     This is part of rtl8187 OpenSource driver
  *     Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
 
 #define EPROM_DELAY 10
 
-#define EPROM_ANAPARAM_ADDRLWORD 0xd
-#define EPROM_ANAPARAM_ADDRHWORD 0xe
-
-#define EPROM_RFCHIPID 0x6
-#define EPROM_TXPW_BASE 0x05
-#define EPROM_RFCHIPID_RTL8225U 5
-#define EPROM_RF_PARAM 0x4
-#define EPROM_CONFIG2 0xc
-
-#define EPROM_VERSION 0x1E
-#define MAC_ADR 0x7
-
-#define CIS 0x18
-
-#define EPROM_TXPW0 0x16
-#define EPROM_TXPW2 0x1b
-#define EPROM_TXPW1 0x3d
-
 int eprom_read(struct net_device *dev, u32 addr); /* reads a 16 bits word */
index 9b7f822e976206137394aa43c7ec873c2295eb77..a8c8e8c0660da5470cf07cb652bf6ceec3a59681 100644 (file)
 #include "r819xU_phy.h"
 #include "r8190_rtl8256.h"
 
+/*
+ * Forward declaration of local functions
+ */
+static void phy_rf8256_config_para_file(struct net_device *dev);
+
 /*--------------------------------------------------------------------------
  * Overview:   set RF band width (20M or 40M)
  * Input:       struct net_device*     dev
@@ -23,7 +28,7 @@
  * Note:       8226 support both 20M  and 40 MHz
  *--------------------------------------------------------------------------
  */
-void PHY_SetRF8256Bandwidth(struct net_device *dev, enum ht_channel_width Bandwidth)
+void phy_set_rf8256_bandwidth(struct net_device *dev, enum ht_channel_width Bandwidth)
 {
        u8      eRFPath;
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -37,9 +42,9 @@ void PHY_SetRF8256Bandwidth(struct net_device *dev, enum ht_channel_width Bandwi
 
                switch (Bandwidth) {
                case HT_CHANNEL_WIDTH_20:
-                               if (priv->card_8192_version == VERSION_819xU_A
+                               if (priv->card_8192_version == VERSION_819XU_A
                                        || priv->card_8192_version
-                                       == VERSION_819xU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
+                                       == VERSION_819XU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
                                        rtl8192_phy_SetRFReg(dev,
                                                (enum rf90_radio_path_e)eRFPath,
                                                0x0b, bMask12Bits, 0x100); /* phy para:1ba */
@@ -53,11 +58,11 @@ void PHY_SetRF8256Bandwidth(struct net_device *dev, enum ht_channel_width Bandwi
                                                (enum rf90_radio_path_e)eRFPath,
                                                0x14, bMask12Bits, 0x5ab);
                                } else {
-                                       RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+                                       RT_TRACE(COMP_ERR, "phy_set_rf8256_bandwidth(): unknown hardware version\n");
                                        }
                                break;
                case HT_CHANNEL_WIDTH_20_40:
-                               if (priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
+                               if (priv->card_8192_version == VERSION_819XU_A || priv->card_8192_version == VERSION_819XU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
                                        rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0b, bMask12Bits, 0x300); /* phy para:3ba */
                                        rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x2c, bMask12Bits, 0x3df);
                                        rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x0e, bMask12Bits, 0x0a1);
@@ -68,11 +73,11 @@ void PHY_SetRF8256Bandwidth(struct net_device *dev, enum ht_channel_width Bandwi
                                        else
                                                rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path_e)eRFPath, 0x14, bMask12Bits, 0x5ab);
                                } else {
-                                       RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+                                       RT_TRACE(COMP_ERR, "phy_set_rf8256_bandwidth(): unknown hardware version\n");
                                        }
                                break;
                default:
-                               RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n", Bandwidth);
+                               RT_TRACE(COMP_ERR, "phy_set_rf8256_bandwidth(): unknown Bandwidth: %#X\n", Bandwidth);
                                break;
 
                }
@@ -85,7 +90,7 @@ void PHY_SetRF8256Bandwidth(struct net_device *dev, enum ht_channel_width Bandwi
  * Return:      NONE
  *--------------------------------------------------------------------------
  */
-void PHY_RF8256_Config(struct net_device *dev)
+void phy_rf8256_config(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        /* Initialize general global value
@@ -94,7 +99,7 @@ void PHY_RF8256_Config(struct net_device *dev)
         */
        priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
        /* Config BB and RF */
-       phy_RF8256_Config_ParaFile(dev);
+       phy_rf8256_config_para_file(dev);
 }
 /*--------------------------------------------------------------------------
  * Overview:    Interface to config 8256
@@ -103,7 +108,7 @@ void PHY_RF8256_Config(struct net_device *dev)
  * Return:      NONE
  *--------------------------------------------------------------------------
  */
-void phy_RF8256_Config_ParaFile(struct net_device *dev)
+static void phy_rf8256_config_para_file(struct net_device *dev)
 {
        u32     u4RegValue = 0;
        u8      eRFPath;
@@ -152,7 +157,7 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
                 * TODO: this function should be removed on ASIC , Emily 2007.2.2
                 */
                if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (enum rf90_radio_path_e)eRFPath)) {
-                       RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
+                       RT_TRACE(COMP_ERR, "phy_rf8256_config():Check Radio[%d] Fail!!\n", eRFPath);
                        goto phy_RF8256_Config_ParaFile_Fail;
                }
 
@@ -207,7 +212,7 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
                }
 
                if (ret) {
-                       RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
+                       RT_TRACE(COMP_ERR, "phy_rf8256_config_para_file():Radio[%d] Fail!!", eRFPath);
                        goto phy_RF8256_Config_ParaFile_Fail;
                }
 
@@ -221,7 +226,7 @@ phy_RF8256_Config_ParaFile_Fail:
 }
 
 
-void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel)
+void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel)
 {
        u32     TxAGC = 0;
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -240,7 +245,7 @@ void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel)
 }
 
 
-void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel)
+void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        /* Joseph TxPower for 8192 testing */
index 29b926cad14bea082bdb7a4f42d98baa9704f493..9ea67f86f911653aa36ad784ef3407620912f3b0 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  *      This is part of the rtl8180-sa2400 driver
  *      released under the GPL (See file COPYING for details).
 #define RTL8225H
 
 #define RTL819X_TOTAL_RF_PATH 2 /* for 8192U */
-void PHY_SetRF8256Bandwidth(struct net_device *dev, enum ht_channel_width Bandwidth);
-void PHY_RF8256_Config(struct net_device *dev);
-void phy_RF8256_Config_ParaFile(struct net_device *dev);
-void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8        powerlevel);
-void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel);
+void phy_set_rf8256_bandwidth(struct net_device *dev,
+                             enum ht_channel_width bandwidth);
+void phy_rf8256_config(struct net_device *dev);
+void phy_set_rf8256_cck_tx_power(struct net_device *dev, u8 powerlevel);
+void phy_set_rf8256_ofdm_tx_power(struct net_device *dev, u8 powerlevel);
 
 #endif
index 94a14899406979a4f1e079c085918147e7c436d9..e65a893fd08483e7001a8381f9981d817c2d0737 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * This is part of rtl8187 OpenSource driver.
  * Copyright (C) Andrea Merello 2004-2005  <andrea.merello@gmail.com>
 #include "ieee80211/ieee80211.h"
 
 #define RTL8192U
-#define RTL819xU_MODULE_NAME "rtl819xU"
+#define RTL819XU_MODULE_NAME "rtl819xU"
 /* HW security */
 #define MAX_KEY_LEN     61
 #define KEY_BUF_SIZE    5
 
-#define        Rx_Smooth_Factor                20
+#define        RX_SMOOTH_FACTOR                20
 #define DMESG(x, a...)
 #define DMESGW(x, a...)
 #define DMESGE(x, a...)
 extern u32 rt_global_debug_component;
 #define RT_TRACE(component, x, args...) \
        do {                                                    \
-               if (rt_global_debug_component & component)      \
+               if (rt_global_debug_component & (component))    \
                        pr_debug("RTL8192U: " x "\n", ##args);  \
        } while (0)
 
@@ -111,7 +112,7 @@ extern u32 rt_global_debug_component;
        do {                                                            \
                if ((rt_global_debug_component & (level)) == (level)) { \
                        int i;                                          \
-                       u8 *pdata = (u8 *) data;                        \
+                       u8 *pdata = (u8 *)data;                         \
                        pr_debug("RTL8192U: %s()\n", __func__);         \
                        for (i = 0; i < (int)(datalen); i++) {          \
                                printk("%2x ", pdata[i]);               \
@@ -798,6 +799,18 @@ typedef enum _tag_TxCmd_Config_Index {
        TXCMD_XXXX_CTRL,
 } DCMD_TXCMD_OP;
 
+enum version_819xu {
+       VERSION_819XU_A, // A-cut
+       VERSION_819XU_B, // B-cut
+       VERSION_819XU_C,// C-cut
+};
+
+//added for different RF type
+enum rt_rf_type {
+       RF_1T2R = 0,
+       RF_2T4R,
+};
+
 typedef struct r8192_priv {
        struct usb_device *udev;
        /* For maintain info from eeprom */
@@ -815,7 +828,7 @@ typedef struct r8192_priv {
        /* O: rtl8192, 1: rtl8185 V B/C, 2: rtl8185 V D */
        short card_8192;
        /* If TCR reports card V B/C, this discriminates */
-       u8 card_8192_version;
+       enum version_819xu card_8192_version;
        short enable_gpio0;
        enum card_type {
                PCI, MINIPCI, CARDBUS, USB
@@ -838,7 +851,7 @@ typedef struct r8192_priv {
 
        struct mutex wx_mutex;
 
-       u8 rf_type;                     /* 0: 1T2R, 1: 2T4R */
+       enum rt_rf_type   rf_type;          /* 0: 1T2R, 1: 2T4R */
        RT_RF_TYPE_819xU rf_chip;
 
        short (*rf_set_sens)(struct net_device *dev, short sens);
@@ -864,9 +877,9 @@ typedef struct r8192_priv {
        int     rx_inx;
 #endif
 
-       struct sk_buff_head rx_queue;
-       struct sk_buff_head skb_queue;
-       struct work_struct qos_activate;
+       struct sk_buff_head rx_queue;
+       struct sk_buff_head skb_queue;
+       struct work_struct qos_activate;
        short  tx_urb_index;
        atomic_t tx_pending[0x10]; /* UART_PRIORITY + 1 */
 
@@ -1014,7 +1027,7 @@ typedef struct r8192_priv {
        u8      nrxAMPDU_aggr_num;
 
        /* For gpio */
-        bool bHwRadioOff;
+       bool bHwRadioOff;
 
        u32 reset_count;
        bool bpbc_pressed;
@@ -1079,9 +1092,6 @@ bool init_firmware(struct net_device *dev);
 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192_tx(struct net_device *dev, struct sk_buff *skb);
 
-u32 read_cam(struct net_device *dev, u8 addr);
-void write_cam(struct net_device *dev, u8 addr, u32 data);
-
 int read_nic_byte(struct net_device *dev, int x, u8 *data);
 int read_nic_byte_E(struct net_device *dev, int x, u8 *data);
 int read_nic_dword(struct net_device *dev, int x, u32 *data);
@@ -1094,22 +1104,12 @@ void force_pci_posting(struct net_device *dev);
 
 void rtl8192_rtx_disable(struct net_device *dev);
 void rtl8192_rx_enable(struct net_device *dev);
-void rtl8192_tx_enable(struct net_device *dev);
-
-void rtl8192_disassociate(struct net_device *dev);
-void rtl8185_set_rf_pins_enable(struct net_device *dev, u32 a);
 
-void rtl8192_set_anaparam(struct net_device *dev, u32 a);
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a);
 void rtl8192_update_msr(struct net_device *dev);
 int rtl8192_down(struct net_device *dev);
 int rtl8192_up(struct net_device *dev);
 void rtl8192_commit(struct net_device *dev);
 void rtl8192_set_chan(struct net_device *dev, short ch);
-void write_phy(struct net_device *dev, u8 adr, u8 data);
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
-void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
 void rtl8192_set_rxconf(struct net_device *dev);
 void rtl819xusb_beacon_tx(struct net_device *dev, u16 tx_rate);
 
index e218b5c20642ddcd32cee0e11b997ef0d0f9289d..0ac0bbf7d923193940ee8f1ed7ca1a6bbfcf0318 100644 (file)
@@ -128,7 +128,7 @@ static void rtl8192_usb_disconnect(struct usb_interface *intf);
 
 
 static struct usb_driver rtl8192_usb_driver = {
-       .name           = RTL819xU_MODULE_NAME,           /* Driver name   */
+       .name           = RTL819XU_MODULE_NAME,           /* Driver name   */
        .id_table       = rtl8192_usb_id_tbl,             /* PCI_ID table  */
        .probe          = rtl8192_usb_probe,              /* probe fn      */
        .disconnect     = rtl8192_usb_disconnect,         /* remove fn     */
@@ -183,7 +183,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
        case COUNTRY_CODE_ISRAEL:
        case COUNTRY_CODE_TELEC:
        case COUNTRY_CODE_MIC:
-               Dot11d_Init(ieee);
+               rtl8192u_dot11d_init(ieee);
                ieee->bGlobalDomain = false;
                /* actually 8225 & 8256 rf chips only support B,G,24N mode */
                if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) {
@@ -211,8 +211,8 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
                /* this flag enabled to follow 11d country IE setting,
                 * otherwise, it shall follow global domain settings.
                 */
-               GET_DOT11D_INFO(ieee)->enabled = 0;
-               Dot11d_Reset(ieee);
+               GET_DOT11D_INFO(ieee)->dot11d_enabled = 0;
+               dot11d_reset(ieee);
                ieee->bGlobalDomain = true;
                break;
 
@@ -237,22 +237,6 @@ static void CamResetAllEntry(struct net_device *dev)
        write_nic_dword(dev, RWCAM, ulcommand);
 }
 
-
-void write_cam(struct net_device *dev, u8 addr, u32 data)
-{
-       write_nic_dword(dev, WCAMI, data);
-       write_nic_dword(dev, RWCAM, BIT(31) | BIT(16) | (addr & 0xff));
-}
-
-u32 read_cam(struct net_device *dev, u8 addr)
-{
-       u32 data;
-
-       write_nic_dword(dev, RWCAM, 0x80000000 | (addr & 0xff));
-       read_nic_dword(dev, 0xa8, &data);
-       return data;
-}
-
 int write_nic_byte_E(struct net_device *dev, int indx, u8 data)
 {
        int status;
@@ -643,7 +627,7 @@ static int __maybe_unused proc_get_stats_rx(struct seq_file *m, void *v)
 static void rtl8192_proc_module_init(void)
 {
        RT_TRACE(COMP_INIT, "Initializing proc filesystem");
-       rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
+       rtl8192_proc = proc_mkdir(RTL819XU_MODULE_NAME, init_net.proc_net);
 }
 
 static void rtl8192_proc_init_one(struct net_device *dev)
@@ -846,13 +830,6 @@ void rtl8192_rx_enable(struct net_device *dev)
        rtl8192_rx_initiate(dev);
 }
 
-
-void rtl8192_tx_enable(struct net_device *dev)
-{
-}
-
-
-
 void rtl8192_rtx_disable(struct net_device *dev)
 {
        u8 cmd;
@@ -1997,7 +1974,7 @@ static void rtl8192_update_ratr_table(struct net_device *dev)
                break;
        case IEEE_N_24G:
        case IEEE_N_5G:
-               if (ieee->pHTInfo->PeerMimoPs == 0) { /* MIMO_PS_STATIC */
+               if (ieee->pHTInfo->PeerMimoPs == MIMO_PS_STATIC) {
                        ratr_value &= 0x0007F007;
                } else {
                        if (priv->rf_type == RF_1T2R)
@@ -2382,20 +2359,20 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                if (ret < 0)
                        return ret;
                priv->eeprom_pid = (u16)ret;
-               ret = eprom_read(dev, EEPROM_ChannelPlan >> 1);
+               ret = eprom_read(dev, EEPROM_CHANNEL_PLAN >> 1);
                if (ret < 0)
                        return ret;
                tmpValue = (u16)ret;
                priv->eeprom_ChannelPlan = (tmpValue & 0xff00) >> 8;
                priv->btxpowerdata_readfromEEPORM = true;
-               ret = eprom_read(dev, (EEPROM_Customer_ID >> 1)) >> 8;
+               ret = eprom_read(dev, (EEPROM_CUSTOMER_ID >> 1)) >> 8;
                if (ret < 0)
                        return ret;
                priv->eeprom_CustomerID = (u16)ret;
        } else {
                priv->eeprom_vid = 0;
                priv->eeprom_pid = 0;
-               priv->card_8192_version = VERSION_819xU_B;
+               priv->card_8192_version = VERSION_819XU_B;
                priv->eeprom_ChannelPlan = 0;
                priv->eeprom_CustomerID = 0;
        }
@@ -2422,48 +2399,48 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
        priv->rf_type = RTL819X_DEFAULT_RF_TYPE; /* default 1T2R */
        priv->rf_chip = RF_8256;
 
-       if (priv->card_8192_version == (u8)VERSION_819xU_A) {
+       if (priv->card_8192_version == VERSION_819XU_A) {
                /* read Tx power gain offset of legacy OFDM to HT rate */
                if (bLoad_From_EEPOM) {
-                       ret = eprom_read(dev, (EEPROM_TxPowerDiff >> 1));
+                       ret = eprom_read(dev, (EEPROM_TX_POWER_DIFF >> 1));
                        if (ret < 0)
                                return ret;
                        priv->EEPROMTxPowerDiff = ((u16)ret & 0xff00) >> 8;
                } else
-                       priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
+                       priv->EEPROMTxPowerDiff = EEPROM_DEFAULT_TX_POWER;
                RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
                /* read ThermalMeter from EEPROM */
                if (bLoad_From_EEPOM) {
-                       ret = eprom_read(dev, (EEPROM_ThermalMeter >> 1));
+                       ret = eprom_read(dev, (EEPROM_THERMAL_METER >> 1));
                        if (ret < 0)
                                return ret;
                        priv->EEPROMThermalMeter = (u8)((u16)ret & 0x00ff);
                } else
-                       priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
+                       priv->EEPROMThermalMeter = EEPROM_DEFAULT_THERNAL_METER;
                RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
                /* for tx power track */
                priv->TSSI_13dBm = priv->EEPROMThermalMeter * 100;
                /* read antenna tx power offset of B/C/D to A from EEPROM */
                if (bLoad_From_EEPOM) {
-                       ret = eprom_read(dev, (EEPROM_PwDiff >> 1));
+                       ret = eprom_read(dev, (EEPROM_PW_DIFF >> 1));
                        if (ret < 0)
                                return ret;
                        priv->EEPROMPwDiff = ((u16)ret & 0x0f00) >> 8;
                } else
-                       priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
+                       priv->EEPROMPwDiff = EEPROM_DEFAULT_PW_DIFF;
                RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
                /* Read CrystalCap from EEPROM */
                if (bLoad_From_EEPOM) {
-                       ret = eprom_read(dev, (EEPROM_CrystalCap >> 1));
+                       ret = eprom_read(dev, (EEPROM_CRYSTAL_CAP >> 1));
                        if (ret < 0)
                                return ret;
                        priv->EEPROMCrystalCap = (u16)ret & 0x0f;
                } else
-                       priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
+                       priv->EEPROMCrystalCap = EEPROM_DEFAULT_CRYSTAL_CAP;
                RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
                /* get per-channel Tx power level */
                if (bLoad_From_EEPOM) {
-                       ret = eprom_read(dev, (EEPROM_TxPwIndex_Ver >> 1));
+                       ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_VER >> 1));
                        if (ret < 0)
                                return ret;
                        priv->EEPROM_Def_Ver = ((u16)ret & 0xff00) >> 8;
@@ -2474,7 +2451,7 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                        int i;
 
                        if (bLoad_From_EEPOM) {
-                               ret = eprom_read(dev, (EEPROM_TxPwIndex_CCK >> 1));
+                               ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_CCK >> 1));
                                if (ret < 0)
                                        return ret;
                                priv->EEPROMTxPowerLevelCCK = ((u16)ret & 0xff) >> 8;
@@ -2483,10 +2460,10 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                        RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
                        for (i = 0; i < 3; i++) {
                                if (bLoad_From_EEPOM) {
-                                       ret = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G + i) >> 1);
+                                       ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_OFDM_24G + i) >> 1);
                                        if (ret < 0)
                                                return ret;
-                                       if (((EEPROM_TxPwIndex_OFDM_24G + i) % 2) == 0)
+                                       if (((EEPROM_TX_PW_INDEX_OFDM_24G + i) % 2) == 0)
                                                tmpValue = (u16)ret & 0x00ff;
                                        else
                                                tmpValue = ((u16)ret & 0xff00) >> 8;
@@ -2498,7 +2475,7 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                        }
                } else if (priv->EEPROM_Def_Ver == 1) {
                        if (bLoad_From_EEPOM) {
-                               ret = eprom_read(dev, EEPROM_TxPwIndex_CCK_V1 >> 1);
+                               ret = eprom_read(dev, EEPROM_TX_PW_INDEX_CCK_V1 >> 1);
                                if (ret < 0)
                                        return ret;
                                tmpValue = ((u16)ret & 0xff00) >> 8;
@@ -2508,7 +2485,7 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                        priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
 
                        if (bLoad_From_EEPOM) {
-                               ret = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2) >> 1);
+                               ret = eprom_read(dev, (EEPROM_TX_PW_INDEX_CCK_V1 + 2) >> 1);
                                if (ret < 0)
                                        return ret;
                                tmpValue = (u16)ret;
@@ -2517,12 +2494,12 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                        *((u16 *)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
                        if (bLoad_From_EEPOM)
                                tmpValue = eprom_read(dev,
-                                       EEPROM_TxPwIndex_OFDM_24G_V1 >> 1);
+                                       EEPROM_TX_PW_INDEX_OFDM_24G_V1 >> 1);
                        else
                                tmpValue = 0x1010;
                        *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
                        if (bLoad_From_EEPOM)
-                               tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1 + 2) >> 1);
+                               tmpValue = eprom_read(dev, (EEPROM_TX_PW_INDEX_OFDM_24G_V1 + 2) >> 1);
                        else
                                tmpValue = 0x10;
                        priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
@@ -2567,7 +2544,7 @@ static int rtl8192_read_eeprom_info(struct net_device *dev)
                 * 92U does not enable TX power tracking.
                 */
                priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
-       } /* end if VersionID == VERSION_819xU_A */
+       } /* end if VersionID == VERSION_819XU_A */
 
        /* for dlink led */
        switch (priv->eeprom_CustomerID) {
@@ -2872,7 +2849,7 @@ static bool rtl8192_adapter_start(struct net_device *dev)
 
        rtl8192_phy_configmac(dev);
 
-       if (priv->card_8192_version == (u8)VERSION_819xU_A) {
+       if (priv->card_8192_version == VERSION_819XU_A) {
                rtl8192_phy_getTxPower(dev);
                rtl8192_phy_setTxPower(dev, priv->chan);
        }
@@ -3998,13 +3975,13 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
                                        pprevious_stats->RxMIMOSignalStrength[rfpath];
                        if (pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath]) {
                                priv->stats.rx_rssi_percentage[rfpath] =
-                                       ((priv->stats.rx_rssi_percentage[rfpath] * (Rx_Smooth_Factor - 1)) +
-                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (Rx_Smooth_Factor);
+                                       ((priv->stats.rx_rssi_percentage[rfpath] * (RX_SMOOTH_FACTOR - 1)) +
+                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (RX_SMOOTH_FACTOR);
                                priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
                        } else {
                                priv->stats.rx_rssi_percentage[rfpath] =
-                                       ((priv->stats.rx_rssi_percentage[rfpath] * (Rx_Smooth_Factor - 1)) +
-                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (Rx_Smooth_Factor);
+                                       ((priv->stats.rx_rssi_percentage[rfpath] * (RX_SMOOTH_FACTOR - 1)) +
+                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) / (RX_SMOOTH_FACTOR);
                        }
                        RT_TRACE(COMP_DBG,
                                 "priv->stats.rx_rssi_percentage[rfPath]  = %d\n",
@@ -4049,13 +4026,13 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
                                pprevious_stats->RxPWDBAll;
                if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
                        priv->undecorated_smoothed_pwdb =
-                               (((priv->undecorated_smoothed_pwdb) * (Rx_Smooth_Factor - 1)) +
-                                (pprevious_stats->RxPWDBAll)) / (Rx_Smooth_Factor);
+                               (((priv->undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
+                                (pprevious_stats->RxPWDBAll)) / (RX_SMOOTH_FACTOR);
                        priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
                } else {
                        priv->undecorated_smoothed_pwdb =
-                               (((priv->undecorated_smoothed_pwdb) * (Rx_Smooth_Factor - 1)) +
-                                (pprevious_stats->RxPWDBAll)) / (Rx_Smooth_Factor);
+                               (((priv->undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
+                                (pprevious_stats->RxPWDBAll)) / (RX_SMOOTH_FACTOR);
                }
        }
 
@@ -4098,8 +4075,8 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
                                        if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) /* initialize */
                                                priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
                                        priv->stats.rx_evm_percentage[nspatial_stream] =
-                                               ((priv->stats.rx_evm_percentage[nspatial_stream] * (Rx_Smooth_Factor - 1)) +
-                                                (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] * 1)) / (Rx_Smooth_Factor);
+                                               ((priv->stats.rx_evm_percentage[nspatial_stream] * (RX_SMOOTH_FACTOR - 1)) +
+                                                (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] * 1)) / (RX_SMOOTH_FACTOR);
                                }
                        }
                }
@@ -4460,15 +4437,15 @@ static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
 
        /* Check if the received packet is acceptable. */
        bpacket_match_bssid = (type != IEEE80211_FTYPE_CTL) &&
-                              (eqMacAddr(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
+                              (ether_addr_equal(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
                               && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV);
        bpacket_toself =  bpacket_match_bssid &
-                         (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
+                         (ether_addr_equal(praddr, priv->ieee80211->dev->dev_addr));
 
        if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BEACON)
                bPacketBeacon = true;
        if (WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) {
-               if ((eqMacAddr(praddr, dev->dev_addr)))
+               if ((ether_addr_equal(praddr, dev->dev_addr)))
                        bToSelfBA = true;
        }
 
index 00a123d44207b54c35a8eaaea4d330c9a1eaba9e..5a958335681d5eee59fff86d5b949069d1a51619 100644 (file)
 #ifndef R8192_HW
 #define R8192_HW
 
-typedef enum _VERSION_819xU {
-       VERSION_819xU_A, // A-cut
-       VERSION_819xU_B, // B-cut
-       VERSION_819xU_C,// C-cut
-} VERSION_819xU, *PVERSION_819xU;
-//added for different RF type
-typedef enum _RT_RF_TYPE_DEF {
-       RF_1T2R = 0,
-       RF_2T4R,
-
-       RF_819X_MAX_TYPE
-} RT_RF_TYPE_DEF;
-
-
-typedef enum _BaseBand_Config_Type {
-       BaseBand_Config_PHY_REG = 0,                    //Radio Path A
-       BaseBand_Config_AGC_TAB = 1,                    //Radio Path B
-} BaseBand_Config_Type, *PBaseBand_Config_Type;
 #define        RTL8187_REQT_READ       0xc0
 #define        RTL8187_REQT_WRITE      0x40
 #define        RTL8187_REQ_GET_REGS    0x05
@@ -47,58 +29,33 @@ typedef enum _BaseBand_Config_Type {
 #define MAX_RX_URB 16
 
 #define R8180_MAX_RETRY 255
-//#define MAX_RX_NORMAL_URB 3
-//#define MAX_RX_COMMAND_URB 2
-#define RX_URB_SIZE 9100
-
-#define BB_ANTATTEN_CHAN14     0x0c
-#define BB_ANTENNA_B 0x40
 
-#define BB_HOST_BANG           BIT(30)
-#define BB_HOST_BANG_EN                BIT(2)
-#define BB_HOST_BANG_CLK       BIT(1)
-#define BB_HOST_BANG_RW                BIT(3)
-#define BB_HOST_BANG_DATA       1
+#define RX_URB_SIZE 9100
 
-//#if (RTL819X_FPGA_VER & RTL819X_FPGA_VIVI_070920)
-#define AFR                    0x010
-#define AFR_CardBEn            BIT(0)
-#define AFR_CLKRUN_SEL         BIT(1)
-#define AFR_FuncRegEn          BIT(2)
 #define RTL8190_EEPROM_ID      0x8129
 #define EEPROM_VID             0x02
 #define EEPROM_PID             0x04
 #define EEPROM_NODE_ADDRESS_BYTE_0     0x0C
 
-#define EEPROM_TxPowerDiff     0x1F
-#define EEPROM_ThermalMeter    0x20
-#define EEPROM_PwDiff          0x21    //0x21
-#define EEPROM_CrystalCap      0x22    //0x22
+#define EEPROM_TX_POWER_DIFF   0x1F
+#define EEPROM_THERMAL_METER   0x20
+#define EEPROM_PW_DIFF         0x21    //0x21
+#define EEPROM_CRYSTAL_CAP     0x22    //0x22
 
-#define EEPROM_TxPwIndex_CCK   0x23    //0x23
-#define EEPROM_TxPwIndex_OFDM_24G      0x24    //0x24~0x26
-#define EEPROM_TxPwIndex_CCK_V1                0x29    //0x29~0x2B
-#define EEPROM_TxPwIndex_OFDM_24G_V1   0x2C    //0x2C~0x2E
-#define EEPROM_TxPwIndex_Ver           0x27    //0x27
+#define EEPROM_TX_PW_INDEX_CCK 0x23    //0x23
+#define EEPROM_TX_PW_INDEX_OFDM_24G    0x24    //0x24~0x26
+#define EEPROM_TX_PW_INDEX_CCK_V1      0x29    //0x29~0x2B
+#define EEPROM_TX_PW_INDEX_OFDM_24G_V1 0x2C    //0x2C~0x2E
+#define EEPROM_TX_PW_INDEX_VER         0x27    //0x27
 
-#define EEPROM_Default_TxPowerDiff             0x0
-#define EEPROM_Default_ThermalMeter            0x7
-#define EEPROM_Default_PwDiff                  0x4
-#define EEPROM_Default_CrystalCap              0x5
-#define EEPROM_Default_TxPower                 0x1010
-#define EEPROM_Customer_ID                     0x7B    //0x7B:CustomerID
-#define EEPROM_ChannelPlan                     0x16    //0x7C
-#define EEPROM_IC_VER                          0x7d    //0x7D
-#define EEPROM_CRC                             0x7e    //0x7E~0x7F
+#define EEPROM_DEFAULT_THERNAL_METER           0x7
+#define EEPROM_DEFAULT_PW_DIFF                 0x4
+#define EEPROM_DEFAULT_CRYSTAL_CAP             0x5
+#define EEPROM_DEFAULT_TX_POWER                0x1010
+#define EEPROM_CUSTOMER_ID                     0x7B    //0x7B:CustomerID
+#define EEPROM_CHANNEL_PLAN                    0x16    //0x7C
 
-#define EEPROM_CID_DEFAULT                     0x0
-#define EEPROM_CID_CAMEO                               0x1
 #define EEPROM_CID_RUNTOP                              0x2
-#define EEPROM_CID_Senao                               0x3
-#define EEPROM_CID_TOSHIBA                             0x4     // Toshiba setting, Merge by Jacken, 2008/01/31
-#define EEPROM_CID_NetCore                             0x5
-#define EEPROM_CID_Nettronix                   0x6
-#define EEPROM_CID_Pronet                              0x7
 #define EEPROM_CID_DLINK                               0x8
 
 #define AC_PARAM_TXOP_LIMIT_OFFSET     16
@@ -108,18 +65,16 @@ typedef enum _BaseBand_Config_Type {
 
 //#endif
 enum _RTL8192Usb_HW {
+       MAC0                    = 0x000,
+       MAC4                    = 0x004,
 
-       PCIF                    = 0x009, // PCI Function Register 0x0009h~0x000bh
 #define        BB_GLOBAL_RESET_BIT     0x1
        BB_GLOBAL_RESET         = 0x020, // BasebandGlobal Reset Register
        BSSIDR                  = 0x02E, // BSSID Register
        CMDR                    = 0x037, // Command register
-#define CR_RST                 0x10
 #define CR_RE                  0x08
 #define CR_TE                  0x04
-#define CR_MulRW               0x01
        SIFS                    = 0x03E, // SIFS register
-       TCR                     = 0x040, // Transmit Configuration Register
 
 #define TCR_MXDMA_2048         7
 #define TCR_LRL_OFFSET         0
@@ -132,26 +87,16 @@ enum _RTL8192Usb_HW {
                         BIT(22) | BIT(23))
 #define RX_FIFO_THRESHOLD_MASK (BIT(13) | BIT(14) | BIT(15))
 #define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_128 3
-#define RX_FIFO_THRESHOLD_256 4
-#define RX_FIFO_THRESHOLD_512 5
-#define RX_FIFO_THRESHOLD_1024 6
 #define RX_FIFO_THRESHOLD_NONE 7
 #define MAX_RX_DMA_MASK        (BIT(8) | BIT(9) | BIT(10))
 #define RCR_MXDMA_OFFSET       8
 #define RCR_FIFO_OFFSET                13
 #define RCR_ONLYERLPKT         BIT(31)                 // Early Receiving based on Packet Size.
-#define RCR_ENCS2              BIT(30)                 // Enable Carrier Sense Detection Method 2
-#define RCR_ENCS1              BIT(29)                 // Enable Carrier Sense Detection Method 1
-#define RCR_ENMBID             BIT(27)                 // Enable Multiple BssId.
-#define RCR_ACKTXBW            (BIT(24) | BIT(25))     // TXBW Setting of ACK frames
 #define RCR_CBSSID             BIT(23)                 // Accept BSSID match packet
 #define RCR_APWRMGT            BIT(22)                 // Accept power management packet
-#define        RCR_ADD3                BIT(21)                 // Accept address 3 match packet
 #define RCR_AMF                        BIT(20)                 // Accept management type frame
 #define RCR_ACF                        BIT(19)                 // Accept control type frame
 #define RCR_ADF                        BIT(18)                 // Accept data type frame
-#define RCR_RXFTH              BIT(13)                 // Rx FIFO Threshold
 #define RCR_AICV               BIT(12)                 // Accept ICV error packet
 #define        RCR_ACRC32              BIT(5)                  // Accept CRC32 error packet
 #define        RCR_AB                  BIT(3)                  // Accept broadcast packet
@@ -160,14 +105,10 @@ enum _RTL8192Usb_HW {
 #define        RCR_AAP                 BIT(0)                  // Accept all unicast packet
        SLOT_TIME               = 0x049, // Slot Time Register
        ACK_TIMEOUT             = 0x04c, // Ack Timeout Register
-       PIFS_TIME               = 0x04d, // PIFS time
-       USTIME                  = 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock.
        EDCAPARA_BE             = 0x050, // EDCA Parameter of AC BE
        EDCAPARA_BK             = 0x054, // EDCA Parameter of AC BK
        EDCAPARA_VO             = 0x058, // EDCA Parameter of AC VO
        EDCAPARA_VI             = 0x05C, // EDCA Parameter of AC VI
-       RFPC                    = 0x05F, // Rx FIFO Packet Count
-       CWRR                    = 0x060, // Contention Window Report Register
        BCN_TCFG                = 0x062, // Beacon Time Configuration
 #define BCN_TCFG_CW_SHIFT              8
 #define BCN_TCFG_IFS                   0
@@ -178,7 +119,6 @@ enum _RTL8192Usb_HW {
        BCN_ERR_THRESH          = 0x078, // Beacon Error Threshold
        RWCAM                   = 0x0A0, //IN 8190 Data Sheet is called CAMcmd
        WCAMI                   = 0x0A4, // Software write CAM input content
-       RCAMO                   = 0x0A8, // Software read/write CAM config
        SECR                    = 0x0B0, //Security Configuration Register
 #define        SCR_TxUseDK             BIT(0)                  //Force Tx Use Default Key
 #define SCR_RxUseDK            BIT(1)                  //Force Rx Use Default Key
@@ -186,21 +126,6 @@ enum _RTL8192Usb_HW {
 #define SCR_RxDecEnable                BIT(3)                  //Enable Rx Decryption
 #define SCR_SKByA2             BIT(4)                  //Search kEY BY A2
 #define SCR_NoSKMC             BIT(5)                  //No Key Search for Multicast
-#define SCR_UseDK              0x01
-#define SCR_TxSecEnable                0x02
-#define SCR_RxSecEnable                0x04
-       TPPoll                  = 0x0fd, // Transmit priority polling register
-       PSR                     = 0x0ff, // Page Select Register
-#define CPU_CCK_LOOPBACK       0x00030000
-#define CPU_GEN_SYSTEM_RESET   0x00000001
-#define CPU_GEN_FIRMWARE_RESET 0x00000008
-#define CPU_GEN_BOOT_RDY       0x00000010
-#define CPU_GEN_FIRM_RDY       0x00000020
-#define CPU_GEN_PUT_CODE_OK    0x00000080
-#define CPU_GEN_BB_RST         0x00000100
-#define CPU_GEN_PWR_STB_CPU    0x00000004
-#define CPU_GEN_NO_LOOPBACK_MSK        0xFFF8FFFF              // Set bit18,17,16 to 0. Set bit19
-#define CPU_GEN_NO_LOOPBACK_SET        0x00080000              // Set BIT19 to 1
 
 //----------------------------------------------------------------------------
 //       8190 CPU General Register             (offset 0x100, 4 byte)
@@ -216,72 +141,20 @@ enum _RTL8192Usb_HW {
 #define CPU_GEN_NO_LOOPBACK_MSK        0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
 #define CPU_GEN_NO_LOOPBACK_SET        0x00080000 // Set BIT19 to 1
        CPU_GEN                 = 0x100, // CPU Reset Register
-       LED1Cfg                 =               0x154,// LED1 Configuration Register
-       LED0Cfg                 =               0x155,// LED0 Configuration Register
 
-       AcmAvg                  = 0x170, // ACM Average Period Register
        AcmHwCtrl               = 0x171, // ACM Hardware Control Register
 //----------------------------------------------------------------------------
 ////
 ////       8190 AcmHwCtrl bits                                    (offset 0x171, 1 byte)
 ////----------------------------------------------------------------------------
 //
-#define AcmHw_HwEn              BIT(0)
 #define AcmHw_BeqEn             BIT(1)
-#define AcmHw_ViqEn             BIT(2)
-#define AcmHw_VoqEn             BIT(3)
-#define AcmHw_BeqStatus         BIT(4)
-#define AcmHw_ViqStatus         BIT(5)
-#define AcmHw_VoqStatus         BIT(6)
 
-       AcmFwCtrl               = 0x172, // ACM Firmware Control Register
-       AES_11N_FIX             = 0x173,
-       VOAdmTime               = 0x174, // VO Queue Admitted Time Register
-       VIAdmTime               = 0x178, // VI Queue Admitted Time Register
-       BEAdmTime               = 0x17C, // BE Queue Admitted Time Register
        RQPN1                   = 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk
        RQPN2                   = 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High
        RQPN3                   = 0x188, // Reserved Queue Page Number, Bcn, Public,
-//     QPRR                    = 0x1E0, // Queue Page Report per TID
        QPNR                    = 0x1D0, //0x1F0, // Queue Packet Number report per TID
-       BQDA                    = 0x200, // Beacon Queue Descriptor Address
-       HQDA                    = 0x204, // High Priority Queue Descriptor Address
-       CQDA                    = 0x208, // Command Queue Descriptor Address
-       MQDA                    = 0x20C, // Management Queue Descriptor Address
-       HCCAQDA                 = 0x210, // HCCA Queue Descriptor Address
-       VOQDA                   = 0x214, // VO Queue Descriptor Address
-       VIQDA                   = 0x218, // VI Queue Descriptor Address
-       BEQDA                   = 0x21C, // BE Queue Descriptor Address
-       BKQDA                   = 0x220, // BK Queue Descriptor Address
-       RCQDA                   = 0x224, // Receive command Queue Descriptor Address
-       RDQDA                   = 0x228, // Receive Queue Descriptor Start Address
-
-       MAR0                    = 0x240, // Multicast filter.
-       MAR4                    = 0x244,
-
-       CCX_PERIOD              = 0x250, // CCX Measurement Period Register, in unit of TU.
-       CLM_RESULT              = 0x251, // CCA Busy fraction register.
-       NHM_PERIOD              = 0x252, // NHM Measurement Period register, in unit of TU.
 
-       NHM_THRESHOLD0          = 0x253, // Noise Histogram Meashorement0.
-       NHM_THRESHOLD1          = 0x254, // Noise Histogram Meashorement1.
-       NHM_THRESHOLD2          = 0x255, // Noise Histogram Meashorement2.
-       NHM_THRESHOLD3          = 0x256, // Noise Histogram Meashorement3.
-       NHM_THRESHOLD4          = 0x257, // Noise Histogram Meashorement4.
-       NHM_THRESHOLD5          = 0x258, // Noise Histogram Meashorement5.
-       NHM_THRESHOLD6          = 0x259, // Noise Histogram Meashorement6
-
-       MCTRL                   = 0x25A, // Measurement Control
-
-       NHM_RPI_COUNTER0        = 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0.
-       NHM_RPI_COUNTER1        = 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1].
-       NHM_RPI_COUNTER2        = 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2].
-       NHM_RPI_COUNTER3        = 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3].
-       NHM_RPI_COUNTER4        = 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4].
-       NHM_RPI_COUNTER5        = 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5].
-       NHM_RPI_COUNTER6        = 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6].
-       NHM_RPI_COUNTER7        = 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7].
-#define        BW_OPMODE_11J                   BIT(0)
 #define        BW_OPMODE_5G                    BIT(1)
 #define        BW_OPMODE_20MHZ                 BIT(2)
        BW_OPMODE               = 0x300, // Bandwidth operation mode
@@ -292,18 +165,10 @@ enum _RTL8192Usb_HW {
 #define MSR_LINK_SHIFT     0
 #define MSR_LINK_ADHOC     1
 #define MSR_LINK_MASTER    3
-#define MSR_LINK_ENEDCA           BIT(4)
        RETRY_LIMIT             = 0x304, // Retry Limit [15:8]-short, [7:0]-long
 #define RETRY_LIMIT_SHORT_SHIFT 8
 #define RETRY_LIMIT_LONG_SHIFT 0
-       TSFR                    = 0x308,
        RRSR                    = 0x310, // Response Rate Set
-#define RRSR_RSC_OFFSET                        21
-#define RRSR_SHORT_OFFSET                      23
-#define RRSR_RSC_DUPLICATE                     0x600000
-#define RRSR_RSC_LOWSUBCHNL            0x400000
-#define RRSR_RSC_UPSUBCHANL            0x200000
-#define RRSR_SHORT                                     0x800000
 #define RRSR_1M                                                BIT(0)
 #define RRSR_2M                                                BIT(1)
 #define RRSR_5_5M                                      BIT(2)
@@ -316,17 +181,9 @@ enum _RTL8192Usb_HW {
 #define RRSR_36M                                       BIT(9)
 #define RRSR_48M                                       BIT(10)
 #define RRSR_54M                                       BIT(11)
-#define RRSR_MCS0                                      BIT(12)
-#define RRSR_MCS1                                      BIT(13)
-#define RRSR_MCS2                                      BIT(14)
-#define RRSR_MCS3                                      BIT(15)
-#define RRSR_MCS4                                      BIT(16)
-#define RRSR_MCS5                                      BIT(17)
-#define RRSR_MCS6                                      BIT(18)
-#define RRSR_MCS7                                      BIT(19)
 #define BRSR_AckShortPmb                       BIT(23)         // CCK ACK: use Short Preamble or not.
-       RATR0                   = 0x320, // Rate Adaptive Table register1
        UFWP                    = 0x318,
+       RATR0                   = 0x320, // Rate Adaptive Table register1
        DRIVER_RSSI             = 0x32c,                                        // Driver tell Firmware current RSSI
 //----------------------------------------------------------------------------
 //       8190 Rate Adaptive Table Register     (offset 0x320, 4 byte)
@@ -372,41 +229,18 @@ enum _RTL8192Usb_HW {
 #define RATE_ALL_OFDM_2SS      RATR_MCS8|RATR_MCS9     |RATR_MCS10|RATR_MCS11| \
                                                        RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
 
-       MCS_TXAGC               = 0x340, // MCS AGC
-       CCK_TXAGC               = 0x348, // CCK AGC
-//     ISR                     = 0x350, // Interrupt Status Register
-//     IMR                     = 0x354, // Interrupt Mask Register
-//     IMR_POLL                = 0x360,
-       MacBlkCtrl              = 0x403, // Mac block on/off control register
-
        EPROM_CMD               = 0xfe58,
 #define Cmd9346CR_9356SEL      BIT(4)
-#define EPROM_CMD_RESERVED_MASK BIT(5)
 #define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK (BIT(7) | BIT(6))
-#define EPROM_CMD_CONFIG 0x3
 #define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
 #define EPROM_CMD_PROGRAM 2
 #define EPROM_CS_BIT BIT(3)
 #define EPROM_CK_BIT BIT(2)
 #define EPROM_W_BIT  BIT(1)
 #define EPROM_R_BIT  BIT(0)
-
-       MAC0                    = 0x000,
-       MAC1                    = 0x001,
-       MAC2                    = 0x002,
-       MAC3                    = 0x003,
-       MAC4                    = 0x004,
-       MAC5                    = 0x005,
-
 };
 //----------------------------------------------------------------------------
 //       818xB AnaParm & AnaParm2 Register
 //----------------------------------------------------------------------------
-//#define ANAPARM_ASIC_ON    0x45090658
-//#define ANAPARM2_ASIC_ON   0x727f3f52
 #define GPI 0x108
-#define GPO 0x109
-#define GPE 0x10a
 #endif
index 9c7e19aedff141cced9ecf80cc17d5ecbe9a4b22..c3ea906f3af3cfc79ef4fe4956384be688b27ab5 100644 (file)
@@ -208,8 +208,8 @@ bool init_firmware(struct net_device *dev)
        u32                     file_length = 0;
        u8                      *mapped_file = NULL;
        u32                     init_step = 0;
-       opt_rst_type_e  rst_opt = OPT_SYSTEM_RESET;
-       firmware_init_step_e    starting_state = FW_INIT_STEP0_BOOT;
+       enum opt_rst_type_e        rst_opt = OPT_SYSTEM_RESET;
+       enum firmware_init_step_e  starting_state = FW_INIT_STEP0_BOOT;
 
        rt_firmware             *pfirmware = priv->pFirmware;
        const struct firmware   *fw_entry;
index cccd1c82ffe09057df274a23b00d37ab81077b09..b84344c1e62bf42c51ca029d25b3a202a1622ba4 100644 (file)
@@ -2,19 +2,18 @@
 #ifndef __INC_FIRMWARE_H
 #define __INC_FIRMWARE_H
 
-#define RTL8190_CPU_START_OFFSET       0x80
 #define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) \
-       (4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
+       (4 * ((v) / 4) - 8 - USB_HWDESC_HEADER_LEN)
 
-typedef enum _firmware_init_step {
+enum firmware_init_step_e {
        FW_INIT_STEP0_BOOT = 0,
        FW_INIT_STEP1_MAIN = 1,
        FW_INIT_STEP2_DATA = 2,
-} firmware_init_step_e;
+};
 
-typedef enum _opt_rst_type {
+enum opt_rst_type_e {
        OPT_SYSTEM_RESET = 0,
        OPT_FIRMWARE_RESET = 1,
-} opt_rst_type_e;
+};
 
 #endif
index 7ee10d49894bc5824fab4723ab6974ff57664780..5f04afe53d6952c5cb03190e9f3bce7b847714a5 100644 (file)
@@ -511,7 +511,8 @@ void rtl8192_phy_configmac(struct net_device *dev)
  * notice:    BB parameters may change all the time, so please make
  *            sure it has been synced with the newest.
  *****************************************************************************/
-void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
+static void rtl8192_phyConfigBB(struct net_device *dev,
+                               enum baseband_config_type ConfigType)
 {
        u32 i;
 
@@ -525,7 +526,7 @@ void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
                Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
        }
 #endif
-       if (ConfigType == BaseBand_Config_PHY_REG) {
+       if (ConfigType == BASEBAND_CONFIG_PHY_REG) {
                for (i = 0; i < PHY_REG_1T2RArrayLength; i += 2) {
                        rtl8192_setBBreg(dev, Rtl8192UsbPHY_REG_1T2RArray[i],
                                         bMaskDWord,
@@ -535,7 +536,7 @@ void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
                                 i, Rtl8192UsbPHY_REG_1T2RArray[i],
                                 Rtl8192UsbPHY_REG_1T2RArray[i+1]);
                }
-       } else if (ConfigType == BaseBand_Config_AGC_TAB) {
+       } else if (ConfigType == BASEBAND_CONFIG_AGC_TAB) {
                for (i = 0; i < AGCTAB_ArrayLength; i += 2) {
                        rtl8192_setBBreg(dev, Rtl8192UsbAGCTAB_Array[i],
                                         bMaskDWord, Rtl8192UsbAGCTAB_Array[i+1]);
@@ -793,7 +794,7 @@ static void rtl8192_BB_Config_ParaFile(struct net_device *dev)
                                                  (enum rf90_radio_path_e)0);
                if (status != 0) {
                        RT_TRACE((COMP_ERR | COMP_PHY),
-                                "PHY_RF8256_Config(): Check PHY%d Fail!!\n",
+                                "phy_rf8256_config(): Check PHY%d Fail!!\n",
                                 eCheckItem-1);
                        return;
                }
@@ -802,7 +803,7 @@ static void rtl8192_BB_Config_ParaFile(struct net_device *dev)
        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
        /* ----BB Register Initilazation---- */
        /* ==m==>Set PHY REG From Header<==m== */
-       rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);
+       rtl8192_phyConfigBB(dev, BASEBAND_CONFIG_PHY_REG);
 
        /* ----Set BB reset de-Active---- */
        read_nic_dword(dev, CPU_GEN, &reg_u32);
@@ -810,11 +811,11 @@ static void rtl8192_BB_Config_ParaFile(struct net_device *dev)
 
        /* ----BB AGC table Initialization---- */
        /* ==m==>Set PHY REG From Header<==m== */
-       rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);
+       rtl8192_phyConfigBB(dev, BASEBAND_CONFIG_AGC_TAB);
 
        /* ----Enable XSTAL ---- */
        write_nic_byte_E(dev, 0x5e, 0x00);
-       if (priv->card_8192_version == (u8)VERSION_819xU_A) {
+       if (priv->card_8192_version == VERSION_819XU_A) {
                /* Antenna gain offset from B/C/D to A */
                reg_u32 = priv->AntennaTxPwDiff[1]<<4 |
                           priv->AntennaTxPwDiff[0];
@@ -917,8 +918,8 @@ void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel)
        switch (priv->rf_chip) {
        case RF_8256:
                /* need further implement */
-               PHY_SetRF8256CCKTxPower(dev, powerlevel);
-               PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
+               phy_set_rf8256_cck_tx_power(dev, powerlevel);
+               phy_set_rf8256_ofdm_tx_power(dev, powerlevelOFDM24G);
                break;
        default:
                RT_TRACE((COMP_PHY|COMP_ERR),
@@ -940,7 +941,7 @@ void rtl8192_phy_RFConfig(struct net_device *dev)
 
        switch (priv->rf_chip) {
        case RF_8256:
-               PHY_RF8256_Config(dev);
+               phy_rf8256_config(dev);
                break;
        default:
                RT_TRACE(COMP_ERR, "error chip id\n");
@@ -1065,8 +1066,8 @@ static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
                break;
 
        case RF_8256:
-               PHY_SetRF8256CCKTxPower(dev, powerlevel);
-               PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
+               phy_set_rf8256_cck_tx_power(dev, powerlevel);
+               phy_set_rf8256_ofdm_tx_power(dev, powerlevelOFDM24G);
                break;
 
        case RF_8258:
@@ -1271,7 +1272,7 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel,
 
        RT_TRACE(COMP_CH, "%s() stage: %d, step: %d, channel: %d\n",
                 __func__, *stage, *step, channel);
-       if (!IsLegalChannel(priv->ieee80211, channel)) {
+       if (!is_legal_channel(priv->ieee80211, channel)) {
                RT_TRACE(COMP_ERR, "set to illegal channel: %d\n", channel);
                /* return true to tell upper caller function this channel
                 * setting is finished! Or it will in while loop.
@@ -1367,7 +1368,7 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel,
 
                switch (CurrentCmd->cmd_id) {
                case CMD_ID_SET_TX_PWR_LEVEL:
-                       if (priv->card_8192_version == (u8)VERSION_819xU_A)
+                       if (priv->card_8192_version == VERSION_819XU_A)
                                /* consider it later! */
                                rtl8192_SetTxPowerLevel(dev, channel);
                        break;
@@ -1633,7 +1634,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev)
                break;
 
        case RF_8256:
-               PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
+               phy_set_rf8256_bandwidth(dev, priv->CurrentChannelBW);
                break;
 
        case RF_8258:
index c7ec3182857f07a688890d71ddc5eaa06a9a059a..8c2933264407b56d9b4b0fa34a17702b62017403 100644 (file)
@@ -7,6 +7,11 @@
 #define MAX_RFDEPENDCMD_CNT 16
 #define MAX_POSTCMD_CNT 16
 
+enum baseband_config_type {
+       BASEBAND_CONFIG_PHY_REG = 0,                    //Radio Path A
+       BASEBAND_CONFIG_AGC_TAB = 1,                    //Radio Path B
+};
+
 enum switch_chan_cmd_id {
        CMD_ID_END,
        CMD_ID_SET_TX_PWR_LEVEL,
@@ -52,7 +57,6 @@ u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
                           enum rf90_radio_path_e e_rfpath,
                           u32 reg_addr, u32 bitmask);
 void rtl8192_phy_configmac(struct net_device *dev);
-void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType);
 u8 rtl8192_phy_checkBBAndRF(struct net_device *dev,
                            enum hw90_block_e CheckBlock,
                            enum rf90_radio_path_e e_rfpath);
index f5c0231891b12f8ff08af21a2524565a477b51d6..4ad7f35b1644a66347541bbec198e75b8c94406c 100644 (file)
@@ -1,16 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index ede99e96984f47bd029a47a8c0530f004331673d..48d62fe6c8d43a2d1e6f559f57e626b8c2c75a90 100644 (file)
@@ -1,16 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 039da36fad3d6ca39e6fb044d645cc595023f81e..4b9b8a97a0bc6c950a465591caa4e00c68fe6069 100644 (file)
@@ -1,16 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 2a3f0746ee2c66a68915b1759cde57443168b654..7cdd609cab6caa0a4b63f47bfd015eaadd49f416 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * hal_init.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 7a4c00e49a8859e8c06fc5104c68e9bff7a60eb4..bb4f56a5fb01367a502c1ebcdce8e1c1584e0d15 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * ieee80211.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index d605dfd02200db88a8b10c47e88568fc10e3e4c8..1470771daa62251a023e61c6afaa4f9f91add4c0 100644 (file)
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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/>.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index baaa52f04560dc5a9361986a6a050b8fca7b77f8..9d156efbc9edfe9933143464a0c689fb762635c7 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * mlme_linux.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index a20fe81f921f9f56843b6ddae6a6cbf2bd8cc625..9eaf94f072ff373f5c4ac2822a765c2af9d2d436 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 40510089b781bb07f80b392d6180a306440e24e8..a9fac87fcabc59b9d02ebbb68903e62055d0ad1e 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index ff4e451c10f95c57313fca3f405d4885f23a5cfe..2d3f380072991ad0a536531b7527bf67b0329ba4 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * os_intfs.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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.
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 5d37e1f951cf58a8473b46d18f90995ca631d623..2cc25db1a91de84fce37991b199fade3a0612c23 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 5d33020554cd5d260b2a6c28cc299626b7cd115b..e939c4a954b3f26d494bbbf3cd73097e01ec575f 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 8cf4286f63184dec49a8f7816d39d075657d6ad1..4e20cbafa9fbeb49bacc73ae0db68201731c6ecb 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * recv_linux.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 1f4986e940a37662cce2e4f70184748dffafe875..dcd3b484c79310497728167133aeeda08f19a7ab 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index dee35fe2587a292aac05ac5758f314bb352f3735..a4a687dcc2e7bb41e68012ece28952d4b587bc34 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 
 #ifndef __RTL8712_BITDEF_H__
index b1dfe9f466191a78598488e5340c490a298b6019..1920d02f7c9f3724cb1516f857875f1bb8a76cfd 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl8712_cmd.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 9181bb6b04c343f87d1ea0b3736a0f7a530cfce9..92fb77666d4462d411d927d26a7bd58d1503c8ca 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 4b8985d500987c92199ef51b3ecff4886037d72f..e125c7222ab5ea4040c6d4cc71d4bd35c6484734 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_CMDCTRL_BITDEF_H__
 #define __RTL8712_CMDCTRL_BITDEF_H__
index 8df42a70399fdc263329ce2d51594e5a5d1cd632..fc67771c89b7851e01769eda3bb1f7ce200be9c5 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_CMDCTRL_REGDEF_H__
 #define __RTL8712_CMDCTRL_REGDEF_H__
index 4b3436795cb14e4a8ee1aa5aa655efb941971c1e..bb3863467f0d67951b03b1edc47135179805eae8 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_DEBUGCTRL_BITDEF_H__
 #define __RTL8712_DEBUGCTRL_BITDEF_H__
index d7c964d436a1c878615a5040eb38d4b141efa490..319220e9d53de3f0111893b396c66ea80988b19e 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_DEBUGCTRL_REGDEF_H__
 #define __RTL8712_DEBUGCTRL_REGDEF_H__
index 32dab81f1767f05cfa03153ab30228b522d4d852..9048d6a6529697ddd9b71f1ac811497afd550402 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index d992cb8b1c73872b01359d571e06c603f19cb0a4..02ec9f3bba6659774eaa6eacbab93ad852ae4d5a 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_EDCASETTING_REGDEF_H__
 #define __RTL8712_EDCASETTING_REGDEF_H__
index d90213eb5e2042d49e81bafa53203af4a4593c11..8bc45ffd30293c0732c6e10eae6dc245a8933c9e 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * rtl8712_efuse.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index cad7085c3f8a36c740f3c2b52d3f6f685a748e3f..0d3e5feadcc01027d5b8106b200a4b976c5e49d5 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index bd8240476d713c0a18527bcd1cf825809879db3f..f09645fa1886e44de061ab6b752bceb2ca38bc51 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_FIFOCTRL_BITDEF_H__
 #define __RTL8712_FIFOCTRL_BITDEF_H__
index 6d527380fd29460a62481dbbfb769e5285762cee..189fdeb16d7d31fb779f3ad4fd6499033b411b6f 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_FIFOCTRL_REGDEF_H__
 #define __RTL8712_FIFOCTRL_REGDEF_H__
index 66c35c990983c5dee8dd32947b1a4679d7903ec7..ee651fb3fde3fce6114201fe024a68f75b981451 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index a0379360d0a3bf6632d0bc3d6e2ace7f3bab4513..892a7fb1392355c9dd757011c05f708cfddb83ab 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 84456bb560ef70a416034ded9cc2582cca19710d..42f519739128177b393d931867cdc6cd425ac6cc 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 2a561d2862e061a81c7100fa9577c122f908b507..e9732a1bcd7ef8f058bf7dcd0424304abcfe3ead 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_INTERRUPT_BITDEF_H__
 #define __RTL8712_INTERRUPT_BITDEF_H__
index 391eff37f5737670a044cc88489653c49bd970c5..8eb79f73c014b7da45b30c844bb9fd4ed162af42 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl8712_io.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 0aa97c9dcced23c1b084a81df6f10b2a12a8dd49..5b1004b2df47a7d29b1039a81bc0c0be4a2d78bb 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl8712_led.c
  *
  * Copyright(c) 2007 - 2010  Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 28e0a7ebcad7c5e09f64447b2dc2afdb164262b5..3d9f40fa84697f1ae0dc18ffb2386f9a703db696 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_MACSETTING_BITDEF_H__
 #define __RTL8712_MACSETTING_BITDEF_H__
index ced0da9332d52d6147ebe8fc89d7fa7c9ff13b44..e8cb2eee9294cf67f2aef27dcd20ff5efb23040e 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_MACSETTING_REGDEF_H__
 #define __RTL8712_MACSETTING_REGDEF_H__
index 8fc689416519644fe545325b4a12750134e4e7cc..53e0d6b440f34ee5bc3a4893e4df9d70a2f2f967 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_POWERSAVE_BITDEF_H__
 #define __RTL8712_POWERSAVE_BITDEF_H__
index 4632ddd5d1f7689a5bd0ed8280617866d6145e15..1bcfde4b1c11f1647d9c0208cbb8a192ca8fd105 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_POWERSAVE_REGDEF_H__
 #define __RTL8712_POWERSAVE_REGDEF_H__
index 6d3d6e8522fbc078fc1bb4027e6aef89825a3c76..1de51c48f9c1b2d01866a3a6ec9dbc03ac9d35c2 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_RATECTRL_BITDEF_H__
 #define __RTL8712_RATECTRL_BITDEF_H__
index 73dfc3610154ea8be76acc779f441819f574c6c7..a3eaee0e1b69186f85c74c7247bdec0f47578bb9 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 4264cd341f031e7b7f2648d725df3ee368b1f1da..5bf9070b7a282b0893a5c27039035c279715fe69 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl8712_recv.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 0352e6fafd90e9e2eda6fbdd0c554e9dfc2e94c6..6954c5bfbcafbca9892dcdcbcc00710258c2383c 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index e7bca55b59d01580253b7f54d6dea3d8b8efbbdd..28aec9aa539fd315367c1bab84088c0e703d389c 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 05dafa0c33330187207a88f610591477abaea2c1..1c26a7eca64a4d4d6ff1fe9add4c1b61fc918f18 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_SECURITY_BITDEF_H__
 #define __RTL8712_SECURITY_BITDEF_H__
index 51e042815cc967941180ad80bba1107e3daefe23..c0bab4c49ae95f79459156378b41b7fce889e0e2 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 2e66d28d6918ab6485312023f349f0e697ff114d..a328ca9b340cfaa9cdbc612558f267eaf6c0f637 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 767dfdf8d83f1f89d56c1b75815ccbe779d0e9f1..e95eb5832ec41953368ef7d771e0e779211be6a5 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 7244215824211add3dc1cd52a69e3b7d7f33012b..1af5f1dd3c20d592bd2a02ce7f31b44d7eb2e0ab 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_TIMECTRL_BITDEF_H__
 #define __RTL8712_TIMECTRL_BITDEF_H__
index 106916c7e310fb0c0a9a52e91005d90ccb67d71b..b51603f1b880044a3ba7b6423b8877030d185374 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL8712_TIMECTRL_REGDEF_H__
 #define __RTL8712_TIMECTRL_REGDEF_H__
index 61a3603aa587dba40559abddeee9826e3264b0f0..d3b45c6cd855e4a87e7ff386d9410c79b40511c0 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index d9f8347ab46197c0a7b4738b5ccc23389b2d3859..662383fe7a8da34748be918498a529bdf925b059 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index fb64c2891e22016164a606cb4aecd0cc5dd77cd8..aa6fb516f398a0c26d25a980ebef056c51a068f9 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl8712_xmit.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 02b1593ada011d654f694554b5a650bfd47890f3..9be8fb70c92e2417de396474e45fe42b7384cd2a 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 620cee8b851448d1ae3c201053d00304c8349ddb..05a78ac24987c6d74e5171c1c7fe57b8c032dd49 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_cmd.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 24da2ccea04f0b735088bcb6624e725fb885f561..75a126d8e26c0cce1ffe5801d81db8a54ef4bc11 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 74468b058258320dd4110f6b39d3c2762dbf2c1d..a427547c02ba2adb31ffeca266e8e883ca2463d9 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 4e713610ad8b344e481ace1872bba9cc2a0672f8..948bd0c757b56a57eaec0a8c32e41c50ab874b50 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_eeprom.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 497276e53bbe988424b21a471dfd857b20ce36eb..7bdeb2aaa0259b83165365f114f7d2f4588adb9f 100644 (file)
@@ -1,21 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
  ******************************************************************************/
 #ifndef __RTL871X_EEPROM_H__
 #define __RTL871X_EEPROM_H__
index 517137906e6c736074f3a10cdcac306d64f03900..d9a5476d2426cc1e59dadbe5972bc4fb7b9e24f7 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 513f458ea07caf5b6c2c9d65db289d65675d4836..ebd78665775dd02862b9d20af703b0b0e67435be 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 3a10940db9b7da54cd8730ce62da06c7c24631b8..17dafeffd6f4f136e4f710ebc931f58f9606e790 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_io.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
@@ -68,7 +56,7 @@ static uint _init_intf_hdl(struct _adapter *padapter,
        set_intf_option(&pintf_hdl->intf_option);
        set_intf_funs(pintf_hdl);
        set_intf_ops(&pintf_hdl->io_ops);
-       pintf_priv->intf_dev = (u8 *)&(padapter->dvobjpriv);
+       pintf_priv->intf_dev = (u8 *)&padapter->dvobjpriv;
        if (init_intf_priv(pintf_priv) == _FAIL)
                goto _init_intf_hdl_fail;
        return _SUCCESS;
@@ -92,7 +80,7 @@ static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl)
 
        pintfhdl->intf_option = 0;
        pintfhdl->adapter = dev;
-       pintfhdl->intf_dev = (u8 *)&(adapter->dvobjpriv);
+       pintfhdl->intf_dev = (u8 *)&adapter->dvobjpriv;
        if (!_init_intf_hdl(adapter, pintfhdl))
                goto register_intf_hdl_fail;
        return _SUCCESS;
@@ -135,7 +123,7 @@ uint r8712_alloc_io_queue(struct _adapter *adapter)
                list_add_tail(&pio_req->list, &pio_queue->free_ioreqs);
                pio_req++;
        }
-       if ((register_intf_hdl((u8 *)adapter, &(pio_queue->intf))) == _FAIL)
+       if ((register_intf_hdl((u8 *)adapter, &pio_queue->intf)) == _FAIL)
                goto alloc_io_queue_fail;
        adapter->pio_queue = pio_queue;
        return _SUCCESS;
index dd054d7367b3e4aff79b36727ec1993ff5ebab2a..28941423b7ed2cc7a981b5e66057f4b5d0cebaf9 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index c3ff7c3e6681e3e328e6a6b788d5888dfc7187ef..e723357ac8c05533c163fb8cb109fc7be1558709 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_ioctl_linux.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
@@ -67,11 +55,6 @@ static const long ieee80211_wlan_frequencies[] = {
        2472, 2484
 };
 
-static const char * const iw_operation_mode[] = {
-       "Auto", "Ad-Hoc", "Managed",  "Master", "Repeater", "Secondary",
-        "Monitor"
-};
-
 void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
 {
        union iwreq_data wrqu;
@@ -1789,7 +1772,7 @@ static int r871x_wx_set_enc_ext(struct net_device *dev,
                return -ENOMEM;
        param->cmd = IEEE_CMD_SET_ENCRYPTION;
        eth_broadcast_addr(param->sta_addr);
-       strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
+       strlcpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
        if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
                param->u.crypt.set_tx = 0;
        if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
index ca769f781e96d490bdc6b5e1b5af5089550bd93c..2dc20da21679c3250e6e1f1f46ff978ec2208ade 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_ioctl_rtl.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 3bcceae3cbeb5eda99d950480543bc0078a84c47..7c0b880ac68659859c86c336c2fe4773ba8eddd4 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index f4a53df7f2c1a2cb5a6438b0235cf7b120f5990c..2622d5e3bff9b2d5852369705002b097f9c8d7cb 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_ioctl_set.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 2c94cd151c96bf880dabb9a030c587dd341cfb7f..8b1085aea9625eab81224b026ef7b36293f59555 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index adfbc400a18d92b36801d2ff34727d024068d131..ee19c873cf0109294e30e8fbda44e92d0c467a17 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index ac547ddd72d1df2d3374c6366266dbd7cebb3a26..a7374006a9fbe1eef65649377bd07f6e9aef3354 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_mlme.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 918947f3815167a2170c578b6711fd1da09c60e2..8a54181f481693dae7f098de588f1deb4cb88ee0 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index ba208a2e1e4ee48d33e13a9ca7261b5098aaa16b..1d5364f5a51890dafc9ad037f514016b010116f5 100644 (file)
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 8df452e3e3cef84a48fa7c5447bff043d50c1e32..e79a67676469d2b7fc8521b87727e4cab4666b7f 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 6e264a8d0087cb6a23ad3779fd2a0fcad4b4e828..588346da1412fc02c284a0a6b8ca871890bb292b 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_mp_ioctl.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 741006f1e45a04b34298586a711b0fe8a56b0e89..44cd911f2aa139da58c190dafaf2d87a2bc7afbe 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index ae4c9567bb55519f58472b566daca2085dd22f25..351984fe254e3f5d08dd3e886b169039bfb17266 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_pwrctrl.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index bd2c3a2df48bca854834fbd65b8623906ee776ac..11b5034f203db8cee595591b1691a5bb4a48c22b 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 2ef31a4e9a6bf07c88a392c4826955a3989a4b34..f10896df094b7359f41c3bfcba9f41a2d441eba6 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_recv.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 133ed6462928a671833181b48c574a9c3a73c905..cc54453cd4242ee9d5b702266020c47c88d44482 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 1075eacdb441a74a7947bfa151ff8c5abc11708b..f82645011d02038a7f6405b8b517a2a4e7e187f6 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_security.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 46b88a41d236643307f9f9f8a0eee29904cb7459..25b4d379766dcb093873712731c83ebd9839cf2d 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index e2d75e4c473f20a6742565daca59eff1d0d89e7a..9648ee15b40e8fe3f598796f9f9b1f847d8e5a87 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_sta_mgt.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 44924d5de2179a09f267be45f82706c4668300b2..97ea1451426c05c6c675c3b8c14f880c8ff0691c 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index a8ae14ce661394573c4e746a4002b6e3f1df2741..5c7dc9c6f76bdbb293a154450c3b65e47fd78091 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * rtl871x_xmit.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
@@ -433,7 +421,7 @@ static sint xmitframe_addmic(struct _adapter *padapter,
                                        r8712_secmicappend(&micdata, payload,
                                                           length);
                                        payload = payload + length;
-                               } else{
+                               } else {
                                        length = pxmitpriv->frag_len -
                                            pattrib->hdrlen - pattrib->iv_len -
                                            ((psecuritypriv->sw_encrypt) ?
index 40927277f498447f752740976d5a531266c2abf4..3bea2e374f137a1fec88a98b6f887b1d62144f39 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 742dfa0ca8176d9a7d1b4fa508531bcccd46509d..45dbed10295f0ccb0a339bce2e003a6642808e85 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 0b159850f5a2613d5165e81bfdc7b0fe272cffc2..02e73c2412d4f000257b0357a6406b43a16847a8 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * usb_halinit.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 85eadddfaf06092e1525c762c9c0334418844d01..92d75d7c51aed2b6b7b7fb8d59887a00022d329e 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * usb_intf.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 332e2e51d7785c002b0b5e6479377f2fd2310c50..eef52d5c730a4ce7fc733b7e8b83a940e702195d 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * usb_ops.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 78e775a46364ebcfd1fabe174e1cf81110dc4f57..d62975447d29b15f442b4c7af40d62ec37314f11 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 6d12a96fa65f2f0f00011c184664ae1bf0660349..ee5968808332cbc357dd45f4f5d1ae8c2bade81a 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * usb_ops_linux.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 609f9210cc4655291ec327fbf12fe6211b678660..ddfa405d0c9b1c424ad9e9768f3ca0af0a6bae7c 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 00a4302e9983f985a6355302b151f69efb7572ec..77346debea0377d9a83a9810e5df9d2bb3ec1990 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 9dc9ce5a2cccd75b848f4705bcc44f79c331d666..b54ccaacc527f8f1dc736f0421982c87846cf730 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 4ee4136b5c28fa34d4af7aeb90ec043a238ce74c..8bcb0775411fbaed92730e7a2fbe5e927b1fba0d 100644 (file)
@@ -1,22 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /******************************************************************************
  * xmit_linux.c
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  * Linux device driver for RTL8192SU
  *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index 8eba7ca0ddef2b36f135d7bdaac2ccd8de51d948..21f6b31e0f500fe820c309d53ad815f66c95cd76 100644 (file)
@@ -1,20 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /******************************************************************************
  *
  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
  * Modifications for inclusion into the Linux staging tree are
  * Copyright(c) 2010 Larry Finger. All rights reserved.
  *
index faf4b4158cfa2c174ea2f68c3829f7933d64c35f..2691241bfd84724335e805204d80dc7bc516285e 100644 (file)
@@ -861,7 +861,7 @@ void start_bss_network(struct adapter *padapter, u8 *pbuf)
                update_hw_ht_param(padapter);
        }
 
-       if (pmlmepriv->cur_network.join_res != true) { /* setting only at  first time */
+       if (!pmlmepriv->cur_network.join_res) { /* setting only at  first time */
 
                /* WEP Key will be set before this function, do not clear CAM. */
                if (
@@ -899,7 +899,7 @@ void start_bss_network(struct adapter *padapter, u8 *pbuf)
 
        rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
 
-       if (pmlmepriv->cur_network.join_res != true) { /* setting only at  first time */
+       if (!pmlmepriv->cur_network.join_res) { /* setting only at  first time */
 
                /* u32 initialgain; */
 
@@ -992,7 +992,7 @@ void start_bss_network(struct adapter *padapter, u8 *pbuf)
        );
 
 
-       if (true == pmlmeext->bstart_bss) {
+       if (pmlmeext->bstart_bss) {
 
                update_beacon(padapter, _TIM_IE_, NULL, true);
 
@@ -1047,7 +1047,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 
        DBG_871X("%s, len =%d\n", __func__, len);
 
-       if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
+       if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
                return _FAIL;
 
 
@@ -1379,7 +1379,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
        }
 
        /* ht_cap */
-       if (pregistrypriv->ht_enable && ht_cap == true) {
+       if (pregistrypriv->ht_enable && ht_cap) {
 
                pmlmepriv->htpriv.ht_option = true;
                pmlmepriv->qospriv.qos_option = 1;
@@ -1482,7 +1482,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
        spin_unlock_bh(&(pacl_node_q->lock));
 
 
-       if (added == true)
+       if (added)
                return ret;
 
 
@@ -1492,7 +1492,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
 
                paclnode = &pacl_list->aclnode[i];
 
-               if (paclnode->valid == false) {
+               if (!paclnode->valid) {
 
                        INIT_LIST_HEAD(&paclnode->list);
 
@@ -1547,7 +1547,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
                        !memcmp(baddr, addr, ETH_ALEN)
                ) {
 
-                       if (paclnode->valid == true) {
+                       if (paclnode->valid) {
 
                                paclnode->valid = false;
 
@@ -1912,7 +1912,7 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
        pmlmeext = &(padapter->mlmeextpriv);
        /* pmlmeinfo = &(pmlmeext->mlmext_info); */
 
-       if (false == pmlmeext->bstart_bss)
+       if (!pmlmeext->bstart_bss)
                return;
 
        spin_lock_bh(&pmlmepriv->bcn_update_lock);
@@ -1998,7 +1998,7 @@ static int rtw_ht_operation_update(struct adapter *padapter)
        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
        struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
 
-       if (pmlmepriv->htpriv.ht_option == true)
+       if (pmlmepriv->htpriv.ht_option)
                return 0;
 
        /* if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) */
@@ -2066,7 +2066,7 @@ static int rtw_ht_operation_update(struct adapter *padapter)
 void associated_clients_update(struct adapter *padapter, u8 updated)
 {
        /* update associcated stations cap. */
-       if (updated == true) {
+       if (updated) {
 
                struct list_head        *phead, *plist;
                struct sta_info *psta = NULL;
@@ -2458,7 +2458,7 @@ void sta_info_update(struct adapter *padapter, struct sta_info *psta)
                psta->htpriv.ht_option = false;
        }
 
-       if (pmlmepriv->htpriv.ht_option == false)
+       if (!pmlmepriv->htpriv.ht_option)
                psta->htpriv.ht_option = false;
 
        update_sta_info_apmode(padapter, psta);
index f852fde473503b45c78c6b23a043026c7d543531..a2a2cefd178696f9962e24fb008a38cb66649517 100644 (file)
@@ -657,7 +657,7 @@ int proc_get_suspend_resume_info(struct seq_file *m, void *v)
        DBG_871X_SEL_NL(m, "dbg_enwow_dload_fw_fail_cnt =%d\n", pdbgpriv->dbg_enwow_dload_fw_fail_cnt);
        DBG_871X_SEL_NL(m, "dbg_ips_drvopen_fail_cnt =%d\n", pdbgpriv->dbg_ips_drvopen_fail_cnt);
        DBG_871X_SEL_NL(m, "dbg_poll_fail_cnt =%d\n", pdbgpriv->dbg_poll_fail_cnt);
-       DBG_871X_SEL_NL(m, "dbg_rpwm_toogle_cnt =%d\n", pdbgpriv->dbg_rpwm_toogle_cnt);
+       DBG_871X_SEL_NL(m, "dbg_rpwm_toggle_cnt =%d\n", pdbgpriv->dbg_rpwm_toggle_cnt);
        DBG_871X_SEL_NL(m, "dbg_rpwm_timeout_fail_cnt =%d\n", pdbgpriv->dbg_rpwm_timeout_fail_cnt);
 
        return 0;
index f9392b8db49bcde74b60183252198f300ff92227..4c5d5cf9dfe0875bf135ccc6f907dbcff48a1b24 100644 (file)
@@ -802,7 +802,7 @@ int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwor
 /* TODO: Perry : For Power Management */
 void rtw_atimdone_event_callback(struct adapter        *adapter, u8 *pbuf)
 {
-       RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_evet\n"));
+       RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_event\n"));
 }
 
 
index 0952d15f6d40f66243cc8c91e7d109fb749886f2..69c7abc0e3a551af5fd0328a0f6926010a32986d 100644 (file)
@@ -1267,13 +1267,12 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
        /*  checking SSID */
        p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
                pkt_len - WLAN_HDR_A3_LEN - ie_offset);
-       if (p == NULL) {
-               status = _STATS_FAILURE_;
-       }
 
-       if (ie_len == 0) /*  broadcast ssid, however it is not allowed in assocreq */
+       if (!p || ie_len == 0) {
+               /*  broadcast ssid, however it is not allowed in assocreq */
                status = _STATS_FAILURE_;
-       else {
+               goto OnAssocReqFail;
+       } else {
                /*  check if ssid match */
                if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
                        status = _STATS_FAILURE_;
@@ -3796,7 +3795,7 @@ int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int
                        break;
 
                if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
-                       msleep(wait_ms);
+                       mdelay(wait_ms);
 
        } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
 
index 110bbe340b783fe59c4d2f849776d82cb5bd3bbf..59a667753266556a61cbd24c95249ed264d0d839 100644 (file)
@@ -1232,7 +1232,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
        if (pwrpriv->ps_processing) {
                DBG_871X("%s wait ps_processing...\n", __func__);
                while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000)
-                       msleep(10);
+                       mdelay(10);
                if (pwrpriv->ps_processing)
                        DBG_871X("%s wait ps_processing timeout\n", __func__);
                else
@@ -1244,7 +1244,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
                while (pwrpriv->bInSuspend
                        && jiffies_to_msecs(jiffies - start) <= 3000
                ) {
-                       msleep(10);
+                       mdelay(10);
                }
                if (pwrpriv->bInSuspend)
                        DBG_871X("%s wait bInSuspend timeout\n", __func__);
index 6c8ac9e86c9ff29e096b27c8f473baf447b1fcfd..240818b4a2c930460bdacb1866a1af66ec9d6371 100644 (file)
@@ -1543,7 +1543,7 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
        pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + hw_hdr_offset;
 
        /* 4 start to encrypt each fragment */
-       if ((pattrib->encrypt == _AES_)) {
+       if (pattrib->encrypt == _AES_) {
                RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_encrypt: stainfo!= NULL!!!\n"));
 
                if (IS_MCAST(pattrib->ra))
@@ -1866,8 +1866,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
 
        pframe = (unsigned char *)((union recv_frame *)precvframe)->u.hdr.rx_data;
        /* 4 start to encrypt each fragment */
-       if ((prxattrib->encrypt == _AES_)) {
-
+       if (prxattrib->encrypt == _AES_) {
                stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]);
                if (stainfo != NULL) {
                        RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_aes_decrypt: stainfo!= NULL!!!\n"));
index 0d2c61b67d0e6147b420623b80dd22db5dacfd29..12c1cd590056983d063f45889872be1b4e6502f6 100644 (file)
@@ -2919,7 +2919,6 @@ int PHY_ConfigRFWithTxPwrTrackParaFile(struct adapter *Adapter, char *pFileName)
        struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
        int     rlen = 0, rtStatus = _FAIL;
        char *szLine, *ptmp;
-       u32 i = 0;
 
        if (!(Adapter->registrypriv.load_phy_file & LOAD_RF_TXPWR_TRACK_PARA_FILE))
                return rtStatus;
@@ -2958,8 +2957,10 @@ int PHY_ConfigRFWithTxPwrTrackParaFile(struct adapter *Adapter, char *pFileName)
                                char band[5] = "", path[5] = "", sign[5] = "";
                                char chnl[5] = "", rate[10] = "";
                                char data[300] = ""; /*  100 is too small */
+                               const int len = strlen(szLine);
+                               int i;
 
-                               if (strlen(szLine) < 10 || szLine[0] != '[')
+                               if (len < 10 || szLine[0] != '[')
                                        continue;
 
                                strncpy(band, szLine+1, 2);
@@ -2973,7 +2974,7 @@ int PHY_ConfigRFWithTxPwrTrackParaFile(struct adapter *Adapter, char *pFileName)
                                if (!ParseQualifiedString(szLine, &i, chnl, '[', ']')) {
                                        /* DBG_871X("Fail to parse channel group!\n"); */
                                }
-                               while (szLine[i] != '{' && i < strlen(szLine))
+                               while (i < len && szLine[i] != '{')
                                        i++;
                                if (!ParseQualifiedString(szLine, &i, data, '{', '}')) {
                                        /* DBG_871X("Fail to parse data!\n"); */
@@ -3083,7 +3084,7 @@ static int phy_ParsePowerLimitTableFile(struct adapter *Adapter, char *buffer)
 
                        if (colNum > TXPWR_LMT_MAX_REGULATION_NUM) {
                                DBG_871X(
-                                       "unvalid col number %d (greater than max %d)\n",
+                                       "invalid col number %d (greater than max %d)\n",
                                        colNum, TXPWR_LMT_MAX_REGULATION_NUM
                                );
                                return _FAIL;
@@ -3101,7 +3102,7 @@ static int phy_ParsePowerLimitTableFile(struct adapter *Adapter, char *buffer)
                                /* DBG_871X("regulation %s!\n", regulation[forCnt]); */
 
                                if (regulation_name_cnt == 0) {
-                                       DBG_871X("unvalid number of regulation!\n");
+                                       DBG_871X("invalid number of regulation!\n");
                                        return _FAIL;
                                }
                        }
index a12fdce77eaee057af62019e1476ca3d502ac50a..4fa6cd315cf7dd9ade675a0e624550eb8c2811a8 100644 (file)
@@ -655,7 +655,7 @@ void odm_DIG(void *pDM_VOID)
                                ODM_COMP_DIG,
                                ODM_DBG_LOUD,
                                (
-                                       "odm_DIG(): Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n",
+                                       "odm_DIG(): Abnormal #beacon (%d) case in STA mode: Force lower bound to 0x%x !!!!!!\n\n",
                                        pDM_Odm->PhyDbgInfo.NumQryBeaconPkt,
                                        pDM_DigTable->rx_gain_range_min
                                )
@@ -671,7 +671,7 @@ void odm_DIG(void *pDM_VOID)
                        ODM_COMP_DIG,
                        ODM_DBG_LOUD,
                        (
-                               "odm_DIG(): Abnrormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n",
+                               "odm_DIG(): Abnormal lower bound case: Force lower bound to 0x%x !!!!!!\n\n",
                                pDM_DigTable->rx_gain_range_min
                        )
                );
index acc64fa8f166aba293bb01fa9dc9d645b2b2984b..0e674f39ef03c3aab370bf5617aa124fea5aa393 100644 (file)
@@ -97,7 +97,7 @@ void odm_EdcaTurboCheckCE(void *pDM_VOID)
                return;
        }
 
-       if ((pregpriv->wifi_spec == 1)) {
+       if (pregpriv->wifi_spec == 1) {
                precvpriv->bIsAnyNonBEPkts = false;
                return;
        }
index 592917fc00aa55d00cccc37043c12e10dc811f1e..c7e55618b9a88f6a0f8328908bed671849580121 100644 (file)
@@ -3348,7 +3348,7 @@ static void hw_var_set_opmode(struct adapter *padapter, u8 variable, u8 *val)
                        /*  disable atim wnd */
                        rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
                        /* rtw_write8(padapter, REG_BCN_CTRL, 0x18); */
-               } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) {
+               } else if (mode == _HW_STATE_ADHOC_) {
                        ResumeTxBeacon(padapter);
                        rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
                } else if (mode == _HW_STATE_AP_) {
index c57f290f605a2c6448bab55dcb6dfa40f836027e..062fda9962beda983ec72f34a781fb9d43bbc64f 100644 (file)
@@ -381,7 +381,7 @@ struct debug_priv {
        u32 dbg_enwow_dload_fw_fail_cnt;
        u32 dbg_ips_drvopen_fail_cnt;
        u32 dbg_poll_fail_cnt;
-       u32 dbg_rpwm_toogle_cnt;
+       u32 dbg_rpwm_toggle_cnt;
        u32 dbg_rpwm_timeout_fail_cnt;
        u64 dbg_rx_fifo_last_overflow;
        u64 dbg_rx_fifo_curr_overflow;
index c38298d960fffc18b3cca843ef1881de839a4629..28bfdbdc6e76aa1bcc4aecbb1b07c7a8f3483f32 100644 (file)
@@ -209,9 +209,9 @@ static char *translate_scan(struct adapter *padapter,
                i++;
        }
 
-       if (vht_cap == true) {
+       if (vht_cap) {
                max_rate = vht_data_rate;
-       } else if (ht_cap == true) {
+       } else if (ht_cap) {
                if (mcs_rate&0x8000) { /* MCS15 */
                        max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
                } else if (mcs_rate&0x0080) { /* MCS7 */
@@ -337,7 +337,7 @@ static char *translate_scan(struct adapter *padapter,
 
 
        #ifdef CONFIG_SIGNAL_DISPLAY_DBM
-       iwe.u.qual.level = (u8) translate_percentage_to_dbm(ss);/* dbm */
+       iwe.u.qual.level = (u8)translate_percentage_to_dbm(ss);/* dbm */
        #else
        #ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
        {
@@ -392,7 +392,7 @@ exit:
 
 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
 {
-       struct adapter *padapter = (struct adapter *) rtw_netdev_priv(dev);
+       struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
        int ret = 0;
 
        if ((value & WLAN_AUTH_SHARED_KEY) && (value & WLAN_AUTH_OPEN)) {
@@ -436,7 +436,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
        param->u.crypt.err = 0;
        param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
 
-       if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
+       if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
                ret =  -EINVAL;
                goto exit;
        }
@@ -528,8 +528,8 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
        }
 
        if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
-               struct sta_info * psta,*pbcmc_sta;
-               struct sta_priv * pstapriv = &padapter->stapriv;
+               struct sta_info *psta, *pbcmc_sta;
+               struct sta_priv *pstapriv = &padapter->stapriv;
 
                if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
                        psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
@@ -862,7 +862,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
                goto exit;
        }
 
-       if (padapter->hw_init_completed ==false) {
+       if (!padapter->hw_init_completed) {
                ret = -EPERM;
                goto exit;
        }
@@ -946,7 +946,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
        u8          j, blInserted = false;
        int         intReturn = false;
        struct security_priv *psecuritypriv = &padapter->securitypriv;
-        struct iw_pmksa*  pPMK = (struct iw_pmksa*) extra;
+        struct iw_pmksa*  pPMK = (struct iw_pmksa*)extra;
         u8     strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
         u8     strIssueBssid[ ETH_ALEN ] = { 0x00 };
 
@@ -1236,7 +1236,7 @@ static int rtw_wx_set_mlme(struct net_device *dev,
        int ret = 0;
        u16 reason;
        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       struct iw_mlme *mlme = (struct iw_mlme *) extra;
+       struct iw_mlme *mlme = (struct iw_mlme *)extra;
 
 
        if (mlme == NULL)
@@ -1295,7 +1295,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
                goto exit;
        }
 
-       if (padapter->hw_init_completed ==false) {
+       if (!padapter->hw_init_completed ) {
                ret = -1;
                goto exit;
        }
@@ -1303,7 +1303,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
        /*  When Busy Traffic, driver do not site survey. So driver return success. */
        /*  wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
        /*  modify by thomas 2011-02-22. */
-       if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
+       if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
                indicate_wx_scan_complete_event(padapter);
                goto exit;
        }
@@ -2390,7 +2390,7 @@ static int rtw_wx_set_channel_plan(struct net_device *dev,
                                union iwreq_data *wrqu, char *extra)
 {
        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-       u8 channel_plan_req = (u8) (*((int *)wrqu));
+       u8 channel_plan_req = (u8)(*((int *)wrqu));
 
        if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1))
                DBG_871X("%s set channel_plan = 0x%02X\n", __func__, channel_plan_req);
@@ -2584,7 +2584,7 @@ static int rtw_wps_start(struct net_device *dev,
                goto exit;
        }
 
-       uintRet = copy_from_user((void*) &u32wps_start, pdata->pointer, 4);
+       uintRet = copy_from_user((void*)&u32wps_start, pdata->pointer, 4);
        if (u32wps_start == 0)
                u32wps_start = *extra;
 
@@ -4229,7 +4229,7 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
        * so, we just check hw_init_completed
        */
 
-       if (padapter->hw_init_completed ==false) {
+       if (!padapter->hw_init_completed) {
                ret = -EPERM;
                goto out;
        }
index 6d02904de63f393d7eca2c6031ea24051993c880..7c03b69b8ed3e33b6096ebe98ffdc027a8ddea7f 100644 (file)
@@ -22,7 +22,7 @@ static const struct sdio_device_id sdio_ids[] =
        { SDIO_DEVICE(0x024c, 0xb723), },
        { /* end: all zeroes */                         },
 };
-static const struct acpi_device_id acpi_ids[] = {
+static const struct acpi_device_id acpi_ids[] __used = {
        {"OBDA8723", 0x0000},
        {}
 };
index 4d1f9bf53c53533ddfadf2187c7456f1f612bd29..24e19ffd4431d72c369e1ec44cbf76da65cb6b79 100644 (file)
@@ -281,11 +281,9 @@ bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code,
 static void halbtc_leave_lps(struct btc_coexist *btcoexist)
 {
        struct rtl_priv *rtlpriv;
-       struct rtl_ps_ctl *ppsc;
        bool ap_enable = false;
 
        rtlpriv = btcoexist->adapter;
-       ppsc = rtl_psc(rtlpriv);
 
        btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
                           &ap_enable);
@@ -304,11 +302,9 @@ static void halbtc_leave_lps(struct btc_coexist *btcoexist)
 static void halbtc_enter_lps(struct btc_coexist *btcoexist)
 {
        struct rtl_priv *rtlpriv;
-       struct rtl_ps_ctl *ppsc;
        bool ap_enable = false;
 
        rtlpriv = btcoexist->adapter;
-       ppsc = rtl_psc(rtlpriv);
 
        btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
                           &ap_enable);
@@ -1261,13 +1257,13 @@ bool exhalbtc_initlize_variables_wifi_only(struct rtl_priv *rtlpriv)
 
        switch (rtlpriv->rtlhal.interface) {
        case INTF_PCI:
-               wifionly_cfg->chip_interface = BTC_INTF_PCI;
+               wifionly_cfg->chip_interface = WIFIONLY_INTF_PCI;
                break;
        case INTF_USB:
-               wifionly_cfg->chip_interface = BTC_INTF_USB;
+               wifionly_cfg->chip_interface = WIFIONLY_INTF_USB;
                break;
        default:
-               wifionly_cfg->chip_interface = BTC_INTF_UNKNOWN;
+               wifionly_cfg->chip_interface = WIFIONLY_INTF_UNKNOWN;
                break;
        }
 
index 1dc71455f270c5539fe2aaff39a07becc9cd8560..abb0f720cf21369b4a09bfe449d23cbf2d1f01e6 100644 (file)
@@ -245,7 +245,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
        if (!efuse_word)
                goto out;
        for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
-               efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16), GFP_ATOMIC);
+               efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16),
+                                       GFP_ATOMIC);
                if (!efuse_word[i])
                        goto done;
        }
index f0c6fc8c6aca61e2a20dcfe7f6ea03f15fd0119e..7bfc9620479ad040090260bd67e908d68233ff42 100644 (file)
@@ -209,7 +209,7 @@ static int init_halmac_event_with_waittime(struct rtl_priv *rtlpriv,
        if (!rtlpriv->halmac.indicator[id].comp) {
                comp = kzalloc(sizeof(*comp), GFP_KERNEL);
                if (!comp)
-                       return -1;
+                       return -ENOMEM;
        } else {
                RT_TRACE(rtlpriv, COMP_HALMAC, DBG_LOUD,
                         "%s: <WARN> id(%d) sctx is not NULL!!\n", __func__,
@@ -359,7 +359,7 @@ static int init_priv(struct rtl_halmac *halmac)
        size = sizeof(*indicator) * count;
        indicator = kzalloc(size, GFP_KERNEL);
        if (!indicator)
-               return -1;
+               return -ENOMEM;
        halmac->indicator = indicator;
 
        return 0;
index 42020101380af38738f919c31e8de5aaad40fe7e..d6cea73fa1854bbebb5f00e6a63ae3e8c8f9fffe 100644 (file)
@@ -555,7 +555,7 @@ void phydm_lamode_trigger_setting(void *dm_void, char input[][16], u32 *_used,
                                output + used, out_len - used,
                                "{En} {0:BB,1:BB_MAC,2:RF0,3:RF1,4:MAC}\n {BB:dbg_port[bit],BB_MAC:0-ok/1-fail/2-cca,MAC:ref} {DMA type} {TrigTime}\n {polling_time/ref_mask} {dbg_port} {0:P_Edge, 1:N_Edge} {SpRate:0-80M,1-40M,2-20M} {Capture num}\n");
                        /**/
-               } else if ((is_enable_la_mode == 1)) {
+               } else if (is_enable_la_mode == 1) {
                        PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[1]);
 
                        trig_mode = (u8)var1[1];
index 3115e7bdc749aa7807e65ed71a4e775b6be4f93a..f10776fbe2d93bd1290b729396ac7814270afca1 100644 (file)
@@ -813,7 +813,7 @@ void odm_DIG(void *dm_void)
                        dig_tab->rx_gain_range_min = 0x1c;
                        ODM_RT_TRACE(
                                dm, ODM_COMP_DIG,
-                               "DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n",
+                               "DIG: Abnormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n",
                                dm->phy_dbg_info.num_qry_beacon_pkt,
                                dig_tab->rx_gain_range_min);
                }
@@ -824,7 +824,7 @@ void odm_DIG(void *dm_void)
                dig_tab->rx_gain_range_min = dig_tab->rx_gain_range_max;
                ODM_RT_TRACE(
                        dm, ODM_COMP_DIG,
-                       "DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n",
+                       "DIG: Abnormal lower bound case: Force lower bound to 0x%x\n",
                        dig_tab->rx_gain_range_min);
        }
 
index 3afd206ce4b1857d4cb6311b11c3cd71fb71bb2d..5213ca77117581e8c7864d6029d9d28444582dd6 100644 (file)
@@ -410,7 +410,7 @@ int rtl_regd_init(struct ieee80211_hw *hw,
        struct wiphy *wiphy = hw->wiphy;
        struct country_code_to_enum_rd *country = NULL;
 
-       if (!wiphy || !&rtlpriv->regd)
+       if (!wiphy)
                return -EINVAL;
 
        /* init country_code from efuse channel plan */
index a45f0eb69d3f2fdb1b14df330a5dbf8cb0ddc24d..9cb6c7906213192e78d541b3986498d42b2a5877 100644 (file)
@@ -1840,10 +1840,6 @@ struct rtl_efuse {
        u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE];
        u16 efuse_usedbytes;
        u8 efuse_usedpercentage;
-#ifdef EFUSE_REPG_WORKAROUND
-       bool efuse_re_pg_sec1flag;
-       u8 efuse_re_pg_data[8];
-#endif
 
        u8 autoload_failflag;
        u8 autoload_status;
index 3a71dbb6d24a8d1133d0f2cdcd0f418ad7f59ccc..f53adf15c685ed7fe75fd137b9caab374e33e503 100644 (file)
@@ -111,9 +111,8 @@ static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode,
        u8 val, err_code = 0;
        enum dma_data_direction dir;
 
-       if (!buf || !buf_len) {
+       if (!buf || !buf_len)
                return STATUS_FAIL;
-       }
 
        if (trans_mode == MS_TM_AUTO_READ) {
                dir = DMA_FROM_DEVICE;
@@ -162,12 +161,11 @@ static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode,
        }
 
        retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
-       if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
+
+       if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -178,9 +176,8 @@ static int ms_write_bytes(struct rtsx_chip *chip,
        struct ms_info *ms_card = &chip->ms_card;
        int retval, i;
 
-       if (!data || (data_len < cnt)) {
+       if (!data || (data_len < cnt))
                return STATUS_ERROR;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -244,9 +241,8 @@ static int ms_read_bytes(struct rtsx_chip *chip,
        int retval, i;
        u8 *ptr;
 
-       if (!data) {
+       if (!data)
                return STATUS_ERROR;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -371,14 +367,12 @@ static int ms_set_init_para(struct rtsx_chip *chip)
        }
 
        retval = switch_clock(chip, ms_card->ms_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = select_card(chip, MS_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -389,14 +383,12 @@ static int ms_switch_clock(struct rtsx_chip *chip)
        int retval;
 
        retval = select_card(chip, MS_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = switch_clock(chip, ms_card->ms_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -409,60 +401,59 @@ static int ms_pull_ctl_disable(struct rtsx_chip *chip)
                retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF,
                                             MS_D1_PD | MS_D2_PD | MS_CLK_PD |
                                             MS_D6_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF,
                                             MS_D3_PD | MS_D0_PD | MS_BS_PD |
                                             XD_D4_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF,
                                             MS_D7_PD | XD_CE_PD | XD_CLE_PD |
                                             XD_CD_PU);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF,
                                             XD_RDY_PD | SD_D3_PD | SD_D2_PD |
                                             XD_ALE_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF,
                                             MS_INS_PU | SD_WP_PD | SD_CD_PU |
                                             SD_CMD_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF,
                                             MS_D5_PD | MS_D4_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
        } else if (CHECK_PID(chip, 0x5288)) {
                if (CHECK_BARO_PKG(chip, QFN)) {
                        retval = rtsx_write_register(chip, CARD_PULL_CTL1,
                                                     0xFF, 0x55);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
+
                        retval = rtsx_write_register(chip, CARD_PULL_CTL2,
                                                     0xFF, 0x55);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
+
                        retval = rtsx_write_register(chip, CARD_PULL_CTL3,
                                                     0xFF, 0x4B);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
+
                        retval = rtsx_write_register(chip, CARD_PULL_CTL4,
                                                     0xFF, 0x69);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        }
 
@@ -502,9 +493,8 @@ static int ms_pull_ctl_enable(struct rtsx_chip *chip)
        }
 
        retval = rtsx_send_cmd(chip, MS_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -523,36 +513,31 @@ static int ms_prepare_reset(struct rtsx_chip *chip)
        ms_card->pro_under_formatting = 0;
 
        retval = ms_power_off_card3v3(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (!chip->ft2_fast_mode)
                wait_timeout(250);
 
        retval = enable_card_clock(chip, MS_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (chip->asic_code) {
                retval = ms_pull_ctl_enable(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = rtsx_write_register(chip, FPGA_PULL_CTL,
                                             FPGA_MS_PULL_CTL_BIT | 0x20, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        if (!chip->ft2_fast_mode) {
                retval = card_power_on(chip, MS_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                wait_timeout(150);
 
@@ -572,9 +557,8 @@ static int ms_prepare_reset(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN,
                                     MS_OUTPUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (chip->asic_code) {
                retval = rtsx_write_register(chip, MS_CFG, 0xFF,
@@ -582,34 +566,31 @@ static int ms_prepare_reset(struct rtsx_chip *chip)
                                             PUSH_TIME_DEFAULT |
                                             NO_EXTEND_TOGGLE |
                                             MS_BUS_WIDTH_1);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
        } else {
                retval = rtsx_write_register(chip, MS_CFG, 0xFF,
                                             SAMPLE_TIME_FALLING |
                                             PUSH_TIME_DEFAULT |
                                             NO_EXTEND_TOGGLE |
                                             MS_BUS_WIDTH_1);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
        retval = rtsx_write_register(chip, MS_TRANS_CFG, 0xFF,
                                     NO_WAIT_INT | NO_AUTO_READ_INT_REG);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        retval = rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR,
                                     MS_STOP | MS_CLR_ERR);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = ms_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -621,9 +602,8 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
        u8 val;
 
        retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
                retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG,
@@ -631,14 +611,13 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_read_register(chip, PPBUF_BASE2 + 2, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        dev_dbg(rtsx_dev(chip), "Type register: 0x%x\n", val);
        if (val != 0x01) {
                if (val != 0x02)
@@ -648,9 +627,9 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
        }
 
        retval = rtsx_read_register(chip, PPBUF_BASE2 + 4, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        dev_dbg(rtsx_dev(chip), "Category register: 0x%x\n", val);
        if (val != 0) {
                ms_card->check_ms_flow = 1;
@@ -658,15 +637,15 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
        }
 
        retval = rtsx_read_register(chip, PPBUF_BASE2 + 5, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        dev_dbg(rtsx_dev(chip), "Class register: 0x%x\n", val);
        if (val == 0) {
                retval = rtsx_read_register(chip, PPBUF_BASE2, &val);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                if (val & WRT_PRTCT)
                        chip->card_wp |= MS_CARD;
                else
@@ -682,9 +661,9 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
        ms_card->ms_type |= TYPE_MSPRO;
 
        retval = rtsx_read_register(chip, PPBUF_BASE2 + 3, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        dev_dbg(rtsx_dev(chip), "IF Mode register: 0x%x\n", val);
        if (val == 0) {
                ms_card->ms_type &= 0x0F;
@@ -720,13 +699,11 @@ static int ms_confirm_cpu_startup(struct rtsx_chip *chip)
                        if (retval == STATUS_SUCCESS)
                                break;
                }
-               if (i == MS_MAX_RETRY_COUNT) {
+               if (i == MS_MAX_RETRY_COUNT)
                        return STATUS_FAIL;
-               }
 
-               if (k > 100) {
+               if (k > 100)
                        return STATUS_FAIL;
-               }
 
                k++;
                wait_timeout(100);
@@ -737,16 +714,14 @@ static int ms_confirm_cpu_startup(struct rtsx_chip *chip)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        if (val & INT_REG_ERR) {
-               if (val & INT_REG_CMDNK) {
+               if (val & INT_REG_CMDNK)
                        chip->card_wp |= (MS_CARD);
-               } else {
+               else
                        return STATUS_FAIL;
-               }
        }
        /* --  end confirm CPU startup */
 
@@ -766,9 +741,8 @@ static int ms_switch_parallel_bus(struct rtsx_chip *chip)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -787,27 +761,24 @@ static int ms_switch_8bit_bus(struct rtsx_chip *chip)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, MS_CFG, 0x98,
                                     MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        ms_card->ms_type |= MS_8BIT;
        retval = ms_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
                retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT,
                                         1, NO_WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -820,19 +791,16 @@ static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus)
 
        for (i = 0; i < 3; i++) {
                retval = ms_prepare_reset(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_identify_media_type(chip, switch_8bit_bus);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_confirm_cpu_startup(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_switch_parallel_bus(chip);
                if (retval != STATUS_SUCCESS) {
@@ -846,25 +814,22 @@ static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus)
                }
        }
 
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        /* Switch MS-PRO into Parallel mode */
        retval = rtsx_write_register(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        retval = rtsx_write_register(chip, MS_CFG, PUSH_TIME_ODD,
                                     PUSH_TIME_ODD);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = ms_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        /* If MSPro HG Card, We shall try to switch to 8-bit bus */
        if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) {
@@ -887,9 +852,8 @@ static int msxc_change_power(struct rtsx_chip *chip, u8 mode)
        ms_cleanup_work(chip);
 
        retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        buf[0] = 0;
        buf[1] = mode;
@@ -899,22 +863,19 @@ static int msxc_change_power(struct rtsx_chip *chip, u8 mode)
        buf[5] = 0;
 
        retval = ms_write_bytes(chip, PRO_WRITE_REG, 6, NO_WAIT_INT, buf, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_read_register(chip, MS_TRANS_CFG, buf);
-       if (retval) {
+       if (retval)
                return retval;
-       }
-       if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) {
+
+       if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR))
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -936,9 +897,8 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
 #endif
 
        retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_MS8BIT(ms_card))
                data[0] = PARALLEL_8BIT_IF;
@@ -960,14 +920,12 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        buf = kmalloc(64 * 512, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
                retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT);
@@ -1150,18 +1108,15 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
 
 #ifdef SUPPORT_MSXC
        if (CHK_MSXC(ms_card)) {
-               if (class_code != 0x03) {
+               if (class_code != 0x03)
                        return STATUS_FAIL;
-               }
        } else {
-               if (class_code != 0x02) {
+               if (class_code != 0x02)
                        return STATUS_FAIL;
-               }
        }
 #else
-       if (class_code != 0x02) {
+       if (class_code != 0x02)
                return STATUS_FAIL;
-       }
 #endif
 
        if (device_type != 0x00) {
@@ -1173,9 +1128,8 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
                }
        }
 
-       if (sub_class & 0xC0) {
+       if (sub_class & 0xC0)
                return STATUS_FAIL;
-       }
 
        dev_dbg(rtsx_dev(chip), "class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n",
                class_code, device_type, sub_class);
@@ -1223,18 +1177,16 @@ retry:
        if (retval != STATUS_SUCCESS) {
                if (ms_card->switch_8bit_fail) {
                        retval = ms_pro_reset_flow(chip, 0);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                } else {
                        return STATUS_FAIL;
                }
        }
 
        retval = ms_read_attribute_info(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
 #ifdef XC_POWERCLASS
        if (CHK_HG8BIT(ms_card))
@@ -1274,9 +1226,8 @@ retry:
 
 #ifdef SUPPORT_MAGIC_GATE
        retval = mg_set_tpc_para_sub(chip, 0, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 #endif
 
        if (CHK_HG8BIT(ms_card))
@@ -1293,14 +1244,12 @@ static int ms_read_status_reg(struct rtsx_chip *chip)
        u8 val[2];
 
        retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) {
                ms_set_err_code(chip, MS_FLASH_READ_ERROR);
@@ -1319,9 +1268,8 @@ static int ms_read_extra_data(struct rtsx_chip *chip,
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_MS4BIT(ms_card)) {
                /* Parallel interface */
@@ -1342,9 +1290,8 @@ static int ms_read_extra_data(struct rtsx_chip *chip,
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -1353,15 +1300,13 @@ static int ms_read_extra_data(struct rtsx_chip *chip,
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (val & INT_REG_CMDNK) {
                ms_set_err_code(chip, MS_CMD_NK);
@@ -1370,24 +1315,21 @@ static int ms_read_extra_data(struct rtsx_chip *chip,
        if (val & INT_REG_CED) {
                if (val & INT_REG_ERR) {
                        retval = ms_read_status_reg(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
                                                    MS_EXTRA_SIZE, SystemParm,
                                                    6);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                }
        }
 
        retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT,
                               data, MS_EXTRA_SIZE);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (buf && buf_len) {
                if (buf_len > MS_EXTRA_SIZE)
@@ -1405,15 +1347,13 @@ static int ms_write_extra_data(struct rtsx_chip *chip, u16 block_addr,
        int retval, i;
        u8 val, data[16];
 
-       if (!buf || (buf_len < MS_EXTRA_SIZE)) {
+       if (!buf || (buf_len < MS_EXTRA_SIZE))
                return STATUS_FAIL;
-       }
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, 6 + MS_EXTRA_SIZE);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_MS4BIT(ms_card))
                data[0] = 0x88;
@@ -1431,20 +1371,17 @@ static int ms_write_extra_data(struct rtsx_chip *chip, u16 block_addr,
 
        retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE),
                                NO_WAIT_INT, data, 16);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (val & INT_REG_CMDNK) {
                ms_set_err_code(chip, MS_CMD_NK);
@@ -1468,9 +1405,8 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_MS4BIT(ms_card))
                data[0] = 0x88;
@@ -1484,20 +1420,17 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
        data[5] = page_num;
 
        retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (val & INT_REG_CMDNK) {
                ms_set_err_code(chip, MS_CMD_NK);
@@ -1524,13 +1457,11 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
 
        retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA,
                                 0, NO_WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
-       if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) {
+       if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR))
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1542,15 +1473,13 @@ static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk)
        u8 val, data[8], extra[MS_EXTRA_SIZE];
 
        retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, 7);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -1568,20 +1497,17 @@ static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk)
        data[7] = 0xFF;
 
        retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 7);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (val & INT_REG_CMDNK) {
                ms_set_err_code(chip, MS_CMD_NK);
@@ -1606,9 +1532,8 @@ static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk)
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -1624,21 +1549,18 @@ static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk)
        data[5] = 0;
 
        retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
 ERASE_RTY:
        retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (val & INT_REG_CMDNK) {
                if (i < 3) {
@@ -1701,9 +1623,8 @@ static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk,
 
                retval = ms_write_extra_data(chip, phy_blk, i,
                                             extra, MS_EXTRA_SIZE);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -1723,30 +1644,25 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
                start_page, end_page);
 
        retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_read_status_reg(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_read_register(chip, PPBUF_BASE2, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (val & BUF_FULL) {
                retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (!(val & INT_REG_CED)) {
                        ms_set_err_code(chip, MS_FLASH_WRITE_ERROR);
@@ -1764,9 +1680,8 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 
                retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
                                            MS_EXTRA_SIZE, SystemParm, 6);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -1783,20 +1698,17 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 
                retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT,
                                        data, 6);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                ms_set_err_code(chip, MS_NO_ERROR);
                retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (val & INT_REG_CMDNK) {
                        ms_set_err_code(chip, MS_CMD_NK);
@@ -1817,9 +1729,8 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
                                                         MS_TM_NORMAL_READ,
                                                         READ_PAGE_DATA,
                                                         0, NO_WAIT_INT);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
 
                                if (uncorrect_flag) {
                                        ms_set_page_status(log_blk, setPS_NG,
@@ -1854,9 +1765,8 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
                                        if (retval == STATUS_SUCCESS)
                                                break;
                                }
-                               if (rty_cnt == MS_MAX_RETRY_COUNT) {
+                               if (rty_cnt == MS_MAX_RETRY_COUNT)
                                        return STATUS_FAIL;
-                               }
                        }
 
                        if (!(val & INT_REG_BREQ)) {
@@ -1895,20 +1805,17 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 
                retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE),
                                        NO_WAIT_INT, data, 16);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                ms_set_err_code(chip, MS_NO_ERROR);
                retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (val & INT_REG_CMDNK) {
                        ms_set_err_code(chip, MS_CMD_NK);
@@ -1926,9 +1833,8 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
                        retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
                                                    MS_EXTRA_SIZE, SystemParm,
                                                    7);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -1947,21 +1853,18 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 
                        retval = ms_write_bytes(chip, WRITE_REG, 7,
                                                NO_WAIT_INT, data, 8);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        ms_set_err_code(chip, MS_NO_ERROR);
                        retval = ms_read_bytes(chip, GET_INT, 1,
                                               NO_WAIT_INT, &val, 1);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        if (val & INT_REG_CMDNK) {
                                ms_set_err_code(chip, MS_CMD_NK);
@@ -1992,26 +1895,23 @@ static int reset_ms(struct rtsx_chip *chip)
 #endif
 
        retval = ms_prepare_reset(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_card->ms_type |= TYPE_MS;
 
        retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_read_status_reg(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_read_register(chip, PPBUF_BASE2, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        if (val & WRT_PRTCT)
                chip->card_wp |= MS_CARD;
        else
@@ -2059,9 +1959,8 @@ RE_SEARCH:
        }
 
        retval = ms_read_page(chip, ms_card->boot_block, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        /* Read MS system information as sys_info */
        rtsx_init_cmd(chip);
@@ -2070,9 +1969,8 @@ RE_SEARCH:
                rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0);
 
        retval = rtsx_send_cmd(chip, MS_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        ptr = rtsx_get_cmd_data(chip);
        memcpy(ms_card->raw_sys_info, ptr, 96);
@@ -2094,9 +1992,8 @@ RE_SEARCH:
        rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0);
 
        retval = rtsx_send_cmd(chip, MS_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        ptr = rtsx_get_cmd_data(chip);
 
@@ -2169,33 +2066,29 @@ RE_SEARCH:
        /* Switch I/F Mode */
        if (ptr[15]) {
                retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = rtsx_write_register(chip, PPBUF_BASE2, 0xFF, 0x88);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
+
                retval = rtsx_write_register(chip, PPBUF_BASE2 + 1, 0xFF, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1,
                                         NO_WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = rtsx_write_register(chip, MS_CFG,
                                             0x58 | MS_NO_CHECK_INT,
                                             MS_BUS_WIDTH_4 |
                                             PUSH_TIME_ODD |
                                             MS_NO_CHECK_INT);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                ms_card->ms_type |= MS_4BIT;
        }
@@ -2221,28 +2114,24 @@ static int ms_init_l2p_tbl(struct rtsx_chip *chip)
 
        size = ms_card->segment_cnt * sizeof(struct zone_entry);
        ms_card->segment = vzalloc(size);
-       if (!ms_card->segment) {
+       if (!ms_card->segment)
                return STATUS_FAIL;
-       }
 
        retval = ms_read_page(chip, ms_card->boot_block, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto INIT_FAIL;
-       }
 
        reg_addr = PPBUF_BASE2;
        for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) {
                int block_no;
 
                retval = rtsx_read_register(chip, reg_addr++, &val1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto INIT_FAIL;
-               }
 
                retval = rtsx_read_register(chip, reg_addr++, &val2);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto INIT_FAIL;
-               }
 
                defect_block = ((u16)val1 << 8) | val2;
                if (defect_block == 0xFFFF)
@@ -2403,9 +2292,8 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
 
        if (!ms_card->segment) {
                retval = ms_init_l2p_tbl(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return retval;
-               }
        }
 
        if (ms_card->segment[seg_no].build_flag) {
@@ -2423,17 +2311,15 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
 
        if (!segment->l2p_table) {
                segment->l2p_table = vmalloc(array_size(table_size, 2));
-               if (!segment->l2p_table) {
+               if (!segment->l2p_table)
                        goto BUILD_FAIL;
-               }
        }
        memset((u8 *)(segment->l2p_table), 0xff, table_size * 2);
 
        if (!segment->free_table) {
                segment->free_table = vmalloc(MS_FREE_TABLE_CNT * 2);
-               if (!segment->free_table) {
+               if (!segment->free_table)
                        goto BUILD_FAIL;
-               }
        }
        memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2);
 
@@ -2558,9 +2444,8 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
                                return STATUS_SUCCESS;
                        }
                        retval = ms_init_page(chip, phy_blk, log_blk, 0, 1);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                goto BUILD_FAIL;
-                       }
 
                        segment->l2p_table[idx] = phy_blk;
                        if (seg_no == ms_card->segment_cnt - 1) {
@@ -2591,16 +2476,14 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
                                retval = ms_copy_page(chip, tmp_blk, phy_blk,
                                                      log_blk, 0,
                                                      ms_card->page_off + 1);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
 
                                segment->l2p_table[log_blk] = phy_blk;
 
                                retval = ms_set_bad_block(chip, tmp_blk);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
                        }
                }
        }
@@ -2626,14 +2509,12 @@ int reset_ms_card(struct rtsx_chip *chip)
        memset(ms_card, 0, sizeof(struct ms_info));
 
        retval = enable_card_clock(chip, MS_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = select_card(chip, MS_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_card->ms_type = 0;
 
@@ -2641,27 +2522,24 @@ int reset_ms_card(struct rtsx_chip *chip)
        if (retval != STATUS_SUCCESS) {
                if (ms_card->check_ms_flow) {
                        retval = reset_ms(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                } else {
                        return STATUS_FAIL;
                }
        }
 
        retval = ms_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (!CHK_MSPRO(ms_card)) {
                /* Build table for the last segment,
                 * to check if L2P table block exists, erasing it
                 */
                retval = ms_build_l2p_tbl(chip, seg_no);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        dev_dbg(rtsx_dev(chip), "ms_card->ms_type = 0x%x\n", ms_card->ms_type);
@@ -2690,9 +2568,8 @@ static int mspro_set_rw_cmd(struct rtsx_chip *chip,
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2731,9 +2608,8 @@ static inline int ms_auto_tune_clock(struct rtsx_chip *chip)
        }
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2782,9 +2658,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
        }
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (srb->sc_data_direction == DMA_FROM_DEVICE)
                trans_mode = MS_TM_AUTO_READ;
@@ -2792,9 +2667,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
                trans_mode = MS_TM_AUTO_WRITE;
 
        retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (ms_card->seq_mode) {
                if ((ms_card->pre_dir != srb->sc_data_direction) ||
@@ -2808,9 +2682,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
                        ms_card->total_sec_cnt = 0;
                        if (val & MS_INT_BREQ) {
                                retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
 
                                rtsx_write_register(chip, RBCTL, RB_FLUSH,
                                                    RB_FLUSH);
@@ -3019,14 +2892,12 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
        u16 para;
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        memset(buf, 0, 2);
        switch (short_data_len) {
@@ -3051,9 +2922,8 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        if (quick_format)
                para = 0x0000;
@@ -3061,18 +2931,15 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
                para = 0x0001;
 
        retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
-       if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) {
+       if (tmp & (MS_INT_CMDNK | MS_INT_ERR))
                return STATUS_FAIL;
-       }
 
        if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) {
                ms_card->pro_under_formatting = 1;
@@ -3113,9 +2980,8 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk,
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_MS4BIT(ms_card))
                data[0] = 0x88;
@@ -3134,16 +3000,14 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk,
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
 
        retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ptr = buf;
 
@@ -3156,9 +3020,8 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk,
                }
 
                retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (val & INT_REG_CMDNK) {
                        ms_set_err_code(chip, MS_CMD_NK);
@@ -3197,16 +3060,14 @@ static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk,
                if (page_addr == (end_page - 1)) {
                        if (!(val & INT_REG_CED)) {
                                retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
                        }
 
                        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT,
                                               &val, 1);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        if (!(val & INT_REG_CED)) {
                                ms_set_err_code(chip, MS_FLASH_READ_ERROR);
@@ -3280,9 +3141,8 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
        if (!start_page) {
                retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                            SystemParm, 7);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (CHK_MS4BIT(ms_card))
                        data[0] = 0x88;
@@ -3299,28 +3159,24 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
 
                retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT,
                                        data, 8);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                ms_set_err_code(chip, MS_NO_ERROR);
                retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1,
                                         NO_WAIT_INT);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE,
                                    SystemParm, (6 + MS_EXTRA_SIZE));
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -3352,23 +3208,20 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        for (i = 0; i < MS_MAX_RETRY_COUNT; i++) {
                retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT);
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        ptr = buf;
        for (page_addr = start_page; page_addr < end_page; page_addr++) {
@@ -3421,16 +3274,14 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
                        ms_set_err_code(chip, MS_TO_ERROR);
                        rtsx_clear_ms_error(chip);
 
-                       if (retval == -ETIMEDOUT) {
+                       if (retval == -ETIMEDOUT)
                                return STATUS_TIMEDOUT;
-                       }
                        return STATUS_FAIL;
                }
 
                retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if ((end_page - start_page) == 1) {
                        if (!(val & INT_REG_CED)) {
@@ -3442,16 +3293,14 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
                                if (!(val & INT_REG_CED)) {
                                        retval = ms_send_cmd(chip, BLOCK_END,
                                                             WAIT_INT);
-                                       if (retval != STATUS_SUCCESS) {
+                                       if (retval != STATUS_SUCCESS)
                                                return STATUS_FAIL;
-                                       }
                                }
 
                                retval = ms_read_bytes(chip, GET_INT, 1,
                                                       NO_WAIT_INT, &val, 1);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
                        }
 
                        if ((page_addr == (end_page - 1)) ||
@@ -3479,9 +3328,8 @@ static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 
        retval = ms_copy_page(chip, old_blk, new_blk, log_blk,
                              page_off, ms_card->page_off + 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        seg_no = old_blk >> 9;
 
@@ -3507,9 +3355,8 @@ static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
        if (start_page) {
                retval = ms_copy_page(chip, old_blk, new_blk, log_blk,
                                      0, start_page);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -3524,9 +3371,8 @@ int ms_delay_write(struct rtsx_chip *chip)
 
        if (delay_write->delay_write_flag) {
                retval = ms_set_init_para(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                delay_write->delay_write_flag = 0;
                retval = ms_finish_write(chip,
@@ -3534,9 +3380,8 @@ int ms_delay_write(struct rtsx_chip *chip)
                                        delay_write->new_phyblock,
                                        delay_write->logblock,
                                        delay_write->pageoff);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -3850,14 +3695,12 @@ static int ms_poll_int(struct rtsx_chip *chip)
        rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED);
 
        retval = rtsx_send_cmd(chip, MS_CARD, 5000);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        val = *rtsx_get_cmd_data(chip);
-       if (val & MS_INT_ERR) {
+       if (val & MS_INT_ERR)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -3920,9 +3763,8 @@ static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (i == MS_MAX_RETRY_COUNT) {
+       if (i == MS_MAX_RETRY_COUNT)
                return STATUS_FAIL;
-       }
 
        if (check_ms_err(chip)) {
                rtsx_clear_ms_error(chip);
@@ -3943,9 +3785,8 @@ static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type,
        else
                retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6);
 
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        buf[0] = 0;
        buf[1] = 0;
@@ -3957,9 +3798,8 @@ static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type,
        }
        retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6,
                                NO_WAIT_INT, buf, 6);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -3979,9 +3819,8 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = mg_send_ex_cmd(chip, MG_SET_LID, 0);
        if (retval != STATUS_SUCCESS) {
@@ -4019,14 +3858,12 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        buf = kmalloc(1540, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        buf[0] = 0x04;
        buf[1] = 0x1A;
@@ -4073,9 +3910,8 @@ int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = mg_send_ex_cmd(chip, MG_GET_ID, 0);
        if (retval != STATUS_SUCCESS) {
@@ -4148,9 +3984,8 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0);
        if (retval != STATUS_SUCCESS) {
@@ -4204,9 +4039,8 @@ int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0);
        if (retval != STATUS_SUCCESS) {
@@ -4251,14 +4085,12 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        buf = kmalloc(1028, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        buf[0] = 0x04;
        buf[1] = 0x02;
@@ -4307,14 +4139,12 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        ms_cleanup_work(chip);
 
        retval = ms_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        buf = kmalloc(1028, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        bufflen = min_t(int, 1028, scsi_bufflen(srb));
        rtsx_stor_get_xfer_buf(buf, bufflen, srb);
@@ -4433,32 +4263,28 @@ int ms_power_off_card3v3(struct rtsx_chip *chip)
        int retval;
 
        retval = disable_card_clock(chip, MS_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (chip->asic_code) {
                retval = ms_pull_ctl_disable(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = rtsx_write_register(chip, FPGA_PULL_CTL,
                                             FPGA_MS_PULL_CTL_BIT | 0x20,
                                             FPGA_MS_PULL_CTL_BIT);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
        retval = rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
+
        if (!chip->ft2_fast_mode) {
                retval = card_power_off(chip, MS_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -4486,9 +4312,8 @@ int release_ms_card(struct rtsx_chip *chip)
 #endif
 
        retval = ms_power_off_card3v3(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
index d26a8e372fce1328f0d8d8fb151ffe1522382384..6dc541e06fb9f3a91396cce3953fd843fcc60367 100644 (file)
@@ -647,9 +647,8 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
        dev_dbg(rtsx_dev(chip), "Switch SSC clock to %dMHz (cur_clk = %d)\n",
                clk, chip->cur_clk);
 
-       if ((clk <= 2) || (n > max_n)) {
+       if ((clk <= 2) || (n > max_n))
                return STATUS_FAIL;
-       }
 
        mcu_cnt = (u8)(125 / clk + 3);
        if (mcu_cnt > 7)
@@ -688,15 +687,13 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
        }
 
        retval = rtsx_send_cmd(chip, 0, WAIT_TIME);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_ERROR;
-       }
 
        udelay(10);
        retval = rtsx_write_register(chip, CLK_CTL, CLK_LOW_FREQ, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        chip->cur_clk = clk;
 
@@ -790,49 +787,41 @@ int switch_normal_clock(struct rtsx_chip *chip, int clk)
        }
 
        retval = rtsx_write_register(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if (sd_vpclk_phase_reset) {
                retval = rtsx_write_register(chip, SD_VPCLK0_CTL,
                                             PHASE_NOT_RESET, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, SD_VPCLK1_CTL,
                                             PHASE_NOT_RESET, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
        retval = rtsx_write_register(chip, CLK_DIV, 0xFF,
                                     (div << 4) | mcu_cnt);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, CLK_SEL, 0xFF, sel);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (sd_vpclk_phase_reset) {
                udelay(200);
                retval = rtsx_write_register(chip, SD_VPCLK0_CTL,
                                             PHASE_NOT_RESET, PHASE_NOT_RESET);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, SD_VPCLK1_CTL,
                                             PHASE_NOT_RESET, PHASE_NOT_RESET);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                udelay(200);
        }
        retval = rtsx_write_register(chip, CLK_CTL, 0xFF, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        chip->cur_clk = clk;
 
@@ -878,9 +867,8 @@ int enable_card_clock(struct rtsx_chip *chip, u8 card)
                clk_en |= MS_CLK_EN;
 
        retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, clk_en);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -898,9 +886,8 @@ int disable_card_clock(struct rtsx_chip *chip, u8 card)
                clk_en |= MS_CLK_EN;
 
        retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -924,9 +911,8 @@ int card_power_on(struct rtsx_chip *chip, u8 card)
        rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        udelay(chip->pmos_pwr_on_interval);
 
@@ -934,9 +920,8 @@ int card_power_on(struct rtsx_chip *chip, u8 card)
        rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -955,9 +940,8 @@ int card_power_off(struct rtsx_chip *chip, u8 card)
        }
 
        retval = rtsx_write_register(chip, CARD_PWR_CTL, mask, val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -969,9 +953,8 @@ int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
        unsigned int lun = SCSI_LUN(srb);
        int i;
 
-       if (!chip->rw_card[lun]) {
+       if (!chip->rw_card[lun])
                return STATUS_FAIL;
-       }
 
        for (i = 0; i < 3; i++) {
                chip->rw_need_retry = 0;
@@ -1009,36 +992,33 @@ int card_share_mode(struct rtsx_chip *chip, int card)
 
        if (CHECK_PID(chip, 0x5208)) {
                mask = CARD_SHARE_MASK;
-               if (card == SD_CARD) {
+               if (card == SD_CARD)
                        value = CARD_SHARE_48_SD;
-               } else if (card == MS_CARD) {
+               else if (card == MS_CARD)
                        value = CARD_SHARE_48_MS;
-               } else if (card == XD_CARD) {
+               else if (card == XD_CARD)
                        value = CARD_SHARE_48_XD;
-               } else {
+               else
                        return STATUS_FAIL;
-               }
 
        } else if (CHECK_PID(chip, 0x5288)) {
                mask = 0x03;
-               if (card == SD_CARD) {
+               if (card == SD_CARD)
                        value = CARD_SHARE_BAROSSA_SD;
-               } else if (card == MS_CARD) {
+               else if (card == MS_CARD)
                        value = CARD_SHARE_BAROSSA_MS;
-               } else if (card == XD_CARD) {
+               else if (card == XD_CARD)
                        value = CARD_SHARE_BAROSSA_XD;
-               } else {
+               else
                        return STATUS_FAIL;
-               }
 
        } else {
                return STATUS_FAIL;
        }
 
        retval = rtsx_write_register(chip, CARD_SHARE_MODE, mask, value);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1050,28 +1030,25 @@ int select_card(struct rtsx_chip *chip, int card)
        if (chip->cur_card != card) {
                u8 mod;
 
-               if (card == SD_CARD) {
+               if (card == SD_CARD)
                        mod = SD_MOD_SEL;
-               } else if (card == MS_CARD) {
+               else if (card == MS_CARD)
                        mod = MS_MOD_SEL;
-               } else if (card == XD_CARD) {
+               else if (card == XD_CARD)
                        mod = XD_MOD_SEL;
-               } else if (card == SPI_CARD) {
+               else if (card == SPI_CARD)
                        mod = SPI_MOD_SEL;
-               } else {
+               else
                        return STATUS_FAIL;
-               }
 
                retval = rtsx_write_register(chip, CARD_SELECT, 0x07, mod);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                chip->cur_card = card;
 
                retval =  card_share_mode(chip, card);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -1120,9 +1097,8 @@ int detect_card_cd(struct rtsx_chip *chip, int card)
        }
 
        status = rtsx_readl(chip, RTSX_BIPR);
-       if (!(status & card_cd)) {
+       if (!(status & card_cd))
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
index ac165d8a081cac36480d31176aed0ab020f73ff4..820b1113ea896654f0e827b57f6613ce4c9d0d13 100644 (file)
@@ -1062,9 +1062,8 @@ static inline int card_power_off_all(struct rtsx_chip *chip)
        int retval;
 
        retval = rtsx_write_register(chip, CARD_PWR_CTL, 0x0F, 0x0F);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
index 6b1234bff09cca5a85cf08610355864058717ade..94fb35429bf1c4f8dd3ccf37fdf5d8bf9c969960 100644 (file)
@@ -116,34 +116,29 @@ static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip)
                                                     0xFF,
                                                     MS_INS_PU | SD_WP_PU |
                                                     SD_CD_PU | SD_CMD_PU);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                } else {
                        retval = rtsx_write_register(chip, FPGA_PULL_CTL,
                                                     0xFF,
                                                     FPGA_SD_PULL_CTL_EN);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
                retval = rtsx_write_register(chip, CARD_SHARE_MODE, 0xFF,
                                             CARD_SHARE_48_SD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                /* Enable SDIO internal clock */
                retval = rtsx_write_register(chip, 0xFF2C, 0x01, 0x01);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                retval = rtsx_write_register(chip, SDIO_CTRL, 0xFF,
                                             SDIO_BUS_CTRL | SDIO_CD_CTRL);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                chip->sd_int = 1;
                chip->sd_io = 1;
@@ -164,16 +159,14 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
        if (chip->driver_first_load) {
                if (CHECK_PID(chip, 0x5288)) {
                        retval = rtsx_read_register(chip, 0xFE5A, &tmp);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        if (tmp & 0x08)
                                sw_bypass_sd = true;
                } else if (CHECK_PID(chip, 0x5208)) {
                        retval = rtsx_read_register(chip, 0xFE70, &tmp);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        if (tmp & 0x80)
                                sw_bypass_sd = true;
                }
@@ -192,9 +185,8 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
                u8 cd_toggle_mask = 0;
 
                retval = rtsx_read_register(chip, TLPTISTAT, &tmp);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                cd_toggle_mask = 0x08;
 
                if (tmp & cd_toggle_mask) {
@@ -202,22 +194,19 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
                        if (CHECK_PID(chip, 0x5288)) {
                                retval = rtsx_write_register(chip, 0xFE5A,
                                                             0x08, 0x00);
-                               if (retval) {
+                               if (retval)
                                        return retval;
-                               }
                        } else if (CHECK_PID(chip, 0x5208)) {
                                retval = rtsx_write_register(chip, 0xFE70,
                                                             0x80, 0x00);
-                               if (retval) {
+                               if (retval)
                                        return retval;
-                               }
                        }
 
                        retval = rtsx_write_register(chip, TLPTISTAT, 0xFF,
                                                     tmp);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
 
                        chip->need_reset |= SD_CARD;
                } else {
@@ -225,36 +214,31 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
 
                        if (chip->asic_code) {
                                retval = sd_pull_ctl_enable(chip);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
                        } else {
                                retval = rtsx_write_register
                                                (chip, FPGA_PULL_CTL,
                                                 FPGA_SD_PULL_CTL_BIT | 0x20,
                                                 0);
-                               if (retval) {
+                               if (retval)
                                        return retval;
-                               }
                        }
                        retval = card_share_mode(chip, SD_CARD);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        /* Enable sdio_bus_auto_switch */
                        if (CHECK_PID(chip, 0x5288)) {
                                retval = rtsx_write_register(chip, 0xFE5A,
                                                             0x08, 0x08);
-                               if (retval) {
+                               if (retval)
                                        return retval;
-                               }
                        } else if (CHECK_PID(chip, 0x5208)) {
                                retval = rtsx_write_register(chip, 0xFE70,
                                                             0x80, 0x80);
-                               if (retval) {
+                               if (retval)
                                        return retval;
-                               }
                        }
 
                        chip->chip_insert_with_sdio = 1;
@@ -262,9 +246,8 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
                }
        } else {
                retval = rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                chip->need_reset |= SD_CARD;
        }
@@ -283,32 +266,28 @@ static int rtsx_reset_aspm(struct rtsx_chip *chip)
 
                ret = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF,
                                        chip->aspm_l0s_l1_en);
-               if (ret != STATUS_SUCCESS) {
+               if (ret != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                return STATUS_SUCCESS;
        }
 
        if (CHECK_PID(chip, 0x5208)) {
                ret = rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, 0x3F);
-               if (ret) {
+               if (ret)
                        return ret;
-               }
        }
        ret = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en);
-       if (ret != STATUS_SUCCESS) {
+       if (ret != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        chip->aspm_level[0] = chip->aspm_l0s_l1_en;
        if (CHK_SDIO_EXIST(chip)) {
                chip->aspm_level[1] = chip->aspm_l0s_l1_en;
                ret = rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1,
                                        0xC0, 0xFF, chip->aspm_l0s_l1_en);
-               if (ret != STATUS_SUCCESS) {
+               if (ret != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        chip->aspm_enabled = 1;
@@ -327,9 +306,8 @@ static int rtsx_enable_pcie_intr(struct rtsx_chip *chip)
 
        if (chip->phy_debug_mode) {
                ret = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0);
-               if (ret) {
+               if (ret)
                        return ret;
-               }
                rtsx_disable_bus_int(chip);
        } else {
                rtsx_enable_bus_int(chip);
@@ -339,27 +317,23 @@ static int rtsx_enable_pcie_intr(struct rtsx_chip *chip)
                u16 reg;
 
                ret = rtsx_read_phy_register(chip, 0x00, &reg);
-               if (ret != STATUS_SUCCESS) {
+               if (ret != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                reg &= 0xFE7F;
                reg |= 0x80;
                ret = rtsx_write_phy_register(chip, 0x00, reg);
-               if (ret != STATUS_SUCCESS) {
+               if (ret != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                ret = rtsx_read_phy_register(chip, 0x1C, &reg);
-               if (ret != STATUS_SUCCESS) {
+               if (ret != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                reg &= 0xFFF7;
                ret = rtsx_write_phy_register(chip, 0x1C, reg);
-               if (ret != STATUS_SUCCESS) {
+               if (ret != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        if (chip->driver_first_load && (chip->ic_version < IC_VER_C))
@@ -377,100 +351,85 @@ int rtsx_reset_chip(struct rtsx_chip *chip)
        rtsx_disable_aspm(chip);
 
        retval = rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        /* Disable card clock */
        retval = rtsx_write_register(chip, CARD_CLK_EN, 0x1E, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
 #ifdef SUPPORT_OCP
        /* SSC power on, OCD power on */
        if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
                retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        } else {
                retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN,
                                             MS_OC_POWER_DOWN);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        retval = rtsx_write_register(chip, OCPPARA1, OCP_TIME_MASK,
                                     OCP_TIME_800);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, OCPPARA2, OCP_THD_MASK,
                                     OCP_THD_244_946);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, OCPCTL, 0xFF,
                                     CARD_OC_INT_EN | CARD_DETECT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 #else
        /* OC power down */
        retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN,
                                     OC_POWER_DOWN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 #endif
 
        if (!CHECK_PID(chip, 0x5288)) {
                retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0xFF, 0x03);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        /* Turn off LED */
        retval = rtsx_write_register(chip, CARD_GPIO, 0xFF, 0x03);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        /* Reset delink mode */
        retval = rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        /* Card driving select */
        retval = rtsx_write_register(chip, CARD_DRIVE_SEL, 0xFF,
                                     chip->card_drive_sel);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
 #ifdef LED_AUTO_BLINK
        retval = rtsx_write_register(chip, CARD_AUTO_BLINK, 0xFF,
                                     LED_BLINK_SPEED | BLINK_EN | LED_GPIO0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 #endif
 
        if (chip->asic_code) {
                /* Enable SSC Clock */
                retval = rtsx_write_register(chip, SSC_CTL1, 0xFF,
                                             SSC_8X_EN | SSC_SEL_4M);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, SSC_CTL2, 0xFF, 0x12);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        /*
@@ -482,72 +441,61 @@ int rtsx_reset_chip(struct rtsx_chip *chip)
         *    bit[4]    u_non_sticky_rst_n_dbg  rst_value = 0
         */
        retval = rtsx_write_register(chip, CHANGE_LINK_STATE, 0x16, 0x10);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        /* Enable ASPM */
        if (chip->aspm_l0s_l1_en) {
                retval = rtsx_reset_aspm(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                if (chip->asic_code && CHECK_PID(chip, 0x5208)) {
                        retval = rtsx_write_phy_register(chip, 0x07, 0x0129);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                }
                retval = rtsx_write_config_byte(chip, LCTLR,
                                                chip->aspm_l0s_l1_en);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        retval = rtsx_write_config_byte(chip, 0x81, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_SDIO_EXIST(chip)) {
                retval = rtsx_write_cfg_dw(chip,
                                           CHECK_PID(chip, 0x5288) ? 2 : 1,
                                           0xC0, 0xFF00, 0x0100);
 
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        if (CHECK_PID(chip, 0x5288) && !CHK_SDIO_EXIST(chip)) {
                retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        retval = rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT,
                                     LINK_RDY_INT);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = rtsx_write_register(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = rtsx_enable_pcie_intr(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        chip->need_reset = 0;
 
@@ -569,17 +517,15 @@ int rtsx_reset_chip(struct rtsx_chip *chip)
 #else  /* HW_AUTO_SWITCH_SD_BUS */
                retval = rtsx_pre_handle_sdio_old(chip);
 #endif  /* HW_AUTO_SWITCH_SD_BUS */
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
        } else {
                chip->sd_io = 0;
                retval = rtsx_write_register(chip, SDIO_CTRL,
                                             SDIO_BUS_CTRL | SDIO_CD_CTRL, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
 nextcard:
@@ -590,78 +536,67 @@ nextcard:
        if (chip->int_reg & CARD_EXIST) {
                retval = rtsx_write_register(chip, SSC_CTL1, SSC_RSTB,
                                             SSC_RSTB);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        dev_dbg(rtsx_dev(chip), "In %s, chip->need_reset = 0x%x\n", __func__,
                (unsigned int)(chip->need_reset));
 
        retval = rtsx_write_register(chip, RCCTL, 0x01, 0x00);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) {
                /* Turn off main power when entering S3/S4 state */
                retval = rtsx_write_register(chip, MAIN_PWR_OFF_CTL, 0x03,
                                             0x03);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        if (chip->remote_wakeup_en && !chip->auto_delink_en) {
                retval = rtsx_write_register(chip, WAKE_SEL_CTL, 0x07, 0x07);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if (chip->aux_pwr_exist) {
                        retval = rtsx_write_register(chip, PME_FORCE_CTL,
                                                     0xFF, 0x33);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        } else {
                retval = rtsx_write_register(chip, WAKE_SEL_CTL, 0x07, 0x04);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, PME_FORCE_CTL, 0xFF, 0x30);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) {
                retval = rtsx_write_register(chip, PETXCFG, 0x1C, 0x14);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        if (chip->asic_code && CHECK_PID(chip, 0x5208)) {
                retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        if (chip->ft2_fast_mode) {
                retval = rtsx_write_register(chip, CARD_PWR_CTL, 0xFF,
                                             MS_PARTIAL_POWER_ON |
                                             SD_PARTIAL_POWER_ON);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                udelay(chip->pmos_pwr_on_interval);
                retval = rtsx_write_register(chip, CARD_PWR_CTL, 0xFF,
                                             MS_POWER_ON | SD_POWER_ON);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                wait_timeout(200);
        }
@@ -715,20 +650,17 @@ static int rts5208_init(struct rtsx_chip *chip)
        u8 val = 0;
 
        retval = rtsx_write_register(chip, CLK_SEL, 0x03, 0x03);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_read_register(chip, CLK_SEL, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        chip->asic_code = val == 0 ? 1 : 0;
 
        if (chip->asic_code) {
                retval = rtsx_read_phy_register(chip, 0x1C, &reg);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                dev_dbg(rtsx_dev(chip), "Value of phy register 0x1C is 0x%x\n",
                        reg);
@@ -737,24 +669,21 @@ static int rts5208_init(struct rtsx_chip *chip)
 
        } else {
                retval = rtsx_read_register(chip, 0xFE80, &val);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                chip->ic_version = val;
                chip->phy_debug_mode = 0;
        }
 
        retval = rtsx_read_register(chip, PDINFO, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val);
        chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0;
 
        retval = rtsx_read_register(chip, 0xFE50, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        chip->hw_bypass_sd = val & 0x01 ? 1 : 0;
 
        rtsx_read_config_byte(chip, 0x0E, &val);
@@ -765,9 +694,8 @@ static int rts5208_init(struct rtsx_chip *chip)
 
        if (chip->use_hw_setting) {
                retval = rtsx_read_register(chip, CHANGE_LINK_STATE, &val);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                chip->auto_delink_en = val & 0x80 ? 1 : 0;
        }
 
@@ -781,42 +709,36 @@ static int rts5288_init(struct rtsx_chip *chip)
        u32 lval = 0;
 
        retval = rtsx_write_register(chip, CLK_SEL, 0x03, 0x03);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_read_register(chip, CLK_SEL, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        chip->asic_code = val == 0 ? 1 : 0;
 
        chip->ic_version = 0;
        chip->phy_debug_mode = 0;
 
        retval = rtsx_read_register(chip, PDINFO, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val);
        chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0;
 
        retval = rtsx_read_register(chip, CARD_SHARE_MODE, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        dev_dbg(rtsx_dev(chip), "CARD_SHARE_MODE: 0x%x\n", val);
        chip->baro_pkg = val & 0x04 ? QFN : LQFP;
 
        retval = rtsx_read_register(chip, 0xFE5A, &val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        chip->hw_bypass_sd = val & 0x10 ? 1 : 0;
 
        retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        max_func = (u8)((lval >> 29) & 0x07);
        dev_dbg(rtsx_dev(chip), "Max function number: %d\n", max_func);
@@ -827,9 +749,8 @@ static int rts5288_init(struct rtsx_chip *chip)
 
        if (chip->use_hw_setting) {
                retval = rtsx_read_register(chip, CHANGE_LINK_STATE, &val);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                chip->auto_delink_en = val & 0x80 ? 1 : 0;
 
                if (CHECK_BARO_PKG(chip, LQFP))
@@ -905,28 +826,24 @@ int rtsx_init_chip(struct rtsx_chip *chip)
                chip->mmc_ddr_tx_phase = 0;
 
        retval = rtsx_write_register(chip, FPDCTL, SSC_POWER_DOWN, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        wait_timeout(200);
        retval = rtsx_write_register(chip, CLK_DIV, 0x07, 0x07);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        dev_dbg(rtsx_dev(chip), "chip->use_hw_setting = %d\n",
                chip->use_hw_setting);
 
        if (CHECK_PID(chip, 0x5208)) {
                retval = rts5208_init(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
        } else if (CHECK_PID(chip, 0x5288)) {
                retval = rts5288_init(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        if (chip->ss_en == 2)
@@ -973,9 +890,8 @@ int rtsx_init_chip(struct rtsx_chip *chip)
        }
 
        retval = rtsx_reset_chip(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1403,9 +1319,8 @@ int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data)
        for (i = 0; i < MAX_RW_REG_CNT; i++) {
                val = rtsx_readl(chip, RTSX_HAIMR);
                if ((val & BIT(31)) == 0) {
-                       if (data != (u8)val) {
+                       if (data != (u8)val)
                                return STATUS_FAIL;
-                       }
 
                        return STATUS_SUCCESS;
                }
@@ -1432,9 +1347,8 @@ int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data)
                        break;
        }
 
-       if (i >= MAX_RW_REG_CNT) {
+       if (i >= MAX_RW_REG_CNT)
                return STATUS_TIMEDOUT;
-       }
 
        if (data)
                *data = (u8)(val & 0xFF);
@@ -1454,9 +1368,8 @@ int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask,
                        retval = rtsx_write_register(chip, CFGDATA0 + i,
                                                     0xFF,
                                                     (u8)(val & mask & 0xFF));
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        mode |= (1 << i);
                }
                mask >>= 8;
@@ -1465,27 +1378,23 @@ int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask,
 
        if (mode) {
                retval = rtsx_write_register(chip, CFGADDR0, 0xFF, (u8)addr);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CFGADDR1, 0xFF,
                                             (u8)(addr >> 8));
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                retval = rtsx_write_register(chip, CFGRWCTL, 0xFF,
                                             0x80 | mode |
                                             ((func_no & 0x03) << 4));
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                for (i = 0; i < MAX_RW_REG_CNT; i++) {
                        retval = rtsx_read_register(chip, CFGRWCTL, &tmp);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        if ((tmp & 0x80) == 0)
                                break;
                }
@@ -1502,33 +1411,28 @@ int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val)
        u32 data = 0;
 
        retval = rtsx_write_register(chip, CFGADDR0, 0xFF, (u8)addr);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, CFGADDR1, 0xFF, (u8)(addr >> 8));
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, CFGRWCTL, 0xFF,
                                     0x80 | ((func_no & 0x03) << 4));
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        for (i = 0; i < MAX_RW_REG_CNT; i++) {
                retval = rtsx_read_register(chip, CFGRWCTL, &tmp);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if ((tmp & 0x80) == 0)
                        break;
        }
 
        for (i = 0; i < 4; i++) {
                retval = rtsx_read_register(chip, CFGDATA0 + i, &tmp);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                data |= (u32)tmp << (i * 8);
        }
 
@@ -1547,9 +1451,8 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
        int dw_len, i, j;
        int retval;
 
-       if (!buf) {
+       if (!buf)
                return STATUS_NOMEM;
-       }
 
        if ((len + offset) % 4)
                dw_len = (len + offset) / 4 + 1;
@@ -1559,9 +1462,8 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
        dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len);
 
        data = vzalloc(array_size(dw_len, 4));
-       if (!data) {
+       if (!data)
                return STATUS_NOMEM;
-       }
 
        mask = vzalloc(array_size(dw_len, 4));
        if (!mask) {
@@ -1617,9 +1519,8 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
        dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len);
 
        data = vmalloc(array_size(dw_len, 4));
-       if (!data) {
+       if (!data)
                return STATUS_NOMEM;
-       }
 
        for (i = 0; i < dw_len; i++) {
                retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4,
@@ -1655,36 +1556,30 @@ int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val)
        u8 tmp;
 
        retval = rtsx_write_register(chip, PHYDATA0, 0xFF, (u8)val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, PHYDATA1, 0xFF, (u8)(val >> 8));
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, PHYADDR, 0xFF, addr);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, PHYRWCTL, 0xFF, 0x81);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        for (i = 0; i < 100000; i++) {
                retval = rtsx_read_register(chip, PHYRWCTL, &tmp);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if (!(tmp & 0x80)) {
                        finished = true;
                        break;
                }
        }
 
-       if (!finished) {
+       if (!finished)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1698,38 +1593,32 @@ int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val)
        u8 tmp;
 
        retval = rtsx_write_register(chip, PHYADDR, 0xFF, addr);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, PHYRWCTL, 0xFF, 0x80);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        for (i = 0; i < 100000; i++) {
                retval = rtsx_read_register(chip, PHYRWCTL, &tmp);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if (!(tmp & 0x80)) {
                        finished = true;
                        break;
                }
        }
 
-       if (!finished) {
+       if (!finished)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_read_register(chip, PHYDATA0, &tmp);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        data = tmp;
        retval = rtsx_read_register(chip, PHYDATA1, &tmp);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        data |= (u16)tmp << 8;
 
        if (val)
@@ -1745,28 +1634,24 @@ int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val)
        u8 data = 0;
 
        retval = rtsx_write_register(chip, EFUSE_CTRL, 0xFF, 0x80 | addr);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        for (i = 0; i < 100; i++) {
                retval = rtsx_read_register(chip, EFUSE_CTRL, &data);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if (!(data & 0x80))
                        break;
                udelay(1);
        }
 
-       if (data & 0x80) {
+       if (data & 0x80)
                return STATUS_TIMEDOUT;
-       }
 
        retval = rtsx_read_register(chip, EFUSE_DATA, &data);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if (val)
                *val = data;
 
@@ -1787,28 +1672,24 @@ int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val)
                dev_dbg(rtsx_dev(chip), "Write 0x%x to 0x%x\n", tmp, addr);
 
                retval = rtsx_write_register(chip, EFUSE_DATA, 0xFF, tmp);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, EFUSE_CTRL, 0xFF,
                                             0xA0 | addr);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                for (j = 0; j < 100; j++) {
                        retval = rtsx_read_register(chip, EFUSE_CTRL, &data);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        if (!(data & 0x80))
                                break;
                        wait_timeout(3);
                }
 
-               if (data & 0x80) {
+               if (data & 0x80)
                        return STATUS_TIMEDOUT;
-               }
 
                wait_timeout(5);
        }
@@ -1822,16 +1703,14 @@ int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit)
        u16 value;
 
        retval = rtsx_read_phy_register(chip, reg, &value);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (value & (1 << bit)) {
                value &= ~(1 << bit);
                retval = rtsx_write_phy_register(chip, reg, value);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -1843,16 +1722,14 @@ int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit)
        u16 value;
 
        retval = rtsx_read_phy_register(chip, reg, &value);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if ((value & (1 << bit)) == 0) {
                value |= (1 << bit);
                retval = rtsx_write_phy_register(chip, reg, value);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -2153,9 +2030,8 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
        u16 reg_addr;
        u8 *ptr;
 
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        ptr = buf;
        reg_addr = PPBUF_BASE2;
@@ -2166,9 +2042,8 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
                        rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
 
                retval = rtsx_send_cmd(chip, 0, 250);
-               if (retval < 0) {
+               if (retval < 0)
                        return STATUS_FAIL;
-               }
 
                memcpy(ptr, rtsx_get_cmd_data(chip), 256);
                ptr += 256;
@@ -2181,9 +2056,8 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
                        rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
 
                retval = rtsx_send_cmd(chip, 0, 250);
-               if (retval < 0) {
+               if (retval < 0)
                        return STATUS_FAIL;
-               }
        }
 
        memcpy(ptr, rtsx_get_cmd_data(chip), buf_len % 256);
@@ -2198,9 +2072,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
        u16 reg_addr;
        u8 *ptr;
 
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        ptr = buf;
        reg_addr = PPBUF_BASE2;
@@ -2214,9 +2087,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
                }
 
                retval = rtsx_send_cmd(chip, 0, 250);
-               if (retval < 0) {
+               if (retval < 0)
                        return STATUS_FAIL;
-               }
        }
 
        if (buf_len % 256) {
@@ -2229,9 +2101,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
                }
 
                retval = rtsx_send_cmd(chip, 0, 250);
-               if (retval < 0) {
+               if (retval < 0)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -2239,9 +2110,8 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
 
 int rtsx_check_chip_exist(struct rtsx_chip *chip)
 {
-       if (rtsx_readl(chip, 0) == 0xFFFFFFFF) {
+       if (rtsx_readl(chip, 0) == 0xFFFFFFFF)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2264,9 +2134,8 @@ int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl)
 
        if (mask) {
                retval = rtsx_write_register(chip, FPDCTL, mask, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (CHECK_PID(chip, 0x5288))
                        wait_timeout(200);
@@ -2294,9 +2163,8 @@ int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl)
        if (mask) {
                val = mask;
                retval = rtsx_write_register(chip, FPDCTL, mask, val);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
index c9a6d97938f63a91ea819def1669a913e511bb34..9c594a778425e5e8237574d231378af37b3857b9 100644 (file)
@@ -507,9 +507,8 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = vmalloc(scsi_bufflen(srb));
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
 #ifdef SUPPORT_MAGIC_GATE
        if ((chip->mspro_formatter_enable) &&
@@ -637,9 +636,8 @@ static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = vmalloc(scsi_bufflen(srb));
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        tmp = (unsigned char *)sense;
        memcpy(buf, tmp, scsi_bufflen(srb));
@@ -783,9 +781,8 @@ static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 #endif
 
        buf = kmalloc(data_size, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        page_code = srb->cmnd[2] & 0x3f;
 
@@ -999,9 +996,8 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12;
 
        buf = kmalloc(buf_len, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        buf[i++] = 0;
        buf[i++] = 0;
@@ -1076,9 +1072,8 @@ static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = kmalloc(8, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        card_size = get_card_size(chip, lun);
        buf[0] = (unsigned char)((card_size - 1) >> 24);
@@ -1116,9 +1111,8 @@ static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5];
 
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        retval = rtsx_force_power_on(chip, SSC_PDCTL);
        if (retval != STATUS_SUCCESS) {
@@ -1180,9 +1174,8 @@ static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb),
                                        len);
                buf = vmalloc(len);
-               if (!buf) {
+               if (!buf)
                        return TRANSPORT_ERROR;
-               }
 
                rtsx_stor_get_xfer_buf(buf, len, srb);
                scsi_set_resid(srb, scsi_bufflen(srb) - len);
@@ -1227,9 +1220,8 @@ static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        retval = rtsx_force_power_on(chip, SSC_PDCTL);
        if (retval != STATUS_SUCCESS) {
@@ -1282,9 +1274,8 @@ static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        rtsx_stor_get_xfer_buf(buf, len, srb);
        scsi_set_resid(srb, scsi_bufflen(srb) - len);
@@ -1702,41 +1693,35 @@ static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        if (phy_debug_mode) {
                chip->phy_debug_mode = 1;
                retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_FAILED;
-               }
 
                rtsx_disable_bus_int(chip);
 
                retval = rtsx_read_phy_register(chip, 0x1C, &reg);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_FAILED;
-               }
 
                reg |= 0x0001;
                retval = rtsx_write_phy_register(chip, 0x1C, reg);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_FAILED;
-               }
        } else {
                chip->phy_debug_mode = 0;
                retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_FAILED;
-               }
 
                rtsx_enable_bus_int(chip);
 
                retval = rtsx_read_phy_register(chip, 0x1C, &reg);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_FAILED;
-               }
 
                reg &= 0xFFFE;
                retval = rtsx_write_phy_register(chip, 0x1C, reg);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_FAILED;
-               }
        }
 
        return TRANSPORT_GOOD;
@@ -1840,9 +1825,8 @@ static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        if (len) {
                buf = vmalloc(len);
-               if (!buf) {
+               if (!buf)
                        return TRANSPORT_ERROR;
-               }
 
                retval = rtsx_force_power_on(chip, SSC_PDCTL);
                if (retval != STATUS_SUCCESS) {
@@ -1903,9 +1887,8 @@ static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                                        len);
 
                buf = vmalloc(len);
-               if (!buf) {
+               if (!buf)
                        return TRANSPORT_ERROR;
-               }
 
                rtsx_stor_get_xfer_buf(buf, len, srb);
                scsi_set_resid(srb, scsi_bufflen(srb) - len);
@@ -1999,9 +1982,8 @@ static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7];
 
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        retval = rtsx_force_power_on(chip, SSC_PDCTL);
        if (retval != STATUS_SUCCESS) {
@@ -2049,9 +2031,8 @@ static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        rtsx_stor_get_xfer_buf(buf, len, srb);
        scsi_set_resid(srb, scsi_bufflen(srb) - len);
@@ -2096,9 +2077,8 @@ static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        len = srb->cmnd[5];
 
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        retval = rtsx_force_power_on(chip, SSC_PDCTL);
        if (retval != STATUS_SUCCESS) {
@@ -2147,9 +2127,8 @@ static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        len = (u8)min_t(unsigned int, scsi_bufflen(srb), len);
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        rtsx_stor_get_xfer_buf(buf, len, srb);
        scsi_set_resid(srb, scsi_bufflen(srb) - len);
@@ -2215,29 +2194,25 @@ exit:
        vfree(buf);
 
        retval = card_power_off(chip, SPI_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_ERROR;
-       }
 
        if (chip->asic_code) {
                retval = rtsx_write_register(chip, PWR_GATE_CTRL,
                                             LDO3318_PWR_MASK, LDO_OFF);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_ERROR;
-               }
 
                wait_timeout(600);
 
                retval = rtsx_write_phy_register(chip, 0x08, val);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_ERROR;
-               }
 
                retval = rtsx_write_register(chip, PWR_GATE_CTRL,
                                             LDO3318_PWR_MASK, LDO_ON);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return TRANSPORT_ERROR;
-               }
        }
 
        return result;
@@ -2278,9 +2253,8 @@ static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        retval = rtsx_read_cfg_seq(chip, func, addr, buf, len);
        if (retval != STATUS_SUCCESS) {
@@ -2335,9 +2309,8 @@ static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len);
        buf = vmalloc(len);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        rtsx_stor_get_xfer_buf(buf, len, srb);
        scsi_set_resid(srb, scsi_bufflen(srb) - len);
@@ -2657,9 +2630,8 @@ static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir);
 
-       if (result != STATUS_SUCCESS) {
+       if (result != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
        return TRANSPORT_GOOD;
 }
@@ -2849,9 +2821,8 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = kmalloc(buf_len, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return TRANSPORT_ERROR;
-       }
 
        i = 0;
        /*  GET Memory Stick Media Information Response Header */
@@ -3025,9 +2996,8 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[8] == 0x04) &&
                    (srb->cmnd[9] == 0x1C)) {
                        retval = mg_get_local_EKB(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
@@ -3041,9 +3011,8 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[8] == 0x00) &&
                    (srb->cmnd[9] == 0x24)) {
                        retval = mg_get_rsp_chg(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
@@ -3062,9 +3031,8 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[4] == 0x00) &&
                    (srb->cmnd[5] < 32)) {
                        retval = mg_get_ICV(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
@@ -3131,9 +3099,8 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[8] == 0x00) &&
                    (srb->cmnd[9] == 0x0C)) {
                        retval = mg_set_leaf_id(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
@@ -3147,9 +3114,8 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[8] == 0x00) &&
                    (srb->cmnd[9] == 0x0C)) {
                        retval = mg_chg(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
@@ -3163,9 +3129,8 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[8] == 0x00) &&
                    (srb->cmnd[9] == 0x0C)) {
                        retval = mg_rsp(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
@@ -3184,9 +3149,8 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                    (srb->cmnd[4] == 0x00) &&
                    (srb->cmnd[5] < 32)) {
                        retval = mg_set_ICV(srb, chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else {
                        set_sense_type(chip, lun,
index e7efa34195c7b11e4ef6d251a836bd19715302af..ff1a9aa152ce9d686ee30293e0bbdca90d90c344 100644 (file)
@@ -109,9 +109,8 @@ static int sd_check_data0_status(struct rtsx_chip *chip)
        u8 stat;
 
        retval = rtsx_read_register(chip, REG_SD_STAT1, &stat);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (!(stat & SD_DAT0_STATUS)) {
                sd_set_err_code(chip, SD_BUSY);
@@ -234,9 +233,8 @@ RTY_SEND_CMD:
                if ((cmd_idx != SEND_RELATIVE_ADDR) &&
                    (cmd_idx != SEND_IF_COND)) {
                        if (cmd_idx != STOP_TRANSMISSION) {
-                               if (ptr[1] & 0x80) {
+                               if (ptr[1] & 0x80)
                                        return STATUS_FAIL;
-                               }
                        }
 #ifdef SUPPORT_SD_LOCK
                        if (ptr[1] & 0x7D) {
@@ -284,9 +282,8 @@ static int sd_read_data(struct rtsx_chip *chip,
        if (!buf)
                buf_len = 0;
 
-       if (buf_len > 512) {
+       if (buf_len > 512)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -331,9 +328,8 @@ static int sd_read_data(struct rtsx_chip *chip,
 
        if (buf && buf_len) {
                retval = rtsx_read_ppbuf(chip, buf, buf_len);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -359,9 +355,8 @@ static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode,
 
        if (buf && buf_len) {
                retval = rtsx_write_ppbuf(chip, buf, buf_len);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        rtsx_init_cmd(chip);
@@ -426,9 +421,8 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp)
                        break;
        }
 
-       if (i == 6) {
+       if (i == 6)
                return STATUS_FAIL;
-       }
 
        memcpy(sd_card->raw_csd, rsp + 1, 15);
 
@@ -543,9 +537,8 @@ static int sd_set_sample_push_timing(struct rtsx_chip *chip)
        }
 
        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x1C, val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -606,9 +599,8 @@ static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div)
                val = 0x20;
 
        retval = rtsx_write_register(chip, REG_SD_CFG1, mask, val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -619,16 +611,14 @@ static int sd_set_init_para(struct rtsx_chip *chip)
        int retval;
 
        retval = sd_set_sample_push_timing(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        sd_choose_proper_clock(chip);
 
        retval = switch_clock(chip, sd_card->sd_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -651,9 +641,8 @@ int sd_select_card(struct rtsx_chip *chip, int select)
        }
 
        retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -667,9 +656,8 @@ static int sd_update_lock_status(struct rtsx_chip *chip)
 
        retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
                                     SD_RSP_TYPE_R1, rsp, 5);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (rsp[1] & 0x02)
                sd_card->sd_lock_status |= SD_LOCKED;
@@ -679,9 +667,8 @@ static int sd_update_lock_status(struct rtsx_chip *chip)
        dev_dbg(rtsx_dev(chip), "sd_card->sd_lock_status = 0x%x\n",
                sd_card->sd_lock_status);
 
-       if (rsp[1] & 0x01) {
+       if (rsp[1] & 0x01)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -698,9 +685,8 @@ static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state,
                retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
                                             sd_card->sd_addr, SD_RSP_TYPE_R1,
                                             rsp, 5);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (((rsp[3] & 0x1E) == state) &&
                    ((rsp[3] & 0x01) == data_ready))
@@ -719,31 +705,27 @@ static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage)
                        retval = rtsx_write_phy_register(chip, 0x08,
                                                         0x4FC0 |
                                                         chip->phy_voltage);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                } else {
                        retval = rtsx_write_register(chip, SD_PAD_CTL,
                                                     SD_IO_USING_1V8, 0);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        } else if (voltage == SD_IO_1V8) {
                if (chip->asic_code) {
                        retval = rtsx_write_phy_register(chip, 0x08,
                                                         0x4C40 |
                                                         chip->phy_voltage);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                } else {
                        retval = rtsx_write_register(chip, SD_PAD_CTL,
                                                     SD_IO_USING_1V8,
                                                     SD_IO_USING_1V8);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        } else {
                return STATUS_FAIL;
@@ -760,22 +742,19 @@ static int sd_voltage_switch(struct rtsx_chip *chip)
        retval = rtsx_write_register(chip, SD_BUS_STAT,
                                     SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
                                     SD_CLK_TOGGLE_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1,
                                     NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        udelay(chip->sd_voltage_switch_delay);
 
        retval = rtsx_read_register(chip, SD_BUS_STAT, &stat);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
                                SD_DAT1_STATUS | SD_DAT0_STATUS)) {
                return STATUS_FAIL;
@@ -783,27 +762,23 @@ static int sd_voltage_switch(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, SD_BUS_STAT, 0xFF,
                                     SD_CLK_FORCE_STOP);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = sd_change_bank_voltage(chip, SD_IO_1V8);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        wait_timeout(50);
 
        retval = rtsx_write_register(chip, SD_BUS_STAT, 0xFF,
                                     SD_CLK_TOGGLE_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        wait_timeout(10);
 
        retval = rtsx_read_register(chip, SD_BUS_STAT, &stat);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
                                SD_DAT1_STATUS | SD_DAT0_STATUS)) !=
                        (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
@@ -817,9 +792,8 @@ static int sd_voltage_switch(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, SD_BUS_STAT,
                                     SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -831,23 +805,19 @@ static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir)
        if (tune_dir == TUNE_RX) {
                retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF,
                                             DCM_RESET | DCM_RX);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, DCM_RX);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        } else {
                retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF,
                                             DCM_RESET | DCM_TX);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, DCM_TX);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -877,28 +847,23 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
        if (chip->asic_code) {
                retval = rtsx_write_register(chip, CLK_CTL, CHANGE_CLK,
                                             CHANGE_CLK);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, SD_VP_CTL, 0x1F,
                                             sample_point);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, SD_VPCLK0_CTL,
                                             PHASE_NOT_RESET, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, SD_VPCLK0_CTL,
                                             PHASE_NOT_RESET, PHASE_NOT_RESET);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CLK_CTL, CHANGE_CLK, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        } else {
                rtsx_read_register(chip, SD_VP_CTL, &val);
                dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val);
@@ -909,30 +874,26 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
                        retval = rtsx_write_register(chip, SD_VP_CTL,
                                                     PHASE_CHANGE,
                                                     PHASE_CHANGE);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        udelay(50);
                        retval = rtsx_write_register(chip, SD_VP_CTL, 0xFF,
                                                     PHASE_CHANGE |
                                                     PHASE_NOT_RESET |
                                                     sample_point);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                } else {
                        retval = rtsx_write_register(chip, CLK_CTL,
                                                     CHANGE_CLK, CHANGE_CLK);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        udelay(50);
                        retval = rtsx_write_register(chip, SD_VP_CTL, 0xFF,
                                                     PHASE_NOT_RESET |
                                                     sample_point);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
                udelay(100);
 
@@ -942,45 +903,38 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
                rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL,
                             DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE);
                retval = rtsx_send_cmd(chip, SD_CARD, 100);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto fail;
-               }
 
                val = *rtsx_get_cmd_data(chip);
-               if (val & DCMPS_ERROR) {
+               if (val & DCMPS_ERROR)
                        goto fail;
-               }
 
-               if ((val & DCMPS_CURRENT_PHASE) != sample_point) {
+               if ((val & DCMPS_CURRENT_PHASE) != sample_point)
                        goto fail;
-               }
 
                retval = rtsx_write_register(chip, SD_DCMPS_CTL,
                                             DCMPS_CHANGE, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if (ddr_rx) {
                        retval = rtsx_write_register(chip, SD_VP_CTL,
                                                     PHASE_CHANGE, 0);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                } else {
                        retval = rtsx_write_register(chip, CLK_CTL,
                                                     CHANGE_CLK, 0);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
 
                udelay(50);
        }
 
        retval = rtsx_write_register(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 
@@ -1005,9 +959,8 @@ static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width)
 
        retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
                                     SD_RSP_TYPE_R1, NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        cmd[0] = 0x40 | SEND_SCR;
        cmd[1] = 0;
@@ -1024,9 +977,8 @@ static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width)
 
        memcpy(sd_card->raw_scr, buf, 8);
 
-       if ((buf[0] & 0x0F) == 0) {
+       if ((buf[0] & 0x0F) == 0)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1207,29 +1159,25 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, u8 func_group,
 
                dev_dbg(rtsx_dev(chip), "Maximum current consumption: %dmA\n",
                        cc);
-               if ((cc == 0) || (cc > 800)) {
+               if ((cc == 0) || (cc > 800))
                        return STATUS_FAIL;
-               }
 
                retval = sd_query_switch_result(chip, func_group,
                                                func_to_switch, buf, 64);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) {
                        retval = rtsx_write_register(chip, OCPPARA2,
                                                     SD_OCP_THD_MASK,
                                                     chip->sd_800mA_ocp_thd);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PWR_CTL,
                                                     PMOS_STRG_MASK,
                                                     PMOS_STRG_800mA);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        }
 
@@ -1278,9 +1226,8 @@ static int sd_check_switch(struct rtsx_chip *chip,
                        }
 
                        retval = rtsx_read_register(chip, SD_STAT1, &stat);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        if (stat & SD_CRC16_ERR) {
                                dev_dbg(rtsx_dev(chip), "SD CRC16 error when switching mode\n");
                                return STATUS_FAIL;
@@ -1293,9 +1240,8 @@ static int sd_check_switch(struct rtsx_chip *chip,
                wait_timeout(20);
        }
 
-       if (!switch_good) {
+       if (!switch_good)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1310,9 +1256,8 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
        /* Get supported functions */
        retval = sd_check_switch_mode(chip, SD_CHECK_MODE, NO_ARGUMENT,
                                      NO_ARGUMENT, bus_width);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail);
 
@@ -1394,13 +1339,11 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
        if (CHK_SD_DDR50(sd_card)) {
                retval = rtsx_write_register(chip, SD_PUSH_POINT_CTL, 0x06,
                                             0x04);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = sd_set_sample_push_timing(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        if (!func_to_switch || (func_to_switch == HS_SUPPORT)) {
@@ -1454,9 +1397,8 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
                retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch,
                                         bus_width);
                if (retval != STATUS_SUCCESS) {
-                       if (sd_check_err_code(chip, SD_NO_CARD)) {
+                       if (sd_check_err_code(chip, SD_NO_CARD))
                                return STATUS_FAIL;
-                       }
                }
                dev_dbg(rtsx_dev(chip), "Switch current limit finished! (%d)\n",
                        retval);
@@ -1464,9 +1406,8 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
 
        if (CHK_SD_DDR50(sd_card)) {
                retval = rtsx_write_register(chip, SD_PUSH_POINT_CTL, 0x06, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -1480,9 +1421,8 @@ static int sd_wait_data_idle(struct rtsx_chip *chip)
 
        for (i = 0; i < 100; i++) {
                retval = rtsx_read_register(chip, SD_DATA_STATE, &val);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                if (val & SD_DATA_IDLE) {
                        retval = STATUS_SUCCESS;
                        break;
@@ -1500,9 +1440,8 @@ static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
        u8 cmd[5];
 
        retval = sd_change_phase(chip, sample_point, TUNE_RX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        cmd[0] = 0x40 | SEND_TUNING_PATTERN;
        cmd[1] = 0;
@@ -1529,17 +1468,15 @@ static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
        u8 cmd[5];
 
        retval = sd_change_phase(chip, sample_point, TUNE_RX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        dev_dbg(rtsx_dev(chip), "sd ddr tuning rx\n");
 
        retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
                                     SD_RSP_TYPE_R1, NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        cmd[0] = 0x40 | SD_STATUS;
        cmd[1] = 0;
@@ -1573,9 +1510,8 @@ static int mmc_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
                bus_width = SD_BUS_WIDTH_1;
 
        retval = sd_change_phase(chip, sample_point, TUNE_RX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        dev_dbg(rtsx_dev(chip), "mmc ddr tuning rx\n");
 
@@ -1603,15 +1539,13 @@ static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
        int retval;
 
        retval = sd_change_phase(chip, sample_point, TUNE_TX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
                                     SD_RSP_80CLK_TIMEOUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr,
                                     SD_RSP_TYPE_R1, NULL, 0);
@@ -1625,9 +1559,8 @@ static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
 
        retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
                                     0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1639,9 +1572,8 @@ static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
        u8 cmd[5], bus_width;
 
        retval = sd_change_phase(chip, sample_point, TUNE_TX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (CHK_SD(sd_card)) {
                bus_width = SD_BUS_WIDTH_4;
@@ -1655,15 +1587,13 @@ static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
        }
 
        retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
                                     SD_RSP_80CLK_TIMEOUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        cmd[0] = 0x40 | PROGRAM_CSD;
        cmd[1] = 0;
@@ -1681,9 +1611,8 @@ static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point)
 
        retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
                                     0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1,
                            NULL, 0);
@@ -1826,11 +1755,10 @@ static int sd_tuning_rx(struct rtsx_chip *chip)
                        tuning_cmd = sd_sdr_tuning_rx_cmd;
 
        } else {
-               if (CHK_MMC_DDR52(sd_card)) {
+               if (CHK_MMC_DDR52(sd_card))
                        tuning_cmd = mmc_ddr_tuning_rx_cmd;
-               } else {
+               else
                        return STATUS_FAIL;
-               }
        }
 
        for (i = 0; i < 3; i++) {
@@ -1855,14 +1783,12 @@ static int sd_tuning_rx(struct rtsx_chip *chip)
        dev_dbg(rtsx_dev(chip), "RX phase_map = 0x%08x\n", phase_map);
 
        final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX);
-       if (final_phase == 0xFF) {
+       if (final_phase == 0xFF)
                return STATUS_FAIL;
-       }
 
        retval = sd_change_phase(chip, final_phase, TUNE_RX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1877,9 +1803,8 @@ static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
                                     SD_RSP_80CLK_TIMEOUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        phase_map = 0;
        for (i = MAX_PHASE; i >= 0; i--) {
@@ -1904,22 +1829,19 @@ static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN,
                                     0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase_map = 0x%08x\n",
                phase_map);
 
        final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
-       if (final_phase == 0xFF) {
+       if (final_phase == 0xFF)
                return STATUS_FAIL;
-       }
 
        retval = sd_change_phase(chip, final_phase, TUNE_TX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase: %d\n",
                (int)final_phase);
@@ -1943,11 +1865,10 @@ static int sd_tuning_tx(struct rtsx_chip *chip)
                        tuning_cmd = sd_sdr_tuning_tx_cmd;
 
        } else {
-               if (CHK_MMC_DDR52(sd_card)) {
+               if (CHK_MMC_DDR52(sd_card))
                        tuning_cmd = sd_ddr_tuning_tx_cmd;
-               } else {
+               else
                        return STATUS_FAIL;
-               }
        }
 
        for (i = 0; i < 3; i++) {
@@ -1974,14 +1895,12 @@ static int sd_tuning_tx(struct rtsx_chip *chip)
        dev_dbg(rtsx_dev(chip), "TX phase_map = 0x%08x\n", phase_map);
 
        final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
-       if (final_phase == 0xFF) {
+       if (final_phase == 0xFF)
                return STATUS_FAIL;
-       }
 
        retval = sd_change_phase(chip, final_phase, TUNE_TX);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1991,14 +1910,12 @@ static int sd_sdr_tuning(struct rtsx_chip *chip)
        int retval;
 
        retval = sd_tuning_tx(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = sd_tuning_rx(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2009,27 +1926,23 @@ static int sd_ddr_tuning(struct rtsx_chip *chip)
 
        if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) {
                retval = sd_ddr_pre_tuning_tx(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase,
                                         TUNE_TX);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        retval = sd_tuning_rx(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) {
                retval = sd_tuning_tx(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -2041,27 +1954,23 @@ static int mmc_ddr_tuning(struct rtsx_chip *chip)
 
        if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) {
                retval = sd_ddr_pre_tuning_tx(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase,
                                         TUNE_TX);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        retval = sd_tuning_rx(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) {
                retval = sd_tuning_tx(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -2074,14 +1983,12 @@ int sd_switch_clock(struct rtsx_chip *chip)
        int re_tuning = 0;
 
        retval = select_card(chip, SD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = switch_clock(chip, sd_card->sd_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (re_tuning) {
                if (CHK_SD(sd_card)) {
@@ -2094,9 +2001,8 @@ int sd_switch_clock(struct rtsx_chip *chip)
                                retval = mmc_ddr_tuning(chip);
                }
 
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -2126,25 +2032,21 @@ static int sd_prepare_reset(struct rtsx_chip *chip)
        chip->sd_io = 0;
 
        retval = sd_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return retval;
-       }
 
        retval = rtsx_write_register(chip, REG_SD_CFG1, 0xFF, 0x40);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR,
                                     SD_STOP | SD_CLR_ERR);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = select_card(chip, SD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2157,60 +2059,50 @@ static int sd_pull_ctl_disable(struct rtsx_chip *chip)
                retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF,
                                             XD_D3_PD | SD_D7_PD | SD_CLK_PD |
                                             SD_D5_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF,
                                             SD_D6_PD | SD_D0_PD | SD_D1_PD |
                                             XD_D5_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF,
                                             SD_D4_PD | XD_CE_PD | XD_CLE_PD |
                                             XD_CD_PU);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF,
                                             XD_RDY_PD | SD_D3_PD | SD_D2_PD |
                                             XD_ALE_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF,
                                             MS_INS_PU | SD_WP_PD | SD_CD_PU |
                                             SD_CMD_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF,
                                             MS_D5_PD | MS_D4_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        } else if (CHECK_PID(chip, 0x5288)) {
                if (CHECK_BARO_PKG(chip, QFN)) {
                        retval = rtsx_write_register(chip, CARD_PULL_CTL1,
                                                     0xFF, 0x55);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PULL_CTL2,
                                                     0xFF, 0x55);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PULL_CTL3,
                                                     0xFF, 0x4B);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PULL_CTL4,
                                                     0xFF, 0x69);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        }
 
@@ -2250,9 +2142,8 @@ int sd_pull_ctl_enable(struct rtsx_chip *chip)
        }
 
        retval = rtsx_send_cmd(chip, SD_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2262,36 +2153,31 @@ static int sd_init_power(struct rtsx_chip *chip)
        int retval;
 
        retval = sd_power_off_card3v3(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (!chip->ft2_fast_mode)
                wait_timeout(250);
 
        retval = enable_card_clock(chip, SD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (chip->asic_code) {
                retval = sd_pull_ctl_enable(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = rtsx_write_register(chip, FPGA_PULL_CTL,
                                             FPGA_SD_PULL_CTL_BIT | 0x20, 0);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        if (!chip->ft2_fast_mode) {
                retval = card_power_on(chip, SD_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                wait_timeout(260);
 
@@ -2306,9 +2192,8 @@ static int sd_init_power(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN,
                                     SD_OUTPUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2318,14 +2203,12 @@ static int sd_dummy_clock(struct rtsx_chip *chip)
        int retval;
 
        retval = rtsx_write_register(chip, REG_SD_CFG3, 0x01, 0x01);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        wait_timeout(5);
        retval = rtsx_write_register(chip, REG_SD_CFG3, 0x01, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -2373,9 +2256,8 @@ static int sd_check_wp_state(struct rtsx_chip *chip)
 
        retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
                                     SD_RSP_TYPE_R1, NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        cmd[0] = 0x40 | SD_STATUS;
        cmd[1] = 0;
@@ -2689,9 +2571,8 @@ SD_UNLOCK_ENTRY:
 
                retval = rtsx_write_register(chip, SD30_DRIVE_SEL, 0x07,
                                             chip->sd30_drive_sel_1v8);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
 
                retval = sd_set_init_para(chip);
                if (retval != STATUS_SUCCESS)
@@ -2753,14 +2634,12 @@ SD_UNLOCK_ENTRY:
        if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) {
                retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_H, 0xFF,
                                             0x02);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_L, 0xFF,
                                             0x00);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 #endif
 
@@ -2780,9 +2659,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
 
        retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL,
                                     0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return SWITCH_FAIL;
-       }
 
        if (width == MMC_8BIT_BUS) {
                buf[0] = 0x55;
@@ -2798,9 +2676,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
        }
 
        retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return SWITCH_ERR;
-       }
 
        retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, NULL, 0, byte_cnt, 1,
                               bus_width, buf, len, 100);
@@ -2811,9 +2688,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
        }
 
        retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return SWITCH_ERR;
-       }
 
        dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", BUSTEST_R);
 
@@ -2979,9 +2855,8 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, bool switch_ddr)
 
        sd_choose_proper_clock(chip);
        retval = switch_clock(chip, sd_card->sd_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        /* Test Bus Procedure */
        retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS);
@@ -3028,18 +2903,16 @@ static int reset_mmc(struct rtsx_chip *chip)
 
 switch_fail:
        retval = sd_prepare_reset(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return retval;
-       }
 
        SET_MMC(sd_card);
 
 RTY_MMC_RST:
        retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0,
                                     NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        do {
                if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
@@ -3075,9 +2948,8 @@ RTY_MMC_RST:
                i++;
        } while (!(rsp[1] & 0x80) && (i < 255));
 
-       if (i == 255) {
+       if (i == 255)
                return STATUS_FAIL;
-       }
 
        if ((rsp[1] & 0x60) == 0x40)
                SET_MMC_SECTOR_MODE(sd_card);
@@ -3086,47 +2958,40 @@ RTY_MMC_RST:
 
        retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2,
                                     NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        sd_card->sd_addr = 0x00100000;
        retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr,
                                     SD_RSP_TYPE_R6, rsp, 5);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = sd_check_csd(chip, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2;
 
        retval = sd_select_card(chip, 1);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1,
                                     NULL, 0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
 #ifdef SUPPORT_SD_LOCK
 MMC_UNLOCK_ENTRY:
        retval = sd_update_lock_status(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 #endif
 
        retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        chip->card_bus_width[chip->card2lun[SD_CARD]] = 1;
 
@@ -3136,30 +3001,26 @@ MMC_UNLOCK_ENTRY:
                        retval = mmc_switch_timing_bus(chip, switch_ddr);
                        if (retval != STATUS_SUCCESS) {
                                retval = sd_init_power(chip);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
                                sd_card->mmc_dont_switch_bus = 1;
                                goto switch_fail;
                        }
                }
 
-               if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) {
+               if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0))
                        return STATUS_FAIL;
-               }
 
                if (switch_ddr && CHK_MMC_DDR52(sd_card)) {
                        retval = sd_set_init_para(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        retval = mmc_ddr_tuning(chip);
                        if (retval != STATUS_SUCCESS) {
                                retval = sd_init_power(chip);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return STATUS_FAIL;
-                               }
 
                                switch_ddr = false;
                                goto switch_fail;
@@ -3170,9 +3031,8 @@ MMC_UNLOCK_ENTRY:
                                retval = sd_read_lba0(chip);
                                if (retval != STATUS_SUCCESS) {
                                        retval = sd_init_power(chip);
-                                       if (retval != STATUS_SUCCESS) {
+                                       if (retval != STATUS_SUCCESS)
                                                return STATUS_FAIL;
-                                       }
 
                                        switch_ddr = false;
                                        goto switch_fail;
@@ -3185,14 +3045,12 @@ MMC_UNLOCK_ENTRY:
        if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) {
                retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_H, 0xFF,
                                             0x02);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_L, 0xFF,
                                             0x00);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 #endif
 
@@ -3214,88 +3072,74 @@ int reset_sd_card(struct rtsx_chip *chip)
        chip->capacity[chip->card2lun[SD_CARD]] = 0;
 
        retval = enable_card_clock(chip, SD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (chip->ignore_sd && CHK_SDIO_EXIST(chip) &&
            !CHK_SDIO_IGNORED(chip)) {
                if (chip->asic_code) {
                        retval = sd_pull_ctl_enable(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                } else {
                        retval = rtsx_write_register(chip, FPGA_PULL_CTL,
                                                     FPGA_SD_PULL_CTL_BIT |
                                                     0x20, 0);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                }
                retval = card_share_mode(chip, SD_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                chip->sd_io = 1;
                return STATUS_FAIL;
        }
 
        retval = sd_init_power(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (chip->sd_ctl & RESET_MMC_FIRST) {
                retval = reset_mmc(chip);
                if (retval != STATUS_SUCCESS) {
-                       if (sd_check_err_code(chip, SD_NO_CARD)) {
+                       if (sd_check_err_code(chip, SD_NO_CARD))
                                return STATUS_FAIL;
-                       }
 
                        retval = reset_sd(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                }
        } else {
                retval = reset_sd(chip);
                if (retval != STATUS_SUCCESS) {
-                       if (sd_check_err_code(chip, SD_NO_CARD)) {
+                       if (sd_check_err_code(chip, SD_NO_CARD))
                                return STATUS_FAIL;
-                       }
 
-                       if (chip->sd_io) {
+                       if (chip->sd_io)
                                return STATUS_FAIL;
-                       }
                        retval = reset_mmc(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                }
        }
 
        retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_L, 0xFF, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_H, 0xFF, 2);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity;
 
        retval = sd_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        dev_dbg(rtsx_dev(chip), "sd_card->sd_type = 0x%x\n", sd_card->sd_type);
 
@@ -3321,40 +3165,33 @@ static int reset_mmc_only(struct rtsx_chip *chip)
        chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0;
 
        retval = enable_card_clock(chip, SD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = sd_init_power(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = reset_mmc(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_L, 0xFF, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_H, 0xFF, 2);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity;
 
        retval = sd_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        dev_dbg(rtsx_dev(chip), "In %s, sd_card->sd_type = 0x%x\n",
                __func__, sd_card->sd_type);
@@ -3380,9 +3217,8 @@ static int wait_data_buf_ready(struct rtsx_chip *chip)
                retval = sd_send_cmd_get_rsp(chip, SEND_STATUS,
                                             sd_card->sd_addr, SD_RSP_TYPE_R1,
                                             NULL, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                if (sd_card->sd_data_buf_ready) {
                        return sd_send_cmd_get_rsp(chip, SEND_STATUS,
@@ -3460,9 +3296,8 @@ static inline int sd_auto_tune_clock(struct rtsx_chip *chip)
        }
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -3819,9 +3654,8 @@ RTY_SEND_CMD:
 
                        if (rsp_type & SD_WAIT_BUSY_END) {
                                retval = sd_check_data0_status(chip);
-                               if (retval != STATUS_SUCCESS) {
+                               if (retval != STATUS_SUCCESS)
                                        return retval;
-                               }
                        } else {
                                sd_set_err_code(chip, SD_TO_ERR);
                        }
@@ -3859,9 +3693,8 @@ RTY_SEND_CMD:
        if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) ||
            (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) {
                if ((cmd_idx != STOP_TRANSMISSION) && !special_check) {
-                       if (ptr[1] & 0x80) {
+                       if (ptr[1] & 0x80)
                                return STATUS_FAIL;
-                       }
                }
 #ifdef SUPPORT_SD_LOCK
                if (ptr[1] & 0x7D) {
@@ -3870,15 +3703,13 @@ RTY_SEND_CMD:
 #endif
                        return STATUS_FAIL;
                }
-               if (ptr[2] & 0xF8) {
+               if (ptr[2] & 0xF8)
                        return STATUS_FAIL;
-               }
 
                if (cmd_idx == SELECT_CARD) {
                        if (rsp_type == SD_RSP_TYPE_R2) {
-                               if ((ptr[3] & 0x1E) != 0x04) {
+                               if ((ptr[3] & 0x1E) != 0x04)
                                        return STATUS_FAIL;
-                               }
                        }
                }
        }
@@ -3915,9 +3746,8 @@ int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type)
        rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0);
 
        retval = rtsx_send_cmd(chip, SD_CARD, 100);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (rsp) {
                int min_len = (rsp_len < len) ? rsp_len : len;
@@ -4057,9 +3887,8 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
        if (sd_card->pre_cmd_err) {
                sd_card->pre_cmd_err = 0;
@@ -4085,39 +3914,34 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        sd_card->last_rsp_type = rsp_type;
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
 #ifdef SUPPORT_SD_LOCK
        if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
                if (CHK_MMC_8BIT(sd_card)) {
                        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
                                                     SD_BUS_WIDTH_8);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) {
                        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
                                                     SD_BUS_WIDTH_4);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
                }
        }
 #else
        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 #endif
 
        if (standby) {
                retval = sd_select_card(chip, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_cmd_failed;
-               }
        }
 
        if (acmd) {
@@ -4125,29 +3949,25 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                                                 sd_card->sd_addr,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_cmd_failed;
-               }
        }
 
        retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type,
                                         sd_card->rsp, rsp_len, false);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto sd_execute_cmd_failed;
-       }
 
        if (standby) {
                retval = sd_select_card(chip, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_cmd_failed;
-               }
        }
 
 #ifdef SUPPORT_SD_LOCK
        retval = sd_update_lock_status(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto sd_execute_cmd_failed;
-       }
 #endif
 
        scsi_set_resid(srb, 0);
@@ -4186,9 +4006,8 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
        cmd_idx = srb->cmnd[2] & 0x3F;
        if (srb->cmnd[1] & 0x04)
@@ -4211,9 +4030,8 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        sd_card->last_rsp_type = rsp_type;
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
 #ifdef SUPPORT_SD_LOCK
        if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
@@ -4235,16 +4053,14 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
        }
 
        if (standby) {
                retval = sd_select_card(chip, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
        }
 
        if (acmd) {
@@ -4252,9 +4068,8 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                                                 sd_card->sd_addr,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
        }
 
        if (data_len <= 512) {
@@ -4273,9 +4088,8 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                cmd[4] = srb->cmnd[6];
 
                buf = kmalloc(data_len, GFP_KERNEL);
-               if (!buf) {
+               if (!buf)
                        return TRANSPORT_ERROR;
-               }
 
                retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt,
                                      blk_cnt, bus_width, buf, data_len, 2000);
@@ -4340,43 +4154,37 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto sd_execute_read_cmd_failed;
-       }
 
        if (standby) {
                retval = sd_select_card(chip, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
        }
 
        if (send_cmd12) {
                retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0,
                                                 SD_RSP_TYPE_R1b, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
        }
 
        if (data_len < 512) {
                retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
 
                retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
 
                retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_read_cmd_failed;
-               }
        }
 
        if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04))
@@ -4390,9 +4198,8 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto sd_execute_read_cmd_failed;
-       }
 
        scsi_set_resid(srb, 0);
        return TRANSPORT_GOOD;
@@ -4438,9 +4245,8 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
        cmd_idx = srb->cmnd[2] & 0x3F;
        if (srb->cmnd[1] & 0x04)
@@ -4472,48 +4278,42 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        sd_card->last_rsp_type = rsp_type;
 
        retval = sd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 
 #ifdef SUPPORT_SD_LOCK
        if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) {
                if (CHK_MMC_8BIT(sd_card)) {
                        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
                                                     SD_BUS_WIDTH_8);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
 
                } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) {
                        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03,
                                                     SD_BUS_WIDTH_4);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return TRANSPORT_FAILED;
-                       }
                }
        }
 #else
        retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return TRANSPORT_FAILED;
-       }
 #endif
 
        if (data_len < 512) {
                retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
        }
 
        if (standby) {
                retval = sd_select_card(chip, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
        }
 
        if (acmd) {
@@ -4521,25 +4321,22 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                                                 sd_card->sd_addr,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
        }
 
        retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type,
                                         sd_card->rsp, rsp_len, false);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto sd_execute_write_cmd_failed;
-       }
 
        if (data_len <= 512) {
                u16 i;
                u8 *buf;
 
                buf = kmalloc(data_len, GFP_KERNEL);
-               if (!buf) {
+               if (!buf)
                        return TRANSPORT_ERROR;
-               }
 
                rtsx_stor_get_xfer_buf(buf, data_len, srb);
 
@@ -4663,37 +4460,32 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        if (standby) {
                retval = sd_select_card(chip, 1);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
        }
 
        if (send_cmd12) {
                retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0,
                                                 SD_RSP_TYPE_R1b, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
        }
 
        if (data_len < 512) {
                retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200,
                                                 SD_RSP_TYPE_R1, NULL, 0,
                                                 false);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
 
                retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
 
                retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        goto sd_execute_write_cmd_failed;
-               }
        }
 
        if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04))
@@ -4707,9 +4499,8 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                if (retval == STATUS_SUCCESS)
                        break;
        }
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                goto sd_execute_write_cmd_failed;
-       }
 
 #ifdef SUPPORT_SD_LOCK
        if (cmd_idx == LOCK_UNLOCK) {
@@ -4888,36 +4679,31 @@ int sd_power_off_card3v3(struct rtsx_chip *chip)
        int retval;
 
        retval = disable_card_clock(chip, SD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (!chip->ft2_fast_mode) {
                retval = card_power_off(chip, SD_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                mdelay(50);
        }
 
        if (chip->asic_code) {
                retval = sd_pull_ctl_disable(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = rtsx_write_register(chip, FPGA_PULL_CTL,
                                             FPGA_SD_PULL_CTL_BIT | 0x20,
                                             FPGA_SD_PULL_CTL_BIT);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -4944,9 +4730,8 @@ int release_sd_card(struct rtsx_chip *chip)
        memset(sd_card->raw_scr, 0, 8);
 
        retval = sd_power_off_card3v3(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
index 4675668ad977d68f577e4c3edd76512a5a5bda1b..110cb9093f30d7654a8236d094519bdeaa2985d5 100644 (file)
@@ -41,14 +41,12 @@ static int spi_init(struct rtsx_chip *chip)
        retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF,
                                     CS_POLARITY_LOW | DTO_MSB_FIRST
                                     | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK,
                                     SAMPLE_DELAY_HALF);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -60,42 +58,35 @@ static int spi_set_init_para(struct rtsx_chip *chip)
 
        retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF,
                                     (u8)(spi->clk_div >> 8));
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF,
                                     (u8)(spi->clk_div));
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = switch_clock(chip, spi->spi_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = select_card(chip, SPI_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN,
                                     SPI_CLK_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN,
                                     SPI_OUTPUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        wait_timeout(10);
 
        retval = spi_init(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -247,47 +238,39 @@ static int spi_init_eeprom(struct rtsx_chip *chip)
                clk = CLK_30;
 
        retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        retval = switch_clock(chip, clk);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = select_card(chip, SPI_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN,
                                     SPI_CLK_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN,
                                     SPI_OUTPUT_EN);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        wait_timeout(10);
 
        retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF,
                                     CS_POLARITY_HIGH | SPI_EEPROM_AUTO);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK,
                                     SAMPLE_DELAY_HALF);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -306,9 +289,8 @@ static int spi_eeprom_program_enable(struct rtsx_chip *chip)
                     SPI_TRANSFER0_END);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -318,14 +300,12 @@ int spi_erase_eeprom_chip(struct rtsx_chip *chip)
        int retval;
 
        retval = spi_init_eeprom(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = spi_eeprom_program_enable(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -339,14 +319,12 @@ int spi_erase_eeprom_chip(struct rtsx_chip *chip)
                     SPI_TRANSFER0_END);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -356,14 +334,12 @@ int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
        int retval;
 
        retval = spi_init_eeprom(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = spi_eeprom_program_enable(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -379,14 +355,12 @@ int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
                     SPI_TRANSFER0_END);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -397,9 +371,8 @@ int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
        u8 data;
 
        retval = spi_init_eeprom(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -416,23 +389,20 @@ int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
                     SPI_TRANSFER0_END);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        wait_timeout(5);
        retval = rtsx_read_register(chip, SPI_DATA, &data);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (val)
                *val = data;
 
        retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -442,14 +412,12 @@ int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
        int retval;
 
        retval = spi_init_eeprom(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = spi_eeprom_program_enable(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -466,14 +434,12 @@ int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
                     SPI_TRANSFER0_END);
 
        retval = rtsx_send_cmd(chip, 0, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -577,9 +543,8 @@ int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        if (len) {
                buf = kmalloc(len, GFP_KERNEL);
-               if (!buf) {
+               if (!buf)
                        return STATUS_ERROR;
-               }
 
                retval = rtsx_read_ppbuf(chip, buf, len);
                if (retval != STATUS_SUCCESS) {
@@ -621,9 +586,8 @@ int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
-       if (!buf) {
+       if (!buf)
                return STATUS_ERROR;
-       }
 
        while (len) {
                u16 pagelen = SF_PAGE_LEN - (u8)addr;
@@ -716,9 +680,8 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        if (program_mode == BYTE_PROGRAM) {
                buf = kmalloc(4, GFP_KERNEL);
-               if (!buf) {
+               if (!buf)
                        return STATUS_ERROR;
-               }
 
                while (len) {
                        retval = sf_enable_write(chip, SPI_WREN);
@@ -762,14 +725,12 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                int first_byte = 1;
 
                retval = sf_enable_write(chip, SPI_WREN);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                buf = kmalloc(4, GFP_KERNEL);
-               if (!buf) {
+               if (!buf)
                        return STATUS_ERROR;
-               }
 
                while (len) {
                        rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset,
@@ -808,19 +769,16 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
                kfree(buf);
 
                retval = sf_disable_write(chip, SPI_WRDI);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = sf_polling_status(chip, 100);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else if (program_mode == PAGE_PROGRAM) {
                buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
-               if (!buf) {
+               if (!buf)
                        return STATUS_NOMEM;
-               }
 
                while (len) {
                        u16 pagelen = SF_PAGE_LEN - (u8)addr;
@@ -893,24 +851,20 @@ int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
 
        if (erase_mode == PAGE_ERASE) {
                retval = sf_enable_write(chip, SPI_WREN);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = sf_erase(chip, ins, 1, addr);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else if (erase_mode == CHIP_ERASE) {
                retval = sf_enable_write(chip, SPI_WREN);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                retval = sf_erase(chip, ins, 0, 0);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                spi_set_err_code(chip, SPI_INVALID_COMMAND);
                return STATUS_FAIL;
@@ -935,9 +889,8 @@ int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
        }
 
        retval = sf_enable_write(chip, ewsr);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
index 261d868a30725854980770fa8db4975343f061d9..d71f19ceb6fa4ca7be1ec197c6214213e4b3b1ce 100644 (file)
@@ -60,9 +60,8 @@ static int xd_set_init_para(struct rtsx_chip *chip)
                xd_card->xd_clock = CLK_50;
 
        retval = switch_clock(chip, xd_card->xd_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -73,14 +72,12 @@ static int xd_switch_clock(struct rtsx_chip *chip)
        int retval;
 
        retval = select_card(chip, XD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = switch_clock(chip, xd_card->xd_clock);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -102,9 +99,8 @@ static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len)
                rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0);
 
        retval = rtsx_send_cmd(chip, XD_CARD, 20);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        ptr = rtsx_get_cmd_data(chip) + 1;
        if (id_buf && buf_len) {
@@ -173,9 +169,8 @@ static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr,
        rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0);
 
        retval = rtsx_send_cmd(chip, XD_CARD, 500);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        if (buf && buf_len) {
                u8 *ptr = rtsx_get_cmd_data(chip) + 1;
@@ -193,9 +188,8 @@ static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset,
 {
        int retval, i;
 
-       if (!buf || (buf_len < 0)) {
+       if (!buf || (buf_len < 0))
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -220,9 +214,8 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,
        int retval;
        u8 reg;
 
-       if (!buf || (buf_len < 10)) {
+       if (!buf || (buf_len < 10))
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -246,36 +239,31 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,
        }
 
        retval = rtsx_read_register(chip, XD_PAGE_STATUS, &reg);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if (reg != XD_GPG) {
                rtsx_clear_xd_error(chip);
                return STATUS_FAIL;
        }
 
        retval = rtsx_read_register(chip, XD_CTL, &reg);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) {
                retval = xd_read_data_from_ppb(chip, 0, buf, buf_len);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
                if (reg & XD_ECC1_ERROR) {
                        u8 ecc_bit, ecc_byte;
 
                        retval = rtsx_read_register(chip, XD_ECC_BIT1,
                                                    &ecc_bit);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_read_register(chip, XD_ECC_BYTE1,
                                                    &ecc_byte);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
 
                        dev_dbg(rtsx_dev(chip), "ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n",
                                ecc_bit, ecc_byte);
@@ -291,22 +279,19 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,
                rtsx_clear_xd_error(chip);
 
                retval = xd_read_data_from_ppb(chip, 256, buf, buf_len);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
                if (reg & XD_ECC2_ERROR) {
                        u8 ecc_bit, ecc_byte;
 
                        retval = rtsx_read_register(chip, XD_ECC_BIT2,
                                                    &ecc_bit);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_read_register(chip, XD_ECC_BYTE2,
                                                    &ecc_byte);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
 
                        dev_dbg(rtsx_dev(chip), "ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n",
                                ecc_bit, ecc_byte);
@@ -404,68 +389,58 @@ static int xd_pull_ctl_disable(struct rtsx_chip *chip)
                                             XD_D2_PD |
                                             XD_D1_PD |
                                             XD_D0_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF,
                                             XD_D7_PD |
                                             XD_D6_PD |
                                             XD_D5_PD |
                                             XD_D4_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF,
                                             XD_WP_PD |
                                             XD_CE_PD |
                                             XD_CLE_PD |
                                             XD_CD_PU);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF,
                                             XD_RDY_PD |
                                             XD_WE_PD |
                                             XD_RE_PD |
                                             XD_ALE_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF,
                                             MS_INS_PU |
                                             SD_WP_PD |
                                             SD_CD_PU |
                                             SD_CMD_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
                retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF,
                                             MS_D5_PD | MS_D4_PD);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        } else if (CHECK_PID(chip, 0x5288)) {
                if (CHECK_BARO_PKG(chip, QFN)) {
                        retval = rtsx_write_register(chip, CARD_PULL_CTL1,
                                                     0xFF, 0x55);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PULL_CTL2,
                                                     0xFF, 0x55);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PULL_CTL3,
                                                     0xFF, 0x4B);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                        retval = rtsx_write_register(chip, CARD_PULL_CTL4,
                                                     0xFF, 0x69);
-                       if (retval) {
+                       if (retval)
                                return retval;
-                       }
                }
        }
 
@@ -479,9 +454,8 @@ static int reset_xd(struct rtsx_chip *chip)
        u8 *ptr, id_buf[4], redunt[11];
 
        retval = select_card(chip, XD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -505,15 +479,13 @@ static int reset_xd(struct rtsx_chip *chip)
        rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0);
 
        retval = rtsx_send_cmd(chip, XD_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        if (!chip->ft2_fast_mode) {
                retval = card_power_off(chip, XD_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                wait_timeout(250);
 
@@ -529,14 +501,12 @@ static int reset_xd(struct rtsx_chip *chip)
                }
 
                retval = rtsx_send_cmd(chip, XD_CARD, 100);
-               if (retval < 0) {
+               if (retval < 0)
                        return STATUS_FAIL;
-               }
 
                retval = card_power_on(chip, XD_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
 #ifdef SUPPORT_OCP
                wait_timeout(50);
@@ -565,17 +535,15 @@ static int reset_xd(struct rtsx_chip *chip)
        rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN);
 
        retval = rtsx_send_cmd(chip, XD_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        if (!chip->ft2_fast_mode)
                wait_timeout(200);
 
        retval = xd_set_init_para(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        /* Read ID to check if the timing setting is right */
        for (i = 0; i < 4; i++) {
@@ -598,9 +566,8 @@ static int reset_xd(struct rtsx_chip *chip)
                rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
 
                retval = rtsx_send_cmd(chip, XD_CARD, 100);
-               if (retval < 0) {
+               if (retval < 0)
                        return STATUS_FAIL;
-               }
 
                ptr = rtsx_get_cmd_data(chip) + 1;
 
@@ -612,9 +579,8 @@ static int reset_xd(struct rtsx_chip *chip)
                        continue;
 
                retval = xd_read_id(chip, READ_ID, id_buf, 4);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                dev_dbg(rtsx_dev(chip), "READ_ID: 0x%x 0x%x 0x%x 0x%x\n",
                        id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
@@ -694,9 +660,8 @@ static int reset_xd(struct rtsx_chip *chip)
                /* Confirm timing setting */
                for (j = 0; j < 10; j++) {
                        retval = xd_read_id(chip, READ_ID, id_buf, 4);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        if (id_buf[1] != xd_card->device_code)
                                break;
@@ -716,22 +681,19 @@ static int reset_xd(struct rtsx_chip *chip)
        }
 
        retval = xd_read_id(chip, READ_xD_ID, id_buf, 4);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
        dev_dbg(rtsx_dev(chip), "READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n",
                id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
-       if (id_buf[2] != XD_ID_CODE) {
+       if (id_buf[2] != XD_ID_CODE)
                return STATUS_FAIL;
-       }
 
        /* Search CIS block */
        for (i = 0; i < 24; i++) {
                u32 page_addr;
 
-               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
+               if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                page_addr = (u32)i << xd_card->block_shift;
 
@@ -769,9 +731,8 @@ static int reset_xd(struct rtsx_chip *chip)
                        page_addr += j;
 
                        retval = xd_read_cis(chip, page_addr, buf, 10);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
 
                        if ((buf[0] == 0x01) && (buf[1] == 0x03) &&
                            (buf[2] == 0xD9) &&
@@ -841,17 +802,15 @@ static int xd_init_l2p_tbl(struct rtsx_chip *chip)
        dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__,
                xd_card->zone_cnt);
 
-       if (xd_card->zone_cnt < 1) {
+       if (xd_card->zone_cnt < 1)
                return STATUS_FAIL;
-       }
 
        size = xd_card->zone_cnt * sizeof(struct zone_entry);
        dev_dbg(rtsx_dev(chip), "Buffer size for l2p table is %d\n", size);
 
        xd_card->zone = vmalloc(size);
-       if (!xd_card->zone) {
+       if (!xd_card->zone)
                return STATUS_ERROR;
-       }
 
        for (i = 0; i < xd_card->zone_cnt; i++) {
                xd_card->zone[i].build_flag = 0;
@@ -1028,19 +987,16 @@ int reset_xd_card(struct rtsx_chip *chip)
        xd_card->delay_write.delay_write_flag = 0;
 
        retval = enable_card_clock(chip, XD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = reset_xd(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = xd_init_l2p_tbl(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1054,9 +1010,8 @@ static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk)
 
        dev_dbg(rtsx_dev(chip), "mark block 0x%x as bad block\n", phy_blk);
 
-       if (phy_blk == BLK_NOT_FOUND) {
+       if (phy_blk == BLK_NOT_FOUND)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -1107,12 +1062,10 @@ static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk,
 
        dev_dbg(rtsx_dev(chip), "Init block 0x%x\n", phy_blk);
 
-       if (start_page > end_page) {
+       if (start_page > end_page)
                return STATUS_FAIL;
-       }
-       if (phy_blk == BLK_NOT_FOUND) {
+       if (phy_blk == BLK_NOT_FOUND)
                return STATUS_FAIL;
-       }
 
        rtsx_init_cmd(chip);
 
@@ -1164,13 +1117,11 @@ static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,
        dev_dbg(rtsx_dev(chip), "Copy page from block 0x%x to block 0x%x\n",
                old_blk, new_blk);
 
-       if (start_page > end_page) {
+       if (start_page > end_page)
                return STATUS_FAIL;
-       }
 
-       if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) {
+       if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND))
                return STATUS_FAIL;
-       }
 
        old_page = (old_blk << xd_card->block_shift) + start_page;
        new_page = (new_blk << xd_card->block_shift) + start_page;
@@ -1179,9 +1130,8 @@ static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,
 
        retval = rtsx_write_register(chip, CARD_DATA_SOURCE, 0x01,
                                     PINGPONG_BUFFER);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        for (i = start_page; i < end_page; i++) {
                if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
@@ -1287,9 +1237,8 @@ static int xd_reset_cmd(struct rtsx_chip *chip)
        rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0);
 
        retval = rtsx_send_cmd(chip, XD_CARD, 100);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        ptr = rtsx_get_cmd_data(chip) + 1;
        if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY))
@@ -1305,9 +1254,8 @@ static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)
        u8 reg = 0, *ptr;
        int i, retval;
 
-       if (phy_blk == BLK_NOT_FOUND) {
+       if (phy_blk == BLK_NOT_FOUND)
                return STATUS_FAIL;
-       }
 
        page_addr = phy_blk << xd_card->block_shift;
 
@@ -1333,9 +1281,8 @@ static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)
                        }
                        xd_set_err_code(chip, XD_ERASE_FAIL);
                        retval = xd_reset_cmd(chip);
-                       if (retval != STATUS_SUCCESS) {
+                       if (retval != STATUS_SUCCESS)
                                return STATUS_FAIL;
-                       }
                        continue;
                }
 
@@ -1382,17 +1329,15 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
 
        if (!zone->l2p_table) {
                zone->l2p_table = vmalloc(2000);
-               if (!zone->l2p_table) {
+               if (!zone->l2p_table)
                        goto build_fail;
-               }
        }
        memset((u8 *)(zone->l2p_table), 0xff, 2000);
 
        if (!zone->free_table) {
                zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2);
-               if (!zone->free_table) {
+               if (!zone->free_table)
                        goto build_fail;
-               }
        }
        memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2);
 
@@ -1555,9 +1500,8 @@ static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd)
                     XD_TRANSFER_END, XD_TRANSFER_END);
 
        retval = rtsx_send_cmd(chip, XD_CARD, 200);
-       if (retval < 0) {
+       if (retval < 0)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
@@ -1636,17 +1580,15 @@ static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,
 
 fail:
        retval = rtsx_read_register(chip, XD_PAGE_STATUS, &reg_val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (reg_val !=  XD_GPG)
                xd_set_err_code(chip, XD_PRG_ERROR);
 
        retval = rtsx_read_register(chip, XD_CTL, &reg_val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ==
                                (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) ||
@@ -1702,9 +1644,8 @@ static int xd_finish_write(struct rtsx_chip *chip,
        dev_dbg(rtsx_dev(chip), "new_blk = 0x%x, ", new_blk);
        dev_dbg(rtsx_dev(chip), "log_blk = 0x%x\n", log_blk);
 
-       if (page_off > xd_card->page_off) {
+       if (page_off > xd_card->page_off)
                return STATUS_FAIL;
-       }
 
        zone_no = (int)(log_blk / 1000);
        log_off = (u16)(log_blk % 1000);
@@ -1760,9 +1701,8 @@ static int xd_prepare_write(struct rtsx_chip *chip,
 
        if (page_off) {
                retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -1858,9 +1798,8 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
 
 fail:
        retval = rtsx_read_register(chip, XD_DAT, &reg_val);
-       if (retval) {
+       if (retval)
                return retval;
-       }
        if (reg_val & PROGRAM_ERROR) {
                xd_set_err_code(chip, XD_PRG_ERROR);
                xd_mark_bad_block(chip, new_blk);
@@ -1880,9 +1819,8 @@ int xd_delay_write(struct rtsx_chip *chip)
        if (delay_write->delay_write_flag) {
                dev_dbg(rtsx_dev(chip), "%s\n", __func__);
                retval = xd_switch_clock(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                delay_write->delay_write_flag = 0;
                retval = xd_finish_write(chip,
@@ -1890,9 +1828,8 @@ int xd_delay_write(struct rtsx_chip *chip)
                                         delay_write->new_phyblock,
                                         delay_write->logblock,
                                         delay_write->pageoff);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -1924,9 +1861,8 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
        ptr = (u8 *)scsi_sglist(srb);
 
        retval = xd_switch_clock(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
                chip->card_fail |= XD_CARD;
@@ -2180,34 +2116,29 @@ int xd_power_off_card3v3(struct rtsx_chip *chip)
        int retval;
 
        retval = disable_card_clock(chip, XD_CARD);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        retval = rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0);
-       if (retval) {
+       if (retval)
                return retval;
-       }
 
        if (!chip->ft2_fast_mode) {
                retval = card_power_off(chip, XD_CARD);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
 
                wait_timeout(50);
        }
 
        if (chip->asic_code) {
                retval = xd_pull_ctl_disable(chip);
-               if (retval != STATUS_SUCCESS) {
+               if (retval != STATUS_SUCCESS)
                        return STATUS_FAIL;
-               }
        } else {
                retval = rtsx_write_register(chip, FPGA_PULL_CTL, 0xFF, 0xDF);
-               if (retval) {
+               if (retval)
                        return retval;
-               }
        }
 
        return STATUS_SUCCESS;
@@ -2227,9 +2158,8 @@ int release_xd_card(struct rtsx_chip *chip)
        xd_free_l2p_tbl(chip);
 
        retval = xd_power_off_card3v3(chip);
-       if (retval != STATUS_SUCCESS) {
+       if (retval != STATUS_SUCCESS)
                return STATUS_FAIL;
-       }
 
        return STATUS_SUCCESS;
 }
index 7e22d093b09110084ee7952e41ebc80bd6fcf9c7..4dac691ad1b1ae5e2380b020d5fc58684bf782ab 100644 (file)
@@ -131,7 +131,7 @@ static int programModeRegisters(struct mode_parameter *pModeParam,
                                  DISPLAY_CTRL_HSYNC_PHASE |
                                  DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE);
 
-                        poke32(CRT_DISPLAY_CTRL, tmp | reg);
+                       poke32(CRT_DISPLAY_CTRL, tmp | reg);
                }
 
        } else if (pll->clockType == PRIMARY_PLL) {
index 4b34a083f5cf7b17ba3994d8f7afbad1567212a7..8391f57d538380839bfa6a84d30b20d97b3e8a81 100644 (file)
@@ -39,8 +39,8 @@ unsigned short sii164GetVendorID(void)
 {
        unsigned short vendorID;
 
-       vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
-                   (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
+       vendorID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
+                   (unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
 
        return vendorID;
 }
@@ -56,8 +56,8 @@ unsigned short sii164GetDeviceID(void)
 {
        unsigned short deviceID;
 
-       deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
-                   (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
+       deviceID = ((unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
+                   (unsigned short)i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
 
        return deviceID;
 }
index 846d7d243994cab582da872803ce1beda5c5d2a2..e9f10c2669eacef8c7b4d2cff92691024292f9e8 100644 (file)
@@ -1007,7 +1007,7 @@ NO_PARAM:
        }
 }
 
-static void sm750fb_frambuffer_release(struct sm750_dev *sm750_dev)
+static void sm750fb_framebuffer_release(struct sm750_dev *sm750_dev)
 {
        struct fb_info *fb_info;
 
@@ -1019,7 +1019,7 @@ static void sm750fb_frambuffer_release(struct sm750_dev *sm750_dev)
        }
 }
 
-static int sm750fb_frambuffer_alloc(struct sm750_dev *sm750_dev, int fbidx)
+static int sm750fb_framebuffer_alloc(struct sm750_dev *sm750_dev, int fbidx)
 {
        struct fb_info *fb_info;
        struct lynxfb_par *par;
@@ -1137,7 +1137,7 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
        /* allocate frame buffer info structures according to g_dualview */
        max_fb = g_dualview ? 2 : 1;
        for (fbidx = 0; fbidx < max_fb; fbidx++) {
-               err = sm750fb_frambuffer_alloc(sm750_dev, fbidx);
+               err = sm750fb_framebuffer_alloc(sm750_dev, fbidx);
                if (err)
                        goto release_fb;
        }
@@ -1145,7 +1145,7 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
        return 0;
 
 release_fb:
-       sm750fb_frambuffer_release(sm750_dev);
+       sm750fb_framebuffer_release(sm750_dev);
        return err;
 }
 
@@ -1155,7 +1155,7 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)
 
        sm750_dev = pci_get_drvdata(pdev);
 
-       sm750fb_frambuffer_release(sm750_dev);
+       sm750fb_framebuffer_release(sm750_dev);
        arch_phys_wc_del(sm750_dev->mtrr.vram);
 
        iounmap(sm750_dev->pvReg);
index eac63aab81622cc447ee31d263f7ddab150e4b3b..979e3ae249c13e43770db5b8b0146596fe25f759 100644 (file)
@@ -227,9 +227,9 @@ static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch)
 {
        int ret;
 
-       if (ch < 0x80)
+       if (ch < 0x80) {
                ret = spk_ttyio_out(in_synth, ch);
-       else if (ch < 0x800) {
+       else if (ch < 0x800) {
                ret  = spk_ttyio_out(in_synth, 0xc0 | (ch >> 6));
                ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
        } else {
index 468eea856ca6491f323533514f8e96ffb46b7701..2e0f99c3f10c66d18c5b21e0ee265e41c585c84e 100644 (file)
@@ -1,5 +1,4 @@
 TODO:
--Move the driver over to the atomic API
 -Get a full review from the drm-maintainers on dri-devel done on this driver
 -Extend this TODO with the results of that review
 
index 69cc508af1bce1aa52e244f74b2628fcdba35eb9..257030460fb620dd848977c971c9a2df7c4fcec4 100644 (file)
@@ -49,139 +49,140 @@ static const struct pci_device_id pciidlist[] = {
 };
 MODULE_DEVICE_TABLE(pci, pciidlist);
 
+static struct drm_fb_helper_funcs vbox_fb_helper_funcs = {
+       .fb_probe = vboxfb_create,
+};
+
 static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       struct drm_device *dev = NULL;
+       struct vbox_private *vbox;
        int ret = 0;
 
-       dev = drm_dev_alloc(&driver, &pdev->dev);
-       if (IS_ERR(dev)) {
-               ret = PTR_ERR(dev);
-               goto err_drv_alloc;
+       if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
+               return -ENODEV;
+
+       vbox = kzalloc(sizeof(*vbox), GFP_KERNEL);
+       if (!vbox)
+               return -ENOMEM;
+
+       ret = drm_dev_init(&vbox->ddev, &driver, &pdev->dev);
+       if (ret) {
+               kfree(vbox);
+               return ret;
        }
 
+       vbox->ddev.pdev = pdev;
+       vbox->ddev.dev_private = vbox;
+       pci_set_drvdata(pdev, vbox);
+       mutex_init(&vbox->hw_mutex);
+
        ret = pci_enable_device(pdev);
        if (ret)
-               goto err_pci_enable;
-
-       dev->pdev = pdev;
-       pci_set_drvdata(pdev, dev);
+               goto err_dev_put;
 
-       ret = vbox_driver_load(dev);
+       ret = vbox_hw_init(vbox);
        if (ret)
-               goto err_vbox_driver_load;
+               goto err_pci_disable;
 
-       ret = drm_dev_register(dev, 0);
+       ret = vbox_mm_init(vbox);
        if (ret)
-               goto err_drv_dev_register;
-
-       return ret;
-
- err_drv_dev_register:
-       vbox_driver_unload(dev);
- err_vbox_driver_load:
-       pci_disable_device(pdev);
- err_pci_enable:
-       drm_dev_put(dev);
- err_drv_alloc:
-       return ret;
-}
-
-static void vbox_pci_remove(struct pci_dev *pdev)
-{
-       struct drm_device *dev = pci_get_drvdata(pdev);
-
-       drm_dev_unregister(dev);
-       vbox_driver_unload(dev);
-       drm_dev_put(dev);
-}
+               goto err_hw_fini;
 
-static int vbox_drm_freeze(struct drm_device *dev)
-{
-       struct vbox_private *vbox = dev->dev_private;
+       ret = vbox_mode_init(vbox);
+       if (ret)
+               goto err_mm_fini;
 
-       drm_kms_helper_poll_disable(dev);
+       ret = vbox_irq_init(vbox);
+       if (ret)
+               goto err_mode_fini;
 
-       pci_save_state(dev->pdev);
+       ret = drm_fb_helper_fbdev_setup(&vbox->ddev, &vbox->fb_helper,
+                                       &vbox_fb_helper_funcs, 32,
+                                       vbox->num_crtcs);
+       if (ret)
+               goto err_irq_fini;
 
-       drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true);
+       ret = drm_dev_register(&vbox->ddev, 0);
+       if (ret)
+               goto err_fbdev_fini;
 
        return 0;
-}
-
-static int vbox_drm_thaw(struct drm_device *dev)
-{
-       struct vbox_private *vbox = dev->dev_private;
-
-       drm_mode_config_reset(dev);
-       drm_helper_resume_force_mode(dev);
-       drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false);
 
-       return 0;
+err_fbdev_fini:
+       vbox_fbdev_fini(vbox);
+err_irq_fini:
+       vbox_irq_fini(vbox);
+err_mode_fini:
+       vbox_mode_fini(vbox);
+err_mm_fini:
+       vbox_mm_fini(vbox);
+err_hw_fini:
+       vbox_hw_fini(vbox);
+err_pci_disable:
+       pci_disable_device(pdev);
+err_dev_put:
+       drm_dev_put(&vbox->ddev);
+       return ret;
 }
 
-static int vbox_drm_resume(struct drm_device *dev)
+static void vbox_pci_remove(struct pci_dev *pdev)
 {
-       int ret;
-
-       if (pci_enable_device(dev->pdev))
-               return -EIO;
-
-       ret = vbox_drm_thaw(dev);
-       if (ret)
-               return ret;
-
-       drm_kms_helper_poll_enable(dev);
-
-       return 0;
+       struct vbox_private *vbox = pci_get_drvdata(pdev);
+
+       drm_dev_unregister(&vbox->ddev);
+       vbox_fbdev_fini(vbox);
+       vbox_irq_fini(vbox);
+       vbox_mode_fini(vbox);
+       vbox_mm_fini(vbox);
+       vbox_hw_fini(vbox);
+       drm_dev_put(&vbox->ddev);
 }
 
 static int vbox_pm_suspend(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct drm_device *ddev = pci_get_drvdata(pdev);
+       struct vbox_private *vbox = dev_get_drvdata(dev);
        int error;
 
-       error = vbox_drm_freeze(ddev);
+       error = drm_mode_config_helper_suspend(&vbox->ddev);
        if (error)
                return error;
 
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
+       pci_save_state(vbox->ddev.pdev);
+       pci_disable_device(vbox->ddev.pdev);
+       pci_set_power_state(vbox->ddev.pdev, PCI_D3hot);
 
        return 0;
 }
 
 static int vbox_pm_resume(struct device *dev)
 {
-       struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+       struct vbox_private *vbox = dev_get_drvdata(dev);
+
+       if (pci_enable_device(vbox->ddev.pdev))
+               return -EIO;
 
-       return vbox_drm_resume(ddev);
+       return drm_mode_config_helper_resume(&vbox->ddev);
 }
 
 static int vbox_pm_freeze(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct drm_device *ddev = pci_get_drvdata(pdev);
-
-       if (!ddev || !ddev->dev_private)
-               return -ENODEV;
+       struct vbox_private *vbox = dev_get_drvdata(dev);
 
-       return vbox_drm_freeze(ddev);
+       return drm_mode_config_helper_suspend(&vbox->ddev);
 }
 
 static int vbox_pm_thaw(struct device *dev)
 {
-       struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+       struct vbox_private *vbox = dev_get_drvdata(dev);
 
-       return vbox_drm_thaw(ddev);
+       return drm_mode_config_helper_resume(&vbox->ddev);
 }
 
 static int vbox_pm_poweroff(struct device *dev)
 {
-       struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+       struct vbox_private *vbox = dev_get_drvdata(dev);
 
-       return vbox_drm_freeze(ddev);
+       return drm_mode_config_helper_suspend(&vbox->ddev);
 }
 
 static const struct dev_pm_ops vbox_pm_ops = {
@@ -259,10 +260,10 @@ static void vbox_master_drop(struct drm_device *dev, struct drm_file *file_priv)
 static struct drm_driver driver = {
        .driver_features =
            DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
-           DRIVER_PRIME,
+           DRIVER_PRIME | DRIVER_ATOMIC,
        .dev_priv_size = 0,
 
-       .lastclose = vbox_driver_lastclose,
+       .lastclose = drm_fb_helper_lastclose,
        .master_set = vbox_master_set,
        .master_drop = vbox_master_drop,
 
index 594f84272957ac9a657315fbbe5b1a87a2d36e48..73395a7536c5aecd8c62bc04634cb0afb4b418b6 100644 (file)
                                sizeof(struct hgsmi_host_flags))
 #define HOST_FLAGS_OFFSET GUEST_HEAP_USABLE_SIZE
 
-struct vbox_fbdev;
+struct vbox_framebuffer {
+       struct drm_framebuffer base;
+       struct drm_gem_object *obj;
+};
 
 struct vbox_private {
-       struct drm_device *dev;
+       /* Must be first; or we must define our own release callback */
+       struct drm_device ddev;
+       struct drm_fb_helper fb_helper;
+       struct vbox_framebuffer afb;
 
        u8 __iomem *guest_heap;
        u8 __iomem *vbva_buffers;
@@ -90,8 +96,6 @@ struct vbox_private {
        /** Array of structures for receiving mode hints. */
        struct vbva_modehint *last_mode_hints;
 
-       struct vbox_fbdev *fbdev;
-
        int fb_mtrr;
 
        struct {
@@ -115,21 +119,12 @@ struct vbox_private {
         * encompassing all screen ones or is the fbdev console active?
         */
        bool single_framebuffer;
-       u32 cursor_width;
-       u32 cursor_height;
-       u32 cursor_hot_x;
-       u32 cursor_hot_y;
-       size_t cursor_data_size;
        u8 cursor_data[CURSOR_DATA_SIZE];
 };
 
 #undef CURSOR_PIXEL_COUNT
 #undef CURSOR_DATA_SIZE
 
-int vbox_driver_load(struct drm_device *dev);
-void vbox_driver_unload(struct drm_device *dev);
-void vbox_driver_lastclose(struct drm_device *dev);
-
 struct vbox_gem_object;
 
 struct vbox_connector {
@@ -145,43 +140,51 @@ struct vbox_connector {
 
 struct vbox_crtc {
        struct drm_crtc base;
-       bool blanked;
        bool disconnected;
        unsigned int crtc_id;
        u32 fb_offset;
        bool cursor_enabled;
        u32 x_hint;
        u32 y_hint;
+       /*
+        * When setting a mode we not only pass the mode to the hypervisor,
+        * but also information on how to map / translate input coordinates
+        * for the emulated USB tablet.  This input-mapping may change when
+        * the mode on *another* crtc changes.
+        *
+        * This means that sometimes we must do a modeset on other crtc-s then
+        * the one being changed to update the input-mapping. Including crtc-s
+        * which may be disabled inside the guest (shown as a black window
+        * on the host unless closed by the user).
+        *
+        * With atomic modesetting the mode-info of disabled crtcs gets zeroed
+        * yet we need it when updating the input-map to avoid resizing the
+        * window as a side effect of a mode_set on another crtc. Therefor we
+        * cache the info of the last mode below.
+        */
+       u32 width;
+       u32 height;
+       u32 x;
+       u32 y;
 };
 
 struct vbox_encoder {
        struct drm_encoder base;
 };
 
-struct vbox_framebuffer {
-       struct drm_framebuffer base;
-       struct drm_gem_object *obj;
-};
-
-struct vbox_fbdev {
-       struct drm_fb_helper helper;
-       struct vbox_framebuffer afb;
-       int size;
-       struct ttm_bo_kmap_obj mapping;
-       int x1, y1, x2, y2;     /* dirty rect */
-       spinlock_t dirty_lock;
-};
-
 #define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base)
 #define to_vbox_connector(x) container_of(x, struct vbox_connector, base)
 #define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base)
 #define to_vbox_framebuffer(x) container_of(x, struct vbox_framebuffer, base)
 
-int vbox_mode_init(struct drm_device *dev);
-void vbox_mode_fini(struct drm_device *dev);
+bool vbox_check_supported(u16 id);
+int vbox_hw_init(struct vbox_private *vbox);
+void vbox_hw_fini(struct vbox_private *vbox);
+
+int vbox_mode_init(struct vbox_private *vbox);
+void vbox_mode_fini(struct vbox_private *vbox);
 
 #define DRM_MODE_FB_CMD drm_mode_fb_cmd2
-#define CRTC_FB(crtc) ((crtc)->primary->fb)
 
 void vbox_enable_accel(struct vbox_private *vbox);
 void vbox_disable_accel(struct vbox_private *vbox);
@@ -191,14 +194,14 @@ void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
                                       struct drm_clip_rect *rects,
                                       unsigned int num_rects);
 
-int vbox_framebuffer_init(struct drm_device *dev,
+int vbox_framebuffer_init(struct vbox_private *vbox,
                          struct vbox_framebuffer *vbox_fb,
                          const struct DRM_MODE_FB_CMD *mode_cmd,
                          struct drm_gem_object *obj);
 
-int vbox_fbdev_init(struct drm_device *dev);
-void vbox_fbdev_fini(struct drm_device *dev);
-void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr);
+int vboxfb_create(struct drm_fb_helper *helper,
+                 struct drm_fb_helper_surface_size *sizes);
+void vbox_fbdev_fini(struct vbox_private *vbox);
 
 struct vbox_bo {
        struct ttm_buffer_object bo;
@@ -218,6 +221,11 @@ static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
 
 #define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
 
+static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
+{
+       return bo->bo.offset;
+}
+
 int vbox_dumb_create(struct drm_file *file,
                     struct drm_device *dev,
                     struct drm_mode_create_dumb *args);
@@ -232,13 +240,13 @@ int vbox_dumb_mmap_offset(struct drm_file *file,
 int vbox_mm_init(struct vbox_private *vbox);
 void vbox_mm_fini(struct vbox_private *vbox);
 
-int vbox_bo_create(struct drm_device *dev, int size, int align,
+int vbox_bo_create(struct vbox_private *vbox, int size, int align,
                   u32 flags, struct vbox_bo **pvboxbo);
 
-int vbox_gem_create(struct drm_device *dev,
+int vbox_gem_create(struct vbox_private *vbox,
                    u32 size, bool iskernel, struct drm_gem_object **obj);
 
-int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr);
+int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag);
 int vbox_bo_unpin(struct vbox_bo *bo);
 
 static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
@@ -262,6 +270,8 @@ static inline void vbox_bo_unreserve(struct vbox_bo *bo)
 void vbox_ttm_placement(struct vbox_bo *bo, int domain);
 int vbox_bo_push_sysram(struct vbox_bo *bo);
 int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
+void *vbox_bo_kmap(struct vbox_bo *bo);
+void vbox_bo_kunmap(struct vbox_bo *bo);
 
 /* vbox_prime.c */
 int vbox_gem_prime_pin(struct drm_gem_object *obj);
index 034f8ffa8f206e825469fa239e6dfedd7cd9b964..d1a1f74c8de35c0719324465111930eb796fbeb4 100644 (file)
@@ -66,38 +66,19 @@ static struct fb_ops vboxfb_ops = {
        .fb_debug_leave = drm_fb_helper_debug_leave,
 };
 
-static int vboxfb_create_object(struct vbox_fbdev *fbdev,
-                               struct DRM_MODE_FB_CMD *mode_cmd,
-                               struct drm_gem_object **gobj_p)
+int vboxfb_create(struct drm_fb_helper *helper,
+                 struct drm_fb_helper_surface_size *sizes)
 {
-       struct drm_device *dev = fbdev->helper.dev;
-       u32 size;
-       struct drm_gem_object *gobj;
-       u32 pitch = mode_cmd->pitches[0];
-       int ret;
-
-       size = pitch * mode_cmd->height;
-       ret = vbox_gem_create(dev, size, true, &gobj);
-       if (ret)
-               return ret;
-
-       *gobj_p = gobj;
-
-       return 0;
-}
-
-static int vboxfb_create(struct drm_fb_helper *helper,
-                        struct drm_fb_helper_surface_size *sizes)
-{
-       struct vbox_fbdev *fbdev =
-           container_of(helper, struct vbox_fbdev, helper);
-       struct drm_device *dev = fbdev->helper.dev;
+       struct vbox_private *vbox =
+               container_of(helper, struct vbox_private, fb_helper);
+       struct pci_dev *pdev = vbox->ddev.pdev;
        struct DRM_MODE_FB_CMD mode_cmd;
        struct drm_framebuffer *fb;
        struct fb_info *info;
        struct drm_gem_object *gobj;
        struct vbox_bo *bo;
        int size, ret;
+       u64 gpu_addr;
        u32 pitch;
 
        mode_cmd.width = sizes->surface_width;
@@ -109,45 +90,35 @@ static int vboxfb_create(struct drm_fb_helper *helper,
 
        size = pitch * mode_cmd.height;
 
-       ret = vboxfb_create_object(fbdev, &mode_cmd, &gobj);
+       ret = vbox_gem_create(vbox, size, true, &gobj);
        if (ret) {
                DRM_ERROR("failed to create fbcon backing object %d\n", ret);
                return ret;
        }
 
-       ret = vbox_framebuffer_init(dev, &fbdev->afb, &mode_cmd, gobj);
+       ret = vbox_framebuffer_init(vbox, &vbox->afb, &mode_cmd, gobj);
        if (ret)
                return ret;
 
        bo = gem_to_vbox_bo(gobj);
 
-       ret = vbox_bo_reserve(bo, false);
+       ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
        if (ret)
                return ret;
 
-       ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
-       if (ret) {
-               vbox_bo_unreserve(bo);
-               return ret;
-       }
-
-       ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
-       vbox_bo_unreserve(bo);
-       if (ret) {
-               DRM_ERROR("failed to kmap fbcon\n");
-               return ret;
-       }
-
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info))
-               return -PTR_ERR(info);
+               return PTR_ERR(info);
 
-       info->par = fbdev;
+       info->screen_size = size;
+       info->screen_base = (char __iomem *)vbox_bo_kmap(bo);
+       if (IS_ERR(info->screen_base))
+               return PTR_ERR(info->screen_base);
 
-       fbdev->size = size;
+       info->par = helper;
 
-       fb = &fbdev->afb.base;
-       fbdev->helper.fb = fb;
+       fb = &vbox->afb.base;
+       helper->fb = fb;
 
        strcpy(info->fix.id, "vboxdrmfb");
 
@@ -162,15 +133,16 @@ static int vboxfb_create(struct drm_fb_helper *helper,
         * This seems to be done for safety checking that the framebuffer
         * is not registered twice by different drivers.
         */
-       info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
-       info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
+       info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
+       info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
 
        drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
-       drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width,
+       drm_fb_helper_fill_var(info, helper, sizes->fb_width,
                               sizes->fb_height);
 
-       info->screen_base = (char __iomem *)bo->kmap.virtual;
-       info->screen_size = size;
+       gpu_addr = vbox_bo_gpu_offset(bo);
+       info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr;
+       info->fix.smem_len = vbox->available_vram_size - gpu_addr;
 
 #ifdef CONFIG_DRM_KMS_FB_HELPER
        info->fbdefio = &vbox_defio;
@@ -184,86 +156,30 @@ static int vboxfb_create(struct drm_fb_helper *helper,
        return 0;
 }
 
-static struct drm_fb_helper_funcs vbox_fb_helper_funcs = {
-       .fb_probe = vboxfb_create,
-};
-
-void vbox_fbdev_fini(struct drm_device *dev)
+void vbox_fbdev_fini(struct vbox_private *vbox)
 {
-       struct vbox_private *vbox = dev->dev_private;
-       struct vbox_fbdev *fbdev = vbox->fbdev;
-       struct vbox_framebuffer *afb = &fbdev->afb;
+       struct vbox_framebuffer *afb = &vbox->afb;
 
 #ifdef CONFIG_DRM_KMS_FB_HELPER
-       if (fbdev->helper.fbdev && fbdev->helper.fbdev->fbdefio)
-               fb_deferred_io_cleanup(fbdev->helper.fbdev);
+       if (vbox->fb_helper.fbdev && vbox->fb_helper.fbdev->fbdefio)
+               fb_deferred_io_cleanup(vbox->fb_helper.fbdev);
 #endif
 
-       drm_fb_helper_unregister_fbi(&fbdev->helper);
+       drm_fb_helper_unregister_fbi(&vbox->fb_helper);
 
        if (afb->obj) {
                struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
 
-               if (!vbox_bo_reserve(bo, false)) {
-                       if (bo->kmap.virtual)
-                               ttm_bo_kunmap(&bo->kmap);
-                       /*
-                        * QXL does this, but is it really needed before
-                        * freeing?
-                        */
-                       if (bo->pin_count)
-                               vbox_bo_unpin(bo);
-                       vbox_bo_unreserve(bo);
-               }
+               vbox_bo_kunmap(bo);
+
+               if (bo->pin_count)
+                       vbox_bo_unpin(bo);
+
                drm_gem_object_put_unlocked(afb->obj);
                afb->obj = NULL;
        }
-       drm_fb_helper_fini(&fbdev->helper);
+       drm_fb_helper_fini(&vbox->fb_helper);
 
        drm_framebuffer_unregister_private(&afb->base);
        drm_framebuffer_cleanup(&afb->base);
 }
-
-int vbox_fbdev_init(struct drm_device *dev)
-{
-       struct vbox_private *vbox = dev->dev_private;
-       struct vbox_fbdev *fbdev;
-       int ret;
-
-       fbdev = devm_kzalloc(dev->dev, sizeof(*fbdev), GFP_KERNEL);
-       if (!fbdev)
-               return -ENOMEM;
-
-       vbox->fbdev = fbdev;
-       spin_lock_init(&fbdev->dirty_lock);
-
-       drm_fb_helper_prepare(dev, &fbdev->helper, &vbox_fb_helper_funcs);
-       ret = drm_fb_helper_init(dev, &fbdev->helper, vbox->num_crtcs);
-       if (ret)
-               return ret;
-
-       ret = drm_fb_helper_single_add_all_connectors(&fbdev->helper);
-       if (ret)
-               goto err_fini;
-
-       /* disable all the possible outputs/crtcs before entering KMS mode */
-       drm_helper_disable_unused_functions(dev);
-
-       ret = drm_fb_helper_initial_config(&fbdev->helper, 32);
-       if (ret)
-               goto err_fini;
-
-       return 0;
-
-err_fini:
-       drm_fb_helper_fini(&fbdev->helper);
-       return ret;
-}
-
-void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr)
-{
-       struct fb_info *fbdev = vbox->fbdev->helper.fbdev;
-
-       fbdev->fix.smem_start = fbdev->apertures->ranges[0].base + gpu_addr;
-       fbdev->fix.smem_len = vbox->available_vram_size - gpu_addr;
-}
index 74abdf02d9fddd9567a4361eef12e81707c023d0..09f858ec1369afde5ddf42c8a731a23f5894a3f2 100644 (file)
@@ -123,7 +123,7 @@ static void validate_or_set_position_hints(struct vbox_private *vbox)
  */
 static void vbox_update_mode_hints(struct vbox_private *vbox)
 {
-       struct drm_device *dev = vbox->dev;
+       struct drm_device *dev = &vbox->ddev;
        struct drm_connector *connector;
        struct vbox_connector *vbox_conn;
        struct vbva_modehint *hints;
@@ -179,7 +179,7 @@ static void vbox_hotplug_worker(struct work_struct *work)
                                                 hotplug_work);
 
        vbox_update_mode_hints(vbox);
-       drm_kms_helper_hotplug_event(vbox->dev);
+       drm_kms_helper_hotplug_event(&vbox->ddev);
 }
 
 int vbox_irq_init(struct vbox_private *vbox)
@@ -187,11 +187,11 @@ int vbox_irq_init(struct vbox_private *vbox)
        INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker);
        vbox_update_mode_hints(vbox);
 
-       return drm_irq_install(vbox->dev, vbox->dev->pdev->irq);
+       return drm_irq_install(&vbox->ddev, vbox->ddev.pdev->irq);
 }
 
 void vbox_irq_fini(struct vbox_private *vbox)
 {
-       drm_irq_uninstall(vbox->dev);
+       drm_irq_uninstall(&vbox->ddev);
        flush_work(&vbox->hotplug_work);
 }
index 429f6a453619e32afa41e19dc9c235f704f0944d..7466c1103ff626ea2b01c9ae36dbdd3b2f1d51d1 100644 (file)
@@ -102,24 +102,30 @@ void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
                                       unsigned int num_rects)
 {
        struct vbox_private *vbox = fb->dev->dev_private;
+       struct drm_display_mode *mode;
        struct drm_crtc *crtc;
+       int crtc_x, crtc_y;
        unsigned int i;
 
        mutex_lock(&vbox->hw_mutex);
        list_for_each_entry(crtc, &fb->dev->mode_config.crtc_list, head) {
-               if (CRTC_FB(crtc) != fb)
+               if (crtc->primary->state->fb != fb)
                        continue;
 
+               mode = &crtc->state->mode;
+               crtc_x = crtc->primary->state->src_x >> 16;
+               crtc_y = crtc->primary->state->src_y >> 16;
+
                vbox_enable_accel(vbox);
 
                for (i = 0; i < num_rects; ++i) {
                        struct vbva_cmd_hdr cmd_hdr;
                        unsigned int crtc_id = to_vbox_crtc(crtc)->crtc_id;
 
-                       if ((rects[i].x1 > crtc->x + crtc->hwmode.hdisplay) ||
-                           (rects[i].y1 > crtc->y + crtc->hwmode.vdisplay) ||
-                           (rects[i].x2 < crtc->x) ||
-                           (rects[i].y2 < crtc->y))
+                       if ((rects[i].x1 > crtc_x + mode->hdisplay) ||
+                           (rects[i].y1 > crtc_y + mode->vdisplay) ||
+                           (rects[i].x2 < crtc_x) ||
+                           (rects[i].y2 < crtc_y))
                                continue;
 
                        cmd_hdr.x = (s16)rects[i].x1;
@@ -155,16 +161,16 @@ static const struct drm_framebuffer_funcs vbox_fb_funcs = {
        .dirty = vbox_user_framebuffer_dirty,
 };
 
-int vbox_framebuffer_init(struct drm_device *dev,
+int vbox_framebuffer_init(struct vbox_private *vbox,
                          struct vbox_framebuffer *vbox_fb,
                          const struct DRM_MODE_FB_CMD *mode_cmd,
                          struct drm_gem_object *obj)
 {
        int ret;
 
-       drm_helper_mode_fill_fb_struct(dev, &vbox_fb->base, mode_cmd);
+       drm_helper_mode_fill_fb_struct(&vbox->ddev, &vbox_fb->base, mode_cmd);
        vbox_fb->obj = obj;
-       ret = drm_framebuffer_init(dev, &vbox_fb->base, &vbox_fb_funcs);
+       ret = drm_framebuffer_init(&vbox->ddev, &vbox_fb->base, &vbox_fb_funcs);
        if (ret) {
                DRM_ERROR("framebuffer init failed %d\n", ret);
                return ret;
@@ -173,45 +179,11 @@ int vbox_framebuffer_init(struct drm_device *dev,
        return 0;
 }
 
-static struct drm_framebuffer *vbox_user_framebuffer_create(
-               struct drm_device *dev,
-               struct drm_file *filp,
-               const struct drm_mode_fb_cmd2 *mode_cmd)
-{
-       struct drm_gem_object *obj;
-       struct vbox_framebuffer *vbox_fb;
-       int ret = -ENOMEM;
-
-       obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]);
-       if (!obj)
-               return ERR_PTR(-ENOENT);
-
-       vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL);
-       if (!vbox_fb)
-               goto err_unref_obj;
-
-       ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj);
-       if (ret)
-               goto err_free_vbox_fb;
-
-       return &vbox_fb->base;
-
-err_free_vbox_fb:
-       kfree(vbox_fb);
-err_unref_obj:
-       drm_gem_object_put_unlocked(obj);
-       return ERR_PTR(ret);
-}
-
-static const struct drm_mode_config_funcs vbox_mode_funcs = {
-       .fb_create = vbox_user_framebuffer_create,
-};
-
 static int vbox_accel_init(struct vbox_private *vbox)
 {
        unsigned int i;
 
-       vbox->vbva_info = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
+       vbox->vbva_info = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs,
                                       sizeof(*vbox->vbva_info), GFP_KERNEL);
        if (!vbox->vbva_info)
                return -ENOMEM;
@@ -219,7 +191,7 @@ static int vbox_accel_init(struct vbox_private *vbox)
        /* Take a command buffer for each screen from the end of usable VRAM. */
        vbox->available_vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE;
 
-       vbox->vbva_buffers = pci_iomap_range(vbox->dev->pdev, 0,
+       vbox->vbva_buffers = pci_iomap_range(vbox->ddev.pdev, 0,
                                             vbox->available_vram_size,
                                             vbox->num_crtcs *
                                             VBVA_MIN_BUFFER_SIZE);
@@ -238,7 +210,7 @@ static int vbox_accel_init(struct vbox_private *vbox)
 static void vbox_accel_fini(struct vbox_private *vbox)
 {
        vbox_disable_accel(vbox);
-       pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers);
+       pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers);
 }
 
 /** Do we support the 4.3 plus mode hint reporting interface? */
@@ -262,7 +234,7 @@ static bool have_hgsmi_mode_hints(struct vbox_private *vbox)
        return have_hints == VINF_SUCCESS && have_cursor == VINF_SUCCESS;
 }
 
-static bool vbox_check_supported(u16 id)
+bool vbox_check_supported(u16 id)
 {
        u16 dispi_id;
 
@@ -276,7 +248,7 @@ static bool vbox_check_supported(u16 id)
  * Set up our heaps and data exchange buffers in VRAM before handing the rest
  * to the memory manager.
  */
-static int vbox_hw_init(struct vbox_private *vbox)
+int vbox_hw_init(struct vbox_private *vbox)
 {
        int ret = -ENOMEM;
 
@@ -287,7 +259,7 @@ static int vbox_hw_init(struct vbox_private *vbox)
 
        /* Map guest-heap at end of vram */
        vbox->guest_heap =
-           pci_iomap_range(vbox->dev->pdev, 0, GUEST_HEAP_OFFSET(vbox),
+           pci_iomap_range(vbox->ddev.pdev, 0, GUEST_HEAP_OFFSET(vbox),
                            GUEST_HEAP_SIZE);
        if (!vbox->guest_heap)
                return -ENOMEM;
@@ -322,7 +294,7 @@ static int vbox_hw_init(struct vbox_private *vbox)
                goto err_destroy_guest_pool;
        }
 
-       vbox->last_mode_hints = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
+       vbox->last_mode_hints = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs,
                                             sizeof(struct vbva_modehint),
                                             GFP_KERNEL);
        if (!vbox->last_mode_hints) {
@@ -339,102 +311,18 @@ static int vbox_hw_init(struct vbox_private *vbox)
 err_destroy_guest_pool:
        gen_pool_destroy(vbox->guest_pool);
 err_unmap_guest_heap:
-       pci_iounmap(vbox->dev->pdev, vbox->guest_heap);
+       pci_iounmap(vbox->ddev.pdev, vbox->guest_heap);
        return ret;
 }
 
-static void vbox_hw_fini(struct vbox_private *vbox)
+void vbox_hw_fini(struct vbox_private *vbox)
 {
        vbox_accel_fini(vbox);
        gen_pool_destroy(vbox->guest_pool);
-       pci_iounmap(vbox->dev->pdev, vbox->guest_heap);
-}
-
-int vbox_driver_load(struct drm_device *dev)
-{
-       struct vbox_private *vbox;
-       int ret = 0;
-
-       if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
-               return -ENODEV;
-
-       vbox = devm_kzalloc(dev->dev, sizeof(*vbox), GFP_KERNEL);
-       if (!vbox)
-               return -ENOMEM;
-
-       dev->dev_private = vbox;
-       vbox->dev = dev;
-
-       mutex_init(&vbox->hw_mutex);
-
-       ret = vbox_hw_init(vbox);
-       if (ret)
-               return ret;
-
-       ret = vbox_mm_init(vbox);
-       if (ret)
-               goto err_hw_fini;
-
-       drm_mode_config_init(dev);
-
-       dev->mode_config.funcs = (void *)&vbox_mode_funcs;
-       dev->mode_config.min_width = 64;
-       dev->mode_config.min_height = 64;
-       dev->mode_config.preferred_depth = 24;
-       dev->mode_config.max_width = VBE_DISPI_MAX_XRES;
-       dev->mode_config.max_height = VBE_DISPI_MAX_YRES;
-
-       ret = vbox_mode_init(dev);
-       if (ret)
-               goto err_drm_mode_cleanup;
-
-       ret = vbox_irq_init(vbox);
-       if (ret)
-               goto err_mode_fini;
-
-       ret = vbox_fbdev_init(dev);
-       if (ret)
-               goto err_irq_fini;
-
-       return 0;
-
-err_irq_fini:
-       vbox_irq_fini(vbox);
-err_mode_fini:
-       vbox_mode_fini(dev);
-err_drm_mode_cleanup:
-       drm_mode_config_cleanup(dev);
-       vbox_mm_fini(vbox);
-err_hw_fini:
-       vbox_hw_fini(vbox);
-       return ret;
-}
-
-void vbox_driver_unload(struct drm_device *dev)
-{
-       struct vbox_private *vbox = dev->dev_private;
-
-       vbox_fbdev_fini(dev);
-       vbox_irq_fini(vbox);
-       vbox_mode_fini(dev);
-       drm_mode_config_cleanup(dev);
-       vbox_mm_fini(vbox);
-       vbox_hw_fini(vbox);
+       pci_iounmap(vbox->ddev.pdev, vbox->guest_heap);
 }
 
-/**
- * @note this is described in the DRM framework documentation.  AST does not
- * have it, but we get an oops on driver unload if it is not present.
- */
-void vbox_driver_lastclose(struct drm_device *dev)
-{
-       struct vbox_private *vbox = dev->dev_private;
-
-       if (vbox->fbdev)
-               drm_fb_helper_restore_fbdev_mode_unlocked(&vbox->fbdev->helper);
-}
-
-int vbox_gem_create(struct drm_device *dev,
+int vbox_gem_create(struct vbox_private *vbox,
                    u32 size, bool iskernel, struct drm_gem_object **obj)
 {
        struct vbox_bo *vboxbo;
@@ -446,7 +334,7 @@ int vbox_gem_create(struct drm_device *dev,
        if (size == 0)
                return -EINVAL;
 
-       ret = vbox_bo_create(dev, size, 0, 0, &vboxbo);
+       ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo);
        if (ret) {
                if (ret != -ERESTARTSYS)
                        DRM_ERROR("failed to allocate GEM object\n");
@@ -461,14 +349,16 @@ int vbox_gem_create(struct drm_device *dev,
 int vbox_dumb_create(struct drm_file *file,
                     struct drm_device *dev, struct drm_mode_create_dumb *args)
 {
-       int ret;
+       struct vbox_private *vbox =
+               container_of(dev, struct vbox_private, ddev);
        struct drm_gem_object *gobj;
        u32 handle;
+       int ret;
 
        args->pitch = args->width * ((args->bpp + 7) / 8);
        args->size = args->pitch * args->height;
 
-       ret = vbox_gem_create(dev, args->size, false, &gobj);
+       ret = vbox_gem_create(vbox, args->size, false, &gobj);
        if (ret)
                return ret;
 
@@ -482,24 +372,11 @@ int vbox_dumb_create(struct drm_file *file,
        return 0;
 }
 
-static void vbox_bo_unref(struct vbox_bo **bo)
-{
-       struct ttm_buffer_object *tbo;
-
-       if ((*bo) == NULL)
-               return;
-
-       tbo = &((*bo)->bo);
-       ttm_bo_unref(&tbo);
-       if (!tbo)
-               *bo = NULL;
-}
-
 void vbox_gem_free_object(struct drm_gem_object *obj)
 {
        struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
 
-       vbox_bo_unref(&vbox_bo);
+       ttm_bo_put(&vbox_bo->bo);
 }
 
 static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
index 79836c8fb909d6851ed1edb014146aae07326ea0..6acc965247ff78efd4b92643a15eb5151a0ff47e 100644 (file)
  *          Hans de Goede <hdegoede@redhat.com>
  */
 #include <linux/export.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
+#include <drm/drm_atomic_helper.h>
 
 #include "vbox_drv.h"
 #include "vboxvideo.h"
 #include "hgsmi_channels.h"
 
-static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
-                           u32 handle, u32 width, u32 height,
-                           s32 hot_x, s32 hot_y);
-static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y);
-
 /**
  * Set a graphics mode.  Poke any required values into registers, do an HGSMI
  * mode set and tell the host we support advanced graphics functions.
  */
-static void vbox_do_modeset(struct drm_crtc *crtc,
-                           const struct drm_display_mode *mode)
+static void vbox_do_modeset(struct drm_crtc *crtc)
 {
+       struct drm_framebuffer *fb = crtc->primary->state->fb;
        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
        struct vbox_private *vbox;
        int width, height, bpp, pitch;
@@ -58,12 +55,12 @@ static void vbox_do_modeset(struct drm_crtc *crtc,
        s32 x_offset, y_offset;
 
        vbox = crtc->dev->dev_private;
-       width = mode->hdisplay ? mode->hdisplay : 640;
-       height = mode->vdisplay ? mode->vdisplay : 480;
-       bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
-       pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
-       x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
-       y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint;
+       width = vbox_crtc->width ? vbox_crtc->width : 640;
+       height = vbox_crtc->height ? vbox_crtc->height : 480;
+       bpp = fb ? fb->format->cpp[0] * 8 : 32;
+       pitch = fb ? fb->pitches[0] : width * bpp / 8;
+       x_offset = vbox->single_framebuffer ? vbox_crtc->x : vbox_crtc->x_hint;
+       y_offset = vbox->single_framebuffer ? vbox_crtc->y : vbox_crtc->y_hint;
 
        /*
         * This is the old way of setting graphics modes.  It assumed one screen
@@ -71,31 +68,29 @@ static void vbox_do_modeset(struct drm_crtc *crtc,
         * VirtualBox, certain parts of the code still assume that the first
         * screen is programmed this way, so try to fake it.
         */
-       if (vbox_crtc->crtc_id == 0 && crtc->enabled &&
+       if (vbox_crtc->crtc_id == 0 && fb &&
            vbox_crtc->fb_offset / pitch < 0xffff - crtc->y &&
            vbox_crtc->fb_offset % (bpp / 8) == 0) {
                vbox_write_ioport(VBE_DISPI_INDEX_XRES, width);
                vbox_write_ioport(VBE_DISPI_INDEX_YRES, height);
                vbox_write_ioport(VBE_DISPI_INDEX_VIRT_WIDTH, pitch * 8 / bpp);
-               vbox_write_ioport(VBE_DISPI_INDEX_BPP,
-                                 CRTC_FB(crtc)->format->cpp[0] * 8);
+               vbox_write_ioport(VBE_DISPI_INDEX_BPP, bpp);
                vbox_write_ioport(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
                vbox_write_ioport(
                        VBE_DISPI_INDEX_X_OFFSET,
-                       vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x);
+                       vbox_crtc->fb_offset % pitch / bpp * 8 + vbox_crtc->x);
                vbox_write_ioport(VBE_DISPI_INDEX_Y_OFFSET,
-                                 vbox_crtc->fb_offset / pitch + crtc->y);
+                                 vbox_crtc->fb_offset / pitch + vbox_crtc->y);
        }
 
        flags = VBVA_SCREEN_F_ACTIVE;
-       flags |= (crtc->enabled && !vbox_crtc->blanked) ?
-                0 : VBVA_SCREEN_F_BLANK;
+       flags |= (fb && crtc->state->active) ? 0 : VBVA_SCREEN_F_BLANK;
        flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
        hgsmi_process_display_info(vbox->guest_pool, vbox_crtc->crtc_id,
                                   x_offset, y_offset,
-                                  crtc->x * bpp / 8 + crtc->y * pitch,
-                                  pitch, width, height,
-                                  vbox_crtc->blanked ? 0 : bpp, flags);
+                                  vbox_crtc->x * bpp / 8 +
+                                                       vbox_crtc->y * pitch,
+                                  pitch, width, height, bpp, flags);
 }
 
 static int vbox_set_view(struct drm_crtc *crtc)
@@ -132,34 +127,6 @@ static int vbox_set_view(struct drm_crtc *crtc)
        return 0;
 }
 
-static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
-       struct vbox_private *vbox = crtc->dev->dev_private;
-
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-               vbox_crtc->blanked = false;
-               break;
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-       case DRM_MODE_DPMS_OFF:
-               vbox_crtc->blanked = true;
-               break;
-       }
-
-       mutex_lock(&vbox->hw_mutex);
-       vbox_do_modeset(crtc, &crtc->hwmode);
-       mutex_unlock(&vbox->hw_mutex);
-}
-
-static bool vbox_crtc_mode_fixup(struct drm_crtc *crtc,
-                                const struct drm_display_mode *mode,
-                                struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
 /*
  * Try to map the layout of virtual screens to the range of the input device.
  * Return true if we need to re-set the crtc modes due to screen offset
@@ -169,7 +136,7 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
 {
        struct drm_crtc *crtci;
        struct drm_connector *connectori;
-       struct drm_framebuffer *fb1 = NULL;
+       struct drm_framebuffer *fb, *fb1 = NULL;
        bool single_framebuffer = true;
        bool old_single_framebuffer = vbox->single_framebuffer;
        u16 width = 0, height = 0;
@@ -179,30 +146,30 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
         * If so then screen layout can be deduced from the crtc offsets.
         * Same fall-back if this is the fbdev frame-buffer.
         */
-       list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
+       list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) {
+               fb = crtci->primary->state->fb;
+               if (!fb)
+                       continue;
+
                if (!fb1) {
-                       fb1 = CRTC_FB(crtci);
-                       if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb)
+                       fb1 = fb;
+                       if (to_vbox_framebuffer(fb1) == &vbox->afb)
                                break;
-               } else if (CRTC_FB(crtci) && fb1 != CRTC_FB(crtci)) {
+               } else if (fb != fb1) {
                        single_framebuffer = false;
                }
        }
-       if (single_framebuffer) {
-               list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
-                                   head) {
-                       if (to_vbox_crtc(crtci)->crtc_id != 0)
-                               continue;
+       if (!fb1)
+               return false;
 
-                       vbox->single_framebuffer = true;
-                       vbox->input_mapping_width = CRTC_FB(crtci)->width;
-                       vbox->input_mapping_height = CRTC_FB(crtci)->height;
-                       return old_single_framebuffer !=
-                              vbox->single_framebuffer;
-               }
+       if (single_framebuffer) {
+               vbox->single_framebuffer = true;
+               vbox->input_mapping_width = fb1->width;
+               vbox->input_mapping_height = fb1->height;
+               return old_single_framebuffer != vbox->single_framebuffer;
        }
        /* Otherwise calculate the total span of all screens. */
-       list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list,
+       list_for_each_entry(connectori, &vbox->ddev.mode_config.connector_list,
                            head) {
                struct vbox_connector *vbox_connector =
                    to_vbox_connector(connectori);
@@ -221,180 +188,462 @@ static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
        return old_single_framebuffer != vbox->single_framebuffer;
 }
 
-static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
-                                struct drm_framebuffer *old_fb,
-                                struct drm_framebuffer *new_fb,
-                                int x, int y)
+static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc,
+                                       struct drm_framebuffer *fb,
+                                       struct drm_display_mode *mode,
+                                       int x, int y)
 {
+       struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
        struct vbox_private *vbox = crtc->dev->dev_private;
        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
-       struct drm_gem_object *obj;
-       struct vbox_framebuffer *vbox_fb;
-       struct vbox_bo *bo;
-       int ret;
-       u64 gpu_addr;
-
-       /* Unpin the previous fb. */
-       if (old_fb) {
-               vbox_fb = to_vbox_framebuffer(old_fb);
-               obj = vbox_fb->obj;
-               bo = gem_to_vbox_bo(obj);
-               ret = vbox_bo_reserve(bo, false);
-               if (ret)
-                       return ret;
+       bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
+
+       mutex_lock(&vbox->hw_mutex);
 
-               vbox_bo_unpin(bo);
-               vbox_bo_unreserve(bo);
+       vbox_crtc->width = mode->hdisplay;
+       vbox_crtc->height = mode->vdisplay;
+       vbox_crtc->x = x;
+       vbox_crtc->y = y;
+       vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo);
+
+       /* vbox_do_modeset() checks vbox->single_framebuffer so update it now */
+       if (needs_modeset && vbox_set_up_input_mapping(vbox)) {
+               struct drm_crtc *crtci;
+
+               list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list,
+                                   head) {
+                       if (crtci == crtc)
+                               continue;
+                       vbox_do_modeset(crtci);
+               }
        }
 
-       vbox_fb = to_vbox_framebuffer(new_fb);
-       obj = vbox_fb->obj;
-       bo = gem_to_vbox_bo(obj);
+       vbox_set_view(crtc);
+       vbox_do_modeset(crtc);
 
-       ret = vbox_bo_reserve(bo, false);
-       if (ret)
-               return ret;
+       if (needs_modeset)
+               hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
+                                          vbox->input_mapping_width,
+                                          vbox->input_mapping_height);
 
-       ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
-       if (ret) {
-               vbox_bo_unreserve(bo);
-               return ret;
+       mutex_unlock(&vbox->hw_mutex);
+}
+
+static void vbox_crtc_atomic_enable(struct drm_crtc *crtc,
+                                   struct drm_crtc_state *old_crtc_state)
+{
+}
+
+static void vbox_crtc_atomic_disable(struct drm_crtc *crtc,
+                                    struct drm_crtc_state *old_crtc_state)
+{
+}
+
+static void vbox_crtc_atomic_flush(struct drm_crtc *crtc,
+                                  struct drm_crtc_state *old_crtc_state)
+{
+       struct drm_pending_vblank_event *event;
+       unsigned long flags;
+
+       if (crtc->state && crtc->state->event) {
+               event = crtc->state->event;
+               crtc->state->event = NULL;
+
+               spin_lock_irqsave(&crtc->dev->event_lock, flags);
+               drm_crtc_send_vblank_event(crtc, event);
+               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
        }
+}
 
-       if (&vbox->fbdev->afb == vbox_fb)
-               vbox_fbdev_set_base(vbox, gpu_addr);
-       vbox_bo_unreserve(bo);
+static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
+       .atomic_enable = vbox_crtc_atomic_enable,
+       .atomic_disable = vbox_crtc_atomic_disable,
+       .atomic_flush = vbox_crtc_atomic_flush,
+};
 
-       /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
-       vbox_crtc->fb_offset = gpu_addr;
-       if (vbox_set_up_input_mapping(vbox)) {
-               struct drm_crtc *crtci;
+static void vbox_crtc_destroy(struct drm_crtc *crtc)
+{
+       drm_crtc_cleanup(crtc);
+       kfree(crtc);
+}
 
-               list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
-                                   head) {
-                       vbox_set_view(crtc);
-                       vbox_do_modeset(crtci, &crtci->mode);
-               }
+static const struct drm_crtc_funcs vbox_crtc_funcs = {
+       .set_config = drm_atomic_helper_set_config,
+       .page_flip = drm_atomic_helper_page_flip,
+       /* .gamma_set = vbox_crtc_gamma_set, */
+       .destroy = vbox_crtc_destroy,
+       .reset = drm_atomic_helper_crtc_reset,
+       .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+       .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+};
+
+static int vbox_primary_atomic_check(struct drm_plane *plane,
+                                    struct drm_plane_state *new_state)
+{
+       struct drm_crtc_state *crtc_state = NULL;
+
+       if (new_state->crtc) {
+               crtc_state = drm_atomic_get_existing_crtc_state(
+                                           new_state->state, new_state->crtc);
+               if (WARN_ON(!crtc_state))
+                       return -EINVAL;
        }
 
-       return 0;
+       return drm_atomic_helper_check_plane_state(new_state, crtc_state,
+                                                  DRM_PLANE_HELPER_NO_SCALING,
+                                                  DRM_PLANE_HELPER_NO_SCALING,
+                                                  false, true);
 }
 
-static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-                                  struct drm_framebuffer *old_fb)
+static void vbox_primary_atomic_update(struct drm_plane *plane,
+                                      struct drm_plane_state *old_state)
 {
-       return vbox_crtc_do_set_base(crtc, old_fb, CRTC_FB(crtc), x, y);
+       struct drm_crtc *crtc = plane->state->crtc;
+       struct drm_framebuffer *fb = plane->state->fb;
+
+       vbox_crtc_set_base_and_mode(crtc, fb, &crtc->state->mode,
+                                   plane->state->src_x >> 16,
+                                   plane->state->src_y >> 16);
 }
 
-static int vbox_crtc_mode_set(struct drm_crtc *crtc,
-                             struct drm_display_mode *mode,
-                             struct drm_display_mode *adjusted_mode,
-                             int x, int y, struct drm_framebuffer *old_fb)
+static void vbox_primary_atomic_disable(struct drm_plane *plane,
+                                       struct drm_plane_state *old_state)
 {
-       struct vbox_private *vbox = crtc->dev->dev_private;
+       struct drm_crtc *crtc = old_state->crtc;
+
+       /* vbox_do_modeset checks plane->state->fb and will disable if NULL */
+       vbox_crtc_set_base_and_mode(crtc, old_state->fb, &crtc->state->mode,
+                                   old_state->src_x >> 16,
+                                   old_state->src_y >> 16);
+}
+
+static int vbox_primary_prepare_fb(struct drm_plane *plane,
+                                  struct drm_plane_state *new_state)
+{
+       struct vbox_bo *bo;
        int ret;
 
-       vbox_crtc_mode_set_base(crtc, x, y, old_fb);
+       if (!new_state->fb)
+               return 0;
 
-       mutex_lock(&vbox->hw_mutex);
-       ret = vbox_set_view(crtc);
-       if (!ret)
-               vbox_do_modeset(crtc, mode);
-       hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
-                                  vbox->input_mapping_width,
-                                  vbox->input_mapping_height);
-       mutex_unlock(&vbox->hw_mutex);
+       bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
+       ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
+       if (ret)
+               DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret);
 
        return ret;
 }
 
-static int vbox_crtc_page_flip(struct drm_crtc *crtc,
-                              struct drm_framebuffer *fb,
-                              struct drm_pending_vblank_event *event,
-                              uint32_t page_flip_flags,
-                              struct drm_modeset_acquire_ctx *ctx)
+static void vbox_primary_cleanup_fb(struct drm_plane *plane,
+                                   struct drm_plane_state *old_state)
 {
-       struct vbox_private *vbox = crtc->dev->dev_private;
-       struct drm_device *drm = vbox->dev;
-       unsigned long flags;
-       int rc;
+       struct vbox_bo *bo;
 
-       rc = vbox_crtc_do_set_base(crtc, CRTC_FB(crtc), fb, 0, 0);
-       if (rc)
-               return rc;
+       if (!old_state->fb)
+               return;
 
-       mutex_lock(&vbox->hw_mutex);
-       vbox_set_view(crtc);
-       vbox_do_modeset(crtc, &crtc->mode);
-       mutex_unlock(&vbox->hw_mutex);
+       bo = gem_to_vbox_bo(to_vbox_framebuffer(old_state->fb)->obj);
+       vbox_bo_unpin(bo);
+}
 
-       spin_lock_irqsave(&drm->event_lock, flags);
+static int vbox_cursor_atomic_check(struct drm_plane *plane,
+                                   struct drm_plane_state *new_state)
+{
+       struct drm_crtc_state *crtc_state = NULL;
+       u32 width = new_state->crtc_w;
+       u32 height = new_state->crtc_h;
+       int ret;
 
-       if (event)
-               drm_crtc_send_vblank_event(crtc, event);
+       if (new_state->crtc) {
+               crtc_state = drm_atomic_get_existing_crtc_state(
+                                           new_state->state, new_state->crtc);
+               if (WARN_ON(!crtc_state))
+                       return -EINVAL;
+       }
 
-       spin_unlock_irqrestore(&drm->event_lock, flags);
+       ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
+                                                 DRM_PLANE_HELPER_NO_SCALING,
+                                                 DRM_PLANE_HELPER_NO_SCALING,
+                                                 true, true);
+       if (ret)
+               return ret;
+
+       if (!new_state->fb)
+               return 0;
+
+       if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
+           width == 0 || height == 0)
+               return -EINVAL;
 
        return 0;
 }
 
-static void vbox_crtc_disable(struct drm_crtc *crtc)
+/**
+ * Copy the ARGB image and generate the mask, which is needed in case the host
+ * does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
+ * if the corresponding alpha value in the ARGB image is greater than 0xF0.
+ */
+static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
+                             size_t mask_size)
 {
+       size_t line_size = (width + 7) / 8;
+       u32 i, j;
+
+       memcpy(dst + mask_size, src, width * height * 4);
+       for (i = 0; i < height; ++i)
+               for (j = 0; j < width; ++j)
+                       if (((u32 *)src)[i * width + j] > 0xf0000000)
+                               dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
 }
 
-static void vbox_crtc_prepare(struct drm_crtc *crtc)
+static void vbox_cursor_atomic_update(struct drm_plane *plane,
+                                     struct drm_plane_state *old_state)
 {
+       struct vbox_private *vbox =
+               container_of(plane->dev, struct vbox_private, ddev);
+       struct vbox_crtc *vbox_crtc = to_vbox_crtc(plane->state->crtc);
+       struct drm_framebuffer *fb = plane->state->fb;
+       struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
+       u32 width = plane->state->crtc_w;
+       u32 height = plane->state->crtc_h;
+       size_t data_size, mask_size;
+       u32 flags;
+       u8 *src;
+
+       /*
+        * VirtualBox uses the host windowing system to draw the cursor so
+        * moves are a no-op, we only need to upload new cursor sprites.
+        */
+       if (fb == old_state->fb)
+               return;
+
+       mutex_lock(&vbox->hw_mutex);
+
+       vbox_crtc->cursor_enabled = true;
+
+       /* pinning is done in prepare/cleanup framebuffer */
+       src = vbox_bo_kmap(bo);
+       if (IS_ERR(src)) {
+               mutex_unlock(&vbox->hw_mutex);
+               DRM_WARN("Could not kmap cursor bo, skipping update\n");
+               return;
+       }
+
+       /*
+        * The mask must be calculated based on the alpha
+        * channel, one bit per ARGB word, and must be 32-bit
+        * padded.
+        */
+       mask_size = ((width + 7) / 8 * height + 3) & ~3;
+       data_size = width * height * 4 + mask_size;
+
+       copy_cursor_image(src, vbox->cursor_data, width, height, mask_size);
+       vbox_bo_kunmap(bo);
+
+       flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
+               VBOX_MOUSE_POINTER_ALPHA;
+       hgsmi_update_pointer_shape(vbox->guest_pool, flags,
+                                  min_t(u32, max(fb->hot_x, 0), width),
+                                  min_t(u32, max(fb->hot_y, 0), height),
+                                  width, height, vbox->cursor_data, data_size);
+
+       mutex_unlock(&vbox->hw_mutex);
 }
 
-static void vbox_crtc_commit(struct drm_crtc *crtc)
+static void vbox_cursor_atomic_disable(struct drm_plane *plane,
+                                      struct drm_plane_state *old_state)
 {
-}
+       struct vbox_private *vbox =
+               container_of(plane->dev, struct vbox_private, ddev);
+       struct vbox_crtc *vbox_crtc = to_vbox_crtc(old_state->crtc);
+       bool cursor_enabled = false;
+       struct drm_crtc *crtci;
 
-static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
-       .dpms = vbox_crtc_dpms,
-       .mode_fixup = vbox_crtc_mode_fixup,
-       .mode_set = vbox_crtc_mode_set,
-       /* .mode_set_base = vbox_crtc_mode_set_base, */
-       .disable = vbox_crtc_disable,
-       .prepare = vbox_crtc_prepare,
-       .commit = vbox_crtc_commit,
-};
+       mutex_lock(&vbox->hw_mutex);
 
-static void vbox_crtc_reset(struct drm_crtc *crtc)
+       vbox_crtc->cursor_enabled = false;
+
+       list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) {
+               if (to_vbox_crtc(crtci)->cursor_enabled)
+                       cursor_enabled = true;
+       }
+
+       if (!cursor_enabled)
+               hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0,
+                                          0, 0, NULL, 0);
+
+       mutex_unlock(&vbox->hw_mutex);
+}
+
+static int vbox_cursor_prepare_fb(struct drm_plane *plane,
+                                 struct drm_plane_state *new_state)
 {
+       struct vbox_bo *bo;
+
+       if (!new_state->fb)
+               return 0;
+
+       bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
+       return vbox_bo_pin(bo, TTM_PL_FLAG_SYSTEM);
 }
 
-static void vbox_crtc_destroy(struct drm_crtc *crtc)
+static void vbox_cursor_cleanup_fb(struct drm_plane *plane,
+                                  struct drm_plane_state *old_state)
 {
-       drm_crtc_cleanup(crtc);
-       kfree(crtc);
+       struct vbox_bo *bo;
+
+       if (!plane->state->fb)
+               return;
+
+       bo = gem_to_vbox_bo(to_vbox_framebuffer(plane->state->fb)->obj);
+       vbox_bo_unpin(bo);
 }
 
-static const struct drm_crtc_funcs vbox_crtc_funcs = {
-       .cursor_move = vbox_cursor_move,
-       .cursor_set2 = vbox_cursor_set2,
-       .reset = vbox_crtc_reset,
-       .set_config = drm_crtc_helper_set_config,
-       /* .gamma_set = vbox_crtc_gamma_set, */
-       .page_flip = vbox_crtc_page_flip,
-       .destroy = vbox_crtc_destroy,
+static const uint32_t vbox_cursor_plane_formats[] = {
+       DRM_FORMAT_ARGB8888,
 };
 
+static const struct drm_plane_helper_funcs vbox_cursor_helper_funcs = {
+       .atomic_check   = vbox_cursor_atomic_check,
+       .atomic_update  = vbox_cursor_atomic_update,
+       .atomic_disable = vbox_cursor_atomic_disable,
+       .prepare_fb     = vbox_cursor_prepare_fb,
+       .cleanup_fb     = vbox_cursor_cleanup_fb,
+};
+
+static const struct drm_plane_funcs vbox_cursor_plane_funcs = {
+       .update_plane   = drm_atomic_helper_update_plane,
+       .disable_plane  = drm_atomic_helper_disable_plane,
+       .destroy        = drm_primary_helper_destroy,
+       .reset          = drm_atomic_helper_plane_reset,
+       .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+       .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static const uint32_t vbox_primary_plane_formats[] = {
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+};
+
+static const struct drm_plane_helper_funcs vbox_primary_helper_funcs = {
+       .atomic_check = vbox_primary_atomic_check,
+       .atomic_update = vbox_primary_atomic_update,
+       .atomic_disable = vbox_primary_atomic_disable,
+       .prepare_fb = vbox_primary_prepare_fb,
+       .cleanup_fb = vbox_primary_cleanup_fb,
+};
+
+static const struct drm_plane_funcs vbox_primary_plane_funcs = {
+       .update_plane   = drm_atomic_helper_update_plane,
+       .disable_plane  = drm_atomic_helper_disable_plane,
+       .destroy        = drm_primary_helper_destroy,
+       .reset          = drm_atomic_helper_plane_reset,
+       .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+       .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static struct drm_plane *vbox_create_plane(struct vbox_private *vbox,
+                                          unsigned int possible_crtcs,
+                                          enum drm_plane_type type)
+{
+       const struct drm_plane_helper_funcs *helper_funcs = NULL;
+       const struct drm_plane_funcs *funcs;
+       struct drm_plane *plane;
+       const uint32_t *formats;
+       int num_formats;
+       int err;
+
+       if (type == DRM_PLANE_TYPE_PRIMARY) {
+               funcs = &vbox_primary_plane_funcs;
+               formats = vbox_primary_plane_formats;
+               helper_funcs = &vbox_primary_helper_funcs;
+               num_formats = ARRAY_SIZE(vbox_primary_plane_formats);
+       } else if (type == DRM_PLANE_TYPE_CURSOR) {
+               funcs = &vbox_cursor_plane_funcs;
+               formats = vbox_cursor_plane_formats;
+               helper_funcs = &vbox_cursor_helper_funcs;
+               num_formats = ARRAY_SIZE(vbox_cursor_plane_formats);
+       } else {
+               return ERR_PTR(-EINVAL);
+       }
+
+       plane = kzalloc(sizeof(*plane), GFP_KERNEL);
+       if (!plane)
+               return ERR_PTR(-ENOMEM);
+
+       err = drm_universal_plane_init(&vbox->ddev, plane, possible_crtcs,
+                                      funcs, formats, num_formats,
+                                      NULL, type, NULL);
+       if (err)
+               goto free_plane;
+
+       drm_plane_helper_add(plane, helper_funcs);
+
+       return plane;
+
+free_plane:
+       kfree(plane);
+       return ERR_PTR(-EINVAL);
+}
+
 static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i)
 {
+       struct vbox_private *vbox =
+               container_of(dev, struct vbox_private, ddev);
+       struct drm_plane *cursor = NULL;
        struct vbox_crtc *vbox_crtc;
+       struct drm_plane *primary;
+       u32 caps = 0;
+       int ret;
+
+       ret = hgsmi_query_conf(vbox->guest_pool,
+                              VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
+       if (ret)
+               return ERR_PTR(ret);
 
        vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL);
        if (!vbox_crtc)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
+
+       primary = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_PRIMARY);
+       if (IS_ERR(primary)) {
+               ret = PTR_ERR(primary);
+               goto free_mem;
+       }
+
+       if ((caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
+               cursor = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_CURSOR);
+               if (IS_ERR(cursor)) {
+                       ret = PTR_ERR(cursor);
+                       goto clean_primary;
+               }
+       } else {
+               DRM_WARN("VirtualBox host is too old, no cursor support\n");
+       }
 
        vbox_crtc->crtc_id = i;
 
-       drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
+       ret = drm_crtc_init_with_planes(dev, &vbox_crtc->base, primary, cursor,
+                                       &vbox_crtc_funcs, NULL);
+       if (ret)
+               goto clean_cursor;
+
        drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
        drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
 
        return vbox_crtc;
+
+clean_cursor:
+       if (cursor) {
+               drm_plane_cleanup(cursor);
+               kfree(cursor);
+       }
+clean_primary:
+       drm_plane_cleanup(primary);
+       kfree(primary);
+free_mem:
+       kfree(vbox_crtc);
+       return ERR_PTR(ret);
 }
 
 static void vbox_encoder_destroy(struct drm_encoder *encoder)
@@ -403,55 +652,10 @@ static void vbox_encoder_destroy(struct drm_encoder *encoder)
        kfree(encoder);
 }
 
-static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
-                                                   *connector)
-{
-       int enc_id = connector->encoder_ids[0];
-
-       /* pick the encoder ids */
-       if (enc_id)
-               return drm_encoder_find(connector->dev, NULL, enc_id);
-
-       return NULL;
-}
-
 static const struct drm_encoder_funcs vbox_enc_funcs = {
        .destroy = vbox_encoder_destroy,
 };
 
-static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-}
-
-static bool vbox_mode_fixup(struct drm_encoder *encoder,
-                           const struct drm_display_mode *mode,
-                           struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void vbox_encoder_mode_set(struct drm_encoder *encoder,
-                                 struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-}
-
-static void vbox_encoder_prepare(struct drm_encoder *encoder)
-{
-}
-
-static void vbox_encoder_commit(struct drm_encoder *encoder)
-{
-}
-
-static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
-       .dpms = vbox_encoder_dpms,
-       .mode_fixup = vbox_mode_fixup,
-       .prepare = vbox_encoder_prepare,
-       .commit = vbox_encoder_commit,
-       .mode_set = vbox_encoder_mode_set,
-};
-
 static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
                                             unsigned int i)
 {
@@ -463,7 +667,6 @@ static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
 
        drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
                         DRM_MODE_ENCODER_DAC, NULL);
-       drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
 
        vbox_encoder->base.possible_crtcs = 1 << i;
        return &vbox_encoder->base;
@@ -589,29 +792,23 @@ static int vbox_get_modes(struct drm_connector *connector)
 
        if (vbox_connector->vbox_crtc->x_hint != -1)
                drm_object_property_set_value(&connector->base,
-                       vbox->dev->mode_config.suggested_x_property,
+                       vbox->ddev.mode_config.suggested_x_property,
                        vbox_connector->vbox_crtc->x_hint);
        else
                drm_object_property_set_value(&connector->base,
-                       vbox->dev->mode_config.suggested_x_property, 0);
+                       vbox->ddev.mode_config.suggested_x_property, 0);
 
        if (vbox_connector->vbox_crtc->y_hint != -1)
                drm_object_property_set_value(&connector->base,
-                       vbox->dev->mode_config.suggested_y_property,
+                       vbox->ddev.mode_config.suggested_y_property,
                        vbox_connector->vbox_crtc->y_hint);
        else
                drm_object_property_set_value(&connector->base,
-                       vbox->dev->mode_config.suggested_y_property, 0);
+                       vbox->ddev.mode_config.suggested_y_property, 0);
 
        return num_modes;
 }
 
-static enum drm_mode_status vbox_mode_valid(struct drm_connector *connector,
-                          struct drm_display_mode *mode)
-{
-       return MODE_OK;
-}
-
 static void vbox_connector_destroy(struct drm_connector *connector)
 {
        drm_connector_unregister(connector);
@@ -648,16 +845,16 @@ static int vbox_fill_modes(struct drm_connector *connector, u32 max_x,
 }
 
 static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
-       .mode_valid = vbox_mode_valid,
        .get_modes = vbox_get_modes,
-       .best_encoder = vbox_best_single_encoder,
 };
 
 static const struct drm_connector_funcs vbox_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
        .detect = vbox_connector_detect,
        .fill_modes = vbox_fill_modes,
        .destroy = vbox_connector_destroy,
+       .reset = drm_atomic_helper_connector_reset,
+       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static int vbox_connector_init(struct drm_device *dev,
@@ -686,225 +883,92 @@ static int vbox_connector_init(struct drm_device *dev,
                                   dev->mode_config.suggested_x_property, 0);
        drm_object_attach_property(&connector->base,
                                   dev->mode_config.suggested_y_property, 0);
-       drm_connector_register(connector);
 
        drm_connector_attach_encoder(connector, encoder);
 
        return 0;
 }
 
-int vbox_mode_init(struct drm_device *dev)
+static struct drm_framebuffer *vbox_user_framebuffer_create(
+               struct drm_device *dev,
+               struct drm_file *filp,
+               const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-       struct vbox_private *vbox = dev->dev_private;
-       struct drm_encoder *encoder;
-       struct vbox_crtc *vbox_crtc;
-       unsigned int i;
-       int ret;
+       struct vbox_private *vbox =
+               container_of(dev, struct vbox_private, ddev);
+       struct drm_gem_object *obj;
+       struct vbox_framebuffer *vbox_fb;
+       int ret = -ENOMEM;
 
-       /* vbox_cursor_init(dev); */
-       for (i = 0; i < vbox->num_crtcs; ++i) {
-               vbox_crtc = vbox_crtc_init(dev, i);
-               if (!vbox_crtc)
-                       return -ENOMEM;
-               encoder = vbox_encoder_init(dev, i);
-               if (!encoder)
-                       return -ENOMEM;
-               ret = vbox_connector_init(dev, vbox_crtc, encoder);
-               if (ret)
-                       return ret;
-       }
+       obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]);
+       if (!obj)
+               return ERR_PTR(-ENOENT);
 
-       return 0;
-}
+       vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL);
+       if (!vbox_fb)
+               goto err_unref_obj;
 
-void vbox_mode_fini(struct drm_device *dev)
-{
-       /* vbox_cursor_fini(dev); */
-}
+       ret = vbox_framebuffer_init(vbox, vbox_fb, mode_cmd, obj);
+       if (ret)
+               goto err_free_vbox_fb;
 
-/**
- * Copy the ARGB image and generate the mask, which is needed in case the host
- * does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
- * if the corresponding alpha value in the ARGB image is greater than 0xF0.
- */
-static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
-                             size_t mask_size)
-{
-       size_t line_size = (width + 7) / 8;
-       u32 i, j;
+       return &vbox_fb->base;
 
-       memcpy(dst + mask_size, src, width * height * 4);
-       for (i = 0; i < height; ++i)
-               for (j = 0; j < width; ++j)
-                       if (((u32 *)src)[i * width + j] > 0xf0000000)
-                               dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
+err_free_vbox_fb:
+       kfree(vbox_fb);
+err_unref_obj:
+       drm_gem_object_put_unlocked(obj);
+       return ERR_PTR(ret);
 }
 
-static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
-                           u32 handle, u32 width, u32 height,
-                           s32 hot_x, s32 hot_y)
+static const struct drm_mode_config_funcs vbox_mode_funcs = {
+       .fb_create = vbox_user_framebuffer_create,
+       .atomic_check = drm_atomic_helper_check,
+       .atomic_commit = drm_atomic_helper_commit,
+};
+
+int vbox_mode_init(struct vbox_private *vbox)
 {
-       struct vbox_private *vbox = crtc->dev->dev_private;
-       struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
-       struct ttm_bo_kmap_obj uobj_map;
-       size_t data_size, mask_size;
-       struct drm_gem_object *obj;
-       u32 flags, caps = 0;
-       struct vbox_bo *bo;
-       bool src_isiomem;
-       u8 *dst = NULL;
-       u8 *src;
+       struct drm_device *dev = &vbox->ddev;
+       struct drm_encoder *encoder;
+       struct vbox_crtc *vbox_crtc;
+       unsigned int i;
        int ret;
 
-       /*
-        * Re-set this regularly as in 5.0.20 and earlier the information was
-        * lost on save and restore.
-        */
-       hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
-                                  vbox->input_mapping_width,
-                                  vbox->input_mapping_height);
-       if (!handle) {
-               bool cursor_enabled = false;
-               struct drm_crtc *crtci;
-
-               /* Hide cursor. */
-               vbox_crtc->cursor_enabled = false;
-               list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
-                                   head) {
-                       if (to_vbox_crtc(crtci)->cursor_enabled)
-                               cursor_enabled = true;
-               }
-
-               if (!cursor_enabled)
-                       hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0,
-                                                  0, 0, NULL, 0);
-               return 0;
-       }
-
-       vbox_crtc->cursor_enabled = true;
-
-       if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
-           width == 0 || height == 0)
-               return -EINVAL;
-
-       ret = hgsmi_query_conf(vbox->guest_pool,
-                              VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
-       if (ret)
-               return ret;
-
-       if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
-               /*
-                * -EINVAL means cursor_set2() not supported, -EAGAIN means
-                * retry at once.
-                */
-               return -EBUSY;
-       }
-
-       obj = drm_gem_object_lookup(file_priv, handle);
-       if (!obj) {
-               DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
-               return -ENOENT;
-       }
+       drm_mode_config_init(dev);
 
-       bo = gem_to_vbox_bo(obj);
-       ret = vbox_bo_reserve(bo, false);
-       if (ret)
-               goto out_unref_obj;
+       dev->mode_config.funcs = (void *)&vbox_mode_funcs;
+       dev->mode_config.min_width = 0;
+       dev->mode_config.min_height = 0;
+       dev->mode_config.preferred_depth = 24;
+       dev->mode_config.max_width = VBE_DISPI_MAX_XRES;
+       dev->mode_config.max_height = VBE_DISPI_MAX_YRES;
 
-       /*
-        * The mask must be calculated based on the alpha
-        * channel, one bit per ARGB word, and must be 32-bit
-        * padded.
-        */
-       mask_size = ((width + 7) / 8 * height + 3) & ~3;
-       data_size = width * height * 4 + mask_size;
-       vbox->cursor_hot_x = min_t(u32, max(hot_x, 0), width);
-       vbox->cursor_hot_y = min_t(u32, max(hot_y, 0), height);
-       vbox->cursor_width = width;
-       vbox->cursor_height = height;
-       vbox->cursor_data_size = data_size;
-       dst = vbox->cursor_data;
-
-       ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
-       if (ret) {
-               vbox->cursor_data_size = 0;
-               goto out_unreserve_bo;
-       }
-
-       src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
-       if (src_isiomem) {
-               DRM_ERROR("src cursor bo not in main memory\n");
-               ret = -EIO;
-               goto out_unmap_bo;
+       for (i = 0; i < vbox->num_crtcs; ++i) {
+               vbox_crtc = vbox_crtc_init(dev, i);
+               if (IS_ERR(vbox_crtc)) {
+                       ret = PTR_ERR(vbox_crtc);
+                       goto err_drm_mode_cleanup;
+               }
+               encoder = vbox_encoder_init(dev, i);
+               if (!encoder) {
+                       ret = -ENOMEM;
+                       goto err_drm_mode_cleanup;
+               }
+               ret = vbox_connector_init(dev, vbox_crtc, encoder);
+               if (ret)
+                       goto err_drm_mode_cleanup;
        }
 
-       copy_cursor_image(src, dst, width, height, mask_size);
-
-       flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
-               VBOX_MOUSE_POINTER_ALPHA;
-       ret = hgsmi_update_pointer_shape(vbox->guest_pool, flags,
-                                        vbox->cursor_hot_x, vbox->cursor_hot_y,
-                                        width, height, dst, data_size);
-out_unmap_bo:
-       ttm_bo_kunmap(&uobj_map);
-out_unreserve_bo:
-       vbox_bo_unreserve(bo);
-out_unref_obj:
-       drm_gem_object_put_unlocked(obj);
+       drm_mode_config_reset(dev);
+       return 0;
 
+err_drm_mode_cleanup:
+       drm_mode_config_cleanup(dev);
        return ret;
 }
 
-static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y)
+void vbox_mode_fini(struct vbox_private *vbox)
 {
-       struct vbox_private *vbox = crtc->dev->dev_private;
-       u32 flags = VBOX_MOUSE_POINTER_VISIBLE |
-           VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
-       s32 crtc_x =
-           vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
-       s32 crtc_y =
-           vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
-       u32 host_x, host_y;
-       u32 hot_x = 0;
-       u32 hot_y = 0;
-       int ret;
-
-       /*
-        * We compare these to unsigned later and don't
-        * need to handle negative.
-        */
-       if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
-               return 0;
-
-       ret = hgsmi_cursor_position(vbox->guest_pool, true, x + crtc_x,
-                                   y + crtc_y, &host_x, &host_y);
-
-       /*
-        * The only reason we have vbox_cursor_move() is that some older clients
-        * might use DRM_IOCTL_MODE_CURSOR instead of DRM_IOCTL_MODE_CURSOR2 and
-        * use DRM_MODE_CURSOR_MOVE to set the hot-spot.
-        *
-        * However VirtualBox 5.0.20 and earlier has a bug causing it to return
-        * 0,0 as host cursor location after a save and restore.
-        *
-        * To work around this we ignore a 0, 0 return, since missing the odd
-        * time when it legitimately happens is not going to hurt much.
-        */
-       if (ret || (host_x == 0 && host_y == 0))
-               return ret;
-
-       if (x + crtc_x < host_x)
-               hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
-       if (y + crtc_y < host_y)
-               hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
-
-       if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
-               return 0;
-
-       vbox->cursor_hot_x = hot_x;
-       vbox->cursor_hot_y = hot_y;
-
-       return hgsmi_update_pointer_shape(vbox->guest_pool, flags,
-                       hot_x, hot_y, vbox->cursor_width, vbox->cursor_height,
-                       vbox->cursor_data, vbox->cursor_data_size);
+       drm_mode_config_cleanup(&vbox->ddev);
 }
index 548edb7c494b420eeb9163370bbd39ea3f7a0c26..5ecfa76291733a5e01aca0edab6b7f6a40acdb94 100644 (file)
@@ -169,7 +169,7 @@ static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
                return 0;
        case TTM_PL_VRAM:
                mem->bus.offset = mem->start << PAGE_SHIFT;
-               mem->bus.base = pci_resource_start(vbox->dev->pdev, 0);
+               mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0);
                mem->bus.is_iomem = true;
                break;
        default:
@@ -224,7 +224,7 @@ static struct ttm_bo_driver vbox_bo_driver = {
 int vbox_mm_init(struct vbox_private *vbox)
 {
        int ret;
-       struct drm_device *dev = vbox->dev;
+       struct drm_device *dev = &vbox->ddev;
        struct ttm_bo_device *bdev = &vbox->ttm.bdev;
 
        ret = vbox_ttm_global_init(vbox);
@@ -269,8 +269,8 @@ void vbox_mm_fini(struct vbox_private *vbox)
 {
 #ifdef DRM_MTRR_WC
        drm_mtrr_del(vbox->fb_mtrr,
-                    pci_resource_start(vbox->dev->pdev, 0),
-                    pci_resource_len(vbox->dev->pdev, 0), DRM_MTRR_WC);
+                    pci_resource_start(vbox->ddev.pdev, 0),
+                    pci_resource_len(vbox->ddev.pdev, 0), DRM_MTRR_WC);
 #else
        arch_phys_wc_del(vbox->fb_mtrr);
 #endif
@@ -305,10 +305,9 @@ void vbox_ttm_placement(struct vbox_bo *bo, int domain)
        }
 }
 
-int vbox_bo_create(struct drm_device *dev, int size, int align,
+int vbox_bo_create(struct vbox_private *vbox, int size, int align,
                   u32 flags, struct vbox_bo **pvboxbo)
 {
-       struct vbox_private *vbox = dev->dev_private;
        struct vbox_bo *vboxbo;
        size_t acc_size;
        int ret;
@@ -317,7 +316,7 @@ int vbox_bo_create(struct drm_device *dev, int size, int align,
        if (!vboxbo)
                return -ENOMEM;
 
-       ret = drm_gem_object_init(dev, &vboxbo->gem, size);
+       ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size);
        if (ret)
                goto err_free_vboxbo;
 
@@ -344,39 +343,32 @@ err_free_vboxbo:
        return ret;
 }
 
-static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
-{
-       return bo->bo.offset;
-}
-
-int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr)
+int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag)
 {
        struct ttm_operation_ctx ctx = { false, false };
        int i, ret;
 
        if (bo->pin_count) {
                bo->pin_count++;
-               if (gpu_addr)
-                       *gpu_addr = vbox_bo_gpu_offset(bo);
-
                return 0;
        }
 
+       ret = vbox_bo_reserve(bo, false);
+       if (ret)
+               return ret;
+
        vbox_ttm_placement(bo, pl_flag);
 
        for (i = 0; i < bo->placement.num_placement; i++)
                bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
 
        ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-       if (ret)
-               return ret;
-
-       bo->pin_count = 1;
+       if (ret == 0)
+               bo->pin_count = 1;
 
-       if (gpu_addr)
-               *gpu_addr = vbox_bo_gpu_offset(bo);
+       vbox_bo_unreserve(bo);
 
-       return 0;
+       return ret;
 }
 
 int vbox_bo_unpin(struct vbox_bo *bo)
@@ -392,14 +384,20 @@ int vbox_bo_unpin(struct vbox_bo *bo)
        if (bo->pin_count)
                return 0;
 
+       ret = vbox_bo_reserve(bo, false);
+       if (ret) {
+               DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret);
+               return ret;
+       }
+
        for (i = 0; i < bo->placement.num_placement; i++)
                bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
 
        ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
-       if (ret)
-               return ret;
 
-       return 0;
+       vbox_bo_unreserve(bo);
+
+       return ret;
 }
 
 /*
@@ -420,8 +418,10 @@ int vbox_bo_push_sysram(struct vbox_bo *bo)
        if (bo->pin_count)
                return 0;
 
-       if (bo->kmap.virtual)
+       if (bo->kmap.virtual) {
                ttm_bo_kunmap(&bo->kmap);
+               bo->kmap.virtual = NULL;
+       }
 
        vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
 
@@ -450,3 +450,27 @@ int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
 
        return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
 }
+
+void *vbox_bo_kmap(struct vbox_bo *bo)
+{
+       int ret;
+
+       if (bo->kmap.virtual)
+               return bo->kmap.virtual;
+
+       ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+       if (ret) {
+               DRM_ERROR("Error kmapping bo: %d\n", ret);
+               return NULL;
+       }
+
+       return bo->kmap.virtual;
+}
+
+void vbox_bo_kunmap(struct vbox_bo *bo)
+{
+       if (bo->kmap.virtual) {
+               ttm_bo_kunmap(&bo->kmap);
+               bo->kmap.virtual = NULL;
+       }
+}
index ec468d5719b11212b52816fd5389d8638c3ab8f2..a6ec72a5f0bece85fed0bc248981c131fff77053 100644 (file)
@@ -1,23 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright 2011 Broadcom Corporation.  All rights reserved. */
 
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/moduleparam.h>
-#include <linux/sched.h>
-
 #include <sound/core.h>
 #include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/rawmidi.h>
-#include <sound/initval.h>
 #include <sound/tlv.h>
 #include <sound/asoundef.h>
 
 #define CTRL_VOL_MAX 400
 #define CTRL_VOL_MIN -10239 /* originally -10240 */
 
+static int bcm2835_audio_set_chip_ctls(struct bcm2835_chip *chip)
+{
+       int i, err = 0;
+
+       /* change ctls for all substreams */
+       for (i = 0; i < MAX_SUBSTREAMS; i++) {
+               if (chip->alsa_stream[i]) {
+                       err = bcm2835_audio_set_ctls(chip->alsa_stream[i]);
+                       if (err < 0)
+                               break;
+               }
+       }
+       return err;
+}
+
 static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_info *uinfo)
 {
@@ -49,41 +49,15 @@ static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-/* toggles mute on or off depending on the value of nmute, and returns
- * 1 if the mute value was changed, otherwise 0
- */
-static int toggle_mute(struct bcm2835_chip *chip, int nmute)
-{
-       /* if settings are ok, just return 0 */
-       if (chip->mute == nmute)
-               return 0;
-
-       /* if the sound is muted then we need to unmute */
-       if (chip->mute == CTRL_VOL_MUTE) {
-               chip->volume = chip->old_volume; /* copy the old volume back */
-               audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume);
-       } else /* otherwise we mute */ {
-               chip->old_volume = chip->volume;
-               chip->volume = 26214; /* set volume to minimum level AKA mute */
-               audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume);
-       }
-
-       chip->mute = nmute;
-       return 1;
-}
-
 static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
        struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
 
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
-
-       BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK));
+       mutex_lock(&chip->audio_mutex);
 
        if (kcontrol->private_value == PCM_PLAYBACK_VOLUME)
-               ucontrol->value.integer.value[0] = chip2alsa(chip->volume);
+               ucontrol->value.integer.value[0] = chip->volume;
        else if (kcontrol->private_value == PCM_PLAYBACK_MUTE)
                ucontrol->value.integer.value[0] = chip->mute;
        else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE)
@@ -97,79 +71,60 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
        struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+       int val, *valp;
        int changed = 0;
 
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
-
-       if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
-               audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]);
-               if (chip->mute == CTRL_VOL_MUTE) {
-                       /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */
-                       changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */
-                       goto unlock;
-               }
-               if (changed || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) {
-                       chip->volume = alsa2chip(ucontrol->value.integer.value[0]);
-                       changed = 1;
-               }
-
-       } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
-               /* Now implemented */
-               audio_info(" Mute attempted\n");
-               changed = toggle_mute(chip, ucontrol->value.integer.value[0]);
-
-       } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) {
-               if (ucontrol->value.integer.value[0] != chip->dest) {
-                       chip->dest = ucontrol->value.integer.value[0];
-                       changed = 1;
-               }
+       if (kcontrol->private_value == PCM_PLAYBACK_VOLUME)
+               valp = &chip->volume;
+       else if (kcontrol->private_value == PCM_PLAYBACK_MUTE)
+               valp = &chip->mute;
+       else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE)
+               valp = &chip->dest;
+       else
+               return -EINVAL;
+
+       val = ucontrol->value.integer.value[0];
+       mutex_lock(&chip->audio_mutex);
+       if (val != *valp) {
+               *valp = val;
+               changed = 1;
+               if (bcm2835_audio_set_chip_ctls(chip))
+                       dev_err(chip->card->dev, "Failed to set ALSA controls..\n");
        }
-
-       if (changed && bcm2835_audio_set_ctls(chip))
-               dev_err(chip->card->dev, "Failed to set ALSA controls..\n");
-
-unlock:
        mutex_unlock(&chip->audio_mutex);
        return changed;
 }
 
 static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1);
 
-static struct snd_kcontrol_new snd_bcm2835_ctl[] = {
+static const struct snd_kcontrol_new snd_bcm2835_ctl[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "PCM Playback Volume",
-               .index = 0,
                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
                .private_value = PCM_PLAYBACK_VOLUME,
                .info = snd_bcm2835_ctl_info,
                .get = snd_bcm2835_ctl_get,
                .put = snd_bcm2835_ctl_put,
-               .count = 1,
                .tlv = {.p = snd_bcm2835_db_scale}
        },
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "PCM Playback Switch",
-               .index = 0,
                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
                .private_value = PCM_PLAYBACK_MUTE,
                .info = snd_bcm2835_ctl_info,
                .get = snd_bcm2835_ctl_get,
                .put = snd_bcm2835_ctl_put,
-               .count = 1,
        },
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "PCM Playback Route",
-               .index = 0,
                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
                .private_value = PCM_PLAYBACK_DEVICE,
                .info = snd_bcm2835_ctl_info,
                .get = snd_bcm2835_ctl_get,
                .put = snd_bcm2835_ctl_put,
-               .count = 1,
        },
 };
 
@@ -187,8 +142,7 @@ static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol,
        struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
        int i;
 
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
+       mutex_lock(&chip->audio_mutex);
 
        for (i = 0; i < 4; i++)
                ucontrol->value.iec958.status[i] =
@@ -205,8 +159,7 @@ static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol,
        unsigned int val = 0;
        int i, change;
 
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
+       mutex_lock(&chip->audio_mutex);
 
        for (i = 0; i < 4; i++)
                val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
@@ -237,51 +190,7 @@ static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-       uinfo->count = 1;
-       return 0;
-}
-
-static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
-       int i;
-
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
-
-       for (i = 0; i < 4; i++)
-               ucontrol->value.iec958.status[i] =
-               (chip->spdif_status >> (i * 8)) & 0xff;
-
-       mutex_unlock(&chip->audio_mutex);
-       return 0;
-}
-
-static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
-       unsigned int val = 0;
-       int i, change;
-
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
-
-       for (i = 0; i < 4; i++)
-               val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
-       change = val != chip->spdif_status;
-       chip->spdif_status = val;
-
-       mutex_unlock(&chip->audio_mutex);
-       return change;
-}
-
-static struct snd_kcontrol_new snd_bcm2835_spdif[] = {
+static const struct snd_kcontrol_new snd_bcm2835_spdif[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_PCM,
                .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -296,39 +205,34 @@ static struct snd_kcontrol_new snd_bcm2835_spdif[] = {
                .info = snd_bcm2835_spdif_mask_info,
                .get = snd_bcm2835_spdif_mask_get,
        },
-       {
-               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-               SNDRV_CTL_ELEM_ACCESS_INACTIVE,
-               .iface = SNDRV_CTL_ELEM_IFACE_PCM,
-               .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
-               .info = snd_bcm2835_spdif_stream_info,
-               .get = snd_bcm2835_spdif_stream_get,
-               .put = snd_bcm2835_spdif_stream_put,
-       },
 };
 
-int snd_bcm2835_new_ctl(struct bcm2835_chip *chip)
+static int create_ctls(struct bcm2835_chip *chip, size_t size,
+                      const struct snd_kcontrol_new *kctls)
 {
-       int err;
-       unsigned int idx;
+       int i, err;
 
-       strcpy(chip->card->mixername, "Broadcom Mixer");
-       for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) {
-               err = snd_ctl_add(chip->card,
-                                 snd_ctl_new1(&snd_bcm2835_ctl[idx], chip));
-               if (err < 0)
-                       return err;
-       }
-       for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) {
-               err = snd_ctl_add(chip->card,
-                                 snd_ctl_new1(&snd_bcm2835_spdif[idx], chip));
+       for (i = 0; i < size; i++) {
+               err = snd_ctl_add(chip->card, snd_ctl_new1(&kctls[i], chip));
                if (err < 0)
                        return err;
        }
        return 0;
 }
 
-static struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = {
+int snd_bcm2835_new_ctl(struct bcm2835_chip *chip)
+{
+       int err;
+
+       strcpy(chip->card->mixername, "Broadcom Mixer");
+       err = create_ctls(chip, ARRAY_SIZE(snd_bcm2835_ctl), snd_bcm2835_ctl);
+       if (err < 0)
+               return err;
+       return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_spdif),
+                          snd_bcm2835_spdif);
+}
+
+static const struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Headphone Playback Volume",
@@ -357,21 +261,12 @@ static struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = {
 
 int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip)
 {
-       int err;
-       unsigned int idx;
-
        strcpy(chip->card->mixername, "Broadcom Mixer");
-       for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_headphones_ctl); idx++) {
-               err = snd_ctl_add(chip->card,
-                                 snd_ctl_new1(&snd_bcm2835_headphones_ctl[idx],
-                                              chip));
-               if (err)
-                       return err;
-       }
-       return 0;
+       return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_headphones_ctl),
+                          snd_bcm2835_headphones_ctl);
 }
 
-static struct snd_kcontrol_new snd_bcm2835_hdmi[] = {
+static const struct snd_kcontrol_new snd_bcm2835_hdmi[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "HDMI Playback Volume",
@@ -400,16 +295,8 @@ static struct snd_kcontrol_new snd_bcm2835_hdmi[] = {
 
 int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip)
 {
-       int err;
-       unsigned int idx;
-
        strcpy(chip->card->mixername, "Broadcom Mixer");
-       for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_hdmi); idx++) {
-               err = snd_ctl_add(chip->card,
-                                 snd_ctl_new1(&snd_bcm2835_hdmi[idx], chip));
-               if (err)
-                       return err;
-       }
-       return 0;
+       return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_hdmi),
+                          snd_bcm2835_hdmi);
 }
 
index 8359cf881bef5360ce58a23860895cea81e4fb58..e66da11af5cf528cc1277ae0a9d809aca2283f9b 100644 (file)
@@ -11,7 +11,8 @@
 /* hardware definition */
 static const struct snd_pcm_hardware snd_bcm2835_playback_hw = {
        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
-       SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+                SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+                SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR),
        .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
        .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
        .rate_min = 8000,
@@ -27,7 +28,8 @@ static const struct snd_pcm_hardware snd_bcm2835_playback_hw = {
 
 static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
-       SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+                SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
+                SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR),
        .formats = SNDRV_PCM_FMTBIT_S16_LE,
        .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
        SNDRV_PCM_RATE_48000,
@@ -44,48 +46,37 @@ static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
 
 static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
 {
-       audio_info("Freeing up alsa stream here ..\n");
        kfree(runtime->private_data);
-       runtime->private_data = NULL;
 }
 
-void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream)
+void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream,
+                          unsigned int bytes)
 {
-       unsigned int consumed = 0;
-       int new_period = 0;
-
-       audio_info("alsa_stream=%p substream=%p\n", alsa_stream,
-               alsa_stream ? alsa_stream->substream : 0);
-
-       if (alsa_stream->open)
-               consumed = bcm2835_audio_retrieve_buffers(alsa_stream);
-
-       /* We get called only if playback was triggered, So, the number of buffers we retrieve in
-        * each iteration are the buffers that have been played out already
-        */
-
-       if (alsa_stream->period_size) {
-               if ((alsa_stream->pos / alsa_stream->period_size) !=
-                       ((alsa_stream->pos + consumed) / alsa_stream->period_size))
-                       new_period = 1;
-       }
-       audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n",
-               alsa_stream->pos,
-               consumed,
-               alsa_stream->buffer_size,
-               (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods),
-               frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr),
-               new_period);
-       if (alsa_stream->buffer_size) {
-               alsa_stream->pos += consumed & ~(1 << 30);
-               alsa_stream->pos %= alsa_stream->buffer_size;
+       struct snd_pcm_substream *substream = alsa_stream->substream;
+       unsigned int pos;
+
+       if (!alsa_stream->period_size)
+               return;
+
+       if (bytes >= alsa_stream->buffer_size) {
+               snd_pcm_stream_lock(substream);
+               snd_pcm_stop(substream,
+                            alsa_stream->draining ?
+                            SNDRV_PCM_STATE_SETUP :
+                            SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock(substream);
+               return;
        }
 
-       if (alsa_stream->substream) {
-               if (new_period)
-                       snd_pcm_period_elapsed(alsa_stream->substream);
-       } else {
-               audio_warning(" unexpected NULL substream\n");
+       pos = atomic_read(&alsa_stream->pos);
+       pos += bytes;
+       pos %= alsa_stream->buffer_size;
+       atomic_set(&alsa_stream->pos, pos);
+
+       alsa_stream->period_offset += bytes;
+       if (alsa_stream->period_offset >= alsa_stream->period_size) {
+               alsa_stream->period_offset %= alsa_stream->period_size;
+               snd_pcm_period_elapsed(substream);
        }
 }
 
@@ -99,11 +90,7 @@ static int snd_bcm2835_playback_open_generic(
        int idx;
        int err;
 
-       if (mutex_lock_interruptible(&chip->audio_mutex)) {
-               audio_error("Interrupted whilst waiting for lock\n");
-               return -EINTR;
-       }
-       audio_info("Alsa open (%d)\n", substream->number);
+       mutex_lock(&chip->audio_mutex);
        idx = substream->number;
 
        if (spdif && chip->opened) {
@@ -114,21 +101,13 @@ static int snd_bcm2835_playback_open_generic(
                goto out;
        }
        if (idx >= MAX_SUBSTREAMS) {
-               audio_error
-                       ("substream(%d) device doesn't exist max(%d) substreams allowed\n",
+               dev_err(chip->dev,
+                       "substream(%d) device doesn't exist max(%d) substreams allowed\n",
                        idx, MAX_SUBSTREAMS);
                err = -ENODEV;
                goto out;
        }
 
-       /* Check if we are ready */
-       if (!(chip->avail_substreams & (1 << idx))) {
-               /* We are not ready yet */
-               audio_error("substream(%d) device is not ready yet\n", idx);
-               err = -EAGAIN;
-               goto out;
-       }
-
        alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL);
        if (!alsa_stream) {
                err = -ENOMEM;
@@ -140,8 +119,6 @@ static int snd_bcm2835_playback_open_generic(
        alsa_stream->substream = substream;
        alsa_stream->idx = idx;
 
-       spin_lock_init(&alsa_stream->lock);
-
        err = bcm2835_audio_open(alsa_stream);
        if (err) {
                kfree(alsa_stream);
@@ -162,11 +139,14 @@ static int snd_bcm2835_playback_open_generic(
                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
                                   16);
 
+       /* position update is in 10ms order */
+       snd_pcm_hw_constraint_minmax(runtime,
+                                    SNDRV_PCM_HW_PARAM_PERIOD_TIME,
+                                    10 * 1000, UINT_MAX);
+
        chip->alsa_stream[idx] = alsa_stream;
 
        chip->opened |= (1 << idx);
-       alsa_stream->open = 1;
-       alsa_stream->draining = 1;
 
 out:
        mutex_unlock(&chip->audio_mutex);
@@ -194,37 +174,15 @@ static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
        struct bcm2835_alsa_stream *alsa_stream;
 
        chip = snd_pcm_substream_chip(substream);
-       if (mutex_lock_interruptible(&chip->audio_mutex)) {
-               audio_error("Interrupted whilst waiting for lock\n");
-               return -EINTR;
-       }
+       mutex_lock(&chip->audio_mutex);
        runtime = substream->runtime;
        alsa_stream = runtime->private_data;
 
-       audio_info("Alsa close\n");
-
-       /*
-        * Call stop if it's still running. This happens when app
-        * is force killed and we don't get a stop trigger.
-        */
-       if (alsa_stream->running) {
-               int err;
-
-               err = bcm2835_audio_stop(alsa_stream);
-               alsa_stream->running = 0;
-               if (err)
-                       audio_error(" Failed to STOP alsa device\n");
-       }
-
        alsa_stream->period_size = 0;
        alsa_stream->buffer_size = 0;
 
-       if (alsa_stream->open) {
-               alsa_stream->open = 0;
-               bcm2835_audio_close(alsa_stream);
-       }
-       if (alsa_stream->chip)
-               alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL;
+       bcm2835_audio_close(alsa_stream);
+       alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL;
        /*
         * Do not free up alsa_stream here, it will be freed up by
         * runtime->private_free callback we registered in *_open above
@@ -241,22 +199,7 @@ static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
 static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params)
 {
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
-       int err;
-
-       err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
-       if (err < 0) {
-               audio_error
-                       (" pcm_lib_malloc failed to allocated pages for buffers\n");
-               return err;
-       }
-
-       alsa_stream->channels = params_channels(params);
-       alsa_stream->params_rate = params_rate(params);
-       alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params));
-
-       return err;
+       return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
 }
 
 /* hw_free callback */
@@ -274,9 +217,6 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
        int channels;
        int err;
 
-       if (mutex_lock_interruptible(&chip->audio_mutex))
-               return -EINTR;
-
        /* notify the vchiq that it should enter spdif passthrough mode by
         * setting channels=0 (see
         * https://github.com/raspberrypi/linux/issues/528)
@@ -284,18 +224,13 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
        if (chip->spdif_status & IEC958_AES0_NONAUDIO)
                channels = 0;
        else
-               channels = alsa_stream->channels;
+               channels = runtime->channels;
 
        err = bcm2835_audio_set_params(alsa_stream, channels,
-               alsa_stream->params_rate,
-               alsa_stream->pcm_format_width);
+                                      runtime->rate,
+                                      snd_pcm_format_width(runtime->format));
        if (err < 0)
-               audio_error(" error setting hw params\n");
-
-       bcm2835_audio_setup(alsa_stream);
-
-       /* in preparation of the stream, set the controls (volume level) of the stream */
-       bcm2835_audio_set_ctls(alsa_stream->chip);
+               return err;
 
        memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
 
@@ -305,13 +240,10 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
 
        alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream);
        alsa_stream->period_size = snd_pcm_lib_period_bytes(substream);
-       alsa_stream->pos = 0;
-
-       audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n",
-               alsa_stream->buffer_size, alsa_stream->period_size,
-               alsa_stream->pos, runtime->frame_bits);
+       atomic_set(&alsa_stream->pos, 0);
+       alsa_stream->period_offset = 0;
+       alsa_stream->draining = false;
 
-       mutex_unlock(&chip->audio_mutex);
        return 0;
 }
 
@@ -321,12 +253,8 @@ static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
        void *src = (void *) (substream->runtime->dma_area + rec->sw_data);
-       int err;
-
-       err = bcm2835_audio_write(alsa_stream, bytes, src);
-       if (err)
-               audio_error(" Failed to transfer to alsa device (%d)\n", err);
 
+       bcm2835_audio_write(alsa_stream, bytes, src);
 }
 
 static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
@@ -335,7 +263,6 @@ static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
        struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect;
 
-       pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max;
        return snd_pcm_indirect_playback_transfer(substream, pcm_indirect,
                                                  snd_bcm2835_pcm_transfer);
 }
@@ -345,50 +272,18 @@ static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
-       int err = 0;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
-               audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n",
-                       alsa_stream->running);
-               if (!alsa_stream->running) {
-                       err = bcm2835_audio_start(alsa_stream);
-                       if (!err) {
-                               alsa_stream->pcm_indirect.hw_io =
-                                       alsa_stream->pcm_indirect.hw_data =
-                                       bytes_to_frames(runtime,
-                                       alsa_stream->pos);
-                               substream->ops->ack(substream);
-                               alsa_stream->running = 1;
-                               alsa_stream->draining = 1;
-                       } else {
-                               audio_error(" Failed to START alsa device (%d)\n", err);
-                       }
-               }
-               break;
+               return bcm2835_audio_start(alsa_stream);
+       case SNDRV_PCM_TRIGGER_DRAIN:
+               alsa_stream->draining = true;
+               return bcm2835_audio_drain(alsa_stream);
        case SNDRV_PCM_TRIGGER_STOP:
-               audio_debug
-                       ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n",
-                       alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING);
-               if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
-                       audio_info("DRAINING\n");
-                       alsa_stream->draining = 1;
-               } else {
-                       audio_info("DROPPING\n");
-                       alsa_stream->draining = 0;
-               }
-               if (alsa_stream->running) {
-                       err = bcm2835_audio_stop(alsa_stream);
-                       if (err != 0)
-                               audio_error(" Failed to STOP alsa device (%d)\n", err);
-                       alsa_stream->running = 0;
-               }
-               break;
+               return bcm2835_audio_stop(alsa_stream);
        default:
-               err = -EINVAL;
+               return -EINVAL;
        }
-
-       return err;
 }
 
 /* pointer callback */
@@ -398,31 +293,16 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 
-       audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0,
-               frames_to_bytes(runtime, runtime->status->hw_ptr),
-               frames_to_bytes(runtime, runtime->control->appl_ptr),
-               alsa_stream->pos);
-
        return snd_pcm_indirect_playback_pointer(substream,
                &alsa_stream->pcm_indirect,
-               alsa_stream->pos);
-}
-
-static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
-       unsigned int cmd, void *arg)
-{
-       int ret = snd_pcm_lib_ioctl(substream, cmd, arg);
-
-       audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream,
-               cmd, arg, arg ? *(unsigned int *)arg : 0, ret);
-       return ret;
+               atomic_read(&alsa_stream->pos));
 }
 
 /* operators */
 static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
        .open = snd_bcm2835_playback_open,
        .close = snd_bcm2835_playback_close,
-       .ioctl = snd_bcm2835_pcm_lib_ioctl,
+       .ioctl = snd_pcm_lib_ioctl,
        .hw_params = snd_bcm2835_pcm_hw_params,
        .hw_free = snd_bcm2835_pcm_hw_free,
        .prepare = snd_bcm2835_pcm_prepare,
@@ -434,7 +314,7 @@ static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
 static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
        .open = snd_bcm2835_playback_spdif_open,
        .close = snd_bcm2835_playback_close,
-       .ioctl = snd_bcm2835_pcm_lib_ioctl,
+       .ioctl = snd_pcm_lib_ioctl,
        .hw_params = snd_bcm2835_pcm_hw_params,
        .hw_free = snd_bcm2835_pcm_hw_free,
        .prepare = snd_bcm2835_pcm_prepare,
@@ -444,104 +324,36 @@ static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
 };
 
 /* create a pcm device */
-int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels)
-{
-       struct snd_pcm *pcm;
-       int err;
-
-       mutex_init(&chip->audio_mutex);
-       if (mutex_lock_interruptible(&chip->audio_mutex)) {
-               audio_error("Interrupted whilst waiting for lock\n");
-               return -EINTR;
-       }
-       err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm);
-       if (err < 0)
-               goto out;
-       pcm->private_data = chip;
-       strcpy(pcm->name, "bcm2835 ALSA");
-       chip->pcm = pcm;
-       chip->dest = AUDIO_DEST_AUTO;
-       chip->volume = alsa2chip(0);
-       chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */
-       /* set operators */
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-                       &snd_bcm2835_playback_ops);
-
-       /* pre-allocation of buffers */
-       /* NOTE: this may fail */
-       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
-                                             snd_dma_continuous_data(GFP_KERNEL),
-                                             snd_bcm2835_playback_hw.buffer_bytes_max,
-                                             snd_bcm2835_playback_hw.buffer_bytes_max);
-
-out:
-       mutex_unlock(&chip->audio_mutex);
-
-       return 0;
-}
-
-int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip)
+int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
+                       int idx, enum snd_bcm2835_route route,
+                       u32 numchannels, bool spdif)
 {
        struct snd_pcm *pcm;
        int err;
 
-       if (mutex_lock_interruptible(&chip->audio_mutex)) {
-               audio_error("Interrupted whilst waiting for lock\n");
-               return -EINTR;
-       }
-       err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm);
-       if (err < 0)
-               goto out;
-
-       pcm->private_data = chip;
-       strcpy(pcm->name, "bcm2835 IEC958/HDMI");
-       chip->pcm_spdif = pcm;
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-                       &snd_bcm2835_playback_spdif_ops);
-
-       /* pre-allocation of buffers */
-       /* NOTE: this may fail */
-       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
-               snd_dma_continuous_data(GFP_KERNEL),
-               snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max);
-out:
-       mutex_unlock(&chip->audio_mutex);
-
-       return 0;
-}
-
-int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip,
-                              const char *name,
-                              enum snd_bcm2835_route route,
-                              u32 numchannels)
-{
-       struct snd_pcm *pcm;
-       int err;
-
-       mutex_init(&chip->audio_mutex);
-
-       err = snd_pcm_new(chip->card, name, 0, numchannels,
-                         0, &pcm);
+       err = snd_pcm_new(chip->card, name, idx, numchannels, 0, &pcm);
        if (err)
                return err;
 
        pcm->private_data = chip;
+       pcm->nonatomic = true;
        strcpy(pcm->name, name);
-       chip->pcm = pcm;
-       chip->dest = route;
-       chip->volume = alsa2chip(0);
-       chip->mute = CTRL_VOL_UNMUTE;
+       if (!spdif) {
+               chip->dest = route;
+               chip->volume = 0;
+               chip->mute = CTRL_VOL_UNMUTE;
+       }
 
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                       spdif ? &snd_bcm2835_playback_spdif_ops :
                        &snd_bcm2835_playback_ops);
 
-       snd_pcm_lib_preallocate_pages_for_all(
-               pcm,
-               SNDRV_DMA_TYPE_CONTINUOUS,
-               snd_dma_continuous_data(GFP_KERNEL),
-               snd_bcm2835_playback_hw.buffer_bytes_max,
-               snd_bcm2835_playback_hw.buffer_bytes_max);
+       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+               chip->card->dev, 128 * 1024, 128 * 1024);
 
+       if (spdif)
+               chip->pcm_spdif = pcm;
+       else
+               chip->pcm = pcm;
        return 0;
 }
-
index 868e2d6aaf1bc06a03f61c9b4fac846800c97bf5..781754f36da732d8cc0f98f7c4340c8a909e3933 100644 (file)
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright 2011 Broadcom Corporation.  All rights reserved. */
 
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
-#include <linux/syscalls.h>
-#include <linux/uaccess.h>
 #include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/atomic.h>
 #include <linux/module.h>
 #include <linux/completion.h>
-
 #include "bcm2835.h"
-
-/* ---- Include Files -------------------------------------------------------- */
-
 #include "vc_vchi_audioserv_defs.h"
 
-/* ---- Private Constants and Types ------------------------------------------ */
-
-#define BCM2835_AUDIO_STOP           0
-#define BCM2835_AUDIO_START          1
-#define BCM2835_AUDIO_WRITE          2
-
-/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */
-#ifdef AUDIO_DEBUG_ENABLE
-#define LOG_ERR(fmt, arg...)   pr_err("%s:%d " fmt, __func__, __LINE__, ##arg)
-#define LOG_WARN(fmt, arg...)  pr_info("%s:%d " fmt, __func__, __LINE__, ##arg)
-#define LOG_INFO(fmt, arg...)  pr_info("%s:%d " fmt, __func__, __LINE__, ##arg)
-#define LOG_DBG(fmt, arg...)   pr_info("%s:%d " fmt, __func__, __LINE__, ##arg)
-#else
-#define LOG_ERR(fmt, arg...)   pr_err("%s:%d " fmt, __func__, __LINE__, ##arg)
-#define LOG_WARN(fmt, arg...)   no_printk(fmt, ##arg)
-#define LOG_INFO(fmt, arg...)   no_printk(fmt, ##arg)
-#define LOG_DBG(fmt, arg...)    no_printk(fmt, ##arg)
-#endif
-
 struct bcm2835_audio_instance {
-       unsigned int num_connections;
-       VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS];
+       struct device *dev;
+       VCHI_SERVICE_HANDLE_T vchi_handle;
        struct completion msg_avail_comp;
        struct mutex vchi_mutex;
        struct bcm2835_alsa_stream *alsa_stream;
        int result;
+       unsigned int max_packet;
        short peer_version;
 };
 
 static bool force_bulk;
+module_param(force_bulk, bool, 0444);
+MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio");
 
-/* ---- Private Variables ---------------------------------------------------- */
-
-/* ---- Private Function Prototypes ------------------------------------------ */
-
-/* ---- Private Functions ---------------------------------------------------- */
-
-static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream);
-static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream);
-static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream,
-                                     unsigned int count, void *src);
-
-// Routine to send a message across a service
-
-static int
-bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
-                      void *data,
-                      unsigned int size)
+static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance)
 {
-       return vchi_queue_kernel_message(handle,
-                                        data,
-                                        size);
+       mutex_lock(&instance->vchi_mutex);
+       vchi_service_use(instance->vchi_handle);
 }
 
-static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 |
-                                               'M' << 8  | 'A');
-static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 |
-                                               'T' << 8  | 'A');
-
-struct bcm2835_audio_work {
-       struct work_struct my_work;
-       struct bcm2835_alsa_stream *alsa_stream;
-       int cmd;
-       void *src;
-       unsigned int count;
-};
-
-static void my_wq_function(struct work_struct *work)
+static void bcm2835_audio_unlock(struct bcm2835_audio_instance *instance)
 {
-       struct bcm2835_audio_work *w =
-               container_of(work, struct bcm2835_audio_work, my_work);
-       int ret = -9;
-
-       switch (w->cmd) {
-       case BCM2835_AUDIO_START:
-               ret = bcm2835_audio_start_worker(w->alsa_stream);
-               break;
-       case BCM2835_AUDIO_STOP:
-               ret = bcm2835_audio_stop_worker(w->alsa_stream);
-               break;
-       case BCM2835_AUDIO_WRITE:
-               ret = bcm2835_audio_write_worker(w->alsa_stream, w->count,
-                                                w->src);
-               break;
-       default:
-               LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd);
-               break;
-       }
-       kfree((void *)work);
+       vchi_service_release(instance->vchi_handle);
+       mutex_unlock(&instance->vchi_mutex);
 }
 
-int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream)
+static int bcm2835_audio_send_msg_locked(struct bcm2835_audio_instance *instance,
+                                        struct vc_audio_msg *m, bool wait)
 {
-       struct bcm2835_audio_work *work;
+       int status;
 
-       work = kmalloc(sizeof(*work), GFP_ATOMIC);
-       /*--- Queue some work (item 1) ---*/
-       if (!work) {
-               LOG_ERR(" .. Error: NULL work kmalloc\n");
-               return -ENOMEM;
+       if (wait) {
+               instance->result = -1;
+               init_completion(&instance->msg_avail_comp);
        }
-       INIT_WORK(&work->my_work, my_wq_function);
-       work->alsa_stream = alsa_stream;
-       work->cmd = BCM2835_AUDIO_START;
-       if (!queue_work(alsa_stream->my_wq, &work->my_work)) {
-               kfree(work);
-               return -EBUSY;
-       }
-       return 0;
-}
-
-int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream)
-{
-       struct bcm2835_audio_work *work;
 
-       work = kmalloc(sizeof(*work), GFP_ATOMIC);
-       /*--- Queue some work (item 1) ---*/
-       if (!work) {
-               LOG_ERR(" .. Error: NULL work kmalloc\n");
-               return -ENOMEM;
+       status = vchi_queue_kernel_message(instance->vchi_handle,
+                                          m, sizeof(*m));
+       if (status) {
+               dev_err(instance->dev,
+                       "vchi message queue failed: %d, msg=%d\n",
+                       status, m->type);
+               return -EIO;
        }
-       INIT_WORK(&work->my_work, my_wq_function);
-       work->alsa_stream = alsa_stream;
-       work->cmd = BCM2835_AUDIO_STOP;
-       if (!queue_work(alsa_stream->my_wq, &work->my_work)) {
-               kfree(work);
-               return -EBUSY;
+
+       if (wait) {
+               if (!wait_for_completion_timeout(&instance->msg_avail_comp,
+                                                msecs_to_jiffies(10 * 1000))) {
+                       dev_err(instance->dev,
+                               "vchi message timeout, msg=%d\n", m->type);
+                       return -ETIMEDOUT;
+               } else if (instance->result) {
+                       dev_err(instance->dev,
+                               "vchi message response error:%d, msg=%d\n",
+                               instance->result, m->type);
+                       return -EIO;
+               }
        }
+
        return 0;
 }
 
-int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
-                       unsigned int count, void *src)
+static int bcm2835_audio_send_msg(struct bcm2835_audio_instance *instance,
+                                 struct vc_audio_msg *m, bool wait)
 {
-       struct bcm2835_audio_work *work;
+       int err;
 
-       work = kmalloc(sizeof(*work), GFP_ATOMIC);
-       /*--- Queue some work (item 1) ---*/
-       if (!work) {
-               LOG_ERR(" .. Error: NULL work kmalloc\n");
-               return -ENOMEM;
-       }
-       INIT_WORK(&work->my_work, my_wq_function);
-       work->alsa_stream = alsa_stream;
-       work->cmd = BCM2835_AUDIO_WRITE;
-       work->src = src;
-       work->count = count;
-       if (!queue_work(alsa_stream->my_wq, &work->my_work)) {
-               kfree(work);
-               return -EBUSY;
-       }
-       return 0;
+       bcm2835_audio_lock(instance);
+       err = bcm2835_audio_send_msg_locked(instance, m, wait);
+       bcm2835_audio_unlock(instance);
+       return err;
 }
 
-static void my_workqueue_quit(struct bcm2835_alsa_stream *alsa_stream)
+static int bcm2835_audio_send_simple(struct bcm2835_audio_instance *instance,
+                                    int type, bool wait)
 {
-       flush_workqueue(alsa_stream->my_wq);
-       destroy_workqueue(alsa_stream->my_wq);
-       alsa_stream->my_wq = NULL;
+       struct vc_audio_msg m = { .type = type };
+
+       return bcm2835_audio_send_msg(instance, &m, wait);
 }
 
+static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 |
+                                               'M' << 8  | 'A');
+static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 |
+                                               'T' << 8  | 'A');
+
 static void audio_vchi_callback(void *param,
                                const VCHI_CALLBACK_REASON_T reason,
                                void *msg_handle)
@@ -197,172 +106,87 @@ static void audio_vchi_callback(void *param,
        if (reason != VCHI_CALLBACK_MSG_AVAILABLE)
                return;
 
-       if (!instance) {
-               LOG_ERR(" .. instance is null\n");
-               BUG();
-               return;
-       }
-       if (!instance->vchi_handle[0]) {
-               LOG_ERR(" .. instance->vchi_handle[0] is null\n");
-               BUG();
-               return;
-       }
-       status = vchi_msg_dequeue(instance->vchi_handle[0],
+       status = vchi_msg_dequeue(instance->vchi_handle,
                                  &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE);
        if (m.type == VC_AUDIO_MSG_TYPE_RESULT) {
-               LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n",
-                       instance, m.u.result.success);
                instance->result = m.u.result.success;
                complete(&instance->msg_avail_comp);
        } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
-               struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream;
-
-               LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n",
-                       instance, m.u.complete.count);
                if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 ||
                    m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2)
-                       LOG_ERR(" .. response is corrupt\n");
-               else if (alsa_stream) {
-                       atomic_add(m.u.complete.count,
-                                  &alsa_stream->retrieved);
-                       bcm2835_playback_fifo(alsa_stream);
-               } else {
-                       LOG_ERR(" .. unexpected alsa_stream=%p\n",
-                               alsa_stream);
-               }
+                       dev_err(instance->dev, "invalid cookie\n");
+               else
+                       bcm2835_playback_fifo(instance->alsa_stream,
+                                             m.u.complete.count);
        } else {
-               LOG_ERR(" .. unexpected m.type=%d\n", m.type);
+               dev_err(instance->dev, "unexpected callback type=%d\n", m.type);
        }
 }
 
-static struct bcm2835_audio_instance *
+static int
 vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance,
-                  VCHI_CONNECTION_T **vchi_connections,
-                  unsigned int num_connections)
+                  struct bcm2835_audio_instance *instance)
 {
-       unsigned int i;
-       struct bcm2835_audio_instance *instance;
+       SERVICE_CREATION_T params = {
+               .version                = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER),
+               .service_id             = VC_AUDIO_SERVER_NAME,
+               .callback               = audio_vchi_callback,
+               .callback_param         = instance,
+       };
        int status;
-       int ret;
-
-       LOG_DBG("%s: start", __func__);
 
-       if (num_connections > VCHI_MAX_NUM_CONNECTIONS) {
-               LOG_ERR("%s: unsupported number of connections %u (max=%u)\n",
-                       __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS);
-
-               return ERR_PTR(-EINVAL);
-       }
-       /* Allocate memory for this instance */
-       instance = kzalloc(sizeof(*instance), GFP_KERNEL);
-       if (!instance)
-               return ERR_PTR(-ENOMEM);
-
-       instance->num_connections = num_connections;
-
-       /* Create a lock for exclusive, serialized VCHI connection access */
-       mutex_init(&instance->vchi_mutex);
        /* Open the VCHI service connections */
-       for (i = 0; i < num_connections; i++) {
-               SERVICE_CREATION_T params = {
-                       .version                = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER),
-                       .service_id             = VC_AUDIO_SERVER_NAME,
-                       .connection             = vchi_connections[i],
-                       .rx_fifo_size           = 0,
-                       .tx_fifo_size           = 0,
-                       .callback               = audio_vchi_callback,
-                       .callback_param         = instance,
-                       .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE
-                       .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE
-                       .want_crc               = 0
-               };
-
-               LOG_DBG("%s: about to open %i\n", __func__, i);
-               status = vchi_service_open(vchi_instance, &params,
-                                          &instance->vchi_handle[i]);
-
-               LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status);
-               if (status) {
-                       LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n",
-                               __func__, status);
-                       ret = -EPERM;
-                       goto err_close_services;
-               }
-               /* Finished with the service for now */
-               vchi_service_release(instance->vchi_handle[i]);
-       }
-
-       LOG_DBG("%s: okay\n", __func__);
-       return instance;
+       status = vchi_service_open(vchi_instance, &params,
+                                  &instance->vchi_handle);
 
-err_close_services:
-       for (i = 0; i < instance->num_connections; i++) {
-               LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]);
-               if (instance->vchi_handle[i])
-                       vchi_service_close(instance->vchi_handle[i]);
+       if (status) {
+               dev_err(instance->dev,
+                       "failed to open VCHI service connection (status=%d)\n",
+                       status);
+               kfree(instance);
+               return -EPERM;
        }
 
-       kfree(instance);
-       LOG_ERR("%s: error\n", __func__);
+       /* Finished with the service for now */
+       vchi_service_release(instance->vchi_handle);
 
-       return ERR_PTR(ret);
+       return 0;
 }
 
-static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance)
+static void vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance)
 {
-       unsigned int i;
-
-       if (!instance) {
-               LOG_ERR("%s: invalid handle %p\n", __func__, instance);
-
-               return -1;
-       }
+       int status;
 
-       LOG_DBG(" .. about to lock (%d)\n", instance->num_connections);
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
-                       instance->num_connections);
-               return -EINTR;
-       }
+       mutex_lock(&instance->vchi_mutex);
+       vchi_service_use(instance->vchi_handle);
 
        /* Close all VCHI service connections */
-       for (i = 0; i < instance->num_connections; i++) {
-               int status;
-
-               LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]);
-               vchi_service_use(instance->vchi_handle[i]);
-
-               status = vchi_service_close(instance->vchi_handle[i]);
-               if (status) {
-                       LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n",
-                               __func__, status);
-               }
+       status = vchi_service_close(instance->vchi_handle);
+       if (status) {
+               dev_err(instance->dev,
+                       "failed to close VCHI service connection (status=%d)\n",
+                       status);
        }
 
        mutex_unlock(&instance->vchi_mutex);
-
-       kfree(instance);
-
-       return 0;
 }
 
-int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx)
+int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx)
 {
        int ret;
 
        /* Initialize and create a VCHI connection */
        ret = vchi_initialise(&vchi_ctx->vchi_instance);
        if (ret) {
-               LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n",
-                       __func__, ret);
-
+               dev_err(dev, "failed to initialise VCHI instance (ret=%d)\n",
+                       ret);
                return -EIO;
        }
 
-       ret = vchi_connect(NULL, 0, vchi_ctx->vchi_instance);
+       ret = vchi_connect(vchi_ctx->vchi_instance);
        if (ret) {
-               LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n",
-                       __func__, ret);
+               dev_dbg(dev, "failed to connect VCHI instance (ret=%d)\n",
+                       ret);
 
                kfree(vchi_ctx->vchi_instance);
                vchi_ctx->vchi_instance = NULL;
@@ -381,473 +205,170 @@ void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx)
        vchi_ctx->vchi_instance = NULL;
 }
 
-static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream)
-{
-       struct bcm2835_audio_instance *instance =
-               (struct bcm2835_audio_instance *)alsa_stream->instance;
-       struct bcm2835_vchi_ctx *vhci_ctx = alsa_stream->chip->vchi_ctx;
-
-       LOG_INFO("%s: start\n", __func__);
-       BUG_ON(instance);
-       if (instance) {
-               LOG_ERR("%s: VCHI instance already open (%p)\n",
-                       __func__, instance);
-               instance->alsa_stream = alsa_stream;
-               alsa_stream->instance = instance;
-               return 0;
-       }
-
-       /* Initialize an instance of the audio service */
-       instance = vc_vchi_audio_init(vhci_ctx->vchi_instance,
-                                     &vhci_ctx->vchi_connection, 1);
-
-       if (IS_ERR(instance)) {
-               LOG_ERR("%s: failed to initialize audio service\n", __func__);
-
-               /* vchi_instance is retained for use the next time. */
-               return PTR_ERR(instance);
-       }
-
-       instance->alsa_stream = alsa_stream;
-       alsa_stream->instance = instance;
-
-       LOG_DBG(" success !\n");
-
-       return 0;
-}
-
 int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
 {
+       struct bcm2835_vchi_ctx *vchi_ctx = alsa_stream->chip->vchi_ctx;
        struct bcm2835_audio_instance *instance;
-       struct vc_audio_msg m;
-       int status;
-       int ret;
+       int err;
 
-       alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1);
-       if (!alsa_stream->my_wq)
+       /* Allocate memory for this instance */
+       instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+       if (!instance)
                return -ENOMEM;
+       mutex_init(&instance->vchi_mutex);
+       instance->dev = alsa_stream->chip->dev;
+       instance->alsa_stream = alsa_stream;
+       alsa_stream->instance = instance;
 
-       ret = bcm2835_audio_open_connection(alsa_stream);
-       if (ret)
-               goto free_wq;
-
-       instance = alsa_stream->instance;
-       LOG_DBG(" instance (%p)\n", instance);
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections);
-               ret = -EINTR;
-               goto free_wq;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       m.type = VC_AUDIO_MSG_TYPE_OPEN;
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
-
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
-
-               ret = -1;
-               goto unlock;
-       }
+       err = vc_vchi_audio_init(vchi_ctx->vchi_instance,
+                                instance);
+       if (err < 0)
+               goto free_instance;
 
-       ret = 0;
+       err = bcm2835_audio_send_simple(instance, VC_AUDIO_MSG_TYPE_OPEN,
+                                       false);
+       if (err < 0)
+               goto deinit;
 
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
+       bcm2835_audio_lock(instance);
+       vchi_get_peer_version(instance->vchi_handle, &instance->peer_version);
+       bcm2835_audio_unlock(instance);
+       if (instance->peer_version < 2 || force_bulk)
+               instance->max_packet = 0; /* bulk transfer */
+       else
+               instance->max_packet = 4000;
 
-free_wq:
-       if (ret)
-               destroy_workqueue(alsa_stream->my_wq);
+       return 0;
 
-       return ret;
+ deinit:
+       vc_vchi_audio_deinit(instance);
+ free_instance:
+       alsa_stream->instance = NULL;
+       kfree(instance);
+       return err;
 }
 
-static int bcm2835_audio_set_ctls_chan(struct bcm2835_alsa_stream *alsa_stream,
-                                      struct bcm2835_chip *chip)
+int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream)
 {
-       struct vc_audio_msg m;
-       struct bcm2835_audio_instance *instance = alsa_stream->instance;
-       int status;
-       int ret;
-
-       LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n",
-                chip->dest, chip->volume);
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
-                       instance->num_connections);
-               return -EINTR;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       instance->result = -1;
+       struct bcm2835_chip *chip = alsa_stream->chip;
+       struct vc_audio_msg m = {};
 
        m.type = VC_AUDIO_MSG_TYPE_CONTROL;
        m.u.control.dest = chip->dest;
-       m.u.control.volume = chip->volume;
+       if (!chip->mute)
+               m.u.control.volume = CHIP_MIN_VOLUME;
+       else
+               m.u.control.volume = alsa2chip(chip->volume);
 
-       /* Create the message available completion */
-       init_completion(&instance->msg_avail_comp);
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
-
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
-
-               ret = -1;
-               goto unlock;
-       }
-
-       /* We are expecting a reply from the videocore */
-       wait_for_completion(&instance->msg_avail_comp);
-
-       if (instance->result) {
-               LOG_ERR("%s: result=%d\n", __func__, instance->result);
-
-               ret = -1;
-               goto unlock;
-       }
-
-       ret = 0;
-
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
-
-       return ret;
-}
-
-int bcm2835_audio_set_ctls(struct bcm2835_chip *chip)
-{
-       int i;
-       int ret = 0;
-
-       LOG_DBG(" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume);
-
-       /* change ctls for all substreams */
-       for (i = 0; i < MAX_SUBSTREAMS; i++) {
-               if (chip->avail_substreams & (1 << i)) {
-                       if (!chip->alsa_stream[i]) {
-                               LOG_DBG(" No ALSA stream available?! %i:%p (%x)\n", i, chip->alsa_stream[i], chip->avail_substreams);
-                               ret = 0;
-                       } else if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) {
-                               LOG_ERR("Couldn't set the controls for stream %d\n", i);
-                               ret = -1;
-                       } else {
-                               LOG_DBG(" Controls set for stream %d\n", i);
-                       }
-               }
-       }
-       return ret;
+       return bcm2835_audio_send_msg(alsa_stream->instance, &m, true);
 }
 
 int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream,
                             unsigned int channels, unsigned int samplerate,
                             unsigned int bps)
 {
-       struct vc_audio_msg m;
-       struct bcm2835_audio_instance *instance = alsa_stream->instance;
-       int status;
-       int ret;
-
-       LOG_INFO(" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n",
-                channels, samplerate, bps);
+       struct vc_audio_msg m = {
+                .type = VC_AUDIO_MSG_TYPE_CONFIG,
+                .u.config.channels = channels,
+                .u.config.samplerate = samplerate,
+                .u.config.bps = bps,
+       };
+       int err;
 
        /* resend ctls - alsa_stream may not have been open when first send */
-       ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip);
-       if (ret) {
-               LOG_ERR(" Alsa controls not supported\n");
-               return -EINVAL;
-       }
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections);
-               return -EINTR;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       instance->result = -1;
+       err = bcm2835_audio_set_ctls(alsa_stream);
+       if (err)
+               return err;
 
-       m.type = VC_AUDIO_MSG_TYPE_CONFIG;
-       m.u.config.channels = channels;
-       m.u.config.samplerate = samplerate;
-       m.u.config.bps = bps;
-
-       /* Create the message available completion */
-       init_completion(&instance->msg_avail_comp);
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
-
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
-
-               ret = -1;
-               goto unlock;
-       }
-
-       /* We are expecting a reply from the videocore */
-       wait_for_completion(&instance->msg_avail_comp);
-
-       if (instance->result) {
-               LOG_ERR("%s: result=%d", __func__, instance->result);
-
-               ret = -1;
-               goto unlock;
-       }
-
-       ret = 0;
-
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
-
-       return ret;
+       return bcm2835_audio_send_msg(alsa_stream->instance, &m, true);
 }
 
-int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream)
+int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream)
 {
-
-       return 0;
+       return bcm2835_audio_send_simple(alsa_stream->instance,
+                                        VC_AUDIO_MSG_TYPE_START, false);
 }
 
-static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream)
+int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream)
 {
-       struct vc_audio_msg m;
-       struct bcm2835_audio_instance *instance = alsa_stream->instance;
-       int status;
-       int ret;
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
-                       instance->num_connections);
-               return -EINTR;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       m.type = VC_AUDIO_MSG_TYPE_START;
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
-
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
-
-               ret = -1;
-               goto unlock;
-       }
-
-       ret = 0;
-
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
-       return ret;
+       return bcm2835_audio_send_simple(alsa_stream->instance,
+                                        VC_AUDIO_MSG_TYPE_STOP, false);
 }
 
-static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream)
+int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream)
 {
-       struct vc_audio_msg m;
-       struct bcm2835_audio_instance *instance = alsa_stream->instance;
-       int status;
-       int ret;
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
-                       instance->num_connections);
-               return -EINTR;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       m.type = VC_AUDIO_MSG_TYPE_STOP;
-       m.u.stop.draining = alsa_stream->draining;
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
-
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
+       struct vc_audio_msg m = {
+               .type = VC_AUDIO_MSG_TYPE_STOP,
+               .u.stop.draining = 1,
+       };
 
-               ret = -1;
-               goto unlock;
-       }
-
-       ret = 0;
-
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
-       return ret;
+       return bcm2835_audio_send_msg(alsa_stream->instance, &m, false);
 }
 
 int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream)
 {
-       struct vc_audio_msg m;
        struct bcm2835_audio_instance *instance = alsa_stream->instance;
-       int status;
-       int ret;
+       int err;
 
-       my_workqueue_quit(alsa_stream);
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
-                       instance->num_connections);
-               return -EINTR;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       m.type = VC_AUDIO_MSG_TYPE_CLOSE;
-
-       /* Create the message available completion */
-       init_completion(&instance->msg_avail_comp);
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
-
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
-               ret = -1;
-               goto unlock;
-       }
-
-       /* We are expecting a reply from the videocore */
-       wait_for_completion(&instance->msg_avail_comp);
-
-       if (instance->result) {
-               LOG_ERR("%s: failed result (result=%d)\n",
-                       __func__, instance->result);
-
-               ret = -1;
-               goto unlock;
-       }
-
-       ret = 0;
-
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
+       err = bcm2835_audio_send_simple(alsa_stream->instance,
+                                       VC_AUDIO_MSG_TYPE_CLOSE, true);
 
        /* Stop the audio service */
        vc_vchi_audio_deinit(instance);
        alsa_stream->instance = NULL;
+       kfree(instance);
 
-       return ret;
+       return err;
 }
 
-static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream,
-                                     unsigned int count, void *src)
+int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
+                       unsigned int size, void *src)
 {
-       struct vc_audio_msg m;
        struct bcm2835_audio_instance *instance = alsa_stream->instance;
-       int status;
-       int ret;
-
-       LOG_INFO(" Writing %d bytes from %p\n", count, src);
-
-       if (mutex_lock_interruptible(&instance->vchi_mutex)) {
-               LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
-                       instance->num_connections);
-               return -EINTR;
-       }
-       vchi_service_use(instance->vchi_handle[0]);
-
-       if (instance->peer_version == 0 &&
-           vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0)
-               LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version);
-
-       m.type = VC_AUDIO_MSG_TYPE_WRITE;
-       m.u.write.count = count;
-       // old version uses bulk, new version uses control
-       m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000;
-       m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1;
-       m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2;
-       m.u.write.silence = src == NULL;
-
-       /* Send the message to the videocore */
-       status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                       &m, sizeof(m));
+       struct vc_audio_msg m = {
+               .type = VC_AUDIO_MSG_TYPE_WRITE,
+               .u.write.count = size,
+               .u.write.max_packet = instance->max_packet,
+               .u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1,
+               .u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2,
+       };
+       unsigned int count;
+       int err, status;
 
-       if (status) {
-               LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
-                       __func__, status);
+       if (!size)
+               return 0;
 
-               ret = -1;
+       bcm2835_audio_lock(instance);
+       err = bcm2835_audio_send_msg_locked(instance, &m, false);
+       if (err < 0)
                goto unlock;
-       }
-       if (!m.u.write.silence) {
-               if (!m.u.write.max_packet) {
-                       /* Send the message to the videocore */
-                       status = vchi_bulk_queue_transmit(instance->vchi_handle[0],
-                                                         src, count,
-                                                         0 * VCHI_FLAGS_BLOCK_UNTIL_QUEUED
-                                                         +
-                                                         1 * VCHI_FLAGS_BLOCK_UNTIL_DATA_READ,
-                                                         NULL);
-               } else {
-                       while (count > 0) {
-                               int bytes = min_t(int, m.u.write.max_packet, count);
-
-                               status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
-                                                               src, bytes);
-                               src = (char *)src + bytes;
-                               count -= bytes;
-                       }
-               }
-               if (status) {
-                       LOG_ERR("%s: failed on vchi_bulk_queue_transmit (status=%d)\n",
-                               __func__, status);
 
-                       ret = -1;
-                       goto unlock;
+       count = size;
+       if (!instance->max_packet) {
+               /* Send the message to the videocore */
+               status = vchi_bulk_queue_transmit(instance->vchi_handle,
+                                                 src, count,
+                                                 VCHI_FLAGS_BLOCK_UNTIL_DATA_READ,
+                                                 NULL);
+       } else {
+               while (count > 0) {
+                       int bytes = min(instance->max_packet, count);
+
+                       status = vchi_queue_kernel_message(instance->vchi_handle,
+                                                          src, bytes);
+                       src += bytes;
+                       count -= bytes;
                }
        }
-       ret = 0;
-
-unlock:
-       vchi_service_release(instance->vchi_handle[0]);
-       mutex_unlock(&instance->vchi_mutex);
-       return ret;
-}
-
-/**
- * Returns all buffers from arm->vc
- */
-void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream)
-{
-}
-
-/**
- * Forces VC to flush(drop) its filled playback buffers and
- * return them the us. (VC->ARM)
- */
-void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream)
-{
-}
 
-unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream)
-{
-       unsigned int count = atomic_read(&alsa_stream->retrieved);
+       if (status) {
+               dev_err(instance->dev,
+                       "failed on %d bytes transfer (status=%d)\n",
+                       size, status);
+               err = -EIO;
+       }
 
-       atomic_sub(count, &alsa_stream->retrieved);
-       return count;
+ unlock:
+       bcm2835_audio_unlock(instance);
+       return err;
 }
-
-module_param(force_bulk, bool, 0444);
-MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio");
index da0fa34501faddaeca0039aa73897d2b0dd08f9f..87d56ab1ffa0c64f5661cd92c733077b7e8d57fb 100644 (file)
@@ -22,38 +22,6 @@ module_param(enable_compat_alsa, bool, 0444);
 MODULE_PARM_DESC(enable_compat_alsa,
                 "Enables ALSA compatibility virtual audio device");
 
-static void snd_devm_unregister_child(struct device *dev, void *res)
-{
-       struct device *childdev = *(struct device **)res;
-       struct bcm2835_chip *chip = dev_get_drvdata(childdev);
-       struct snd_card *card = chip->card;
-
-       snd_card_free(card);
-
-       device_unregister(childdev);
-}
-
-static int snd_devm_add_child(struct device *dev, struct device *child)
-{
-       struct device **dr;
-       int ret;
-
-       dr = devres_alloc(snd_devm_unregister_child, sizeof(*dr), GFP_KERNEL);
-       if (!dr)
-               return -ENOMEM;
-
-       ret = device_add(child);
-       if (ret) {
-               devres_free(dr);
-               return ret;
-       }
-
-       *dr = child;
-       devres_add(dev, dr);
-
-       return 0;
-}
-
 static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res)
 {
        struct bcm2835_vchi_ctx *vchi_ctx = res;
@@ -73,7 +41,7 @@ static int bcm2835_devm_add_vchi_ctx(struct device *dev)
 
        memset(vchi_ctx, 0, sizeof(*vchi_ctx));
 
-       ret = bcm2835_new_vchi_ctx(vchi_ctx);
+       ret = bcm2835_new_vchi_ctx(dev, vchi_ctx);
        if (ret) {
                devres_free(vchi_ctx);
                return ret;
@@ -84,101 +52,6 @@ static int bcm2835_devm_add_vchi_ctx(struct device *dev)
        return 0;
 }
 
-static void snd_bcm2835_release(struct device *dev)
-{
-       struct bcm2835_chip *chip = dev_get_drvdata(dev);
-
-       kfree(chip);
-}
-
-static struct device *
-snd_create_device(struct device *parent,
-                 struct device_driver *driver,
-                 const char *name)
-{
-       struct device *device;
-       int ret;
-
-       device = devm_kzalloc(parent, sizeof(*device), GFP_KERNEL);
-       if (!device)
-               return ERR_PTR(-ENOMEM);
-
-       device_initialize(device);
-       device->parent = parent;
-       device->driver = driver;
-       device->release = snd_bcm2835_release;
-
-       dev_set_name(device, "%s", name);
-
-       ret = snd_devm_add_child(parent, device);
-       if (ret)
-               return ERR_PTR(ret);
-
-       return device;
-}
-
-/* component-destructor
- * (see "Management of Cards and Components")
- */
-static int snd_bcm2835_dev_free(struct snd_device *device)
-{
-       struct bcm2835_chip *chip = device->device_data;
-       struct snd_card *card = chip->card;
-
-       snd_device_free(card, chip);
-
-       return 0;
-}
-
-/* chip-specific constructor
- * (see "Management of Cards and Components")
- */
-static int snd_bcm2835_create(struct snd_card *card,
-                             struct bcm2835_chip **rchip)
-{
-       struct bcm2835_chip *chip;
-       int err;
-       static struct snd_device_ops ops = {
-               .dev_free = snd_bcm2835_dev_free,
-       };
-
-       *rchip = NULL;
-
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-       if (!chip)
-               return -ENOMEM;
-
-       chip->card = card;
-
-       chip->vchi_ctx = devres_find(card->dev->parent,
-                                    bcm2835_devm_free_vchi_ctx, NULL, NULL);
-       if (!chip->vchi_ctx) {
-               kfree(chip);
-               return -ENODEV;
-       }
-
-       err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-       if (err) {
-               kfree(chip);
-               return err;
-       }
-
-       *rchip = chip;
-       return 0;
-}
-
-static struct snd_card *snd_bcm2835_card_new(struct device *dev)
-{
-       struct snd_card *card;
-       int ret;
-
-       ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card);
-       if (ret)
-               return ERR_PTR(ret);
-
-       return card;
-}
-
 typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip,
                                         const char *name,
                                         enum snd_bcm2835_route route,
@@ -203,17 +76,26 @@ static int bcm2835_audio_alsa_newpcm(struct bcm2835_chip *chip,
 {
        int err;
 
-       err = snd_bcm2835_new_pcm(chip, numchannels - 1);
+       err = snd_bcm2835_new_pcm(chip, "bcm2835 ALSA", 0, AUDIO_DEST_AUTO,
+                                 numchannels - 1, false);
        if (err)
                return err;
 
-       err = snd_bcm2835_new_spdif_pcm(chip);
+       err = snd_bcm2835_new_pcm(chip, "bcm2835 IEC958/HDMI", 1, 0, 1, true);
        if (err)
                return err;
 
        return 0;
 }
 
+static int bcm2835_audio_simple_newpcm(struct bcm2835_chip *chip,
+                                      const char *name,
+                                      enum snd_bcm2835_route route,
+                                      u32 numchannels)
+{
+       return snd_bcm2835_new_pcm(chip, name, 0, route, numchannels, false);
+}
+
 static struct bcm2835_audio_driver bcm2835_audio_alsa = {
        .driver = {
                .name = "bcm2835_alsa",
@@ -234,7 +116,7 @@ static struct bcm2835_audio_driver bcm2835_audio_hdmi = {
        .shortname = "bcm2835 HDMI",
        .longname  = "bcm2835 HDMI",
        .minchannels = 1,
-       .newpcm = snd_bcm2835_new_simple_pcm,
+       .newpcm = bcm2835_audio_simple_newpcm,
        .newctl = snd_bcm2835_new_hdmi_ctl,
        .route = AUDIO_DEST_HDMI
 };
@@ -247,7 +129,7 @@ static struct bcm2835_audio_driver bcm2835_audio_headphones = {
        .shortname = "bcm2835 Headphones",
        .longname  = "bcm2835 Headphones",
        .minchannels = 1,
-       .newpcm = snd_bcm2835_new_simple_pcm,
+       .newpcm = bcm2835_audio_simple_newpcm,
        .newctl = snd_bcm2835_new_headphones_ctl,
        .route = AUDIO_DEST_HEADPHONES
 };
@@ -272,71 +154,75 @@ static struct bcm2835_audio_drivers children_devices[] = {
        },
 };
 
-static int snd_add_child_device(struct device *device,
+static void bcm2835_card_free(void *data)
+{
+       snd_card_free(data);
+}
+
+static int snd_add_child_device(struct device *dev,
                                struct bcm2835_audio_driver *audio_driver,
                                u32 numchans)
 {
        struct snd_card *card;
-       struct device *child;
        struct bcm2835_chip *chip;
-       int err, i;
-
-       child = snd_create_device(device, &audio_driver->driver,
-                                 audio_driver->driver.name);
-       if (IS_ERR(child)) {
-               dev_err(device,
-                       "Unable to create child device %p, error %ld",
-                       audio_driver->driver.name,
-                       PTR_ERR(child));
-               return PTR_ERR(child);
+       int err;
+
+       err = snd_card_new(dev, -1, NULL, THIS_MODULE, sizeof(*chip), &card);
+       if (err < 0) {
+               dev_err(dev, "Failed to create card");
+               return err;
        }
 
-       card = snd_bcm2835_card_new(child);
-       if (IS_ERR(card)) {
-               dev_err(child, "Failed to create card");
-               return PTR_ERR(card);
+       chip = card->private_data;
+       chip->card = card;
+       chip->dev = dev;
+       mutex_init(&chip->audio_mutex);
+
+       chip->vchi_ctx = devres_find(dev,
+                                    bcm2835_devm_free_vchi_ctx, NULL, NULL);
+       if (!chip->vchi_ctx) {
+               err = -ENODEV;
+               goto error;
        }
 
-       snd_card_set_dev(card, child);
        strcpy(card->driver, audio_driver->driver.name);
        strcpy(card->shortname, audio_driver->shortname);
        strcpy(card->longname, audio_driver->longname);
 
-       err = snd_bcm2835_create(card, &chip);
-       if (err) {
-               dev_err(child, "Failed to create chip, error %d\n", err);
-               return err;
-       }
-
-       chip->dev = child;
-
        err = audio_driver->newpcm(chip, audio_driver->shortname,
                audio_driver->route,
                numchans);
        if (err) {
-               dev_err(child, "Failed to create pcm, error %d\n", err);
-               return err;
+               dev_err(dev, "Failed to create pcm, error %d\n", err);
+               goto error;
        }
 
        err = audio_driver->newctl(chip);
        if (err) {
-               dev_err(child, "Failed to create controls, error %d\n", err);
-               return err;
+               dev_err(dev, "Failed to create controls, error %d\n", err);
+               goto error;
        }
 
-       for (i = 0; i < numchans; i++)
-               chip->avail_substreams |= (1 << i);
-
        err = snd_card_register(card);
        if (err) {
-               dev_err(child, "Failed to register card, error %d\n", err);
-               return err;
+               dev_err(dev, "Failed to register card, error %d\n", err);
+               goto error;
        }
 
-       dev_set_drvdata(child, chip);
-       dev_info(child, "card created with %d channels\n", numchans);
+       dev_set_drvdata(dev, chip);
+
+       err = devm_add_action(dev, bcm2835_card_free, card);
+       if (err < 0) {
+               dev_err(dev, "Failed to add devm action, err %d\n", err);
+               goto error;
+       }
 
+       dev_info(dev, "card created with %d channels\n", numchans);
        return 0;
+
+ error:
+       snd_card_free(card);
+       return err;
 }
 
 static int snd_add_child_devices(struct device *device, u32 numchans)
index 5dc427240a1d759b2df64a8560ebf5eba59f5454..34a0125ce646ab30ecfe666f0e3d1b8cfb7989cf 100644 (file)
@@ -5,59 +5,12 @@
 #define __SOUND_ARM_BCM2835_H
 
 #include <linux/device.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
 #include <linux/wait.h>
 #include <sound/core.h>
-#include <sound/initval.h>
 #include <sound/pcm.h>
-#include <sound/pcm_params.h>
 #include <sound/pcm-indirect.h>
-#include <linux/workqueue.h>
-
 #include "interface/vchi/vchi.h"
 
-/*
- * #define AUDIO_DEBUG_ENABLE
- * #define AUDIO_VERBOSE_DEBUG_ENABLE
- */
-
-/* Debug macros */
-
-#ifdef AUDIO_DEBUG_ENABLE
-#ifdef AUDIO_VERBOSE_DEBUG_ENABLE
-
-#define audio_debug(fmt, arg...) \
-       pr_info("%s:%d " fmt, __func__, __LINE__, ##arg)
-
-#define audio_info(fmt, arg...) \
-       pr_info("%s:%d " fmt, __func__, __LINE__, ##arg)
-
-#else
-
-#define audio_debug(fmt, arg...)
-
-#define audio_info(fmt, arg...)
-
-#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */
-
-#else
-
-#define audio_debug(fmt, arg...)
-
-#define audio_info(fmt, arg...)
-
-#endif /* AUDIO_DEBUG_ENABLE */
-
-#define audio_error(fmt, arg...) \
-       pr_err("%s:%d " fmt, __func__, __LINE__, ##arg)
-
-#define audio_warning(fmt, arg...) \
-       pr_warn("%s:%d " fmt, __func__, __LINE__, ##arg)
-
-#define audio_alert(fmt, arg...) \
-       pr_alert("%s:%d " fmt, __func__, __LINE__, ##arg)
-
 #define MAX_SUBSTREAMS   (8)
 #define AVAIL_SUBSTREAMS_MASK  (0xff)
 
@@ -74,6 +27,8 @@ enum {
 // convert chip to alsa volume
 #define chip2alsa(vol) -(((vol) * 100) >> 8)
 
+#define CHIP_MIN_VOLUME                26214 /* minimum level aka mute */
+
 /* Some constants for values .. */
 enum snd_bcm2835_route {
        AUDIO_DEST_AUTO = 0,
@@ -90,7 +45,6 @@ enum snd_bcm2835_ctrl {
 
 struct bcm2835_vchi_ctx {
        VCHI_INSTANCE_T vchi_instance;
-       VCHI_CONNECTION_T *vchi_connection;
 };
 
 /* definition of the chip-specific record */
@@ -98,13 +52,10 @@ struct bcm2835_chip {
        struct snd_card *card;
        struct snd_pcm *pcm;
        struct snd_pcm *pcm_spdif;
-       /* Bitmat for valid reg_base and irq numbers */
-       unsigned int avail_substreams;
        struct device *dev;
        struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS];
 
        int volume;
-       int old_volume; /* stores the volume value whist muted */
        int dest;
        int mute;
 
@@ -120,38 +71,26 @@ struct bcm2835_alsa_stream {
        struct snd_pcm_substream *substream;
        struct snd_pcm_indirect pcm_indirect;
 
-       spinlock_t lock;
-
-       int open;
-       int running;
        int draining;
 
-       int channels;
-       int params_rate;
-       int pcm_format_width;
-
-       unsigned int pos;
+       atomic_t pos;
+       unsigned int period_offset;
        unsigned int buffer_size;
        unsigned int period_size;
 
-       atomic_t retrieved;
        struct bcm2835_audio_instance *instance;
-       struct workqueue_struct *my_wq;
        int idx;
 };
 
 int snd_bcm2835_new_ctl(struct bcm2835_chip *chip);
-int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels);
-int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip);
-int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip,
-                              const char *name,
-                              enum snd_bcm2835_route route,
-                              u32 numchannels);
+int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
+                       int idx, enum snd_bcm2835_route route,
+                       u32 numchannels, bool spdif);
 
 int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip);
 int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip);
 
-int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx);
+int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx);
 void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx);
 
 int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream);
@@ -159,16 +98,15 @@ int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream);
 int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream,
                             unsigned int channels, unsigned int samplerate,
                             unsigned int bps);
-int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream);
 int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream);
 int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream);
-int bcm2835_audio_set_ctls(struct bcm2835_chip *chip);
+int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream);
+int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream);
 int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
                        unsigned int count,
                        void *src);
-void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream);
+void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream,
+                          unsigned int size);
 unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream);
-void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream);
-void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream);
 
 #endif /* __SOUND_ARM_BCM2835_H */
index cefce72d814fc8fc8ec44f06faf1eb5b9b1af2cf..6c2b4ffe49964096e135fc400ab070672c18458a 100644 (file)
@@ -15,9 +15,3 @@ padding in the V4L2 spec, but that padding doesn't match what the
 hardware can do.  If we exposed the native padding requirements
 through the V4L2 "multiplanar" formats, the firmware would have one
 less copy it needed to do.
-
-3) Port to ARM64
-
-The bulk_receive() does some manual cache flushing that are 32-bit ARM
-only, which we should convert to proper cross-platform APIs.
-
index cff7b1e07153b951f397a5a789920cef979cb2a4..a2c55cb2192a33a6a4f1f27d8e65968e82dba540 100644 (file)
@@ -1106,7 +1106,7 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
        {
                V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU,
                0, ARRAY_SIZE(mains_freq_qmenu) - 1,
-               1, 1, NULL,
+               1, 1, mains_freq_qmenu,
                MMAL_PARAMETER_FLICKER_AVOID,
                &ctrl_set_flicker_avoidance,
                false
index 51e5b04ff0f58d6dffc79ded005977595c341c45..cc2d9933b96935b3fa18b279b1c66e072c707f60 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/vmalloc.h>
-#include <asm/cacheflush.h>
 #include <media/videobuf2-vmalloc.h>
 
 #include "mmal-common.h"
@@ -1803,19 +1802,12 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
 {
        int status;
        struct vchiq_mmal_instance *instance;
-       static VCHI_CONNECTION_T *vchi_connection;
        static VCHI_INSTANCE_T vchi_instance;
        SERVICE_CREATION_T params = {
                .version                = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER),
                .service_id             = VC_MMAL_SERVER_NAME,
-               .connection             = vchi_connection,
-               .rx_fifo_size           = 0,
-               .tx_fifo_size           = 0,
                .callback               = service_callback,
                .callback_param         = NULL,
-               .want_unaligned_bulk_rx = 1,
-               .want_unaligned_bulk_tx = 1,
-               .want_crc               = 0
        };
 
        /* compile time checks to ensure structure size as they are
@@ -1839,7 +1831,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
                return -EIO;
        }
 
-       status = vchi_connect(NULL, 0, vchi_instance);
+       status = vchi_connect(vchi_instance);
        if (status) {
                pr_err("Failed to connect VCHI instance (status=%d)\n", status);
                return -EIO;
diff --git a/drivers/staging/vc04_services/interface/vchi/connections/connection.h b/drivers/staging/vc04_services/interface/vchi/connections/connection.h
deleted file mode 100644 (file)
index 67c8438..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CONNECTION_H_
-#define CONNECTION_H_
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/semaphore.h>
-
-#include "interface/vchi/vchi_cfg_internal.h"
-#include "interface/vchi/vchi_common.h"
-#include "interface/vchi/message_drivers/message.h"
-
-/******************************************************************************
- Global defs
- *****************************************************************************/
-
-// Opaque handle for a connection / service pair
-typedef struct opaque_vchi_connection_connected_service_handle_t *VCHI_CONNECTION_SERVICE_HANDLE_T;
-
-// opaque handle to the connection state information
-typedef struct opaque_vchi_connection_info_t VCHI_CONNECTION_STATE_T;
-
-typedef struct vchi_connection_t VCHI_CONNECTION_T;
-
-/******************************************************************************
- API
- *****************************************************************************/
-
-// Routine to init a connection with a particular low level driver
-typedef VCHI_CONNECTION_STATE_T * (*VCHI_CONNECTION_INIT_T)( struct vchi_connection_t * connection,
-                                                             const VCHI_MESSAGE_DRIVER_T * driver );
-
-// Routine to control CRC enabling at a connection level
-typedef int32_t (*VCHI_CONNECTION_CRC_CONTROL_T)( VCHI_CONNECTION_STATE_T *state_handle,
-                                                  VCHI_CRC_CONTROL_T control );
-
-// Routine to create a service
-typedef int32_t (*VCHI_CONNECTION_SERVICE_CONNECT_T)( VCHI_CONNECTION_STATE_T *state_handle,
-                                                      int32_t service_id,
-                                                      uint32_t rx_fifo_size,
-                                                      uint32_t tx_fifo_size,
-                                                      int server,
-                                                      VCHI_CALLBACK_T callback,
-                                                      void *callback_param,
-                                                      int32_t want_crc,
-                                                      int32_t want_unaligned_bulk_rx,
-                                                      int32_t want_unaligned_bulk_tx,
-                                                      VCHI_CONNECTION_SERVICE_HANDLE_T *service_handle );
-
-// Routine to close a service
-typedef int32_t (*VCHI_CONNECTION_SERVICE_DISCONNECT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle );
-
-// Routine to queue a message
-typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                            const void *data,
-                                                            uint32_t data_size,
-                                                            VCHI_FLAGS_T flags,
-                                                            void *msg_handle );
-
-// scatter-gather (vector) message queueing
-typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                             VCHI_MSG_VECTOR_T *vector,
-                                                             uint32_t count,
-                                                             VCHI_FLAGS_T flags,
-                                                             void *msg_handle );
-
-// Routine to dequeue a message
-typedef int32_t (*VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                              void *data,
-                                                              uint32_t max_data_size_to_read,
-                                                              uint32_t *actual_msg_size,
-                                                              VCHI_FLAGS_T flags );
-
-// Routine to peek at a message
-typedef int32_t (*VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                           void **data,
-                                                           uint32_t *msg_size,
-                                                           VCHI_FLAGS_T flags );
-
-// Routine to hold a message
-typedef int32_t (*VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                           void **data,
-                                                           uint32_t *msg_size,
-                                                           VCHI_FLAGS_T flags,
-                                                           void **message_handle );
-
-// Routine to initialise a received message iterator
-typedef int32_t (*VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                                VCHI_MSG_ITER_T *iter,
-                                                                VCHI_FLAGS_T flags );
-
-// Routine to release a held message
-typedef int32_t (*VCHI_CONNECTION_HELD_MSG_RELEASE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                       void *message_handle );
-
-// Routine to get info on a held message
-typedef int32_t (*VCHI_CONNECTION_HELD_MSG_INFO_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                    void *message_handle,
-                                                    void **data,
-                                                    int32_t *msg_size,
-                                                    uint32_t *tx_timestamp,
-                                                    uint32_t *rx_timestamp );
-
-// Routine to check whether the iterator has a next message
-typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
-                                                       const VCHI_MSG_ITER_T *iter );
-
-// Routine to advance the iterator
-typedef int32_t (*VCHI_CONNECTION_MSG_ITER_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
-                                                    VCHI_MSG_ITER_T *iter,
-                                                    void **data,
-                                                    uint32_t *msg_size );
-
-// Routine to remove the last message returned by the iterator
-typedef int32_t (*VCHI_CONNECTION_MSG_ITER_REMOVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
-                                                      VCHI_MSG_ITER_T *iter );
-
-// Routine to hold the last message returned by the iterator
-typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HOLD_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
-                                                    VCHI_MSG_ITER_T *iter,
-                                                    void **msg_handle );
-
-// Routine to transmit bulk data
-typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                          const void *data_src,
-                                                          uint32_t data_size,
-                                                          VCHI_FLAGS_T flags,
-                                                          void *bulk_handle );
-
-// Routine to receive data
-typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
-                                                         void *data_dst,
-                                                         uint32_t data_size,
-                                                         VCHI_FLAGS_T flags,
-                                                         void *bulk_handle );
-
-// Routine to report if a server is available
-typedef int32_t (*VCHI_CONNECTION_SERVER_PRESENT)( VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t peer_flags );
-
-// Routine to report the number of RX slots available
-typedef int (*VCHI_CONNECTION_RX_SLOTS_AVAILABLE)( const VCHI_CONNECTION_STATE_T *state );
-
-// Routine to report the RX slot size
-typedef uint32_t (*VCHI_CONNECTION_RX_SLOT_SIZE)( const VCHI_CONNECTION_STATE_T *state );
-
-// Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO
-typedef void (*VCHI_CONNECTION_RX_BULK_BUFFER_ADDED)(VCHI_CONNECTION_STATE_T *state,
-                                                     int32_t service,
-                                                     uint32_t length,
-                                                     MESSAGE_TX_CHANNEL_T channel,
-                                                     uint32_t channel_params,
-                                                     uint32_t data_length,
-                                                     uint32_t data_offset);
-
-// Callback to inform a service that a Xon or Xoff message has been received
-typedef void (*VCHI_CONNECTION_FLOW_CONTROL)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t xoff);
-
-// Callback to inform a service that a server available reply message has been received
-typedef void (*VCHI_CONNECTION_SERVER_AVAILABLE_REPLY)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, uint32_t flags);
-
-// Callback to indicate that bulk auxiliary messages have arrived
-typedef void (*VCHI_CONNECTION_BULK_AUX_RECEIVED)(VCHI_CONNECTION_STATE_T *state);
-
-// Callback to indicate that bulk auxiliary messages have arrived
-typedef void (*VCHI_CONNECTION_BULK_AUX_TRANSMITTED)(VCHI_CONNECTION_STATE_T *state, void *handle);
-
-// Callback with all the connection info you require
-typedef void (*VCHI_CONNECTION_INFO)(VCHI_CONNECTION_STATE_T *state, uint32_t protocol_version, uint32_t slot_size, uint32_t num_slots, uint32_t min_bulk_size);
-
-// Callback to inform of a disconnect
-typedef void (*VCHI_CONNECTION_DISCONNECT)(VCHI_CONNECTION_STATE_T *state, uint32_t flags);
-
-// Callback to inform of a power control request
-typedef void (*VCHI_CONNECTION_POWER_CONTROL)(VCHI_CONNECTION_STATE_T *state, MESSAGE_TX_CHANNEL_T channel, int32_t enable);
-
-// allocate memory suitably aligned for this connection
-typedef void * (*VCHI_BUFFER_ALLOCATE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, uint32_t * length);
-
-// free memory allocated by buffer_allocate
-typedef void   (*VCHI_BUFFER_FREE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, void * address);
-
-/******************************************************************************
- System driver struct
- *****************************************************************************/
-
-struct opaque_vchi_connection_api_t {
-   // Routine to init the connection
-   VCHI_CONNECTION_INIT_T                      init;
-
-   // Connection-level CRC control
-   VCHI_CONNECTION_CRC_CONTROL_T               crc_control;
-
-   // Routine to connect to or create service
-   VCHI_CONNECTION_SERVICE_CONNECT_T           service_connect;
-
-   // Routine to disconnect from a service
-   VCHI_CONNECTION_SERVICE_DISCONNECT_T        service_disconnect;
-
-   // Routine to queue a message
-   VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T     service_queue_msg;
-
-   // scatter-gather (vector) message queue
-   VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T    service_queue_msgv;
-
-   // Routine to dequeue a message
-   VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T   service_dequeue_msg;
-
-   // Routine to peek at a message
-   VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T      service_peek_msg;
-
-   // Routine to hold a message
-   VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T      service_hold_msg;
-
-   // Routine to initialise a received message iterator
-   VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T service_look_ahead_msg;
-
-   // Routine to release a message
-   VCHI_CONNECTION_HELD_MSG_RELEASE_T          held_msg_release;
-
-   // Routine to get information on a held message
-   VCHI_CONNECTION_HELD_MSG_INFO_T             held_msg_info;
-
-   // Routine to check for next message on iterator
-   VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T         msg_iter_has_next;
-
-   // Routine to get next message on iterator
-   VCHI_CONNECTION_MSG_ITER_NEXT_T             msg_iter_next;
-
-   // Routine to remove the last message returned by iterator
-   VCHI_CONNECTION_MSG_ITER_REMOVE_T           msg_iter_remove;
-
-   // Routine to hold the last message returned by iterator
-   VCHI_CONNECTION_MSG_ITER_HOLD_T             msg_iter_hold;
-
-   // Routine to transmit bulk data
-   VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T       bulk_queue_transmit;
-
-   // Routine to receive data
-   VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T        bulk_queue_receive;
-
-   // Routine to report the available servers
-   VCHI_CONNECTION_SERVER_PRESENT              server_present;
-
-   // Routine to report the number of RX slots available
-   VCHI_CONNECTION_RX_SLOTS_AVAILABLE          connection_rx_slots_available;
-
-   // Routine to report the RX slot size
-   VCHI_CONNECTION_RX_SLOT_SIZE                connection_rx_slot_size;
-
-   // Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO
-   VCHI_CONNECTION_RX_BULK_BUFFER_ADDED        rx_bulk_buffer_added;
-
-   // Callback to inform a service that a Xon or Xoff message has been received
-   VCHI_CONNECTION_FLOW_CONTROL                flow_control;
-
-   // Callback to inform a service that a server available reply message has been received
-   VCHI_CONNECTION_SERVER_AVAILABLE_REPLY      server_available_reply;
-
-   // Callback to indicate that bulk auxiliary messages have arrived
-   VCHI_CONNECTION_BULK_AUX_RECEIVED           bulk_aux_received;
-
-   // Callback to indicate that a bulk auxiliary message has been transmitted
-   VCHI_CONNECTION_BULK_AUX_TRANSMITTED        bulk_aux_transmitted;
-
-   // Callback to provide information about the connection
-   VCHI_CONNECTION_INFO                        connection_info;
-
-   // Callback to notify that peer has requested disconnect
-   VCHI_CONNECTION_DISCONNECT                  disconnect;
-
-   // Callback to notify that peer has requested power change
-   VCHI_CONNECTION_POWER_CONTROL               power_control;
-
-   // allocate memory suitably aligned for this connection
-   VCHI_BUFFER_ALLOCATE                        buffer_allocate;
-
-   // free memory allocated by buffer_allocate
-   VCHI_BUFFER_FREE                            buffer_free;
-
-};
-
-struct vchi_connection_t {
-   const VCHI_CONNECTION_API_T *api;
-   VCHI_CONNECTION_STATE_T     *state;
-#ifdef VCHI_COARSE_LOCKING
-   struct semaphore             sem;
-#endif
-};
-
-#endif /* CONNECTION_H_ */
-
-/****************************** End of file **********************************/
diff --git a/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h
deleted file mode 100644 (file)
index 834263f..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VCHI_MESSAGE_H_
-#define _VCHI_MESSAGE_H_
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/semaphore.h>
-
-#include "interface/vchi/vchi_cfg_internal.h"
-#include "interface/vchi/vchi_common.h"
-
-typedef enum message_event_type {
-   MESSAGE_EVENT_NONE,
-   MESSAGE_EVENT_NOP,
-   MESSAGE_EVENT_MESSAGE,
-   MESSAGE_EVENT_SLOT_COMPLETE,
-   MESSAGE_EVENT_RX_BULK_PAUSED,
-   MESSAGE_EVENT_RX_BULK_COMPLETE,
-   MESSAGE_EVENT_TX_COMPLETE,
-   MESSAGE_EVENT_MSG_DISCARDED
-} MESSAGE_EVENT_TYPE_T;
-
-typedef enum vchi_msg_flags {
-   VCHI_MSG_FLAGS_NONE                  = 0x0,
-   VCHI_MSG_FLAGS_TERMINATE_DMA         = 0x1
-} VCHI_MSG_FLAGS_T;
-
-typedef enum message_tx_channel {
-   MESSAGE_TX_CHANNEL_MESSAGE           = 0,
-   MESSAGE_TX_CHANNEL_BULK              = 1 // drivers may provide multiple bulk channels, from 1 upwards
-} MESSAGE_TX_CHANNEL_T;
-
-// Macros used for cycling through bulk channels
-#define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
-#define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
-
-typedef enum message_rx_channel {
-   MESSAGE_RX_CHANNEL_MESSAGE           = 0,
-   MESSAGE_RX_CHANNEL_BULK              = 1 // drivers may provide multiple bulk channels, from 1 upwards
-} MESSAGE_RX_CHANNEL_T;
-
-// Message receive slot information
-typedef struct rx_msg_slot_info {
-
-   struct rx_msg_slot_info *next;
-   //struct slot_info *prev;
-#if !defined VCHI_COARSE_LOCKING
-   struct semaphore   sem;
-#endif
-
-   uint8_t           *addr;               // base address of slot
-   uint32_t           len;                // length of slot in bytes
-
-   uint32_t           write_ptr;          // hardware causes this to advance
-   uint32_t           read_ptr;           // this module does the reading
-   int                active;             // is this slot in the hardware dma fifo?
-   uint32_t           msgs_parsed;        // count how many messages are in this slot
-   uint32_t           msgs_released;      // how many messages have been released
-   void              *state;              // connection state information
-   uint8_t            ref_count[VCHI_MAX_SERVICES_PER_CONNECTION];          // reference count for slots held by services
-} RX_MSG_SLOTINFO_T;
-
-// The message driver no longer needs to know about the fields of RX_BULK_SLOTINFO_T - sort this out.
-// In particular, it mustn't use addr and len - they're the client buffer, but the message
-// driver will be tasked with sending the aligned core section.
-typedef struct rx_bulk_slotinfo_t {
-   struct rx_bulk_slotinfo_t *next;
-
-   struct semaphore *blocking;
-
-   // needed by DMA
-   void        *addr;
-   uint32_t     len;
-
-   // needed for the callback
-   void        *service;
-   void        *handle;
-   VCHI_FLAGS_T flags;
-} RX_BULK_SLOTINFO_T;
-
-/* ----------------------------------------------------------------------
- * each connection driver will have a pool of the following struct.
- *
- * the pool will be managed by vchi_qman_*
- * this means there will be multiple queues (single linked lists)
- * a given struct message_info will be on exactly one of these queues
- * at any one time
- * -------------------------------------------------------------------- */
-typedef struct rx_message_info {
-
-   struct message_info *next;
-   //struct message_info *prev;
-
-   uint8_t    *addr;
-   uint32_t   len;
-   RX_MSG_SLOTINFO_T *slot; // points to whichever slot contains this message
-   uint32_t   tx_timestamp;
-   uint32_t   rx_timestamp;
-
-} RX_MESSAGE_INFO_T;
-
-typedef struct {
-   MESSAGE_EVENT_TYPE_T type;
-
-   struct {
-      // for messages
-      void    *addr;           // address of message
-      uint16_t slot_delta;     // whether this message indicated slot delta
-      uint32_t len;            // length of message
-      RX_MSG_SLOTINFO_T *slot; // slot this message is in
-      int32_t  service;   // service id this message is destined for
-      uint32_t tx_timestamp;   // timestamp from the header
-      uint32_t rx_timestamp;   // timestamp when we parsed it
-   } message;
-
-   // FIXME: cleanup slot reporting...
-   RX_MSG_SLOTINFO_T *rx_msg;
-   RX_BULK_SLOTINFO_T *rx_bulk;
-   void *tx_handle;
-   MESSAGE_TX_CHANNEL_T tx_channel;
-
-} MESSAGE_EVENT_T;
-
-// callbacks
-typedef void VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T( void *state );
-
-typedef struct {
-   VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T *event_callback;
-} VCHI_MESSAGE_DRIVER_OPEN_T;
-
-// handle to this instance of message driver (as returned by ->open)
-typedef struct opaque_mhandle_t *VCHI_MDRIVER_HANDLE_T;
-
-struct opaque_vchi_message_driver_t {
-   VCHI_MDRIVER_HANDLE_T *(*open)( VCHI_MESSAGE_DRIVER_OPEN_T *params, void *state );
-   int32_t (*suspending)( VCHI_MDRIVER_HANDLE_T *handle );
-   int32_t (*resumed)( VCHI_MDRIVER_HANDLE_T *handle );
-   int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, int32_t enable );
-   int32_t (*add_msg_rx_slot)( VCHI_MDRIVER_HANDLE_T *handle, RX_MSG_SLOTINFO_T *slot );      // rx message
-   int32_t (*add_bulk_rx)( VCHI_MDRIVER_HANDLE_T *handle, void *data, uint32_t len, RX_BULK_SLOTINFO_T *slot );  // rx data (bulk)
-   int32_t (*send)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, VCHI_MSG_FLAGS_T flags, void *send_handle );      // tx (message & bulk)
-   void    (*next_event)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_EVENT_T *event );     // get the next event from message_driver
-   int32_t (*enable)( VCHI_MDRIVER_HANDLE_T *handle );
-   int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, int32_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void
-                            *address, uint32_t length_avail, uint32_t max_total_length, int32_t pad_to_fill, int32_t allow_partial );
-
-   int32_t (*update_message)( VCHI_MDRIVER_HANDLE_T *handle, void *dest, int16_t *slot_count );
-   int32_t (*buffer_aligned)( VCHI_MDRIVER_HANDLE_T *handle, int tx, int uncached, const void *address, const uint32_t length );
-   void *  (*allocate_buffer)( VCHI_MDRIVER_HANDLE_T *handle, uint32_t *length );
-   void    (*free_buffer)( VCHI_MDRIVER_HANDLE_T *handle, void *address );
-   int     (*rx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
-   int     (*tx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
-
-   int32_t  (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
-   uint32_t (*tx_bulk_chunk_size)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
-   int     (*tx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
-   int     (*rx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_RX_CHANNEL_T channel );
-   void    (*form_bulk_aux)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, uint32_t chunk_size, const void **aux_data, int32_t *aux_len );
-   void    (*debug)( VCHI_MDRIVER_HANDLE_T *handle );
-};
-
-#endif // _VCHI_MESSAGE_H_
-
-/****************************** End of file ***********************************/
index 66a3a060fad2a9fd3f889bb8387c37e54b7eb327..01381904775d770442f7ec4c253dde36771154ec 100644 (file)
@@ -36,7 +36,6 @@
 
 #include "interface/vchi/vchi_cfg.h"
 #include "interface/vchi/vchi_common.h"
-#include "interface/vchi/connections/connection.h"
 #include "vchi_mh.h"
 
 /******************************************************************************
@@ -60,46 +59,8 @@ struct vchi_version {
 #define VCHI_VERSION(v_) { v_, v_ }
 #define VCHI_VERSION_EX(v_, m_) { v_, m_ }
 
-typedef enum {
-   VCHI_VEC_POINTER,
-   VCHI_VEC_HANDLE,
-   VCHI_VEC_LIST
-} VCHI_MSG_VECTOR_TYPE_T;
-
-typedef struct vchi_msg_vector_ex {
-
-   VCHI_MSG_VECTOR_TYPE_T type;
-   union {
-      // a memory handle
-      struct {
-         VCHI_MEM_HANDLE_T handle;
-         uint32_t offset;
-         int32_t vec_len;
-      } handle;
-
-      // an ordinary data pointer
-      struct {
-         const void *vec_base;
-         int32_t vec_len;
-      } ptr;
-
-      // a nested vector list
-      struct {
-         struct vchi_msg_vector_ex *vec;
-         uint32_t vec_len;
-      } list;
-   } u;
-} VCHI_MSG_VECTOR_EX_T;
-
-// Construct an entry in a msg vector for a pointer (p) of length (l)
-#define VCHI_VEC_POINTER(p,l)  VCHI_VEC_POINTER, { { (VCHI_MEM_HANDLE_T)(p), (l) } }
-
-// Construct an entry in a msg vector for a message handle (h), starting at offset (o) of length (l)
-#define VCHI_VEC_HANDLE(h,o,l) VCHI_VEC_HANDLE,  { { (h), (o), (l) } }
-
 // Macros to manipulate 'FOURCC' values
-#define MAKE_FOURCC(x) ((int32_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] ))
-#define FOURCC_TO_CHAR(x) (x >> 24) & 0xFF,(x >> 16) & 0xFF,(x >> 8) & 0xFF, x & 0xFF
+#define MAKE_FOURCC(x) ((int32_t)((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]))
 
 // Opaque service information
 struct opaque_vchi_service_t;
@@ -115,20 +76,8 @@ typedef struct {
 typedef struct {
        struct vchi_version version;
        int32_t service_id;
-       VCHI_CONNECTION_T *connection;
-       uint32_t rx_fifo_size;
-       uint32_t tx_fifo_size;
        VCHI_CALLBACK_T callback;
        void *callback_param;
-       /* client intends to receive bulk transfers of
-               odd lengths or into unaligned buffers */
-       int32_t want_unaligned_bulk_rx;
-       /* client intends to transmit bulk transfers of
-               odd lengths or out of unaligned buffers */
-       int32_t want_unaligned_bulk_tx;
-       /* client wants to check CRCs on (bulk) xfers.
-               Only needs to be set at 1 end - will do both directions. */
-       int32_t want_crc;
 } SERVICE_CREATION_T;
 
 // Opaque handle for a VCHI instance
@@ -137,15 +86,6 @@ typedef struct opaque_vchi_instance_handle_t *VCHI_INSTANCE_T;
 // Opaque handle for a server or client
 typedef struct opaque_vchi_service_handle_t *VCHI_SERVICE_HANDLE_T;
 
-// Service registration & startup
-typedef void (*VCHI_SERVICE_INIT)(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections);
-
-typedef struct service_info_tag {
-   const char * const vll_filename; /* VLL to load to start this service. This is an empty string if VLL is "static" */
-   VCHI_SERVICE_INIT init;          /* Service initialisation function */
-   void *vll_handle;                /* VLL handle; NULL when unloaded or a "static VLL" in build */
-} SERVICE_INFO_T;
-
 /******************************************************************************
  Global funcs - implementation is specific to which side you are on (local / remote)
  *****************************************************************************/
@@ -154,28 +94,19 @@ typedef struct service_info_tag {
 extern "C" {
 #endif
 
-extern /*@observer@*/ VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * function_table,
-                                                   const VCHI_MESSAGE_DRIVER_T * low_level);
-
 // Routine used to initialise the vchi on both local + remote connections
-extern int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle );
+extern int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle);
 
-extern int32_t vchi_exit( void );
+extern int32_t vchi_exit(void);
 
-extern int32_t vchi_connect( VCHI_CONNECTION_T **connections,
-                             const uint32_t num_connections,
-                             VCHI_INSTANCE_T instance_handle );
+extern int32_t vchi_connect(VCHI_INSTANCE_T instance_handle);
 
 //When this is called, ensure that all services have no data pending.
 //Bulk transfers can remain 'queued'
-extern int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle );
-
-// Global control over bulk CRC checking
-extern int32_t vchi_crc_control( VCHI_CONNECTION_T *connection,
-                                 VCHI_CRC_CONTROL_T control );
+extern int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle);
 
 // helper functions
-extern void * vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length);
+extern void *vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length);
 extern void vchi_free_buffer(VCHI_SERVICE_HANDLE_T handle, void *address);
 extern uint32_t vchi_current_time(VCHI_INSTANCE_T instance_handle);
 
@@ -183,32 +114,32 @@ extern uint32_t vchi_current_time(VCHI_INSTANCE_T instance_handle);
  Global service API
  *****************************************************************************/
 // Routine to create a named service
-extern int32_t vchi_service_create( VCHI_INSTANCE_T instance_handle,
-                                    SERVICE_CREATION_T *setup,
-                                    VCHI_SERVICE_HANDLE_T *handle );
+extern int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,
+                                  SERVICE_CREATION_T *setup,
+                                  VCHI_SERVICE_HANDLE_T *handle);
 
 // Routine to destroy a service
-extern int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle );
+extern int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle);
 
 // Routine to open a named service
-extern int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle,
-                                  SERVICE_CREATION_T *setup,
-                                  VCHI_SERVICE_HANDLE_T *handle);
+extern int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,
+                                SERVICE_CREATION_T *setup,
+                                VCHI_SERVICE_HANDLE_T *handle);
 
-extern int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle,
-                                      short *peer_version );
+extern int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle,
+                                    short *peer_version);
 
 // Routine to close a named service
-extern int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle );
+extern int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle);
 
 // Routine to increment ref count on a named service
-extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle );
+extern int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle);
 
 // Routine to decrement ref count on a named service
-extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle );
+extern int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle);
 
 // Routine to set a control option for a named service
-extern int32_t vchi_service_set_option( const VCHI_SERVICE_HANDLE_T handle,
+extern int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,
                                        VCHI_SERVICE_OPTION_T option,
                                        int value);
 
@@ -226,128 +157,120 @@ vchi_queue_user_message(VCHI_SERVICE_HANDLE_T handle,
 
 // Routine to receive a msg from a service
 // Dequeue is equivalent to hold, copy into client buffer, release
-extern int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle,
-                                 void *data,
-                                 uint32_t max_data_size_to_read,
-                                 uint32_t *actual_msg_size,
-                                 VCHI_FLAGS_T flags );
+extern int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,
+                               void *data,
+                               uint32_t max_data_size_to_read,
+                               uint32_t *actual_msg_size,
+                               VCHI_FLAGS_T flags);
 
 // Routine to look at a message in place.
 // The message is not dequeued, so a subsequent call to peek or dequeue
 // will return the same message.
-extern int32_t vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle,
-                              void **data,
-                              uint32_t *msg_size,
-                              VCHI_FLAGS_T flags );
+extern int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,
+                            void **data,
+                            uint32_t *msg_size,
+                            VCHI_FLAGS_T flags);
 
 // Routine to remove a message after it has been read in place with peek
 // The first message on the queue is dequeued.
-extern int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle );
+extern int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle);
 
 // Routine to look at a message in place.
 // The message is dequeued, so the caller is left holding it; the descriptor is
 // filled in and must be released when the user has finished with the message.
-extern int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle,
-                              void **data,        // } may be NULL, as info can be
-                              uint32_t *msg_size, // } obtained from HELD_MSG_T
-                              VCHI_FLAGS_T flags,
-                              VCHI_HELD_MSG_T *message_descriptor );
+extern int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,
+                            void **data,        // } may be NULL, as info can be
+                            uint32_t *msg_size, // } obtained from HELD_MSG_T
+                            VCHI_FLAGS_T flags,
+                            VCHI_HELD_MSG_T *message_descriptor);
 
 // Initialise an iterator to look through messages in place
-extern int32_t vchi_msg_look_ahead( VCHI_SERVICE_HANDLE_T handle,
-                                    VCHI_MSG_ITER_T *iter,
-                                    VCHI_FLAGS_T flags );
+extern int32_t vchi_msg_look_ahead(VCHI_SERVICE_HANDLE_T handle,
+                                  VCHI_MSG_ITER_T *iter,
+                                  VCHI_FLAGS_T flags);
 
 /******************************************************************************
  Global service support API - operations on held messages and message iterators
  *****************************************************************************/
 
 // Routine to get the address of a held message
-extern void *vchi_held_msg_ptr( const VCHI_HELD_MSG_T *message );
+extern void *vchi_held_msg_ptr(const VCHI_HELD_MSG_T *message);
 
 // Routine to get the size of a held message
-extern int32_t vchi_held_msg_size( const VCHI_HELD_MSG_T *message );
+extern int32_t vchi_held_msg_size(const VCHI_HELD_MSG_T *message);
 
 // Routine to get the transmit timestamp as written into the header by the peer
-extern uint32_t vchi_held_msg_tx_timestamp( const VCHI_HELD_MSG_T *message );
+extern uint32_t vchi_held_msg_tx_timestamp(const VCHI_HELD_MSG_T *message);
 
 // Routine to get the reception timestamp, written as we parsed the header
-extern uint32_t vchi_held_msg_rx_timestamp( const VCHI_HELD_MSG_T *message );
+extern uint32_t vchi_held_msg_rx_timestamp(const VCHI_HELD_MSG_T *message);
 
 // Routine to release a held message after it has been processed
-extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message );
+extern int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message);
 
 // Indicates whether the iterator has a next message.
-extern int32_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter );
+extern int32_t vchi_msg_iter_has_next(const VCHI_MSG_ITER_T *iter);
 
 // Return the pointer and length for the next message and advance the iterator.
-extern int32_t vchi_msg_iter_next( VCHI_MSG_ITER_T *iter,
-                                   void **data,
-                                   uint32_t *msg_size );
+extern int32_t vchi_msg_iter_next(VCHI_MSG_ITER_T *iter,
+                                 void **data,
+                                 uint32_t *msg_size);
 
 // Remove the last message returned by vchi_msg_iter_next.
 // Can only be called once after each call to vchi_msg_iter_next.
-extern int32_t vchi_msg_iter_remove( VCHI_MSG_ITER_T *iter );
+extern int32_t vchi_msg_iter_remove(VCHI_MSG_ITER_T *iter);
 
 // Hold the last message returned by vchi_msg_iter_next.
 // Can only be called once after each call to vchi_msg_iter_next.
-extern int32_t vchi_msg_iter_hold( VCHI_MSG_ITER_T *iter,
-                                   VCHI_HELD_MSG_T *message );
+extern int32_t vchi_msg_iter_hold(VCHI_MSG_ITER_T *iter,
+                                 VCHI_HELD_MSG_T *message);
 
 // Return information for the next message, and hold it, advancing the iterator.
-extern int32_t vchi_msg_iter_hold_next( VCHI_MSG_ITER_T *iter,
-                                        void **data,        // } may be NULL
-                                        uint32_t *msg_size, // }
-                                        VCHI_HELD_MSG_T *message );
+extern int32_t vchi_msg_iter_hold_next(VCHI_MSG_ITER_T *iter,
+                                      void **data,        // } may be NULL
+                                      uint32_t *msg_size, // }
+                                      VCHI_HELD_MSG_T *message);
 
 /******************************************************************************
  Global bulk API
  *****************************************************************************/
 
 // Routine to prepare interface for a transfer from the other side
-extern int32_t vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle,
-                                        void *data_dst,
-                                        uint32_t data_size,
-                                        VCHI_FLAGS_T flags,
-                                        void *transfer_handle );
+extern int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,
+                                      void *data_dst,
+                                      uint32_t data_size,
+                                      VCHI_FLAGS_T flags,
+                                      void *transfer_handle);
 
 // Prepare interface for a transfer from the other side into relocatable memory.
-int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle,
-                                       VCHI_MEM_HANDLE_T h_dst,
-                                       uint32_t offset,
-                                       uint32_t data_size,
-                                       const VCHI_FLAGS_T flags,
-                                       void * const bulk_handle );
+int32_t vchi_bulk_queue_receive_reloc(const VCHI_SERVICE_HANDLE_T handle,
+                                     VCHI_MEM_HANDLE_T h_dst,
+                                     uint32_t offset,
+                                     uint32_t data_size,
+                                     const VCHI_FLAGS_T flags,
+                                     void * const bulk_handle);
 
 // Routine to queue up data ready for transfer to the other (once they have signalled they are ready)
-extern int32_t vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle,
-                                         const void *data_src,
-                                         uint32_t data_size,
-                                         VCHI_FLAGS_T flags,
-                                         void *transfer_handle );
+extern int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
+                                       const void *data_src,
+                                       uint32_t data_size,
+                                       VCHI_FLAGS_T flags,
+                                       void *transfer_handle);
 
 /******************************************************************************
  Configuration plumbing
  *****************************************************************************/
 
-// function prototypes for the different mid layers (the state info gives the different physical connections)
-extern const VCHI_CONNECTION_API_T *single_get_func_table( void );
-//extern const VCHI_CONNECTION_API_T *local_server_get_func_table( void );
-//extern const VCHI_CONNECTION_API_T *local_client_get_func_table( void );
-
-// declare all message drivers here
-const VCHI_MESSAGE_DRIVER_T *vchi_mphi_message_driver_func_table( void );
-
 #ifdef __cplusplus
 }
 #endif
 
-extern int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle,
-                                               VCHI_MEM_HANDLE_T h_src,
-                                               uint32_t offset,
-                                               uint32_t data_size,
-                                               VCHI_FLAGS_T flags,
-                                               void *transfer_handle );
+extern int32_t vchi_bulk_queue_transmit_reloc(VCHI_SERVICE_HANDLE_T handle,
+                                             VCHI_MEM_HANDLE_T h_src,
+                                             uint32_t offset,
+                                             uint32_t data_size,
+                                             VCHI_FLAGS_T flags,
+                                             void *transfer_handle);
 #endif /* VCHI_H_ */
 
 /****************************** End of file **********************************/
index b6f42b86f206f16476e86e696f18fc0adbdf0d4d..0d3c468c35049d85259ef6b380d960dc67926cb8 100644 (file)
  * can guarantee this by enabling unaligned transmits).
  * Not API. */
 #ifndef VCHI_MIN_BULK_SIZE
-#  define VCHI_MIN_BULK_SIZE    ( VCHI_MAX_MSG_SIZE / 2 < 4096 ? VCHI_MAX_MSG_SIZE / 2 : 4096 )
+#  define VCHI_MIN_BULK_SIZE    (VCHI_MAX_MSG_SIZE / 2 < 4096 ? VCHI_MAX_MSG_SIZE / 2 : 4096)
 #endif
 
 /* Maximum size of bulk transmission chunks, for each interface type. A trade-off between
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h b/drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h
deleted file mode 100644 (file)
index 35dcba4..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef VCHI_CFG_INTERNAL_H_
-#define VCHI_CFG_INTERNAL_H_
-
-/****************************************************************************************
- * Control optimisation attempts.
- ***************************************************************************************/
-
-// Don't use lots of short-term locks - use great long ones, reducing the overall locks-per-second
-#define VCHI_COARSE_LOCKING
-
-// Avoid lock then unlock on exit from blocking queue operations (msg tx, bulk rx/tx)
-// (only relevant if VCHI_COARSE_LOCKING)
-#define VCHI_ELIDE_BLOCK_EXIT_LOCK
-
-// Avoid lock on non-blocking peek
-// (only relevant if VCHI_COARSE_LOCKING)
-#define VCHI_AVOID_PEEK_LOCK
-
-// Use one slot-handler thread per connection, rather than 1 thread dealing with all connections in rotation.
-#define VCHI_MULTIPLE_HANDLER_THREADS
-
-// Put free descriptors onto the head of the free queue, rather than the tail, so that we don't thrash
-// our way through the pool of descriptors.
-#define VCHI_PUSH_FREE_DESCRIPTORS_ONTO_HEAD
-
-// Don't issue a MSG_AVAILABLE callback for every single message. Possibly only safe if VCHI_COARSE_LOCKING.
-#define VCHI_FEWER_MSG_AVAILABLE_CALLBACKS
-
-// Don't use message descriptors for TX messages that don't need them
-#define VCHI_MINIMISE_TX_MSG_DESCRIPTORS
-
-// Nano-locks for multiqueue
-//#define VCHI_MQUEUE_NANOLOCKS
-
-// Lock-free(er) dequeuing
-//#define VCHI_RX_NANOLOCKS
-
-#endif /*VCHI_CFG_INTERNAL_H_*/
index e767209030642dcc0ca48f0037f0b7e93d1f0e27..83d740feab9650c3e8d524e32dcf3ce23175a373 100644 (file)
@@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
 int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
 {
        struct device *dev = &pdev->dev;
-       struct rpi_firmware *fw = platform_get_drvdata(pdev);
+       struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
+       struct rpi_firmware *fw = drvdata->fw;
        VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
        struct resource *res;
        void *slot_mem;
@@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
        if (err < 0)
                return err;
 
+       g_cache_line_size = drvdata->cache_line_size;
        g_fragments_size = 2 * g_cache_line_size;
 
        /* Allocate space for the channels in coherent memory */
index bc05c69383b8598ad0b7a5978f89b4dd55710a93..ea789376de0f8cfa7442edb2ddcfb6cde5bb2ef0 100644 (file)
@@ -170,6 +170,14 @@ static struct device *vchiq_dev;
 static DEFINE_SPINLOCK(msg_queue_spinlock);
 static struct platform_device *bcm2835_camera;
 
+static struct vchiq_drvdata bcm2835_drvdata = {
+       .cache_line_size = 32,
+};
+
+static struct vchiq_drvdata bcm2836_drvdata = {
+       .cache_line_size = 64,
+};
+
 static const char *const ioctl_names[] = {
        "CONNECT",
        "SHUTDOWN",
@@ -3573,12 +3581,25 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
        }
 }
 
+static const struct of_device_id vchiq_of_match[] = {
+       { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata },
+       { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata },
+       {},
+};
+MODULE_DEVICE_TABLE(of, vchiq_of_match);
+
 static int vchiq_probe(struct platform_device *pdev)
 {
        struct device_node *fw_node;
-       struct rpi_firmware *fw;
+       const struct of_device_id *of_id;
+       struct vchiq_drvdata *drvdata;
        int err;
 
+       of_id = of_match_node(vchiq_of_match, pdev->dev.of_node);
+       drvdata = (struct vchiq_drvdata *)of_id->data;
+       if (!drvdata)
+               return -EINVAL;
+
        fw_node = of_find_compatible_node(NULL, NULL,
                                          "raspberrypi,bcm2835-firmware");
        if (!fw_node) {
@@ -3586,12 +3607,12 @@ static int vchiq_probe(struct platform_device *pdev)
                return -ENOENT;
        }
 
-       fw = rpi_firmware_get(fw_node);
+       drvdata->fw = rpi_firmware_get(fw_node);
        of_node_put(fw_node);
-       if (!fw)
+       if (!drvdata->fw)
                return -EPROBE_DEFER;
 
-       platform_set_drvdata(pdev, fw);
+       platform_set_drvdata(pdev, drvdata);
 
        err = vchiq_platform_init(pdev, &g_state);
        if (err != 0)
@@ -3661,12 +3682,6 @@ static int vchiq_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id vchiq_of_match[] = {
-       { .compatible = "brcm,bcm2835-vchiq", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, vchiq_of_match);
-
 static struct platform_driver vchiq_driver = {
        .driver = {
                .name = "bcm2835_vchiq",
index 40bb0c63b1a9d2a430a7b315d5c3a8424a05a8f0..2f3ebc99cbcfdb7c1375502de7eeacd24614bee5 100644 (file)
@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct {
 
 } VCHIQ_ARM_STATE_T;
 
+struct vchiq_drvdata {
+       const unsigned int cache_line_size;
+       struct rpi_firmware *fw;
+};
+
 extern int vchiq_arm_log_level;
 extern int vchiq_susp_log_level;
 
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion
deleted file mode 100644 (file)
index dd1f324..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/perl -w
-# SPDX-License-Identifier: GPL-2.0
-
-use strict;
-
-#
-# Generate a version from available information
-#
-
-my $prefix = shift @ARGV;
-my $root = shift @ARGV;
-
-
-if ( not defined $root ) {
-       die "usage: $0 prefix root-dir\n";
-}
-
-if ( ! -d $root ) {
-       die "root directory $root not found\n";
-}
-
-my $version = "unknown";
-my $tainted = "";
-
-if ( -d "$root/.git" ) {
-       # attempt to work out git version. only do so
-       # on a linux build host, as cygwin builds are
-       # already slow enough
-
-       if ( -f "/usr/bin/git" || -f "/usr/local/bin/git" ) {
-               if (not open(F, "git --git-dir $root/.git rev-parse --verify HEAD|")) {
-                       $version = "no git version";
-               }
-               else {
-                       $version = <F>;
-                       $version =~ s/[ \r\n]*$//;     # chomp may not be enough (cygwin).
-                       $version =~ s/^[ \r\n]*//;     # chomp may not be enough (cygwin).
-               }
-
-               if (open(G, "git --git-dir $root/.git status --porcelain|")) {
-                       $tainted = <G>;
-                       $tainted =~ s/[ \r\n]*$//;     # chomp may not be enough (cygwin).
-                       $tainted =~ s/^[ \r\n]*//;     # chomp may not be enough (cygwin).
-                       if (length $tainted) {
-                       $version = join ' ', $version, "(tainted)";
-               }
-               else {
-                       $version = join ' ', $version, "(clean)";
-         }
-               }
-       }
-}
-
-my $hostname = `hostname`;
-$hostname =~ s/[ \r\n]*$//;     # chomp may not be enough (cygwin).
-$hostname =~ s/^[ \r\n]*//;     # chomp may not be enough (cygwin).
-
-
-print STDERR "Version $version\n";
-print <<EOF;
-#include "${prefix}_build_info.h"
-#include <linux/broadcom/vc_debug_sym.h>
-
-VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_hostname, "$hostname" );
-VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_version, "$version" );
-VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_time,    __TIME__ );
-VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_date,    __DATE__ );
-
-const char *vchiq_get_build_hostname( void )
-{
-   return vchiq_build_hostname;
-}
-
-const char *vchiq_get_build_version( void )
-{
-   return vchiq_build_version;
-}
-
-const char *vchiq_get_build_date( void )
-{
-   return vchiq_build_date;
-}
-
-const char *vchiq_get_build_time( void )
-{
-   return vchiq_build_time;
-}
-EOF
index dddc828390d0a33c8288734ea300897c5a57cc11..c3223fcdaf872c7bec7cf2b2385e390638cc8c18 100644 (file)
@@ -50,33 +50,6 @@ struct shim_service {
        void *callback_param;
 };
 
-/* ----------------------------------------------------------------------
- * return pointer to the mphi message driver function table
- * -------------------------------------------------------------------- */
-const VCHI_MESSAGE_DRIVER_T *
-vchi_mphi_message_driver_func_table(void)
-{
-       return NULL;
-}
-
-/* ----------------------------------------------------------------------
- * return a pointer to the 'single' connection driver fops
- * -------------------------------------------------------------------- */
-const VCHI_CONNECTION_API_T *
-single_get_func_table(void)
-{
-       return NULL;
-}
-
-VCHI_CONNECTION_T *vchi_create_connection(
-       const VCHI_CONNECTION_API_T *function_table,
-       const VCHI_MESSAGE_DRIVER_T *low_level)
-{
-       (void)function_table;
-       (void)low_level;
-       return NULL;
-}
-
 /***********************************************************
  * Name: vchi_msg_peek
  *
@@ -517,9 +490,7 @@ EXPORT_SYMBOL(vchi_initialise);
 /***********************************************************
  * Name: vchi_connect
  *
- * Arguments: VCHI_CONNECTION_T **connections
- *            const uint32_t num_connections
- *            VCHI_INSTANCE_T instance_handle)
+ * Arguments: VCHI_INSTANCE_T instance_handle
  *
  * Description: Starts the command service on each connection,
  *              causing INIT messages to be pinged back and forth
@@ -527,15 +498,10 @@ EXPORT_SYMBOL(vchi_initialise);
  * Returns: 0 if successful, failure otherwise
  *
  ***********************************************************/
-int32_t vchi_connect(VCHI_CONNECTION_T **connections,
-       const uint32_t num_connections,
-       VCHI_INSTANCE_T instance_handle)
+int32_t vchi_connect(VCHI_INSTANCE_T instance_handle)
 {
        VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
 
-       (void)connections;
-       (void)num_connections;
-
        return vchiq_connect(instance);
 }
 EXPORT_SYMBOL(vchi_connect);
index 9c4a5325afc7453044f0c2dc03d9d6f2b997d93b..a7c1e46a953ed1cc1729789a68815802e6b8ec97 100644 (file)
@@ -65,6 +65,7 @@ static const unsigned short wFB_Opt0[2][5] = {
        {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
        {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
 };
+
 static const unsigned short wFB_Opt1[2][5] = {
        {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
        {RATE_6M,  RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
@@ -212,12 +213,12 @@ s_uGetRTSCTSRsvTime(
        } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
                uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
                uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-               uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
+               uRrvTime = uCTSTime + uAckTime + uDataTime + 2 * pDevice->uSIFS;
                return cpu_to_le16((u16)uRrvTime);
        }
 
        /* RTSRrvTime */
-       uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
+       uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3 * pDevice->uSIFS;
        return cpu_to_le16((u16)uRrvTime);
 }
 
@@ -240,7 +241,7 @@ s_uGetDataDuration(
        bool bLastFrag = false;
        unsigned int uAckTime = 0, uNextPktTime = 0;
 
-       if (uFragIdx == (uMACfragNum-1))
+       if (uFragIdx == (uMACfragNum - 1))
                bLastFrag = true;
 
        switch (byDurType) {
@@ -253,7 +254,7 @@ s_uGetDataDuration(
                                return 0;
                        }
                } else {/* First Frag or Mid Frag */
-                       if (uFragIdx == (uMACfragNum-2))
+                       if (uFragIdx == (uMACfragNum - 2))
                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
                        else
                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
@@ -276,7 +277,7 @@ s_uGetDataDuration(
                                return 0;
                        }
                } else {/* First Frag or Mid Frag */
-                       if (uFragIdx == (uMACfragNum-2))
+                       if (uFragIdx == (uMACfragNum - 2))
                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
                        else
                                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
@@ -305,7 +306,7 @@ s_uGetDataDuration(
                                else if (wRate > RATE_54M)
                                        wRate = RATE_54M;
 
-                               if (uFragIdx == (uMACfragNum-2))
+                               if (uFragIdx == (uMACfragNum - 2))
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
                                else
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
@@ -316,7 +317,7 @@ s_uGetDataDuration(
                                else if (wRate > RATE_54M)
                                        wRate = RATE_54M;
 
-                               if (uFragIdx == (uMACfragNum-2))
+                               if (uFragIdx == (uMACfragNum - 2))
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
                                else
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
@@ -346,7 +347,7 @@ s_uGetDataDuration(
                                else if (wRate > RATE_54M)
                                        wRate = RATE_54M;
 
-                               if (uFragIdx == (uMACfragNum-2))
+                               if (uFragIdx == (uMACfragNum - 2))
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
                                else
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
@@ -357,7 +358,7 @@ s_uGetDataDuration(
                                else if (wRate > RATE_54M)
                                        wRate = RATE_54M;
 
-                               if (uFragIdx == (uMACfragNum-2))
+                               if (uFragIdx == (uMACfragNum - 2))
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
                                else
                                        uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
@@ -1093,7 +1094,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
                                                        sizeof(struct vnt_tx_datahead_g);
                        } else { /* RTS_needless */
                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
-                               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
+                               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
                                pvRTS = NULL;
                                pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
@@ -1105,7 +1106,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
                        /* Auto Fall Back */
                        if (bRTS) {/* RTS_need */
                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
-                               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
+                               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
                                pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
                                pvCTS = NULL;
                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
@@ -1114,7 +1115,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
                                        cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
                        } else { /* RTS_needless */
                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
-                               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
+                               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
                                pvRTS = NULL;
                                pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
                                pvTxDataHd = (void  *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
@@ -1128,7 +1129,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
                if (byFBOption == AUTO_FB_NONE) {
                        if (bRTS) {
                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
-                               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
+                               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
                                pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                                pvCTS = NULL;
                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
@@ -1137,7 +1138,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
                                        cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
                        } else { /* RTS_needless, need MICHDR */
                                pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
-                               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
+                               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
                                pvRTS = NULL;
                                pvCTS = NULL;
                                pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
index 73f7fefd3bc37c2481976c6d5f429f0dae53edde..f9d3ad41c8628d2f0cb6e989b3568fad89c55379 100644 (file)
@@ -1,13 +1,13 @@
 config WILC1000
        tristate
-       ---help---
+       help
          This module only support IEEE 802.11n WiFi.
 
 config WILC1000_SDIO
        tristate "Atmel WILC1000 SDIO (WiFi only)"
        depends on CFG80211 && INET && MMC
        select WILC1000
-       ---help---
+       help
          This module adds support for the SDIO interface of adapters using
          WILC1000 chipset. The Atmel WILC1000 SDIO is a full speed interface.
          It meets SDIO card specification version 2.0. The interface supports
@@ -21,7 +21,7 @@ config WILC1000_SPI
        tristate "Atmel WILC1000 SPI (WiFi only)"
        depends on CFG80211 && INET && SPI
        select WILC1000
-       ---help---
+       help
          This module adds support for the SPI interface of adapters using
          WILC1000 chipset. The Atmel WILC1000 has a Serial Peripheral
          Interface (SPI) that operates as a SPI slave. This SPI interface can
@@ -34,7 +34,7 @@ config WILC1000_HW_OOB_INTR
        bool "WILC1000 out of band interrupt"
        depends on WILC1000_SDIO
        default n
-       ---help---
+       help
          This option enables out-of-band interrupt support for the WILC1000
          chipset. This OOB interrupt is intended to provide a faster interrupt
          mechanism for SDIO host controllers that don't support SDIO interrupt.
index ee7e26b886a563e8743d6fdf4a3948de9eaec453..37e8560e501e43e484a944c0a239d92d00a40eec 100644 (file)
@@ -4,12 +4,9 @@ obj-$(CONFIG_WILC1000) += wilc1000.o
 ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
                -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
 
-ccflags-y += -I$(src)/ -DWILC_ASIC_A0 -DWILC_DEBUGFS
-
 wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
                        coreconfigurator.o host_interface.o \
-                       wilc_wlan_cfg.o wilc_debugfs.o \
-                       wilc_wlan.o
+                       wilc_wlan_cfg.o wilc_wlan.o
 
 obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
 wilc1000-sdio-objs += wilc_sdio.o
index e5420676afb327db18fb5d9521009a3fc2449f60..d6d3a971be432a3b2e6d0f576e2e33e1a84ced79 100644 (file)
@@ -116,7 +116,7 @@ static inline void get_address3(u8 *msa, u8 *addr)
        memcpy(addr, msa + 16, 6);
 }
 
-static inline void get_BSSID(u8 *data, u8 *bssid)
+static inline void get_bssid(u8 *data, u8 *bssid)
 {
        if (get_from_ds(data) == 1)
                get_address2(data, bssid);
@@ -233,7 +233,7 @@ s32 wilc_parse_network_info(u8 *msg_buffer,
        network_info->tsf_hi = tsf_lo | ((u64)tsf_hi << 32);
 
        get_ssid(msa, network_info->ssid, &network_info->ssid_len);
-       get_BSSID(msa, network_info->bssid);
+       get_bssid(msa, network_info->bssid);
 
        network_info->ch = get_current_channel_802_11n(msa, rx_len
                                                       + FCS_LEN);
index 42d8accb1f60f2c475574b9c02d119fac7b59e0b..01db8999335e3e33fc39e0af985b9ef4cbd4be1b 100644 (file)
@@ -90,6 +90,7 @@ struct beacon_attr {
 struct set_multicast {
        bool enabled;
        u32 cnt;
+       u8 *mc_list;
 };
 
 struct del_all_sta {
@@ -186,23 +187,7 @@ struct join_bss_param {
 };
 
 static struct host_if_drv *terminated_handle;
-bool wilc_optaining_ip;
-static u8 p2p_listen_state;
-static struct workqueue_struct *hif_workqueue;
-static struct completion hif_driver_comp;
 static struct mutex hif_deinit_lock;
-static struct timer_list periodic_rssi;
-static struct wilc_vif *periodic_rssi_vif;
-
-u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
-
-static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
-
-static u8 set_ip[2][4];
-static u8 get_ip[2][4];
-static u32 clients_count;
-
-static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 
 /* 'msg' should be free by the caller for syc */
 static struct host_if_msg*
@@ -229,7 +214,11 @@ wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *),
 static int wilc_enqueue_work(struct host_if_msg *msg)
 {
        INIT_WORK(&msg->work, msg->fn);
-       if (!hif_workqueue || !queue_work(hif_workqueue, &msg->work))
+
+       if (!msg->vif || !msg->vif->wilc || !msg->vif->wilc->hif_workqueue)
+               return -EINVAL;
+
+       if (!queue_work(msg->vif->wilc->hif_workqueue, &msg->work))
                return -EINVAL;
 
        return 0;
@@ -320,10 +309,12 @@ static void handle_set_wfi_drv_handler(struct work_struct *work)
        if (ret)
                netdev_err(vif->ndev, "Failed to set driver handler\n");
 
-       complete(&hif_driver_comp);
        kfree(buffer);
 
 free_msg:
+       if (msg->is_sync)
+               complete(&msg->work_comp);
+
        kfree(msg);
 }
 
@@ -343,73 +334,12 @@ static void handle_set_operation_mode(struct work_struct *work)
        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
                                   wilc_get_vif_idx(vif));
 
-       if (hif_op_mode->mode == IDLE_MODE)
-               complete(&hif_driver_comp);
-
        if (ret)
                netdev_err(vif->ndev, "Failed to set operation mode\n");
 
        kfree(msg);
 }
 
-static void handle_set_ip_address(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_vif *vif = msg->vif;
-       u8 *ip_addr = msg->body.ip_info.ip_addr;
-       u8 idx = msg->body.ip_info.idx;
-       int ret;
-       struct wid wid;
-       char firmware_ip_addr[4] = {0};
-
-       if (ip_addr[0] < 192)
-               ip_addr[0] = 0;
-
-       memcpy(set_ip[idx], ip_addr, IP_ALEN);
-
-       wid.id = WID_IP_ADDRESS;
-       wid.type = WID_STR;
-       wid.val = ip_addr;
-       wid.size = IP_ALEN;
-
-       ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
-                                  wilc_get_vif_idx(vif));
-
-       host_int_get_ipaddress(vif, firmware_ip_addr, idx);
-
-       if (ret)
-               netdev_err(vif->ndev, "Failed to set IP address\n");
-       kfree(msg);
-}
-
-static void handle_get_ip_address(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-       struct wilc_vif *vif = msg->vif;
-       u8 idx = msg->body.ip_info.idx;
-       int ret;
-       struct wid wid;
-
-       wid.id = WID_IP_ADDRESS;
-       wid.type = WID_STR;
-       wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
-       wid.size = IP_ALEN;
-
-       ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
-                                  wilc_get_vif_idx(vif));
-
-       memcpy(get_ip[idx], wid.val, IP_ALEN);
-
-       kfree(wid.val);
-
-       if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
-               wilc_setup_ipaddress(vif, set_ip[idx], idx);
-
-       if (ret)
-               netdev_err(vif->ndev, "Failed to get IP address\n");
-       kfree(msg);
-}
-
 static void handle_get_mac_address(struct work_struct *work)
 {
        struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -791,7 +721,7 @@ static void handle_scan(struct work_struct *work)
                goto error;
        }
 
-       if (wilc_optaining_ip || wilc_connecting) {
+       if (vif->obtaining_ip || vif->connecting) {
                netdev_err(vif->ndev, "Don't do obss scan\n");
                result = -EBUSY;
                goto error;
@@ -883,7 +813,6 @@ error:
        kfree(msg);
 }
 
-u8 wilc_connected_ssid[6] = {0};
 static void handle_connect(struct work_struct *work)
 {
        struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -905,11 +834,6 @@ static void handle_connect(struct work_struct *work)
                return;
        }
 
-       if (memcmp(conn_attr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
-               netdev_err(vif->ndev, "Discard connect request\n");
-               goto error;
-       }
-
        bss_param = conn_attr->params;
        if (!bss_param) {
                netdev_err(vif->ndev, "Required BSSID not found\n");
@@ -1089,10 +1013,6 @@ static void handle_connect(struct work_struct *work)
        cur_byte = wid_list[wid_cnt].val;
        wid_cnt++;
 
-       if (conn_attr->bssid)
-               memcpy(wilc_connected_ssid,
-                      conn_attr->bssid, ETH_ALEN);
-
        result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
                                      wid_cnt,
                                      wilc_get_vif_idx(vif));
@@ -1215,8 +1135,6 @@ static void handle_connect_timeout(struct work_struct *work)
        kfree(hif_drv->usr_conn_req.ies);
        hif_drv->usr_conn_req.ies = NULL;
 
-       eth_zero_addr(wilc_connected_ssid);
-
 out:
        kfree(msg);
 }
@@ -1456,10 +1374,10 @@ done:
        kfree(msg);
 }
 
-static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
-                                      u8 *assoc_resp_info,
-                                      u32 max_assoc_resp_info_len,
-                                      u32 *rcvd_assoc_resp_info_len)
+static void host_int_get_assoc_res_info(struct wilc_vif *vif,
+                                       u8 *assoc_resp_info,
+                                       u32 max_assoc_resp_info_len,
+                                       u32 *rcvd_assoc_resp_info_len)
 {
        int result;
        struct wid wid;
@@ -1474,11 +1392,10 @@ static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
        if (result) {
                *rcvd_assoc_resp_info_len = 0;
                netdev_err(vif->ndev, "Failed to send association response\n");
-               return -EINVAL;
+               return;
        }
 
        *rcvd_assoc_resp_info_len = wid.size;
-       return result;
 }
 
 static inline void host_int_free_user_conn_req(struct host_if_drv *hif_drv)
@@ -1504,16 +1421,16 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
        if (mac_status == MAC_STATUS_CONNECTED) {
                u32 assoc_resp_info_len;
 
-               memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
+               memset(hif_drv->assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
 
-               host_int_get_assoc_res_info(vif, rcv_assoc_resp,
+               host_int_get_assoc_res_info(vif, hif_drv->assoc_resp,
                                            MAX_ASSOC_RESP_FRAME_SIZE,
                                            &assoc_resp_info_len);
 
                if (assoc_resp_info_len != 0) {
                        s32 err = 0;
 
-                       err = wilc_parse_assoc_resp_info(rcv_assoc_resp,
+                       err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp,
                                                         assoc_resp_info_len,
                                                         &conn_info);
                        if (err)
@@ -1523,16 +1440,6 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
                }
        }
 
-       if (mac_status == MAC_STATUS_CONNECTED &&
-           conn_info.status != WLAN_STATUS_SUCCESS) {
-               netdev_err(vif->ndev,
-                          "Received MAC status is MAC_STATUS_CONNECTED, Assoc Resp is not SUCCESS\n");
-               eth_zero_addr(wilc_connected_ssid);
-       } else if (mac_status == MAC_STATUS_DISCONNECTED)    {
-               netdev_err(vif->ndev, "Received MAC status is MAC_STATUS_DISCONNECTED\n");
-               eth_zero_addr(wilc_connected_ssid);
-       }
-
        if (hif_drv->usr_conn_req.bssid) {
                memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6);
 
@@ -1562,8 +1469,8 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
 
                hif_drv->hif_state = HOST_IF_CONNECTED;
 
-               wilc_optaining_ip = true;
-               mod_timer(&wilc_during_ip_timer,
+               vif->obtaining_ip = true;
+               mod_timer(&vif->during_ip_timer,
                          jiffies + msecs_to_jiffies(10000));
        } else {
                hif_drv->hif_state = HOST_IF_IDLE;
@@ -1595,7 +1502,7 @@ static inline void host_int_handle_disconnect(struct wilc_vif *vif)
        disconn_info.ie_len = 0;
 
        if (conn_result) {
-               wilc_optaining_ip = false;
+               vif->obtaining_ip = false;
                wilc_set_power_mgmt(vif, 0, 0);
 
                conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, 0,
@@ -1942,11 +1849,9 @@ static void handle_disconnect(struct work_struct *work)
        wid.val = (s8 *)&dummy_reason_code;
        wid.size = sizeof(char);
 
-       wilc_optaining_ip = false;
+       vif->obtaining_ip = false;
        wilc_set_power_mgmt(vif, 0, 0);
 
-       eth_zero_addr(wilc_connected_ssid);
-
        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
                                      wilc_get_vif_idx(vif));
 
@@ -2076,9 +1981,9 @@ static void handle_get_statistics(struct work_struct *work)
 
        if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
            stats->link_speed != DEFAULT_LINK_SPEED)
-               wilc_enable_tcp_ack_filter(true);
+               wilc_enable_tcp_ack_filter(vif, true);
        else if (stats->link_speed != DEFAULT_LINK_SPEED)
-               wilc_enable_tcp_ack_filter(false);
+               wilc_enable_tcp_ack_filter(vif, false);
 
        /* free 'msg' for async command, for sync caller will free it */
        if (msg->is_sync)
@@ -2397,7 +2302,7 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
                goto error;
        }
 
-       if (wilc_optaining_ip || wilc_connecting) {
+       if (vif->obtaining_ip || vif->connecting) {
                result = -EBUSY;
                goto error;
        }
@@ -2422,7 +2327,6 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
                netdev_err(vif->ndev, "Failed to set remain on channel\n");
 
 error:
-       p2p_listen_state = 1;
        hif_drv->remain_on_ch_timer_vif = vif;
        mod_timer(&hif_drv->remain_on_ch_timer,
                  jiffies + msecs_to_jiffies(hif_remain_ch->duration));
@@ -2478,8 +2382,9 @@ static void handle_listen_state_expired(struct work_struct *work)
        struct wid wid;
        int result;
        struct host_if_drv *hif_drv = vif->hif_drv;
+       struct wilc_priv *priv = wdev_priv(vif->ndev->ieee80211_ptr);
 
-       if (p2p_listen_state) {
+       if (priv->p2p_listen_state) {
                remain_on_chan_flag = false;
                wid.id = WID_REMAIN_ON_CHAN;
                wid.type = WID_STR;
@@ -2504,7 +2409,6 @@ static void handle_listen_state_expired(struct work_struct *work)
                        hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
                                                      hif_remain_ch->id);
                }
-               p2p_listen_state = 0;
        } else {
                netdev_dbg(vif->ndev, "Not in listen state\n");
        }
@@ -2589,8 +2493,8 @@ static void handle_set_mcast_filter(struct work_struct *work)
        *cur_byte++ = ((hif_set_mc->cnt >> 16) & 0xFF);
        *cur_byte++ = ((hif_set_mc->cnt >> 24) & 0xFF);
 
-       if (hif_set_mc->cnt > 0)
-               memcpy(cur_byte, wilc_multicast_mac_addr_list,
+       if (hif_set_mc->cnt > 0 && hif_set_mc->mc_list)
+               memcpy(cur_byte, hif_set_mc->mc_list,
                       ((hif_set_mc->cnt) * ETH_ALEN));
 
        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
@@ -2599,6 +2503,7 @@ static void handle_set_mcast_filter(struct work_struct *work)
                netdev_err(vif->ndev, "Failed to send setup multicast\n");
 
 error:
+       kfree(hif_set_mc->mc_list);
        kfree(wid.val);
        kfree(msg);
 }
@@ -2661,14 +2566,6 @@ static void handle_remain_on_chan_work(struct work_struct *work)
        kfree(msg);
 }
 
-static void handle_hif_exit_work(struct work_struct *work)
-{
-       struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-
-       /* free 'msg' data in caller */
-       complete(&msg->work_comp);
-}
-
 static void handle_scan_complete(struct work_struct *work)
 {
        struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -3195,12 +3092,12 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
 }
 
 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
-                            u8 ifc_id)
+                            u8 ifc_id, bool is_sync)
 {
        int result;
        struct host_if_msg *msg;
 
-       msg = wilc_alloc_work(vif, handle_set_wfi_drv_handler, false);
+       msg = wilc_alloc_work(vif, handle_set_wfi_drv_handler, is_sync);
        if (IS_ERR(msg))
                return PTR_ERR(msg);
 
@@ -3212,8 +3109,12 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
        if (result) {
                netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
                kfree(msg);
+               return result;
        }
 
+       if (is_sync)
+               wait_for_completion(&msg->work_comp);
+
        return result;
 }
 
@@ -3421,9 +3322,9 @@ int wilc_hif_set_cfg(struct wilc_vif *vif,
        return result;
 }
 
-static void get_periodic_rssi(struct timer_list *unused)
+static void get_periodic_rssi(struct timer_list *t)
 {
-       struct wilc_vif *vif = periodic_rssi_vif;
+       struct wilc_vif *vif = from_timer(vif, t, periodic_rssi);
 
        if (!vif->hif_drv) {
                netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
@@ -3431,9 +3332,9 @@ static void get_periodic_rssi(struct timer_list *unused)
        }
 
        if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
-               wilc_get_statistics(vif, &vif->wilc->dummy_statistics, false);
+               wilc_get_statistics(vif, &vif->periodic_stat, false);
 
-       mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
+       mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
 }
 
 int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
@@ -3455,25 +3356,13 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
                        break;
                }
 
-       wilc_optaining_ip = false;
+       vif->obtaining_ip = false;
 
-       if (clients_count == 0) {
-               init_completion(&hif_driver_comp);
+       if (wilc->clients_count == 0)
                mutex_init(&hif_deinit_lock);
-       }
 
-       if (clients_count == 0) {
-               hif_workqueue = create_singlethread_workqueue("WILC_wq");
-               if (!hif_workqueue) {
-                       netdev_err(vif->ndev, "Failed to create workqueue\n");
-                       kfree(hif_drv);
-                       return -ENOMEM;
-               }
-
-               periodic_rssi_vif = vif;
-               timer_setup(&periodic_rssi, get_periodic_rssi, 0);
-               mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
-       }
+       timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0);
+       mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000));
 
        timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0);
        timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0);
@@ -3493,7 +3382,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
 
        mutex_unlock(&hif_drv->cfg_values_lock);
 
-       clients_count++;
+       wilc->clients_count++;
 
        return 0;
 }
@@ -3514,11 +3403,10 @@ int wilc_deinit(struct wilc_vif *vif)
 
        del_timer_sync(&hif_drv->scan_timer);
        del_timer_sync(&hif_drv->connect_timer);
-       del_timer_sync(&periodic_rssi);
+       del_timer_sync(&vif->periodic_rssi);
        del_timer_sync(&hif_drv->remain_on_ch_timer);
 
-       wilc_set_wfi_drv_handler(vif, 0, 0, 0);
-       wait_for_completion(&hif_driver_comp);
+       wilc_set_wfi_drv_handler(vif, 0, 0, 0, true);
 
        if (hif_drv->usr_scan_req.scan_result) {
                hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
@@ -3529,25 +3417,9 @@ int wilc_deinit(struct wilc_vif *vif)
 
        hif_drv->hif_state = HOST_IF_IDLE;
 
-       if (clients_count == 1) {
-               struct host_if_msg *msg;
-
-               msg = wilc_alloc_work(vif, handle_hif_exit_work, true);
-               if (!IS_ERR(msg)) {
-                       result = wilc_enqueue_work(msg);
-                       if (result)
-                               netdev_err(vif->ndev, "deinit : Error(%d)\n",
-                                          result);
-                       else
-                               wait_for_completion(&msg->work_comp);
-                       kfree(msg);
-               }
-               destroy_workqueue(hif_workqueue);
-       }
-
        kfree(hif_drv);
 
-       clients_count--;
+       vif->wilc->clients_count--;
        terminated_handle = NULL;
        mutex_unlock(&hif_deinit_lock);
        return result;
@@ -3743,14 +3615,14 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
        return result;
 }
 
-int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
+void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
 {
        int result;
        struct host_if_msg *msg;
 
        msg = wilc_alloc_work(vif, handle_register_frame, false);
        if (IS_ERR(msg))
-               return PTR_ERR(msg);
+               return;
 
        switch (frame_type) {
        case ACTION:
@@ -3772,8 +3644,6 @@ int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
                netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
                kfree(msg);
        }
-
-       return result;
 }
 
 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
@@ -3992,8 +3862,8 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
        return result;
 }
 
-int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
-                               u32 count)
+int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count,
+                               u8 *mc_list)
 {
        int result;
        struct host_if_msg *msg;
@@ -4004,6 +3874,7 @@ int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
 
        msg->body.multicast_info.enabled = enabled;
        msg->body.multicast_info.cnt = count;
+       msg->body.multicast_info.mc_list = mc_list;
 
        result = wilc_enqueue_work(msg);
        if (result) {
@@ -4013,48 +3884,6 @@ int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
        return result;
 }
 
-int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
-{
-       int result;
-       struct host_if_msg *msg;
-
-       msg = wilc_alloc_work(vif, handle_set_ip_address, false);
-       if (IS_ERR(msg))
-               return PTR_ERR(msg);
-
-       msg->body.ip_info.ip_addr = ip_addr;
-       msg->body.ip_info.idx = idx;
-
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg);
-       }
-
-       return result;
-}
-
-static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
-{
-       int result;
-       struct host_if_msg *msg;
-
-       msg = wilc_alloc_work(vif, handle_get_ip_address, false);
-       if (IS_ERR(msg))
-               return PTR_ERR(msg);
-
-       msg->body.ip_info.ip_addr = ip_addr;
-       msg->body.ip_info.idx = idx;
-
-       result = wilc_enqueue_work(msg);
-       if (result) {
-               netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-               kfree(msg);
-       }
-
-       return result;
-}
-
 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
 {
        int ret;
index 84866a62a4d4290524defdc523c9d1eddbe11d6d..33fb7318734b51944f2d56c0ca0d0661817eb003 100644 (file)
@@ -9,8 +9,6 @@
 #include <linux/ieee80211.h>
 #include "coreconfigurator.h"
 
-#define IP_ALEN  4
-
 #define IDLE_MODE      0x00
 #define AP_MODE                0x01
 #define STATION_MODE   0x02
@@ -284,6 +282,7 @@ struct host_if_drv {
 
        bool ifc_up;
        int driver_handler_id;
+       u8 assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
 };
 
 struct add_sta_param {
@@ -341,18 +340,17 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr);
 int wilc_edit_station(struct wilc_vif *vif,
                      struct add_sta_param *sta_param);
 int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout);
-int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
-                               u32 count);
-int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
+int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count,
+                               u8 *mc_list);
 int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
                           u32 duration, u16 chan,
                           wilc_remain_on_chan_expired expired,
                           wilc_remain_on_chan_ready ready,
                           void *user_arg);
 int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id);
-int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg);
+void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg);
 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
-                            u8 ifc_id);
+                            u8 ifc_id, bool is_sync);
 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode);
 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats,
                        bool is_sync);
@@ -361,11 +359,4 @@ int wilc_get_vif_idx(struct wilc_vif *vif);
 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power);
 int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power);
 
-extern bool wilc_optaining_ip;
-extern u8 wilc_connected_ssid[6];
-extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
-
-extern int wilc_connecting;
-extern struct timer_list wilc_during_ip_timer;
-
 #endif
index 1afdb9e86bc1a466f73176a421af4540152bfaa2..a63446818eac0c82efe506675ba5965ff2e8b872 100644 (file)
@@ -253,7 +253,7 @@ struct net_device *wilc_wfi_init_mon_interface(const char *name,
        return wilc_wfi_mon;
 }
 
-int wilc_wfi_deinit_mon_interface(void)
+void wilc_wfi_deinit_mon_interface(void)
 {
        bool rollback_lock = false;
 
@@ -270,5 +270,4 @@ int wilc_wfi_deinit_mon_interface(void)
                }
                wilc_wfi_mon = NULL;
        }
-       return 0;
 }
index 3b8d237decbf179b7016242583909fc46146c99c..76c901235e93e5bed908698a446bfdcf26f0a766 100644 (file)
@@ -12,8 +12,6 @@
 
 #include "wilc_wfi_cfgoperations.h"
 
-bool wilc_enable_ps = true;
-
 static int dev_state_ev_handler(struct notifier_block *this,
                                unsigned long event, void *ptr)
 {
@@ -50,11 +48,11 @@ static int dev_state_ev_handler(struct notifier_block *this,
        case NETDEV_UP:
                if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
                        hif_drv->ifc_up = 1;
-                       wilc_optaining_ip = false;
-                       del_timer(&wilc_during_ip_timer);
+                       vif->obtaining_ip = false;
+                       del_timer(&vif->during_ip_timer);
                }
 
-               if (wilc_enable_ps)
+               if (vif->wilc->enable_ps)
                        wilc_set_power_mgmt(vif, 1, 0);
 
                netdev_dbg(dev, "[%s] Up IP\n", dev_iface->ifa_label);
@@ -63,14 +61,13 @@ static int dev_state_ev_handler(struct notifier_block *this,
                netdev_dbg(dev, "IP add=%d:%d:%d:%d\n",
                           ip_addr_buf[0], ip_addr_buf[1],
                           ip_addr_buf[2], ip_addr_buf[3]);
-               wilc_setup_ipaddress(vif, ip_addr_buf, vif->idx);
 
                break;
 
        case NETDEV_DOWN:
                if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) {
                        hif_drv->ifc_up = 0;
-                       wilc_optaining_ip = false;
+                       vif->obtaining_ip = false;
                }
 
                if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0)
@@ -85,8 +82,6 @@ static int dev_state_ev_handler(struct notifier_block *this,
                           ip_addr_buf[0], ip_addr_buf[1],
                           ip_addr_buf[2], ip_addr_buf[3]);
 
-               wilc_setup_ipaddress(vif, ip_addr_buf, vif->idx);
-
                break;
 
        default:
@@ -164,9 +159,9 @@ static void deinit_irq(struct net_device *dev)
 
 void wilc_mac_indicate(struct wilc *wilc)
 {
-       int status;
+       s8 status;
 
-       wilc_wlan_cfg_get_val(WID_STATUS, (unsigned char *)&status, 4);
+       wilc_wlan_cfg_get_val(wilc, WID_STATUS, &status, 1);
        if (wilc->mac_status == MAC_STATUS_INIT) {
                wilc->mac_status = status;
                complete(&wilc->sync_event);
@@ -197,14 +192,12 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
        return NULL;
 }
 
-int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
+void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
 {
        struct wilc_vif *vif = netdev_priv(wilc_netdev);
 
        memcpy(vif->bssid, bssid, 6);
        vif->mode = mode;
-
-       return 0;
 }
 
 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
@@ -269,9 +262,6 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
 
        netdev_info(dev, "loading firmware %s\n", firmware);
 
-       if (!(&vif->ndev->dev))
-               goto fail;
-
        if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) {
                netdev_err(dev, "%s - firmware not available\n", firmware);
                ret = -1;
@@ -532,7 +522,7 @@ fail:
        return -1;
 }
 
-static int wlan_deinit_locks(struct net_device *dev)
+static void wlan_deinit_locks(struct net_device *dev)
 {
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
@@ -540,8 +530,6 @@ static int wlan_deinit_locks(struct net_device *dev)
        mutex_destroy(&wilc->hif_cs);
        mutex_destroy(&wilc->rxq_cs);
        mutex_destroy(&wilc->txq_add_to_head_cs);
-
-       return 0;
 }
 
 static void wlan_deinitialize_threads(struct net_device *dev)
@@ -595,7 +583,7 @@ static void wilc_wlan_deinitialize(struct net_device *dev)
        }
 }
 
-static int wlan_init_locks(struct net_device *dev)
+static void wlan_init_locks(struct net_device *dev)
 {
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wl = vif->wilc;
@@ -611,8 +599,6 @@ static int wlan_init_locks(struct net_device *dev)
        init_completion(&wl->cfg_event);
        init_completion(&wl->sync_event);
        init_completion(&wl->txq_thread_started);
-
-       return 0;
 }
 
 static int wlan_initialize_threads(struct net_device *dev)
@@ -688,7 +674,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
                        int size;
                        char firmware_ver[20];
 
-                       size = wilc_wlan_cfg_get_val(WID_FIRMWARE_VERSION,
+                       size = wilc_wlan_cfg_get_val(wl, WID_FIRMWARE_VERSION,
                                                     firmware_ver,
                                                     sizeof(firmware_ver));
                        firmware_ver[size] = '\0';
@@ -740,6 +726,7 @@ static int wilc_mac_open(struct net_device *ndev)
 {
        struct wilc_vif *vif = netdev_priv(ndev);
        struct wilc *wl = vif->wilc;
+       struct wilc_priv *priv = wdev_priv(vif->ndev->ieee80211_ptr);
        unsigned char mac_add[ETH_ALEN] = {0};
        int ret = 0;
        int i = 0;
@@ -764,7 +751,8 @@ static int wilc_mac_open(struct net_device *ndev)
        for (i = 0; i < wl->vif_num; i++) {
                if (ndev == wl->vif[i]->ndev) {
                        wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
-                                                vif->iftype, vif->ifc_id);
+                                                vif->iftype, vif->ifc_id,
+                                                false);
                        wilc_set_operation_mode(vif, vif->iftype);
                        break;
                }
@@ -792,6 +780,7 @@ static int wilc_mac_open(struct net_device *ndev)
                                 vif->frame_reg[1].reg);
        netif_wake_queue(ndev);
        wl->open_ifcs++;
+       priv->p2p.local_random = 0x01;
        vif->mac_opened = 1;
        return 0;
 }
@@ -807,35 +796,39 @@ static void wilc_set_multicast_list(struct net_device *dev)
 {
        struct netdev_hw_addr *ha;
        struct wilc_vif *vif = netdev_priv(dev);
-       int i = 0;
+       int i;
+       u8 *mc_list;
+       u8 *cur_mc;
 
        if (dev->flags & IFF_PROMISC)
                return;
 
        if (dev->flags & IFF_ALLMULTI ||
            dev->mc.count > WILC_MULTICAST_TABLE_SIZE) {
-               wilc_setup_multicast_filter(vif, false, 0);
+               wilc_setup_multicast_filter(vif, false, 0, NULL);
                return;
        }
 
        if (dev->mc.count == 0) {
-               wilc_setup_multicast_filter(vif, true, 0);
+               wilc_setup_multicast_filter(vif, true, 0, NULL);
                return;
        }
 
+       mc_list = kmalloc_array(dev->mc.count, ETH_ALEN, GFP_KERNEL);
+       if (!mc_list)
+               return;
+
+       cur_mc = mc_list;
+       i = 0;
        netdev_for_each_mc_addr(ha, dev) {
-               memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN);
-               netdev_dbg(dev, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i,
-                          wilc_multicast_mac_addr_list[i][0],
-                          wilc_multicast_mac_addr_list[i][1],
-                          wilc_multicast_mac_addr_list[i][2],
-                          wilc_multicast_mac_addr_list[i][3],
-                          wilc_multicast_mac_addr_list[i][4],
-                          wilc_multicast_mac_addr_list[i][5]);
+               memcpy(cur_mc, ha->addr, ETH_ALEN);
+               netdev_dbg(dev, "Entry[%d]: %pM\n", i, cur_mc);
                i++;
+               cur_mc += ETH_ALEN;
        }
 
-       wilc_setup_multicast_filter(vif, true, (dev->mc.count));
+       if (wilc_setup_multicast_filter(vif, true, dev->mc.count, mc_list))
+               kfree(mc_list);
 }
 
 static void linux_wlan_tx_complete(void *priv, int status)
@@ -1016,15 +1009,18 @@ void wilc_netdev_cleanup(struct wilc *wilc)
 {
        int i;
 
-       if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev))
+       if (!wilc)
+               return;
+
+       if (wilc->vif[0]->ndev || wilc->vif[1]->ndev)
                unregister_inetaddr_notifier(&g_dev_notifier);
 
-       if (wilc && wilc->firmware) {
+       if (wilc->firmware) {
                release_firmware(wilc->firmware);
                wilc->firmware = NULL;
        }
 
-       if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) {
+       if (wilc->vif[0]->ndev || wilc->vif[1]->ndev) {
                for (i = 0; i < NUM_CONCURRENT_IFC; i++)
                        if (wilc->vif[i]->ndev)
                                if (wilc->vif[i]->mac_opened)
@@ -1037,6 +1033,10 @@ void wilc_netdev_cleanup(struct wilc *wilc)
                }
        }
 
+       flush_workqueue(wilc->hif_workqueue);
+       destroy_workqueue(wilc->hif_workqueue);
+       wilc_wlan_cfg_deinit(wilc);
+       kfree(wilc->bus_data);
        kfree(wilc);
 }
 EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
@@ -1062,20 +1062,34 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
        if (!wl)
                return -ENOMEM;
 
+       ret = wilc_wlan_cfg_init(wl);
+       if (ret)
+               goto free_wl;
+
        *wilc = wl;
        wl->io_type = io_type;
        wl->hif_func = ops;
+       wl->enable_ps = true;
+       wl->chip_ps_state = CHIP_WAKEDUP;
        INIT_LIST_HEAD(&wl->txq_head.list);
        INIT_LIST_HEAD(&wl->rxq_head.list);
 
+       wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
+       if (!wl->hif_workqueue) {
+               ret = -ENOMEM;
+               goto free_cfg;
+       }
+
        register_inetaddr_notifier(&g_dev_notifier);
 
        for (i = 0; i < NUM_CONCURRENT_IFC; i++) {
                struct wireless_dev *wdev;
 
                ndev = alloc_etherdev(sizeof(struct wilc_vif));
-               if (!ndev)
-                       return -ENOMEM;
+               if (!ndev) {
+                       ret = -ENOMEM;
+                       goto free_ndev;
+               }
 
                vif = netdev_priv(ndev);
                memset(vif, 0, sizeof(struct wilc_vif));
@@ -1096,15 +1110,14 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
                ndev->netdev_ops = &wilc_netdev_ops;
 
                wdev = wilc_create_wiphy(ndev, dev);
-
-               if (dev)
-                       SET_NETDEV_DEV(ndev, dev);
-
                if (!wdev) {
                        netdev_err(ndev, "Can't register WILC Wiphy\n");
-                       return -1;
+                       ret = -ENOMEM;
+                       goto free_ndev;
                }
 
+               SET_NETDEV_DEV(ndev, dev);
+
                vif->ndev->ieee80211_ptr = wdev;
                vif->ndev->ml_priv = vif;
                wdev->netdev = vif->ndev;
@@ -1115,13 +1128,33 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
 
                ret = register_netdev(ndev);
                if (ret)
-                       return ret;
+                       goto free_ndev;
 
                vif->iftype = STATION_MODE;
                vif->mac_opened = 0;
        }
 
        return 0;
+
+free_ndev:
+       for (; i >= 0; i--) {
+               if (wl->vif[i]) {
+                       if (wl->vif[i]->iftype == STATION_MODE)
+                               unregister_netdev(wl->vif[i]->ndev);
+
+                       if (wl->vif[i]->ndev) {
+                               wilc_free_wiphy(wl->vif[i]->ndev);
+                               free_netdev(wl->vif[i]->ndev);
+                       }
+               }
+       }
+       unregister_inetaddr_notifier(&g_dev_notifier);
+       destroy_workqueue(wl->hif_workqueue);
+free_cfg:
+       wilc_wlan_cfg_deinit(wl);
+free_wl:
+       kfree(wl);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(wilc_netdev_init);
 
diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c
deleted file mode 100644 (file)
index 8001df6..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
- * All rights reserved.
- */
-
-#if defined(WILC_DEBUGFS)
-#include <linux/module.h>
-#include <linux/debugfs.h>
-
-#include "wilc_wlan_if.h"
-
-static struct dentry *wilc_dir;
-
-#define DEBUG           BIT(0)
-#define INFO            BIT(1)
-#define WRN             BIT(2)
-#define ERR             BIT(3)
-
-#define DBG_LEVEL_ALL  (DEBUG | INFO | WRN | ERR)
-static atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
-EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
-
-static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf,
-                                    size_t count, loff_t *ppos)
-{
-       char buf[128];
-       int res = 0;
-
-       /* only allow read from start */
-       if (*ppos > 0)
-               return 0;
-
-       res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n",
-                       atomic_read(&WILC_DEBUG_LEVEL));
-
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-static ssize_t wilc_debug_level_write(struct file *filp,
-                                     const char __user *buf, size_t count,
-                                     loff_t *ppos)
-{
-       int flag = 0;
-       int ret;
-
-       ret = kstrtouint_from_user(buf, count, 16, &flag);
-       if (ret)
-               return ret;
-
-       if (flag > DBG_LEVEL_ALL) {
-               pr_info("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n",
-                       __func__, flag, atomic_read(&WILC_DEBUG_LEVEL));
-               return -EINVAL;
-       }
-
-       atomic_set(&WILC_DEBUG_LEVEL, (int)flag);
-
-       if (flag == 0)
-               pr_info("Debug-level disabled\n");
-       else
-               pr_info("Debug-level enabled\n");
-
-       return count;
-}
-
-#define FOPS(_open, _read, _write, _poll) { \
-               .owner  = THIS_MODULE, \
-               .open   = (_open), \
-               .read   = (_read), \
-               .write  = (_write), \
-               .poll           = (_poll), \
-}
-
-struct wilc_debugfs_info_t {
-       const char *name;
-       int perm;
-       unsigned int data;
-       const struct file_operations fops;
-};
-
-static struct wilc_debugfs_info_t debugfs_info[] = {
-       {
-               "wilc_debug_level",
-               0666,
-               (DEBUG | ERR),
-               FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL),
-       },
-};
-
-static int __init wilc_debugfs_init(void)
-{
-       int i;
-       struct wilc_debugfs_info_t *info;
-
-       wilc_dir = debugfs_create_dir("wilc_wifi", NULL);
-       for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) {
-               info = &debugfs_info[i];
-               debugfs_create_file(info->name,
-                                   info->perm,
-                                   wilc_dir,
-                                   &info->data,
-                                   &info->fops);
-       }
-       return 0;
-}
-module_init(wilc_debugfs_init);
-
-static void __exit wilc_debugfs_remove(void)
-{
-       debugfs_remove_recursive(wilc_dir);
-}
-module_exit(wilc_debugfs_remove);
-
-#endif
index b2080d8b801f872496afe36a2ec2a1ee29b7febc..ca351c95034498e3c470cbb9991576c34464c7eb 100644 (file)
@@ -30,7 +30,6 @@ struct wilc_sdio {
        int has_thrpt_enh3;
 };
 
-static struct wilc_sdio g_sdio;
 static const struct wilc_hif_func wilc_hif_sdio;
 
 static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data);
@@ -109,6 +108,11 @@ static int linux_sdio_probe(struct sdio_func *func,
        struct wilc *wilc;
        int ret;
        struct gpio_desc *gpio = NULL;
+       struct wilc_sdio *sdio_priv;
+
+       sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL);
+       if (!sdio_priv)
+               return -ENOMEM;
 
        if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
                gpio = gpiod_get(&func->dev, "irq", GPIOD_IN);
@@ -124,9 +128,11 @@ static int linux_sdio_probe(struct sdio_func *func,
        ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, &wilc_hif_sdio);
        if (ret) {
                dev_err(&func->dev, "Couldn't initialize netdev\n");
+               kfree(sdio_priv);
                return ret;
        }
        sdio_set_drvdata(func, wilc);
+       wilc->bus_data = sdio_priv;
        wilc->dev = &func->dev;
        wilc->gpio_irq = gpio;
 
@@ -381,6 +387,7 @@ fail:
 static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
        int ret;
 
        cpu_to_le32s(&data);
@@ -415,7 +422,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
                cmd.increment = 1;
                cmd.count = 4;
                cmd.buffer = (u8 *)&data;
-               cmd.block_size = g_sdio.block_size;
+               cmd.block_size = sdio_priv->block_size;
                ret = wilc_sdio_cmd53(wilc, &cmd);
                if (ret) {
                        dev_err(&func->dev,
@@ -434,7 +441,8 @@ fail:
 static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       u32 block_size = g_sdio.block_size;
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       u32 block_size = sdio_priv->block_size;
        struct sdio_cmd53 cmd;
        int nblk, nleft, ret;
 
@@ -523,6 +531,7 @@ fail:
 static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
        int ret;
 
        if (addr >= 0xf0 && addr <= 0xff) {
@@ -553,7 +562,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
                cmd.count = 4;
                cmd.buffer = (u8 *)data;
 
-               cmd.block_size = g_sdio.block_size;
+               cmd.block_size = sdio_priv->block_size;
                ret = wilc_sdio_cmd53(wilc, &cmd);
                if (ret) {
                        dev_err(&func->dev,
@@ -574,7 +583,8 @@ fail:
 static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
-       u32 block_size = g_sdio.block_size;
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
+       u32 block_size = sdio_priv->block_size;
        struct sdio_cmd53 cmd;
        int nblk, nleft, ret;
 
@@ -674,14 +684,13 @@ static int sdio_deinit(struct wilc *wilc)
 static int sdio_init(struct wilc *wilc, bool resume)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
        struct sdio_cmd52 cmd;
        int loop, ret;
        u32 chipid;
 
-       if (!resume) {
-               memset(&g_sdio, 0, sizeof(struct wilc_sdio));
-               g_sdio.irq_gpio = wilc->dev_irq_num;
-       }
+       if (!resume)
+               sdio_priv->irq_gpio = wilc->dev_irq_num;
 
        /**
         *      function 0 csa enable
@@ -704,7 +713,7 @@ static int sdio_init(struct wilc *wilc, bool resume)
                dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
                goto fail;
        }
-       g_sdio.block_size = WILC_SDIO_BLOCK_SIZE;
+       sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;
 
        /**
         *      enable func1 IO
@@ -778,11 +787,11 @@ static int sdio_init(struct wilc *wilc, bool resume)
                }
                dev_err(&func->dev, "chipid (%08x)\n", chipid);
                if ((chipid & 0xfff) > 0x2a0)
-                       g_sdio.has_thrpt_enh3 = 1;
+                       sdio_priv->has_thrpt_enh3 = 1;
                else
-                       g_sdio.has_thrpt_enh3 = 0;
+                       sdio_priv->has_thrpt_enh3 = 0;
                dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
-                        g_sdio.has_thrpt_enh3);
+                        sdio_priv->has_thrpt_enh3);
        }
 
        return 1;
@@ -820,6 +829,7 @@ static int sdio_read_size(struct wilc *wilc, u32 *size)
 static int sdio_read_int(struct wilc *wilc, u32 *int_status)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
        u32 tmp;
        struct sdio_cmd52 cmd;
 
@@ -828,7 +838,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status)
        /**
         *      Read IRQ flags
         **/
-       if (!g_sdio.irq_gpio) {
+       if (!sdio_priv->irq_gpio) {
                int i;
 
                cmd.function = 1;
@@ -848,7 +858,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status)
                        tmp |= INT_4;
                if (cmd.data & BIT(6))
                        tmp |= INT_5;
-               for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
+               for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) {
                        if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
                                dev_err(&func->dev,
                                        "Unexpected interrupt (1) : tmp=%x, data=%x\n",
@@ -877,13 +887,14 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status)
 static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
        int ret;
        int vmm_ctl;
 
-       if (g_sdio.has_thrpt_enh3) {
+       if (sdio_priv->has_thrpt_enh3) {
                u32 reg;
 
-               if (g_sdio.irq_gpio) {
+               if (sdio_priv->irq_gpio) {
                        u32 flags;
 
                        flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
@@ -919,7 +930,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
                }
                return 1;
        }
-       if (g_sdio.irq_gpio) {
+       if (sdio_priv->irq_gpio) {
                /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
                /*
                 * Cannot clear multiple interrupts.
@@ -932,7 +943,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
                        int i;
 
                        ret = 1;
-                       for (i = 0; i < g_sdio.nint; i++) {
+                       for (i = 0; i < sdio_priv->nint; i++) {
                                if (flags & 1) {
                                        struct sdio_cmd52 cmd;
 
@@ -956,7 +967,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
                        }
                        if (!ret)
                                goto fail;
-                       for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
+                       for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) {
                                if (flags & 1)
                                        dev_err(&func->dev,
                                                "Unexpected interrupt cleared %d...\n",
@@ -1001,6 +1012,7 @@ fail:
 static int sdio_sync_ext(struct wilc *wilc, int nint)
 {
        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
+       struct wilc_sdio *sdio_priv = wilc->bus_data;
        u32 reg;
 
        if (nint > MAX_NUM_INT) {
@@ -1013,7 +1025,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint)
                return 0;
        }
 
-       g_sdio.nint = nint;
+       sdio_priv->nint = nint;
 
        /**
         *      Disable power sequencer
@@ -1029,7 +1041,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint)
                return 0;
        }
 
-       if (g_sdio.irq_gpio) {
+       if (sdio_priv->irq_gpio) {
                u32 reg;
                int ret, i;
 
index 5517477d875af7d71def392104ed8d550198c8a9..cef127b249fbcbbf0ed347f49a5e6fda0cce72b4 100644 (file)
@@ -14,7 +14,6 @@ struct wilc_spi {
        int has_thrpt_enh;
 };
 
-static struct wilc_spi g_spi;
 static const struct wilc_hif_func wilc_hif_spi;
 
 /********************************************
@@ -107,6 +106,11 @@ static int wilc_bus_probe(struct spi_device *spi)
        int ret;
        struct wilc *wilc;
        struct gpio_desc *gpio;
+       struct wilc_spi *spi_priv;
+
+       spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL);
+       if (!spi_priv)
+               return -ENOMEM;
 
        gpio = gpiod_get(&spi->dev, "irq", GPIOD_IN);
        if (IS_ERR(gpio)) {
@@ -117,11 +121,14 @@ static int wilc_bus_probe(struct spi_device *spi)
        }
 
        ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, &wilc_hif_spi);
-       if (ret)
+       if (ret) {
+               kfree(spi_priv);
                return ret;
+       }
 
        spi_set_drvdata(spi, wilc);
        wilc->dev = &spi->dev;
+       wilc->bus_data = spi_priv;
        wilc->gpio_irq = gpio;
 
        return 0;
@@ -275,6 +282,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                            u8 clockless)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        u8 wb[32], rb[32];
        u8 wix, rix;
        u32 len2;
@@ -375,7 +383,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
        if (result != N_OK)
                return result;
 
-       if (!g_spi.crc_off)
+       if (!spi_priv->crc_off)
                wb[len - 1] = (crc7(0x7f, (const u8 *)&wb[0], len - 1)) << 1;
        else
                len -= 1;
@@ -393,7 +401,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
        } else if (cmd == CMD_INTERNAL_READ || cmd == CMD_SINGLE_READ) {
                int tmp = NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
                        + NUM_DUMMY_BYTES;
-               if (!g_spi.crc_off)
+               if (!spi_priv->crc_off)
                        len2 = len + tmp + NUM_CRC_BYTES;
                else
                        len2 = len + tmp;
@@ -485,7 +493,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        return N_FAIL;
                }
 
-               if (!g_spi.crc_off) {
+               if (!spi_priv->crc_off) {
                        /*
                         * Read Crc
                         */
@@ -527,7 +535,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        /*
                         * Read Crc
                         */
-                       if (!g_spi.crc_off && wilc_spi_rx(wilc, crc, 2)) {
+                       if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
                                dev_err(&spi->dev,
                                        "Failed block crc read, bus err\n");
                                return N_FAIL;
@@ -585,7 +593,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
                        /*
                         * Read Crc
                         */
-                       if (!g_spi.crc_off && wilc_spi_rx(wilc, crc, 2)) {
+                       if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) {
                                dev_err(&spi->dev,
                                        "Failed block crc read, bus err\n");
                                result = N_FAIL;
@@ -602,6 +610,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
 static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        int ix, nbytes;
        int result = 1;
        u8 cmd, order, crc[2] = {0};
@@ -648,7 +657,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
                /*
                 * Write Crc
                 */
-               if (!g_spi.crc_off) {
+               if (!spi_priv->crc_off) {
                        if (wilc_spi_tx(wilc, crc, 2)) {
                                dev_err(&spi->dev, "Failed data block crc write, bus error...\n");
                                result = N_FAIL;
@@ -816,6 +825,7 @@ static int _wilc_spi_deinit(struct wilc *wilc)
 static int wilc_spi_init(struct wilc *wilc, bool resume)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        u32 reg;
        u32 chipid;
        static int isinit;
@@ -828,12 +838,9 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
                return 1;
        }
 
-       memset(&g_spi, 0, sizeof(struct wilc_spi));
-
        /*
         * configure protocol
         */
-       g_spi.crc_off = 0;
 
        /*
         * TODO: We can remove the CRC trials if there is a definite
@@ -845,7 +852,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
                 * Read failed. Try with CRC off. This might happen when module
                 * is removed but chip isn't reset
                 */
-               g_spi.crc_off = 1;
+               spi_priv->crc_off = 1;
                dev_err(&spi->dev,
                        "Failed read with CRC on, retrying with CRC off\n");
                if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
@@ -857,7 +864,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
                        return 0;
                }
        }
-       if (g_spi.crc_off == 0) {
+       if (spi_priv->crc_off == 0) {
                reg &= ~0xc; /* disable crc checking */
                reg &= ~0x70;
                reg |= (0x5 << 4);
@@ -867,7 +874,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
                                __LINE__);
                        return 0;
                }
-               g_spi.crc_off = 1;
+               spi_priv->crc_off = 1;
        }
 
        /*
@@ -878,7 +885,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
                return 0;
        }
 
-       g_spi.has_thrpt_enh = 1;
+       spi_priv->has_thrpt_enh = 1;
 
        isinit = 1;
 
@@ -888,9 +895,10 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
 static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        int ret;
 
-       if (g_spi.has_thrpt_enh) {
+       if (spi_priv->has_thrpt_enh) {
                ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
                                        size);
                *size = *size  & IRQ_DMA_WD_CNT_MASK;
@@ -915,6 +923,7 @@ static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
 static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        int ret;
        u32 tmp;
        u32 byte_cnt;
@@ -923,7 +932,7 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
        u32 irq_flags;
        int k = IRG_FLAGS_OFFSET + 5;
 
-       if (g_spi.has_thrpt_enh) {
+       if (spi_priv->has_thrpt_enh) {
                ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE,
                                        int_status);
                return ret;
@@ -943,12 +952,12 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
                wilc_spi_read_reg(wilc, 0x1a90, &irq_flags);
                tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
 
-               if (g_spi.nint > 5) {
+               if (spi_priv->nint > 5) {
                        wilc_spi_read_reg(wilc, 0x1a94, &irq_flags);
                        tmp |= (((irq_flags >> 0) & 0x7) << k);
                }
 
-               unknown_mask = ~((1ul << g_spi.nint) - 1);
+               unknown_mask = ~((1ul << spi_priv->nint) - 1);
 
                if ((tmp >> IRG_FLAGS_OFFSET) & unknown_mask) {
                        dev_err(&spi->dev,
@@ -968,11 +977,12 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
 static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        int ret;
        u32 flags;
        u32 tbl_ctl;
 
-       if (g_spi.has_thrpt_enh) {
+       if (spi_priv->has_thrpt_enh) {
                ret = spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE,
                                         val);
                return ret;
@@ -983,7 +993,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
                int i;
 
                ret = 1;
-               for (i = 0; i < g_spi.nint; i++) {
+               for (i = 0; i < spi_priv->nint; i++) {
                        /*
                         * No matter what you write 1 or 0,
                         * it will clear interrupt.
@@ -1001,7 +1011,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
                                0x10c8 + i * 4);
                        return ret;
                }
-               for (i = g_spi.nint; i < MAX_NUM_INT; i++) {
+               for (i = spi_priv->nint; i < MAX_NUM_INT; i++) {
                        if (flags & 1)
                                dev_err(&spi->dev,
                                        "Unexpected interrupt cleared %d...\n",
@@ -1041,6 +1051,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val)
 static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
 {
        struct spi_device *spi = to_spi_device(wilc->dev);
+       struct wilc_spi *spi_priv = wilc->bus_data;
        u32 reg;
        int ret, i;
 
@@ -1049,7 +1060,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint)
                return 0;
        }
 
-       g_spi.nint = nint;
+       spi_priv->nint = nint;
 
        /*
         * interrupt pin mux select
index 7cd033004651b6097f5fb9f7d45e7addd4064561..4fbbbbd5a64b2d446ee108ef12e0dac89eda0cb4 100644 (file)
@@ -82,12 +82,6 @@ static const struct wiphy_wowlan_support wowlan_support = {
        .flags = WIPHY_WOWLAN_ANY
 };
 
-static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
-static u32 last_scanned_cnt;
-struct timer_list wilc_during_ip_timer;
-static struct timer_list aging_timer;
-static u8 op_ifcs;
-
 #define CHAN2G(_channel, _freq, _flags) {       \
                .band             = NL80211_BAND_2GHZ, \
                .center_freq      = (_freq),             \
@@ -143,10 +137,7 @@ struct p2p_mgmt_data {
 static u8 wlan_channel = INVALID_CHANNEL;
 static u8 curr_channel;
 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
-static u8 p2p_local_random = 0x01;
-static u8 p2p_recv_random;
 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
-static bool wilc_ie;
 
 static struct ieee80211_supported_band wilc_band_2ghz = {
        .channels = ieee80211_2ghz_channels,
@@ -158,25 +149,18 @@ static struct ieee80211_supported_band wilc_band_2ghz = {
 #define AGING_TIME     (9 * 1000)
 #define DURING_IP_TIME_OUT     15000
 
-static void clear_shadow_scan(void)
+static void clear_shadow_scan(struct wilc_priv *priv)
 {
        int i;
 
-       if (op_ifcs != 0)
-               return;
-
-       del_timer_sync(&aging_timer);
+       for (i = 0; i < priv->scanned_cnt; i++) {
+               kfree(priv->scanned_shadow[i].ies);
+               priv->scanned_shadow[i].ies = NULL;
 
-       for (i = 0; i < last_scanned_cnt; i++) {
-               if (last_scanned_shadow[last_scanned_cnt].ies) {
-                       kfree(last_scanned_shadow[i].ies);
-                       last_scanned_shadow[last_scanned_cnt].ies = NULL;
-               }
-
-               kfree(last_scanned_shadow[i].join_params);
-               last_scanned_shadow[i].join_params = NULL;
+               kfree(priv->scanned_shadow[i].join_params);
+               priv->scanned_shadow[i].join_params = NULL;
        }
-       last_scanned_cnt = 0;
+       priv->scanned_cnt = 0;
 }
 
 static u32 get_rssi_avg(struct network_info *network_info)
@@ -198,14 +182,14 @@ static void refresh_scan(struct wilc_priv *priv, bool direct_scan)
        struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
        int i;
 
-       for (i = 0; i < last_scanned_cnt; i++) {
+       for (i = 0; i < priv->scanned_cnt; i++) {
                struct network_info *network_info;
                s32 freq;
                struct ieee80211_channel *channel;
                int rssi;
                struct cfg80211_bss *bss;
 
-               network_info = &last_scanned_shadow[i];
+               network_info = &priv->scanned_shadow[i];
 
                if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan)
                        continue;
@@ -229,62 +213,68 @@ static void refresh_scan(struct wilc_priv *priv, bool direct_scan)
        }
 }
 
-static void reset_shadow_found(void)
+static void reset_shadow_found(struct wilc_priv *priv)
 {
        int i;
 
-       for (i = 0; i < last_scanned_cnt; i++)
-               last_scanned_shadow[i].found = 0;
+       for (i = 0; i < priv->scanned_cnt; i++)
+               priv->scanned_shadow[i].found = 0;
 }
 
-static void update_scan_time(void)
+static void update_scan_time(struct wilc_priv *priv)
 {
        int i;
 
-       for (i = 0; i < last_scanned_cnt; i++)
-               last_scanned_shadow[i].time_scan = jiffies;
+       for (i = 0; i < priv->scanned_cnt; i++)
+               priv->scanned_shadow[i].time_scan = jiffies;
 }
 
-static void remove_network_from_shadow(struct timer_list *unused)
+static void remove_network_from_shadow(struct timer_list *t)
 {
+       struct wilc_priv *priv = from_timer(priv, t, aging_timer);
        unsigned long now = jiffies;
        int i, j;
 
-       for (i = 0; i < last_scanned_cnt; i++) {
-               if (!time_after(now, last_scanned_shadow[i].time_scan +
+       for (i = 0; i < priv->scanned_cnt; i++) {
+               if (!time_after(now, priv->scanned_shadow[i].time_scan +
                                (unsigned long)(SCAN_RESULT_EXPIRE)))
                        continue;
-               kfree(last_scanned_shadow[i].ies);
-               last_scanned_shadow[i].ies = NULL;
+               kfree(priv->scanned_shadow[i].ies);
+               priv->scanned_shadow[i].ies = NULL;
 
-               kfree(last_scanned_shadow[i].join_params);
+               kfree(priv->scanned_shadow[i].join_params);
 
-               for (j = i; (j < last_scanned_cnt - 1); j++)
-                       last_scanned_shadow[j] = last_scanned_shadow[j + 1];
+               for (j = i; (j < priv->scanned_cnt - 1); j++)
+                       priv->scanned_shadow[j] = priv->scanned_shadow[j + 1];
 
-               last_scanned_cnt--;
+               priv->scanned_cnt--;
        }
 
-       if (last_scanned_cnt != 0)
-               mod_timer(&aging_timer, jiffies + msecs_to_jiffies(AGING_TIME));
+       if (priv->scanned_cnt != 0)
+               mod_timer(&priv->aging_timer,
+                         jiffies + msecs_to_jiffies(AGING_TIME));
 }
 
-static void clear_during_ip(struct timer_list *unused)
+static void clear_during_ip(struct timer_list *t)
 {
-       wilc_optaining_ip = false;
+       struct wilc_vif *vif = from_timer(vif, t, during_ip_timer);
+
+       vif->obtaining_ip = false;
 }
 
-static int is_network_in_shadow(struct network_info *nw_info, void *user_void)
+static int is_network_in_shadow(struct network_info *nw_info,
+                               struct wilc_priv *priv)
 {
        int state = -1;
        int i;
 
-       if (last_scanned_cnt == 0) {
-               mod_timer(&aging_timer, jiffies + msecs_to_jiffies(AGING_TIME));
+       if (priv->scanned_cnt == 0) {
+               mod_timer(&priv->aging_timer,
+                         jiffies + msecs_to_jiffies(AGING_TIME));
                state = -1;
        } else {
-               for (i = 0; i < last_scanned_cnt; i++) {
-                       if (memcmp(last_scanned_shadow[i].bssid,
+               for (i = 0; i < priv->scanned_cnt; i++) {
+                       if (memcmp(priv->scanned_shadow[i].bssid,
                                   nw_info->bssid, 6) == 0) {
                                state = i;
                                break;
@@ -295,23 +285,23 @@ static int is_network_in_shadow(struct network_info *nw_info, void *user_void)
 }
 
 static void add_network_to_shadow(struct network_info *nw_info,
-                                 void *user_void, void *join_params)
+                                 struct wilc_priv *priv, void *join_params)
 {
-       int ap_found = is_network_in_shadow(nw_info, user_void);
+       int ap_found = is_network_in_shadow(nw_info, priv);
        u32 ap_index = 0;
        u8 rssi_index = 0;
        struct network_info *shadow_nw_info;
 
-       if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
+       if (priv->scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
                return;
 
        if (ap_found == -1) {
-               ap_index = last_scanned_cnt;
-               last_scanned_cnt++;
+               ap_index = priv->scanned_cnt;
+               priv->scanned_cnt++;
        } else {
                ap_index = ap_found;
        }
-       shadow_nw_info = &last_scanned_shadow[ap_index];
+       shadow_nw_info = &priv->scanned_shadow[ap_index];
        rssi_index = shadow_nw_info->rssi_history.index;
        shadow_nw_info->rssi_history.samples[rssi_index++] = nw_info->rssi;
        if (rssi_index == NUM_RSSI) {
@@ -403,7 +393,7 @@ static void cfg_scan_result(enum scan_event scan_event,
                        u32 i;
 
                        for (i = 0; i < priv->rcvd_ch_cnt; i++) {
-                               if (memcmp(last_scanned_shadow[i].bssid,
+                               if (memcmp(priv->scanned_shadow[i].bssid,
                                           network_info->bssid, 6) == 0)
                                        break;
                        }
@@ -411,8 +401,8 @@ static void cfg_scan_result(enum scan_event scan_event,
                        if (i >= priv->rcvd_ch_cnt)
                                return;
 
-                       last_scanned_shadow[i].rssi = network_info->rssi;
-                       last_scanned_shadow[i].time_scan = jiffies;
+                       priv->scanned_shadow[i].rssi = network_info->rssi;
+                       priv->scanned_shadow[i].time_scan = jiffies;
                }
        } else if (scan_event == SCAN_EVENT_DONE) {
                refresh_scan(priv, false);
@@ -438,7 +428,7 @@ static void cfg_scan_result(enum scan_event scan_event,
                                .aborted = false,
                        };
 
-                       update_scan_time();
+                       update_scan_time(priv);
                        refresh_scan(priv, false);
 
                        cfg80211_scan_done(priv->scan_req, &info);
@@ -449,19 +439,17 @@ static void cfg_scan_result(enum scan_event scan_event,
        }
 }
 
-static inline bool wilc_wfi_cfg_scan_time_expired(int i)
+static inline bool wilc_cfg_scan_time_expired(struct wilc_priv *priv, int i)
 {
        unsigned long now = jiffies;
 
-       if (time_after(now, last_scanned_shadow[i].time_scan_cached +
+       if (time_after(now, priv->scanned_shadow[i].time_scan_cached +
                       (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
                return true;
        else
                return false;
 }
 
-int wilc_connecting;
-
 static void cfg_connect_result(enum conn_event conn_disconn_evt,
                               struct connect_info *conn_info,
                               u8 mac_status,
@@ -475,7 +463,7 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt,
        struct host_if_drv *wfi_drv = priv->hif_drv;
        u8 null_bssid[ETH_ALEN] = {0};
 
-       wilc_connecting = 0;
+       vif->connecting = false;
 
        if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
                u16 connect_status;
@@ -487,7 +475,6 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt,
                        connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
                        wilc_wlan_set_bssid(priv->dev, null_bssid,
                                            STATION_MODE);
-                       eth_zero_addr(wilc_connected_ssid);
 
                        if (!wfi_drv->p2p_connect)
                                wlan_channel = INVALID_CHANNEL;
@@ -502,11 +489,11 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt,
                        memcpy(priv->associated_bss, conn_info->bssid,
                               ETH_ALEN);
 
-                       for (i = 0; i < last_scanned_cnt; i++) {
-                               if (memcmp(last_scanned_shadow[i].bssid,
+                       for (i = 0; i < priv->scanned_cnt; i++) {
+                               if (memcmp(priv->scanned_shadow[i].bssid,
                                           conn_info->bssid,
                                           ETH_ALEN) == 0) {
-                                       if (wilc_wfi_cfg_scan_time_expired(i))
+                                       if (wilc_cfg_scan_time_expired(priv, i))
                                                scan_refresh = true;
 
                                        break;
@@ -524,13 +511,12 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt,
                                        conn_info->resp_ies_len, connect_status,
                                        GFP_KERNEL);
        } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
-               wilc_optaining_ip = false;
-               p2p_local_random = 0x01;
-               p2p_recv_random = 0x00;
-               wilc_ie = false;
+               vif->obtaining_ip = false;
+               priv->p2p.local_random = 0x01;
+               priv->p2p.recv_random = 0x00;
+               priv->p2p.is_wilc_ie = false;
                eth_zero_addr(priv->associated_bss);
                wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE);
-               eth_zero_addr(wilc_connected_ssid);
 
                if (!wfi_drv->p2p_connect)
                        wlan_channel = INVALID_CHANNEL;
@@ -620,7 +606,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 
        priv->rcvd_ch_cnt = 0;
 
-       reset_shadow_found();
+       reset_shadow_found(priv);
 
        priv->cfg_scanning = true;
        if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
@@ -673,25 +659,25 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
        enum authtype auth_type = ANY;
        u32 cipher_group;
 
-       wilc_connecting = 1;
+       vif->connecting = true;
 
        if (!(strncmp(sme->ssid, "DIRECT-", 7)))
                wfi_drv->p2p_connect = 1;
        else
                wfi_drv->p2p_connect = 0;
 
-       for (i = 0; i < last_scanned_cnt; i++) {
-               if (sme->ssid_len == last_scanned_shadow[i].ssid_len &&
-                   memcmp(last_scanned_shadow[i].ssid,
+       for (i = 0; i < priv->scanned_cnt; i++) {
+               if (sme->ssid_len == priv->scanned_shadow[i].ssid_len &&
+                   memcmp(priv->scanned_shadow[i].ssid,
                           sme->ssid,
                           sme->ssid_len) == 0) {
                        if (!sme->bssid) {
                                if (sel_bssi_idx == UINT_MAX ||
-                                   last_scanned_shadow[i].rssi >
-                                   last_scanned_shadow[sel_bssi_idx].rssi)
+                                   priv->scanned_shadow[i].rssi >
+                                   priv->scanned_shadow[sel_bssi_idx].rssi)
                                        sel_bssi_idx = i;
                        } else {
-                               if (memcmp(last_scanned_shadow[i].bssid,
+                               if (memcmp(priv->scanned_shadow[i].bssid,
                                           sme->bssid,
                                           ETH_ALEN) == 0) {
                                        sel_bssi_idx = i;
@@ -701,12 +687,16 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                }
        }
 
-       if (sel_bssi_idx < last_scanned_cnt) {
-               nw_info = &last_scanned_shadow[sel_bssi_idx];
+       if (sel_bssi_idx < priv->scanned_cnt) {
+               nw_info = &priv->scanned_shadow[sel_bssi_idx];
        } else {
                ret = -ENOENT;
-               wilc_connecting = 0;
-               return ret;
+               goto out_error;
+       }
+
+       if (ether_addr_equal_unaligned(vif->bssid, nw_info->bssid)) {
+               ret = -EALREADY;
+               goto out_error;
        }
 
        memset(priv->wep_key, 0, sizeof(priv->wep_key));
@@ -748,8 +738,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                        ret = -ENOTSUPP;
                        netdev_err(dev, "%s: Unsupported cipher\n",
                                   __func__);
-                       wilc_connecting = 0;
-                       return ret;
+                       goto out_error;
                }
        }
 
@@ -796,13 +785,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
                                security, auth_type,
                                nw_info->ch,
                                nw_info->join_params);
-       if (ret != 0) {
+       if (ret) {
+               u8 null_bssid[ETH_ALEN] = {0};
+
                netdev_err(dev, "wilc_set_join_req(): Error\n");
                ret = -ENOENT;
-               wilc_connecting = 0;
-               return ret;
+               wilc_wlan_set_bssid(dev, null_bssid, STATION_MODE);
+               goto out_error;
        }
+       return 0;
 
+out_error:
+       vif->connecting = false;
        return ret;
 }
 
@@ -816,7 +810,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev,
        int ret;
        u8 null_bssid[ETH_ALEN] = {0};
 
-       wilc_connecting = 0;
+       vif->connecting = false;
 
        if (!wilc)
                return -EIO;
@@ -832,9 +826,9 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev,
                wlan_channel = INVALID_CHANNEL;
        wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE);
 
-       p2p_local_random = 0x01;
-       p2p_recv_random = 0x00;
-       wilc_ie = false;
+       priv->p2p.local_random = 0x01;
+       priv->p2p.recv_random = 0x00;
+       priv->p2p.is_wilc_ie = false;
        wfi_drv->p2p_timeout = 0;
 
        ret = wilc_disconnect(vif, reason_code);
@@ -1132,9 +1126,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev,
 
                if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
                    stats.link_speed != DEFAULT_LINK_SPEED)
-                       wilc_enable_tcp_ack_filter(true);
+                       wilc_enable_tcp_ack_filter(vif, true);
                else if (stats.link_speed != DEFAULT_LINK_SPEED)
-                       wilc_enable_tcp_ack_filter(false);
+                       wilc_enable_tcp_ack_filter(vif, false);
        }
        return 0;
 }
@@ -1333,20 +1327,21 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
        struct wilc_vif *vif = netdev_priv(priv->dev);
 
        subtype = buff[P2P_PUB_ACTION_SUBTYPE];
-       if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) && !wilc_ie) {
+       if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
+           !priv->p2p.is_wilc_ie) {
                for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
                        if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
-                               p2p_recv_random = buff[i + 6];
-                               wilc_ie = true;
+                               priv->p2p.recv_random = buff[i + 6];
+                               priv->p2p.is_wilc_ie = true;
                                break;
                        }
                }
        }
 
-       if (p2p_local_random <= p2p_recv_random) {
+       if (priv->p2p.local_random <= priv->p2p.recv_random) {
                netdev_dbg(vif->ndev,
                           "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",
-                          p2p_local_random, p2p_recv_random);
+                          priv->p2p.local_random, priv->p2p.recv_random);
                return;
        }
 
@@ -1414,7 +1409,7 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
                                                                  size);
 
                        if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
-                           wilc_ie)
+                           priv->p2p.is_wilc_ie)
                                size -= 7;
 
                        break;
@@ -1506,7 +1501,8 @@ static int cancel_remain_on_channel(struct wiphy *wiphy,
                        priv->remain_on_ch_params.listen_session_id);
 }
 
-static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx,
+static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv,
+                                       struct p2p_mgmt_data *mgmt_tx,
                                        struct cfg80211_mgmt_tx_params *params,
                                        u8 iftype, u32 buf_len)
 {
@@ -1516,17 +1512,16 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx,
        u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE];
 
        if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) {
-               if (p2p_local_random == 1 &&
-                   p2p_recv_random < p2p_local_random) {
-                       get_random_bytes(&p2p_local_random, 1);
-                       p2p_local_random++;
+               if (priv->p2p.local_random == 1 &&
+                   priv->p2p.recv_random < priv->p2p.local_random) {
+                       get_random_bytes(&priv->p2p.local_random, 1);
+                       priv->p2p.local_random++;
                }
        }
 
-       if (p2p_local_random <= p2p_recv_random || !(subtype == GO_NEG_REQ ||
-                                                    subtype == GO_NEG_RSP ||
-                                                    subtype == P2P_INV_REQ ||
-                                                    subtype == P2P_INV_RSP))
+       if (priv->p2p.local_random <= priv->p2p.recv_random ||
+           !(subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
+             subtype == P2P_INV_REQ || subtype == P2P_INV_RSP))
                return;
 
        for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
@@ -1550,7 +1545,7 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx,
 
                memcpy(&mgmt_tx->buff[len], p2p_vendor_spec,
                       vendor_spec_len);
-               mgmt_tx->buff[len + vendor_spec_len] = p2p_local_random;
+               mgmt_tx->buff[len + vendor_spec_len] = priv->p2p.local_random;
                mgmt_tx->size = buf_len;
        }
 }
@@ -1569,7 +1564,7 @@ static int mgmt_tx(struct wiphy *wiphy,
        struct wilc_priv *priv = wiphy_priv(wiphy);
        struct host_if_drv *wfi_drv = priv->hif_drv;
        struct wilc_vif *vif = netdev_priv(wdev->netdev);
-       u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
+       u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(priv->p2p.local_random);
        int ret = 0;
 
        *cookie = (unsigned long)buf;
@@ -1617,8 +1612,8 @@ static int mgmt_tx(struct wiphy *wiphy,
 
                case PUBLIC_ACT_VENDORSPEC:
                        if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4))
-                               wilc_wfi_cfg_tx_vendor_spec(mgmt_tx, params,
-                                                           vif->iftype,
+                               wilc_wfi_cfg_tx_vendor_spec(priv, mgmt_tx,
+                                                           params, vif->iftype,
                                                            buf_len);
                        else
                                netdev_dbg(vif->ndev,
@@ -1732,7 +1727,7 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        if (!priv->hif_drv)
                return -EIO;
 
-       if (wilc_enable_ps)
+       if (vif->wilc->enable_ps)
                wilc_set_power_mgmt(vif, enabled, timeout);
 
        return 0;
@@ -1746,15 +1741,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wl = vif->wilc;
 
-       p2p_local_random = 0x01;
-       p2p_recv_random = 0x00;
-       wilc_ie = false;
-       wilc_optaining_ip = false;
-       del_timer(&wilc_during_ip_timer);
+       priv->p2p.local_random = 0x01;
+       priv->p2p.recv_random = 0x00;
+       priv->p2p.is_wilc_ie = false;
+       vif->obtaining_ip = false;
+       del_timer(&vif->during_ip_timer);
 
        switch (type) {
        case NL80211_IFTYPE_STATION:
-               wilc_connecting = 0;
+               vif->connecting = false;
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
                vif->monitor_flag = 0;
@@ -1764,46 +1759,46 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
                memset(priv->assoc_stainfo.sta_associated_bss, 0,
                       MAX_NUM_STA * ETH_ALEN);
 
-               wilc_enable_ps = true;
+               wl->enable_ps = true;
                wilc_set_power_mgmt(vif, 1, 0);
                break;
 
        case NL80211_IFTYPE_P2P_CLIENT:
-               wilc_connecting = 0;
+               vif->connecting = false;
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
                vif->monitor_flag = 0;
                vif->iftype = CLIENT_MODE;
                wilc_set_operation_mode(vif, STATION_MODE);
 
-               wilc_enable_ps = false;
+               wl->enable_ps = false;
                wilc_set_power_mgmt(vif, 0, 0);
                break;
 
        case NL80211_IFTYPE_AP:
-               wilc_enable_ps = false;
+               wl->enable_ps = false;
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
                vif->iftype = AP_MODE;
 
                if (wl->initialized) {
                        wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
-                                                0, vif->ifc_id);
+                                                0, vif->ifc_id, false);
                        wilc_set_operation_mode(vif, AP_MODE);
                        wilc_set_power_mgmt(vif, 0, 0);
                }
                break;
 
        case NL80211_IFTYPE_P2P_GO:
-               wilc_optaining_ip = true;
-               mod_timer(&wilc_during_ip_timer,
+               vif->obtaining_ip = true;
+               mod_timer(&vif->during_ip_timer,
                          jiffies + msecs_to_jiffies(DURING_IP_TIME_OUT));
                wilc_set_operation_mode(vif, AP_MODE);
                dev->ieee80211_ptr->iftype = type;
                priv->wdev->iftype = type;
                vif->iftype = GO_MODE;
 
-               wilc_enable_ps = false;
+               wl->enable_ps = false;
                wilc_set_power_mgmt(vif, 0, 0);
                break;
 
@@ -2154,8 +2149,12 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net,
        set_wiphy_dev(wdev->wiphy, dev);
 
        ret = wiphy_register(wdev->wiphy);
-       if (ret)
+       if (ret) {
                netdev_err(net, "Cannot register wiphy device\n");
+               wiphy_free(wdev->wiphy);
+               kfree(wdev);
+               return NULL;
+       }
 
        priv->dev = net;
        return wdev;
@@ -2165,12 +2164,10 @@ int wilc_init_host_int(struct net_device *net)
 {
        int ret;
        struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr);
+       struct wilc_vif *vif = netdev_priv(priv->dev);
 
-       if (op_ifcs == 0) {
-               timer_setup(&aging_timer, remove_network_from_shadow, 0);
-               timer_setup(&wilc_during_ip_timer, clear_during_ip, 0);
-       }
-       op_ifcs++;
+       timer_setup(&priv->aging_timer, remove_network_from_shadow, 0);
+       timer_setup(&vif->during_ip_timer, clear_during_ip, 0);
 
        priv->p2p_listen_state = false;
 
@@ -2182,7 +2179,7 @@ int wilc_init_host_int(struct net_device *net)
        return ret;
 }
 
-int wilc_deinit_host_int(struct net_device *net)
+void wilc_deinit_host_int(struct net_device *net)
 {
        int ret;
        struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr);
@@ -2190,19 +2187,15 @@ int wilc_deinit_host_int(struct net_device *net)
 
        priv->p2p_listen_state = false;
 
-       op_ifcs--;
-
        mutex_destroy(&priv->scan_req_lock);
        ret = wilc_deinit(vif);
 
-       clear_shadow_scan();
-       if (op_ifcs == 0)
-               del_timer_sync(&wilc_during_ip_timer);
+       del_timer_sync(&priv->aging_timer);
+       clear_shadow_scan(priv);
+       del_timer_sync(&vif->during_ip_timer);
 
        if (ret)
                netdev_err(net, "Error while deinitializing host interface\n");
-
-       return ret;
 }
 
 void wilc_free_wiphy(struct net_device *net)
index be412b65926c0071e136e8c0b732d96f0484db83..4812c8e2c79ba06eb7b846f0b020a4a84c027a52 100644 (file)
 struct wireless_dev *wilc_create_wiphy(struct net_device *net,
                                       struct device *dev);
 void wilc_free_wiphy(struct net_device *net);
-int wilc_deinit_host_int(struct net_device *net);
+void wilc_deinit_host_int(struct net_device *net);
 int wilc_init_host_int(struct net_device *net);
 void wilc_wfi_monitor_rx(u8 *buff, u32 size);
-int wilc_wfi_deinit_mon_interface(void);
+void wilc_wfi_deinit_mon_interface(void);
 struct net_device *wilc_wfi_init_mon_interface(const char *name,
                                               struct net_device *real_dev);
 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
index b7eee772f3fed77e0ce5bfb9f64acb47f517fbf7..4f05a16c778e9c3f91782661de7fe4b5c4ed4f7d 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "host_interface.h"
 #include "wilc_wlan.h"
+#include "wilc_wlan_cfg.h"
 
 #define FLOW_CONTROL_LOWER_THRESHOLD           128
 #define FLOW_CONTROL_UPPER_THRESHOLD           256
@@ -68,6 +69,12 @@ struct wilc_wfi_p2p_listen_params {
        u32 listen_session_id;
 };
 
+struct wilc_p2p_var {
+       u8 local_random;
+       u8 recv_random;
+       bool is_wilc_ie;
+};
+
 struct wilc_priv {
        struct wireless_dev *wdev;
        struct cfg80211_scan_request *scan_req;
@@ -94,7 +101,10 @@ struct wilc_priv {
        /* mutexes */
        struct mutex scan_req_lock;
        bool p2p_listen_state;
-
+       struct timer_list aging_timer;
+       struct network_info scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
+       int scanned_cnt;
+       struct wilc_p2p_var p2p;
 };
 
 struct frame_reg {
@@ -102,6 +112,32 @@ struct frame_reg {
        bool reg;
 };
 
+#define MAX_TCP_SESSION                25
+#define MAX_PENDING_ACKS               256
+
+struct ack_session_info {
+       u32 seq_num;
+       u32 bigger_ack_num;
+       u16 src_port;
+       u16 dst_port;
+       u16 status;
+};
+
+struct pending_acks {
+       u32 ack_num;
+       u32 session_index;
+       struct txq_entry_t  *txqe;
+};
+
+struct tcp_ack_filter {
+       struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
+       struct pending_acks pending_acks[MAX_PENDING_ACKS];
+       u32 pending_base;
+       u32 tcp_session;
+       u32 pending_acks_idx;
+       bool enabled;
+};
+
 struct wilc_vif {
        u8 idx;
        u8 iftype;
@@ -116,12 +152,18 @@ struct wilc_vif {
        struct net_device *ndev;
        u8 mode;
        u8 ifc_id;
+       struct timer_list during_ip_timer;
+       bool obtaining_ip;
+       struct timer_list periodic_rssi;
+       struct rf_info periodic_stat;
+       struct tcp_ack_filter ack_filter;
+       bool connecting;
 };
 
 struct wilc {
        const struct wilc_hif_func *hif_func;
        int io_type;
-       int mac_status;
+       s8 mac_status;
        struct gpio_desc *gpio_irq;
        bool initialized;
        int dev_irq_num;
@@ -165,7 +207,12 @@ struct wilc {
        struct device *dev;
        bool suspend_event;
 
-       struct rf_info dummy_statistics;
+       bool enable_ps;
+       int clients_count;
+       struct workqueue_struct *hif_workqueue;
+       enum chip_ps_states chip_ps_state;
+       struct wilc_cfg cfg;
+       void *bus_data;
 };
 
 struct wilc_wfi_mon_priv {
@@ -178,6 +225,6 @@ void wilc_netdev_cleanup(struct wilc *wilc);
 int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
                     const struct wilc_hif_func *ops);
 void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
-int wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
+void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
 
 #endif
index 8b184aa30d25d958dab26ddd1adc73583965debd..a48c906b244389868aabead9e10e633672a479fd 100644 (file)
@@ -9,8 +9,6 @@
 #include "wilc_wfi_netdevice.h"
 #include "wilc_wlan_cfg.h"
 
-static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP;
-
 static inline bool is_wilc1000(u32 id)
 {
        return ((id & 0xfffff000) == 0x100000 ? true : false);
@@ -73,8 +71,8 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
        complete(&wilc->txq_event);
 }
 
-static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
-                                    struct txq_entry_t *tqe)
+static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
+                                     struct txq_entry_t *tqe)
 {
        unsigned long flags;
        struct wilc *wilc = vif->wilc;
@@ -89,69 +87,47 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
        spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
        mutex_unlock(&wilc->txq_add_to_head_cs);
        complete(&wilc->txq_event);
-
-       return 0;
 }
 
-struct ack_session_info;
-struct ack_session_info {
-       u32 seq_num;
-       u32 bigger_ack_num;
-       u16 src_port;
-       u16 dst_port;
-       u16 status;
-};
-
-struct pending_acks_info {
-       u32 ack_num;
-       u32 session_index;
-       struct txq_entry_t  *txqe;
-};
-
 #define NOT_TCP_ACK                    (-1)
 
-#define MAX_TCP_SESSION                25
-#define MAX_PENDING_ACKS               256
-static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
-static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS];
-
-static u32 pending_base;
-static u32 tcp_session;
-static u32 pending_acks;
-
-static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq)
+static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
+                                  u32 dst_prt, u32 seq)
 {
-       if (tcp_session < 2 * MAX_TCP_SESSION) {
-               ack_session_info[tcp_session].seq_num = seq;
-               ack_session_info[tcp_session].bigger_ack_num = 0;
-               ack_session_info[tcp_session].src_port = src_prt;
-               ack_session_info[tcp_session].dst_port = dst_prt;
-               tcp_session++;
+       struct tcp_ack_filter *f = &vif->ack_filter;
+
+       if (f->tcp_session < 2 * MAX_TCP_SESSION) {
+               f->ack_session_info[f->tcp_session].seq_num = seq;
+               f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
+               f->ack_session_info[f->tcp_session].src_port = src_prt;
+               f->ack_session_info[f->tcp_session].dst_port = dst_prt;
+               f->tcp_session++;
        }
-       return 0;
 }
 
-static inline int update_tcp_session(u32 index, u32 ack)
+static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
 {
+       struct tcp_ack_filter *f = &vif->ack_filter;
+
        if (index < 2 * MAX_TCP_SESSION &&
-           ack > ack_session_info[index].bigger_ack_num)
-               ack_session_info[index].bigger_ack_num = ack;
-       return 0;
+           ack > f->ack_session_info[index].bigger_ack_num)
+               f->ack_session_info[index].bigger_ack_num = ack;
 }
 
-static inline int add_tcp_pending_ack(u32 ack, u32 session_index,
-                                     struct txq_entry_t *txqe)
+static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
+                                      u32 session_index,
+                                      struct txq_entry_t *txqe)
 {
-       u32 i = pending_base + pending_acks;
+       struct tcp_ack_filter *f = &vif->ack_filter;
+       u32 i = f->pending_base + f->pending_acks_idx;
 
        if (i < MAX_PENDING_ACKS) {
-               pending_acks_info[i].ack_num = ack;
-               pending_acks_info[i].txqe = txqe;
-               pending_acks_info[i].session_index = session_index;
-               txqe->tcp_pending_ack_idx = i;
-               pending_acks++;
+               f->pending_acks[i].ack_num = ack;
+               f->pending_acks[i].txqe = txqe;
+               f->pending_acks[i].session_index = session_index;
+               txqe->ack_idx = i;
+               f->pending_acks_idx++;
        }
-       return 0;
 }
 
 static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
@@ -162,72 +138,79 @@ static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
        unsigned long flags;
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
+       struct tcp_ack_filter *f = &vif->ack_filter;
+       const struct iphdr *ip_hdr_ptr;
+       const struct tcphdr *tcp_hdr_ptr;
+       u32 ihl, total_length, data_offset;
 
        spin_lock_irqsave(&wilc->txq_spinlock, flags);
 
-       if (eth_hdr_ptr->h_proto == htons(ETH_P_IP)) {
-               const struct iphdr *ip_hdr_ptr = buffer + ETH_HLEN;
+       if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
+               goto out;
 
-               if (ip_hdr_ptr->protocol == IPPROTO_TCP) {
-                       const struct tcphdr *tcp_hdr_ptr;
-                       u32 IHL, total_length, data_offset;
+       ip_hdr_ptr = buffer + ETH_HLEN;
 
-                       IHL = ip_hdr_ptr->ihl << 2;
-                       tcp_hdr_ptr = buffer + ETH_HLEN + IHL;
-                       total_length = ntohs(ip_hdr_ptr->tot_len);
+       if (ip_hdr_ptr->protocol != IPPROTO_TCP)
+               goto out;
 
-                       data_offset = tcp_hdr_ptr->doff << 2;
-                       if (total_length == (IHL + data_offset)) {
-                               u32 seq_no, ack_no;
+       ihl = ip_hdr_ptr->ihl << 2;
+       tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
+       total_length = ntohs(ip_hdr_ptr->tot_len);
 
-                               seq_no = ntohl(tcp_hdr_ptr->seq);
-                               ack_no = ntohl(tcp_hdr_ptr->ack_seq);
-                               for (i = 0; i < tcp_session; i++) {
-                                       u32 j = ack_session_info[i].seq_num;
+       data_offset = tcp_hdr_ptr->doff << 2;
+       if (total_length == (ihl + data_offset)) {
+               u32 seq_no, ack_no;
 
-                                       if (i < 2 * MAX_TCP_SESSION &&
-                                           j == seq_no) {
-                                               update_tcp_session(i, ack_no);
-                                               break;
-                                       }
-                               }
-                               if (i == tcp_session)
-                                       add_tcp_session(0, 0, seq_no);
+               seq_no = ntohl(tcp_hdr_ptr->seq);
+               ack_no = ntohl(tcp_hdr_ptr->ack_seq);
+               for (i = 0; i < f->tcp_session; i++) {
+                       u32 j = f->ack_session_info[i].seq_num;
 
-                               add_tcp_pending_ack(ack_no, i, tqe);
+                       if (i < 2 * MAX_TCP_SESSION &&
+                           j == seq_no) {
+                               update_tcp_session(vif, i, ack_no);
+                               break;
                        }
                }
+               if (i == f->tcp_session)
+                       add_tcp_session(vif, 0, 0, seq_no);
+
+               add_tcp_pending_ack(vif, ack_no, i, tqe);
        }
+
+out:
        spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
 }
 
-static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
+static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
 {
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
+       struct tcp_ack_filter *f = &vif->ack_filter;
        u32 i = 0;
        u32 dropped = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&wilc->txq_spinlock, flags);
-       for (i = pending_base; i < (pending_base + pending_acks); i++) {
-               u32 session_index;
+       for (i = f->pending_base;
+            i < (f->pending_base + f->pending_acks_idx); i++) {
+               u32 index;
                u32 bigger_ack_num;
 
                if (i >= MAX_PENDING_ACKS)
                        break;
 
-               session_index = pending_acks_info[i].session_index;
+               index = f->pending_acks[i].session_index;
 
-               if (session_index >= 2 * MAX_TCP_SESSION)
+               if (index >= 2 * MAX_TCP_SESSION)
                        break;
 
-               bigger_ack_num = ack_session_info[session_index].bigger_ack_num;
+               bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
 
-               if (pending_acks_info[i].ack_num < bigger_ack_num) {
+               if (f->pending_acks[i].ack_num < bigger_ack_num) {
                        struct txq_entry_t *tqe;
 
-                       tqe = pending_acks_info[i].txqe;
+                       tqe = f->pending_acks[i].txqe;
                        if (tqe) {
                                wilc_wlan_txq_remove(wilc, tqe);
                                tqe->status = 1;
@@ -239,13 +222,13 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
                        }
                }
        }
-       pending_acks = 0;
-       tcp_session = 0;
+       f->pending_acks_idx = 0;
+       f->tcp_session = 0;
 
-       if (pending_base == 0)
-               pending_base = MAX_TCP_SESSION;
+       if (f->pending_base == 0)
+               f->pending_base = MAX_TCP_SESSION;
        else
-               pending_base = 0;
+               f->pending_base = 0;
 
        spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
 
@@ -254,15 +237,11 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
                                            msecs_to_jiffies(1));
                dropped--;
        }
-
-       return 1;
 }
 
-static bool enabled;
-
-void wilc_enable_tcp_ack_filter(bool value)
+void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
 {
-       enabled = value;
+       vif->ack_filter.enabled = value;
 }
 
 static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
@@ -287,12 +266,9 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
        tqe->buffer_size = buffer_size;
        tqe->tx_complete_func = NULL;
        tqe->priv = NULL;
-       tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
+       tqe->ack_idx = NOT_TCP_ACK;
 
-       if (wilc_wlan_txq_add_to_head(vif, tqe)) {
-               kfree(tqe);
-               return 0;
-       }
+       wilc_wlan_txq_add_to_head(vif, tqe);
 
        return 1;
 }
@@ -319,8 +295,8 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
        tqe->tx_complete_func = func;
        tqe->priv = priv;
 
-       tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
-       if (enabled)
+       tqe->ack_idx = NOT_TCP_ACK;
+       if (vif->ack_filter.enabled)
                tcp_process(dev, tqe);
        wilc_wlan_txq_add_to_tail(dev, tqe);
        return wilc->txq_entries;
@@ -347,7 +323,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
        tqe->buffer_size = buffer_size;
        tqe->tx_complete_func = func;
        tqe->priv = priv;
-       tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
+       tqe->ack_idx = NOT_TCP_ACK;
        wilc_wlan_txq_add_to_tail(dev, tqe);
        return 1;
 }
@@ -436,7 +412,7 @@ void chip_wakeup(struct wilc *wilc)
                } while (wilc_get_chipid(wilc, true) == 0);
        } else if ((wilc->io_type & 0x1) == HIF_SDIO) {
                wilc->hif_func->hif_write_reg(wilc, 0xfa, 1);
-               udelay(200);
+               usleep_range(200, 400);
                wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
                do {
                        wilc->hif_func->hif_write_reg(wilc, 0xf0,
@@ -457,7 +433,7 @@ void chip_wakeup(struct wilc *wilc)
                } while ((clk_status_reg & 0x1) == 0);
        }
 
-       if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
+       if (wilc->chip_ps_state == CHIP_SLEEPING_MANUAL) {
                if (wilc_get_chipid(wilc, false) < 0x1002b0) {
                        u32 val32;
 
@@ -470,20 +446,20 @@ void chip_wakeup(struct wilc *wilc)
                        wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
                }
        }
-       chip_ps_state = CHIP_WAKEDUP;
+       wilc->chip_ps_state = CHIP_WAKEDUP;
 }
 EXPORT_SYMBOL_GPL(chip_wakeup);
 
 void wilc_chip_sleep_manually(struct wilc *wilc)
 {
-       if (chip_ps_state != CHIP_WAKEDUP)
+       if (wilc->chip_ps_state != CHIP_WAKEDUP)
                return;
        acquire_bus(wilc, ACQUIRE_ONLY);
 
        chip_allow_sleep(wilc);
        wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1);
 
-       chip_ps_state = CHIP_SLEEPING_MANUAL;
+       wilc->chip_ps_state = CHIP_SLEEPING_MANUAL;
        release_bus(wilc, RELEASE_ONLY);
 }
 EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually);
@@ -685,9 +661,9 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
                tqe->status = 1;
                if (tqe->tx_complete_func)
                        tqe->tx_complete_func(tqe->priv, tqe->status);
-               if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK &&
-                   tqe->tcp_pending_ack_idx < MAX_PENDING_ACKS)
-                       pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL;
+               if (tqe->ack_idx != NOT_TCP_ACK &&
+                   tqe->ack_idx < MAX_PENDING_ACKS)
+                       vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
                kfree(tqe);
        } while (--entries);
 
@@ -1218,9 +1194,9 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
        return ret_size;
 }
 
-int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size)
+int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size)
 {
-       return wilc_wlan_cfg_get_wid_value(wid, buffer, buffer_size);
+       return wilc_wlan_cfg_get_wid_value(wl, wid, buffer, buffer_size);
 }
 
 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
@@ -1240,7 +1216,8 @@ int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
                        }
                }
                for (i = 0; i < count; i++) {
-                       wids[i].size = wilc_wlan_cfg_get_val(wids[i].id,
+                       wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
+                                                            wids[i].id,
                                                             wids[i].val,
                                                             wids[i].size);
                }
@@ -1339,11 +1316,6 @@ int wilc_wlan_init(struct net_device *dev)
                goto fail;
        }
 
-       if (!wilc_wlan_cfg_init()) {
-               ret = -ENOBUFS;
-               goto fail;
-       }
-
        if (!wilc->tx_buffer)
                wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
 
index 7467188dbf2f78ee74a9697c34972badb7e0f1a0..27667131de1aa21ecc43559d040d99723a7e61c2 100644 (file)
 struct txq_entry_t {
        struct list_head list;
        int type;
-       int tcp_pending_ack_idx;
+       int ack_idx;
        u8 *buffer;
        int buffer_size;
        void *priv;
@@ -277,19 +277,19 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
                      u32 buffer_size, int commit, u32 drv_handler);
 int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
                      u32 drv_handler);
-int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size);
+int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer,
+                         u32 buffer_size);
 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
                               u32 buffer_size, wilc_tx_complete_func_t func);
 void wilc_chip_sleep_manually(struct wilc *wilc);
 
-void wilc_enable_tcp_ack_filter(bool value);
+void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value);
 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc);
 netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
 
 void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
 void host_wakeup_notify(struct wilc *wilc);
 void host_sleep_notify(struct wilc *wilc);
-extern bool wilc_enable_ps;
 void chip_allow_sleep(struct wilc *wilc);
 void chip_wakeup(struct wilc *wilc);
 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
index 421576386ab4a5bf5beb2d9ceaeb981d84f8db7f..faa001c75681dd8cf85ad4999b64d54d153fb6b6 100644 (file)
@@ -8,6 +8,7 @@
 #include "wilc_wlan.h"
 #include "wilc_wlan_cfg.h"
 #include "coreconfigurator.h"
+#include "wilc_wfi_netdevice.h"
 
 enum cfg_cmd_type {
        CFG_BYTE_CMD    = 0,
@@ -17,134 +18,30 @@ enum cfg_cmd_type {
        CFG_BIN_CMD     = 4
 };
 
-struct wilc_mac_cfg {
-       int mac_status;
-       u8 mac_address[7];
-       u8 ip_address[5];
-       u8 bssid[7];
-       u8 ssid[34];
-       u8 firmware_version[129];
-       u8 supp_rate[24];
-       u8 wep_key[28];
-       u8 i_psk[66];
-       u8 hw_product_version[33];
-       u8 phyversion[17];
-       u8 supp_username[21];
-       u8 supp_password[64];
-       u8 assoc_req[256];
-       u8 assoc_rsp[256];
-       u8 firmware_info[8];
-       u8 scan_result[256];
-       u8 scan_result1[256];
-};
-
-static struct wilc_mac_cfg g_mac;
-
-static struct wilc_cfg_byte g_cfg_byte[] = {
-       {WID_BSS_TYPE, 0},
-       {WID_CURRENT_TX_RATE, 0},
-       {WID_CURRENT_CHANNEL, 0},
-       {WID_PREAMBLE, 0},
-       {WID_11G_OPERATING_MODE, 0},
+static const struct wilc_cfg_byte g_cfg_byte[] = {
        {WID_STATUS, 0},
-       {WID_SCAN_TYPE, 0},
-       {WID_KEY_ID, 0},
-       {WID_QOS_ENABLE, 0},
-       {WID_POWER_MANAGEMENT, 0},
-       {WID_11I_MODE, 0},
-       {WID_AUTH_TYPE, 0},
-       {WID_SITE_SURVEY, 0},
-       {WID_LISTEN_INTERVAL, 0},
-       {WID_DTIM_PERIOD, 0},
-       {WID_ACK_POLICY, 0},
-       {WID_BCAST_SSID, 0},
-       {WID_REKEY_POLICY, 0},
-       {WID_SHORT_SLOT_ALLOWED, 0},
-       {WID_START_SCAN_REQ, 0},
        {WID_RSSI, 0},
        {WID_LINKSPEED, 0},
-       {WID_AUTO_RX_SENSITIVITY, 0},
-       {WID_DATAFLOW_CONTROL, 0},
-       {WID_SCAN_FILTER, 0},
-       {WID_11N_PROT_MECH, 0},
-       {WID_11N_ERP_PROT_TYPE, 0},
-       {WID_11N_ENABLE, 0},
-       {WID_11N_OPERATING_MODE, 0},
-       {WID_11N_OBSS_NONHT_DETECTION, 0},
-       {WID_11N_HT_PROT_TYPE, 0},
-       {WID_11N_RIFS_PROT_ENABLE, 0},
-       {WID_11N_SMPS_MODE, 0},
-       {WID_11N_CURRENT_TX_MCS, 0},
-       {WID_11N_SHORT_GI_ENABLE, 0},
-       {WID_RIFS_MODE, 0},
-       {WID_TX_ABORT_CONFIG, 0},
-       {WID_11N_IMMEDIATE_BA_ENABLED, 0},
-       {WID_11N_TXOP_PROT_DISABLE, 0},
        {WID_NIL, 0}
 };
 
-static struct wilc_cfg_hword g_cfg_hword[] = {
-       {WID_LINK_LOSS_THRESHOLD, 0},
-       {WID_RTS_THRESHOLD, 0},
-       {WID_FRAG_THRESHOLD, 0},
-       {WID_SHORT_RETRY_LIMIT, 0},
-       {WID_LONG_RETRY_LIMIT, 0},
-       {WID_BEACON_INTERVAL, 0},
-       {WID_RX_SENSE, 0},
-       {WID_ACTIVE_SCAN_TIME, 0},
-       {WID_PASSIVE_SCAN_TIME, 0},
-       {WID_SITE_SURVEY_SCAN_TIME, 0},
-       {WID_JOIN_START_TIMEOUT, 0},
-       {WID_AUTH_TIMEOUT, 0},
-       {WID_ASOC_TIMEOUT, 0},
-       {WID_11I_PROTOCOL_TIMEOUT, 0},
-       {WID_EAPOL_RESPONSE_TIMEOUT, 0},
-       {WID_11N_SIG_QUAL_VAL, 0},
-       {WID_CCA_THRESHOLD, 0},
+static const struct wilc_cfg_hword g_cfg_hword[] = {
        {WID_NIL, 0}
 };
 
-static struct wilc_cfg_word g_cfg_word[] = {
+static const struct wilc_cfg_word g_cfg_word[] = {
        {WID_FAILED_COUNT, 0},
-       {WID_RETRY_COUNT, 0},
-       {WID_MULTIPLE_RETRY_COUNT, 0},
-       {WID_FRAME_DUPLICATE_COUNT, 0},
-       {WID_ACK_FAILURE_COUNT, 0},
        {WID_RECEIVED_FRAGMENT_COUNT, 0},
-       {WID_MCAST_RECEIVED_FRAME_COUNT, 0},
-       {WID_FCS_ERROR_COUNT, 0},
        {WID_SUCCESS_FRAME_COUNT, 0},
-       {WID_TX_FRAGMENT_COUNT, 0},
-       {WID_TX_MULTICAST_FRAME_COUNT, 0},
-       {WID_RTS_SUCCESS_COUNT, 0},
-       {WID_RTS_FAILURE_COUNT, 0},
-       {WID_WEP_UNDECRYPTABLE_COUNT, 0},
-       {WID_REKEY_PERIOD, 0},
-       {WID_REKEY_PACKET_COUNT, 0},
-       {WID_HW_RX_COUNT, 0},
        {WID_GET_INACTIVE_TIME, 0},
        {WID_NIL, 0}
 
 };
 
-static struct wilc_cfg_str g_cfg_str[] = {
-       {WID_SSID, g_mac.ssid}, /* 33 + 1 bytes */
-       {WID_FIRMWARE_VERSION, g_mac.firmware_version},
-       {WID_OPERATIONAL_RATE_SET, g_mac.supp_rate},
-       {WID_BSSID, g_mac.bssid},       /* 6 bytes */
-       {WID_WEP_KEY_VALUE, g_mac.wep_key},     /* 27 bytes */
-       {WID_11I_PSK, g_mac.i_psk},     /* 65 bytes */
-       {WID_HARDWARE_VERSION, g_mac.hw_product_version},
-       {WID_MAC_ADDR, g_mac.mac_address},
-       {WID_PHY_VERSION, g_mac.phyversion},
-       {WID_SUPP_USERNAME, g_mac.supp_username},
-       {WID_SUPP_PASSWORD, g_mac.supp_password},
-       {WID_SITE_SURVEY_RESULTS, g_mac.scan_result},
-       {WID_SITE_SURVEY_RESULTS, g_mac.scan_result1},
-       {WID_ASSOC_REQ_INFO, g_mac.assoc_req},
-       {WID_ASSOC_RES_INFO, g_mac.assoc_rsp},
-       {WID_FIRMWARE_INFO, g_mac.firmware_version},
-       {WID_IP_ADDRESS, g_mac.ip_address},
+static const struct wilc_cfg_str g_cfg_str[] = {
+       {WID_FIRMWARE_VERSION, NULL},
+       {WID_MAC_ADDR, NULL},
+       {WID_ASSOC_RES_INFO, NULL},
        {WID_NIL, NULL}
 };
 
@@ -265,7 +162,7 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size)
  ********************************************/
 
 #define GET_WID_TYPE(wid)              (((wid) >> 12) & 0x7)
-static void wilc_wlan_parse_response_frame(u8 *info, int size)
+static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size)
 {
        u16 wid;
        u32 len = 0, i = 0;
@@ -277,11 +174,11 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
                switch (GET_WID_TYPE(wid)) {
                case WID_CHAR:
                        do {
-                               if (g_cfg_byte[i].id == WID_NIL)
+                               if (wl->cfg.b[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_byte[i].id == wid) {
-                                       g_cfg_byte[i].val = info[4];
+                               if (wl->cfg.b[i].id == wid) {
+                                       wl->cfg.b[i].val = info[4];
                                        break;
                                }
                                i++;
@@ -291,12 +188,12 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
 
                case WID_SHORT:
                        do {
-                               if (g_cfg_hword[i].id == WID_NIL)
+                               if (wl->cfg.hw[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_hword[i].id == wid) {
-                                       g_cfg_hword[i].val = (info[4] |
-                                                             (info[5] << 8));
+                               if (wl->cfg.hw[i].id == wid) {
+                                       wl->cfg.hw[i].val = (info[4] |
+                                                            (info[5] << 8));
                                        break;
                                }
                                i++;
@@ -306,14 +203,14 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
 
                case WID_INT:
                        do {
-                               if (g_cfg_word[i].id == WID_NIL)
+                               if (wl->cfg.w[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_word[i].id == wid) {
-                                       g_cfg_word[i].val = (info[4] |
-                                                            (info[5] << 8) |
-                                                            (info[6] << 16) |
-                                                            (info[7] << 24));
+                               if (wl->cfg.w[i].id == wid) {
+                                       wl->cfg.w[i].val = (info[4] |
+                                                           (info[5] << 8) |
+                                                           (info[6] << 16) |
+                                                           (info[7] << 24));
                                        break;
                                }
                                i++;
@@ -323,17 +220,11 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
 
                case WID_STR:
                        do {
-                               if (g_cfg_str[i].id == WID_NIL)
+                               if (wl->cfg.s[i].id == WID_NIL)
                                        break;
 
-                               if (g_cfg_str[i].id == wid) {
-                                       if (wid == WID_SITE_SURVEY_RESULTS) {
-                                               static int toggle;
-
-                                               i += toggle;
-                                               toggle ^= 1;
-                                       }
-                                       memcpy(g_cfg_str[i].str, &info[2],
+                               if (wl->cfg.s[i].id == wid) {
+                                       memcpy(wl->cfg.s[i].str, &info[2],
                                               (info[2] + 2));
                                        break;
                                }
@@ -350,22 +241,28 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size)
        }
 }
 
-static int wilc_wlan_parse_info_frame(u8 *info, int size)
+static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info)
 {
-       struct wilc_mac_cfg *pd = &g_mac;
        u32 wid, len;
-       int type = WILC_CFG_RSP_STATUS;
 
        wid = info[0] | (info[1] << 8);
 
        len = info[2];
 
        if (len == 1 && wid == WID_STATUS) {
-               pd->mac_status = info[3];
-               type = WILC_CFG_RSP_STATUS;
-       }
+               int i = 0;
 
-       return type;
+               do {
+                       if (wl->cfg.b[i].id == WID_NIL)
+                               break;
+
+                       if (wl->cfg.b[i].id == wid) {
+                               wl->cfg.b[i].val = info[3];
+                               break;
+                       }
+                       i++;
+               } while (1);
+       }
 }
 
 /********************************************
@@ -424,24 +321,20 @@ int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id)
        return 2;
 }
 
-int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
+int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer,
+                               u32 buffer_size)
 {
        u32 type = (wid >> 12) & 0xf;
        int i, ret = 0;
 
-       if (wid == WID_STATUS) {
-               *((u32 *)buffer) = g_mac.mac_status;
-               return 4;
-       }
-
        i = 0;
        if (type == CFG_BYTE_CMD) {
                do {
-                       if (g_cfg_byte[i].id == WID_NIL)
+                       if (wl->cfg.b[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_byte[i].id == wid) {
-                               memcpy(buffer,  &g_cfg_byte[i].val, 1);
+                       if (wl->cfg.b[i].id == wid) {
+                               memcpy(buffer, &wl->cfg.b[i].val, 1);
                                ret = 1;
                                break;
                        }
@@ -449,11 +342,11 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
                } while (1);
        } else if (type == CFG_HWORD_CMD) {
                do {
-                       if (g_cfg_hword[i].id == WID_NIL)
+                       if (wl->cfg.hw[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_hword[i].id == wid) {
-                               memcpy(buffer,  &g_cfg_hword[i].val, 2);
+                       if (wl->cfg.hw[i].id == wid) {
+                               memcpy(buffer, &wl->cfg.hw[i].val, 2);
                                ret = 2;
                                break;
                        }
@@ -461,11 +354,11 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
                } while (1);
        } else if (type == CFG_WORD_CMD) {
                do {
-                       if (g_cfg_word[i].id == WID_NIL)
+                       if (wl->cfg.w[i].id == WID_NIL)
                                break;
 
-                       if (g_cfg_word[i].id == wid) {
-                               memcpy(buffer,  &g_cfg_word[i].val, 4);
+                       if (wl->cfg.w[i].id == wid) {
+                               memcpy(buffer, &wl->cfg.w[i].val, 4);
                                ret = 4;
                                break;
                        }
@@ -473,23 +366,17 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
                } while (1);
        } else if (type == CFG_STR_CMD) {
                do {
-                       u32 id = g_cfg_str[i].id;
+                       u32 id = wl->cfg.s[i].id;
 
                        if (id == WID_NIL)
                                break;
 
                        if (id == wid) {
-                               u32 size = g_cfg_str[i].str[0] |
-                                               (g_cfg_str[i].str[1] << 8);
+                               u32 size = (wl->cfg.s[i].str[0] |
+                                           (wl->cfg.s[i].str[1] << 8));
 
                                if (buffer_size >= size) {
-                                       if (id == WID_SITE_SURVEY_RESULTS) {
-                                               static int toggle;
-
-                                               i += toggle;
-                                               toggle ^= 1;
-                                       }
-                                       memcpy(buffer,  &g_cfg_str[i].str[2],
+                                       memcpy(buffer, &wl->cfg.s[i].str[2],
                                               size);
                                        ret = size;
                                }
@@ -498,14 +385,12 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size)
                        i++;
                } while (1);
        }
-
        return ret;
 }
 
-int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
-                             struct wilc_cfg_rsp *rsp)
+void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
+                              struct wilc_cfg_rsp *rsp)
 {
-       int ret = 1;
        u8 msg_type;
        u8 msg_id;
 
@@ -513,6 +398,7 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
        msg_id = frame[1];      /* seq no */
        frame += 4;
        size -= 4;
+       rsp->type = 0;
 
        /*
         * The valid types of response messages are
@@ -523,13 +409,14 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
 
        switch (msg_type) {
        case 'R':
-               wilc_wlan_parse_response_frame(frame, size);
+               wilc_wlan_parse_response_frame(wilc, frame, size);
                rsp->type = WILC_CFG_RSP;
                rsp->seq_no = msg_id;
                break;
 
        case 'I':
-               rsp->type = wilc_wlan_parse_info_frame(frame, size);
+               wilc_wlan_parse_info_frame(wilc, frame);
+               rsp->type = WILC_CFG_RSP_STATUS;
                rsp->seq_no = msg_id;
                /*call host interface info parse as well*/
                wilc_gnrl_async_info_received(wilc, frame - 4, size + 4);
@@ -537,7 +424,6 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
 
        case 'N':
                wilc_network_info_received(wilc, frame - 4, size + 4);
-               rsp->type = 0;
                break;
 
        case 'S':
@@ -545,17 +431,67 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
                break;
 
        default:
-               rsp->type = 0;
                rsp->seq_no = msg_id;
-               ret = 0;
                break;
        }
+}
 
-       return ret;
+int wilc_wlan_cfg_init(struct wilc *wl)
+{
+       struct wilc_cfg_str_vals *str_vals;
+       int i = 0;
+
+       wl->cfg.b = kmemdup(g_cfg_byte, sizeof(g_cfg_byte), GFP_KERNEL);
+       if (!wl->cfg.b)
+               return -ENOMEM;
+
+       wl->cfg.hw = kmemdup(g_cfg_hword, sizeof(g_cfg_hword), GFP_KERNEL);
+       if (!wl->cfg.hw)
+               goto out_b;
+
+       wl->cfg.w = kmemdup(g_cfg_word, sizeof(g_cfg_word), GFP_KERNEL);
+       if (!wl->cfg.w)
+               goto out_hw;
+
+       wl->cfg.s = kmemdup(g_cfg_str, sizeof(g_cfg_str), GFP_KERNEL);
+       if (!wl->cfg.s)
+               goto out_w;
+
+       str_vals = kzalloc(sizeof(*str_vals), GFP_KERNEL);
+       if (!str_vals)
+               goto out_s;
+
+       wl->cfg.str_vals = str_vals;
+       /* store the string cfg parameters */
+       wl->cfg.s[i].id = WID_FIRMWARE_VERSION;
+       wl->cfg.s[i].str = str_vals->firmware_version;
+       i++;
+       wl->cfg.s[i].id = WID_MAC_ADDR;
+       wl->cfg.s[i].str = str_vals->mac_address;
+       i++;
+       wl->cfg.s[i].id = WID_ASSOC_RES_INFO;
+       wl->cfg.s[i].str = str_vals->assoc_rsp;
+       i++;
+       wl->cfg.s[i].id = WID_NIL;
+       wl->cfg.s[i].str = NULL;
+       return 0;
+
+out_s:
+       kfree(wl->cfg.s);
+out_w:
+       kfree(wl->cfg.w);
+out_hw:
+       kfree(wl->cfg.hw);
+out_b:
+       kfree(wl->cfg.b);
+       return -ENOMEM;
 }
 
-int wilc_wlan_cfg_init(void)
+void wilc_wlan_cfg_deinit(struct wilc *wl)
 {
-       memset((void *)&g_mac, 0, sizeof(struct wilc_mac_cfg));
-       return 1;
+       kfree(wl->cfg.b);
+       kfree(wl->cfg.hw);
+       kfree(wl->cfg.w);
+       kfree(wl->cfg.s);
+       kfree(wl->cfg.str_vals);
 }
index 0c649d1f6f1146a034cd87abc37796220d64d7b3..e5ca6cea0682b657094e72ac5131bb2b5e5a8ddc 100644 (file)
@@ -9,7 +9,7 @@
 
 struct wilc_cfg_byte {
        u16 id;
-       u16 val;
+       u8 val;
 };
 
 struct wilc_cfg_hword {
@@ -27,12 +27,28 @@ struct wilc_cfg_str {
        u8 *str;
 };
 
+struct wilc_cfg_str_vals {
+       u8 mac_address[7];
+       u8 firmware_version[129];
+       u8 assoc_rsp[256];
+};
+
+struct wilc_cfg {
+       struct wilc_cfg_byte *b;
+       struct wilc_cfg_hword *hw;
+       struct wilc_cfg_word *w;
+       struct wilc_cfg_str *s;
+       struct wilc_cfg_str_vals *str_vals;
+};
+
 struct wilc;
 int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size);
 int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id);
-int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size);
-int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
-                             struct wilc_cfg_rsp *rsp);
-int wilc_wlan_cfg_init(void);
+int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer,
+                               u32 buffer_size);
+void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size,
+                              struct wilc_cfg_rsp *rsp);
+int wilc_wlan_cfg_init(struct wilc *wl);
+void wilc_wlan_cfg_deinit(struct wilc *wl);
 
 #endif
index b81a73b9bd67e674a9a45ce785708e775edb5d01..ce2066b7428796b9ba1ec167fad40f4a2455df15 100644 (file)
@@ -204,10 +204,6 @@ enum wid_type {
        WID_STR                 = 3,
        WID_BIN_DATA            = 4,
        WID_BIN                 = 5,
-       WID_IP                  = 6,
-       WID_ADR                 = 7,
-       WID_UNDEF               = 8,
-       WID_TYPE_FORCE_32BIT    = 0xFFFFFFFF
 };
 
 struct wid {
index d4cf09b11e3324503e1323bf6eb07191b78926f1..47f2ee926a77147310dbb84030da0d46123a55ca 100644 (file)
@@ -76,7 +76,7 @@ static int prism2_domibset_uint32(struct wlandevice *wlandev, u32 did, u32 data)
        struct p80211item_uint32 *mibitem =
                        (struct p80211item_uint32 *)&msg.mibattribute.data;
 
-       msg.msgcode = DIDmsg_dot11req_mibset;
+       msg.msgcode = DIDMSG_DOT11REQ_MIBSET;
        mibitem->did = did;
        mibitem->data = data;
 
@@ -90,7 +90,7 @@ static int prism2_domibset_pstr32(struct wlandevice *wlandev,
        struct p80211item_pstr32 *mibitem =
                        (struct p80211item_pstr32 *)&msg.mibattribute.data;
 
-       msg.msgcode = DIDmsg_dot11req_mibset;
+       msg.msgcode = DIDMSG_DOT11REQ_MIBSET;
        mibitem->did = did;
        mibitem->data.len = len;
        memcpy(mibitem->data.data, data, len);
@@ -129,7 +129,7 @@ static int prism2_change_virtual_intf(struct wiphy *wiphy,
 
        /* Set Operation mode to the PORT TYPE RID */
        result = prism2_domibset_uint32(wlandev,
-                                       DIDmib_p2_p2Static_p2CnfPortType,
+                                       DIDMIB_P2_STATIC_CNFPORTTYPE,
                                        data);
 
        if (result)
@@ -158,12 +158,12 @@ static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
        }
 
        if (prism2_domibset_uint32(wlandev,
-                                  DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+                                  DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
                                   key_index))
                return -EFAULT;
 
        /* send key to driver */
-       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(key_index + 1);
+       did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1);
 
        if (prism2_domibset_pstr32(wlandev, did, params->key_len, params->key))
                return -EFAULT;
@@ -216,7 +216,7 @@ static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
                return -EINVAL;
 
        /* send key to driver */
-       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(key_index + 1);
+       did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1);
        result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");
 
        if (result)
@@ -234,7 +234,7 @@ static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
        int result = 0;
 
        result = prism2_domibset_uint32(wlandev,
-               DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+               DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
                key_index);
 
        if (result)
@@ -256,7 +256,7 @@ static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
                return -EOPNOTSUPP;
 
        /* build request message */
-       quality.msgcode = DIDmsg_lnxreq_commsquality;
+       quality.msgcode = DIDMSG_LNXREQ_COMMSQUALITY;
        quality.dbm.data = P80211ENUM_truth_true;
        quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
 
@@ -311,7 +311,7 @@ static int prism2_scan(struct wiphy *wiphy,
        priv->scan_request = request;
 
        memset(&msg1, 0x00, sizeof(msg1));
-       msg1.msgcode = DIDmsg_dot11req_scan;
+       msg1.msgcode = DIDMSG_DOT11REQ_SCAN;
        msg1.bsstype.data = P80211ENUM_bsstype_any;
 
        memset(&msg1.bssid.data.data, 0xFF, sizeof(msg1.bssid.data.data));
@@ -350,7 +350,7 @@ static int prism2_scan(struct wiphy *wiphy,
                int freq;
 
                memset(&msg2, 0, sizeof(msg2));
-               msg2.msgcode = DIDmsg_dot11req_scan_results;
+               msg2.msgcode = DIDMSG_DOT11REQ_SCAN_RESULTS;
                msg2.bssindex.data = i;
 
                result = p80211req_dorequest(wlandev, (u8 *)&msg2);
@@ -410,7 +410,7 @@ static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
                        data = wiphy->rts_threshold;
 
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+                                               DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
                                                data);
                if (result) {
                        err = -EFAULT;
@@ -425,7 +425,7 @@ static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
                        data = wiphy->frag_threshold;
 
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+                                               DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
                                                data);
                if (result) {
                        err = -EFAULT;
@@ -455,7 +455,7 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
        if (channel) {
                chan = ieee80211_frequency_to_channel(channel->center_freq);
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+                                               DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
                                                chan);
                if (result)
                        goto exit;
@@ -482,13 +482,13 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
                        }
 
                        result = prism2_domibset_uint32(wlandev,
-                               DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+                               DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
                                sme->key_idx);
                        if (result)
                                goto exit;
 
                        /* send key to driver */
-                       did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(
+                       did = didmib_dot11smt_wepdefaultkeystable_key(
                                        sme->key_idx + 1);
                        result = prism2_domibset_pstr32(wlandev,
                                                        did, sme->key_len,
@@ -502,13 +502,13 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
                 * seems reasonable anyways
                 */
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+                                               DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
                                                P80211ENUM_truth_true);
                if (result)
                        goto exit;
 
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+                                               DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
                                                P80211ENUM_truth_true);
                if (result)
                        goto exit;
@@ -518,13 +518,13 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
                 * and exclude unencrypted
                 */
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+                                               DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
                                                P80211ENUM_truth_false);
                if (result)
                        goto exit;
 
                result = prism2_domibset_uint32(wlandev,
-                                               DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+                                               DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
                                                P80211ENUM_truth_false);
                if (result)
                        goto exit;
@@ -533,7 +533,7 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
        /* Now do the actual join. Note there is no way that I can
         * see to request a specific bssid
         */
-       msg_join.msgcode = DIDmsg_lnxreq_autojoin;
+       msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN;
 
        memcpy(msg_join.ssid.data.data, sme->ssid, length);
        msg_join.ssid.data.len = length;
@@ -556,7 +556,7 @@ static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
        int err = 0;
 
        /* Do a join, with a bogus ssid. Thats the only way I can think of */
-       msg_join.msgcode = DIDmsg_lnxreq_autojoin;
+       msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN;
 
        memcpy(msg_join.ssid.data.data, "---", 3);
        msg_join.ssid.data.len = 3;
@@ -595,7 +595,7 @@ static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
                data = MBM_TO_DBM(mbm);
 
        result = prism2_domibset_uint32(wlandev,
-               DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+               DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
                data);
 
        if (result) {
@@ -618,9 +618,8 @@ static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
        int err = 0;
 
        mibitem = (struct p80211item_uint32 *)&msg.mibattribute.data;
-       msg.msgcode = DIDmsg_dot11req_mibget;
-       mibitem->did =
-           DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+       msg.msgcode = DIDMSG_DOT11REQ_MIBGET;
+       mibitem->did = DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL;
 
        result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
index 16f7dd266e3b18961c56a298ecbc3ff49323e3e0..6261881e9bcd7d0306060a84199ecac9d0ec4515 100644 (file)
@@ -3605,36 +3605,32 @@ static void hfa384x_usbout_callback(struct urb *urb)
                        prism2sta_ev_alloc(wlandev);
                        break;
 
-               case -EPIPE:
-                       {
-                               struct hfa384x *hw = wlandev->priv;
+               case -EPIPE: {
+                       struct hfa384x *hw = wlandev->priv;
 
-                               netdev_warn(hw->wlandev->netdev,
-                                           "%s tx pipe stalled: requesting reset\n",
-                                           wlandev->netdev->name);
-                               if (!test_and_set_bit
-                                   (WORK_TX_HALT, &hw->usb_flags))
-                                       schedule_work(&hw->usb_work);
-                               wlandev->netdev->stats.tx_errors++;
-                               break;
-                       }
+                       netdev_warn(hw->wlandev->netdev,
+                                   "%s tx pipe stalled: requesting reset\n",
+                                   wlandev->netdev->name);
+                       if (!test_and_set_bit(WORK_TX_HALT, &hw->usb_flags))
+                               schedule_work(&hw->usb_work);
+                       wlandev->netdev->stats.tx_errors++;
+                       break;
+               }
 
                case -EPROTO:
                case -ETIMEDOUT:
-               case -EILSEQ:
-                       {
-                               struct hfa384x *hw = wlandev->priv;
-
-                               if (!test_and_set_bit
-                                   (THROTTLE_TX, &hw->usb_flags) &&
-                                   !timer_pending(&hw->throttle)) {
-                                       mod_timer(&hw->throttle,
-                                                 jiffies + THROTTLE_JIFFIES);
-                               }
-                               wlandev->netdev->stats.tx_errors++;
-                               netif_stop_queue(wlandev->netdev);
-                               break;
+               case -EILSEQ: {
+                       struct hfa384x *hw = wlandev->priv;
+
+                       if (!test_and_set_bit(THROTTLE_TX, &hw->usb_flags) &&
+                           !timer_pending(&hw->throttle)) {
+                               mod_timer(&hw->throttle,
+                                         jiffies + THROTTLE_JIFFIES);
                        }
+                       wlandev->netdev->stats.tx_errors++;
+                       netif_stop_queue(wlandev->netdev);
+                       break;
+               }
 
                case -ENOENT:
                case -ESHUTDOWN:
index 91debcf206468e152e6d6a4df2822d4e5b68542f..0ff5fda81b05b5c1684fe74f7cd01b13357e93f0 100644 (file)
@@ -430,7 +430,7 @@ int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
                        /* A bogus length ethfrm has been sent. */
                        /* Is someone trying an oflow attack? */
                        netdev_err(netdev, "DIXII frame too large (%ld > %d)\n",
-                                  (long int)(payload_length -
+                                  (long)(payload_length -
                                   sizeof(struct wlan_llc) -
                                   sizeof(struct wlan_snap)), netdev->mtu);
                        return 1;
index e63b4b557d0aa63c2ae5e64f75052b5425dc24e2..1b91b64c12ed1a6a0527f555b7775dac1ae59113 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
-/* This file is GENERATED AUTOMATICALLY.  DO NOT EDIT OR MODIFY.
- * --------------------------------------------------------------------
+/* --------------------------------------------------------------------
  *
  * Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
  * --------------------------------------------------------------------
 #ifndef _P80211MKMETADEF_H
 #define _P80211MKMETADEF_H
 
-#define DIDmsg_dot11req_mibget \
+#define DIDMSG_DOT11REQ_MIBGET \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(1))
-#define DIDmsg_dot11req_mibget_mibattribute \
+#define DIDMSG_DOT11REQ_MIBGET_MIBATTRIBUTE \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_mibget_resultcode \
+#define DIDMSG_DOT11REQ_MIBGET_RESULTCODE \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_mibset \
+#define DIDMSG_DOT11REQ_MIBSET \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(2))
-#define DIDmsg_dot11req_mibset_mibattribute \
+#define DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(2) | \
                        P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_mibset_resultcode \
+#define DIDMSG_DOT11REQ_MIBSET_RESULTCODE \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(2) | \
                        P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_scan \
+#define DIDMSG_DOT11REQ_SCAN \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(4))
-#define DIDmsg_dot11req_scan_results \
+#define DIDMSG_DOT11REQ_SCAN_RESULTS \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(5))
-#define DIDmsg_dot11req_start \
+#define DIDMSG_DOT11REQ_START \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(13))
-#define DIDmsg_dot11ind_authenticate \
+#define DIDMSG_DOT11IND_AUTHENTICATE \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1))
-#define DIDmsg_dot11ind_associate \
+#define DIDMSG_DOT11IND_ASSOCIATE \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(3))
-#define DIDmsg_lnxreq_ifstate \
+#define DIDMSG_LNXREQ_IFSTATE \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(1))
-#define DIDmsg_lnxreq_wlansniff \
+#define DIDMSG_LNXREQ_WLANSNIFF \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(2))
-#define DIDmsg_lnxreq_hostwep \
+#define DIDMSG_LNXREQ_HOSTWEP \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(3))
-#define DIDmsg_lnxreq_commsquality \
+#define DIDMSG_LNXREQ_COMMSQUALITY \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(4))
-#define DIDmsg_lnxreq_autojoin \
+#define DIDMSG_LNXREQ_AUTOJOIN \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(5))
-#define DIDmsg_p2req_readpda \
+#define DIDMSG_P2REQ_READPDA \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(2))
-#define DIDmsg_p2req_readpda_pda \
+#define DIDMSG_P2REQ_READPDA_PDA \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(2) | \
                        P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_readpda_resultcode \
+#define DIDMSG_P2REQ_READPDA_RESULTCODE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(2) | \
                        P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state \
+#define DIDMSG_P2REQ_RAMDL_STATE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(11))
-#define DIDmsg_p2req_ramdl_state_enable \
+#define DIDMSG_P2REQ_RAMDL_STATE_ENABLE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(11) | \
                        P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state_exeaddr \
+#define DIDMSG_P2REQ_RAMDL_STATE_EXEADDR \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(11) | \
                        P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state_resultcode \
+#define DIDMSG_P2REQ_RAMDL_STATE_RESULTCODE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(11) | \
                        P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write \
+#define DIDMSG_P2REQ_RAMDL_WRITE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(12))
-#define DIDmsg_p2req_ramdl_write_addr \
+#define DIDMSG_P2REQ_RAMDL_WRITE_ADDR \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(12) | \
                        P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_len \
+#define DIDMSG_P2REQ_RAMDL_WRITE_LEN \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(12) | \
                        P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_data \
+#define DIDMSG_P2REQ_RAMDL_WRITE_DATA \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(12) | \
                        P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_resultcode \
+#define DIDMSG_P2REQ_RAMDL_WRITE_RESULTCODE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(12) | \
                        P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_p2req_flashdl_state \
+#define DIDMSG_P2REQ_FLASHDL_STATE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(13))
-#define DIDmsg_p2req_flashdl_write \
+#define DIDMSG_P2REQ_FLASHDL_WRITE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(14))
-#define DIDmib_cat_dot11smt \
+#define DIDMIB_CAT_DOT11SMT \
                        P80211DID_MKSECTION(1)
-#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
+#define DIDMIB_DOT11SMT_WEPDEFAULTKEYSTABLE \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(4))
-#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(_i) \
-                       (DIDmib_dot11smt_dot11WEPDefaultKeysTable | \
+#define didmib_dot11smt_wepdefaultkeystable_key(_i) \
+                       (DIDMIB_DOT11SMT_WEPDEFAULTKEYSTABLE | \
                        P80211DID_MKITEM(_i) | 0x0c000000)
-#define DIDmib_dot11smt_dot11PrivacyTable \
+#define DIDMIB_DOT11SMT_PRIVACYTABLE \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(6))
-#define DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked \
+#define DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(6) | \
                        P80211DID_MKITEM(1) | 0x18000000)
-#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID \
+#define DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(6) | \
                        P80211DID_MKITEM(2) | 0x18000000)
-#define DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted \
+#define DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED \
                        (P80211DID_MKSECTION(1) | \
                        P80211DID_MKGROUP(6) | \
                        P80211DID_MKITEM(4) | 0x18000000)
-#define DIDmib_dot11mac_dot11OperationTable \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1))
-#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(1) | 0x18000000)
-#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(2) | 0x18000000)
-#define DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(3) | 0x10000000)
-#define DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(4) | 0x10000000)
-#define DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(5) | 0x18000000)
-#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
+#define DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME \
                        (P80211DID_MKSECTION(2) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(6) | 0x10000000)
-#define DIDmib_cat_dot11phy \
+#define DIDMIB_CAT_DOT11PHY \
                        P80211DID_MKSECTION(3)
-#define DIDmib_dot11phy_dot11PhyOperationTable \
+#define DIDMIB_DOT11PHY_OPERATIONTABLE \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(1))
-#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
+#define DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(3) | \
                        P80211DID_MKITEM(10) | 0x18000000)
-#define DIDmib_dot11phy_dot11PhyDSSSTable \
+#define DIDMIB_DOT11PHY_DSSSTABLE \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(5))
-#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel \
+#define DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL \
                        (P80211DID_MKSECTION(3) | \
                        P80211DID_MKGROUP(5) | \
                        P80211DID_MKITEM(1) | 0x10000000)
-#define DIDmib_cat_lnx \
+#define DIDMIB_CAT_LNX \
                        P80211DID_MKSECTION(4)
-#define DIDmib_lnx_lnxConfigTable \
+#define DIDMIB_LNX_CONFIGTABLE \
                        (P80211DID_MKSECTION(4) | \
                        P80211DID_MKGROUP(1))
-#define DIDmib_lnx_lnxConfigTable_lnxRSNAIE \
+#define DIDMIB_LNX_CONFIGTABLE_RSNAIE \
                        (P80211DID_MKSECTION(4) | \
                        P80211DID_MKGROUP(1) | \
                        P80211DID_MKITEM(1) | 0x18000000)
-#define DIDmib_cat_p2 \
+#define DIDMIB_CAT_P2 \
                        P80211DID_MKSECTION(5)
-#define DIDmib_p2_p2Static \
+#define DIDMIB_P2_STATIC \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(2))
-#define DIDmib_p2_p2Static_p2CnfPortType \
+#define DIDMIB_P2_STATIC_CNFPORTTYPE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(2) | \
                        P80211DID_MKITEM(1) | 0x18000000)
-#define DIDmib_p2_p2NIC_p2PRISupRange \
+#define DIDMIB_P2_NIC_PRISUPRANGE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(5) | \
                        P80211DID_MKITEM(6) | 0x10000000)
-#define DIDmib_p2_p2MAC \
+#define DIDMIB_P2_MAC \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(6))
-#define DIDmib_p2_p2MAC_p2CurrentTxRate \
+#define DIDMIB_P2_MAC_CURRENTTXRATE \
                        (P80211DID_MKSECTION(5) | \
                        P80211DID_MKGROUP(6) | \
                        P80211DID_MKITEM(12) | 0x10000000)
index 5602ec60607411bcb1f7fb731e83c3104098d06a..4adc64580185a14c56fce2ac3be0e6d99bbd1e2e 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */
-/* This file is GENERATED AUTOMATICALLY.  DO NOT EDIT OR MODIFY.
- * --------------------------------------------------------------------
+/* --------------------------------------------------------------------
  *
  * Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
  * --------------------------------------------------------------------
index 8258cb5a335d8a21c11f5e04e8b6432d66e061c4..a70fb84f38f16ca5018e6f3554cdd58f5eeb9417 100644 (file)
@@ -638,25 +638,25 @@ static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
 
        /* Set up a dot11req_mibset */
        memset(&dot11req, 0, sizeof(dot11req));
-       dot11req.msgcode = DIDmsg_dot11req_mibset;
+       dot11req.msgcode = DIDMSG_DOT11REQ_MIBSET;
        dot11req.msglen = sizeof(dot11req);
        memcpy(dot11req.devname,
               ((struct wlandevice *)dev->ml_priv)->name,
               WLAN_DEVNAMELEN_MAX - 1);
 
        /* Set up the mibattribute argument */
-       mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
+       mibattr->did = DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE;
        mibattr->status = P80211ENUM_msgitem_status_data_ok;
        mibattr->len = sizeof(mibattr->data);
 
-       macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
+       macaddr->did = DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS;
        macaddr->status = P80211ENUM_msgitem_status_data_ok;
        macaddr->len = sizeof(macaddr->data);
        macaddr->data.len = ETH_ALEN;
        memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
 
        /* Set up the resultcode argument */
-       resultcode->did = DIDmsg_dot11req_mibset_resultcode;
+       resultcode->did = DIDMSG_DOT11REQ_MIBSET_RESULTCODE;
        resultcode->status = P80211ENUM_msgitem_status_no_value;
        resultcode->len = sizeof(resultcode->data);
        resultcode->data = 0;
@@ -927,10 +927,6 @@ static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc)
        /* Classify frame, increment counter */
        ftype = WLAN_GET_FC_FTYPE(fc);
        fstype = WLAN_GET_FC_FSTYPE(fc);
-#if 0
-       netdev_dbg(wlandev->netdev, "rx_typedrop : ftype=%d fstype=%d.\n",
-                  ftype, fstype);
-#endif
        switch (ftype) {
        case WLAN_FTYPE_MGMT:
                if ((wlandev->netdev->flags & IFF_PROMISC) ||
index c36d01469afc6d11187a9ab2adba771f81af4ed5..9f5c1267d82954f9e1732822a7fc378fe620f8d7 100644 (file)
@@ -117,7 +117,7 @@ int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf)
 
        /* Check to make sure the MSD is running */
        if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
-              msg->msgcode == DIDmsg_lnxreq_ifstate) ||
+              msg->msgcode == DIDMSG_LNXREQ_IFSTATE) ||
              wlandev->msdstate == WLAN_MSD_RUNNING ||
              wlandev->msdstate == WLAN_MSD_FWLOAD)) {
                return -ENODEV;
@@ -125,7 +125,7 @@ int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf)
 
        /* Check Permissions */
        if (!capable(CAP_NET_ADMIN) &&
-           (msg->msgcode != DIDmsg_dot11req_mibget)) {
+           (msg->msgcode != DIDMSG_DOT11REQ_MIBGET)) {
                netdev_err(wlandev->netdev,
                           "%s: only dot11req_mibget allowed for non-root.\n",
                           wlandev->name);
@@ -172,7 +172,7 @@ static void p80211req_handlemsg(struct wlandevice *wlandev,
                                struct p80211msg *msg)
 {
        switch (msg->msgcode) {
-       case DIDmsg_lnxreq_hostwep:{
+       case DIDMSG_LNXREQ_HOSTWEP: {
                struct p80211msg_lnxreq_hostwep *req =
                        (struct p80211msg_lnxreq_hostwep *)msg;
                wlandev->hostwep &=
@@ -182,15 +182,15 @@ static void p80211req_handlemsg(struct wlandevice *wlandev,
                if (req->encrypt.data == P80211ENUM_truth_true)
                        wlandev->hostwep |= HOSTWEP_ENCRYPT;
 
-       break;
+               break;
        }
-       case DIDmsg_dot11req_mibget:
-       case DIDmsg_dot11req_mibset:{
-               int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+       case DIDMSG_DOT11REQ_MIBGET:
+       case DIDMSG_DOT11REQ_MIBSET: {
+               int isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET);
                struct p80211msg_dot11req_mibget *mib_msg =
                        (struct p80211msg_dot11req_mibget *)msg;
                p80211req_mibset_mibget(wlandev, mib_msg, isget);
-       break;
+               break;
        }
        }                       /* switch msg->msgcode */
 }
@@ -205,17 +205,17 @@ static void p80211req_mibset_mibget(struct wlandevice *wlandev,
        u8 *key = mibitem->data + sizeof(struct p80211pstrd);
 
        switch (mibitem->did) {
-       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(1):
-       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(2):
-       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(3):
-       case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(4):
+       case didmib_dot11smt_wepdefaultkeystable_key(1):
+       case didmib_dot11smt_wepdefaultkeystable_key(2):
+       case didmib_dot11smt_wepdefaultkeystable_key(3):
+       case didmib_dot11smt_wepdefaultkeystable_key(4):
                if (!isget)
                        wep_change_key(wlandev,
                                       P80211DID_ITEM(mibitem->did) - 1,
                                       key, pstr->len);
                break;
 
-       case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID:{
+       case DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID: {
                u32 *data = (u32 *)mibitem->data;
 
                if (isget) {
@@ -224,21 +224,21 @@ static void p80211req_mibset_mibget(struct wlandevice *wlandev,
                        wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
                        wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
                }
-       break;
+               break;
        }
-       case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked:{
+       case DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED: {
                u32 *data = (u32 *)mibitem->data;
 
                p80211req_handle_action(wlandev, data, isget,
                                        HOSTWEP_PRIVACYINVOKED);
-       break;
+               break;
        }
-       case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted:{
+       case DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED: {
                u32 *data = (u32 *)mibitem->data;
 
                p80211req_handle_action(wlandev, data, isget,
                                        HOSTWEP_EXCLUDEUNENCRYPTED);
-       break;
+               break;
        }
        }
 }
index 4fb91294570da3b2838e44b5d7f45890463f6778..f99626ca6bdc95a465ac507aaa2439c563e125cc 100644 (file)
@@ -294,17 +294,17 @@ static int prism2_fwapply(const struct ihex_binrec *rfptr,
 
        /* read the card's PRI-SUP */
        memset(&getmsg, 0, sizeof(getmsg));
-       getmsg.msgcode = DIDmsg_dot11req_mibget;
+       getmsg.msgcode = DIDMSG_DOT11REQ_MIBGET;
        getmsg.msglen = sizeof(getmsg);
        strcpy(getmsg.devname, wlandev->name);
 
-       getmsg.mibattribute.did = DIDmsg_dot11req_mibget_mibattribute;
+       getmsg.mibattribute.did = DIDMSG_DOT11REQ_MIBGET_MIBATTRIBUTE;
        getmsg.mibattribute.status = P80211ENUM_msgitem_status_data_ok;
-       getmsg.resultcode.did = DIDmsg_dot11req_mibget_resultcode;
+       getmsg.resultcode.did = DIDMSG_DOT11REQ_MIBGET_RESULTCODE;
        getmsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
 
        item = (struct p80211itemd *)getmsg.mibattribute.data;
-       item->did = DIDmib_p2_p2NIC_p2PRISupRange;
+       item->did = DIDMIB_P2_NIC_PRISUPRANGE;
        item->status = P80211ENUM_msgitem_status_no_value;
 
        data = (u32 *)item->data;
@@ -706,7 +706,7 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
                        pr_warn("warning: Failed to find PDR for plugrec 0x%04x.\n",
                                s3plug[i].itemcode);
                        continue;       /* and move on to the next PDR */
-#if 0
+
                        /* MSM: They swear that unless it's the MAC address,
                         * the serial number, or the TX calibration records,
                         * then there's reasonable defaults in the f/w
@@ -714,9 +714,6 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
                         * should only be a warning, not fatal.
                         * TODO: add fatals for the PDRs mentioned above.
                         */
-                       result = 1;
-                       continue;
-#endif
                }
 
                /* Validate plug len against PDR len */
@@ -790,13 +787,13 @@ static int read_cardpda(struct pda *pda, struct wlandevice *wlandev)
                return -ENOMEM;
 
        /* set up the msg */
-       msg->msgcode = DIDmsg_p2req_readpda;
+       msg->msgcode = DIDMSG_P2REQ_READPDA;
        msg->msglen = sizeof(msg);
        strcpy(msg->devname, wlandev->name);
-       msg->pda.did = DIDmsg_p2req_readpda_pda;
+       msg->pda.did = DIDMSG_P2REQ_READPDA_PDA;
        msg->pda.len = HFA384x_PDA_LEN_MAX;
        msg->pda.status = P80211ENUM_msgitem_status_no_value;
-       msg->resultcode.did = DIDmsg_p2req_readpda_resultcode;
+       msg->resultcode.did = DIDMSG_P2REQ_READPDA_RESULTCODE;
        msg->resultcode.len = sizeof(u32);
        msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
 
@@ -1024,11 +1021,11 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
 
        /* Initialize the messages */
        strcpy(rstmsg->devname, wlandev->name);
-       rstmsg->msgcode = DIDmsg_p2req_ramdl_state;
+       rstmsg->msgcode = DIDMSG_P2REQ_RAMDL_STATE;
        rstmsg->msglen = sizeof(*rstmsg);
-       rstmsg->enable.did = DIDmsg_p2req_ramdl_state_enable;
-       rstmsg->exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
-       rstmsg->resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
+       rstmsg->enable.did = DIDMSG_P2REQ_RAMDL_STATE_ENABLE;
+       rstmsg->exeaddr.did = DIDMSG_P2REQ_RAMDL_STATE_EXEADDR;
+       rstmsg->resultcode.did = DIDMSG_P2REQ_RAMDL_STATE_RESULTCODE;
        rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok;
        rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok;
        rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
@@ -1037,12 +1034,12 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
        rstmsg->resultcode.len = sizeof(u32);
 
        strcpy(rwrmsg->devname, wlandev->name);
-       rwrmsg->msgcode = DIDmsg_p2req_ramdl_write;
+       rwrmsg->msgcode = DIDMSG_P2REQ_RAMDL_WRITE;
        rwrmsg->msglen = sizeof(*rwrmsg);
-       rwrmsg->addr.did = DIDmsg_p2req_ramdl_write_addr;
-       rwrmsg->len.did = DIDmsg_p2req_ramdl_write_len;
-       rwrmsg->data.did = DIDmsg_p2req_ramdl_write_data;
-       rwrmsg->resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
+       rwrmsg->addr.did = DIDMSG_P2REQ_RAMDL_WRITE_ADDR;
+       rwrmsg->len.did = DIDMSG_P2REQ_RAMDL_WRITE_LEN;
+       rwrmsg->data.did = DIDMSG_P2REQ_RAMDL_WRITE_DATA;
+       rwrmsg->resultcode.did = DIDMSG_P2REQ_RAMDL_WRITE_RESULTCODE;
        rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok;
        rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok;
        rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok;
index e88baf715cec33a43eea91cfd3af8f240d31579b..5c0dad42f5232f72b95973c830675dc98438d0cd 100644 (file)
@@ -148,89 +148,89 @@ static int prism2mib_priv(struct mibrec *mib,
 
 static struct mibrec mibtab[] = {
        /* dot11smt MIB's */
-       {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(1),
+       {didmib_dot11smt_wepdefaultkeystable_key(1),
         F_STA | F_WRITE,
         HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
         prism2mib_wepdefaultkey},
-       {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(2),
+       {didmib_dot11smt_wepdefaultkeystable_key(2),
         F_STA | F_WRITE,
         HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
         prism2mib_wepdefaultkey},
-       {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(3),
+       {didmib_dot11smt_wepdefaultkeystable_key(3),
         F_STA | F_WRITE,
         HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
         prism2mib_wepdefaultkey},
-       {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(4),
+       {didmib_dot11smt_wepdefaultkeystable_key(4),
         F_STA | F_WRITE,
         HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
         prism2mib_wepdefaultkey},
-       {DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+       {DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
         prism2mib_privacyinvoked},
-       {DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+       {DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
         prism2mib_uint32},
-       {DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+       {DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
         prism2mib_excludeunencrypted},
 
        /* dot11mac MIB's */
 
-       {DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
+       {DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
         prism2mib_bytearea2pstr},
-       {DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+       {DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_RTSTHRESH, 0, 0,
         prism2mib_uint32},
-       {DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
+       {DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT,
         F_STA | F_READ,
         HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
         prism2mib_uint32},
-       {DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
+       {DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT,
         F_STA | F_READ,
         HFA384x_RID_LONGRETRYLIMIT, 0, 0,
         prism2mib_uint32},
-       {DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+       {DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_FRAGTHRESH, 0, 0,
         prism2mib_fragmentationthreshold},
-       {DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
+       {DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME,
         F_STA | F_READ,
         HFA384x_RID_MAXTXLIFETIME, 0, 0,
         prism2mib_uint32},
 
        /* dot11phy MIB's */
 
-       {DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+       {DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL,
         F_STA | F_READ,
         HFA384x_RID_CURRENTCHANNEL, 0, 0,
         prism2mib_uint32},
-       {DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+       {DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_TXPOWERMAX, 0, 0,
         prism2mib_uint32},
 
        /* p2Static MIB's */
 
-       {DIDmib_p2_p2Static_p2CnfPortType,
+       {DIDMIB_P2_STATIC_CNFPORTTYPE,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_CNFPORTTYPE, 0, 0,
         prism2mib_uint32},
 
        /* p2MAC MIB's */
 
-       {DIDmib_p2_p2MAC_p2CurrentTxRate,
+       {DIDMIB_P2_MAC_CURRENTTXRATE,
         F_STA | F_READ,
         HFA384x_RID_CURRENTTXRATE, 0, 0,
         prism2mib_uint32},
 
        /* And finally, lnx mibs */
-       {DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
+       {DIDMIB_LNX_CONFIGTABLE_RSNAIE,
         F_STA | F_READ | F_WRITE,
         HFA384x_RID_CNFWPADATA, 0, 0,
         prism2mib_priv},
@@ -301,7 +301,7 @@ int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp)
         ** this is a "mibset" so make make sure that the MIB may be written.
         */
 
-       isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+       isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET);
 
        if (isget) {
                if (!(mib->flag & F_READ)) {
@@ -707,27 +707,27 @@ static int prism2mib_priv(struct mibrec *mib,
        struct p80211pstrd *pstr = data;
 
        switch (mib->did) {
-       case DIDmib_lnx_lnxConfigTable_lnxRSNAIE:{
-                       struct hfa384x_wpa_data wpa;
+       case DIDMIB_LNX_CONFIGTABLE_RSNAIE: {
+               struct hfa384x_wpa_data wpa;
 
-                       if (isget) {
-                               hfa384x_drvr_getconfig(hw,
-                                                      HFA384x_RID_CNFWPADATA,
-                                                      (u8 *)&wpa,
-                                                      sizeof(wpa));
-                               pstr->len = le16_to_cpu(wpa.datalen);
-                               memcpy(pstr->data, wpa.data, pstr->len);
-                       } else {
-                               wpa.datalen = cpu_to_le16(pstr->len);
-                               memcpy(wpa.data, pstr->data, pstr->len);
-
-                               hfa384x_drvr_setconfig(hw,
-                                                      HFA384x_RID_CNFWPADATA,
-                                                      (u8 *)&wpa,
-                                                      sizeof(wpa));
-                       }
-                       break;
+               if (isget) {
+                       hfa384x_drvr_getconfig(hw,
+                                              HFA384x_RID_CNFWPADATA,
+                                              (u8 *)&wpa,
+                                              sizeof(wpa));
+                       pstr->len = le16_to_cpu(wpa.datalen);
+                       memcpy(pstr->data, wpa.data, pstr->len);
+               } else {
+                       wpa.datalen = cpu_to_le16(pstr->len);
+                       memcpy(wpa.data, pstr->data, pstr->len);
+
+                       hfa384x_drvr_setconfig(hw,
+                                              HFA384x_RID_CNFWPADATA,
+                                              (u8 *)&wpa,
+                                              sizeof(wpa));
                }
+               break;
+       }
        default:
                netdev_err(wlandev->netdev, "Unhandled DID 0x%08x\n", mib->did);
        }
index 9149702496801adb8b3d36b1c89a7371d8208cbe..fb54413991313b8b6fd688a3be4cc15eb4502a3f 100644 (file)
@@ -288,99 +288,93 @@ static int prism2sta_mlmerequest(struct wlandevice *wlandev,
        int result = 0;
 
        switch (msg->msgcode) {
-       case DIDmsg_dot11req_mibget:
+       case DIDMSG_DOT11REQ_MIBGET:
                pr_debug("Received mibget request\n");
                result = prism2mgmt_mibset_mibget(wlandev, msg);
                break;
-       case DIDmsg_dot11req_mibset:
+       case DIDMSG_DOT11REQ_MIBSET:
                pr_debug("Received mibset request\n");
                result = prism2mgmt_mibset_mibget(wlandev, msg);
                break;
-       case DIDmsg_dot11req_scan:
+       case DIDMSG_DOT11REQ_SCAN:
                pr_debug("Received scan request\n");
                result = prism2mgmt_scan(wlandev, msg);
                break;
-       case DIDmsg_dot11req_scan_results:
+       case DIDMSG_DOT11REQ_SCAN_RESULTS:
                pr_debug("Received scan_results request\n");
                result = prism2mgmt_scan_results(wlandev, msg);
                break;
-       case DIDmsg_dot11req_start:
+       case DIDMSG_DOT11REQ_START:
                pr_debug("Received mlme start request\n");
                result = prism2mgmt_start(wlandev, msg);
                break;
                /*
                 * Prism2 specific messages
                 */
-       case DIDmsg_p2req_readpda:
+       case DIDMSG_P2REQ_READPDA:
                pr_debug("Received mlme readpda request\n");
                result = prism2mgmt_readpda(wlandev, msg);
                break;
-       case DIDmsg_p2req_ramdl_state:
+       case DIDMSG_P2REQ_RAMDL_STATE:
                pr_debug("Received mlme ramdl_state request\n");
                result = prism2mgmt_ramdl_state(wlandev, msg);
                break;
-       case DIDmsg_p2req_ramdl_write:
+       case DIDMSG_P2REQ_RAMDL_WRITE:
                pr_debug("Received mlme ramdl_write request\n");
                result = prism2mgmt_ramdl_write(wlandev, msg);
                break;
-       case DIDmsg_p2req_flashdl_state:
+       case DIDMSG_P2REQ_FLASHDL_STATE:
                pr_debug("Received mlme flashdl_state request\n");
                result = prism2mgmt_flashdl_state(wlandev, msg);
                break;
-       case DIDmsg_p2req_flashdl_write:
+       case DIDMSG_P2REQ_FLASHDL_WRITE:
                pr_debug("Received mlme flashdl_write request\n");
                result = prism2mgmt_flashdl_write(wlandev, msg);
                break;
                /*
                 * Linux specific messages
                 */
-       case DIDmsg_lnxreq_hostwep:
+       case DIDMSG_LNXREQ_HOSTWEP:
                break;          /* ignore me. */
-       case DIDmsg_lnxreq_ifstate:
-               {
-                       struct p80211msg_lnxreq_ifstate *ifstatemsg;
-
-                       pr_debug("Received mlme ifstate request\n");
-                       ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg;
-                       result =
-                           prism2sta_ifstate(wlandev,
-                                             ifstatemsg->ifstate.data);
-                       ifstatemsg->resultcode.status =
-                           P80211ENUM_msgitem_status_data_ok;
-                       ifstatemsg->resultcode.data = result;
-                       result = 0;
-               }
+       case DIDMSG_LNXREQ_IFSTATE: {
+               struct p80211msg_lnxreq_ifstate *ifstatemsg;
+
+               pr_debug("Received mlme ifstate request\n");
+               ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg;
+               result = prism2sta_ifstate(wlandev,
+                                          ifstatemsg->ifstate.data);
+               ifstatemsg->resultcode.status =
+                       P80211ENUM_msgitem_status_data_ok;
+               ifstatemsg->resultcode.data = result;
+               result = 0;
                break;
-       case DIDmsg_lnxreq_wlansniff:
+       }
+       case DIDMSG_LNXREQ_WLANSNIFF:
                pr_debug("Received mlme wlansniff request\n");
                result = prism2mgmt_wlansniff(wlandev, msg);
                break;
-       case DIDmsg_lnxreq_autojoin:
+       case DIDMSG_LNXREQ_AUTOJOIN:
                pr_debug("Received mlme autojoin request\n");
                result = prism2mgmt_autojoin(wlandev, msg);
                break;
-       case DIDmsg_lnxreq_commsquality:{
-                       struct p80211msg_lnxreq_commsquality *qualmsg;
+       case DIDMSG_LNXREQ_COMMSQUALITY: {
+               struct p80211msg_lnxreq_commsquality *qualmsg;
 
-                       pr_debug("Received commsquality request\n");
+               pr_debug("Received commsquality request\n");
 
-                       qualmsg = (struct p80211msg_lnxreq_commsquality *)msg;
+               qualmsg = (struct p80211msg_lnxreq_commsquality *)msg;
 
-                       qualmsg->link.status =
-                           P80211ENUM_msgitem_status_data_ok;
-                       qualmsg->level.status =
-                           P80211ENUM_msgitem_status_data_ok;
-                       qualmsg->noise.status =
-                           P80211ENUM_msgitem_status_data_ok;
+               qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
+               qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
+               qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
 
-                       qualmsg->link.data = le16_to_cpu(hw->qual.cq_curr_bss);
-                       qualmsg->level.data =
-                               le16_to_cpu(hw->qual.asl_curr_bss);
-                       qualmsg->noise.data = le16_to_cpu(hw->qual.anl_curr_fc);
-                       qualmsg->txrate.data = hw->txrate;
+               qualmsg->link.data = le16_to_cpu(hw->qual.cq_curr_bss);
+               qualmsg->level.data = le16_to_cpu(hw->qual.asl_curr_bss);
+               qualmsg->noise.data = le16_to_cpu(hw->qual.anl_curr_fc);
+               qualmsg->txrate.data = hw->txrate;
 
-                       break;
-               }
+               break;
+       }
        default:
                netdev_warn(wlandev->netdev,
                            "Unknown mgmt request message 0x%08x",
@@ -1949,8 +1943,8 @@ void prism2sta_commsqual_defer(struct work_struct *data)
        }
 
        /* Get the signal rate */
-       msg.msgcode = DIDmsg_dot11req_mibget;
-       mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate;
+       msg.msgcode = DIDMSG_DOT11REQ_MIBGET;
+       mibitem->did = DIDMIB_P2_MAC_CURRENTTXRATE;
        result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
        if (result) {
index e1aafe842d660bb11b1146133105f37bff24873e..34dce850067b9e9c379274ef8b3c91da4bb42ef0 100644 (file)
@@ -696,7 +696,7 @@ static int __init optee_driver_init(void)
                return -ENODEV;
 
        np = of_find_matching_node(fw_np, optee_match);
-       if (!np)
+       if (!np || !of_device_is_available(np))
                return -ENODEV;
 
        optee = optee_probe(np);
index dd46b758852aa9ba2866348e6f973da3447b3623..7b2bb4c500580099a2f6e443da6fab9e4db7ae00 100644 (file)
@@ -38,15 +38,13 @@ static DEFINE_SPINLOCK(driver_lock);
 static struct class *tee_class;
 static dev_t tee_devt;
 
-static int tee_open(struct inode *inode, struct file *filp)
+static struct tee_context *teedev_open(struct tee_device *teedev)
 {
        int rc;
-       struct tee_device *teedev;
        struct tee_context *ctx;
 
-       teedev = container_of(inode->i_cdev, struct tee_device, cdev);
        if (!tee_device_get(teedev))
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx) {
@@ -57,16 +55,16 @@ static int tee_open(struct inode *inode, struct file *filp)
        kref_init(&ctx->refcount);
        ctx->teedev = teedev;
        INIT_LIST_HEAD(&ctx->list_shm);
-       filp->private_data = ctx;
        rc = teedev->desc->ops->open(ctx);
        if (rc)
                goto err;
 
-       return 0;
+       return ctx;
 err:
        kfree(ctx);
        tee_device_put(teedev);
-       return rc;
+       return ERR_PTR(rc);
+
 }
 
 void teedev_ctx_get(struct tee_context *ctx)
@@ -100,6 +98,18 @@ static void teedev_close_context(struct tee_context *ctx)
        teedev_ctx_put(ctx);
 }
 
+static int tee_open(struct inode *inode, struct file *filp)
+{
+       struct tee_context *ctx;
+
+       ctx = teedev_open(container_of(inode->i_cdev, struct tee_device, cdev));
+       if (IS_ERR(ctx))
+               return PTR_ERR(ctx);
+
+       filp->private_data = ctx;
+       return 0;
+}
+
 static int tee_release(struct inode *inode, struct file *filp)
 {
        teedev_close_context(filp->private_data);
@@ -928,6 +938,95 @@ void *tee_get_drvdata(struct tee_device *teedev)
 }
 EXPORT_SYMBOL_GPL(tee_get_drvdata);
 
+struct match_dev_data {
+       struct tee_ioctl_version_data *vers;
+       const void *data;
+       int (*match)(struct tee_ioctl_version_data *, const void *);
+};
+
+static int match_dev(struct device *dev, const void *data)
+{
+       const struct match_dev_data *match_data = data;
+       struct tee_device *teedev = container_of(dev, struct tee_device, dev);
+
+       teedev->desc->ops->get_version(teedev, match_data->vers);
+       return match_data->match(match_data->vers, match_data->data);
+}
+
+struct tee_context *
+tee_client_open_context(struct tee_context *start,
+                       int (*match)(struct tee_ioctl_version_data *,
+                                    const void *),
+                       const void *data, struct tee_ioctl_version_data *vers)
+{
+       struct device *dev = NULL;
+       struct device *put_dev = NULL;
+       struct tee_context *ctx = NULL;
+       struct tee_ioctl_version_data v;
+       struct match_dev_data match_data = { vers ? vers : &v, data, match };
+
+       if (start)
+               dev = &start->teedev->dev;
+
+       do {
+               dev = class_find_device(tee_class, dev, &match_data, match_dev);
+               if (!dev) {
+                       ctx = ERR_PTR(-ENOENT);
+                       break;
+               }
+
+               put_device(put_dev);
+               put_dev = dev;
+
+               ctx = teedev_open(container_of(dev, struct tee_device, dev));
+       } while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM);
+
+       put_device(put_dev);
+       return ctx;
+}
+EXPORT_SYMBOL_GPL(tee_client_open_context);
+
+void tee_client_close_context(struct tee_context *ctx)
+{
+       teedev_close_context(ctx);
+}
+EXPORT_SYMBOL_GPL(tee_client_close_context);
+
+void tee_client_get_version(struct tee_context *ctx,
+                           struct tee_ioctl_version_data *vers)
+{
+       ctx->teedev->desc->ops->get_version(ctx->teedev, vers);
+}
+EXPORT_SYMBOL_GPL(tee_client_get_version);
+
+int tee_client_open_session(struct tee_context *ctx,
+                           struct tee_ioctl_open_session_arg *arg,
+                           struct tee_param *param)
+{
+       if (!ctx->teedev->desc->ops->open_session)
+               return -EINVAL;
+       return ctx->teedev->desc->ops->open_session(ctx, arg, param);
+}
+EXPORT_SYMBOL_GPL(tee_client_open_session);
+
+int tee_client_close_session(struct tee_context *ctx, u32 session)
+{
+       if (!ctx->teedev->desc->ops->close_session)
+               return -EINVAL;
+       return ctx->teedev->desc->ops->close_session(ctx, session);
+}
+EXPORT_SYMBOL_GPL(tee_client_close_session);
+
+int tee_client_invoke_func(struct tee_context *ctx,
+                          struct tee_ioctl_invoke_arg *arg,
+                          struct tee_param *param)
+{
+       if (!ctx->teedev->desc->ops->invoke_func)
+               return -EINVAL;
+       return ctx->teedev->desc->ops->invoke_func(ctx, arg, param);
+}
+EXPORT_SYMBOL_GPL(tee_client_invoke_func);
+
 static int __init tee_init(void)
 {
        int rc;
index 6ab982309e6a04cd3c933850d34aabaaf3dd60e4..d6ebc1cf6aa9b197089a07ed074610e0124869e5 100644 (file)
@@ -290,10 +290,12 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
                                            int delay)
 {
        if (delay > 1000)
-               mod_delayed_work(system_freezable_wq, &tz->poll_queue,
+               mod_delayed_work(system_freezable_power_efficient_wq,
+                                &tz->poll_queue,
                                 round_jiffies(msecs_to_jiffies(delay)));
        else if (delay)
-               mod_delayed_work(system_freezable_wq, &tz->poll_queue,
+               mod_delayed_work(system_freezable_power_efficient_wq,
+                                &tz->poll_queue,
                                 msecs_to_jiffies(delay));
        else
                cancel_delayed_work(&tz->poll_queue);
@@ -1102,8 +1104,9 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
        mutex_unlock(&thermal_list_lock);
 
        ida_simple_remove(&thermal_cdev_ida, cdev->id);
-       device_unregister(&cdev->device);
+       device_del(&cdev->device);
        thermal_cooling_device_destroy_sysfs(cdev);
+       put_device(&cdev->device);
 }
 EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
 
index eea4049b5dcc67836ec99f2f25faa8c4a24ccd4d..769e0a5d1dfccf346cc1c912d151b68ddc0ec6af 100644 (file)
@@ -128,8 +128,8 @@ static int find_console_handle(void)
         */
        iprop = of_get_property(np, "hv-handle", NULL);
        if (!iprop) {
-               pr_err("ehv-bc: no 'hv-handle' property in %s node\n",
-                      np->name);
+               pr_err("ehv-bc: no 'hv-handle' property in %pOFn node\n",
+                      np);
                return 0;
        }
        stdout_bc = be32_to_cpu(*iprop);
@@ -661,8 +661,8 @@ static int ehv_bc_tty_probe(struct platform_device *pdev)
 
        iprop = of_get_property(np, "hv-handle", NULL);
        if (!iprop) {
-               dev_err(&pdev->dev, "no 'hv-handle' property in %s node\n",
-                       np->name);
+               dev_err(&pdev->dev, "no 'hv-handle' property in %pOFn node\n",
+                       np);
                return -ENODEV;
        }
 
@@ -682,8 +682,8 @@ static int ehv_bc_tty_probe(struct platform_device *pdev)
        bc->rx_irq = irq_of_parse_and_map(np, 0);
        bc->tx_irq = irq_of_parse_and_map(np, 1);
        if ((bc->rx_irq == NO_IRQ) || (bc->tx_irq == NO_IRQ)) {
-               dev_err(&pdev->dev, "no 'interrupts' property in %s node\n",
-                       np->name);
+               dev_err(&pdev->dev, "no 'interrupts' property in %pOFn node\n",
+                       np);
                ret = -ENODEV;
                goto error;
        }
index 43174220170924e094567ad6271703bd881e2a6f..3ad460219fd62ea580bbdc7a9102ff22de881d14 100644 (file)
@@ -152,17 +152,28 @@ static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i)
        return &ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)];
 }
 
+/* If we are not echoing the data, perhaps this is a secret so erase it */
+static void zero_buffer(struct tty_struct *tty, u8 *buffer, int size)
+{
+       bool icanon = !!L_ICANON(tty);
+       bool no_echo = !L_ECHO(tty);
+
+       if (icanon && no_echo)
+               memset(buffer, 0x00, size);
+}
+
 static int tty_copy_to_user(struct tty_struct *tty, void __user *to,
                            size_t tail, size_t n)
 {
        struct n_tty_data *ldata = tty->disc_data;
        size_t size = N_TTY_BUF_SIZE - tail;
-       const void *from = read_buf_addr(ldata, tail);
+       void *from = read_buf_addr(ldata, tail);
        int uncopied;
 
        if (n > size) {
                tty_audit_add_data(tty, from, size);
                uncopied = copy_to_user(to, from, size);
+               zero_buffer(tty, from, size - uncopied);
                if (uncopied)
                        return uncopied;
                to += size;
@@ -171,7 +182,9 @@ static int tty_copy_to_user(struct tty_struct *tty, void __user *to,
        }
 
        tty_audit_add_data(tty, from, n);
-       return copy_to_user(to, from, n);
+       uncopied = copy_to_user(to, from, n);
+       zero_buffer(tty, from, n - uncopied);
+       return uncopied;
 }
 
 /**
@@ -1960,11 +1973,12 @@ static int copy_from_read_buf(struct tty_struct *tty,
        n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail);
        n = min(*nr, n);
        if (n) {
-               const unsigned char *from = read_buf_addr(ldata, tail);
+               unsigned char *from = read_buf_addr(ldata, tail);
                retval = copy_to_user(*b, from, n);
                n -= retval;
                is_eof = n == 1 && *from == EOF_CHAR(tty);
                tty_audit_add_data(tty, from, n);
+               zero_buffer(tty, from, n);
                smp_store_release(&ldata->read_tail, ldata->read_tail + n);
                /* Turn single EOF into zero-length read */
                if (L_EXTPROC(tty) && ldata->icanon && is_eof &&
index 8fe3d0ed229ed27c9bdb53ade9c356aaed1abc85..94f3e1c6449094125da28780d211d1341d2e0d8f 100644 (file)
@@ -130,12 +130,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 
                l = l->next;
 
-               if (l == i->head && pass_counter++ > PASS_LIMIT) {
-                       /* If we hit this, we're dead. */
-                       printk_ratelimited(KERN_ERR
-                               "serial8250: too much work for irq%d\n", irq);
+               if (l == i->head && pass_counter++ > PASS_LIMIT)
                        break;
-               }
        } while (l != end);
 
        spin_unlock(&i->lock);
index af8beefe9b5c30b1153ab3ac769e73faecb47ee3..877fd7f8a8ed14e708ec952afbf49790d6a4d09b 100644 (file)
@@ -58,7 +58,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
        struct resource resource;
        struct device_node *np = ofdev->dev.of_node;
        u32 clk, spd, prop;
-       int ret;
+       int ret, irq;
 
        memset(port, 0, sizeof *port);
 
@@ -143,21 +143,27 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
        if (ret >= 0)
                port->line = ret;
 
-       port->irq = irq_of_parse_and_map(np, 0);
-       if (!port->irq) {
-               ret = -EPROBE_DEFER;
-               goto err_unprepare;
+       irq = of_irq_get(np, 0);
+       if (irq < 0) {
+               if (irq == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto err_unprepare;
+               }
+               /* IRQ support not mandatory */
+               irq = 0;
        }
 
+       port->irq = irq;
+
        info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
        if (IS_ERR(info->rst)) {
                ret = PTR_ERR(info->rst);
-               goto err_dispose;
+               goto err_unprepare;
        }
 
        ret = reset_control_deassert(info->rst);
        if (ret)
-               goto err_dispose;
+               goto err_unprepare;
 
        port->type = type;
        port->uartclk = clk;
@@ -184,8 +190,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
                port->handle_irq = fsl8250_handle_irq;
 
        return 0;
-err_dispose:
-       irq_dispose_mapping(port->irq);
 err_unprepare:
        clk_disable_unprepare(info->clk);
 err_pmruntime:
index 3f779d25ec0cdfa10575b153b62dc34c0c5b218b..f776b3eafb9619578986f2c0a3b0234fc2842067 100644 (file)
@@ -552,11 +552,30 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
  */
 static void serial8250_clear_fifos(struct uart_8250_port *p)
 {
+       unsigned char fcr;
+       unsigned char clr_mask = UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
+
        if (p->capabilities & UART_CAP_FIFO) {
-               serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO);
-               serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO |
-                              UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-               serial_out(p, UART_FCR, 0);
+               /*
+                * Make sure to avoid changing FCR[7:3] and ENABLE_FIFO bits.
+                * In case ENABLE_FIFO is not set, there is nothing to flush
+                * so just return. Furthermore, on certain implementations of
+                * the 8250 core, the FCR[7:3] bits may only be changed under
+                * specific conditions and changing them if those conditions
+                * are not met can have nasty side effects. One such core is
+                * the 8250-omap present in TI AM335x.
+                */
+               fcr = serial_in(p, UART_FCR);
+
+               /* FIFO is not enabled, there's nothing to clear. */
+               if (!(fcr & UART_FCR_ENABLE_FIFO))
+                       return;
+
+               fcr |= clr_mask;
+               serial_out(p, UART_FCR, fcr);
+
+               fcr &= ~clr_mask;
+               serial_out(p, UART_FCR, fcr);
        }
 }
 
@@ -1448,7 +1467,7 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
         * Enable previously disabled RX interrupts.
         */
        if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
-               serial8250_clear_and_reinit_fifos(p);
+               serial8250_clear_fifos(p);
 
                p->ier |= UART_IER_RLSI | UART_IER_RDI;
                serial_port_out(&p->port, UART_IER, p->ier);
index 28d88ccf5a0c2da6c399141de475f8c741960e60..164ba133437af69176ce0ca8316c7d572a0ff99a 100644 (file)
@@ -12,9 +12,6 @@
 
 #include "8250.h"
 
-/* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */
-#define UNIPHIER_UART_DEFAULT_FIFO_SIZE        64
-
 /*
  * This hardware is similar to 8250, but its register map is a bit different:
  *   - MMIO32 (regshift = 2)
@@ -158,42 +155,6 @@ static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
        writel(value, up->port.membase + UNIPHIER_UART_DLR);
 }
 
-static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
-                                   struct uniphier8250_priv *priv)
-{
-       int ret;
-       u32 prop;
-       struct device_node *np = dev->of_node;
-
-       ret = of_alias_get_id(np, "serial");
-       if (ret < 0) {
-               dev_err(dev, "failed to get alias id\n");
-               return ret;
-       }
-       port->line = ret;
-
-       /* Get clk rate through clk driver */
-       priv->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               dev_err(dev, "failed to get clock\n");
-               return PTR_ERR(priv->clk);
-       }
-
-       ret = clk_prepare_enable(priv->clk);
-       if (ret < 0)
-               return ret;
-
-       port->uartclk = clk_get_rate(priv->clk);
-
-       /* Check for fifo size */
-       if (of_property_read_u32(np, "fifo-size", &prop) == 0)
-               port->fifosize = prop;
-       else
-               port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE;
-
-       return 0;
-}
-
 static int uniphier_uart_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -226,10 +187,25 @@ static int uniphier_uart_probe(struct platform_device *pdev)
 
        memset(&up, 0, sizeof(up));
 
-       ret = uniphier_of_serial_setup(dev, &up.port, priv);
-       if (ret < 0)
+       ret = of_alias_get_id(dev->of_node, "serial");
+       if (ret < 0) {
+               dev_err(dev, "failed to get alias id\n");
+               return ret;
+       }
+       up.port.line = ret;
+
+       priv->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(priv->clk)) {
+               dev_err(dev, "failed to get clock\n");
+               return PTR_ERR(priv->clk);
+       }
+
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
                return ret;
 
+       up.port.uartclk = clk_get_rate(priv->clk);
+
        spin_lock_init(&priv->atomic_write_lock);
 
        up.port.dev = dev;
@@ -241,10 +217,14 @@ static int uniphier_uart_probe(struct platform_device *pdev)
 
        up.port.type = PORT_16550A;
        up.port.iotype = UPIO_MEM32;
+       up.port.fifosize = 64;
        up.port.regshift = UNIPHIER_UART_REGSHIFT;
        up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE;
        up.capabilities = UART_CAP_FIFO;
 
+       if (of_property_read_bool(dev->of_node, "auto-flow-control"))
+               up.capabilities |= UART_CAP_AFE;
+
        up.port.serial_in = uniphier_serial_in;
        up.port.serial_out = uniphier_serial_out;
        up.dl_read = uniphier_serial_dl_read;
index f005eaf8bc57aab704adffc21258f8ee5e8cabbf..15c2c54638354744beb9a7031ce4f98344e9be1e 100644 (file)
@@ -375,7 +375,7 @@ config SERIAL_8250_RT288X
 
 config SERIAL_8250_OMAP
        tristate "Support for OMAP internal UART (8250 based driver)"
-       depends on SERIAL_8250 && ARCH_OMAP2PLUS
+       depends on SERIAL_8250 && (ARCH_OMAP2PLUS || ARCH_K3)
        help
          If you have a machine based on an Texas Instruments OMAP CPU you
          can enable its onboard serial ports by enabling this option.
index 267d4d1de3f877f0bb8d5060bf43921222f23f2a..05147fe243434a52e4ca827227d95dc1f6a0f2e6 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/suspend.h>
 #include <linux/mm.h>
 
+#include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/ioctls.h>
 
@@ -147,6 +148,8 @@ struct atmel_uart_port {
        struct circ_buf         rx_ring;
 
        struct mctrl_gpios      *gpios;
+       u32                     backup_mode;    /* MR saved during iso7816 operations */
+       u32                     backup_brgr;    /* BRGR saved during iso7816 operations */
        unsigned int            tx_done_mask;
        u32                     fifo_size;
        u32                     rts_high;
@@ -163,6 +166,10 @@ struct atmel_uart_port {
        unsigned int            pending_status;
        spinlock_t              lock_suspended;
 
+       /* ISO7816 */
+       unsigned int            fidi_min;
+       unsigned int            fidi_max;
+
 #ifdef CONFIG_PM
        struct {
                u32             cr;
@@ -361,6 +368,127 @@ static int atmel_config_rs485(struct uart_port *port,
        return 0;
 }
 
+static unsigned int atmel_calc_cd(struct uart_port *port,
+                                 struct serial_iso7816 *iso7816conf)
+{
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+       unsigned int cd;
+       u64 mck_rate;
+
+       mck_rate = (u64)clk_get_rate(atmel_port->clk);
+       do_div(mck_rate, iso7816conf->clk);
+       cd = mck_rate;
+       return cd;
+}
+
+static unsigned int atmel_calc_fidi(struct uart_port *port,
+                                   struct serial_iso7816 *iso7816conf)
+{
+       u64 fidi = 0;
+
+       if (iso7816conf->sc_fi && iso7816conf->sc_di) {
+               fidi = (u64)iso7816conf->sc_fi;
+               do_div(fidi, iso7816conf->sc_di);
+       }
+       return (u32)fidi;
+}
+
+/* Enable or disable the iso7816 support */
+/* Called with interrupts disabled */
+static int atmel_config_iso7816(struct uart_port *port,
+                               struct serial_iso7816 *iso7816conf)
+{
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+       unsigned int mode;
+       unsigned int cd, fidi;
+       int ret = 0;
+
+       /* Disable interrupts */
+       atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
+
+       mode = atmel_uart_readl(port, ATMEL_US_MR);
+
+       if (iso7816conf->flags & SER_ISO7816_ENABLED) {
+               mode &= ~ATMEL_US_USMODE;
+
+               if (iso7816conf->tg > 255) {
+                       dev_err(port->dev, "ISO7816: Timeguard exceeding 255\n");
+                       memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+                       ret = -EINVAL;
+                       goto err_out;
+               }
+
+               if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+                   == SER_ISO7816_T(0)) {
+                       mode |= ATMEL_US_USMODE_ISO7816_T0 | ATMEL_US_DSNACK;
+               } else if ((iso7816conf->flags & SER_ISO7816_T_PARAM)
+                          == SER_ISO7816_T(1)) {
+                       mode |= ATMEL_US_USMODE_ISO7816_T1 | ATMEL_US_INACK;
+               } else {
+                       dev_err(port->dev, "ISO7816: Type not supported\n");
+                       memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+                       ret = -EINVAL;
+                       goto err_out;
+               }
+
+               mode &= ~(ATMEL_US_USCLKS | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+
+               /* select mck clock, and output  */
+               mode |= ATMEL_US_USCLKS_MCK | ATMEL_US_CLKO;
+               /* set parity for normal/inverse mode + max iterations */
+               mode |= ATMEL_US_PAR_EVEN | ATMEL_US_NBSTOP_1 | ATMEL_US_MAX_ITER(3);
+
+               cd = atmel_calc_cd(port, iso7816conf);
+               fidi = atmel_calc_fidi(port, iso7816conf);
+               if (fidi == 0) {
+                       dev_warn(port->dev, "ISO7816 fidi = 0, Generator generates no signal\n");
+               } else if (fidi < atmel_port->fidi_min
+                          || fidi > atmel_port->fidi_max) {
+                       dev_err(port->dev, "ISO7816 fidi = %u, value not supported\n", fidi);
+                       memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+                       ret = -EINVAL;
+                       goto err_out;
+               }
+
+               if (!(port->iso7816.flags & SER_ISO7816_ENABLED)) {
+                       /* port not yet in iso7816 mode: store configuration */
+                       atmel_port->backup_mode = atmel_uart_readl(port, ATMEL_US_MR);
+                       atmel_port->backup_brgr = atmel_uart_readl(port, ATMEL_US_BRGR);
+               }
+
+               atmel_uart_writel(port, ATMEL_US_TTGR, iso7816conf->tg);
+               atmel_uart_writel(port, ATMEL_US_BRGR, cd);
+               atmel_uart_writel(port, ATMEL_US_FIDI, fidi);
+
+               atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXDIS | ATMEL_US_RXEN);
+               atmel_port->tx_done_mask = ATMEL_US_TXEMPTY | ATMEL_US_NACK | ATMEL_US_ITERATION;
+       } else {
+               dev_dbg(port->dev, "Setting UART back to RS232\n");
+               /* back to last RS232 settings */
+               mode = atmel_port->backup_mode;
+               memset(iso7816conf, 0, sizeof(struct serial_iso7816));
+               atmel_uart_writel(port, ATMEL_US_TTGR, 0);
+               atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->backup_brgr);
+               atmel_uart_writel(port, ATMEL_US_FIDI, 0x174);
+
+               if (atmel_use_pdc_tx(port))
+                       atmel_port->tx_done_mask = ATMEL_US_ENDTX |
+                                                  ATMEL_US_TXBUFE;
+               else
+                       atmel_port->tx_done_mask = ATMEL_US_TXRDY;
+       }
+
+       port->iso7816 = *iso7816conf;
+
+       atmel_uart_writel(port, ATMEL_US_MR, mode);
+
+err_out:
+       /* Enable interrupts */
+       atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask);
+
+       return ret;
+}
+
 /*
  * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
  */
@@ -480,8 +608,9 @@ static void atmel_stop_tx(struct uart_port *port)
        /* Disable interrupts */
        atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
 
-       if ((port->rs485.flags & SER_RS485_ENABLED) &&
-           !(port->rs485.flags & SER_RS485_RX_DURING_TX))
+       if (((port->rs485.flags & SER_RS485_ENABLED) &&
+            !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
+           port->iso7816.flags & SER_ISO7816_ENABLED)
                atmel_start_rx(port);
 }
 
@@ -499,8 +628,9 @@ static void atmel_start_tx(struct uart_port *port)
                return;
 
        if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
-               if ((port->rs485.flags & SER_RS485_ENABLED) &&
-                   !(port->rs485.flags & SER_RS485_RX_DURING_TX))
+               if (((port->rs485.flags & SER_RS485_ENABLED) &&
+                    !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
+                   port->iso7816.flags & SER_ISO7816_ENABLED)
                        atmel_stop_rx(port);
 
        if (atmel_use_pdc_tx(port))
@@ -798,8 +928,9 @@ static void atmel_complete_tx_dma(void *arg)
         */
        if (!uart_circ_empty(xmit))
                atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
-       else if ((port->rs485.flags & SER_RS485_ENABLED) &&
-                !(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
+       else if (((port->rs485.flags & SER_RS485_ENABLED) &&
+                 !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
+                port->iso7816.flags & SER_ISO7816_ENABLED) {
                /* DMA done, stop TX, start RX for RS485 */
                atmel_start_rx(port);
        }
@@ -1282,6 +1413,9 @@ atmel_handle_status(struct uart_port *port, unsigned int pending,
                        wake_up_interruptible(&port->state->port.delta_msr_wait);
                }
        }
+
+       if (pending & (ATMEL_US_NACK | ATMEL_US_ITERATION))
+               dev_dbg(port->dev, "ISO7816 ERROR (0x%08x)\n", pending);
 }
 
 /*
@@ -1374,8 +1508,9 @@ static void atmel_tx_pdc(struct uart_port *port)
                atmel_uart_writel(port, ATMEL_US_IER,
                                  atmel_port->tx_done_mask);
        } else {
-               if ((port->rs485.flags & SER_RS485_ENABLED) &&
-                   !(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
+               if (((port->rs485.flags & SER_RS485_ENABLED) &&
+                    !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
+                   port->iso7816.flags & SER_ISO7816_ENABLED) {
                        /* DMA done, stop TX, start RX for RS485 */
                        atmel_start_rx(port);
                }
@@ -1727,6 +1862,22 @@ static void atmel_get_ip_name(struct uart_port *port)
                atmel_port->has_frac_baudrate = true;
                atmel_port->has_hw_timer = true;
                atmel_port->rtor = ATMEL_US_RTOR;
+               version = atmel_uart_readl(port, ATMEL_US_VERSION);
+               switch (version) {
+               case 0x814:     /* sama5d2 */
+                       /* fall through */
+               case 0x701:     /* sama5d4 */
+                       atmel_port->fidi_min = 3;
+                       atmel_port->fidi_max = 65535;
+                       break;
+               case 0x502:     /* sam9x5, sama5d3 */
+                       atmel_port->fidi_min = 3;
+                       atmel_port->fidi_max = 2047;
+                       break;
+               default:
+                       atmel_port->fidi_min = 1;
+                       atmel_port->fidi_max = 2047;
+               }
        } else if (name == dbgu_uart) {
                dev_dbg(port->dev, "Dbgu or uart without hw timer\n");
        } else {
@@ -2100,6 +2251,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
                atmel_uart_writel(port, ATMEL_US_TTGR,
                                  port->rs485.delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
+       } else if (port->iso7816.flags & SER_ISO7816_ENABLED) {
+               atmel_uart_writel(port, ATMEL_US_TTGR, port->iso7816.tg);
+               /* select mck clock, and output  */
+               mode |= ATMEL_US_USCLKS_MCK | ATMEL_US_CLKO;
+               /* set max iterations */
+               mode |= ATMEL_US_MAX_ITER(3);
+               if ((port->iso7816.flags & SER_ISO7816_T_PARAM)
+                               == SER_ISO7816_T(0))
+                       mode |= ATMEL_US_USMODE_ISO7816_T0;
+               else
+                       mode |= ATMEL_US_USMODE_ISO7816_T1;
        } else if (termios->c_cflag & CRTSCTS) {
                /* RS232 with hardware handshake (RTS/CTS) */
                if (atmel_use_fifo(port) &&
@@ -2176,7 +2338,8 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
        }
        quot = cd | fp << ATMEL_US_FP_OFFSET;
 
-       atmel_uart_writel(port, ATMEL_US_BRGR, quot);
+       if (!(port->iso7816.flags & SER_ISO7816_ENABLED))
+               atmel_uart_writel(port, ATMEL_US_BRGR, quot);
        atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
        atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
        atmel_port->tx_stopped = false;
@@ -2357,6 +2520,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
        port->mapbase           = mpdev->resource[0].start;
        port->irq               = mpdev->resource[1].start;
        port->rs485_config      = atmel_config_rs485;
+       port->iso7816_config    = atmel_config_iso7816;
        port->membase           = NULL;
 
        memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
@@ -2380,8 +2544,12 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
                /* only enable clock when USART is in use */
        }
 
-       /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
-       if (port->rs485.flags & SER_RS485_ENABLED)
+       /*
+        * Use TXEMPTY for interrupt when rs485 or ISO7816 else TXRDY or
+        * ENDTX|TXBUFE
+        */
+       if (port->rs485.flags & SER_RS485_ENABLED ||
+           port->iso7816.flags & SER_ISO7816_ENABLED)
                atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
        else if (atmel_use_pdc_tx(port)) {
                port->fifosize = PDC_BUFFER_SIZE;
index ba3a2437cde4c68d99ff77d229f55fe75e1987e5..d811d4f2d0c06c8ffe0370093dc161651c222524 100644 (file)
@@ -78,7 +78,8 @@
 #define        ATMEL_US_OVER           BIT(19) /* Oversampling Mode */
 #define        ATMEL_US_INACK          BIT(20) /* Inhibit Non Acknowledge */
 #define        ATMEL_US_DSNACK         BIT(21) /* Disable Successive NACK */
-#define        ATMEL_US_MAX_ITER       GENMASK(26, 24) /* Max Iterations */
+#define        ATMEL_US_MAX_ITER_MASK  GENMASK(26, 24) /* Max Iterations */
+#define        ATMEL_US_MAX_ITER(n)    (((n) << 24) & ATMEL_US_MAX_ITER_MASK)
 #define        ATMEL_US_FILTER         BIT(28) /* Infrared Receive Line Filter */
 
 #define ATMEL_US_IER           0x08    /* Interrupt Enable Register */
index e5389591bb4f1f83a207ee5be7e3577648972599..b929c7ae3a27eab8c28c218d8f467e62ae91862e 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/console.h>
 #include <linux/sysrq.h>
 #include <linux/device.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/dma-mapping.h>
 #include <linux/fs_uart_pd.h>
 #include <linux/of_address.h>
@@ -1155,8 +1155,8 @@ static int cpm_uart_init_port(struct device_node *np,
        if (!pinfo->clk) {
                data = of_get_property(np, "fsl,cpm-brg", &len);
                if (!data || len != 4) {
-                       printk(KERN_ERR "CPM UART %s has no/invalid "
-                                       "fsl,cpm-brg property.\n", np->name);
+                       printk(KERN_ERR "CPM UART %pOFn has no/invalid "
+                                       "fsl,cpm-brg property.\n", np);
                        return -EINVAL;
                }
                pinfo->brg = *data;
@@ -1164,8 +1164,8 @@ static int cpm_uart_init_port(struct device_node *np,
 
        data = of_get_property(np, "fsl,cpm-command", &len);
        if (!data || len != 4) {
-               printk(KERN_ERR "CPM UART %s has no/invalid "
-                               "fsl,cpm-command property.\n", np->name);
+               printk(KERN_ERR "CPM UART %pOFn has no/invalid "
+                               "fsl,cpm-command property.\n", np);
                return -EINVAL;
        }
        pinfo->command = *data;
index 4eba17f3d2936ed92c4eac28b848051876a46b31..56fc527015cba508da1269950e8c68793f1a1347 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/console.h>
 #include <linux/sysrq.h>
 #include <linux/device.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
index e3bff068dc3c62a93f551a2f6bbddbcceeeb2aac..6a1cd03bfe396386b878f846ede4429234e6b006 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/console.h>
 #include <linux/sysrq.h>
 #include <linux/device.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
index 3f8d1274fc85c2ee0306d93db03042e55c7e193d..00c220e4f43c035ba470c3414f8e070e08845d98 100644 (file)
 /* IMX lpuart has four extra unused regs located at the beginning */
 #define IMX_REG_OFF    0x10
 
+static DEFINE_IDA(fsl_lpuart_ida);
+
 struct lpuart_port {
        struct uart_port        port;
        struct clk              *clk;
@@ -2143,8 +2145,11 @@ static int lpuart_probe(struct platform_device *pdev)
 
        ret = of_alias_get_id(np, "serial");
        if (ret < 0) {
-               dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
-               return ret;
+               ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "port line is full, add device failed\n");
+                       return ret;
+               }
        }
        if (ret >= ARRAY_SIZE(lpuart_ports)) {
                dev_err(&pdev->dev, "serial%d out of range\n", ret);
@@ -2246,6 +2251,8 @@ static int lpuart_remove(struct platform_device *pdev)
 
        uart_remove_one_port(&lpuart_reg, &sport->port);
 
+       ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
+
        clk_disable_unprepare(sport->clk);
 
        if (sport->dma_tx_chan)
@@ -2384,6 +2391,7 @@ static int __init lpuart_serial_init(void)
 
 static void __exit lpuart_serial_exit(void)
 {
+       ida_destroy(&fsl_lpuart_ida);
        platform_driver_unregister(&lpuart_driver);
        uart_unregister_driver(&lpuart_reg);
 }
index 0f67197a3783ffdd62eccd3b41a813a80d66b6df..d4e051b578f6b941207176c471dc7645c33bef69 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/serial.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/rational.h>
 #include <linux/slab.h>
 #include <linux/of.h>
@@ -706,27 +707,25 @@ static irqreturn_t imx_uart_rtsint(int irq, void *dev_id)
 {
        struct imx_port *sport = dev_id;
        u32 usr1;
-       unsigned long flags;
 
-       spin_lock_irqsave(&sport->port.lock, flags);
+       spin_lock(&sport->port.lock);
 
        imx_uart_writel(sport, USR1_RTSD, USR1);
        usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS;
        uart_handle_cts_change(&sport->port, !!usr1);
        wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
 
-       spin_unlock_irqrestore(&sport->port.lock, flags);
+       spin_unlock(&sport->port.lock);
        return IRQ_HANDLED;
 }
 
 static irqreturn_t imx_uart_txint(int irq, void *dev_id)
 {
        struct imx_port *sport = dev_id;
-       unsigned long flags;
 
-       spin_lock_irqsave(&sport->port.lock, flags);
+       spin_lock(&sport->port.lock);
        imx_uart_transmit_buffer(sport);
-       spin_unlock_irqrestore(&sport->port.lock, flags);
+       spin_unlock(&sport->port.lock);
        return IRQ_HANDLED;
 }
 
@@ -735,9 +734,8 @@ static irqreturn_t imx_uart_rxint(int irq, void *dev_id)
        struct imx_port *sport = dev_id;
        unsigned int rx, flg, ignored = 0;
        struct tty_port *port = &sport->port.state->port;
-       unsigned long flags;
 
-       spin_lock_irqsave(&sport->port.lock, flags);
+       spin_lock(&sport->port.lock);
 
        while (imx_uart_readl(sport, USR2) & USR2_RDR) {
                u32 usr2;
@@ -797,7 +795,7 @@ static irqreturn_t imx_uart_rxint(int irq, void *dev_id)
        }
 
 out:
-       spin_unlock_irqrestore(&sport->port.lock, flags);
+       spin_unlock(&sport->port.lock);
        tty_flip_buffer_push(port);
        return IRQ_HANDLED;
 }
@@ -903,13 +901,11 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
        }
 
        if (usr1 & USR1_DTRD) {
-               unsigned long flags;
-
                imx_uart_writel(sport, USR1_DTRD, USR1);
 
-               spin_lock_irqsave(&sport->port.lock, flags);
+               spin_lock(&sport->port.lock);
                imx_uart_mctrl_check(sport);
-               spin_unlock_irqrestore(&sport->port.lock, flags);
+               spin_unlock(&sport->port.lock);
 
                ret = IRQ_HANDLED;
        }
@@ -2384,8 +2380,13 @@ static int imx_uart_remove(struct platform_device *pdev)
 
 static void imx_uart_restore_context(struct imx_port *sport)
 {
-       if (!sport->context_saved)
+       unsigned long flags;
+
+       spin_lock_irqsave(&sport->port.lock, flags);
+       if (!sport->context_saved) {
+               spin_unlock_irqrestore(&sport->port.lock, flags);
                return;
+       }
 
        imx_uart_writel(sport, sport->saved_reg[4], UFCR);
        imx_uart_writel(sport, sport->saved_reg[5], UESC);
@@ -2398,11 +2399,15 @@ static void imx_uart_restore_context(struct imx_port *sport)
        imx_uart_writel(sport, sport->saved_reg[2], UCR3);
        imx_uart_writel(sport, sport->saved_reg[3], UCR4);
        sport->context_saved = false;
+       spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
 static void imx_uart_save_context(struct imx_port *sport)
 {
+       unsigned long flags;
+
        /* Save necessary regs */
+       spin_lock_irqsave(&sport->port.lock, flags);
        sport->saved_reg[0] = imx_uart_readl(sport, UCR1);
        sport->saved_reg[1] = imx_uart_readl(sport, UCR2);
        sport->saved_reg[2] = imx_uart_readl(sport, UCR3);
@@ -2414,6 +2419,7 @@ static void imx_uart_save_context(struct imx_port *sport)
        sport->saved_reg[8] = imx_uart_readl(sport, UBMR);
        sport->saved_reg[9] = imx_uart_readl(sport, IMX21_UTS);
        sport->context_saved = true;
+       spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
 static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
@@ -2447,6 +2453,8 @@ static int imx_uart_suspend_noirq(struct device *dev)
 
        clk_disable(sport->clk_ipg);
 
+       pinctrl_pm_select_sleep_state(dev);
+
        return 0;
 }
 
@@ -2455,6 +2463,8 @@ static int imx_uart_resume_noirq(struct device *dev)
        struct imx_port *sport = dev_get_drvdata(dev);
        int ret;
 
+       pinctrl_pm_select_default_state(dev);
+
        ret = clk_enable(sport->clk_ipg);
        if (ret)
                return ret;
index b4ba2b1dab767cac45a96dd6f0e2064ad138447c..baeeeaec3f030f94d7c0176647dff851e6647232 100644 (file)
@@ -8,6 +8,9 @@
  *
  * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/kgdb.h>
@@ -128,19 +131,6 @@ static void kgdboc_unregister_kbd(void)
 #define kgdboc_restore_input()
 #endif /* ! CONFIG_KDB_KEYBOARD */
 
-static int kgdboc_option_setup(char *opt)
-{
-       if (strlen(opt) >= MAX_CONFIG_LEN) {
-               printk(KERN_ERR "kgdboc: config string too long\n");
-               return -ENOSPC;
-       }
-       strcpy(config, opt);
-
-       return 0;
-}
-
-__setup("kgdboc=", kgdboc_option_setup);
-
 static void cleanup_kgdboc(void)
 {
        if (kgdb_unregister_nmi_console())
@@ -154,15 +144,13 @@ static int configure_kgdboc(void)
 {
        struct tty_driver *p;
        int tty_line = 0;
-       int err;
+       int err = -ENODEV;
        char *cptr = config;
        struct console *cons;
 
-       err = kgdboc_option_setup(config);
-       if (err || !strlen(config) || isspace(config[0]))
+       if (!strlen(config) || isspace(config[0]))
                goto noconfig;
 
-       err = -ENODEV;
        kgdboc_io_ops.is_console = 0;
        kgdb_tty_driver = NULL;
 
@@ -248,7 +236,7 @@ static int param_set_kgdboc_var(const char *kmessage,
        int len = strlen(kmessage);
 
        if (len >= MAX_CONFIG_LEN) {
-               printk(KERN_ERR "kgdboc: config string too long\n");
+               pr_err("config string too long\n");
                return -ENOSPC;
        }
 
@@ -259,8 +247,7 @@ static int param_set_kgdboc_var(const char *kmessage,
        }
 
        if (kgdb_connected) {
-               printk(KERN_ERR
-                      "kgdboc: Cannot reconfigure while KGDB is connected.\n");
+               pr_err("Cannot reconfigure while KGDB is connected.\n");
 
                return -EBUSY;
        }
@@ -311,6 +298,25 @@ static struct kgdb_io kgdboc_io_ops = {
 };
 
 #ifdef CONFIG_KGDB_SERIAL_CONSOLE
+static int kgdboc_option_setup(char *opt)
+{
+       if (!opt) {
+               pr_err("config string not provided\n");
+               return -EINVAL;
+       }
+
+       if (strlen(opt) >= MAX_CONFIG_LEN) {
+               pr_err("config string too long\n");
+               return -ENOSPC;
+       }
+       strcpy(config, opt);
+
+       return 0;
+}
+
+__setup("kgdboc=", kgdboc_option_setup);
+
+
 /* This is only available if kgdboc is a built in for early debugging */
 static int __init kgdboc_early_init(char *opt)
 {
index 76aa289652f7ae20a532e9355affc501de8fe763..27235a526cce8c4b59aa14f6764e466b10988748 100644 (file)
@@ -1634,8 +1634,9 @@ static int mxs_auart_request_gpio_irq(struct mxs_auart_port *s)
 
        /*
         * If something went wrong, rollback.
+        * Be careful: i may be unsigned.
         */
-       while (err && (--i >= 0))
+       while (err && (i-- > 0))
                if (irq[i] >= 0)
                        free_irq(irq[i], s);
 
index 3d21790d961e3d03ce92c360408eff5b9ff974df..a9d40988e1c8d6dff1cc996d1b5f0c40b752060c 100644 (file)
@@ -219,7 +219,7 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
 static bool pmz_receive_chars(struct uart_pmac_port *uap)
 {
        struct tty_port *port;
-       unsigned char ch, r1, drop, error, flag;
+       unsigned char ch, r1, drop, flag;
        int loops = 0;
 
        /* Sanity check, make sure the old bug is no longer happening */
@@ -231,7 +231,6 @@ static bool pmz_receive_chars(struct uart_pmac_port *uap)
        port = &uap->port.state->port;
 
        while (1) {
-               error = 0;
                drop = 0;
 
                r1 = read_zsreg(uap, R1);
@@ -273,7 +272,6 @@ static bool pmz_receive_chars(struct uart_pmac_port *uap)
                uap->port.icount.rx++;
 
                if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) {
-                       error = 1;
                        if (r1 & BRK_ABRT) {
                                pmz_debug("pmz: got break !\n");
                                r1 &= ~(PAR_ERR | CRC_ERR);
@@ -1566,9 +1564,9 @@ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
         * to work around bugs in ancient Apple device-trees
         */
        if (macio_request_resources(uap->dev, "pmac_zilog"))
-               printk(KERN_WARNING "%s: Failed to request resource"
+               printk(KERN_WARNING "%pOFn: Failed to request resource"
                       ", port still active\n",
-                      uap->node->name);
+                      uap->node);
        else
                uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED;
 
index 1515074e18fb6d60a37de13daf6102b98712841f..d3b5261ee80af491ea8a0c6f365f0f83269eae6a 100644 (file)
@@ -851,6 +851,23 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 {
        struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
        unsigned int rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT;
+       u32 proto;
+
+       if (uart_console(uport))
+               port->tx_bytes_pw = 1;
+       else
+               port->tx_bytes_pw = 4;
+       port->rx_bytes_pw = RX_BYTES_PW;
+
+       proto = geni_se_read_proto(&port->se);
+       if (proto != GENI_SE_UART) {
+               dev_err(uport->dev, "Invalid FW loaded, proto: %d\n", proto);
+               return -ENXIO;
+       }
+
+       qcom_geni_serial_stop_rx(uport);
+
+       get_tx_fifo_size(port);
 
        set_rfr_wm(port);
        writel_relaxed(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
@@ -874,30 +891,19 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
                        return -ENOMEM;
        }
        port->setup = true;
+
        return 0;
 }
 
 static int qcom_geni_serial_startup(struct uart_port *uport)
 {
        int ret;
-       u32 proto;
        struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 
        scnprintf(port->name, sizeof(port->name),
                  "qcom_serial_%s%d",
                (uart_console(uport) ? "console" : "uart"), uport->line);
 
-       if (!uart_console(uport)) {
-               port->tx_bytes_pw = 4;
-               port->rx_bytes_pw = RX_BYTES_PW;
-       }
-       proto = geni_se_read_proto(&port->se);
-       if (proto != GENI_SE_UART) {
-               dev_err(uport->dev, "Invalid FW loaded, proto: %d\n", proto);
-               return -ENXIO;
-       }
-
-       get_tx_fifo_size(port);
        if (!port->setup) {
                ret = qcom_geni_serial_port_setup(uport);
                if (ret)
@@ -1056,6 +1062,7 @@ static int __init qcom_geni_console_setup(struct console *co, char *options)
        int bits = 8;
        int parity = 'n';
        int flow = 'n';
+       int ret;
 
        if (co->index >= GENI_UART_CONS_PORTS  || co->index < 0)
                return -ENXIO;
@@ -1071,21 +1078,10 @@ static int __init qcom_geni_console_setup(struct console *co, char *options)
        if (unlikely(!uport->membase))
                return -ENXIO;
 
-       if (geni_se_resources_on(&port->se)) {
-               dev_err(port->se.dev, "Error turning on resources\n");
-               return -ENXIO;
-       }
-
-       if (unlikely(geni_se_read_proto(&port->se) != GENI_SE_UART)) {
-               geni_se_resources_off(&port->se);
-               return -ENXIO;
-       }
-
        if (!port->setup) {
-               port->tx_bytes_pw = 1;
-               port->rx_bytes_pw = RX_BYTES_PW;
-               qcom_geni_serial_stop_rx(uport);
-               qcom_geni_serial_port_setup(uport);
+               ret = qcom_geni_serial_port_setup(uport);
+               if (ret)
+                       return ret;
        }
 
        if (options)
@@ -1203,11 +1199,12 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
 {
        struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 
+       /* If we've never been called, treat it as off */
+       if (old_state == UART_PM_STATE_UNDEFINED)
+               old_state = UART_PM_STATE_OFF;
+
        if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
                geni_se_resources_on(&port->se);
-       else if (!uart_console(uport) && (new_state == UART_PM_STATE_ON &&
-                               old_state == UART_PM_STATE_UNDEFINED))
-               geni_se_resources_on(&port->se);
        else if (new_state == UART_PM_STATE_OFF &&
                        old_state == UART_PM_STATE_ON)
                geni_se_resources_off(&port->se);
@@ -1263,14 +1260,12 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
        if (of_device_is_compatible(pdev->dev.of_node, "qcom,geni-debug-uart"))
                console = true;
 
-       if (pdev->dev.of_node) {
-               if (console) {
-                       drv = &qcom_geni_console_driver;
-                       line = of_alias_get_id(pdev->dev.of_node, "serial");
-               } else {
-                       drv = &qcom_geni_uart_driver;
-                       line = of_alias_get_id(pdev->dev.of_node, "hsuart");
-               }
+       if (console) {
+               drv = &qcom_geni_console_driver;
+               line = of_alias_get_id(pdev->dev.of_node, "serial");
+       } else {
+               drv = &qcom_geni_uart_driver;
+               line = of_alias_get_id(pdev->dev.of_node, "hsuart");
        }
 
        port = get_port_from_line(line, console);
index 2f8fa184aafaadbc9d796ec74588a19d3861caab..da1bd4bba8a9496962002b19252eed16468f7417 100644 (file)
@@ -1941,7 +1941,11 @@ static int s3c24xx_serial_resume(struct device *dev)
 
        if (port) {
                clk_prepare_enable(ourport->clk);
+               if (!IS_ERR(ourport->baudclk))
+                       clk_prepare_enable(ourport->baudclk);
                s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
+               if (!IS_ERR(ourport->baudclk))
+                       clk_disable_unprepare(ourport->baudclk);
                clk_disable_unprepare(ourport->clk);
 
                uart_resume_port(&s3c24xx_uart_drv, port);
@@ -1964,7 +1968,11 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
                        if (rx_enabled(port))
                                uintm &= ~S3C64XX_UINTM_RXD_MSK;
                        clk_prepare_enable(ourport->clk);
+                       if (!IS_ERR(ourport->baudclk))
+                               clk_prepare_enable(ourport->baudclk);
                        wr_regl(port, S3C64XX_UINTM, uintm);
+                       if (!IS_ERR(ourport->baudclk))
+                               clk_disable_unprepare(ourport->baudclk);
                        clk_disable_unprepare(ourport->clk);
                }
        }
index 243c9602505306c3d7581f7e58a5967b680df838..268098681856b4c06b82cb1189928915eb10259a 100644 (file)
@@ -328,6 +328,7 @@ struct sc16is7xx_port {
        struct kthread_worker           kworker;
        struct task_struct              *kworker_task;
        struct kthread_work             irq_work;
+       struct mutex                    efr_lock;
        struct sc16is7xx_one            p[0];
 };
 
@@ -499,6 +500,21 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
                div /= 4;
        }
 
+       /* In an amazing feat of design, the Enhanced Features Register shares
+        * the address of the Interrupt Identification Register, and is
+        * switched in by writing a magic value (0xbf) to the Line Control
+        * Register. Any interrupt firing during this time will see the EFR
+        * where it expects the IIR to be, leading to "Unexpected interrupt"
+        * messages.
+        *
+        * Prevent this possibility by claiming a mutex while accessing the
+        * EFR, and claiming the same mutex from within the interrupt handler.
+        * This is similar to disabling the interrupt, but that doesn't work
+        * because the bulk of the interrupt processing is run as a workqueue
+        * job in thread context.
+        */
+       mutex_lock(&s->efr_lock);
+
        lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
 
        /* Open the LCR divisors for configuration */
@@ -514,6 +530,8 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
        /* Put LCR back to the normal mode */
        sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
 
+       mutex_unlock(&s->efr_lock);
+
        sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
                              SC16IS7XX_MCR_CLKSEL_BIT,
                              prescaler);
@@ -657,7 +675,7 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
                uart_write_wakeup(port);
 }
 
-static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
+static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
 {
        struct uart_port *port = &s->p[portno].port;
 
@@ -666,7 +684,7 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
 
                iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG);
                if (iir & SC16IS7XX_IIR_NO_INT_BIT)
-                       break;
+                       return false;
 
                iir &= SC16IS7XX_IIR_ID_MASK;
 
@@ -688,16 +706,27 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
                                            port->line, iir);
                        break;
                }
-       } while (1);
+       } while (0);
+       return true;
 }
 
 static void sc16is7xx_ist(struct kthread_work *ws)
 {
        struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work);
-       int i;
 
-       for (i = 0; i < s->devtype->nr_uart; ++i)
-               sc16is7xx_port_irq(s, i);
+       mutex_lock(&s->efr_lock);
+
+       while (1) {
+               bool keep_polling = false;
+               int i;
+
+               for (i = 0; i < s->devtype->nr_uart; ++i)
+                       keep_polling |= sc16is7xx_port_irq(s, i);
+               if (!keep_polling)
+                       break;
+       }
+
+       mutex_unlock(&s->efr_lock);
 }
 
 static irqreturn_t sc16is7xx_irq(int irq, void *dev_id)
@@ -892,6 +921,9 @@ static void sc16is7xx_set_termios(struct uart_port *port,
        if (!(termios->c_cflag & CREAD))
                port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK;
 
+       /* As above, claim the mutex while accessing the EFR. */
+       mutex_lock(&s->efr_lock);
+
        sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
                             SC16IS7XX_LCR_CONF_MODE_B);
 
@@ -913,6 +945,8 @@ static void sc16is7xx_set_termios(struct uart_port *port,
        /* Update LCR register */
        sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
 
+       mutex_unlock(&s->efr_lock);
+
        /* Get baud rate generator configuration */
        baud = uart_get_baud_rate(port, termios, old,
                                  port->uartclk / 16 / 4 / 0xffff,
@@ -1178,6 +1212,7 @@ static int sc16is7xx_probe(struct device *dev,
        s->regmap = regmap;
        s->devtype = devtype;
        dev_set_drvdata(dev, s);
+       mutex_init(&s->efr_lock);
 
        kthread_init_worker(&s->kworker);
        kthread_init_work(&s->irq_work, sc16is7xx_ist);
index 54726c3f74c6249b4fab889b1e6691b5add53560..c439a5a1e6c078e71bda4ea756480b1344507707 100644 (file)
@@ -1302,6 +1302,58 @@ static int uart_set_rs485_config(struct uart_port *port,
        return 0;
 }
 
+static int uart_get_iso7816_config(struct uart_port *port,
+                                  struct serial_iso7816 __user *iso7816)
+{
+       unsigned long flags;
+       struct serial_iso7816 aux;
+
+       if (!port->iso7816_config)
+               return -ENOIOCTLCMD;
+
+       spin_lock_irqsave(&port->lock, flags);
+       aux = port->iso7816;
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       if (copy_to_user(iso7816, &aux, sizeof(aux)))
+               return -EFAULT;
+
+       return 0;
+}
+
+static int uart_set_iso7816_config(struct uart_port *port,
+                                  struct serial_iso7816 __user *iso7816_user)
+{
+       struct serial_iso7816 iso7816;
+       int i, ret;
+       unsigned long flags;
+
+       if (!port->iso7816_config)
+               return -ENOIOCTLCMD;
+
+       if (copy_from_user(&iso7816, iso7816_user, sizeof(*iso7816_user)))
+               return -EFAULT;
+
+       /*
+        * There are 5 words reserved for future use. Check that userspace
+        * doesn't put stuff in there to prevent breakages in the future.
+        */
+       for (i = 0; i < 5; i++)
+               if (iso7816.reserved[i])
+                       return -EINVAL;
+
+       spin_lock_irqsave(&port->lock, flags);
+       ret = port->iso7816_config(port, &iso7816);
+       spin_unlock_irqrestore(&port->lock, flags);
+       if (ret)
+               return ret;
+
+       if (copy_to_user(iso7816_user, &port->iso7816, sizeof(port->iso7816)))
+               return -EFAULT;
+
+       return 0;
+}
+
 /*
  * Called via sys_ioctl.  We can use spin_lock_irq() here.
  */
@@ -1371,6 +1423,14 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
        case TIOCSRS485:
                ret = uart_set_rs485_config(uport, uarg);
                break;
+
+       case TIOCSISO7816:
+               ret = uart_set_iso7816_config(state->uart_port, uarg);
+               break;
+
+       case TIOCGISO7816:
+               ret = uart_get_iso7816_config(state->uart_port, uarg);
+               break;
        default:
                if (uport->ops->ioctl)
                        ret = uport->ops->ioctl(uport, cmd, arg);
index ab3f6e91853da3c269cdb6c22c82226195778ece..ff6ba6d86cd8bf9ba43349fde40ec2d576ffed05 100644 (file)
@@ -1516,7 +1516,7 @@ static struct dma_chan *sci_request_dma_chan(struct uart_port *port,
        chan = dma_request_slave_channel(port->dev,
                                         dir == DMA_MEM_TO_DEV ? "tx" : "rx");
        if (!chan) {
-               dev_warn(port->dev, "dma_request_slave_channel failed\n");
+               dev_dbg(port->dev, "dma_request_slave_channel failed\n");
                return NULL;
        }
 
@@ -3414,6 +3414,12 @@ static int __init scif_early_console_setup(struct earlycon_device *device,
 {
        return early_console_setup(device, PORT_SCIF);
 }
+static int __init rzscifa_early_console_setup(struct earlycon_device *device,
+                                         const char *opt)
+{
+       port_cfg.regtype = SCIx_RZ_SCIFA_REGTYPE;
+       return early_console_setup(device, PORT_SCIF);
+}
 static int __init scifa_early_console_setup(struct earlycon_device *device,
                                          const char *opt)
 {
@@ -3432,6 +3438,7 @@ static int __init hscif_early_console_setup(struct earlycon_device *device,
 
 OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup);
 OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup);
+OF_EARLYCON_DECLARE(scif, "renesas,scif-r7s9210", rzscifa_early_console_setup);
 OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup);
 OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup);
 OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup);
index 42b9aded4eb1c6d47a9795d743a27af9627fa563..fe9170731c167a4f09ee0f60047de1ca46f05834 100644 (file)
@@ -888,7 +888,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
 
        /* somebody really wants this output, might be an
         * oops, kdb, panic, etc.  make sure they get it. */
-       if (spin_is_locked(&port->sc_port.lock)) {
+       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;
@@ -905,13 +905,11 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
                 */
 
                for (counter = 0; counter < 150; mdelay(125), counter++) {
-                       if (!spin_is_locked(&port->sc_port.lock)
-                           || stole_lock) {
-                               if (!stole_lock) {
-                                       spin_lock_irqsave(&port->sc_port.lock,
-                                                         flags);
-                                       got_lock = 1;
-                               }
+                       if (stole_lock)
+                               break;
+
+                       if (spin_trylock_irqsave(&port->sc_port.lock, flags)) {
+                               got_lock = 1;
                                break;
                        } else {
                                /* still locked */
@@ -938,7 +936,6 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
                puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
        } else {
                stole_lock = 0;
-               spin_lock_irqsave(&port->sc_port.lock, flags);
                sn_transmit_chars(port, 1);
                spin_unlock_irqrestore(&port->sc_port.lock, flags);
 
index 828f1143859c8010f9916fada4958e229ce4e555..4287ca305b6be269d246e82195453d3745d2e245 100644 (file)
@@ -45,6 +45,8 @@
 
 /* data number in TX and RX fifo */
 #define SPRD_STS1              0x000C
+#define SPRD_RX_FIFO_CNT_MASK  GENMASK(7, 0)
+#define SPRD_TX_FIFO_CNT_MASK  GENMASK(15, 8)
 
 /* interrupt enable register and its BITs */
 #define SPRD_IEN               0x0010
 #define SPRD_LCR_DATA_LEN6     0x4
 #define SPRD_LCR_DATA_LEN7     0x8
 #define SPRD_LCR_DATA_LEN8     0xc
-#define SPRD_LCR_PARITY        (BIT(0) | BIT(1))
+#define SPRD_LCR_PARITY                (BIT(0) | BIT(1))
 #define SPRD_LCR_PARITY_EN     0x2
 #define SPRD_LCR_EVEN_PAR      0x0
 #define SPRD_LCR_ODD_PAR       0x1
 
 /* control register 1 */
-#define SPRD_CTL1                      0x001C
+#define SPRD_CTL1              0x001C
 #define RX_HW_FLOW_CTL_THLD    BIT(6)
 #define RX_HW_FLOW_CTL_EN      BIT(7)
 #define TX_HW_FLOW_CTL_EN      BIT(8)
 #define RX_TOUT_THLD_DEF       0x3E00
-#define RX_HFC_THLD_DEF        0x40
+#define RX_HFC_THLD_DEF                0x40
 
 /* fifo threshold register */
 #define SPRD_CTL2              0x0020
-#define THLD_TX_EMPTY  0x40
-#define THLD_RX_FULL   0x40
+#define THLD_TX_EMPTY          0x40
+#define THLD_TX_EMPTY_SHIFT    8
+#define THLD_RX_FULL           0x40
 
 /* config baud rate register */
 #define SPRD_CLKD0             0x0024
+#define SPRD_CLKD0_MASK                GENMASK(15, 0)
 #define SPRD_CLKD1             0x0028
+#define SPRD_CLKD1_MASK                GENMASK(20, 16)
+#define SPRD_CLKD1_SHIFT       16
 
 /* interrupt mask status register */
-#define SPRD_IMSR                      0x002C
-#define SPRD_IMSR_RX_FIFO_FULL         BIT(0)
+#define SPRD_IMSR              0x002C
+#define SPRD_IMSR_RX_FIFO_FULL BIT(0)
 #define SPRD_IMSR_TX_FIFO_EMPTY        BIT(1)
-#define SPRD_IMSR_BREAK_DETECT         BIT(7)
-#define SPRD_IMSR_TIMEOUT              BIT(13)
-
-struct reg_backup {
-       u32 ien;
-       u32 ctrl0;
-       u32 ctrl1;
-       u32 ctrl2;
-       u32 clkd0;
-       u32 clkd1;
-       u32 dspwait;
-};
+#define SPRD_IMSR_BREAK_DETECT BIT(7)
+#define SPRD_IMSR_TIMEOUT      BIT(13)
 
 struct sprd_uart_port {
        struct uart_port port;
-       struct reg_backup reg_bak;
        char name[16];
 };
 
 static struct sprd_uart_port *sprd_port[UART_NR_MAX];
 static int sprd_ports_num;
 
-static inline unsigned int serial_in(struct uart_port *port, int offset)
+static inline unsigned int serial_in(struct uart_port *port,
+                                    unsigned int offset)
 {
        return readl_relaxed(port->membase + offset);
 }
 
-static inline void serial_out(struct uart_port *port, int offset, int value)
+static inline void serial_out(struct uart_port *port, unsigned int offset,
+                             int value)
 {
        writel_relaxed(value, port->membase + offset);
 }
 
 static unsigned int sprd_tx_empty(struct uart_port *port)
 {
-       if (serial_in(port, SPRD_STS1) & 0xff00)
+       if (serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK)
                return 0;
        else
                return TIOCSER_TEMT;
@@ -224,14 +221,15 @@ static inline void sprd_rx(struct uart_port *port)
        struct tty_port *tty = &port->state->port;
        unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT;
 
-       while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) {
+       while ((serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK) &&
+              max_count--) {
                lsr = serial_in(port, SPRD_LSR);
                ch = serial_in(port, SPRD_RXD);
                flag = TTY_NORMAL;
                port->icount.rx++;
 
                if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE |
-                       SPRD_LSR_FE | SPRD_LSR_OE))
+                          SPRD_LSR_FE | SPRD_LSR_OE))
                        if (handle_lsr_errors(port, &lsr, &flag))
                                continue;
                if (uart_handle_sysrq_char(port, ch))
@@ -294,8 +292,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
        if (ims & SPRD_IMSR_TIMEOUT)
                serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT);
 
-       if (ims & (SPRD_IMSR_RX_FIFO_FULL |
-               SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT))
+       if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT |
+                  SPRD_IMSR_TIMEOUT))
                sprd_rx(port);
 
        if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
@@ -314,16 +312,17 @@ static int sprd_startup(struct uart_port *port)
        struct sprd_uart_port *sp;
        unsigned long flags;
 
-       serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL));
+       serial_out(port, SPRD_CTL2,
+                  THLD_TX_EMPTY << THLD_TX_EMPTY_SHIFT | THLD_RX_FULL);
 
        /* clear rx fifo */
        timeout = SPRD_TIMEOUT;
-       while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff)
+       while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK)
                serial_in(port, SPRD_RXD);
 
        /* clear tx fifo */
        timeout = SPRD_TIMEOUT;
-       while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00)
+       while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK)
                cpu_relax();
 
        /* clear interrupt */
@@ -334,7 +333,7 @@ static int sprd_startup(struct uart_port *port)
        sp = container_of(port, struct sprd_uart_port, port);
        snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line);
        ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq,
-                               IRQF_SHARED, sp->name, port);
+                              IRQF_SHARED, sp->name, port);
        if (ret) {
                dev_err(port->dev, "fail to request serial irq %d, ret=%d\n",
                        port->irq, ret);
@@ -362,8 +361,8 @@ static void sprd_shutdown(struct uart_port *port)
 }
 
 static void sprd_set_termios(struct uart_port *port,
-                                   struct ktermios *termios,
-                                   struct ktermios *old)
+                            struct ktermios *termios,
+                            struct ktermios *old)
 {
        unsigned int baud, quot;
        unsigned int lcr = 0, fc;
@@ -444,10 +443,11 @@ static void sprd_set_termios(struct uart_port *port,
        }
 
        /* clock divider bit0~bit15 */
-       serial_out(port, SPRD_CLKD0, quot & 0xffff);
+       serial_out(port, SPRD_CLKD0, quot & SPRD_CLKD0_MASK);
 
        /* clock divider bit16~bit20 */
-       serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16);
+       serial_out(port, SPRD_CLKD1,
+                  (quot & SPRD_CLKD1_MASK) >> SPRD_CLKD1_SHIFT);
        serial_out(port, SPRD_LCR, lcr);
        fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF;
        serial_out(port, SPRD_CTL1, fc);
@@ -480,8 +480,7 @@ static void sprd_config_port(struct uart_port *port, int flags)
                port->type = PORT_SPRD;
 }
 
-static int sprd_verify_port(struct uart_port *port,
-                                  struct serial_struct *ser)
+static int sprd_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
        if (ser->type != PORT_SPRD)
                return -EINVAL;
@@ -521,7 +520,7 @@ static void wait_for_xmitr(struct uart_port *port)
                if (--tmout == 0)
                        break;
                udelay(1);
-       } while (status & 0xff00);
+       } while (status & SPRD_TX_FIFO_CNT_MASK);
 }
 
 static void sprd_console_putchar(struct uart_port *port, int ch)
@@ -531,7 +530,7 @@ static void sprd_console_putchar(struct uart_port *port, int ch)
 }
 
 static void sprd_console_write(struct console *co, const char *s,
-                                     unsigned int count)
+                              unsigned int count)
 {
        struct uart_port *port = &sprd_port[co->index]->port;
        int locked = 1;
@@ -594,23 +593,21 @@ static void sprd_putc(struct uart_port *port, int c)
        unsigned int timeout = SPRD_TIMEOUT;
 
        while (timeout-- &&
-                  !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER))
+              !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER))
                cpu_relax();
 
        writeb(c, port->membase + SPRD_TXD);
 }
 
-static void sprd_early_write(struct console *con, const char *s,
-                                   unsigned n)
+static void sprd_early_write(struct console *con, const char *s, unsigned int n)
 {
        struct earlycon_device *dev = con->data;
 
        uart_console_write(&dev->port, s, n, sprd_putc);
 }
 
-static int __init sprd_early_console_setup(
-                               struct earlycon_device *device,
-                               const char *opt)
+static int __init sprd_early_console_setup(struct earlycon_device *device,
+                                          const char *opt)
 {
        if (!device->port.membase)
                return -ENODEV;
@@ -692,8 +689,8 @@ static int sprd_probe(struct platform_device *pdev)
 
        index = sprd_probe_dt_alias(index, &pdev->dev);
 
-       sprd_port[index] = devm_kzalloc(&pdev->dev,
-               sizeof(*sprd_port[index]), GFP_KERNEL);
+       sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]),
+                                       GFP_KERNEL);
        if (!sprd_port[index])
                return -ENOMEM;
 
@@ -712,15 +709,12 @@ static int sprd_probe(struct platform_device *pdev)
                up->uartclk = clk_get_rate(clk);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "not provide mem resource\n");
-               return -ENODEV;
-       }
-       up->mapbase = res->start;
        up->membase = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(up->membase))
                return PTR_ERR(up->membase);
 
+       up->mapbase = res->start;
+
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(&pdev->dev, "not provide irq resource: %d\n", irq);
index 98d3eadd2fd0380e467b90f3340020ca1f3ccdd6..f0344adc86db422a40940fd66426fb64596cb6f5 100644 (file)
 #define ULITE_CONTROL_RST_RX   0x02
 #define ULITE_CONTROL_IE       0x10
 
+/* Static pointer to console port */
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+static struct uart_port *console_port;
+#endif
+
 struct uartlite_data {
        const struct uartlite_reg_ops *reg_ops;
        struct clk *clk;
@@ -472,7 +477,7 @@ static void ulite_console_putchar(struct uart_port *port, int ch)
 static void ulite_console_write(struct console *co, const char *s,
                                unsigned int count)
 {
-       struct uart_port *port = &ulite_ports[co->index];
+       struct uart_port *port = console_port;
        unsigned long flags;
        unsigned int ier;
        int locked = 1;
@@ -506,10 +511,8 @@ static int ulite_console_setup(struct console *co, char *options)
        int parity = 'n';
        int flow = 'n';
 
-       if (co->index < 0 || co->index >= ULITE_NR_UARTS)
-               return -EINVAL;
 
-       port = &ulite_ports[co->index];
+       port = console_port;
 
        /* Has the device been initialized yet? */
        if (!port->mapbase) {
@@ -541,14 +544,6 @@ static struct console ulite_console = {
        .data   = &ulite_uart_driver,
 };
 
-static int __init ulite_console_init(void)
-{
-       register_console(&ulite_console);
-       return 0;
-}
-
-console_initcall(ulite_console_init);
-
 static void early_uartlite_putc(struct uart_port *port, int c)
 {
        /*
@@ -660,6 +655,17 @@ static int ulite_assign(struct device *dev, int id, u32 base, int irq,
 
        dev_set_drvdata(dev, port);
 
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+       /*
+        * If console hasn't been found yet try to assign this port
+        * because it is required to be assigned for console setup function.
+        * If register_console() don't assign value, then console_port pointer
+        * is cleanup.
+        */
+       if (ulite_uart_driver.cons->index == -1)
+               console_port = port;
+#endif
+
        /* Register the port */
        rc = uart_add_one_port(&ulite_uart_driver, port);
        if (rc) {
@@ -669,6 +675,12 @@ static int ulite_assign(struct device *dev, int id, u32 base, int irq,
                return rc;
        }
 
+#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
+       /* This is not port which is used for console that's why clean it up */
+       if (ulite_uart_driver.cons->index == -1)
+               console_port = NULL;
+#endif
+
        return 0;
 }
 
@@ -776,13 +788,26 @@ static int ulite_probe(struct platform_device *pdev)
                pdata->clk = NULL;
        }
 
-       ret = clk_prepare(pdata->clk);
+       ret = clk_prepare_enable(pdata->clk);
        if (ret) {
                dev_err(&pdev->dev, "Failed to prepare clock\n");
                return ret;
        }
 
-       return ulite_assign(&pdev->dev, id, res->start, irq, pdata);
+       if (!ulite_uart_driver.state) {
+               dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
+               ret = uart_register_driver(&ulite_uart_driver);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Failed to register driver\n");
+                       return ret;
+               }
+       }
+
+       ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
+
+       clk_disable(pdata->clk);
+
+       return ret;
 }
 
 static int ulite_remove(struct platform_device *pdev)
@@ -813,25 +838,9 @@ static struct platform_driver ulite_platform_driver = {
 
 static int __init ulite_init(void)
 {
-       int ret;
-
-       pr_debug("uartlite: calling uart_register_driver()\n");
-       ret = uart_register_driver(&ulite_uart_driver);
-       if (ret)
-               goto err_uart;
 
        pr_debug("uartlite: calling platform_driver_register()\n");
-       ret = platform_driver_register(&ulite_platform_driver);
-       if (ret)
-               goto err_plat;
-
-       return 0;
-
-err_plat:
-       uart_unregister_driver(&ulite_uart_driver);
-err_uart:
-       pr_err("registering uartlite driver failed: err=%i\n", ret);
-       return ret;
+       return platform_driver_register(&ulite_platform_driver);
 }
 
 static void __exit ulite_exit(void)
index a48f19b1b88f1d48c5c6ae43389eb1e0ef79b9b7..57c66d2c347141e596b2240f00049413d31e9754 100644 (file)
@@ -30,8 +30,6 @@
 #define CDNS_UART_TTY_NAME     "ttyPS"
 #define CDNS_UART_NAME         "xuartps"
 #define CDNS_UART_MAJOR                0       /* use dynamic node allocation */
-#define CDNS_UART_MINOR                0       /* works best with devtmpfs */
-#define CDNS_UART_NR_PORTS     2
 #define CDNS_UART_FIFO_SIZE    64      /* FIFO size */
 #define CDNS_UART_REGISTER_SPACE       0x1000
 
@@ -180,7 +178,9 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
  * @port:              Pointer to the UART port
  * @uartclk:           Reference clock
  * @pclk:              APB clock
+ * @cdns_uart_driver:  Pointer to UART driver
  * @baud:              Current baud rate
+ * @id:                        Port ID
  * @clk_rate_change_nb:        Notifier block for clock changes
  * @quirks:            Flags for RXBS support.
  */
@@ -188,7 +188,9 @@ struct cdns_uart {
        struct uart_port        *port;
        struct clk              *uartclk;
        struct clk              *pclk;
+       struct uart_driver      *cdns_uart_driver;
        unsigned int            baud;
+       int                     id;
        struct notifier_block   clk_rate_change_nb;
        u32                     quirks;
 };
@@ -1003,13 +1005,12 @@ static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
        val = readl(port->membase + CDNS_UART_MODEMCR);
        mode_reg = readl(port->membase + CDNS_UART_MR);
 
-       val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR);
+       val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR |
+                CDNS_UART_MODEMCR_FCM);
        mode_reg &= ~CDNS_UART_MR_CHMODE_MASK;
 
-       if (mctrl & TIOCM_RTS)
-               val |= CDNS_UART_MODEMCR_RTS;
-       if (mctrl & TIOCM_DTR)
-               val |= CDNS_UART_MODEMCR_DTR;
+       if (mctrl & TIOCM_RTS || mctrl & TIOCM_DTR)
+               val |= CDNS_UART_MODEMCR_FCM;
        if (mctrl & TIOCM_LOOP)
                mode_reg |= CDNS_UART_MR_CHMODE_L_LOOP;
        else
@@ -1217,7 +1218,7 @@ static void cdns_uart_console_write(struct console *co, const char *s,
  *
  * Return: 0 on success, negative errno otherwise.
  */
-static int __init cdns_uart_console_setup(struct console *co, char *options)
+static int cdns_uart_console_setup(struct console *co, char *options)
 {
        struct uart_port *port = console_port;
 
@@ -1237,32 +1238,8 @@ static int __init cdns_uart_console_setup(struct console *co, char *options)
 
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
-
-static struct uart_driver cdns_uart_uart_driver;
-
-static struct console cdns_uart_console = {
-       .name   = CDNS_UART_TTY_NAME,
-       .write  = cdns_uart_console_write,
-       .device = uart_console_device,
-       .setup  = cdns_uart_console_setup,
-       .flags  = CON_PRINTBUFFER,
-       .index  = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
-       .data   = &cdns_uart_uart_driver,
-};
 #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
 
-static struct uart_driver cdns_uart_uart_driver = {
-       .owner          = THIS_MODULE,
-       .driver_name    = CDNS_UART_NAME,
-       .dev_name       = CDNS_UART_TTY_NAME,
-       .major          = CDNS_UART_MAJOR,
-       .minor          = CDNS_UART_MINOR,
-       .nr             = CDNS_UART_NR_PORTS,
-#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
-       .cons           = &cdns_uart_console,
-#endif
-};
-
 #ifdef CONFIG_PM_SLEEP
 /**
  * cdns_uart_suspend - suspend event
@@ -1273,24 +1250,12 @@ static struct uart_driver cdns_uart_uart_driver = {
 static int cdns_uart_suspend(struct device *device)
 {
        struct uart_port *port = dev_get_drvdata(device);
-       struct tty_struct *tty;
-       struct device *tty_dev;
-       int may_wake = 0;
-
-       /* Get the tty which could be NULL so don't assume it's valid */
-       tty = tty_port_tty_get(&port->state->port);
-       if (tty) {
-               tty_dev = tty->dev;
-               may_wake = device_may_wakeup(tty_dev);
-               tty_kref_put(tty);
-       }
+       struct cdns_uart *cdns_uart = port->private_data;
+       int may_wake;
 
-       /*
-        * Call the API provided in serial_core.c file which handles
-        * the suspend.
-        */
-       uart_suspend_port(&cdns_uart_uart_driver, port);
-       if (!(console_suspend_enabled && !may_wake)) {
+       may_wake = device_may_wakeup(device);
+
+       if (console_suspend_enabled && may_wake) {
                unsigned long flags = 0;
 
                spin_lock_irqsave(&port->lock, flags);
@@ -1305,7 +1270,11 @@ static int cdns_uart_suspend(struct device *device)
                spin_unlock_irqrestore(&port->lock, flags);
        }
 
-       return 0;
+       /*
+        * Call the API provided in serial_core.c file which handles
+        * the suspend.
+        */
+       return uart_suspend_port(cdns_uart->cdns_uart_driver, port);
 }
 
 /**
@@ -1317,23 +1286,14 @@ static int cdns_uart_suspend(struct device *device)
 static int cdns_uart_resume(struct device *device)
 {
        struct uart_port *port = dev_get_drvdata(device);
+       struct cdns_uart *cdns_uart = port->private_data;
        unsigned long flags = 0;
        u32 ctrl_reg;
-       struct tty_struct *tty;
-       struct device *tty_dev;
-       int may_wake = 0;
-
-       /* Get the tty which could be NULL so don't assume it's valid */
-       tty = tty_port_tty_get(&port->state->port);
-       if (tty) {
-               tty_dev = tty->dev;
-               may_wake = device_may_wakeup(tty_dev);
-               tty_kref_put(tty);
-       }
+       int may_wake;
 
-       if (console_suspend_enabled && !may_wake) {
-               struct cdns_uart *cdns_uart = port->private_data;
+       may_wake = device_may_wakeup(device);
 
+       if (console_suspend_enabled && !may_wake) {
                clk_enable(cdns_uart->pclk);
                clk_enable(cdns_uart->uartclk);
 
@@ -1367,7 +1327,7 @@ static int cdns_uart_resume(struct device *device)
                spin_unlock_irqrestore(&port->lock, flags);
        }
 
-       return uart_resume_port(&cdns_uart_uart_driver, port);
+       return uart_resume_port(cdns_uart->cdns_uart_driver, port);
 }
 #endif /* ! CONFIG_PM_SLEEP */
 static int __maybe_unused cdns_runtime_suspend(struct device *dev)
@@ -1409,6 +1369,90 @@ static const struct of_device_id cdns_uart_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
 
+/*
+ * Maximum number of instances without alias IDs but if there is alias
+ * which target "< MAX_UART_INSTANCES" range this ID can't be used.
+ */
+#define MAX_UART_INSTANCES     32
+
+/* Stores static aliases list */
+static DECLARE_BITMAP(alias_bitmap, MAX_UART_INSTANCES);
+static int alias_bitmap_initialized;
+
+/* Stores actual bitmap of allocated IDs with alias IDs together */
+static DECLARE_BITMAP(bitmap, MAX_UART_INSTANCES);
+/* Protect bitmap operations to have unique IDs */
+static DEFINE_MUTEX(bitmap_lock);
+
+static int cdns_get_id(struct platform_device *pdev)
+{
+       int id, ret;
+
+       mutex_lock(&bitmap_lock);
+
+       /* Alias list is stable that's why get alias bitmap only once */
+       if (!alias_bitmap_initialized) {
+               ret = of_alias_get_alias_list(cdns_uart_of_match, "serial",
+                                             alias_bitmap, MAX_UART_INSTANCES);
+               if (ret && ret != -EOVERFLOW) {
+                       mutex_unlock(&bitmap_lock);
+                       return ret;
+               }
+
+               alias_bitmap_initialized++;
+       }
+
+       /* Make sure that alias ID is not taken by instance without alias */
+       bitmap_or(bitmap, bitmap, alias_bitmap, MAX_UART_INSTANCES);
+
+       dev_dbg(&pdev->dev, "Alias bitmap: %*pb\n",
+               MAX_UART_INSTANCES, bitmap);
+
+       /* Look for a serialN alias */
+       id = of_alias_get_id(pdev->dev.of_node, "serial");
+       if (id < 0) {
+               dev_warn(&pdev->dev,
+                        "No serial alias passed. Using the first free id\n");
+
+               /*
+                * Start with id 0 and check if there is no serial0 alias
+                * which points to device which is compatible with this driver.
+                * If alias exists then try next free position.
+                */
+               id = 0;
+
+               for (;;) {
+                       dev_info(&pdev->dev, "Checking id %d\n", id);
+                       id = find_next_zero_bit(bitmap, MAX_UART_INSTANCES, id);
+
+                       /* No free empty instance */
+                       if (id == MAX_UART_INSTANCES) {
+                               dev_err(&pdev->dev, "No free ID\n");
+                               mutex_unlock(&bitmap_lock);
+                               return -EINVAL;
+                       }
+
+                       dev_dbg(&pdev->dev, "The empty id is %d\n", id);
+                       /* Check if ID is empty */
+                       if (!test_and_set_bit(id, bitmap)) {
+                               /* Break the loop if bit is taken */
+                               dev_dbg(&pdev->dev,
+                                       "Selected ID %d allocation passed\n",
+                                       id);
+                               break;
+                       }
+                       dev_dbg(&pdev->dev,
+                               "Selected ID %d allocation failed\n", id);
+                       /* if taking bit fails then try next one */
+                       id++;
+               }
+       }
+
+       mutex_unlock(&bitmap_lock);
+
+       return id;
+}
+
 /**
  * cdns_uart_probe - Platform driver probe
  * @pdev: Pointer to the platform device structure
@@ -1417,11 +1461,16 @@ MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
  */
 static int cdns_uart_probe(struct platform_device *pdev)
 {
-       int rc, id, irq;
+       int rc, irq;
        struct uart_port *port;
        struct resource *res;
        struct cdns_uart *cdns_uart_data;
        const struct of_device_id *match;
+       struct uart_driver *cdns_uart_uart_driver;
+       char *driver_name;
+#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
+       struct console *cdns_uart_console;
+#endif
 
        cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data),
                        GFP_KERNEL);
@@ -1431,6 +1480,63 @@ static int cdns_uart_probe(struct platform_device *pdev)
        if (!port)
                return -ENOMEM;
 
+       cdns_uart_uart_driver = devm_kzalloc(&pdev->dev,
+                                            sizeof(*cdns_uart_uart_driver),
+                                            GFP_KERNEL);
+       if (!cdns_uart_uart_driver)
+               return -ENOMEM;
+
+       cdns_uart_data->id = cdns_get_id(pdev);
+       if (cdns_uart_data->id < 0)
+               return cdns_uart_data->id;
+
+       /* There is a need to use unique driver name */
+       driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
+                                    CDNS_UART_NAME, cdns_uart_data->id);
+       if (!driver_name) {
+               rc = -ENOMEM;
+               goto err_out_id;
+       }
+
+       cdns_uart_uart_driver->owner = THIS_MODULE;
+       cdns_uart_uart_driver->driver_name = driver_name;
+       cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
+       cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
+       cdns_uart_uart_driver->minor = cdns_uart_data->id;
+       cdns_uart_uart_driver->nr = 1;
+
+#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
+       cdns_uart_console = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_console),
+                                        GFP_KERNEL);
+       if (!cdns_uart_console)
+               return -ENOMEM;
+
+       strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
+               sizeof(cdns_uart_console->name));
+       cdns_uart_console->index = cdns_uart_data->id;
+       cdns_uart_console->write = cdns_uart_console_write;
+       cdns_uart_console->device = uart_console_device;
+       cdns_uart_console->setup = cdns_uart_console_setup;
+       cdns_uart_console->flags = CON_PRINTBUFFER;
+       cdns_uart_console->data = cdns_uart_uart_driver;
+       cdns_uart_uart_driver->cons = cdns_uart_console;
+#endif
+
+       rc = uart_register_driver(cdns_uart_uart_driver);
+       if (rc < 0) {
+               dev_err(&pdev->dev, "Failed to register driver\n");
+               goto err_out_id;
+       }
+
+       cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
+
+       /*
+        * Setting up proper name_base needs to be done after uart
+        * registration because tty_driver structure is not filled.
+        * name_base is 0 by default.
+        */
+       cdns_uart_uart_driver->tty_driver->name_base = cdns_uart_data->id;
+
        match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
        if (match && match->data) {
                const struct cdns_platform_data *data = match->data;
@@ -1446,7 +1552,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
        }
        if (IS_ERR(cdns_uart_data->pclk)) {
                dev_err(&pdev->dev, "pclk clock not found.\n");
-               return PTR_ERR(cdns_uart_data->pclk);
+               rc = PTR_ERR(cdns_uart_data->pclk);
+               goto err_out_unregister_driver;
        }
 
        cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk");
@@ -1457,13 +1564,14 @@ static int cdns_uart_probe(struct platform_device *pdev)
        }
        if (IS_ERR(cdns_uart_data->uartclk)) {
                dev_err(&pdev->dev, "uart_clk clock not found.\n");
-               return PTR_ERR(cdns_uart_data->uartclk);
+               rc = PTR_ERR(cdns_uart_data->uartclk);
+               goto err_out_unregister_driver;
        }
 
        rc = clk_prepare_enable(cdns_uart_data->pclk);
        if (rc) {
                dev_err(&pdev->dev, "Unable to enable pclk clock.\n");
-               return rc;
+               goto err_out_unregister_driver;
        }
        rc = clk_prepare_enable(cdns_uart_data->uartclk);
        if (rc) {
@@ -1490,28 +1598,14 @@ static int cdns_uart_probe(struct platform_device *pdev)
                                &cdns_uart_data->clk_rate_change_nb))
                dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
 #endif
-       /* Look for a serialN alias */
-       id = of_alias_get_id(pdev->dev.of_node, "serial");
-       if (id < 0)
-               id = 0;
-
-       if (id >= CDNS_UART_NR_PORTS) {
-               dev_err(&pdev->dev, "Cannot get uart_port structure\n");
-               rc = -ENODEV;
-               goto err_out_notif_unreg;
-       }
 
        /* At this point, we've got an empty uart_port struct, initialize it */
        spin_lock_init(&port->lock);
-       port->membase   = NULL;
-       port->irq       = 0;
        port->type      = PORT_UNKNOWN;
        port->iotype    = UPIO_MEM32;
        port->flags     = UPF_BOOT_AUTOCONF;
        port->ops       = &cdns_uart_ops;
        port->fifosize  = CDNS_UART_FIFO_SIZE;
-       port->line      = id;
-       port->dev       = NULL;
 
        /*
         * Register the port.
@@ -1538,11 +1632,11 @@ static int cdns_uart_probe(struct platform_device *pdev)
         * If register_console() don't assign value, then console_port pointer
         * is cleanup.
         */
-       if (cdns_uart_uart_driver.cons->index == -1)
+       if (!console_port)
                console_port = port;
 #endif
 
-       rc = uart_add_one_port(&cdns_uart_uart_driver, port);
+       rc = uart_add_one_port(cdns_uart_uart_driver, port);
        if (rc) {
                dev_err(&pdev->dev,
                        "uart_add_one_port() failed; err=%i\n", rc);
@@ -1551,7 +1645,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
        /* This is not port which is used for console that's why clean it up */
-       if (cdns_uart_uart_driver.cons->index == -1)
+       if (console_port == port &&
+           !(cdns_uart_uart_driver->cons->flags & CON_ENABLED))
                console_port = NULL;
 #endif
 
@@ -1561,7 +1656,6 @@ err_out_pm_disable:
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_dont_use_autosuspend(&pdev->dev);
-err_out_notif_unreg:
 #ifdef CONFIG_COMMON_CLK
        clk_notifier_unregister(cdns_uart_data->uartclk,
                        &cdns_uart_data->clk_rate_change_nb);
@@ -1570,7 +1664,13 @@ err_out_clk_disable:
        clk_disable_unprepare(cdns_uart_data->uartclk);
 err_out_clk_dis_pclk:
        clk_disable_unprepare(cdns_uart_data->pclk);
-
+err_out_unregister_driver:
+       uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+err_out_id:
+       mutex_lock(&bitmap_lock);
+       if (cdns_uart_data->id < MAX_UART_INSTANCES)
+               clear_bit(cdns_uart_data->id, bitmap);
+       mutex_unlock(&bitmap_lock);
        return rc;
 }
 
@@ -1591,13 +1691,24 @@ static int cdns_uart_remove(struct platform_device *pdev)
        clk_notifier_unregister(cdns_uart_data->uartclk,
                        &cdns_uart_data->clk_rate_change_nb);
 #endif
-       rc = uart_remove_one_port(&cdns_uart_uart_driver, port);
+       rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
        port->mapbase = 0;
+       mutex_lock(&bitmap_lock);
+       if (cdns_uart_data->id < MAX_UART_INSTANCES)
+               clear_bit(cdns_uart_data->id, bitmap);
+       mutex_unlock(&bitmap_lock);
        clk_disable_unprepare(cdns_uart_data->uartclk);
        clk_disable_unprepare(cdns_uart_data->pclk);
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_dont_use_autosuspend(&pdev->dev);
+
+#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
+       if (console_port == port)
+               console_port = NULL;
+#endif
+
+       uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
        return rc;
 }
 
@@ -1613,28 +1724,14 @@ static struct platform_driver cdns_uart_platform_driver = {
 
 static int __init cdns_uart_init(void)
 {
-       int retval = 0;
-
-       /* Register the cdns_uart driver with the serial core */
-       retval = uart_register_driver(&cdns_uart_uart_driver);
-       if (retval)
-               return retval;
-
        /* Register the platform driver */
-       retval = platform_driver_register(&cdns_uart_platform_driver);
-       if (retval)
-               uart_unregister_driver(&cdns_uart_uart_driver);
-
-       return retval;
+       return platform_driver_register(&cdns_uart_platform_driver);
 }
 
 static void __exit cdns_uart_exit(void)
 {
        /* Unregister the platform driver */
        platform_driver_unregister(&cdns_uart_platform_driver);
-
-       /* Unregister the cdns_uart driver */
-       uart_unregister_driver(&cdns_uart_uart_driver);
 }
 
 arch_initcall(cdns_uart_init);
index c996b6859c5e70c72827f28c33c46bd3d96a1cda..77070c2d1240421fa34f48db9a2ddb24a961f2f0 100644 (file)
@@ -118,9 +118,12 @@ void tty_buffer_free_all(struct tty_port *port)
        struct tty_bufhead *buf = &port->buf;
        struct tty_buffer *p, *next;
        struct llist_node *llist;
+       unsigned int freed = 0;
+       int still_used;
 
        while ((p = buf->head) != NULL) {
                buf->head = p->next;
+               freed += p->size;
                if (p->size > 0)
                        kfree(p);
        }
@@ -132,7 +135,9 @@ void tty_buffer_free_all(struct tty_port *port)
        buf->head = &buf->sentinel;
        buf->tail = &buf->sentinel;
 
-       atomic_set(&buf->mem_used, 0);
+       still_used = atomic_xchg(&buf->mem_used, 0);
+       WARN(still_used != freed, "we still have not freed %d bytes!",
+                       still_used - freed);
 }
 
 /**
@@ -468,11 +473,15 @@ receive_buf(struct tty_port *port, struct tty_buffer *head, int count)
 {
        unsigned char *p = char_buf_ptr(head, head->read);
        char          *f = NULL;
+       int n;
 
        if (~head->flags & TTYB_NORMAL)
                f = flag_buf_ptr(head, head->read);
 
-       return port->client_ops->receive_buf(port, p, f, count);
+       n = port->client_ops->receive_buf(port, p, f, count);
+       if (n > 0)
+               memset(p, 0, n);
+       return n;
 }
 
 /**
index da3c1c2f73c4dadc9e32d3ec8477296b29ba843f..ee80dfbd5442b034451e396cd66608e41e8e43bb 100644 (file)
@@ -409,7 +409,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
        mutex_lock(&tty_mutex);
        /* Search through the tty devices to look for a match */
        list_for_each_entry(p, &tty_drivers, tty_drivers) {
-               if (strncmp(name, p->name, len) != 0)
+               if (!len || strncmp(name, p->name, len) != 0)
                        continue;
                stp = str;
                if (*stp == ',')
index 25d736880013b256cf692a2f5d3e6f51c4af9ece..cb6075096a5b41b6fbf5e87b6b22239c8a5082e3 100644 (file)
@@ -279,7 +279,6 @@ EXPORT_SYMBOL(tty_port_put);
  *     Return a refcount protected tty instance or NULL if the port is not
  *     associated with a tty (eg due to close or hangup)
  */
-
 struct tty_struct *tty_port_tty_get(struct tty_port *port)
 {
        unsigned long flags;
@@ -300,7 +299,6 @@ EXPORT_SYMBOL(tty_port_tty_get);
  *     Associate the port and tty pair. Manages any internal refcounts.
  *     Pass NULL to deassociate a port
  */
-
 void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
 {
        unsigned long flags;
@@ -343,7 +341,6 @@ out:
  *
  *     Caller holds tty lock.
  */
-
 void tty_port_hangup(struct tty_port *port)
 {
        struct tty_struct *tty;
@@ -399,7 +396,6 @@ EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
  *     to hide some internal details. This will eventually become entirely
  *     internal to the tty port.
  */
-
 int tty_port_carrier_raised(struct tty_port *port)
 {
        if (port->ops->carrier_raised == NULL)
@@ -416,7 +412,6 @@ EXPORT_SYMBOL(tty_port_carrier_raised);
  *     to hide some internal details. This will eventually become entirely
  *     internal to the tty port.
  */
-
 void tty_port_raise_dtr_rts(struct tty_port *port)
 {
        if (port->ops->dtr_rts)
@@ -432,7 +427,6 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts);
  *     to hide some internal details. This will eventually become entirely
  *     internal to the tty port.
  */
-
 void tty_port_lower_dtr_rts(struct tty_port *port)
 {
        if (port->ops->dtr_rts)
@@ -464,7 +458,6 @@ EXPORT_SYMBOL(tty_port_lower_dtr_rts);
  *      NB: May drop and reacquire tty lock when blocking, so tty and tty_port
  *      may have changed state (eg., may have been hung up).
  */
-
 int tty_port_block_til_ready(struct tty_port *port,
                                struct tty_struct *tty, struct file *filp)
 {
index 165653a5e45d643bc057b867cc4856d89053f243..d2652dccc69975b6733fa597863561dc5bb92dc0 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/console.h>
 #include <linux/pci_regs.h>
 #include <linux/pci_ids.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/io.h>
 #include <asm/pci-direct.h>
 #include <asm/fixmap.h>
@@ -94,7 +94,7 @@ static void * __init xdbc_get_page(dma_addr_t *dma_addr)
 {
        void *virt;
 
-       virt = alloc_bootmem_pages_nopanic(PAGE_SIZE);
+       virt = memblock_alloc_nopanic(PAGE_SIZE, PAGE_SIZE);
        if (!virt)
                return NULL;
 
@@ -191,7 +191,7 @@ static void __init xdbc_free_ring(struct xdbc_ring *ring)
        if (!seg)
                return;
 
-       free_bootmem(seg->dma, PAGE_SIZE);
+       memblock_free(seg->dma, PAGE_SIZE);
        ring->segment = NULL;
 }
 
@@ -675,10 +675,10 @@ int __init early_xdbc_setup_hardware(void)
                xdbc_free_ring(&xdbc.in_ring);
 
                if (xdbc.table_dma)
-                       free_bootmem(xdbc.table_dma, PAGE_SIZE);
+                       memblock_free(xdbc.table_dma, PAGE_SIZE);
 
                if (xdbc.out_dma)
-                       free_bootmem(xdbc.out_dma, PAGE_SIZE);
+                       memblock_free(xdbc.out_dma, PAGE_SIZE);
 
                xdbc.table_base = NULL;
                xdbc.out_buf = NULL;
@@ -997,8 +997,8 @@ free_and_quit:
        xdbc_free_ring(&xdbc.evt_ring);
        xdbc_free_ring(&xdbc.out_ring);
        xdbc_free_ring(&xdbc.in_ring);
-       free_bootmem(xdbc.table_dma, PAGE_SIZE);
-       free_bootmem(xdbc.out_dma, PAGE_SIZE);
+       memblock_free(xdbc.table_dma, PAGE_SIZE);
+       memblock_free(xdbc.out_dma, PAGE_SIZE);
        writel(0, &xdbc.xdbc_reg->control);
        early_iounmap(xdbc.xhci_base, xdbc.xhci_length);
 
index 9e33d5206d54a30572320dc5e76f07229c565ded..f2497cb96abb00539648182a2bc70d620285ee17 100644 (file)
@@ -166,7 +166,7 @@ int uvcg_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
        unsigned long flags;
        int ret;
 
-       ret = vb2_qbuf(&queue->queue, buf);
+       ret = vb2_qbuf(&queue->queue, NULL, buf);
        if (ret < 0)
                return ret;
 
index c84333eb5eb59bef3ab1ee41b7aea6e0ee982c75..9de5ed38da830a9140a373a4ba0f56b7e0f65ee7 100644 (file)
@@ -21,7 +21,7 @@ config VFIO_VIRQFD
 menuconfig VFIO
        tristate "VFIO Non-Privileged userspace driver framework"
        depends on IOMMU_API
-       select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM_SMMU || ARM_SMMU_V3)
+       select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64)
        select ANON_INODES
        help
          VFIO provides a framework for secure userspace device drivers.
index cddb453a1ba578408a050a18d52c7372ace92029..50cdedfca9fec2d01aaa4b5596a71722969e9a1a 100644 (file)
@@ -434,10 +434,14 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type)
 {
        if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) {
                u8 pin;
+
+               if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) ||
+                   vdev->nointx || vdev->pdev->is_virtfn)
+                       return 0;
+
                pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin);
-               if (IS_ENABLED(CONFIG_VFIO_PCI_INTX) && !vdev->nointx && pin)
-                       return 1;
 
+               return pin ? 1 : 0;
        } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) {
                u8 pos;
                u16 flags;
index 115a36f6f40398b75dfa75b61b50e81f98bc5a63..423ea1f98441a27e1ac351a14f29fb10ad462e16 100644 (file)
@@ -1180,8 +1180,10 @@ static int vfio_msi_cap_len(struct vfio_pci_device *vdev, u8 pos)
                return -ENOMEM;
 
        ret = init_pci_cap_msi_perm(vdev->msi_perm, len, flags);
-       if (ret)
+       if (ret) {
+               kfree(vdev->msi_perm);
                return ret;
+       }
 
        return len;
 }
@@ -1609,6 +1611,15 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev)
        return 0;
 }
 
+/*
+ * Nag about hardware bugs, hopefully to have vendors fix them, but at least
+ * to collect a list of dependencies for the VF INTx pin quirk below.
+ */
+static const struct pci_device_id known_bogus_vf_intx_pin[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x270c) },
+       {}
+};
+
 /*
  * For each device we allocate a pci_config_map that indicates the
  * capability occupying each dword and thus the struct perm_bits we
@@ -1674,6 +1685,24 @@ int vfio_config_init(struct vfio_pci_device *vdev)
        if (pdev->is_virtfn) {
                *(__le16 *)&vconfig[PCI_VENDOR_ID] = cpu_to_le16(pdev->vendor);
                *(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device);
+
+               /*
+                * Per SR-IOV spec rev 1.1, 3.4.1.18 the interrupt pin register
+                * does not apply to VFs and VFs must implement this register
+                * as read-only with value zero.  Userspace is not readily able
+                * to identify whether a device is a VF and thus that the pin
+                * definition on the device is bogus should it violate this
+                * requirement.  We already virtualize the pin register for
+                * other purposes, so we simply need to replace the bogus value
+                * and consider VFs when we determine INTx IRQ count.
+                */
+               if (vconfig[PCI_INTERRUPT_PIN] &&
+                   !pci_match_id(known_bogus_vf_intx_pin, pdev))
+                       pci_warn(pdev,
+                                "Hardware bug: VF reports bogus INTx pin %d\n",
+                                vconfig[PCI_INTERRUPT_PIN]);
+
+               vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
        }
 
        if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)
index ca544aa764b8e6b6b067395f409494767382bd1d..33f0f0f2e8b3403e2ab2d5f94231718e7df27d75 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * AS3711 PMIC backlight driver, using DCDC Step Up Converters
  *
  * Copyright (C) 2012 Renesas Electronics Corporation
  * Author: Guennadi Liakhovetski, <g.liakhovetski@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the version 2 of the GNU General Public License as
- * published by the Free Software Foundation
  */
 
 #include <linux/backlight.h>
@@ -488,5 +485,5 @@ module_platform_driver(as3711_backlight_driver);
 
 MODULE_DESCRIPTION("Backlight Driver for AS3711 PMICs");
 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:as3711-backlight");
index 591a13a597874ec008430f00d448d9aab4a7b847..e413f54208f4b038ef5f33b989da97d7e3927e2f 100644 (file)
@@ -2,6 +2,12 @@
 # fbdev configuration
 #
 
+config FB_CMDLINE
+       bool
+
+config FB_NOTIFY
+       bool
+
 menuconfig FB
        tristate "Support for frame buffer devices"
        select FB_CMDLINE
@@ -41,7 +47,6 @@ menuconfig FB
 config FIRMWARE_EDID
        bool "Enable firmware EDID"
        depends on FB
-       default n
        ---help---
          This enables access to the EDID transferred from the firmware.
         On the i386, this is from the Video BIOS. Enable this if DDC/I2C
@@ -54,23 +59,15 @@ config FIRMWARE_EDID
         combination with certain motherboards and monitors are known to
         suffer from this problem.
 
-config FB_CMDLINE
-       bool
-
-config FB_NOTIFY
-       bool
-
 config FB_DDC
        tristate
        depends on FB
        select I2C_ALGOBIT
        select I2C
-       default n
 
 config FB_BOOT_VESA_SUPPORT
        bool
        depends on FB
-       default n
        ---help---
          If true, at least one selected framebuffer driver can take advantage
          of VESA video modes set at an early boot stage via the vga= parameter.
@@ -78,7 +75,6 @@ config FB_BOOT_VESA_SUPPORT
 config FB_CFB_FILLRECT
        tristate
        depends on FB
-       default n
        ---help---
          Include the cfb_fillrect function for generic software rectangle
          filling. This is used by drivers that don't provide their own
@@ -87,7 +83,6 @@ config FB_CFB_FILLRECT
 config FB_CFB_COPYAREA
        tristate
        depends on FB
-       default n
        ---help---
          Include the cfb_copyarea function for generic software area copying.
          This is used by drivers that don't provide their own (accelerated)
@@ -96,7 +91,6 @@ config FB_CFB_COPYAREA
 config FB_CFB_IMAGEBLIT
        tristate
        depends on FB
-       default n
        ---help---
          Include the cfb_imageblit function for generic software image
          blitting. This is used by drivers that don't provide their own
@@ -105,7 +99,6 @@ config FB_CFB_IMAGEBLIT
 config FB_CFB_REV_PIXELS_IN_BYTE
        bool
        depends on FB
-       default n
        ---help---
          Allow generic frame-buffer functions to work on displays with 1, 2
          and 4 bits per pixel depths which has opposite order of pixels in
@@ -114,7 +107,6 @@ config FB_CFB_REV_PIXELS_IN_BYTE
 config FB_SYS_FILLRECT
        tristate
        depends on FB
-       default n
        ---help---
          Include the sys_fillrect function for generic software rectangle
          filling. This is used by drivers that don't provide their own
@@ -123,7 +115,6 @@ config FB_SYS_FILLRECT
 config FB_SYS_COPYAREA
        tristate
        depends on FB
-       default n
        ---help---
          Include the sys_copyarea function for generic software area copying.
          This is used by drivers that don't provide their own (accelerated)
@@ -132,7 +123,6 @@ config FB_SYS_COPYAREA
 config FB_SYS_IMAGEBLIT
        tristate
        depends on FB
-       default n
        ---help---
          Include the sys_imageblit function for generic software image
          blitting. This is used by drivers that don't provide their own
@@ -141,7 +131,6 @@ config FB_SYS_IMAGEBLIT
 config FB_PROVIDE_GET_FB_UNMAPPED_AREA
        bool
        depends on FB
-       default n
        ---help---
          Allow generic frame-buffer to provide get_fb_unmapped_area
          function.
@@ -173,7 +162,6 @@ endchoice
 config FB_SYS_FOPS
        tristate
        depends on FB
-       default n
 
 config FB_DEFERRED_IO
        bool
@@ -187,7 +175,6 @@ config FB_HECUBA
 config FB_SVGALIB
        tristate
        depends on FB
-       default n
        ---help---
          Common utility functions useful to fbdev drivers of VGA-based
          cards.
@@ -195,19 +182,16 @@ config FB_SVGALIB
 config FB_MACMODES
        tristate
        depends on FB
-       default n
 
 config FB_BACKLIGHT
        bool
        depends on FB
        select BACKLIGHT_LCD_SUPPORT
        select BACKLIGHT_CLASS_DEVICE
-       default n
 
 config FB_MODE_HELPERS
         bool "Enable Video Mode Handling Helpers"
         depends on FB
-       default n
        ---help---
          This enables functions for handling video modes using the
          Generalized Timing Formula and the EDID parser. A few drivers rely
@@ -218,7 +202,6 @@ config FB_MODE_HELPERS
 config FB_TILEBLITTING
        bool "Enable Tile Blitting Support"
        depends on FB
-       default n
        ---help---
          This enables tile blitting.  Tile blitting is a drawing technique
         where the screen is divided into rectangular sections (tiles), whereas
@@ -329,16 +312,9 @@ config FB_ACORN
          hardware found in Acorn RISC PCs and other ARM-based machines.  If
          unsure, say N.
 
-config FB_CLPS711X_OLD
-       tristate
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-
 config FB_CLPS711X
        tristate "CLPS711X LCD support"
        depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
-       select FB_CLPS711X_OLD if ARCH_CLPS711X && !ARCH_MULTIPLATFORM
        select BACKLIGHT_LCD_SUPPORT
        select FB_MODE_HELPERS
        select FB_SYS_FILLRECT
@@ -936,7 +912,6 @@ config FB_NVIDIA_I2C
 config FB_NVIDIA_DEBUG
        bool "Lots of debug output"
        depends on FB_NVIDIA
-       default n
        help
          Say Y here if you want the nVidia driver to output all sorts
          of debugging information to provide to the maintainer when
@@ -983,7 +958,6 @@ config FB_RIVA_I2C
 config FB_RIVA_DEBUG
        bool "Lots of debug output"
        depends on FB_RIVA
-       default n
        help
          Say Y here if you want the Riva driver to output all sorts
          of debugging information to provide to the maintainer when
@@ -1266,7 +1240,6 @@ config FB_RADEON_BACKLIGHT
 config FB_RADEON_DEBUG
        bool "Lots of debug output from Radeon driver"
        depends on FB_RADEON
-       default n
        help
          Say Y here if you want the Radeon driver to output all sorts
          of debugging information to provide to the maintainer when
@@ -1399,7 +1372,6 @@ config FB_SAVAGE_I2C
 config FB_SAVAGE_ACCEL
        bool "Enable Console Acceleration"
        depends on FB_SAVAGE
-       default n
        help
           This option will compile in console acceleration support. If
           the resulting framebuffer console has bothersome glitches, then
@@ -1456,8 +1428,6 @@ if FB_VIA
 
 config FB_VIA_DIRECT_PROCFS
        bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
-       depends on FB_VIA
-       default n
        help
          Allow direct hardware access to some output registers via procfs.
          This is dangerous but may provide the only chance to get the
@@ -1466,8 +1436,6 @@ config FB_VIA_DIRECT_PROCFS
 
 config FB_VIA_X_COMPATIBILITY
        bool "X server compatibility"
-       depends on FB_VIA
-       default n
        help
          This option reduces the functionality (power saving, ...) of the
          framebuffer to avoid negative impact on the OpenChrome X server.
@@ -1692,7 +1660,6 @@ config FB_WM8505
 config FB_WMT_GE_ROPS
        bool "VT8500/WM8xxx accelerated raster ops support"
        depends on (FB = y) && (FB_VT8500 || FB_WM8505)
-       default n
        help
          This adds support for accelerated raster operations on the
          VIA VT8500 and Wondermedia 85xx series SoCs.
@@ -1802,17 +1769,14 @@ config FB_PXA
 
 config FB_PXA_OVERLAY
        bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
-       default n
        depends on FB_PXA && (PXA27x || PXA3xx)
 
 config FB_PXA_SMARTPANEL
        bool "PXA Smartpanel LCD support"
-       default n
        depends on FB_PXA
 
 config FB_PXA_PARAMETERS
        bool "PXA LCD command line parameters"
-       default n
        depends on FB_PXA
        ---help---
          Enable the use of kernel command line or module parameters
@@ -1850,7 +1814,6 @@ config FB_MBX
 config FB_MBX_DEBUG
        bool "Enable debugging info via debugfs"
        depends on FB_MBX && DEBUG_FS
-       default n
        ---help---
          Enable this if you want debugging information using the debug
          filesystem (debugfs)
@@ -2240,7 +2203,7 @@ config FB_MX3
 
 config FB_BROADSHEET
        tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
-       depends on FB
+       depends on FB && (ARCH_PXA || COMPILE_TEST)
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
@@ -2308,10 +2271,6 @@ config FB_SIMPLE
          Configuration re: surface address, size, and format must be provided
          through device tree, or plain old platform data.
 
-source "drivers/video/fbdev/omap/Kconfig"
-source "drivers/video/fbdev/omap2/Kconfig"
-source "drivers/video/fbdev/mmp/Kconfig"
-
 config FB_SSD1307
        tristate "Solomon SSD1307 framebuffer support"
        depends on FB && I2C
@@ -2341,3 +2300,7 @@ config FB_SM712
          This driver is also available as a module. The module will be
          called sm712fb. If you want to compile it as a module, say M
          here and read <file:Documentation/kbuild/modules.txt>.
+
+source "drivers/video/fbdev/omap/Kconfig"
+source "drivers/video/fbdev/omap2/Kconfig"
+source "drivers/video/fbdev/mmp/Kconfig"
index 13c900320c2cc375593d02bd0aa99381d03a6f81..846b0c9ea9db7541c1bc2c347846af0e2437d877 100644 (file)
@@ -14,7 +14,6 @@ obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)        += clps711x-fb.o
-obj-$(CONFIG_FB_CLPS711X_OLD)    += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
index 7e87d0d616581dbf2e58045b424198524d28b3f4..a48741aab24034dd9cd85249a5eb3fa2e354cdb1 100644 (file)
@@ -419,6 +419,8 @@ static int arcfb_ioctl(struct fb_info *info,
                        schedule();
                        finish_wait(&arcfb_waitq, &wait);
                }
+               /* fall through */
+
                case FBIO_GETCONTROL2:
                {
                        unsigned char ctl2;
index 076d24afbd728bb3e8b4ffbc41f8a3be9642b51d..4ed55e6bbb84047927c0da3a314b419e9312dd02 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <video/of_videomode.h>
 #include <video/of_display_timing.h>
 #include <linux/regulator/consumer.h>
 #include <video/videomode.h>
@@ -1028,11 +1029,11 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
        struct device *dev = &sinfo->pdev->dev;
        struct device_node *np =dev->of_node;
        struct device_node *display_np;
-       struct device_node *timings_np;
-       struct display_timings *timings;
        struct atmel_lcdfb_power_ctrl_gpio *og;
        bool is_gpio_power = false;
+       struct fb_videomode fb_vm;
        struct gpio_desc *gpiod;
+       struct videomode vm;
        int ret = -ENOENT;
        int i;
 
@@ -1105,44 +1106,18 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
        pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
        pdata->lcdcon_pol_negative = of_property_read_bool(display_np, "atmel,lcdcon-backlight-inverted");
 
-       timings = of_get_display_timings(display_np);
-       if (!timings) {
-               dev_err(dev, "failed to get display timings\n");
-               ret = -EINVAL;
+       ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE);
+       if (ret) {
+               dev_err(dev, "failed to get videomode from DT\n");
                goto put_display_node;
        }
 
-       timings_np = of_get_child_by_name(display_np, "display-timings");
-       if (!timings_np) {
-               dev_err(dev, "failed to find display-timings node\n");
-               ret = -ENODEV;
+       ret = fb_videomode_from_videomode(&vm, &fb_vm);
+       if (ret < 0)
                goto put_display_node;
-       }
 
-       for (i = 0; i < of_get_child_count(timings_np); i++) {
-               struct videomode vm;
-               struct fb_videomode fb_vm;
-
-               ret = videomode_from_timings(timings, &vm, i);
-               if (ret < 0)
-                       goto put_timings_node;
-               ret = fb_videomode_from_videomode(&vm, &fb_vm);
-               if (ret < 0)
-                       goto put_timings_node;
-
-               fb_add_videomode(&fb_vm, &info->modelist);
-       }
-
-       /*
-        * FIXME: Make sure we are not referencing any fields in display_np
-        * and timings_np and drop our references to them before returning to
-        * avoid leaking the nodes on probe deferral and driver unbind.
-        */
-
-       return 0;
+       fb_add_videomode(&fb_vm, &info->modelist);
 
-put_timings_node:
-       of_node_put(timings_np);
 put_display_node:
        of_node_put(display_np);
        return ret;
index d09bab3bf22412cd7ac4c52c5db42ebad5ded86a..e5a347c581801f6e4769df1fdf517e24d4a87ec1 100644 (file)
@@ -147,6 +147,7 @@ struct atyfb_par {
        u16 pci_id;
        u32 accel_flags;
        int blitter_may_be_busy;
+       unsigned fifo_space;
        int asleep;
        int lock_blank;
        unsigned long res_start;
@@ -346,10 +347,13 @@ extern int aty_init_cursor(struct fb_info *info);
      *  Hardware acceleration
      */
 
-static inline void wait_for_fifo(u16 entries, const struct atyfb_par *par)
+static inline void wait_for_fifo(u16 entries, struct atyfb_par *par)
 {
-       while ((aty_ld_le32(FIFO_STAT, par) & 0xffff) >
-              ((u32) (0x8000 >> entries)));
+       unsigned fifo_space = par->fifo_space;
+       while (entries > fifo_space) {
+               fifo_space = 16 - fls(aty_ld_le32(FIFO_STAT, par) & 0xffff);
+       }
+       par->fifo_space = fifo_space - entries;
 }
 
 static inline void wait_for_idle(struct atyfb_par *par)
@@ -359,7 +363,7 @@ static inline void wait_for_idle(struct atyfb_par *par)
        par->blitter_may_be_busy = 0;
 }
 
-extern void aty_reset_engine(const struct atyfb_par *par);
+extern void aty_reset_engine(struct atyfb_par *par);
 extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
 
 void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
index 05111e90f1681c0e40a8438c5eb427ff25f9ffc3..b6fe103df1453ef1417cf36f306932d5410593f3 100644 (file)
@@ -1480,24 +1480,28 @@ static int atyfb_set_par(struct fb_info *info)
        base = 0x2000;
        printk("debug atyfb: Mach64 non-shadow register values:");
        for (i = 0; i < 256; i = i+4) {
-               if (i % 16 == 0)
-                       printk("\ndebug atyfb: 0x%04X: ", base + i);
-               printk(" %08X", aty_ld_le32(i, par));
+               if (i % 16 == 0) {
+                       pr_cont("\n");
+                       printk("debug atyfb: 0x%04X: ", base + i);
+               }
+               pr_cont(" %08X", aty_ld_le32(i, par));
        }
-       printk("\n\n");
+       pr_cont("\n\n");
 
 #ifdef CONFIG_FB_ATY_CT
        /* PLL registers */
        base = 0x00;
        printk("debug atyfb: Mach64 PLL register values:");
        for (i = 0; i < 64; i++) {
-               if (i % 16 == 0)
-                       printk("\ndebug atyfb: 0x%02X: ", base + i);
+               if (i % 16 == 0) {
+                       pr_cont("\n");
+                       printk("debug atyfb: 0x%02X: ", base + i);
+               }
                if (i % 4 == 0)
-                       printk(" ");
-               printk("%02X", aty_ld_pll_ct(i, par));
+                       pr_cont(" ");
+               pr_cont("%02X", aty_ld_pll_ct(i, par));
        }
-       printk("\n\n");
+       pr_cont("\n\n");
 #endif /* CONFIG_FB_ATY_CT */
 
 #ifdef CONFIG_FB_ATY_GENERIC_LCD
@@ -1509,19 +1513,19 @@ static int atyfb_set_par(struct fb_info *info)
                        for (i = 0; i <= POWER_MANAGEMENT; i++) {
                                if (i == EXT_VERT_STRETCH)
                                        continue;
-                               printk("\ndebug atyfb: 0x%04X: ",
+                               pr_cont("\ndebug atyfb: 0x%04X: ",
                                       lt_lcd_regs[i]);
-                               printk(" %08X", aty_ld_lcd(i, par));
+                               pr_cont(" %08X", aty_ld_lcd(i, par));
                        }
                } else {
                        for (i = 0; i < 64; i++) {
                                if (i % 4 == 0)
-                                       printk("\ndebug atyfb: 0x%02X: ",
+                                       pr_cont("\ndebug atyfb: 0x%02X: ",
                                               base + i);
-                               printk(" %08X", aty_ld_lcd(i, par));
+                               pr_cont(" %08X", aty_ld_lcd(i, par));
                        }
                }
-               printk("\n\n");
+               pr_cont("\n\n");
        }
 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
 }
@@ -2597,8 +2601,8 @@ static int aty_init(struct fb_info *info)
                       aty_ld_le32(DSP_ON_OFF, par),
                       aty_ld_le32(CLOCK_CNTL, par));
                for (i = 0; i < 40; i++)
-                       printk(" %02x", aty_ld_pll_ct(i, par));
-               printk("\n");
+                       pr_cont(" %02x", aty_ld_pll_ct(i, par));
+               pr_cont("\n");
        }
 #endif
        if (par->pll_ops->init_pll)
index 2541a0e0de763669005cf8f1b0825f68e851ffa2..e4b2c89baee2d4e1cb422078605baa1c2cfe56b3 100644 (file)
@@ -37,7 +37,7 @@ static u32 rotation24bpp(u32 dx, u32 direction)
        return ((rotation << 8) | DST_24_ROTATION_ENABLE);
 }
 
-void aty_reset_engine(const struct atyfb_par *par)
+void aty_reset_engine(struct atyfb_par *par)
 {
        /* reset engine */
        aty_st_le32(GEN_TEST_CNTL,
@@ -50,6 +50,8 @@ void aty_reset_engine(const struct atyfb_par *par)
        /* HOST errors */
        aty_st_le32(BUS_CNTL,
                aty_ld_le32(BUS_CNTL, par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK, par);
+
+       par->fifo_space = 0;
 }
 
 static void reset_GTC_3D_engine(const struct atyfb_par *par)
@@ -127,7 +129,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
 
        /* set host attributes */
        wait_for_fifo(13, par);
-       aty_st_le32(HOST_CNTL, 0, par);
+       aty_st_le32(HOST_CNTL, HOST_BYTE_ALIGN, par);
 
        /* set pattern attributes */
        aty_st_le32(PAT_REG0, 0, par);
@@ -233,7 +235,8 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
                rotation = rotation24bpp(dx, direction);
        }
 
-       wait_for_fifo(4, par);
+       wait_for_fifo(5, par);
+       aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par);
        aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par);
        aty_st_le32(SRC_Y_X, (sx << 16) | sy, par);
        aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par);
@@ -269,7 +272,8 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
                rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT);
        }
 
-       wait_for_fifo(3, par);
+       wait_for_fifo(4, par);
+       aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par);
        aty_st_le32(DP_FRGD_CLR, color, par);
        aty_st_le32(DP_SRC,
                    BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
@@ -284,7 +288,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct atyfb_par *par = (struct atyfb_par *) info->par;
        u32 src_bytes, dx = image->dx, dy = image->dy, width = image->width;
-       u32 pix_width_save, pix_width, host_cntl, rotation = 0, src, mix;
+       u32 pix_width, rotation = 0, src, mix;
 
        if (par->asleep)
                return;
@@ -296,8 +300,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
                return;
        }
 
-       pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par);
-       host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN;
+       pix_width = par->crtc.dp_pix_width;
 
        switch (image->depth) {
        case 1:
@@ -345,7 +348,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
                 * since Rage 3D IIc we have DP_HOST_TRIPLE_EN bit
                 * this hwaccelerated triple has an issue with not aligned data
                 */
-               if (M64_HAS(HW_TRIPLE) && image->width % 8 == 0)
+               if (image->depth == 1 && M64_HAS(HW_TRIPLE) && image->width % 8 == 0)
                        pix_width |= DP_HOST_TRIPLE_EN;
        }
 
@@ -370,19 +373,18 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
                mix = FRGD_MIX_D_XOR_S | BKGD_MIX_D;
        }
 
-       wait_for_fifo(6, par);
-       aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par);
+       wait_for_fifo(5, par);
        aty_st_le32(DP_PIX_WIDTH, pix_width, par);
        aty_st_le32(DP_MIX, mix, par);
        aty_st_le32(DP_SRC, src, par);
-       aty_st_le32(HOST_CNTL, host_cntl, par);
+       aty_st_le32(HOST_CNTL, HOST_BYTE_ALIGN, par);
        aty_st_le32(DST_CNTL, DST_Y_TOP_TO_BOTTOM | DST_X_LEFT_TO_RIGHT | rotation, par);
 
        draw_rect(dx, dy, width, image->height, par);
        src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
 
        /* manual triple each pixel */
-       if (info->var.bits_per_pixel == 24 && !(pix_width & DP_HOST_TRIPLE_EN)) {
+       if (image->depth == 1 && info->var.bits_per_pixel == 24 && !(pix_width & DP_HOST_TRIPLE_EN)) {
                int inbit, outbit, mult24, byte_id_in_dword, width;
                u8 *pbitmapin = (u8*)image->data, *pbitmapout;
                u32 hostdword;
@@ -415,7 +417,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
                                }
                        }
                        wait_for_fifo(1, par);
-                       aty_st_le32(HOST_DATA0, hostdword, par);
+                       aty_st_le32(HOST_DATA0, le32_to_cpu(hostdword), par);
                }
        } else {
                u32 *pbitmap, dwords = (src_bytes + 3) / 4;
@@ -424,8 +426,4 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
                        aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par);
                }
        }
-
-       /* restore pix_width */
-       wait_for_fifo(1, par);
-       aty_st_le32(DP_PIX_WIDTH, pix_width_save, par);
 }
index 8de88b129b62244c11e44092687020c2a7b0257f..9af54c2368fdb7252219329e9405a73ad4a2f479 100644 (file)
@@ -355,9 +355,7 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 static void cg14_init_fix(struct fb_info *info, int linebytes,
                          struct device_node *dp)
 {
-       const char *name = dp->name;
-
-       strlcpy(info->fix.id, name, sizeof(info->fix.id));
+       snprintf(info->fix.id, sizeof(info->fix.id), "%pOFn", dp);
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
index 6c334260cf532faca8b36f9e8e05cb76d167fcf7..1bd95b02f3aa413463183503f0b29223ddf09822 100644 (file)
@@ -246,7 +246,7 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 static void cg3_init_fix(struct fb_info *info, int linebytes,
                         struct device_node *dp)
 {
-       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
+       snprintf(info->fix.id, sizeof(info->fix.id), "%pOFn", dp);
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
diff --git a/drivers/video/fbdev/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c
deleted file mode 100644 (file)
index 7693aea..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- *  linux/drivers/video/clps711xfb.c
- *
- *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  Framebuffer driver for the CLPS7111 and EP7212 processors.
- */
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <linux/uaccess.h>
-
-struct fb_info *cfb;
-
-#define CMAP_MAX_SIZE  16
-
-/*
- * LCD AC Prescale.  This comes from the LCD panel manufacturers specifications.
- * This determines how many clocks + 1 of CL1 before the M signal toggles.
- * The number of lines on the display must not be divisible by this number.
- */
-static unsigned int lcd_ac_prescale = 13;
-
-/*
- *    Set a single color register. Return != 0 for invalid regno.
- */
-static int
-clps7111fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                    u_int transp, struct fb_info *info)
-{
-       unsigned int level, mask, shift, pal;
-
-       if (regno >= (1 << info->var.bits_per_pixel))
-               return 1;
-
-       /* gray = 0.30*R + 0.58*G + 0.11*B */
-       level = (red * 77 + green * 151 + blue * 28) >> 20;
-
-       /*
-        * On an LCD, a high value is dark, while a low value is light. 
-        * So we invert the level.
-        *
-        * This isn't true on all machines, so we only do it on EDB7211.
-        *  --rmk
-        */
-       if (machine_is_edb7211()) {
-               level = 15 - level;
-       }
-
-       shift = 4 * (regno & 7);
-       level <<= shift;
-       mask  = 15 << shift;
-       level &= mask;
-
-       regno = regno < 8 ? PALLSW : PALMSW;
-
-       pal = clps_readl(regno);
-       pal = (pal & ~mask) | level;
-       clps_writel(pal, regno);
-
-       return 0;
-}
-
-/*
- * Validate the purposed mode.
- */    
-static int
-clps7111fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-       var->transp.msb_right   = 0;
-       var->transp.offset      = 0;
-       var->transp.length      = 0;
-       var->red.msb_right      = 0;
-       var->red.offset         = 0;
-       var->red.length         = var->bits_per_pixel;
-       var->green              = var->red;
-       var->blue               = var->red;
-
-       if (var->bits_per_pixel > 4) 
-               return -EINVAL;
-
-       return 0;
-}
-
-/*
- * Set the hardware state.
- */ 
-static int 
-clps7111fb_set_par(struct fb_info *info)
-{
-       unsigned int lcdcon, syscon, pixclock;
-
-       switch (info->var.bits_per_pixel) {
-       case 1:
-               info->fix.visual = FB_VISUAL_MONO01;
-               break;
-       case 2:
-               info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-               break;
-       case 4:
-               info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-               break;
-       }
-
-       info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel / 8;
-
-       lcdcon = (info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel) / 128 - 1;
-       lcdcon |= ((info->var.xres_virtual / 16) - 1) << 13;
-       lcdcon |= lcd_ac_prescale << 25;
-
-       /*
-        * Calculate pixel prescale value from the pixclock.  This is:
-        *  36.864MHz / pixclock_mhz - 1.
-        * However, pixclock is in picoseconds, so this ends up being:
-        *  36864000 * pixclock_ps / 10^12 - 1
-        * and this will overflow the 32-bit math.  We perform this as
-        * (9 * 4096000 == 36864000):
-        *  pixclock_ps * 9 * (4096000 / 10^12) - 1
-        */
-       pixclock = 9 * info->var.pixclock / 244140 - 1;
-       lcdcon |= pixclock << 19;
-
-       if (info->var.bits_per_pixel == 4)
-               lcdcon |= LCDCON_GSMD;
-       if (info->var.bits_per_pixel >= 2)
-               lcdcon |= LCDCON_GSEN;
-
-       /*
-        * LCDCON must only be changed while the LCD is disabled
-        */
-       syscon = clps_readl(SYSCON1);
-       clps_writel(syscon & ~SYSCON1_LCDEN, SYSCON1);
-       clps_writel(lcdcon, LCDCON);
-       clps_writel(syscon | SYSCON1_LCDEN, SYSCON1);
-       return 0;
-}
-
-static int clps7111fb_blank(int blank, struct fb_info *info)
-{
-       /* Enable/Disable LCD controller. */
-       if (blank)
-               clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, SYSCON1);
-       else
-               clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN, SYSCON1);
-
-       return 0;
-}
-
-static struct fb_ops clps7111fb_ops = {
-       .owner          = THIS_MODULE,
-       .fb_check_var   = clps7111fb_check_var,
-       .fb_set_par     = clps7111fb_set_par,
-       .fb_setcolreg   = clps7111fb_setcolreg,
-       .fb_blank       = clps7111fb_blank,
-       .fb_fillrect    = cfb_fillrect,
-       .fb_copyarea    = cfb_copyarea,
-       .fb_imageblit   = cfb_imageblit,
-};
-
-static void clps711x_guess_lcd_params(struct fb_info *info)
-{
-       unsigned int lcdcon, syscon, size;
-       unsigned long phys_base = PAGE_OFFSET;
-       void *virt_base = (void *)PAGE_OFFSET;
-
-       info->var.xres_virtual   = 640;
-       info->var.yres_virtual   = 240;
-       info->var.bits_per_pixel = 4;
-       info->var.activate       = FB_ACTIVATE_NOW;
-       info->var.height         = -1;
-       info->var.width          = -1;
-       info->var.pixclock       = 93006; /* 10.752MHz pixel clock */
-
-       /*
-        * If the LCD controller is already running, decode the values
-        * in LCDCON to xres/yres/bpp/pixclock/acprescale
-        */
-       syscon = clps_readl(SYSCON1);
-       if (syscon & SYSCON1_LCDEN) {
-               lcdcon = clps_readl(LCDCON);
-
-               /*
-                * Decode GSMD and GSEN bits to bits per pixel
-                */
-               switch (lcdcon & (LCDCON_GSMD | LCDCON_GSEN)) {
-               case LCDCON_GSMD | LCDCON_GSEN:
-                       info->var.bits_per_pixel = 4;
-                       break;
-
-               case LCDCON_GSEN:
-                       info->var.bits_per_pixel = 2;
-                       break;
-
-               default:
-                       info->var.bits_per_pixel = 1;
-                       break;
-               }
-
-               /*
-                * Decode xres/yres
-                */
-               info->var.xres_virtual = (((lcdcon >> 13) & 0x3f) + 1) * 16;
-               info->var.yres_virtual = (((lcdcon & 0x1fff) + 1) * 128) /
-                                         (info->var.xres_virtual *
-                                          info->var.bits_per_pixel);
-
-               /*
-                * Calculate pixclock
-                */
-               info->var.pixclock = (((lcdcon >> 19) & 0x3f) + 1) * 244140 / 9;
-
-               /*
-                * Grab AC prescale
-                */
-               lcd_ac_prescale = (lcdcon >> 25) & 0x1f;
-       }
-
-       info->var.xres = info->var.xres_virtual;
-       info->var.yres = info->var.yres_virtual;
-       info->var.grayscale = info->var.bits_per_pixel > 1;
-
-       size = info->var.xres * info->var.yres * info->var.bits_per_pixel / 8;
-
-       /*
-        * Might be worth checking to see if we can use the on-board
-        * RAM if size here...
-        * CLPS7110 - no on-board SRAM
-        * EP7212   - 38400 bytes
-        */
-       if (size <= 38400) {
-               printk(KERN_INFO "CLPS711xFB: could use on-board SRAM?\n");
-       }
-
-       if ((syscon & SYSCON1_LCDEN) == 0) {
-               /*
-                * The display isn't running.  Ensure that
-                * the display memory is empty.
-                */
-               memset(virt_base, 0, size);
-       }
-
-       info->screen_base    = virt_base;
-       info->fix.smem_start = phys_base;
-       info->fix.smem_len   = PAGE_ALIGN(size);
-       info->fix.type       = FB_TYPE_PACKED_PIXELS;
-}
-
-static int clps711x_fb_probe(struct platform_device *pdev)
-{
-       int err = -ENOMEM;
-
-       if (fb_get_options("clps711xfb", NULL))
-               return -ENODEV;
-
-       cfb = kzalloc(sizeof(*cfb), GFP_KERNEL);
-       if (!cfb)
-               goto out;
-
-       strcpy(cfb->fix.id, "clps711x");
-
-       cfb->fbops              = &clps7111fb_ops;
-       cfb->flags              = FBINFO_DEFAULT;
-
-       clps711x_guess_lcd_params(cfb);
-
-       fb_alloc_cmap(&cfb->cmap, CMAP_MAX_SIZE, 0);
-
-       err = register_framebuffer(cfb);
-
-out:   return err;
-}
-
-static int clps711x_fb_remove(struct platform_device *pdev)
-{
-       unregister_framebuffer(cfb);
-       kfree(cfb);
-
-       return 0;
-}
-
-static struct platform_driver clps711x_fb_driver = {
-       .driver = {
-               .name   = "video-clps711x",
-       },
-       .probe  = clps711x_fb_probe,
-       .remove = clps711x_fb_remove,
-};
-module_platform_driver(clps711x_fb_driver);
-
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("CLPS711X framebuffer driver");
-MODULE_LICENSE("GPL");
index 852d86c1c527ac26c3987d18d379108849f8060b..dd3128990776ef35670fbc4e3cab09bbf6b10ebe 100644 (file)
@@ -1480,8 +1480,8 @@ int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
        if (ret)
                return ret;
 
-       pr_debug("%pOF: got %dx%d display mode from %s\n",
-               np, vm.hactive, vm.vactive, np->name);
+       pr_debug("%pOF: got %dx%d display mode\n",
+               np, vm.hactive, vm.vactive);
        dump_fb_videomode(fb);
 
        return 0;
index ecdcf358ad5eac2d76f20439add5818625ff64e2..901ca4ed10e9c923c9e332d8b20523a121270b4f 100644 (file)
@@ -1473,7 +1473,7 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        
        dp = pci_device_to_OF_node(pdev);
        if(dp)
-               printk(KERN_INFO "%s: OF name %s\n",__func__, dp->name);
+               printk(KERN_INFO "%s: OF name %pOFn\n",__func__, dp);
        else if (IS_ENABLED(CONFIG_OF))
                printk(KERN_ERR "imsttfb: no OF node for pci device\n");
 
index 71862188f5285953104c62744d3216bfb8a59d10..446ac3364bad21872398f75dec25a1cb0b194346 100644 (file)
@@ -434,7 +434,7 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 static void
 leo_init_fix(struct fb_info *info, struct device_node *dp)
 {
-       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
+       snprintf(info->fix.id, sizeof(info->fix.id), "%pOFn", dp);
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_TRUECOLOR;
index c735d133895c5dc29f80e1940ffbec2c2aa208dc..fcb711143fb23bea6bc910fd6b901c292f881462 100644 (file)
@@ -3,7 +3,6 @@ if MMP_DISP
 config MMP_DISP_CONTROLLER
        bool "mmp display controller hw support"
        depends on CPU_PXA910 || CPU_MMP2
-       default n
        help
                Marvell MMP display hw controller support
                this controller is used on Marvell PXA910 and
index 808890f7064bb63e52abacd872c122f82a7c293f..f58558795f39c907989a8137c8695da916b5985e 100644 (file)
@@ -2,6 +2,5 @@
 config MMP_PANEL_TPOHVGA
        bool "tpohvga panel TJ032MD01BW support"
        depends on SPI_MASTER
-       default n
        help
                tpohvga panel support
index 77c0a2f45b3b949819030e90f252f1905e554843..31f769d67195b9d748fed8aafec7b43633dd1545 100644 (file)
@@ -419,9 +419,13 @@ static void __init offb_init_fb(const char *name,
        var = &info->var;
        info->par = par;
 
-       strcpy(fix->id, "OFfb ");
-       strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
-       fix->id[sizeof(fix->id) - 1] = '\0';
+       if (name) {
+               strcpy(fix->id, "OFfb ");
+               strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
+               fix->id[sizeof(fix->id) - 1] = '\0';
+       } else
+               snprintf(fix->id, sizeof(fix->id), "OFfb %pOFn", dp);
+
 
        var->xres = var->xres_virtual = width;
        var->yres = var->yres_virtual = height;
@@ -644,7 +648,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
                /* kludge for valkyrie */
                if (strcmp(dp->name, "valkyrie") == 0)
                        address += 0x1000;
-               offb_init_fb(no_real_node ? "bootx" : dp->name,
+               offb_init_fb(no_real_node ? "bootx" : NULL,
                             width, height, depth, pitch, address,
                             foreign_endian, no_real_node ? NULL : dp);
        }
index e8c748a0dfe25f5113a1fc7ebbbf94614fa88290..cddbd00cbf9fffdbe92e8e3c12ef3ebf3b4fa0be 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/lcd.h>
-#include <linux/gpio.h>
 
 #include <mach/hardware.h>
-#include <mach/board-ams-delta.h>
 
 #include "omapfb.h"
 
@@ -41,6 +40,8 @@
 /* LCD class device section */
 
 static int ams_delta_lcd;
+static struct gpio_desc *gpiod_vblen;
+static struct gpio_desc *gpiod_ndisp;
 
 static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
 {
@@ -99,41 +100,17 @@ static struct lcd_ops ams_delta_lcd_ops = {
 
 /* omapfb panel section */
 
-static const struct gpio _gpios[] = {
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_LCD_VBLEN,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "lcd_vblen",
-       },
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_LCD_NDISP,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "lcd_ndisp",
-       },
-};
-
-static int ams_delta_panel_init(struct lcd_panel *panel,
-               struct omapfb_device *fbdev)
-{
-       return gpio_request_array(_gpios, ARRAY_SIZE(_gpios));
-}
-
-static void ams_delta_panel_cleanup(struct lcd_panel *panel)
-{
-       gpio_free_array(_gpios, ARRAY_SIZE(_gpios));
-}
-
 static int ams_delta_panel_enable(struct lcd_panel *panel)
 {
-       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 1);
-       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 1);
+       gpiod_set_value(gpiod_ndisp, 1);
+       gpiod_set_value(gpiod_vblen, 1);
        return 0;
 }
 
 static void ams_delta_panel_disable(struct lcd_panel *panel)
 {
-       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 0);
-       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 0);
+       gpiod_set_value(gpiod_vblen, 0);
+       gpiod_set_value(gpiod_ndisp, 0);
 }
 
 static struct lcd_panel ams_delta_panel = {
@@ -154,8 +131,6 @@ static struct lcd_panel ams_delta_panel = {
        .pcd            = 0,
        .acb            = 37,
 
-       .init           = ams_delta_panel_init,
-       .cleanup        = ams_delta_panel_cleanup,
        .enable         = ams_delta_panel_enable,
        .disable        = ams_delta_panel_disable,
 };
@@ -166,9 +141,23 @@ static struct lcd_panel ams_delta_panel = {
 static int ams_delta_panel_probe(struct platform_device *pdev)
 {
        struct lcd_device *lcd_device = NULL;
-#ifdef CONFIG_LCD_CLASS_DEVICE
        int ret;
 
+       gpiod_vblen = devm_gpiod_get(&pdev->dev, "vblen", GPIOD_OUT_LOW);
+       if (IS_ERR(gpiod_vblen)) {
+               ret = PTR_ERR(gpiod_vblen);
+               dev_err(&pdev->dev, "VBLEN GPIO request failed (%d)\n", ret);
+               return ret;
+       }
+
+       gpiod_ndisp = devm_gpiod_get(&pdev->dev, "ndisp", GPIOD_OUT_LOW);
+       if (IS_ERR(gpiod_ndisp)) {
+               ret = PTR_ERR(gpiod_ndisp);
+               dev_err(&pdev->dev, "NDISP GPIO request failed (%d)\n", ret);
+               return ret;
+       }
+
+#ifdef CONFIG_LCD_CLASS_DEVICE
        lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
                                                &ams_delta_lcd_ops);
 
index 6d0bb27e4f85eb1c197f44e676dfe8a66a332ce4..356b89b378d4de2981d285f6711b9f880e73499b 100644 (file)
@@ -10,7 +10,6 @@ config FB_OMAP2_DSS
 
 config FB_OMAP2_DSS_DEBUG
        bool "Debug support"
-       default n
        help
          This enables printing of debug messages. Alternatively, debug messages
          can also be enabled by setting CONFIG_DYNAMIC_DEBUG and then setting
@@ -19,7 +18,6 @@ config FB_OMAP2_DSS_DEBUG
 config FB_OMAP2_DSS_DEBUGFS
        bool "Debugfs filesystem support"
        depends on DEBUG_FS
-       default n
        help
          This enables debugfs for OMAPDSS at <debugfs>/omapdss. This enables
          querying about clock configuration and register configuration of dss,
@@ -28,7 +26,6 @@ config FB_OMAP2_DSS_DEBUGFS
 config FB_OMAP2_DSS_COLLECT_IRQ_STATS
        bool "Collect DSS IRQ statistics"
        depends on FB_OMAP2_DSS_DEBUGFS
-       default n
        help
          Collect DSS IRQ statistics, printable via debugfs.
 
@@ -45,7 +42,6 @@ config FB_OMAP2_DSS_DPI
 config FB_OMAP2_DSS_RFBI
        bool "RFBI support"
        depends on BROKEN
-        default n
        help
          MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
          Instrument's terminology).
@@ -73,7 +69,6 @@ config FB_OMAP4_DSS_HDMI
 
 config FB_OMAP5_DSS_HDMI
        bool "HDMI support for OMAP5"
-       default n
        select FB_OMAP2_DSS_HDMI_COMMON
        help
          HDMI Interface for OMAP5 and similar cores. This adds the High
@@ -82,7 +77,6 @@ config FB_OMAP5_DSS_HDMI
 
 config FB_OMAP2_DSS_SDI
        bool "SDI support"
-        default n
        help
          SDI (Serial Display Interface) support.
 
@@ -91,7 +85,6 @@ config FB_OMAP2_DSS_SDI
 
 config FB_OMAP2_DSS_DSI
        bool "DSI support"
-        default n
        help
          MIPI DSI (Display Serial Interface) support.
 
index 64de5cda541ddd5e55c24a2f60079d962b5add8d..c4283e9e95afafe4f7230088f8f8dd60422d379e 100644 (file)
@@ -239,7 +239,7 @@ static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
 
 static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
+       snprintf(info->fix.id, sizeof(info->fix.id), "%pOFn", dp);
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
index d059d04c63acd7bc118bbc0ec02fc3cb1dfa41f8..e31340fad3c7af576c9ad26ff7603449135f3fb3 100644 (file)
@@ -405,9 +405,6 @@ static int pxa168fb_set_par(struct fb_info *info)
        struct fb_var_screeninfo *var = &info->var;
        struct fb_videomode mode;
        u32 x;
-       struct pxa168fb_mach_info *mi;
-
-       mi = dev_get_platdata(fbi->dev);
 
        /*
         * Set additional mode info.
index a436d44f1b7fbf4e2fe2447de21a6aa5a4903cde..01a7110e61a76a19167fae82d71e1f9efdb312e3 100644 (file)
@@ -106,11 +106,11 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                struct fbtype __user *f = (struct fbtype __user *) arg;
 
                if (put_user(type, &f->fb_type) ||
-                   __put_user(info->var.yres, &f->fb_height) ||
-                   __put_user(info->var.xres, &f->fb_width) ||
-                   __put_user(fb_depth, &f->fb_depth) ||
-                   __put_user(0, &f->fb_cmsize) ||
-                   __put_user(fb_size, &f->fb_cmsize))
+                   put_user(info->var.yres, &f->fb_height) ||
+                   put_user(info->var.xres, &f->fb_width) ||
+                   put_user(fb_depth, &f->fb_depth) ||
+                   put_user(0, &f->fb_cmsize) ||
+                   put_user(fb_size, &f->fb_cmsize))
                        return -EFAULT;
                return 0;
        }
@@ -125,10 +125,10 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                unsigned int index, count, i;
 
                if (get_user(index, &c->index) ||
-                   __get_user(count, &c->count) ||
-                   __get_user(ured, &c->red) ||
-                   __get_user(ugreen, &c->green) ||
-                   __get_user(ublue, &c->blue))
+                   get_user(count, &c->count) ||
+                   get_user(ured, &c->red) ||
+                   get_user(ugreen, &c->green) ||
+                   get_user(ublue, &c->blue))
                        return -EFAULT;
 
                cmap.len = 1;
@@ -165,13 +165,13 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                u8 red, green, blue;
 
                if (get_user(index, &c->index) ||
-                   __get_user(count, &c->count) ||
-                   __get_user(ured, &c->red) ||
-                   __get_user(ugreen, &c->green) ||
-                   __get_user(ublue, &c->blue))
+                   get_user(count, &c->count) ||
+                   get_user(ured, &c->red) ||
+                   get_user(ugreen, &c->green) ||
+                   get_user(ublue, &c->blue))
                        return -EFAULT;
 
-               if (index + count > cmap->len)
+               if (index > cmap->len || count > cmap->len - index)
                        return -EINVAL;
 
                for (i = 0; i < count; i++) {
index 96de91d766230887a8e243258e761c7d716bc596..405715b60ec7cb16ee21cb190869036d5287e934 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SH7760/SH7763 LCDC Framebuffer driver.
  *
@@ -5,10 +6,6 @@
  *             Manuel Lauss <mano@roarinelk.homelinux.net>
  * (c) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
  *
- *  This file is subject to the terms and conditions of the GNU General
- *  Public License.  See the file COPYING in the main directory of this
- *  archive for more details.
- *
  * PLEASE HAVE A LOOK AT Documentation/fb/sh7760fb.txt!
  *
  * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de>
@@ -587,4 +584,4 @@ module_platform_driver(sh7760_lcdc_driver);
 
 MODULE_AUTHOR("Nobuhiro Iwamatsu, Manuel Lauss");
 MODULE_DESCRIPTION("FBdev for SH7760/63 integrated LCD Controller");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 27a2b72e50e84b45e5ba1b292daf4bd386442143..a8fb41f1a2580e02574f9a40cbc5d1919ed34fdb 100644 (file)
@@ -848,9 +848,7 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
            SiS_DDC2Delay(SiS_Pr, 0x4000);
         }
 
-      } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
-        (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
-        (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) {                  /* 315 series, LVDS; Special */
+      } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {                       /* 315 series, LVDS; Special */
 
         if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
            PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
index 6439231f2db22ec13a227ed009598d58cadd737f..4061a20cfe24a2a33b0e8eda203ac6bad718cb3d 100644 (file)
@@ -667,9 +667,9 @@ static int ssd1307fb_probe(struct i2c_client *client,
 
        if (par->reset) {
                /* Reset the screen */
-               gpiod_set_value(par->reset, 0);
+               gpiod_set_value_cansleep(par->reset, 0);
                udelay(4);
-               gpiod_set_value(par->reset, 1);
+               gpiod_set_value_cansleep(par->reset, 1);
                udelay(4);
        }
 
index afbd6101c78eb4c0b87a4c6a8a4cce47cf474176..070026a7e55a507273f8a6a8d7c9b2f9cce70c3c 100644 (file)
@@ -916,8 +916,6 @@ static int dlfb_ops_open(struct fb_info *info, int user)
 
        dlfb->fb_count++;
 
-       kref_get(&dlfb->kref);
-
        if (fb_defio && (info->fbdefio == NULL)) {
                /* enable defio at last moment if not disabled by client */
 
@@ -940,14 +938,17 @@ static int dlfb_ops_open(struct fb_info *info, int user)
        return 0;
 }
 
-/*
- * Called when all client interfaces to start transactions have been disabled,
- * and all references to our device instance (dlfb_data) are released.
- * Every transaction must have a reference, so we know are fully spun down
- */
-static void dlfb_free(struct kref *kref)
+static void dlfb_ops_destroy(struct fb_info *info)
 {
-       struct dlfb_data *dlfb = container_of(kref, struct dlfb_data, kref);
+       struct dlfb_data *dlfb = info->par;
+
+       if (info->cmap.len != 0)
+               fb_dealloc_cmap(&info->cmap);
+       if (info->monspecs.modedb)
+               fb_destroy_modedb(info->monspecs.modedb);
+       vfree(info->screen_base);
+
+       fb_destroy_modelist(&info->modelist);
 
        while (!list_empty(&dlfb->deferred_free)) {
                struct dlfb_deferred_free *d = list_entry(dlfb->deferred_free.next, struct dlfb_deferred_free, list);
@@ -957,40 +958,13 @@ static void dlfb_free(struct kref *kref)
        }
        vfree(dlfb->backing_buffer);
        kfree(dlfb->edid);
+       usb_put_dev(dlfb->udev);
        kfree(dlfb);
-}
-
-static void dlfb_free_framebuffer(struct dlfb_data *dlfb)
-{
-       struct fb_info *info = dlfb->info;
-
-       if (info) {
-               unregister_framebuffer(info);
-
-               if (info->cmap.len != 0)
-                       fb_dealloc_cmap(&info->cmap);
-               if (info->monspecs.modedb)
-                       fb_destroy_modedb(info->monspecs.modedb);
-               vfree(info->screen_base);
-
-               fb_destroy_modelist(&info->modelist);
-
-               dlfb->info = NULL;
-
-               /* Assume info structure is freed after this point */
-               framebuffer_release(info);
-       }
 
-       /* ref taken in probe() as part of registering framebfufer */
-       kref_put(&dlfb->kref, dlfb_free);
+       /* Assume info structure is freed after this point */
+       framebuffer_release(info);
 }
 
-static void dlfb_free_framebuffer_work(struct work_struct *work)
-{
-       struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
-                                            free_framebuffer_work.work);
-       dlfb_free_framebuffer(dlfb);
-}
 /*
  * Assumes caller is holding info->lock mutex (for open and release at least)
  */
@@ -1000,10 +974,6 @@ static int dlfb_ops_release(struct fb_info *info, int user)
 
        dlfb->fb_count--;
 
-       /* We can't free fb_info here - fbmem will touch it when we return */
-       if (dlfb->virtualized && (dlfb->fb_count == 0))
-               schedule_delayed_work(&dlfb->free_framebuffer_work, HZ);
-
        if ((dlfb->fb_count == 0) && (info->fbdefio)) {
                fb_deferred_io_cleanup(info);
                kfree(info->fbdefio);
@@ -1013,8 +983,6 @@ static int dlfb_ops_release(struct fb_info *info, int user)
 
        dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count);
 
-       kref_put(&dlfb->kref, dlfb_free);
-
        return 0;
 }
 
@@ -1172,6 +1140,7 @@ static struct fb_ops dlfb_ops = {
        .fb_blank = dlfb_ops_blank,
        .fb_check_var = dlfb_ops_check_var,
        .fb_set_par = dlfb_ops_set_par,
+       .fb_destroy = dlfb_ops_destroy,
 };
 
 
@@ -1615,12 +1584,13 @@ success:
        return true;
 }
 
-static void dlfb_init_framebuffer_work(struct work_struct *work);
-
 static int dlfb_usb_probe(struct usb_interface *intf,
                          const struct usb_device_id *id)
 {
+       int i;
+       const struct device_attribute *attr;
        struct dlfb_data *dlfb;
+       struct fb_info *info;
        int retval = -ENOMEM;
        struct usb_device *usbdev = interface_to_usbdev(intf);
 
@@ -1631,10 +1601,9 @@ static int dlfb_usb_probe(struct usb_interface *intf,
                goto error;
        }
 
-       kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */
        INIT_LIST_HEAD(&dlfb->deferred_free);
 
-       dlfb->udev = usbdev;
+       dlfb->udev = usb_get_dev(usbdev);
        usb_set_intfdata(intf, dlfb);
 
        dev_dbg(&intf->dev, "console enable=%d\n", console);
@@ -1657,42 +1626,6 @@ static int dlfb_usb_probe(struct usb_interface *intf,
        }
 
 
-       if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
-               retval = -ENOMEM;
-               dev_err(&intf->dev, "unable to allocate urb list\n");
-               goto error;
-       }
-
-       kref_get(&dlfb->kref); /* matching kref_put in free_framebuffer_work */
-
-       /* We don't register a new USB class. Our client interface is dlfbev */
-
-       /* Workitem keep things fast & simple during USB enumeration */
-       INIT_DELAYED_WORK(&dlfb->init_framebuffer_work,
-                         dlfb_init_framebuffer_work);
-       schedule_delayed_work(&dlfb->init_framebuffer_work, 0);
-
-       return 0;
-
-error:
-       if (dlfb) {
-
-               kref_put(&dlfb->kref, dlfb_free); /* last ref from kref_init */
-
-               /* dev has been deallocated. Do not dereference */
-       }
-
-       return retval;
-}
-
-static void dlfb_init_framebuffer_work(struct work_struct *work)
-{
-       int i, retval;
-       struct fb_info *info;
-       const struct device_attribute *attr;
-       struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
-                                            init_framebuffer_work.work);
-
        /* allocates framebuffer driver structure, not framebuffer memory */
        info = framebuffer_alloc(0, &dlfb->udev->dev);
        if (!info) {
@@ -1706,17 +1639,22 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
        dlfb->ops = dlfb_ops;
        info->fbops = &dlfb->ops;
 
+       INIT_LIST_HEAD(&info->modelist);
+
+       if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
+               retval = -ENOMEM;
+               dev_err(&intf->dev, "unable to allocate urb list\n");
+               goto error;
+       }
+
+       /* We don't register a new USB class. Our client interface is dlfbev */
+
        retval = fb_alloc_cmap(&info->cmap, 256, 0);
        if (retval < 0) {
                dev_err(info->device, "cmap allocation failed: %d\n", retval);
                goto error;
        }
 
-       INIT_DELAYED_WORK(&dlfb->free_framebuffer_work,
-                         dlfb_free_framebuffer_work);
-
-       INIT_LIST_HEAD(&info->modelist);
-
        retval = dlfb_setup_modes(dlfb, info, NULL, 0);
        if (retval != 0) {
                dev_err(info->device,
@@ -1760,10 +1698,16 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
                 dev_name(info->dev), info->var.xres, info->var.yres,
                 ((dlfb->backing_buffer) ?
                 info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
-       return;
+       return 0;
 
 error:
-       dlfb_free_framebuffer(dlfb);
+       if (dlfb->info) {
+               dlfb_ops_destroy(dlfb->info);
+       } else if (dlfb) {
+               usb_put_dev(dlfb->udev);
+               kfree(dlfb);
+       }
+       return retval;
 }
 
 static void dlfb_usb_disconnect(struct usb_interface *intf)
@@ -1791,20 +1735,9 @@ static void dlfb_usb_disconnect(struct usb_interface *intf)
                for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
                        device_remove_file(info->dev, &fb_device_attrs[i]);
                device_remove_bin_file(info->dev, &edid_attr);
-               unlink_framebuffer(info);
        }
 
-       usb_set_intfdata(intf, NULL);
-       dlfb->udev = NULL;
-
-       /* if clients still have us open, will be freed on last close */
-       if (dlfb->fb_count == 0)
-               schedule_delayed_work(&dlfb->free_framebuffer_work, 0);
-
-       /* release reference taken by kref_init in probe() */
-       kref_put(&dlfb->kref, dlfb_free);
-
-       /* consider dlfb_data freed */
+       unregister_framebuffer(info);
 }
 
 static struct usb_driver dlfb_driver = {
index 38716eb50408c0a8ab52be3cceaf7bce10a13031..8a3e8f61b991bd7fb14a5552eed46a56c88a1d6a 100644 (file)
@@ -592,10 +592,10 @@ hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)
                return "xvYCC 709";
        case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
                return "sYCC 601";
-       case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601:
-               return "Adobe YCC 601";
-       case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB:
-               return "Adobe RGB";
+       case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
+               return "opYCC 601";
+       case HDMI_EXTENDED_COLORIMETRY_OPRGB:
+               return "opRGB";
        case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
                return "BT.2020 Constant Luminance";
        case HDMI_EXTENDED_COLORIMETRY_BT2020:
index 5244e93ceafc5c0b520ad0f849dadf1d70e09dbb..c2e7aa103fa574c2a83ed1ea6eab1987ca294970 100644 (file)
@@ -170,7 +170,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np)
                goto entryfail;
        }
 
-       pr_debug("%pOF: using %s as default timing\n", np, entry->name);
+       pr_debug("%pOF: using %pOFn as default timing\n", np, entry);
 
        native_mode = entry;
 
index 548c751d2415813fd909cb4926bb3cfdbfa75967..122fb3c3ec9d0dbb8abea7259f916ffd86e610a3 100644 (file)
@@ -455,7 +455,7 @@ int save_vga(struct vgastate *state)
        return 0;
 }
 
-int restore_vga (struct vgastate *state)
+int restore_vga(struct vgastate *state)
 {
        if (state->vidstate == NULL)
                return 1;
index 90d387b50ab747f505597e87b439f1dcfe5f489f..815b9e9bb9757e899f64da4994dbe428c6da133e 100644 (file)
@@ -12,7 +12,6 @@ config XEN_BALLOON
 config XEN_SELFBALLOONING
        bool "Dynamically self-balloon kernel memory to target"
        depends on XEN && XEN_BALLOON && CLEANCACHE && SWAP && XEN_TMEM
-       default n
        help
          Self-ballooning dynamically balloons available kernel memory driven
          by the current usage of anonymous memory ("committed AS") and
@@ -27,7 +26,6 @@ config XEN_SELFBALLOONING
 
 config XEN_BALLOON_MEMORY_HOTPLUG
        bool "Memory hotplug support for Xen balloon driver"
-       default n
        depends on XEN_BALLOON && MEMORY_HOTPLUG
        help
          Memory hotplug support for Xen balloon driver allows expanding memory
@@ -86,7 +84,7 @@ config XEN_SCRUB_PAGES_DEFAULT
        help
          Scrub pages before returning them to the system for reuse by
          other domains.  This makes sure that any confidential data
-         is not accidentally visible to other domains.  Is it more
+         is not accidentally visible to other domains.  It is more
          secure, but slightly less efficient. This can be controlled with
          xen_scrub_pages=0 parameter and
          /sys/devices/system/xen_memory/xen_memory0/scrub_pages.
@@ -105,8 +103,7 @@ config XEN_DEV_EVTCHN
 
 config XEN_BACKEND
        bool "Backend driver support"
-       depends on XEN_DOM0
-       default y
+       default XEN_DOM0
        help
          Support for backend device drivers that provide I/O services
          to other virtual machines.
@@ -227,7 +224,6 @@ config XEN_PCIDEV_BACKEND
 config XEN_PVCALLS_FRONTEND
        tristate "XEN PV Calls frontend driver"
        depends on INET && XEN
-       default n
        select XEN_XENBUS_FRONTEND
        help
          Experimental frontend for the Xen PV Calls protocol
@@ -238,7 +234,6 @@ config XEN_PVCALLS_FRONTEND
 config XEN_PVCALLS_BACKEND
        bool "XEN PV Calls backend driver"
        depends on INET && XEN && XEN_BACKEND
-       default n
        help
          Experimental backend for the Xen PV Calls protocol
          (https://xenbits.xen.org/docs/unstable/misc/pvcalls.html). It
@@ -264,7 +259,6 @@ config XEN_PRIVCMD
 config XEN_STUB
        bool "Xen stub drivers"
        depends on XEN && X86_64 && BROKEN
-       default n
        help
          Allow kernel to install stub drivers, to reserve space for Xen drivers,
          i.e. memory hotplug and cpu hotplug, and to block native drivers loaded,
@@ -275,7 +269,6 @@ config XEN_STUB
 config XEN_ACPI_HOTPLUG_MEMORY
        tristate "Xen ACPI memory hotplug"
        depends on XEN_DOM0 && XEN_STUB && ACPI
-       default n
        help
          This is Xen ACPI memory hotplug.
 
@@ -287,7 +280,6 @@ config XEN_ACPI_HOTPLUG_CPU
        tristate "Xen ACPI cpu hotplug"
        depends on XEN_DOM0 && XEN_STUB && ACPI
        select ACPI_CONTAINER
-       default n
        help
          Xen ACPI cpu enumerating and hotplugging
 
@@ -316,7 +308,6 @@ config XEN_ACPI_PROCESSOR
 config XEN_MCE_LOG
        bool "Xen platform mcelog"
        depends on XEN_DOM0 && X86_64 && X86_MCE
-       default n
        help
          Allow kernel fetching MCE error from Xen platform and
          converting it into Linux mcelog format for mcelog tools
index e12bb256036fbb0d56ee2523ec60b929f57340d5..fdfc64f5aceaa807e392b887d278daf466de3eae 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/cred.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include <linux/mutex.h>
@@ -395,7 +395,10 @@ static enum bp_state reserve_additional_memory(void)
         * callers drop the mutex before trying again.
         */
        mutex_unlock(&balloon_mutex);
+       /* add_memory_resource() requires the device_hotplug lock */
+       lock_device_hotplug();
        rc = add_memory_resource(nid, resource, memhp_auto_online);
+       unlock_device_hotplug();
        mutex_lock(&balloon_mutex);
 
        if (rc) {
index e6c1934734b7d9bdde87e8a9e006e1584c88f15d..93194f3e75404f05655028531d5ae710a6d6db87 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/irq.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/irqnr.h>
 #include <linux/pci.h>
index 84575baceebc829305e49b8855a0cad9c188a9fc..f15f89df1f3653675da3b84b1c7ce47debd1bac6 100644 (file)
@@ -33,7 +33,7 @@
 
 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
index f5c1af4ce9abb550083d2cae04a4e19a485cbcdc..2a7f545bd0b577bef9a0058385c941f5c5fc6977 100644 (file)
@@ -35,7 +35,7 @@
 
 #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/dma-direct.h>
 #include <linux/export.h>
 #include <xen/swiotlb-xen.h>
@@ -217,7 +217,8 @@ retry:
         * Get IO TLB memory from any location.
         */
        if (early)
-               xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes));
+               xen_io_tlb_start = memblock_alloc(PAGE_ALIGN(bytes),
+                                                 PAGE_SIZE);
        else {
 #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
 #define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
@@ -247,7 +248,8 @@ retry:
                               xen_io_tlb_nslabs);
        if (rc) {
                if (early)
-                       free_bootmem(__pa(xen_io_tlb_start), PAGE_ALIGN(bytes));
+                       memblock_free(__pa(xen_io_tlb_start),
+                                     PAGE_ALIGN(bytes));
                else {
                        free_pages((unsigned long)xen_io_tlb_start, order);
                        xen_io_tlb_start = NULL;
index 63c1494a8d73bf2f53f0f0a1887290f338ae454a..2acbfe104e464ab0d8e59bb5ff1862ce08411ed0 100644 (file)
@@ -76,12 +76,15 @@ static void watch_target(struct xenbus_watch *watch,
 
        if (!watch_fired) {
                watch_fired = true;
-               err = xenbus_scanf(XBT_NIL, "memory", "static-max", "%llu",
-                                  &static_max);
-               if (err != 1)
-                       static_max = new_target;
-               else
+
+               if ((xenbus_scanf(XBT_NIL, "memory", "static-max",
+                                 "%llu", &static_max) == 1) ||
+                   (xenbus_scanf(XBT_NIL, "memory", "memory_static_max",
+                                 "%llu", &static_max) == 1))
                        static_max >>= PAGE_SHIFT - 10;
+               else
+                       static_max = new_target;
+
                target_diff = (xen_pv_domain() || xen_initial_domain()) ? 0
                                : static_max - balloon_stats.target_pages;
        }
index 55988b8418eeb7eb315745ad7737278fa3c5ddd7..5165aa82bf7d47322f9abc1ad7e7fb161663b6e4 100644 (file)
@@ -68,7 +68,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/swap.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
index a1c17000129ba1cb4465df0bc679a0756f8937a3..e17ca8156171318394bd41f08a7e27ef8683d70a 100644 (file)
@@ -278,10 +278,8 @@ static void xenbus_va_dev_error(struct xenbus_device *dev, int err,
        dev_err(&dev->dev, "%s\n", printf_buffer);
 
        path_buffer = kasprintf(GFP_KERNEL, "error/%s", dev->nodename);
-       if (!path_buffer ||
-           xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer))
-               dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
-                       dev->nodename, printf_buffer);
+       if (path_buffer)
+               xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer);
 
        kfree(printf_buffer);
        kfree(path_buffer);
index 082d227fa56b378772883f3a4254e7fd05c436d5..6261719f6f2a133c1f059cebaf470f3e28ef0b1c 100644 (file)
@@ -276,7 +276,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
        switch (handler->flags) {
        case ACL_TYPE_ACCESS:
                if (acl) {
-                       struct iattr iattr;
+                       struct iattr iattr = { 0 };
                        struct posix_acl *old_acl = acl;
 
                        retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
index 89bac3d2f05b9a9ddc320fcc9fcc3f3115701991..619128b5583702559dae61480262644e3542b3e7 100644 (file)
@@ -61,6 +61,8 @@ enum {
        Opt_cache_loose, Opt_fscache, Opt_mmap,
        /* Access options */
        Opt_access, Opt_posixacl,
+       /* Lock timeout option */
+       Opt_locktimeout,
        /* Error token */
        Opt_err
 };
@@ -80,6 +82,7 @@ static const match_table_t tokens = {
        {Opt_cachetag, "cachetag=%s"},
        {Opt_access, "access=%s"},
        {Opt_posixacl, "posixacl"},
+       {Opt_locktimeout, "locktimeout=%u"},
        {Opt_err, NULL}
 };
 
@@ -187,6 +190,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 #ifdef CONFIG_9P_FSCACHE
        v9ses->cachetag = NULL;
 #endif
+       v9ses->session_lock_timeout = P9_LOCK_TIMEOUT;
 
        if (!opts)
                return 0;
@@ -359,6 +363,23 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 #endif
                        break;
 
+               case Opt_locktimeout:
+                       r = match_int(&args[0], &option);
+                       if (r < 0) {
+                               p9_debug(P9_DEBUG_ERROR,
+                                        "integer field, but no integer?\n");
+                               ret = r;
+                               continue;
+                       }
+                       if (option < 1) {
+                               p9_debug(P9_DEBUG_ERROR,
+                                        "locktimeout must be a greater than zero integer.\n");
+                               ret = -EINVAL;
+                               continue;
+                       }
+                       v9ses->session_lock_timeout = (long)option * HZ;
+                       break;
+
                default:
                        continue;
                }
index 982e017acadbc7f9efccf445876959e811d85aa4..129e5243a6bf6cfb4d7fb1793ebf5c99686b3c6b 100644 (file)
@@ -116,6 +116,7 @@ struct v9fs_session_info {
        struct p9_client *clnt; /* 9p client */
        struct list_head slist; /* list of sessions registered with v9fs */
        struct rw_semaphore rename_sem;
+       long session_lock_timeout; /* retry interval for blocking locks */
 };
 
 /* cache_validity flags */
index b0405d6aac854d4e3bb69b813f587775cbeeebe8..cb6c4031af552b010c2e8ff5469b9088c769b3b7 100644 (file)
@@ -76,15 +76,6 @@ static inline int dt_type(struct p9_wstat *mistat)
        return rettype;
 }
 
-static void p9stat_init(struct p9_wstat *stbuf)
-{
-       stbuf->name  = NULL;
-       stbuf->uid   = NULL;
-       stbuf->gid   = NULL;
-       stbuf->muid  = NULL;
-       stbuf->extension = NULL;
-}
-
 /**
  * v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
  * @filp: opened file structure
@@ -114,7 +105,6 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
        int err = 0;
        struct p9_fid *fid;
        int buflen;
-       int reclen = 0;
        struct p9_rdir *rdir;
        struct kvec kvec;
 
@@ -145,15 +135,12 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
                        rdir->tail = n;
                }
                while (rdir->head < rdir->tail) {
-                       p9stat_init(&st);
                        err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
                                          rdir->tail - rdir->head, &st);
-                       if (err) {
+                       if (err <= 0) {
                                p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
-                               p9stat_free(&st);
                                return -EIO;
                        }
-                       reclen = st.size+2;
 
                        over = !dir_emit(ctx, st.name, strlen(st.name),
                                         v9fs_qid2ino(&st.qid), dt_type(&st));
@@ -161,8 +148,8 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
                        if (over)
                                return 0;
 
-                       rdir->head += reclen;
-                       ctx->pos += reclen;
+                       rdir->head += err;
+                       ctx->pos += err;
                }
        }
 }
index 5f2e48d41d725b40ec02c3f72ffb735733d3eaa3..a25efa782fccbab2c30a3a743a1c4f547b72e9c4 100644 (file)
@@ -154,6 +154,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
        uint8_t status = P9_LOCK_ERROR;
        int res = 0;
        unsigned char fl_type;
+       struct v9fs_session_info *v9ses;
 
        fid = filp->private_data;
        BUG_ON(fid == NULL);
@@ -189,6 +190,8 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
        if (IS_SETLKW(cmd))
                flock.flags = P9_LOCK_FLAGS_BLOCK;
 
+       v9ses = v9fs_inode2v9ses(file_inode(filp));
+
        /*
         * if its a blocked request and we get P9_LOCK_BLOCKED as the status
         * for lock request, keep on trying
@@ -202,8 +205,17 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
                        break;
                if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
                        break;
-               if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0)
+               if (schedule_timeout_interruptible(v9ses->session_lock_timeout)
+                               != 0)
                        break;
+               /*
+                * p9_client_lock_dotl overwrites flock.client_id with the
+                * server message, free and reuse the client name
+                */
+               if (flock.client_id != fid->clnt->name) {
+                       kfree(flock.client_id);
+                       flock.client_id = fid->clnt->name;
+               }
        }
 
        /* map 9p status to VFS status */
@@ -216,7 +228,7 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
                break;
        default:
                WARN_ONCE(1, "unknown lock status code: %d\n", status);
-               /* fallthough */
+               /* fall through */
        case P9_LOCK_ERROR:
        case P9_LOCK_GRACE:
                res = -ENOLCK;
@@ -235,6 +247,8 @@ out_unlock:
                locks_lock_file_wait(filp, fl);
                fl->fl_type = fl_type;
        }
+       if (flock.client_id != fid->clnt->name)
+               kfree(flock.client_id);
 out:
        return res;
 }
@@ -269,7 +283,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
 
        res = p9_client_getlock_dotl(fid, &glock);
        if (res < 0)
-               return res;
+               goto out;
        /* map 9p lock type to os lock type */
        switch (glock.type) {
        case P9_LOCK_TYPE_RDLCK:
@@ -290,7 +304,9 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
                        fl->fl_end = glock.start + glock.length - 1;
                fl->fl_pid = -glock.proc_id;
        }
-       kfree(glock.client_id);
+out:
+       if (glock.client_id != fid->clnt->name)
+               kfree(glock.client_id);
        return res;
 }
 
index 2ee43b6a4f0995367ca5497f87d343674b319553..539901fb516503a5767fadd3bd278447a9263800 100644 (file)
@@ -1014,9 +1014,26 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
        if ((root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && parent)
                parent_start = parent->start;
 
+       /*
+        * If we are COWing a node/leaf from the extent, chunk or device trees,
+        * make sure that we do not finish block group creation of pending block
+        * groups. We do this to avoid a deadlock.
+        * COWing can result in allocation of a new chunk, and flushing pending
+        * block groups (btrfs_create_pending_block_groups()) can be triggered
+        * when finishing allocation of a new chunk. Creation of a pending block
+        * group modifies the extent, chunk and device trees, therefore we could
+        * deadlock with ourselves since we are holding a lock on an extent
+        * buffer that btrfs_create_pending_block_groups() may try to COW later.
+        */
+       if (root == fs_info->extent_root ||
+           root == fs_info->chunk_root ||
+           root == fs_info->dev_root)
+               trans->can_flush_pending_bgs = false;
+
        cow = btrfs_alloc_tree_block(trans, root, parent_start,
                        root->root_key.objectid, &disk_key, level,
                        search_start, empty_size);
+       trans->can_flush_pending_bgs = true;
        if (IS_ERR(cow))
                return PTR_ERR(cow);
 
index 5149165b49a45d96e2e62091b26b5d54dea1f815..9301b3ad921705c48659b86dd9098f97f42af3e6 100644 (file)
@@ -164,14 +164,27 @@ static struct btrfs_delayed_ref_node* tree_insert(struct rb_root_cached *root,
        return NULL;
 }
 
+static struct btrfs_delayed_ref_head *find_first_ref_head(
+               struct btrfs_delayed_ref_root *dr)
+{
+       struct rb_node *n;
+       struct btrfs_delayed_ref_head *entry;
+
+       n = rb_first_cached(&dr->href_root);
+       if (!n)
+               return NULL;
+
+       entry = rb_entry(n, struct btrfs_delayed_ref_head, href_node);
+
+       return entry;
+}
+
 /*
- * find an head entry based on bytenr. This returns the delayed ref
- * head if it was able to find one, or NULL if nothing was in that spot.
- * If return_bigger is given, the next bigger entry is returned if no exact
- * match is found. But if no bigger one is found then the first node of the
- * ref head tree will be returned.
+ * Find a head entry based on bytenr. This returns the delayed ref head if it
+ * was able to find one, or NULL if nothing was in that spot.  If return_bigger
+ * is given, the next bigger entry is returned if no exact match is found.
  */
-static struct btrfs_delayed_ref_headfind_ref_head(
+static struct btrfs_delayed_ref_head *find_ref_head(
                struct btrfs_delayed_ref_root *dr, u64 bytenr,
                bool return_bigger)
 {
@@ -195,10 +208,9 @@ static struct btrfs_delayed_ref_head* find_ref_head(
                if (bytenr > entry->bytenr) {
                        n = rb_next(&entry->href_node);
                        if (!n)
-                               n = rb_first_cached(&dr->href_root);
+                               return NULL;
                        entry = rb_entry(n, struct btrfs_delayed_ref_head,
                                         href_node);
-                       return entry;
                }
                return entry;
        }
@@ -355,33 +367,25 @@ struct btrfs_delayed_ref_head *btrfs_select_ref_head(
                struct btrfs_delayed_ref_root *delayed_refs)
 {
        struct btrfs_delayed_ref_head *head;
-       u64 start;
-       bool loop = false;
 
 again:
-       start = delayed_refs->run_delayed_start;
-       head = find_ref_head(delayed_refs, start, true);
-       if (!head && !loop) {
+       head = find_ref_head(delayed_refs, delayed_refs->run_delayed_start,
+                            true);
+       if (!head && delayed_refs->run_delayed_start != 0) {
                delayed_refs->run_delayed_start = 0;
-               start = 0;
-               loop = true;
-               head = find_ref_head(delayed_refs, start, true);
-               if (!head)
-                       return NULL;
-       } else if (!head && loop) {
-               return NULL;
+               head = find_first_ref_head(delayed_refs);
        }
+       if (!head)
+               return NULL;
 
        while (head->processing) {
                struct rb_node *node;
 
                node = rb_next(&head->href_node);
                if (!node) {
-                       if (loop)
+                       if (delayed_refs->run_delayed_start == 0)
                                return NULL;
                        delayed_refs->run_delayed_start = 0;
-                       start = 0;
-                       loop = true;
                        goto again;
                }
                head = rb_entry(node, struct btrfs_delayed_ref_head,
index a4cd0221bc8d3684b26ef68ece99fc984f06a911..a1febf155747e05c21212b65bf2d3ff758f37868 100644 (file)
@@ -2366,6 +2366,9 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
                                           insert_reserved);
        else
                BUG();
+       if (ret && insert_reserved)
+               btrfs_pin_extent(trans->fs_info, node->bytenr,
+                                node->num_bytes, 1);
        return ret;
 }
 
@@ -2954,7 +2957,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
        struct btrfs_delayed_ref_head *head;
        int ret;
        int run_all = count == (unsigned long)-1;
-       bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
 
        /* We'll clean this up in btrfs_cleanup_transaction */
        if (trans->aborted)
@@ -2971,7 +2973,6 @@ again:
 #ifdef SCRAMBLE_DELAYED_REFS
        delayed_refs->run_delayed_start = find_middle(&delayed_refs->root);
 #endif
-       trans->can_flush_pending_bgs = false;
        ret = __btrfs_run_delayed_refs(trans, count);
        if (ret < 0) {
                btrfs_abort_transaction(trans, ret);
@@ -3002,7 +3003,6 @@ again:
                goto again;
        }
 out:
-       trans->can_flush_pending_bgs = can_flush_pending_bgs;
        return 0;
 }
 
@@ -4568,6 +4568,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
                        goto out;
        } else {
                ret = 1;
+               space_info->max_extent_size = 0;
        }
 
        space_info->force_alloc = CHUNK_ALLOC_NO_FORCE;
@@ -4589,11 +4590,9 @@ out:
         * the block groups that were made dirty during the lifetime of the
         * transaction.
         */
-       if (trans->can_flush_pending_bgs &&
-           trans->chunk_bytes_reserved >= (u64)SZ_2M) {
+       if (trans->chunk_bytes_reserved >= (u64)SZ_2M)
                btrfs_create_pending_block_groups(trans);
-               btrfs_trans_release_chunk_metadata(trans);
-       }
+
        return ret;
 }
 
@@ -6464,6 +6463,7 @@ static void btrfs_free_reserved_bytes(struct btrfs_block_group_cache *cache,
                space_info->bytes_readonly += num_bytes;
        cache->reserved -= num_bytes;
        space_info->bytes_reserved -= num_bytes;
+       space_info->max_extent_size = 0;
 
        if (delalloc)
                cache->delalloc_bytes -= num_bytes;
@@ -7260,6 +7260,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
        struct btrfs_block_group_cache *block_group = NULL;
        u64 search_start = 0;
        u64 max_extent_size = 0;
+       u64 max_free_space = 0;
        u64 empty_cluster = 0;
        struct btrfs_space_info *space_info;
        int loop = 0;
@@ -7555,8 +7556,8 @@ unclustered_alloc:
                        spin_lock(&ctl->tree_lock);
                        if (ctl->free_space <
                            num_bytes + empty_cluster + empty_size) {
-                               if (ctl->free_space > max_extent_size)
-                                       max_extent_size = ctl->free_space;
+                               max_free_space = max(max_free_space,
+                                                    ctl->free_space);
                                spin_unlock(&ctl->tree_lock);
                                goto loop;
                        }
@@ -7723,6 +7724,8 @@ loop:
        }
 out:
        if (ret == -ENOSPC) {
+               if (!max_extent_size)
+                       max_extent_size = max_free_space;
                spin_lock(&space_info->lock);
                space_info->max_extent_size = max_extent_size;
                spin_unlock(&space_info->lock);
@@ -8004,21 +8007,14 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
        }
 
        path = btrfs_alloc_path();
-       if (!path) {
-               btrfs_free_and_pin_reserved_extent(fs_info,
-                                                  extent_key.objectid,
-                                                  fs_info->nodesize);
+       if (!path)
                return -ENOMEM;
-       }
 
        path->leave_spinning = 1;
        ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path,
                                      &extent_key, size);
        if (ret) {
                btrfs_free_path(path);
-               btrfs_free_and_pin_reserved_extent(fs_info,
-                                                  extent_key.objectid,
-                                                  fs_info->nodesize);
                return ret;
        }
 
@@ -10132,9 +10128,10 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
        struct btrfs_block_group_item item;
        struct btrfs_key key;
        int ret = 0;
-       bool can_flush_pending_bgs = trans->can_flush_pending_bgs;
 
-       trans->can_flush_pending_bgs = false;
+       if (!trans->can_flush_pending_bgs)
+               return;
+
        while (!list_empty(&trans->new_bgs)) {
                block_group = list_first_entry(&trans->new_bgs,
                                               struct btrfs_block_group_cache,
@@ -10159,7 +10156,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
 next:
                list_del_init(&block_group->bg_list);
        }
-       trans->can_flush_pending_bgs = can_flush_pending_bgs;
+       btrfs_trans_release_chunk_metadata(trans);
 }
 
 int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
index 15b925142793b67b0153ec031dd9b01bf1856bd4..97c7a086f7bd69f1dddb68fbdbf5c8bcc995024c 100644 (file)
@@ -2078,6 +2078,14 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                goto out;
 
        inode_lock(inode);
+
+       /*
+        * We take the dio_sem here because the tree log stuff can race with
+        * lockless dio writes and get an extent map logged for an extent we
+        * never waited on.  We need it this high up for lockdep reasons.
+        */
+       down_write(&BTRFS_I(inode)->dio_sem);
+
        atomic_inc(&root->log_batch);
 
        /*
@@ -2086,6 +2094,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
         */
        ret = btrfs_wait_ordered_range(inode, start, len);
        if (ret) {
+               up_write(&BTRFS_I(inode)->dio_sem);
                inode_unlock(inode);
                goto out;
        }
@@ -2109,6 +2118,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                 * checked called fsync.
                 */
                ret = filemap_check_wb_err(inode->i_mapping, file->f_wb_err);
+               up_write(&BTRFS_I(inode)->dio_sem);
                inode_unlock(inode);
                goto out;
        }
@@ -2127,6 +2137,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
+               up_write(&BTRFS_I(inode)->dio_sem);
                inode_unlock(inode);
                goto out;
        }
@@ -2148,6 +2159,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
         * file again, but that will end up using the synchronization
         * inside btrfs_sync_log to keep things safe.
         */
+       up_write(&BTRFS_I(inode)->dio_sem);
        inode_unlock(inode);
 
        /*
index 67441219d6c99fef5bb7135191a73b8b08668de6..4ba0aedc878bd4422e67d47879b1de297ed848c8 100644 (file)
@@ -1772,6 +1772,13 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
        return -1;
 }
 
+static inline u64 get_max_extent_size(struct btrfs_free_space *entry)
+{
+       if (entry->bitmap)
+               return entry->max_extent_size;
+       return entry->bytes;
+}
+
 /* Cache the size of the max extent in bytes */
 static struct btrfs_free_space *
 find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
@@ -1793,8 +1800,8 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
        for (node = &entry->offset_index; node; node = rb_next(node)) {
                entry = rb_entry(node, struct btrfs_free_space, offset_index);
                if (entry->bytes < *bytes) {
-                       if (entry->bytes > *max_extent_size)
-                               *max_extent_size = entry->bytes;
+                       *max_extent_size = max(get_max_extent_size(entry),
+                                              *max_extent_size);
                        continue;
                }
 
@@ -1812,8 +1819,8 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
                }
 
                if (entry->bytes < *bytes + align_off) {
-                       if (entry->bytes > *max_extent_size)
-                               *max_extent_size = entry->bytes;
+                       *max_extent_size = max(get_max_extent_size(entry),
+                                              *max_extent_size);
                        continue;
                }
 
@@ -1825,8 +1832,10 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
                                *offset = tmp;
                                *bytes = size;
                                return entry;
-                       } else if (size > *max_extent_size) {
-                               *max_extent_size = size;
+                       } else {
+                               *max_extent_size =
+                                       max(get_max_extent_size(entry),
+                                           *max_extent_size);
                        }
                        continue;
                }
@@ -2449,6 +2458,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
        struct rb_node *n;
        int count = 0;
 
+       spin_lock(&ctl->tree_lock);
        for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) {
                info = rb_entry(n, struct btrfs_free_space, offset_index);
                if (info->bytes >= bytes && !block_group->ro)
@@ -2457,6 +2467,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
                           info->offset, info->bytes,
                       (info->bitmap) ? "yes" : "no");
        }
+       spin_unlock(&ctl->tree_lock);
        btrfs_info(fs_info, "block group has cluster?: %s",
               list_empty(&block_group->cluster_list) ? "no" : "yes");
        btrfs_info(fs_info,
@@ -2685,8 +2696,8 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
 
        err = search_bitmap(ctl, entry, &search_start, &search_bytes, true);
        if (err) {
-               if (search_bytes > *max_extent_size)
-                       *max_extent_size = search_bytes;
+               *max_extent_size = max(get_max_extent_size(entry),
+                                      *max_extent_size);
                return 0;
        }
 
@@ -2723,8 +2734,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
 
        entry = rb_entry(node, struct btrfs_free_space, offset_index);
        while (1) {
-               if (entry->bytes < bytes && entry->bytes > *max_extent_size)
-                       *max_extent_size = entry->bytes;
+               if (entry->bytes < bytes)
+                       *max_extent_size = max(get_max_extent_size(entry),
+                                              *max_extent_size);
 
                if (entry->bytes < bytes ||
                    (!entry->bitmap && entry->offset < min_start)) {
index 181c58b231103e5a7381be49cddc10c2faf3fdc5..d3df5b52278cea06c05384ef7bf63aaed6b5404f 100644 (file)
@@ -502,6 +502,7 @@ again:
                pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
                if (!pages) {
                        /* just bail out to the uncompressed code */
+                       nr_pages = 0;
                        goto cont;
                }
 
@@ -2940,6 +2941,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
        bool truncated = false;
        bool range_locked = false;
        bool clear_new_delalloc_bytes = false;
+       bool clear_reserved_extent = true;
 
        if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
            !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags) &&
@@ -3043,10 +3045,12 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                                                logical_len, logical_len,
                                                compress_type, 0, 0,
                                                BTRFS_FILE_EXTENT_REG);
-               if (!ret)
+               if (!ret) {
+                       clear_reserved_extent = false;
                        btrfs_release_delalloc_bytes(fs_info,
                                                     ordered_extent->start,
                                                     ordered_extent->disk_len);
+               }
        }
        unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
                           ordered_extent->file_offset, ordered_extent->len,
@@ -3107,8 +3111,13 @@ out:
                 * wrong we need to return the space for this ordered extent
                 * back to the allocator.  We only free the extent in the
                 * truncated case if we didn't write out the extent at all.
+                *
+                * If we made it past insert_reserved_file_extent before we
+                * errored out then we don't need to do this as the accounting
+                * has already been done.
                 */
                if ((ret || !logical_len) &&
+                   clear_reserved_extent &&
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
                    !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags))
                        btrfs_free_reserved_extent(fs_info,
@@ -5259,11 +5268,13 @@ static void evict_inode_truncate_pages(struct inode *inode)
                struct extent_state *cached_state = NULL;
                u64 start;
                u64 end;
+               unsigned state_flags;
 
                node = rb_first(&io_tree->state);
                state = rb_entry(node, struct extent_state, rb_node);
                start = state->start;
                end = state->end;
+               state_flags = state->state;
                spin_unlock(&io_tree->lock);
 
                lock_extent_bits(io_tree, start, end, &cached_state);
@@ -5276,7 +5287,7 @@ static void evict_inode_truncate_pages(struct inode *inode)
                 *
                 * Note, end is the bytenr of last byte, so we need + 1 here.
                 */
-               if (state->state & EXTENT_DELALLOC)
+               if (state_flags & EXTENT_DELALLOC)
                        btrfs_qgroup_free_data(inode, NULL, start, end - start + 1);
 
                clear_extent_bit(io_tree, start, end,
index 5686290a50e1186133ed43fe33cd4b86b811544e..d1eeef9ec5dac512faa62e50766602dc9f110223 100644 (file)
@@ -2283,15 +2283,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
 
        kmem_cache_free(btrfs_trans_handle_cachep, trans);
 
-       /*
-        * If fs has been frozen, we can not handle delayed iputs, otherwise
-        * it'll result in deadlock about SB_FREEZE_FS.
-        */
-       if (current != fs_info->transaction_kthread &&
-           current != fs_info->cleaner_kthread &&
-           !test_bit(BTRFS_FS_FROZEN, &fs_info->flags))
-               btrfs_run_delayed_iputs(fs_info);
-
        return ret;
 
 scrub_continue:
index 0dba09334a163ab9222c22335fc22f46cfbcd5da..e07f3376b7dfc0c9350117bf3db956781e57d45e 100644 (file)
@@ -4390,7 +4390,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
 
        INIT_LIST_HEAD(&extents);
 
-       down_write(&inode->dio_sem);
        write_lock(&tree->lock);
        test_gen = root->fs_info->last_trans_committed;
        logged_start = start;
@@ -4456,7 +4455,6 @@ process:
        }
        WARN_ON(!list_empty(&extents));
        write_unlock(&tree->lock);
-       up_write(&inode->dio_sem);
 
        btrfs_release_path(path);
        if (!ret)
@@ -4652,7 +4650,8 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
                        ASSERT(len == i_size ||
                               (len == fs_info->sectorsize &&
                                btrfs_file_extent_compression(leaf, extent) !=
-                               BTRFS_COMPRESS_NONE));
+                               BTRFS_COMPRESS_NONE) ||
+                              (len < i_size && i_size < fs_info->sectorsize));
                        return 0;
                }
 
index 027408d55aeed946c13fc42ded7e3146f5a5fffa..5f0103f4007906032df4c56ecb2414e8f7cc3803 100644 (file)
@@ -104,6 +104,11 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        struct timespec64 old_ctime = inode->i_ctime;
        umode_t new_mode = inode->i_mode, old_mode = inode->i_mode;
 
+       if (ceph_snap(inode) != CEPH_NOSNAP) {
+               ret = -EROFS;
+               goto out;
+       }
+
        switch (type) {
        case ACL_TYPE_ACCESS:
                name = XATTR_NAME_POSIX_ACL_ACCESS;
@@ -138,11 +143,6 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
                        goto out_free;
        }
 
-       if (ceph_snap(inode) != CEPH_NOSNAP) {
-               ret = -EROFS;
-               goto out_free;
-       }
-
        if (new_mode != old_mode) {
                newattrs.ia_ctime = current_time(inode);
                newattrs.ia_mode = new_mode;
@@ -206,10 +206,9 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
        tmp_buf = kmalloc(max(val_size1, val_size2), GFP_KERNEL);
        if (!tmp_buf)
                goto out_err;
-       pagelist = kmalloc(sizeof(struct ceph_pagelist), GFP_KERNEL);
+       pagelist = ceph_pagelist_alloc(GFP_KERNEL);
        if (!pagelist)
                goto out_err;
-       ceph_pagelist_init(pagelist);
 
        err = ceph_pagelist_reserve(pagelist, PAGE_SIZE);
        if (err)
index 9c332a6f66678a04cfe4b6cf05a33253c85f30f5..8eade7a993c1f5f120908849a38a0c80537cf505 100644 (file)
@@ -322,7 +322,7 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
                /* caller of readpages does not hold buffer and read caps
                 * (fadvise, madvise and readahead cases) */
                int want = CEPH_CAP_FILE_CACHE;
-               ret = ceph_try_get_caps(ci, CEPH_CAP_FILE_RD, want, &got);
+               ret = ceph_try_get_caps(ci, CEPH_CAP_FILE_RD, want, true, &got);
                if (ret < 0) {
                        dout("start_read %p, error getting cap\n", inode);
                } else if (!(got & want)) {
index dd7dfdd2ba13903575aee52a0b8fc27660cda2f8..f3496db4bb3e80d24adec6413168b20299321439 100644 (file)
@@ -519,9 +519,9 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc,
  *    -> we take mdsc->cap_delay_lock
  */
 static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
-                               struct ceph_inode_info *ci)
+                               struct ceph_inode_info *ci,
+                               bool set_timeout)
 {
-       __cap_set_timeouts(mdsc, ci);
        dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode,
             ci->i_ceph_flags, ci->i_hold_caps_max);
        if (!mdsc->stopping) {
@@ -531,6 +531,8 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc,
                                goto no_change;
                        list_del_init(&ci->i_cap_delay_list);
                }
+               if (set_timeout)
+                       __cap_set_timeouts(mdsc, ci);
                list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list);
 no_change:
                spin_unlock(&mdsc->cap_delay_lock);
@@ -720,7 +722,7 @@ void ceph_add_cap(struct inode *inode,
                dout(" issued %s, mds wanted %s, actual %s, queueing\n",
                     ceph_cap_string(issued), ceph_cap_string(wanted),
                     ceph_cap_string(actual_wanted));
-               __cap_delay_requeue(mdsc, ci);
+               __cap_delay_requeue(mdsc, ci, true);
        }
 
        if (flags & CEPH_CAP_FLAG_AUTH) {
@@ -1647,7 +1649,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask,
        if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
            (mask & CEPH_CAP_FILE_BUFFER))
                dirty |= I_DIRTY_DATASYNC;
-       __cap_delay_requeue(mdsc, ci);
+       __cap_delay_requeue(mdsc, ci, true);
        return dirty;
 }
 
@@ -2065,7 +2067,7 @@ ack:
 
        /* Reschedule delayed caps release if we delayed anything */
        if (delayed)
-               __cap_delay_requeue(mdsc, ci);
+               __cap_delay_requeue(mdsc, ci, false);
 
        spin_unlock(&ci->i_ceph_lock);
 
@@ -2125,7 +2127,7 @@ retry:
 
                if (delayed) {
                        spin_lock(&ci->i_ceph_lock);
-                       __cap_delay_requeue(mdsc, ci);
+                       __cap_delay_requeue(mdsc, ci, true);
                        spin_unlock(&ci->i_ceph_lock);
                }
        } else {
@@ -2671,17 +2673,18 @@ static void check_max_size(struct inode *inode, loff_t endoff)
                ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
 }
 
-int ceph_try_get_caps(struct ceph_inode_info *ci, int need, int want, int *got)
+int ceph_try_get_caps(struct ceph_inode_info *ci, int need, int want,
+                     bool nonblock, int *got)
 {
        int ret, err = 0;
 
        BUG_ON(need & ~CEPH_CAP_FILE_RD);
-       BUG_ON(want & ~(CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO));
+       BUG_ON(want & ~(CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO|CEPH_CAP_FILE_SHARED));
        ret = ceph_pool_perm_check(ci, need);
        if (ret < 0)
                return ret;
 
-       ret = try_get_cap_refs(ci, need, want, 0, true, got, &err);
+       ret = try_get_cap_refs(ci, need, want, 0, nonblock, got, &err);
        if (ret) {
                if (err == -EAGAIN) {
                        ret = 0;
index 92ab2043368291e68c5c4b67b2da7e6bfdd25fcf..f788496fafcc9eeab5907cdcd7c68b16e0aecf8a 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/ceph/ceph_debug.h>
+#include <linux/ceph/striper.h>
 
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -556,91 +557,27 @@ enum {
        READ_INLINE =  3,
 };
 
-/*
- * Read a range of bytes striped over one or more objects.  Iterate over
- * objects we stripe over.  (That's not atomic, but good enough for now.)
- *
- * If we get a short result from the OSD, check against i_size; we need to
- * only return a short read to the caller if we hit EOF.
- */
-static int striped_read(struct inode *inode,
-                       u64 pos, u64 len,
-                       struct page **pages, int num_pages,
-                       int page_align, int *checkeof)
-{
-       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
-       struct ceph_inode_info *ci = ceph_inode(inode);
-       u64 this_len;
-       loff_t i_size;
-       int page_idx;
-       int ret, read = 0;
-       bool hit_stripe, was_short;
-
-       /*
-        * we may need to do multiple reads.  not atomic, unfortunately.
-        */
-more:
-       this_len = len;
-       page_idx = (page_align + read) >> PAGE_SHIFT;
-       ret = ceph_osdc_readpages(&fsc->client->osdc, ceph_vino(inode),
-                                 &ci->i_layout, pos, &this_len,
-                                 ci->i_truncate_seq, ci->i_truncate_size,
-                                 pages + page_idx, num_pages - page_idx,
-                                 ((page_align + read) & ~PAGE_MASK));
-       if (ret == -ENOENT)
-               ret = 0;
-       hit_stripe = this_len < len;
-       was_short = ret >= 0 && ret < this_len;
-       dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, len, read,
-            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
-
-       i_size = i_size_read(inode);
-       if (ret >= 0) {
-               if (was_short && (pos + ret < i_size)) {
-                       int zlen = min(this_len - ret, i_size - pos - ret);
-                       int zoff = page_align + read + ret;
-                       dout(" zero gap %llu to %llu\n",
-                            pos + ret, pos + ret + zlen);
-                       ceph_zero_page_vector_range(zoff, zlen, pages);
-                       ret += zlen;
-               }
-
-               read += ret;
-               pos += ret;
-               len -= ret;
-
-               /* hit stripe and need continue*/
-               if (len && hit_stripe && pos < i_size)
-                       goto more;
-       }
-
-       if (read > 0) {
-               ret = read;
-               /* did we bounce off eof? */
-               if (pos + len > i_size)
-                       *checkeof = CHECK_EOF;
-       }
-
-       dout("striped_read returns %d\n", ret);
-       return ret;
-}
-
 /*
  * Completely synchronous read and write methods.  Direct from __user
  * buffer to osd, or directly to user pages (if O_DIRECT).
  *
- * If the read spans object boundary, just do multiple reads.
+ * If the read spans object boundary, just do multiple reads.  (That's not
+ * atomic, but good enough for now.)
+ *
+ * If we get a short result from the OSD, check against i_size; we need to
+ * only return a short read to the caller if we hit EOF.
  */
 static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
-                             int *checkeof)
+                             int *retry_op)
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
-       struct page **pages;
-       u64 off = iocb->ki_pos;
-       int num_pages;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
+       struct ceph_osd_client *osdc = &fsc->client->osdc;
        ssize_t ret;
-       size_t len = iov_iter_count(to);
+       u64 off = iocb->ki_pos;
+       u64 len = iov_iter_count(to);
 
        dout("sync_read on file %p %llu~%u %s\n", file, off, (unsigned)len,
             (file->f_flags & O_DIRECT) ? "O_DIRECT" : "");
@@ -653,61 +590,118 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
         * but it will at least behave sensibly when they are
         * in sequence.
         */
-       ret = filemap_write_and_wait_range(inode->i_mapping, off,
-                                               off + len);
+       ret = filemap_write_and_wait_range(inode->i_mapping, off, off + len);
        if (ret < 0)
                return ret;
 
-       if (unlikely(to->type & ITER_PIPE)) {
+       ret = 0;
+       while ((len = iov_iter_count(to)) > 0) {
+               struct ceph_osd_request *req;
+               struct page **pages;
+               int num_pages;
                size_t page_off;
-               ret = iov_iter_get_pages_alloc(to, &pages, len,
-                                              &page_off);
-               if (ret <= 0)
-                       return -ENOMEM;
-               num_pages = DIV_ROUND_UP(ret + page_off, PAGE_SIZE);
+               u64 i_size;
+               bool more;
+
+               req = ceph_osdc_new_request(osdc, &ci->i_layout,
+                                       ci->i_vino, off, &len, 0, 1,
+                                       CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
+                                       NULL, ci->i_truncate_seq,
+                                       ci->i_truncate_size, false);
+               if (IS_ERR(req)) {
+                       ret = PTR_ERR(req);
+                       break;
+               }
+
+               more = len < iov_iter_count(to);
 
-               ret = striped_read(inode, off, ret, pages, num_pages,
-                                  page_off, checkeof);
-               if (ret > 0) {
-                       iov_iter_advance(to, ret);
-                       off += ret;
+               if (unlikely(to->type & ITER_PIPE)) {
+                       ret = iov_iter_get_pages_alloc(to, &pages, len,
+                                                      &page_off);
+                       if (ret <= 0) {
+                               ceph_osdc_put_request(req);
+                               ret = -ENOMEM;
+                               break;
+                       }
+                       num_pages = DIV_ROUND_UP(ret + page_off, PAGE_SIZE);
+                       if (ret < len) {
+                               len = ret;
+                               osd_req_op_extent_update(req, 0, len);
+                               more = false;
+                       }
                } else {
-                       iov_iter_advance(to, 0);
+                       num_pages = calc_pages_for(off, len);
+                       page_off = off & ~PAGE_MASK;
+                       pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
+                       if (IS_ERR(pages)) {
+                               ceph_osdc_put_request(req);
+                               ret = PTR_ERR(pages);
+                               break;
+                       }
                }
-               ceph_put_page_vector(pages, num_pages, false);
-       } else {
-               num_pages = calc_pages_for(off, len);
-               pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
-               if (IS_ERR(pages))
-                       return PTR_ERR(pages);
-
-               ret = striped_read(inode, off, len, pages, num_pages,
-                                  (off & ~PAGE_MASK), checkeof);
-               if (ret > 0) {
-                       int l, k = 0;
-                       size_t left = ret;
-
-                       while (left) {
-                               size_t page_off = off & ~PAGE_MASK;
-                               size_t copy = min_t(size_t, left,
-                                                   PAGE_SIZE - page_off);
-                               l = copy_page_to_iter(pages[k++], page_off,
-                                                     copy, to);
-                               off += l;
-                               left -= l;
-                               if (l < copy)
+
+               osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_off,
+                                                false, false);
+               ret = ceph_osdc_start_request(osdc, req, false);
+               if (!ret)
+                       ret = ceph_osdc_wait_request(osdc, req);
+               ceph_osdc_put_request(req);
+
+               i_size = i_size_read(inode);
+               dout("sync_read %llu~%llu got %zd i_size %llu%s\n",
+                    off, len, ret, i_size, (more ? " MORE" : ""));
+
+               if (ret == -ENOENT)
+                       ret = 0;
+               if (ret >= 0 && ret < len && (off + ret < i_size)) {
+                       int zlen = min(len - ret, i_size - off - ret);
+                       int zoff = page_off + ret;
+                       dout("sync_read zero gap %llu~%llu\n",
+                             off + ret, off + ret + zlen);
+                       ceph_zero_page_vector_range(zoff, zlen, pages);
+                       ret += zlen;
+               }
+
+               if (unlikely(to->type & ITER_PIPE)) {
+                       if (ret > 0) {
+                               iov_iter_advance(to, ret);
+                               off += ret;
+                       } else {
+                               iov_iter_advance(to, 0);
+                       }
+                       ceph_put_page_vector(pages, num_pages, false);
+               } else {
+                       int idx = 0;
+                       size_t left = ret > 0 ? ret : 0;
+                       while (left > 0) {
+                               size_t len, copied;
+                               page_off = off & ~PAGE_MASK;
+                               len = min_t(size_t, left, PAGE_SIZE - page_off);
+                               copied = copy_page_to_iter(pages[idx++],
+                                                          page_off, len, to);
+                               off += copied;
+                               left -= copied;
+                               if (copied < len) {
+                                       ret = -EFAULT;
                                        break;
+                               }
                        }
+                       ceph_release_page_vector(pages, num_pages);
                }
-               ceph_release_page_vector(pages, num_pages);
+
+               if (ret <= 0 || off >= i_size || !more)
+                       break;
        }
 
        if (off > iocb->ki_pos) {
+               if (ret >= 0 &&
+                   iov_iter_count(to) > 0 && off >= i_size_read(inode))
+                       *retry_op = CHECK_EOF;
                ret = off - iocb->ki_pos;
                iocb->ki_pos = off;
        }
 
-       dout("sync_read result %zd\n", ret);
+       dout("sync_read result %zd retry_op %d\n", ret, *retry_op);
        return ret;
 }
 
@@ -865,7 +859,7 @@ static void ceph_aio_retry_work(struct work_struct *work)
        }
        spin_unlock(&ci->i_ceph_lock);
 
-       req = ceph_osdc_alloc_request(orig_req->r_osdc, snapc, 2,
+       req = ceph_osdc_alloc_request(orig_req->r_osdc, snapc, 1,
                        false, GFP_NOFS);
        if (!req) {
                ret = -ENOMEM;
@@ -877,6 +871,11 @@ static void ceph_aio_retry_work(struct work_struct *work)
        ceph_oloc_copy(&req->r_base_oloc, &orig_req->r_base_oloc);
        ceph_oid_copy(&req->r_base_oid, &orig_req->r_base_oid);
 
+       req->r_ops[0] = orig_req->r_ops[0];
+
+       req->r_mtime = aio_req->mtime;
+       req->r_data_offset = req->r_ops[0].extent.offset;
+
        ret = ceph_osdc_alloc_messages(req, GFP_NOFS);
        if (ret) {
                ceph_osdc_put_request(req);
@@ -884,11 +883,6 @@ static void ceph_aio_retry_work(struct work_struct *work)
                goto out;
        }
 
-       req->r_ops[0] = orig_req->r_ops[0];
-
-       req->r_mtime = aio_req->mtime;
-       req->r_data_offset = req->r_ops[0].extent.offset;
-
        ceph_osdc_put_request(orig_req);
 
        req->r_callback = ceph_aio_complete_req;
@@ -1735,7 +1729,6 @@ static long ceph_fallocate(struct file *file, int mode,
        struct ceph_file_info *fi = file->private_data;
        struct inode *inode = file_inode(file);
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_cap_flush *prealloc_cf;
        int want, got = 0;
        int dirty;
@@ -1743,10 +1736,7 @@ static long ceph_fallocate(struct file *file, int mode,
        loff_t endoff = 0;
        loff_t size;
 
-       if ((offset + length) > max(i_size_read(inode), fsc->max_file_size))
-               return -EFBIG;
-
-       if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
+       if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
                return -EOPNOTSUPP;
 
        if (!S_ISREG(inode->i_mode))
@@ -1763,18 +1753,6 @@ static long ceph_fallocate(struct file *file, int mode,
                goto unlock;
        }
 
-       if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) &&
-           ceph_quota_is_max_bytes_exceeded(inode, offset + length)) {
-               ret = -EDQUOT;
-               goto unlock;
-       }
-
-       if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_FULL) &&
-           !(mode & FALLOC_FL_PUNCH_HOLE)) {
-               ret = -ENOSPC;
-               goto unlock;
-       }
-
        if (ci->i_inline_version != CEPH_INLINE_NONE) {
                ret = ceph_uninline_data(file, NULL);
                if (ret < 0)
@@ -1782,12 +1760,12 @@ static long ceph_fallocate(struct file *file, int mode,
        }
 
        size = i_size_read(inode);
-       if (!(mode & FALLOC_FL_KEEP_SIZE)) {
-               endoff = offset + length;
-               ret = inode_newsize_ok(inode, endoff);
-               if (ret)
-                       goto unlock;
-       }
+
+       /* Are we punching a hole beyond EOF? */
+       if (offset >= size)
+               goto unlock;
+       if ((offset + length) > size)
+               length = size - offset;
 
        if (fi->fmode & CEPH_FILE_MODE_LAZY)
                want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
@@ -1798,16 +1776,8 @@ static long ceph_fallocate(struct file *file, int mode,
        if (ret < 0)
                goto unlock;
 
-       if (mode & FALLOC_FL_PUNCH_HOLE) {
-               if (offset < size)
-                       ceph_zero_pagecache_range(inode, offset, length);
-               ret = ceph_zero_objects(inode, offset, length);
-       } else if (endoff > size) {
-               truncate_pagecache_range(inode, size, -1);
-               if (ceph_inode_set_size(inode, endoff))
-                       ceph_check_caps(ceph_inode(inode),
-                               CHECK_CAPS_AUTHONLY, NULL);
-       }
+       ceph_zero_pagecache_range(inode, offset, length);
+       ret = ceph_zero_objects(inode, offset, length);
 
        if (!ret) {
                spin_lock(&ci->i_ceph_lock);
@@ -1817,9 +1787,6 @@ static long ceph_fallocate(struct file *file, int mode,
                spin_unlock(&ci->i_ceph_lock);
                if (dirty)
                        __mark_inode_dirty(inode, dirty);
-               if ((endoff > size) &&
-                   ceph_quota_is_max_bytes_approaching(inode, endoff))
-                       ceph_check_caps(ci, CHECK_CAPS_NODELAY, NULL);
        }
 
        ceph_put_cap_refs(ci, got);
@@ -1829,6 +1796,300 @@ unlock:
        return ret;
 }
 
+/*
+ * This function tries to get FILE_WR capabilities for dst_ci and FILE_RD for
+ * src_ci.  Two attempts are made to obtain both caps, and an error is return if
+ * this fails; zero is returned on success.
+ */
+static int get_rd_wr_caps(struct ceph_inode_info *src_ci,
+                         loff_t src_endoff, int *src_got,
+                         struct ceph_inode_info *dst_ci,
+                         loff_t dst_endoff, int *dst_got)
+{
+       int ret = 0;
+       bool retrying = false;
+
+retry_caps:
+       ret = ceph_get_caps(dst_ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
+                           dst_endoff, dst_got, NULL);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * Since we're already holding the FILE_WR capability for the dst file,
+        * we would risk a deadlock by using ceph_get_caps.  Thus, we'll do some
+        * retry dance instead to try to get both capabilities.
+        */
+       ret = ceph_try_get_caps(src_ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_SHARED,
+                               false, src_got);
+       if (ret <= 0) {
+               /* Start by dropping dst_ci caps and getting src_ci caps */
+               ceph_put_cap_refs(dst_ci, *dst_got);
+               if (retrying) {
+                       if (!ret)
+                               /* ceph_try_get_caps masks EAGAIN */
+                               ret = -EAGAIN;
+                       return ret;
+               }
+               ret = ceph_get_caps(src_ci, CEPH_CAP_FILE_RD,
+                                   CEPH_CAP_FILE_SHARED, src_endoff,
+                                   src_got, NULL);
+               if (ret < 0)
+                       return ret;
+               /*... drop src_ci caps too, and retry */
+               ceph_put_cap_refs(src_ci, *src_got);
+               retrying = true;
+               goto retry_caps;
+       }
+       return ret;
+}
+
+static void put_rd_wr_caps(struct ceph_inode_info *src_ci, int src_got,
+                          struct ceph_inode_info *dst_ci, int dst_got)
+{
+       ceph_put_cap_refs(src_ci, src_got);
+       ceph_put_cap_refs(dst_ci, dst_got);
+}
+
+/*
+ * This function does several size-related checks, returning an error if:
+ *  - source file is smaller than off+len
+ *  - destination file size is not OK (inode_newsize_ok())
+ *  - max bytes quotas is exceeded
+ */
+static int is_file_size_ok(struct inode *src_inode, struct inode *dst_inode,
+                          loff_t src_off, loff_t dst_off, size_t len)
+{
+       loff_t size, endoff;
+
+       size = i_size_read(src_inode);
+       /*
+        * Don't copy beyond source file EOF.  Instead of simply setting length
+        * to (size - src_off), just drop to VFS default implementation, as the
+        * local i_size may be stale due to other clients writing to the source
+        * inode.
+        */
+       if (src_off + len > size) {
+               dout("Copy beyond EOF (%llu + %zu > %llu)\n",
+                    src_off, len, size);
+               return -EOPNOTSUPP;
+       }
+       size = i_size_read(dst_inode);
+
+       endoff = dst_off + len;
+       if (inode_newsize_ok(dst_inode, endoff))
+               return -EOPNOTSUPP;
+
+       if (ceph_quota_is_max_bytes_exceeded(dst_inode, endoff))
+               return -EDQUOT;
+
+       return 0;
+}
+
+static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
+                                   struct file *dst_file, loff_t dst_off,
+                                   size_t len, unsigned int flags)
+{
+       struct inode *src_inode = file_inode(src_file);
+       struct inode *dst_inode = file_inode(dst_file);
+       struct ceph_inode_info *src_ci = ceph_inode(src_inode);
+       struct ceph_inode_info *dst_ci = ceph_inode(dst_inode);
+       struct ceph_cap_flush *prealloc_cf;
+       struct ceph_object_locator src_oloc, dst_oloc;
+       struct ceph_object_id src_oid, dst_oid;
+       loff_t endoff = 0, size;
+       ssize_t ret = -EIO;
+       u64 src_objnum, dst_objnum, src_objoff, dst_objoff;
+       u32 src_objlen, dst_objlen, object_size;
+       int src_got = 0, dst_got = 0, err, dirty;
+       bool do_final_copy = false;
+
+       if (src_inode == dst_inode)
+               return -EINVAL;
+       if (ceph_snap(dst_inode) != CEPH_NOSNAP)
+               return -EROFS;
+
+       /*
+        * Some of the checks below will return -EOPNOTSUPP, which will force a
+        * fallback to the default VFS copy_file_range implementation.  This is
+        * desirable in several cases (for ex, the 'len' is smaller than the
+        * size of the objects, or in cases where that would be more
+        * efficient).
+        */
+
+       if (ceph_test_mount_opt(ceph_inode_to_client(src_inode), NOCOPYFROM))
+               return -EOPNOTSUPP;
+
+       if ((src_ci->i_layout.stripe_unit != dst_ci->i_layout.stripe_unit) ||
+           (src_ci->i_layout.stripe_count != dst_ci->i_layout.stripe_count) ||
+           (src_ci->i_layout.object_size != dst_ci->i_layout.object_size))
+               return -EOPNOTSUPP;
+
+       if (len < src_ci->i_layout.object_size)
+               return -EOPNOTSUPP; /* no remote copy will be done */
+
+       prealloc_cf = ceph_alloc_cap_flush();
+       if (!prealloc_cf)
+               return -ENOMEM;
+
+       /* Start by sync'ing the source file */
+       ret = file_write_and_wait_range(src_file, src_off, (src_off + len));
+       if (ret < 0)
+               goto out;
+
+       /*
+        * We need FILE_WR caps for dst_ci and FILE_RD for src_ci as other
+        * clients may have dirty data in their caches.  And OSDs know nothing
+        * about caps, so they can't safely do the remote object copies.
+        */
+       err = get_rd_wr_caps(src_ci, (src_off + len), &src_got,
+                            dst_ci, (dst_off + len), &dst_got);
+       if (err < 0) {
+               dout("get_rd_wr_caps returned %d\n", err);
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       ret = is_file_size_ok(src_inode, dst_inode, src_off, dst_off, len);
+       if (ret < 0)
+               goto out_caps;
+
+       size = i_size_read(dst_inode);
+       endoff = dst_off + len;
+
+       /* Drop dst file cached pages */
+       ret = invalidate_inode_pages2_range(dst_inode->i_mapping,
+                                           dst_off >> PAGE_SHIFT,
+                                           endoff >> PAGE_SHIFT);
+       if (ret < 0) {
+               dout("Failed to invalidate inode pages (%zd)\n", ret);
+               ret = 0; /* XXX */
+       }
+       src_oloc.pool = src_ci->i_layout.pool_id;
+       src_oloc.pool_ns = ceph_try_get_string(src_ci->i_layout.pool_ns);
+       dst_oloc.pool = dst_ci->i_layout.pool_id;
+       dst_oloc.pool_ns = ceph_try_get_string(dst_ci->i_layout.pool_ns);
+
+       ceph_calc_file_object_mapping(&src_ci->i_layout, src_off,
+                                     src_ci->i_layout.object_size,
+                                     &src_objnum, &src_objoff, &src_objlen);
+       ceph_calc_file_object_mapping(&dst_ci->i_layout, dst_off,
+                                     dst_ci->i_layout.object_size,
+                                     &dst_objnum, &dst_objoff, &dst_objlen);
+       /* object-level offsets need to the same */
+       if (src_objoff != dst_objoff) {
+               ret = -EOPNOTSUPP;
+               goto out_caps;
+       }
+
+       /*
+        * Do a manual copy if the object offset isn't object aligned.
+        * 'src_objlen' contains the bytes left until the end of the object,
+        * starting at the src_off
+        */
+       if (src_objoff) {
+               /*
+                * we need to temporarily drop all caps as we'll be calling
+                * {read,write}_iter, which will get caps again.
+                */
+               put_rd_wr_caps(src_ci, src_got, dst_ci, dst_got);
+               ret = do_splice_direct(src_file, &src_off, dst_file,
+                                      &dst_off, src_objlen, flags);
+               if (ret < 0) {
+                       dout("do_splice_direct returned %d\n", err);
+                       goto out;
+               }
+               len -= ret;
+               err = get_rd_wr_caps(src_ci, (src_off + len),
+                                    &src_got, dst_ci,
+                                    (dst_off + len), &dst_got);
+               if (err < 0)
+                       goto out;
+               err = is_file_size_ok(src_inode, dst_inode,
+                                     src_off, dst_off, len);
+               if (err < 0)
+                       goto out_caps;
+       }
+       object_size = src_ci->i_layout.object_size;
+       while (len >= object_size) {
+               ceph_calc_file_object_mapping(&src_ci->i_layout, src_off,
+                                             object_size, &src_objnum,
+                                             &src_objoff, &src_objlen);
+               ceph_calc_file_object_mapping(&dst_ci->i_layout, dst_off,
+                                             object_size, &dst_objnum,
+                                             &dst_objoff, &dst_objlen);
+               ceph_oid_init(&src_oid);
+               ceph_oid_printf(&src_oid, "%llx.%08llx",
+                               src_ci->i_vino.ino, src_objnum);
+               ceph_oid_init(&dst_oid);
+               ceph_oid_printf(&dst_oid, "%llx.%08llx",
+                               dst_ci->i_vino.ino, dst_objnum);
+               /* Do an object remote copy */
+               err = ceph_osdc_copy_from(
+                       &ceph_inode_to_client(src_inode)->client->osdc,
+                       src_ci->i_vino.snap, 0,
+                       &src_oid, &src_oloc,
+                       CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL |
+                       CEPH_OSD_OP_FLAG_FADVISE_NOCACHE,
+                       &dst_oid, &dst_oloc,
+                       CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL |
+                       CEPH_OSD_OP_FLAG_FADVISE_DONTNEED, 0);
+               if (err) {
+                       dout("ceph_osdc_copy_from returned %d\n", err);
+                       if (!ret)
+                               ret = err;
+                       goto out_caps;
+               }
+               len -= object_size;
+               src_off += object_size;
+               dst_off += object_size;
+               ret += object_size;
+       }
+
+       if (len)
+               /* We still need one final local copy */
+               do_final_copy = true;
+
+       file_update_time(dst_file);
+       if (endoff > size) {
+               int caps_flags = 0;
+
+               /* Let the MDS know about dst file size change */
+               if (ceph_quota_is_max_bytes_approaching(dst_inode, endoff))
+                       caps_flags |= CHECK_CAPS_NODELAY;
+               if (ceph_inode_set_size(dst_inode, endoff))
+                       caps_flags |= CHECK_CAPS_AUTHONLY;
+               if (caps_flags)
+                       ceph_check_caps(dst_ci, caps_flags, NULL);
+       }
+       /* Mark Fw dirty */
+       spin_lock(&dst_ci->i_ceph_lock);
+       dst_ci->i_inline_version = CEPH_INLINE_NONE;
+       dirty = __ceph_mark_dirty_caps(dst_ci, CEPH_CAP_FILE_WR, &prealloc_cf);
+       spin_unlock(&dst_ci->i_ceph_lock);
+       if (dirty)
+               __mark_inode_dirty(dst_inode, dirty);
+
+out_caps:
+       put_rd_wr_caps(src_ci, src_got, dst_ci, dst_got);
+
+       if (do_final_copy) {
+               err = do_splice_direct(src_file, &src_off, dst_file,
+                                      &dst_off, len, flags);
+               if (err < 0) {
+                       dout("do_splice_direct returned %d\n", err);
+                       goto out;
+               }
+               len -= err;
+               ret += err;
+       }
+
+out:
+       ceph_free_cap_flush(prealloc_cf);
+
+       return ret;
+}
+
 const struct file_operations ceph_file_fops = {
        .open = ceph_open,
        .release = ceph_release,
@@ -1844,5 +2105,5 @@ const struct file_operations ceph_file_fops = {
        .unlocked_ioctl = ceph_ioctl,
        .compat_ioctl   = ceph_ioctl,
        .fallocate      = ceph_fallocate,
+       .copy_file_range = ceph_copy_file_range,
 };
-
index ebc7bdaed2d0d3674013b4800bf4e0265eada596..79dd5e6ed7559568b666784cae7b728dee72ba1a 100644 (file)
@@ -1132,8 +1132,12 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in)
        if (IS_ERR(realdn)) {
                pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n",
                       PTR_ERR(realdn), dn, in, ceph_vinop(in));
-               dput(dn);
-               dn = realdn; /* note realdn contains the error */
+               dn = realdn;
+               /*
+                * Caller should release 'dn' in the case of error.
+                * If 'req->r_dentry' is passed to this function,
+                * caller should leave 'req->r_dentry' untouched.
+                */
                goto out;
        } else if (realdn) {
                dout("dn %p (%d) spliced with %p (%d) "
@@ -1196,7 +1200,9 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
                        WARN_ON_ONCE(1);
                }
 
-               if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME) {
+               if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME &&
+                   test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) &&
+                   !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) {
                        struct qstr dname;
                        struct dentry *dn, *parent;
 
@@ -1677,7 +1683,6 @@ retry_lookup:
                        if (IS_ERR(realdn)) {
                                err = PTR_ERR(realdn);
                                d_drop(dn);
-                               dn = NULL;
                                goto next_item;
                        }
                        dn = realdn;
index bc43c822426a27673eb19754dabc282d182bfc12..67a9aeb2f4ecdc66ea3cfd6131bf0e4082cb0691 100644 (file)
@@ -2071,7 +2071,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        if (req->r_old_dentry_drop)
                len += req->r_old_dentry->d_name.len;
 
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, GFP_NOFS, false);
+       msg = ceph_msg_new2(CEPH_MSG_CLIENT_REQUEST, len, 1, GFP_NOFS, false);
        if (!msg) {
                msg = ERR_PTR(-ENOMEM);
                goto out_free2;
@@ -2136,7 +2136,6 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
        if (req->r_pagelist) {
                struct ceph_pagelist *pagelist = req->r_pagelist;
-               refcount_inc(&pagelist->refcnt);
                ceph_msg_data_add_pagelist(msg, pagelist);
                msg->hdr.data_len = cpu_to_le32(pagelist->length);
        } else {
@@ -3126,12 +3125,11 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
 
        pr_info("mds%d reconnect start\n", mds);
 
-       pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+       pagelist = ceph_pagelist_alloc(GFP_NOFS);
        if (!pagelist)
                goto fail_nopagelist;
-       ceph_pagelist_init(pagelist);
 
-       reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, GFP_NOFS, false);
+       reply = ceph_msg_new2(CEPH_MSG_CLIENT_RECONNECT, 0, 1, GFP_NOFS, false);
        if (!reply)
                goto fail_nomsg;
 
@@ -3241,6 +3239,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
        mutex_unlock(&mdsc->mutex);
 
        up_read(&mdsc->snap_rwsem);
+       ceph_pagelist_release(pagelist);
        return;
 
 fail:
index eab1359d05532afb6960c7acfb5c4fee2891eac9..b5ecd6f50360d53e0fe24c4ea79416722e93fc6c 100644 (file)
@@ -165,6 +165,8 @@ enum {
        Opt_noacl,
        Opt_quotadf,
        Opt_noquotadf,
+       Opt_copyfrom,
+       Opt_nocopyfrom,
 };
 
 static match_table_t fsopt_tokens = {
@@ -203,6 +205,8 @@ static match_table_t fsopt_tokens = {
        {Opt_noacl, "noacl"},
        {Opt_quotadf, "quotadf"},
        {Opt_noquotadf, "noquotadf"},
+       {Opt_copyfrom, "copyfrom"},
+       {Opt_nocopyfrom, "nocopyfrom"},
        {-1, NULL}
 };
 
@@ -355,6 +359,12 @@ static int parse_fsopt_token(char *c, void *private)
        case Opt_noquotadf:
                fsopt->flags |= CEPH_MOUNT_OPT_NOQUOTADF;
                break;
+       case Opt_copyfrom:
+               fsopt->flags &= ~CEPH_MOUNT_OPT_NOCOPYFROM;
+               break;
+       case Opt_nocopyfrom:
+               fsopt->flags |= CEPH_MOUNT_OPT_NOCOPYFROM;
+               break;
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
        case Opt_acl:
                fsopt->sb_flags |= SB_POSIXACL;
@@ -553,6 +563,9 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",noacl");
 #endif
 
+       if (fsopt->flags & CEPH_MOUNT_OPT_NOCOPYFROM)
+               seq_puts(m, ",nocopyfrom");
+
        if (fsopt->mds_namespace)
                seq_show_option(m, "mds_namespace", fsopt->mds_namespace);
        if (fsopt->wsize != CEPH_MAX_WRITE_SIZE)
index 582e28fd1b7bf1c6bda93b4796eb92cc4883fdd2..c005a5400f2ed9b1e0e932ea680c2f0824020277 100644 (file)
@@ -40,6 +40,7 @@
 #define CEPH_MOUNT_OPT_NOPOOLPERM      (1<<11) /* no pool permission check */
 #define CEPH_MOUNT_OPT_MOUNTWAIT       (1<<12) /* mount waits if no mds is up */
 #define CEPH_MOUNT_OPT_NOQUOTADF       (1<<13) /* no root dir quota in statfs */
+#define CEPH_MOUNT_OPT_NOCOPYFROM      (1<<14) /* don't use RADOS 'copy-from' op */
 
 #define CEPH_MOUNT_OPT_DEFAULT    CEPH_MOUNT_OPT_DCACHE
 
@@ -1008,7 +1009,7 @@ extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
 extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
                         loff_t endoff, int *got, struct page **pinned_page);
 extern int ceph_try_get_caps(struct ceph_inode_info *ci,
-                            int need, int want, int *got);
+                            int need, int want, bool nonblock, int *got);
 
 /* for counting open files by mode */
 extern void __ceph_get_fmode(struct ceph_inode_info *ci, int mode);
index 5cc8b94f8206972ce6ce988b92b5103504b335b1..316f6ad10644cdce8fd5cd7fbe526b3293a0866e 100644 (file)
@@ -951,11 +951,10 @@ static int ceph_sync_setxattr(struct inode *inode, const char *name,
 
        if (size > 0) {
                /* copy value into pagelist */
-               pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+               pagelist = ceph_pagelist_alloc(GFP_NOFS);
                if (!pagelist)
                        return -ENOMEM;
 
-               ceph_pagelist_init(pagelist);
                err = ceph_pagelist_append(pagelist, value, size);
                if (err)
                        goto out;
index ce2cc2169040e6de377ed56a54d75d52b74f2a72..6e30949d9f7794a584c1503fe8dbf7a51d0e83b7 100644 (file)
 
 #include <linux/hiddev.h>
 
-#define __DVB_CORE__
-#include <linux/dvb/audio.h>
-#include <linux/dvb/dmx.h>
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/video.h>
 
 #include <linux/sort.h>
 
@@ -95,71 +90,6 @@ static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        return vfs_ioctl(file, cmd, arg);
 }
 
-struct compat_video_event {
-       int32_t         type;
-       compat_time_t   timestamp;
-       union {
-               video_size_t size;
-               unsigned int frame_rate;
-       } u;
-};
-
-static int do_video_get_event(struct file *file,
-               unsigned int cmd, struct compat_video_event __user *up)
-{
-       struct video_event __user *kevent =
-               compat_alloc_user_space(sizeof(*kevent));
-       int err;
-
-       if (kevent == NULL)
-               return -EFAULT;
-
-       err = do_ioctl(file, cmd, (unsigned long)kevent);
-       if (!err) {
-               err  = convert_in_user(&kevent->type, &up->type);
-               err |= convert_in_user(&kevent->timestamp, &up->timestamp);
-               err |= convert_in_user(&kevent->u.size.w, &up->u.size.w);
-               err |= convert_in_user(&kevent->u.size.h, &up->u.size.h);
-               err |= convert_in_user(&kevent->u.size.aspect_ratio,
-                               &up->u.size.aspect_ratio);
-               if (err)
-                       err = -EFAULT;
-       }
-
-       return err;
-}
-
-struct compat_video_still_picture {
-        compat_uptr_t iFrame;
-        int32_t size;
-};
-
-static int do_video_stillpicture(struct file *file,
-               unsigned int cmd, struct compat_video_still_picture __user *up)
-{
-       struct video_still_picture __user *up_native;
-       compat_uptr_t fp;
-       int32_t size;
-       int err;
-
-       err  = get_user(fp, &up->iFrame);
-       err |= get_user(size, &up->size);
-       if (err)
-               return -EFAULT;
-
-       up_native =
-               compat_alloc_user_space(sizeof(struct video_still_picture));
-
-       err =  put_user(compat_ptr(fp), &up_native->iFrame);
-       err |= put_user(size, &up_native->size);
-       if (err)
-               return -EFAULT;
-
-       err = do_ioctl(file, cmd, (unsigned long) up_native);
-
-       return err;
-}
-
 #ifdef CONFIG_BLOCK
 typedef struct sg_io_hdr32 {
        compat_int_t interface_id;      /* [i] 'S' for SCSI generic (required) */
@@ -958,61 +888,6 @@ COMPATIBLE_IOCTL(HIDIOCGFLAG)
 COMPATIBLE_IOCTL(HIDIOCSFLAG)
 COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
 COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
-/* dvb */
-COMPATIBLE_IOCTL(AUDIO_STOP)
-COMPATIBLE_IOCTL(AUDIO_PLAY)
-COMPATIBLE_IOCTL(AUDIO_PAUSE)
-COMPATIBLE_IOCTL(AUDIO_CONTINUE)
-COMPATIBLE_IOCTL(AUDIO_SELECT_SOURCE)
-COMPATIBLE_IOCTL(AUDIO_SET_MUTE)
-COMPATIBLE_IOCTL(AUDIO_SET_AV_SYNC)
-COMPATIBLE_IOCTL(AUDIO_SET_BYPASS_MODE)
-COMPATIBLE_IOCTL(AUDIO_CHANNEL_SELECT)
-COMPATIBLE_IOCTL(AUDIO_GET_STATUS)
-COMPATIBLE_IOCTL(AUDIO_GET_CAPABILITIES)
-COMPATIBLE_IOCTL(AUDIO_CLEAR_BUFFER)
-COMPATIBLE_IOCTL(AUDIO_SET_ID)
-COMPATIBLE_IOCTL(AUDIO_SET_MIXER)
-COMPATIBLE_IOCTL(AUDIO_SET_STREAMTYPE)
-COMPATIBLE_IOCTL(DMX_START)
-COMPATIBLE_IOCTL(DMX_STOP)
-COMPATIBLE_IOCTL(DMX_SET_FILTER)
-COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
-COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
-COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
-COMPATIBLE_IOCTL(DMX_GET_STC)
-COMPATIBLE_IOCTL(DMX_REQBUFS)
-COMPATIBLE_IOCTL(DMX_QUERYBUF)
-COMPATIBLE_IOCTL(DMX_EXPBUF)
-COMPATIBLE_IOCTL(DMX_QBUF)
-COMPATIBLE_IOCTL(DMX_DQBUF)
-COMPATIBLE_IOCTL(VIDEO_STOP)
-COMPATIBLE_IOCTL(VIDEO_PLAY)
-COMPATIBLE_IOCTL(VIDEO_FREEZE)
-COMPATIBLE_IOCTL(VIDEO_CONTINUE)
-COMPATIBLE_IOCTL(VIDEO_SELECT_SOURCE)
-COMPATIBLE_IOCTL(VIDEO_SET_BLANK)
-COMPATIBLE_IOCTL(VIDEO_GET_STATUS)
-COMPATIBLE_IOCTL(VIDEO_SET_DISPLAY_FORMAT)
-COMPATIBLE_IOCTL(VIDEO_FAST_FORWARD)
-COMPATIBLE_IOCTL(VIDEO_SLOWMOTION)
-COMPATIBLE_IOCTL(VIDEO_GET_CAPABILITIES)
-COMPATIBLE_IOCTL(VIDEO_CLEAR_BUFFER)
-COMPATIBLE_IOCTL(VIDEO_SET_STREAMTYPE)
-COMPATIBLE_IOCTL(VIDEO_SET_FORMAT)
-COMPATIBLE_IOCTL(VIDEO_GET_SIZE)
-/* cec */
-COMPATIBLE_IOCTL(CEC_ADAP_G_CAPS)
-COMPATIBLE_IOCTL(CEC_ADAP_G_LOG_ADDRS)
-COMPATIBLE_IOCTL(CEC_ADAP_S_LOG_ADDRS)
-COMPATIBLE_IOCTL(CEC_ADAP_G_PHYS_ADDR)
-COMPATIBLE_IOCTL(CEC_ADAP_S_PHYS_ADDR)
-COMPATIBLE_IOCTL(CEC_G_MODE)
-COMPATIBLE_IOCTL(CEC_S_MODE)
-COMPATIBLE_IOCTL(CEC_TRANSMIT)
-COMPATIBLE_IOCTL(CEC_RECEIVE)
-COMPATIBLE_IOCTL(CEC_DQEVENT)
-
 /* joystick */
 COMPATIBLE_IOCTL(JSIOCGVERSION)
 COMPATIBLE_IOCTL(JSIOCGAXES)
@@ -1080,12 +955,6 @@ static long do_ioctl_trans(unsigned int cmd,
        case RTC_EPOCH_READ32:
        case RTC_EPOCH_SET32:
                return rtc_ioctl(file, cmd, argp);
-
-       /* dvb */
-       case VIDEO_GET_EVENT:
-               return do_video_get_event(file, cmd, argp);
-       case VIDEO_STILLPICTURE:
-               return do_video_stillpicture(file, cmd, argp);
        }
 
        /*
index 0c35e62f108d16bcf7920173e58156f0a71e9c98..9352487bd0fc660f99f67407e323724cf2ff4b76 100644 (file)
@@ -202,7 +202,8 @@ static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset,
                        continue;
                blk_offset = (blocknr - buffer_blocknr[i]) << PAGE_SHIFT;
                blk_offset += offset;
-               if (blk_offset + len > BUFFER_SIZE)
+               if (blk_offset > BUFFER_SIZE ||
+                   blk_offset + len > BUFFER_SIZE)
                        continue;
                return read_buffers[i] + blk_offset;
        }
@@ -872,8 +873,8 @@ static int cramfs_readpage(struct file *file, struct page *page)
                        if (unlikely(block_start & CRAMFS_BLK_FLAG_DIRECT_PTR)) {
                                /* See comments on earlier code. */
                                u32 prev_start = block_start;
-                              block_start = prev_start & ~CRAMFS_BLK_FLAGS;
-                              block_start <<= CRAMFS_BLK_DIRECT_PTR_SHIFT;
+                               block_start = prev_start & ~CRAMFS_BLK_FLAGS;
+                               block_start <<= CRAMFS_BLK_DIRECT_PTR_SHIFT;
                                if (prev_start & CRAMFS_BLK_FLAG_UNCOMPRESSED) {
                                        block_start += PAGE_SIZE;
                                } else {
index c2e443fb76ae85bd22973a888c785e524de1f41a..2593153471cf71bb232bc42e73baea2c0bc5615c 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/export.h>
 #include <linux/security.h>
 #include <linux/seqlock.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/bit_spinlock.h>
 #include <linux/rculist_bl.h>
 #include <linux/list_lru.h>
index 224c04abb2e5ded3f5734cacd1c9f7a25f3562fc..cf4c77f8dd08dc8e88c90a2e255e887c4ebc2f5d 100644 (file)
@@ -256,11 +256,15 @@ ext2_init_acl(struct inode *inode, struct inode *dir)
        if (default_acl) {
                error = __ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
                posix_acl_release(default_acl);
+       } else {
+               inode->i_default_acl = NULL;
        }
        if (acl) {
                if (!error)
                        error = __ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
                posix_acl_release(acl);
+       } else {
+               inode->i_acl = NULL;
        }
        return error;
 }
index 00e759f051619cfd37a58108265bc9f798554a21..e770cd100a6ab2f3ac6ac66e28641167b024117b 100644 (file)
@@ -390,11 +390,7 @@ struct ext2_inode {
 #define EXT2_MOUNT_USRQUOTA            0x020000  /* user quota */
 #define EXT2_MOUNT_GRPQUOTA            0x040000  /* group quota */
 #define EXT2_MOUNT_RESERVATION         0x080000  /* Preallocation */
-#ifdef CONFIG_FS_DAX
 #define EXT2_MOUNT_DAX                 0x100000  /* Direct Access */
-#else
-#define EXT2_MOUNT_DAX                 0
-#endif
 
 
 #define clear_opt(o, opt)              o &= ~EXT2_MOUNT_##opt
index 73bd58fa13de40e8c010bfcd0fb96764ab792f79..cb91baa4275d8150664e05d8a1877ca87fca4ff9 100644 (file)
@@ -309,20 +309,17 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root)
        if (test_opt(sb, NOBH))
                seq_puts(seq, ",nobh");
 
-#if defined(CONFIG_QUOTA)
        if (sbi->s_mount_opt & EXT2_MOUNT_USRQUOTA)
                seq_puts(seq, ",usrquota");
 
        if (sbi->s_mount_opt & EXT2_MOUNT_GRPQUOTA)
                seq_puts(seq, ",grpquota");
-#endif
 
-#ifdef CONFIG_FS_DAX
        if (sbi->s_mount_opt & EXT2_MOUNT_XIP)
                seq_puts(seq, ",xip");
+
        if (sbi->s_mount_opt & EXT2_MOUNT_DAX)
                seq_puts(seq, ",dax");
-#endif
 
        if (!test_opt(sb, RESERVATION))
                seq_puts(seq, ",noreservation");
index 7f5f3699fc6c086cb169c0f0dd9782971408480f..c8366cb8eccd7c4d3131139b52f90c0e4a3979b1 100644 (file)
@@ -369,7 +369,9 @@ static int fat_parse_short(struct super_block *sb,
        }
 
        memcpy(work, de->name, sizeof(work));
-       /* see namei.c, msdos_format_name */
+       /* For an explanation of the special treatment of 0x05 in
+        * filenames, see msdos_format_name in namei_msdos.c
+        */
        if (work[0] == 0x05)
                work[0] = 0xE5;
 
@@ -1071,7 +1073,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo)
                }
        }
 
-       dir->i_mtime = dir->i_atime = current_time(dir);
+       fat_truncate_time(dir, NULL, S_ATIME|S_MTIME);
        if (IS_DIRSYNC(dir))
                (void)fat_sync_inode(dir);
        else
index 9d7d2d5da28bf9e6cfb614a267274612e8579247..4e1b2f6df5e6a63f7db7f5b92d96c443de915171 100644 (file)
@@ -416,6 +416,10 @@ extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
                              __le16 __time, __le16 __date, u8 time_cs);
 extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
                              __le16 *time, __le16 *date, u8 *time_cs);
+extern int fat_truncate_time(struct inode *inode, struct timespec64 *now,
+                            int flags);
+extern int fat_update_time(struct inode *inode, struct timespec64 *now,
+                          int flags);
 extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
 
 int fat_cache_init(void);
index 4f3d72fb1e60d64a71f92e632da19ac4ac132ebc..13935ee99e1e53038f458e257d48f11cc7426591 100644 (file)
@@ -227,7 +227,7 @@ static int fat_cont_expand(struct inode *inode, loff_t size)
        if (err)
                goto out;
 
-       inode->i_ctime = inode->i_mtime = current_time(inode);
+       fat_truncate_time(inode, NULL, S_CTIME|S_MTIME);
        mark_inode_dirty(inode);
        if (IS_SYNC(inode)) {
                int err2;
@@ -330,7 +330,7 @@ static int fat_free(struct inode *inode, int skip)
                MSDOS_I(inode)->i_logstart = 0;
        }
        MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
-       inode->i_ctime = inode->i_mtime = current_time(inode);
+       fat_truncate_time(inode, NULL, S_CTIME|S_MTIME);
        if (wait) {
                err = fat_sync_inode(inode);
                if (err) {
@@ -542,6 +542,18 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
                up_write(&MSDOS_I(inode)->truncate_lock);
        }
 
+       /*
+        * setattr_copy can't truncate these appropriately, so we'll
+        * copy them ourselves
+        */
+       if (attr->ia_valid & ATTR_ATIME)
+               fat_truncate_time(inode, &attr->ia_atime, S_ATIME);
+       if (attr->ia_valid & ATTR_CTIME)
+               fat_truncate_time(inode, &attr->ia_ctime, S_CTIME);
+       if (attr->ia_valid & ATTR_MTIME)
+               fat_truncate_time(inode, &attr->ia_mtime, S_MTIME);
+       attr->ia_valid &= ~(ATTR_ATIME|ATTR_CTIME|ATTR_MTIME);
+
        setattr_copy(inode, attr);
        mark_inode_dirty(inode);
 out:
@@ -552,4 +564,5 @@ EXPORT_SYMBOL_GPL(fat_setattr);
 const struct inode_operations fat_file_inode_operations = {
        .setattr        = fat_setattr,
        .getattr        = fat_getattr,
+       .update_time    = fat_update_time,
 };
index d6b81e31f9f5d827be92ffad4cf240fa32e5f767..c0b5b5c3373bd967f86697f9aa39b75942399877 100644 (file)
@@ -244,7 +244,7 @@ static int fat_write_end(struct file *file, struct address_space *mapping,
        if (err < len)
                fat_write_failed(mapping, pos + len);
        if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
-               inode->i_mtime = inode->i_ctime = current_time(inode);
+               fat_truncate_time(inode, NULL, S_CTIME|S_MTIME);
                MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
                mark_inode_dirty(inode);
        }
@@ -564,7 +564,7 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
                                  de->cdate, de->ctime_cs);
                fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
        } else
-               inode->i_ctime = inode->i_atime = inode->i_mtime;
+               fat_truncate_time(inode, &inode->i_mtime, S_ATIME|S_CTIME);
 
        return 0;
 }
@@ -1626,6 +1626,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
        sb->s_magic = MSDOS_SUPER_MAGIC;
        sb->s_op = &fat_sops;
        sb->s_export_op = &fat_export_ops;
+       /*
+        * fat timestamps are complex and truncated by fat itself, so
+        * we set 1 here to be fast
+        */
+       sb->s_time_gran = 1;
        mutex_init(&sbi->nfs_build_inode_lock);
        ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL,
                             DEFAULT_RATELIMIT_BURST);
index 573836dcaefc4c1d2720ee213e5b90098a4acb87..fce0a76f3f1e4c2617934a93c027d0af0d074b45 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include "fat.h"
+#include <linux/iversion.h>
 
 /*
  * fat_fs_error reports a file system problem that might indicate fa data
@@ -185,6 +186,13 @@ static long days_in_year[] = {
        0,   0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
 };
 
+static inline int fat_tz_offset(struct msdos_sb_info *sbi)
+{
+       return (sbi->options.tz_set ?
+              -sbi->options.time_offset :
+              sys_tz.tz_minuteswest) * SECS_PER_MIN;
+}
+
 /* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
 void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
                       __le16 __time, __le16 __date, u8 time_cs)
@@ -210,10 +218,7 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
                   + days_in_year[month] + day
                   + DAYS_DELTA) * SECS_PER_DAY;
 
-       if (!sbi->options.tz_set)
-               second += sys_tz.tz_minuteswest * SECS_PER_MIN;
-       else
-               second -= sbi->options.time_offset * SECS_PER_MIN;
+       second += fat_tz_offset(sbi);
 
        if (time_cs) {
                ts->tv_sec = second + (time_cs / 100);
@@ -229,9 +234,7 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
                       __le16 *time, __le16 *date, u8 *time_cs)
 {
        struct tm tm;
-       time64_to_tm(ts->tv_sec,
-                  (sbi->options.tz_set ? sbi->options.time_offset :
-                  -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm);
+       time64_to_tm(ts->tv_sec, -fat_tz_offset(sbi), &tm);
 
        /*  FAT can only support year between 1980 to 2107 */
        if (tm.tm_year < 1980 - 1900) {
@@ -263,6 +266,80 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
 }
 EXPORT_SYMBOL_GPL(fat_time_unix2fat);
 
+static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
+{
+       return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
+}
+/*
+ * truncate the various times with appropriate granularity:
+ *   root inode:
+ *     all times always 0
+ *   all other inodes:
+ *     mtime - 2 seconds
+ *     ctime
+ *       msdos - 2 seconds
+ *       vfat  - 10 milliseconds
+ *     atime - 24 hours (00:00:00 in local timezone)
+ */
+int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
+{
+       struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+       struct timespec64 ts;
+
+       if (inode->i_ino == MSDOS_ROOT_INO)
+               return 0;
+
+       if (now == NULL) {
+               now = &ts;
+               ts = current_time(inode);
+       }
+
+       if (flags & S_ATIME) {
+               /* to localtime */
+               time64_t seconds = now->tv_sec - fat_tz_offset(sbi);
+               s32 remainder;
+
+               div_s64_rem(seconds, SECS_PER_DAY, &remainder);
+               /* to day boundary, and back to unix time */
+               seconds = seconds + fat_tz_offset(sbi) - remainder;
+
+               inode->i_atime = (struct timespec64){ seconds, 0 };
+       }
+       if (flags & S_CTIME) {
+               if (sbi->options.isvfat)
+                       inode->i_ctime = timespec64_trunc(*now, 10000000);
+               else
+                       inode->i_ctime = fat_timespec64_trunc_2secs(*now);
+       }
+       if (flags & S_MTIME)
+               inode->i_mtime = fat_timespec64_trunc_2secs(*now);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(fat_truncate_time);
+
+int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
+{
+       int iflags = I_DIRTY_TIME;
+       bool dirty = false;
+
+       if (inode->i_ino == MSDOS_ROOT_INO)
+               return 0;
+
+       fat_truncate_time(inode, now, flags);
+       if (flags & S_VERSION)
+               dirty = inode_maybe_inc_iversion(inode, false);
+       if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
+           !(inode->i_sb->s_flags & SB_LAZYTIME))
+               dirty = true;
+
+       if (dirty)
+               iflags |= I_DIRTY_SYNC;
+       __mark_inode_dirty(inode, iflags);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(fat_update_time);
+
 int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
 {
        int i, err = 0;
index efb8c40c9d27467d0d58d10dd5b1ba313c06d9d6..f2cd365a4e86ec01bf02a2d5afdd5f00c07dab66 100644 (file)
@@ -250,7 +250,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
        if (err)
                return err;
 
-       dir->i_ctime = dir->i_mtime = *ts;
+       fat_truncate_time(dir, ts, S_CTIME|S_MTIME);
        if (IS_DIRSYNC(dir))
                (void)fat_sync_inode(dir);
        else
@@ -294,7 +294,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
                err = PTR_ERR(inode);
                goto out;
        }
-       inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+       fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        d_instantiate(dentry, inode);
@@ -327,7 +327,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
        drop_nlink(dir);
 
        clear_nlink(inode);
-       inode->i_ctime = current_time(inode);
+       fat_truncate_time(inode, NULL, S_CTIME);
        fat_detach(inode);
 out:
        mutex_unlock(&MSDOS_SB(sb)->s_lock);
@@ -380,7 +380,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
                goto out;
        }
        set_nlink(inode, 2);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+       fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        d_instantiate(dentry, inode);
@@ -413,7 +413,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
        if (err)
                goto out;
        clear_nlink(inode);
-       inode->i_ctime = current_time(inode);
+       fat_truncate_time(inode, NULL, S_CTIME);
        fat_detach(inode);
 out:
        mutex_unlock(&MSDOS_SB(sb)->s_lock);
@@ -478,7 +478,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
                                mark_inode_dirty(old_inode);
 
                        inode_inc_iversion(old_dir);
-                       old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
+                       fat_truncate_time(old_dir, NULL, S_CTIME|S_MTIME);
                        if (IS_DIRSYNC(old_dir))
                                (void)fat_sync_inode(old_dir);
                        else
@@ -538,7 +538,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
        if (err)
                goto error_dotdot;
        inode_inc_iversion(old_dir);
-       old_dir->i_ctime = old_dir->i_mtime = ts;
+       fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME);
        if (IS_DIRSYNC(old_dir))
                (void)fat_sync_inode(old_dir);
        else
@@ -548,7 +548,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
                drop_nlink(new_inode);
                if (is_dir)
                        drop_nlink(new_inode);
-               new_inode->i_ctime = ts;
+               fat_truncate_time(new_inode, &ts, S_CTIME);
        }
 out:
        brelse(sinfo.bh);
@@ -637,6 +637,7 @@ static const struct inode_operations msdos_dir_inode_operations = {
        .rename         = msdos_rename,
        .setattr        = fat_setattr,
        .getattr        = fat_getattr,
+       .update_time    = fat_update_time,
 };
 
 static void setup(struct super_block *sb)
index 82cd1e69cbdf283322e8d7fa8566a22cca54fc0a..996c8c25e9c63b30ced0ecaaf325b519d7841551 100644 (file)
@@ -678,7 +678,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
                goto cleanup;
 
        /* update timestamp */
-       dir->i_ctime = dir->i_mtime = dir->i_atime = *ts;
+       fat_truncate_time(dir, ts, S_CTIME|S_MTIME);
        if (IS_DIRSYNC(dir))
                (void)fat_sync_inode(dir);
        else
@@ -779,7 +779,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
                goto out;
        }
        inode_inc_iversion(inode);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+       fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        d_instantiate(dentry, inode);
@@ -810,7 +810,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
        drop_nlink(dir);
 
        clear_nlink(inode);
-       inode->i_mtime = inode->i_atime = current_time(inode);
+       fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
        fat_detach(inode);
        vfat_d_version_set(dentry, inode_query_iversion(dir));
 out:
@@ -836,7 +836,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
        if (err)
                goto out;
        clear_nlink(inode);
-       inode->i_mtime = inode->i_atime = current_time(inode);
+       fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
        fat_detach(inode);
        vfat_d_version_set(dentry, inode_query_iversion(dir));
 out:
@@ -876,7 +876,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        }
        inode_inc_iversion(inode);
        set_nlink(inode, 2);
-       inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
+       fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        d_instantiate(dentry, inode);
@@ -969,7 +969,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (err)
                goto error_dotdot;
        inode_inc_iversion(old_dir);
-       old_dir->i_ctime = old_dir->i_mtime = ts;
+       fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME);
        if (IS_DIRSYNC(old_dir))
                (void)fat_sync_inode(old_dir);
        else
@@ -979,7 +979,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
                drop_nlink(new_inode);
                if (is_dir)
                        drop_nlink(new_inode);
-               new_inode->i_ctime = ts;
+               fat_truncate_time(new_inode, &ts, S_CTIME);
        }
 out:
        brelse(sinfo.bh);
@@ -1032,6 +1032,7 @@ static const struct inode_operations vfat_dir_inode_operations = {
        .rename         = vfat_rename,
        .setattr        = fat_setattr,
        .getattr        = fat_getattr,
+       .update_time    = fat_update_time,
 };
 
 static void setup(struct super_block *sb)
index 60da84a86dabdb2e00d2725481631db385985054..f7b807bc1027a29cf14c698497574f62f4358c16 100644 (file)
@@ -5,4 +5,4 @@
 obj-$(CONFIG_FUSE_FS) += fuse.o
 obj-$(CONFIG_CUSE) += cuse.o
 
-fuse-objs := dev.o dir.o file.o inode.o control.o xattr.o acl.o
+fuse-objs := dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o
index 0b694655d988073d1bf33f5e2c2859260ac6be00..989df5accaee0679d2fd6641753564ca7ef663c9 100644 (file)
@@ -107,7 +107,7 @@ static ssize_t fuse_conn_max_background_read(struct file *file,
        if (!fc)
                return 0;
 
-       val = fc->max_background;
+       val = READ_ONCE(fc->max_background);
        fuse_conn_put(fc);
 
        return fuse_conn_limit_read(file, buf, len, ppos, val);
@@ -125,7 +125,12 @@ static ssize_t fuse_conn_max_background_write(struct file *file,
        if (ret > 0) {
                struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
                if (fc) {
+                       spin_lock(&fc->bg_lock);
                        fc->max_background = val;
+                       fc->blocked = fc->num_background >= fc->max_background;
+                       if (!fc->blocked)
+                               wake_up(&fc->blocked_waitq);
+                       spin_unlock(&fc->bg_lock);
                        fuse_conn_put(fc);
                }
        }
@@ -144,7 +149,7 @@ static ssize_t fuse_conn_congestion_threshold_read(struct file *file,
        if (!fc)
                return 0;
 
-       val = fc->congestion_threshold;
+       val = READ_ONCE(fc->congestion_threshold);
        fuse_conn_put(fc);
 
        return fuse_conn_limit_read(file, buf, len, ppos, val);
@@ -155,18 +160,31 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file,
                                                    size_t count, loff_t *ppos)
 {
        unsigned uninitialized_var(val);
+       struct fuse_conn *fc;
        ssize_t ret;
 
        ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
                                    max_user_congthresh);
-       if (ret > 0) {
-               struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
-               if (fc) {
-                       fc->congestion_threshold = val;
-                       fuse_conn_put(fc);
+       if (ret <= 0)
+               goto out;
+       fc = fuse_ctl_file_conn_get(file);
+       if (!fc)
+               goto out;
+
+       spin_lock(&fc->bg_lock);
+       fc->congestion_threshold = val;
+       if (fc->sb) {
+               if (fc->num_background < fc->congestion_threshold) {
+                       clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
+                       clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
+               } else {
+                       set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
+                       set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
                }
        }
-
+       spin_unlock(&fc->bg_lock);
+       fuse_conn_put(fc);
+out:
        return ret;
 }
 
index 11ea2c4a38abc16a50b78a0a9668706c7d967a62..ae813e609932168ec2e74056fb598aca0ad65907 100644 (file)
 MODULE_ALIAS_MISCDEV(FUSE_MINOR);
 MODULE_ALIAS("devname:fuse");
 
+/* Ordinary requests have even IDs, while interrupts IDs are odd */
+#define FUSE_INT_REQ_BIT (1ULL << 0)
+#define FUSE_REQ_ID_STEP (1ULL << 1)
+
 static struct kmem_cache *fuse_req_cachep;
 
 static struct fuse_dev *fuse_get_dev(struct file *file)
@@ -40,9 +44,6 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages,
                              struct fuse_page_desc *page_descs,
                              unsigned npages)
 {
-       memset(req, 0, sizeof(*req));
-       memset(pages, 0, sizeof(*pages) * npages);
-       memset(page_descs, 0, sizeof(*page_descs) * npages);
        INIT_LIST_HEAD(&req->list);
        INIT_LIST_HEAD(&req->intr_entry);
        init_waitqueue_head(&req->waitq);
@@ -53,30 +54,36 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages,
        __set_bit(FR_PENDING, &req->flags);
 }
 
+static struct page **fuse_req_pages_alloc(unsigned int npages, gfp_t flags,
+                                         struct fuse_page_desc **desc)
+{
+       struct page **pages;
+
+       pages = kzalloc(npages * (sizeof(struct page *) +
+                                 sizeof(struct fuse_page_desc)), flags);
+       *desc = (void *) pages + npages * sizeof(struct page *);
+
+       return pages;
+}
+
 static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
 {
-       struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags);
+       struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
        if (req) {
-               struct page **pages;
-               struct fuse_page_desc *page_descs;
-
-               if (npages <= FUSE_REQ_INLINE_PAGES) {
+               struct page **pages = NULL;
+               struct fuse_page_desc *page_descs = NULL;
+
+               WARN_ON(npages > FUSE_MAX_MAX_PAGES);
+               if (npages > FUSE_REQ_INLINE_PAGES) {
+                       pages = fuse_req_pages_alloc(npages, flags,
+                                                    &page_descs);
+                       if (!pages) {
+                               kmem_cache_free(fuse_req_cachep, req);
+                               return NULL;
+                       }
+               } else if (npages) {
                        pages = req->inline_pages;
                        page_descs = req->inline_page_descs;
-               } else {
-                       pages = kmalloc_array(npages, sizeof(struct page *),
-                                             flags);
-                       page_descs =
-                               kmalloc_array(npages,
-                                             sizeof(struct fuse_page_desc),
-                                             flags);
-               }
-
-               if (!pages || !page_descs) {
-                       kfree(pages);
-                       kfree(page_descs);
-                       kmem_cache_free(fuse_req_cachep, req);
-                       return NULL;
                }
 
                fuse_request_init(req, pages, page_descs, npages);
@@ -95,12 +102,41 @@ struct fuse_req *fuse_request_alloc_nofs(unsigned npages)
        return __fuse_request_alloc(npages, GFP_NOFS);
 }
 
-void fuse_request_free(struct fuse_req *req)
+static void fuse_req_pages_free(struct fuse_req *req)
 {
-       if (req->pages != req->inline_pages) {
+       if (req->pages != req->inline_pages)
                kfree(req->pages);
-               kfree(req->page_descs);
-       }
+}
+
+bool fuse_req_realloc_pages(struct fuse_conn *fc, struct fuse_req *req,
+                           gfp_t flags)
+{
+       struct page **pages;
+       struct fuse_page_desc *page_descs;
+       unsigned int npages = min_t(unsigned int,
+                                   max_t(unsigned int, req->max_pages * 2,
+                                         FUSE_DEFAULT_MAX_PAGES_PER_REQ),
+                                   fc->max_pages);
+       WARN_ON(npages <= req->max_pages);
+
+       pages = fuse_req_pages_alloc(npages, flags, &page_descs);
+       if (!pages)
+               return false;
+
+       memcpy(pages, req->pages, sizeof(struct page *) * req->max_pages);
+       memcpy(page_descs, req->page_descs,
+              sizeof(struct fuse_page_desc) * req->max_pages);
+       fuse_req_pages_free(req);
+       req->pages = pages;
+       req->page_descs = page_descs;
+       req->max_pages = npages;
+
+       return true;
+}
+
+void fuse_request_free(struct fuse_req *req)
+{
+       fuse_req_pages_free(req);
        kmem_cache_free(fuse_req_cachep, req);
 }
 
@@ -235,8 +271,10 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
        struct file *file = req->stolen_file;
        struct fuse_file *ff = file->private_data;
 
+       WARN_ON(req->max_pages);
        spin_lock(&fc->lock);
-       fuse_request_init(req, req->pages, req->page_descs, req->max_pages);
+       memset(req, 0, sizeof(*req));
+       fuse_request_init(req, NULL, NULL, 0);
        BUG_ON(ff->reserved_req);
        ff->reserved_req = req;
        wake_up_all(&fc->reserved_req_waitq);
@@ -287,10 +325,10 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
                         * We get here in the unlikely case that a background
                         * request was allocated but not sent
                         */
-                       spin_lock(&fc->lock);
+                       spin_lock(&fc->bg_lock);
                        if (!fc->blocked)
                                wake_up(&fc->blocked_waitq);
-                       spin_unlock(&fc->lock);
+                       spin_unlock(&fc->bg_lock);
                }
 
                if (test_bit(FR_WAITING, &req->flags)) {
@@ -319,7 +357,13 @@ static unsigned len_args(unsigned numargs, struct fuse_arg *args)
 
 static u64 fuse_get_unique(struct fuse_iqueue *fiq)
 {
-       return ++fiq->reqctr;
+       fiq->reqctr += FUSE_REQ_ID_STEP;
+       return fiq->reqctr;
+}
+
+static unsigned int fuse_req_hash(u64 unique)
+{
+       return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
 }
 
 static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req)
@@ -353,12 +397,13 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
 
 static void flush_bg_queue(struct fuse_conn *fc)
 {
+       struct fuse_iqueue *fiq = &fc->iq;
+
        while (fc->active_background < fc->max_background &&
               !list_empty(&fc->bg_queue)) {
                struct fuse_req *req;
-               struct fuse_iqueue *fiq = &fc->iq;
 
-               req = list_entry(fc->bg_queue.next, struct fuse_req, list);
+               req = list_first_entry(&fc->bg_queue, struct fuse_req, list);
                list_del(&req->list);
                fc->active_background++;
                spin_lock(&fiq->waitq.lock);
@@ -389,14 +434,21 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
        WARN_ON(test_bit(FR_PENDING, &req->flags));
        WARN_ON(test_bit(FR_SENT, &req->flags));
        if (test_bit(FR_BACKGROUND, &req->flags)) {
-               spin_lock(&fc->lock);
+               spin_lock(&fc->bg_lock);
                clear_bit(FR_BACKGROUND, &req->flags);
-               if (fc->num_background == fc->max_background)
+               if (fc->num_background == fc->max_background) {
                        fc->blocked = 0;
-
-               /* Wake up next waiter, if any */
-               if (!fc->blocked && waitqueue_active(&fc->blocked_waitq))
                        wake_up(&fc->blocked_waitq);
+               } else if (!fc->blocked) {
+                       /*
+                        * Wake up next waiter, if any.  It's okay to use
+                        * waitqueue_active(), as we've already synced up
+                        * fc->blocked with waiters with the wake_up() call
+                        * above.
+                        */
+                       if (waitqueue_active(&fc->blocked_waitq))
+                               wake_up(&fc->blocked_waitq);
+               }
 
                if (fc->num_background == fc->congestion_threshold && fc->sb) {
                        clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
@@ -405,7 +457,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
                fc->num_background--;
                fc->active_background--;
                flush_bg_queue(fc);
-               spin_unlock(&fc->lock);
+               spin_unlock(&fc->bg_lock);
        }
        wake_up(&req->waitq);
        if (req->end)
@@ -573,40 +625,38 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
        return ret;
 }
 
-/*
- * Called under fc->lock
- *
- * fc->connected must have been checked previously
- */
-void fuse_request_send_background_locked(struct fuse_conn *fc,
-                                        struct fuse_req *req)
+bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req)
 {
-       BUG_ON(!test_bit(FR_BACKGROUND, &req->flags));
+       bool queued = false;
+
+       WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
        if (!test_bit(FR_WAITING, &req->flags)) {
                __set_bit(FR_WAITING, &req->flags);
                atomic_inc(&fc->num_waiting);
        }
        __set_bit(FR_ISREPLY, &req->flags);
-       fc->num_background++;
-       if (fc->num_background == fc->max_background)
-               fc->blocked = 1;
-       if (fc->num_background == fc->congestion_threshold && fc->sb) {
-               set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
-               set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
+       spin_lock(&fc->bg_lock);
+       if (likely(fc->connected)) {
+               fc->num_background++;
+               if (fc->num_background == fc->max_background)
+                       fc->blocked = 1;
+               if (fc->num_background == fc->congestion_threshold && fc->sb) {
+                       set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
+                       set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
+               }
+               list_add_tail(&req->list, &fc->bg_queue);
+               flush_bg_queue(fc);
+               queued = true;
        }
-       list_add_tail(&req->list, &fc->bg_queue);
-       flush_bg_queue(fc);
+       spin_unlock(&fc->bg_lock);
+
+       return queued;
 }
 
 void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
 {
-       BUG_ON(!req->end);
-       spin_lock(&fc->lock);
-       if (fc->connected) {
-               fuse_request_send_background_locked(fc, req);
-               spin_unlock(&fc->lock);
-       } else {
-               spin_unlock(&fc->lock);
+       WARN_ON(!req->end);
+       if (!fuse_request_queue_background(fc, req)) {
                req->out.h.error = -ENOTCONN;
                req->end(fc, req);
                fuse_put_request(fc, req);
@@ -1084,12 +1134,11 @@ __releases(fiq->waitq.lock)
        int err;
 
        list_del_init(&req->intr_entry);
-       req->intr_unique = fuse_get_unique(fiq);
        memset(&ih, 0, sizeof(ih));
        memset(&arg, 0, sizeof(arg));
        ih.len = reqsize;
        ih.opcode = FUSE_INTERRUPT;
-       ih.unique = req->intr_unique;
+       ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
        arg.unique = req->in.h.unique;
 
        spin_unlock(&fiq->waitq.lock);
@@ -1238,6 +1287,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
        struct fuse_req *req;
        struct fuse_in *in;
        unsigned reqsize;
+       unsigned int hash;
 
  restart:
        spin_lock(&fiq->waitq.lock);
@@ -1310,13 +1360,16 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
                err = reqsize;
                goto out_end;
        }
-       list_move_tail(&req->list, &fpq->processing);
-       spin_unlock(&fpq->lock);
+       hash = fuse_req_hash(req->in.h.unique);
+       list_move_tail(&req->list, &fpq->processing[hash]);
+       __fuse_get_request(req);
        set_bit(FR_SENT, &req->flags);
+       spin_unlock(&fpq->lock);
        /* matches barrier in request_wait_answer() */
        smp_mb__after_atomic();
        if (test_bit(FR_INTERRUPTED, &req->flags))
                queue_interrupt(fiq, req);
+       fuse_put_request(fc, req);
 
        return reqsize;
 
@@ -1663,7 +1716,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
        unsigned int num;
        unsigned int offset;
        size_t total_len = 0;
-       int num_pages;
+       unsigned int num_pages;
 
        offset = outarg->offset & ~PAGE_MASK;
        file_size = i_size_read(inode);
@@ -1675,7 +1728,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
                num = file_size - outarg->offset;
 
        num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ);
+       num_pages = min(num_pages, fc->max_pages);
 
        req = fuse_get_req(fc, num_pages);
        if (IS_ERR(req))
@@ -1792,10 +1845,11 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
 /* Look up request on processing list by unique ID */
 static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
 {
+       unsigned int hash = fuse_req_hash(unique);
        struct fuse_req *req;
 
-       list_for_each_entry(req, &fpq->processing, list) {
-               if (req->in.h.unique == unique || req->intr_unique == unique)
+       list_for_each_entry(req, &fpq->processing[hash], list) {
+               if (req->in.h.unique == unique)
                        return req;
        }
        return NULL;
@@ -1869,22 +1923,26 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
        if (!fpq->connected)
                goto err_unlock_pq;
 
-       req = request_find(fpq, oh.unique);
+       req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
        if (!req)
                goto err_unlock_pq;
 
-       /* Is it an interrupt reply? */
-       if (req->intr_unique == oh.unique) {
+       /* Is it an interrupt reply ID? */
+       if (oh.unique & FUSE_INT_REQ_BIT) {
+               __fuse_get_request(req);
                spin_unlock(&fpq->lock);
 
                err = -EINVAL;
-               if (nbytes != sizeof(struct fuse_out_header))
+               if (nbytes != sizeof(struct fuse_out_header)) {
+                       fuse_put_request(fc, req);
                        goto err_finish;
+               }
 
                if (oh.error == -ENOSYS)
                        fc->no_interrupt = 1;
                else if (oh.error == -EAGAIN)
                        queue_interrupt(&fc->iq, req);
+               fuse_put_request(fc, req);
 
                fuse_copy_finish(cs);
                return nbytes;
@@ -2102,9 +2160,13 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
                struct fuse_dev *fud;
                struct fuse_req *req, *next;
                LIST_HEAD(to_end);
+               unsigned int i;
 
+               /* Background queuing checks fc->connected under bg_lock */
+               spin_lock(&fc->bg_lock);
                fc->connected = 0;
-               fc->blocked = 0;
+               spin_unlock(&fc->bg_lock);
+
                fc->aborted = is_abort;
                fuse_set_initialized(fc);
                list_for_each_entry(fud, &fc->devices, entry) {
@@ -2123,11 +2185,16 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
                                }
                                spin_unlock(&req->waitq.lock);
                        }
-                       list_splice_tail_init(&fpq->processing, &to_end);
+                       for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
+                               list_splice_tail_init(&fpq->processing[i],
+                                                     &to_end);
                        spin_unlock(&fpq->lock);
                }
+               spin_lock(&fc->bg_lock);
+               fc->blocked = 0;
                fc->max_background = UINT_MAX;
                flush_bg_queue(fc);
+               spin_unlock(&fc->bg_lock);
 
                spin_lock(&fiq->waitq.lock);
                fiq->connected = 0;
@@ -2163,10 +2230,12 @@ int fuse_dev_release(struct inode *inode, struct file *file)
                struct fuse_conn *fc = fud->fc;
                struct fuse_pqueue *fpq = &fud->pq;
                LIST_HEAD(to_end);
+               unsigned int i;
 
                spin_lock(&fpq->lock);
                WARN_ON(!list_empty(&fpq->io));
-               list_splice_init(&fpq->processing, &to_end);
+               for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
+                       list_splice_init(&fpq->processing[i], &to_end);
                spin_unlock(&fpq->lock);
 
                end_requests(fc, &to_end);
index 0979609d6eba8804aac53c5b11f32eeb94f91a75..47395b0c3b35e5fde0110eb142414010f06b126a 100644 (file)
 #include <linux/namei.h>
 #include <linux/slab.h>
 #include <linux/xattr.h>
+#include <linux/iversion.h>
 #include <linux/posix_acl.h>
 
-static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
-{
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_inode *fi = get_fuse_inode(dir);
-
-       if (!fc->do_readdirplus)
-               return false;
-       if (!fc->readdirplus_auto)
-               return true;
-       if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
-               return true;
-       if (ctx->pos == 0)
-               return true;
-       return false;
-}
-
 static void fuse_advise_use_readdirplus(struct inode *dir)
 {
        struct fuse_inode *fi = get_fuse_inode(dir);
@@ -80,8 +65,7 @@ static u64 time_to_jiffies(u64 sec, u32 nsec)
  * Set dentry and possibly attribute timeouts from the lookup/mk*
  * replies
  */
-static void fuse_change_entry_timeout(struct dentry *entry,
-                                     struct fuse_entry_out *o)
+void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
 {
        fuse_dentry_settime(entry,
                time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
@@ -92,18 +76,29 @@ static u64 attr_timeout(struct fuse_attr_out *o)
        return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
 }
 
-static u64 entry_attr_timeout(struct fuse_entry_out *o)
+u64 entry_attr_timeout(struct fuse_entry_out *o)
 {
        return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
 }
 
+static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
+{
+       set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
+}
+
 /*
  * Mark the attributes as stale, so that at the next call to
  * ->getattr() they will be fetched from userspace
  */
 void fuse_invalidate_attr(struct inode *inode)
 {
-       get_fuse_inode(inode)->i_time = 0;
+       fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
+}
+
+static void fuse_dir_changed(struct inode *dir)
+{
+       fuse_invalidate_attr(dir);
+       inode_maybe_inc_iversion(dir, false);
 }
 
 /**
@@ -113,7 +108,7 @@ void fuse_invalidate_attr(struct inode *inode)
 void fuse_invalidate_atime(struct inode *inode)
 {
        if (!IS_RDONLY(inode))
-               fuse_invalidate_attr(inode);
+               fuse_invalidate_attr_mask(inode, STATX_ATIME);
 }
 
 /*
@@ -262,11 +257,6 @@ invalid:
        goto out;
 }
 
-static int invalid_nodeid(u64 nodeid)
-{
-       return !nodeid || nodeid == FUSE_ROOT_ID;
-}
-
 static int fuse_dentry_init(struct dentry *dentry)
 {
        dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL);
@@ -469,7 +459,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        kfree(forget);
        d_instantiate(entry, inode);
        fuse_change_entry_timeout(entry, &outentry);
-       fuse_invalidate_attr(dir);
+       fuse_dir_changed(dir);
        err = finish_open(file, entry, generic_file_open);
        if (err) {
                fuse_sync_release(ff, flags);
@@ -583,7 +573,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
        } else {
                fuse_change_entry_timeout(entry, &outarg);
        }
-       fuse_invalidate_attr(dir);
+       fuse_dir_changed(dir);
        return 0;
 
  out_put_forget_req:
@@ -693,7 +683,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
                        drop_nlink(inode);
                spin_unlock(&fc->lock);
                fuse_invalidate_attr(inode);
-               fuse_invalidate_attr(dir);
+               fuse_dir_changed(dir);
                fuse_invalidate_entry_cache(entry);
                fuse_update_ctime(inode);
        } else if (err == -EINTR)
@@ -715,7 +705,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
        err = fuse_simple_request(fc, &args);
        if (!err) {
                clear_nlink(d_inode(entry));
-               fuse_invalidate_attr(dir);
+               fuse_dir_changed(dir);
                fuse_invalidate_entry_cache(entry);
        } else if (err == -EINTR)
                fuse_invalidate_entry(entry);
@@ -754,9 +744,9 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
                        fuse_update_ctime(d_inode(newent));
                }
 
-               fuse_invalidate_attr(olddir);
+               fuse_dir_changed(olddir);
                if (olddir != newdir)
-                       fuse_invalidate_attr(newdir);
+                       fuse_dir_changed(newdir);
 
                /* newent will end up negative */
                if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
@@ -932,7 +922,8 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
 }
 
 static int fuse_update_get_attr(struct inode *inode, struct file *file,
-                               struct kstat *stat, unsigned int flags)
+                               struct kstat *stat, u32 request_mask,
+                               unsigned int flags)
 {
        struct fuse_inode *fi = get_fuse_inode(inode);
        int err = 0;
@@ -942,6 +933,8 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
                sync = true;
        else if (flags & AT_STATX_DONT_SYNC)
                sync = false;
+       else if (request_mask & READ_ONCE(fi->inval_mask))
+               sync = true;
        else
                sync = time_before64(fi->i_time, get_jiffies_64());
 
@@ -959,7 +952,9 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
 
 int fuse_update_attributes(struct inode *inode, struct file *file)
 {
-       return fuse_update_get_attr(inode, file, NULL, 0);
+       /* Do *not* need to get atime for internal purposes */
+       return fuse_update_get_attr(inode, file, NULL,
+                                   STATX_BASIC_STATS & ~STATX_ATIME, 0);
 }
 
 int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
@@ -989,7 +984,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
        if (!entry)
                goto unlock;
 
-       fuse_invalidate_attr(parent);
+       fuse_dir_changed(parent);
        fuse_invalidate_entry(entry);
 
        if (child_nodeid != 0 && d_really_is_positive(entry)) {
@@ -1165,271 +1160,78 @@ static int fuse_permission(struct inode *inode, int mask)
        return err;
 }
 
-static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
-                        struct dir_context *ctx)
-{
-       while (nbytes >= FUSE_NAME_OFFSET) {
-               struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
-               size_t reclen = FUSE_DIRENT_SIZE(dirent);
-               if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
-                       return -EIO;
-               if (reclen > nbytes)
-                       break;
-               if (memchr(dirent->name, '/', dirent->namelen) != NULL)
-                       return -EIO;
-
-               if (!dir_emit(ctx, dirent->name, dirent->namelen,
-                              dirent->ino, dirent->type))
-                       break;
-
-               buf += reclen;
-               nbytes -= reclen;
-               ctx->pos = dirent->off;
-       }
-
-       return 0;
-}
-
-static int fuse_direntplus_link(struct file *file,
-                               struct fuse_direntplus *direntplus,
-                               u64 attr_version)
-{
-       struct fuse_entry_out *o = &direntplus->entry_out;
-       struct fuse_dirent *dirent = &direntplus->dirent;
-       struct dentry *parent = file->f_path.dentry;
-       struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
-       struct dentry *dentry;
-       struct dentry *alias;
-       struct inode *dir = d_inode(parent);
-       struct fuse_conn *fc;
-       struct inode *inode;
-       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
-
-       if (!o->nodeid) {
-               /*
-                * Unlike in the case of fuse_lookup, zero nodeid does not mean
-                * ENOENT. Instead, it only means the userspace filesystem did
-                * not want to return attributes/handle for this entry.
-                *
-                * So do nothing.
-                */
-               return 0;
-       }
-
-       if (name.name[0] == '.') {
-               /*
-                * We could potentially refresh the attributes of the directory
-                * and its parent?
-                */
-               if (name.len == 1)
-                       return 0;
-               if (name.name[1] == '.' && name.len == 2)
-                       return 0;
-       }
-
-       if (invalid_nodeid(o->nodeid))
-               return -EIO;
-       if (!fuse_valid_type(o->attr.mode))
-               return -EIO;
-
-       fc = get_fuse_conn(dir);
-
-       name.hash = full_name_hash(parent, name.name, name.len);
-       dentry = d_lookup(parent, &name);
-       if (!dentry) {
-retry:
-               dentry = d_alloc_parallel(parent, &name, &wq);
-               if (IS_ERR(dentry))
-                       return PTR_ERR(dentry);
-       }
-       if (!d_in_lookup(dentry)) {
-               struct fuse_inode *fi;
-               inode = d_inode(dentry);
-               if (!inode ||
-                   get_node_id(inode) != o->nodeid ||
-                   ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
-                       d_invalidate(dentry);
-                       dput(dentry);
-                       goto retry;
-               }
-               if (is_bad_inode(inode)) {
-                       dput(dentry);
-                       return -EIO;
-               }
-
-               fi = get_fuse_inode(inode);
-               spin_lock(&fc->lock);
-               fi->nlookup++;
-               spin_unlock(&fc->lock);
-
-               forget_all_cached_acls(inode);
-               fuse_change_attributes(inode, &o->attr,
-                                      entry_attr_timeout(o),
-                                      attr_version);
-               /*
-                * The other branch comes via fuse_iget()
-                * which bumps nlookup inside
-                */
-       } else {
-               inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
-                                 &o->attr, entry_attr_timeout(o),
-                                 attr_version);
-               if (!inode)
-                       inode = ERR_PTR(-ENOMEM);
-
-               alias = d_splice_alias(inode, dentry);
-               d_lookup_done(dentry);
-               if (alias) {
-                       dput(dentry);
-                       dentry = alias;
-               }
-               if (IS_ERR(dentry))
-                       return PTR_ERR(dentry);
-       }
-       if (fc->readdirplus_auto)
-               set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
-       fuse_change_entry_timeout(dentry, o);
-
-       dput(dentry);
-       return 0;
-}
-
-static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
-                            struct dir_context *ctx, u64 attr_version)
+static int fuse_readlink_page(struct inode *inode, struct page *page)
 {
-       struct fuse_direntplus *direntplus;
-       struct fuse_dirent *dirent;
-       size_t reclen;
-       int over = 0;
-       int ret;
-
-       while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
-               direntplus = (struct fuse_direntplus *) buf;
-               dirent = &direntplus->dirent;
-               reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
-
-               if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
-                       return -EIO;
-               if (reclen > nbytes)
-                       break;
-               if (memchr(dirent->name, '/', dirent->namelen) != NULL)
-                       return -EIO;
-
-               if (!over) {
-                       /* We fill entries into dstbuf only as much as
-                          it can hold. But we still continue iterating
-                          over remaining entries to link them. If not,
-                          we need to send a FORGET for each of those
-                          which we did not link.
-                       */
-                       over = !dir_emit(ctx, dirent->name, dirent->namelen,
-                                      dirent->ino, dirent->type);
-                       if (!over)
-                               ctx->pos = dirent->off;
-               }
-
-               buf += reclen;
-               nbytes -= reclen;
-
-               ret = fuse_direntplus_link(file, direntplus, attr_version);
-               if (ret)
-                       fuse_force_forget(file, direntplus->entry_out.nodeid);
-       }
-
-       return 0;
-}
-
-static int fuse_readdir(struct file *file, struct dir_context *ctx)
-{
-       int plus, err;
-       size_t nbytes;
-       struct page *page;
-       struct inode *inode = file_inode(file);
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_req *req;
-       u64 attr_version = 0;
-       bool locked;
-
-       if (is_bad_inode(inode))
-               return -EIO;
+       int err;
 
        req = fuse_get_req(fc, 1);
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       page = alloc_page(GFP_KERNEL);
-       if (!page) {
-               fuse_put_request(fc, req);
-               return -ENOMEM;
-       }
-
-       plus = fuse_use_readdirplus(inode, ctx);
+       req->out.page_zeroing = 1;
        req->out.argpages = 1;
        req->num_pages = 1;
        req->pages[0] = page;
-       req->page_descs[0].length = PAGE_SIZE;
-       if (plus) {
-               attr_version = fuse_get_attr_version(fc);
-               fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
-                              FUSE_READDIRPLUS);
-       } else {
-               fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
-                              FUSE_READDIR);
-       }
-       locked = fuse_lock_inode(inode);
+       req->page_descs[0].length = PAGE_SIZE - 1;
+       req->in.h.opcode = FUSE_READLINK;
+       req->in.h.nodeid = get_node_id(inode);
+       req->out.argvar = 1;
+       req->out.numargs = 1;
+       req->out.args[0].size = PAGE_SIZE - 1;
        fuse_request_send(fc, req);
-       fuse_unlock_inode(inode, locked);
-       nbytes = req->out.args[0].size;
        err = req->out.h.error;
-       fuse_put_request(fc, req);
+
        if (!err) {
-               if (plus) {
-                       err = parse_dirplusfile(page_address(page), nbytes,
-                                               file, ctx,
-                                               attr_version);
-               } else {
-                       err = parse_dirfile(page_address(page), nbytes, file,
-                                           ctx);
-               }
+               char *link = page_address(page);
+               size_t len = req->out.args[0].size;
+
+               BUG_ON(len >= PAGE_SIZE);
+               link[len] = '\0';
        }
 
-       __free_page(page);
+       fuse_put_request(fc, req);
        fuse_invalidate_atime(inode);
+
        return err;
 }
 
-static const char *fuse_get_link(struct dentry *dentry,
-                                struct inode *inode,
-                                struct delayed_call *done)
+static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
+                                struct delayed_call *callback)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
-       FUSE_ARGS(args);
-       char *link;
-       ssize_t ret;
+       struct page *page;
+       int err;
+
+       err = -EIO;
+       if (is_bad_inode(inode))
+               goto out_err;
 
+       if (fc->cache_symlinks)
+               return page_get_link(dentry, inode, callback);
+
+       err = -ECHILD;
        if (!dentry)
-               return ERR_PTR(-ECHILD);
+               goto out_err;
 
-       link = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!link)
-               return ERR_PTR(-ENOMEM);
+       page = alloc_page(GFP_KERNEL);
+       err = -ENOMEM;
+       if (!page)
+               goto out_err;
 
-       args.in.h.opcode = FUSE_READLINK;
-       args.in.h.nodeid = get_node_id(inode);
-       args.out.argvar = 1;
-       args.out.numargs = 1;
-       args.out.args[0].size = PAGE_SIZE - 1;
-       args.out.args[0].value = link;
-       ret = fuse_simple_request(fc, &args);
-       if (ret < 0) {
-               kfree(link);
-               link = ERR_PTR(ret);
-       } else {
-               link[ret] = '\0';
-               set_delayed_call(done, kfree_link, link);
+       err = fuse_readlink_page(inode, page);
+       if (err) {
+               __free_page(page);
+               goto out_err;
        }
-       fuse_invalidate_atime(inode);
-       return link;
+
+       set_delayed_call(callback, page_put_link, page);
+
+       return page_address(page);
+
+out_err:
+       return ERR_PTR(err);
 }
 
 static int fuse_dir_open(struct inode *inode, struct file *file)
@@ -1662,8 +1464,11 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
                file = NULL;
        }
 
-       if (attr->ia_valid & ATTR_SIZE)
+       if (attr->ia_valid & ATTR_SIZE) {
+               if (WARN_ON(!S_ISREG(inode->i_mode)))
+                       return -EIO;
                is_truncate = true;
+       }
 
        if (is_truncate) {
                fuse_set_nowrite(inode);
@@ -1811,7 +1616,7 @@ static int fuse_getattr(const struct path *path, struct kstat *stat,
        if (!fuse_allow_current_process(fc))
                return -EACCES;
 
-       return fuse_update_get_attr(inode, NULL, stat, flags);
+       return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
 }
 
 static const struct inode_operations fuse_dir_inode_operations = {
@@ -1867,11 +1672,37 @@ void fuse_init_common(struct inode *inode)
 
 void fuse_init_dir(struct inode *inode)
 {
+       struct fuse_inode *fi = get_fuse_inode(inode);
+
        inode->i_op = &fuse_dir_inode_operations;
        inode->i_fop = &fuse_dir_operations;
+
+       spin_lock_init(&fi->rdc.lock);
+       fi->rdc.cached = false;
+       fi->rdc.size = 0;
+       fi->rdc.pos = 0;
+       fi->rdc.version = 0;
 }
 
+static int fuse_symlink_readpage(struct file *null, struct page *page)
+{
+       int err = fuse_readlink_page(page->mapping->host, page);
+
+       if (!err)
+               SetPageUptodate(page);
+
+       unlock_page(page);
+
+       return err;
+}
+
+static const struct address_space_operations fuse_symlink_aops = {
+       .readpage       = fuse_symlink_readpage,
+};
+
 void fuse_init_symlink(struct inode *inode)
 {
        inode->i_op = &fuse_symlink_inode_operations;
+       inode->i_data.a_ops = &fuse_symlink_aops;
+       inode_nohighmem(inode);
 }
index 32d0b883e74f340d442754a5a87b82629b96658e..58dbc39fea639ef5e0dc95dd830e47c9763ffe29 100644 (file)
@@ -59,6 +59,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
        }
 
        INIT_LIST_HEAD(&ff->write_entry);
+       mutex_init(&ff->readdir.lock);
        refcount_set(&ff->count, 1);
        RB_CLEAR_NODE(&ff->polled_node);
        init_waitqueue_head(&ff->poll_wait);
@@ -73,6 +74,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
 void fuse_file_free(struct fuse_file *ff)
 {
        fuse_request_free(ff->reserved_req);
+       mutex_destroy(&ff->readdir.lock);
        kfree(ff);
 }
 
@@ -848,11 +850,11 @@ static int fuse_readpages_fill(void *_data, struct page *page)
        fuse_wait_on_page_writeback(inode, page->index);
 
        if (req->num_pages &&
-           (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
+           (req->num_pages == fc->max_pages ||
             (req->num_pages + 1) * PAGE_SIZE > fc->max_read ||
             req->pages[req->num_pages - 1]->index + 1 != page->index)) {
-               int nr_alloc = min_t(unsigned, data->nr_pages,
-                                    FUSE_MAX_PAGES_PER_REQ);
+               unsigned int nr_alloc = min_t(unsigned int, data->nr_pages,
+                                             fc->max_pages);
                fuse_send_readpages(req, data->file);
                if (fc->async_read)
                        req = fuse_get_req_for_background(fc, nr_alloc);
@@ -887,7 +889,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_fill_data data;
        int err;
-       int nr_alloc = min_t(unsigned, nr_pages, FUSE_MAX_PAGES_PER_REQ);
+       unsigned int nr_alloc = min_t(unsigned int, nr_pages, fc->max_pages);
 
        err = -EIO;
        if (is_bad_inode(inode))
@@ -1102,12 +1104,13 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
        return count > 0 ? count : err;
 }
 
-static inline unsigned fuse_wr_pages(loff_t pos, size_t len)
+static inline unsigned int fuse_wr_pages(loff_t pos, size_t len,
+                                    unsigned int max_pages)
 {
-       return min_t(unsigned,
+       return min_t(unsigned int,
                     ((pos + len - 1) >> PAGE_SHIFT) -
                     (pos >> PAGE_SHIFT) + 1,
-                    FUSE_MAX_PAGES_PER_REQ);
+                    max_pages);
 }
 
 static ssize_t fuse_perform_write(struct kiocb *iocb,
@@ -1129,7 +1132,8 @@ static ssize_t fuse_perform_write(struct kiocb *iocb,
        do {
                struct fuse_req *req;
                ssize_t count;
-               unsigned nr_pages = fuse_wr_pages(pos, iov_iter_count(ii));
+               unsigned int nr_pages = fuse_wr_pages(pos, iov_iter_count(ii),
+                                                     fc->max_pages);
 
                req = fuse_get_req(fc, nr_pages);
                if (IS_ERR(req)) {
@@ -1319,11 +1323,6 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
        return ret < 0 ? ret : 0;
 }
 
-static inline int fuse_iter_npages(const struct iov_iter *ii_p)
-{
-       return iov_iter_npages(ii_p, FUSE_MAX_PAGES_PER_REQ);
-}
-
 ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                       loff_t *ppos, int flags)
 {
@@ -1343,9 +1342,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
        int err = 0;
 
        if (io->async)
-               req = fuse_get_req_for_background(fc, fuse_iter_npages(iter));
+               req = fuse_get_req_for_background(fc, iov_iter_npages(iter,
+                                                               fc->max_pages));
        else
-               req = fuse_get_req(fc, fuse_iter_npages(iter));
+               req = fuse_get_req(fc, iov_iter_npages(iter, fc->max_pages));
        if (IS_ERR(req))
                return PTR_ERR(req);
 
@@ -1390,9 +1390,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                        fuse_put_request(fc, req);
                        if (io->async)
                                req = fuse_get_req_for_background(fc,
-                                       fuse_iter_npages(iter));
+                                       iov_iter_npages(iter, fc->max_pages));
                        else
-                               req = fuse_get_req(fc, fuse_iter_npages(iter));
+                               req = fuse_get_req(fc, iov_iter_npages(iter,
+                                                               fc->max_pages));
                        if (IS_ERR(req))
                                break;
                }
@@ -1418,7 +1419,7 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io,
 
        res = fuse_direct_io(io, iter, ppos, 0);
 
-       fuse_invalidate_attr(inode);
+       fuse_invalidate_atime(inode);
 
        return res;
 }
@@ -1487,6 +1488,7 @@ __acquires(fc->lock)
        struct fuse_inode *fi = get_fuse_inode(req->inode);
        struct fuse_write_in *inarg = &req->misc.write.in;
        __u64 data_size = req->num_pages * PAGE_SIZE;
+       bool queued;
 
        if (!fc->connected)
                goto out_free;
@@ -1502,7 +1504,8 @@ __acquires(fc->lock)
 
        req->in.args[1].size = inarg->size;
        fi->writectr++;
-       fuse_request_send_background_locked(fc, req);
+       queued = fuse_request_queue_background(fc, req);
+       WARN_ON(!queued);
        return;
 
  out_free:
@@ -1819,12 +1822,18 @@ static int fuse_writepages_fill(struct page *page,
        is_writeback = fuse_page_is_writeback(inode, page->index);
 
        if (req && req->num_pages &&
-           (is_writeback || req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
+           (is_writeback || req->num_pages == fc->max_pages ||
             (req->num_pages + 1) * PAGE_SIZE > fc->max_write ||
             data->orig_pages[req->num_pages - 1]->index + 1 != page->index)) {
                fuse_writepages_send(data);
                data->req = NULL;
+       } else if (req && req->num_pages == req->max_pages) {
+               if (!fuse_req_realloc_pages(fc, req, GFP_NOFS)) {
+                       fuse_writepages_send(data);
+                       req = data->req = NULL;
+               }
        }
+
        err = -ENOMEM;
        tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
        if (!tmp_page)
@@ -1847,7 +1856,7 @@ static int fuse_writepages_fill(struct page *page,
                struct fuse_inode *fi = get_fuse_inode(inode);
 
                err = -ENOMEM;
-               req = fuse_request_alloc_nofs(FUSE_MAX_PAGES_PER_REQ);
+               req = fuse_request_alloc_nofs(FUSE_REQ_INLINE_PAGES);
                if (!req) {
                        __free_page(tmp_page);
                        goto out_unlock;
@@ -1904,6 +1913,7 @@ static int fuse_writepages(struct address_space *mapping,
                           struct writeback_control *wbc)
 {
        struct inode *inode = mapping->host;
+       struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_fill_wb_data data;
        int err;
 
@@ -1916,7 +1926,7 @@ static int fuse_writepages(struct address_space *mapping,
        data.ff = NULL;
 
        err = -ENOMEM;
-       data.orig_pages = kcalloc(FUSE_MAX_PAGES_PER_REQ,
+       data.orig_pages = kcalloc(fc->max_pages,
                                  sizeof(struct page *),
                                  GFP_NOFS);
        if (!data.orig_pages)
@@ -2387,10 +2397,11 @@ static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src,
 }
 
 /* Make sure iov_length() won't overflow */
-static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+static int fuse_verify_ioctl_iov(struct fuse_conn *fc, struct iovec *iov,
+                                size_t count)
 {
        size_t n;
-       u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+       u32 max = fc->max_pages << PAGE_SHIFT;
 
        for (n = 0; n < count; n++, iov++) {
                if (iov->iov_len > (size_t) max)
@@ -2514,7 +2525,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
        BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
 
        err = -ENOMEM;
-       pages = kcalloc(FUSE_MAX_PAGES_PER_REQ, sizeof(pages[0]), GFP_KERNEL);
+       pages = kcalloc(fc->max_pages, sizeof(pages[0]), GFP_KERNEL);
        iov_page = (struct iovec *) __get_free_page(GFP_KERNEL);
        if (!pages || !iov_page)
                goto out;
@@ -2553,7 +2564,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
 
        /* make sure there are enough buffer pages and init request with them */
        err = -ENOMEM;
-       if (max_pages > FUSE_MAX_PAGES_PER_REQ)
+       if (max_pages > fc->max_pages)
                goto out;
        while (num_pages < max_pages) {
                pages[num_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
@@ -2640,11 +2651,11 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                in_iov = iov_page;
                out_iov = in_iov + in_iovs;
 
-               err = fuse_verify_ioctl_iov(in_iov, in_iovs);
+               err = fuse_verify_ioctl_iov(fc, in_iov, in_iovs);
                if (err)
                        goto out;
 
-               err = fuse_verify_ioctl_iov(out_iov, out_iovs);
+               err = fuse_verify_ioctl_iov(fc, out_iov, out_iovs);
                if (err)
                        goto out;
 
@@ -2835,9 +2846,9 @@ static void fuse_do_truncate(struct file *file)
        fuse_do_setattr(file_dentry(file), &attr, file);
 }
 
-static inline loff_t fuse_round_up(loff_t off)
+static inline loff_t fuse_round_up(struct fuse_conn *fc, loff_t off)
 {
-       return round_up(off, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
+       return round_up(off, fc->max_pages << PAGE_SHIFT);
 }
 
 static ssize_t
@@ -2866,7 +2877,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
        if (async_dio && iov_iter_rw(iter) != WRITE && offset + count > i_size) {
                if (offset >= i_size)
                        return 0;
-               iov_iter_truncate(iter, fuse_round_up(i_size - offset));
+               iov_iter_truncate(iter, fuse_round_up(ff->fc, i_size - offset));
                count = iov_iter_count(iter);
        }
 
@@ -3011,6 +3022,82 @@ out:
        return err;
 }
 
+static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in,
+                                   struct file *file_out, loff_t pos_out,
+                                   size_t len, unsigned int flags)
+{
+       struct fuse_file *ff_in = file_in->private_data;
+       struct fuse_file *ff_out = file_out->private_data;
+       struct inode *inode_out = file_inode(file_out);
+       struct fuse_inode *fi_out = get_fuse_inode(inode_out);
+       struct fuse_conn *fc = ff_in->fc;
+       FUSE_ARGS(args);
+       struct fuse_copy_file_range_in inarg = {
+               .fh_in = ff_in->fh,
+               .off_in = pos_in,
+               .nodeid_out = ff_out->nodeid,
+               .fh_out = ff_out->fh,
+               .off_out = pos_out,
+               .len = len,
+               .flags = flags
+       };
+       struct fuse_write_out outarg;
+       ssize_t err;
+       /* mark unstable when write-back is not used, and file_out gets
+        * extended */
+       bool is_unstable = (!fc->writeback_cache) &&
+                          ((pos_out + len) > inode_out->i_size);
+
+       if (fc->no_copy_file_range)
+               return -EOPNOTSUPP;
+
+       inode_lock(inode_out);
+
+       if (fc->writeback_cache) {
+               err = filemap_write_and_wait_range(inode_out->i_mapping,
+                                                  pos_out, pos_out + len);
+               if (err)
+                       goto out;
+
+               fuse_sync_writes(inode_out);
+       }
+
+       if (is_unstable)
+               set_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state);
+
+       args.in.h.opcode = FUSE_COPY_FILE_RANGE;
+       args.in.h.nodeid = ff_in->nodeid;
+       args.in.numargs = 1;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       args.out.numargs = 1;
+       args.out.args[0].size = sizeof(outarg);
+       args.out.args[0].value = &outarg;
+       err = fuse_simple_request(fc, &args);
+       if (err == -ENOSYS) {
+               fc->no_copy_file_range = 1;
+               err = -EOPNOTSUPP;
+       }
+       if (err)
+               goto out;
+
+       if (fc->writeback_cache) {
+               fuse_write_update_size(inode_out, pos_out + outarg.size);
+               file_update_time(file_out);
+       }
+
+       fuse_invalidate_attr(inode_out);
+
+       err = outarg.size;
+out:
+       if (is_unstable)
+               clear_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state);
+
+       inode_unlock(inode_out);
+
+       return err;
+}
+
 static const struct file_operations fuse_file_operations = {
        .llseek         = fuse_file_llseek,
        .read_iter      = fuse_file_read_iter,
@@ -3027,6 +3114,7 @@ static const struct file_operations fuse_file_operations = {
        .compat_ioctl   = fuse_file_compat_ioctl,
        .poll           = fuse_file_poll,
        .fallocate      = fuse_file_fallocate,
+       .copy_file_range = fuse_copy_file_range,
 };
 
 static const struct file_operations fuse_direct_io_file_operations = {
@@ -3062,6 +3150,14 @@ static const struct address_space_operations fuse_file_aops  = {
 
 void fuse_init_file_inode(struct inode *inode)
 {
+       struct fuse_inode *fi = get_fuse_inode(inode);
+
        inode->i_fop = &fuse_file_operations;
        inode->i_data.a_ops = &fuse_file_aops;
+
+       INIT_LIST_HEAD(&fi->write_files);
+       INIT_LIST_HEAD(&fi->queued_writes);
+       fi->writectr = 0;
+       init_waitqueue_head(&fi->page_waitq);
+       INIT_LIST_HEAD(&fi->writepages);
 }
index f78e9614bb5f712d2936bffa2fa886c7027ba7c1..e9f712e81c7d9e188ae174d2bb3f0ba3b853d90f 100644 (file)
 #include <linux/refcount.h>
 #include <linux/user_namespace.h>
 
-/** Max number of pages that can be used in a single read request */
-#define FUSE_MAX_PAGES_PER_REQ 32
+/** Default max number of pages that can be used in a single read request */
+#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
+
+/** Maximum of max_pages received in init_out */
+#define FUSE_MAX_MAX_PAGES 256
 
 /** Bias for fi->writectr, meaning new writepages must not be sent */
 #define FUSE_NOWRITE INT_MIN
@@ -77,6 +80,9 @@ struct fuse_inode {
        /** Time in jiffies until the file attributes are valid */
        u64 i_time;
 
+       /* Which attributes are invalid */
+       u32 inval_mask;
+
        /** The sticky bit in inode->i_mode may have been removed, so
            preserve the original mode */
        umode_t orig_i_mode;
@@ -87,21 +93,51 @@ struct fuse_inode {
        /** Version of last attribute change */
        u64 attr_version;
 
-       /** Files usable in writepage.  Protected by fc->lock */
-       struct list_head write_files;
+       union {
+               /* Write related fields (regular file only) */
+               struct {
+                       /* Files usable in writepage.  Protected by fc->lock */
+                       struct list_head write_files;
+
+                       /* Writepages pending on truncate or fsync */
+                       struct list_head queued_writes;
 
-       /** Writepages pending on truncate or fsync */
-       struct list_head queued_writes;
+                       /* Number of sent writes, a negative bias
+                        * (FUSE_NOWRITE) means more writes are blocked */
+                       int writectr;
+
+                       /* Waitq for writepage completion */
+                       wait_queue_head_t page_waitq;
+
+                       /* List of writepage requestst (pending or sent) */
+                       struct list_head writepages;
+               };
+
+               /* readdir cache (directory only) */
+               struct {
+                       /* true if fully cached */
+                       bool cached;
 
-       /** Number of sent writes, a negative bias (FUSE_NOWRITE)
-        * means more writes are blocked */
-       int writectr;
+                       /* size of cache */
+                       loff_t size;
 
-       /** Waitq for writepage completion */
-       wait_queue_head_t page_waitq;
+                       /* position at end of cache (position of next entry) */
+                       loff_t pos;
 
-       /** List of writepage requestst (pending or sent) */
-       struct list_head writepages;
+                       /* version of the cache */
+                       u64 version;
+
+                       /* modification time of directory when cache was
+                        * started */
+                       struct timespec64 mtime;
+
+                       /* iversion of directory when cache was started */
+                       u64 iversion;
+
+                       /* protects above fields */
+                       spinlock_t lock;
+               } rdc;
+       };
 
        /** Miscellaneous bits describing inode state */
        unsigned long state;
@@ -148,6 +184,25 @@ struct fuse_file {
        /** Entry on inode's write_files list */
        struct list_head write_entry;
 
+       /* Readdir related */
+       struct {
+               /*
+                * Protects below fields against (crazy) parallel readdir on
+                * same open file.  Uncontended in the normal case.
+                */
+               struct mutex lock;
+
+               /* Dir stream position */
+               loff_t pos;
+
+               /* Offset in cache */
+               loff_t cache_off;
+
+               /* Version of cache we are reading */
+               u64 version;
+
+       } readdir;
+
        /** RB node to be linked on fuse_conn->polled_files */
        struct rb_node polled_node;
 
@@ -311,9 +366,6 @@ struct fuse_req {
        /** refcount */
        refcount_t count;
 
-       /** Unique ID for the interrupt request */
-       u64 intr_unique;
-
        /* Request flags, updated with test/set/clear_bit() */
        unsigned long flags;
 
@@ -411,6 +463,9 @@ struct fuse_iqueue {
        struct fasync_struct *fasync;
 };
 
+#define FUSE_PQ_HASH_BITS 8
+#define FUSE_PQ_HASH_SIZE (1 << FUSE_PQ_HASH_BITS)
+
 struct fuse_pqueue {
        /** Connection established */
        unsigned connected;
@@ -418,8 +473,8 @@ struct fuse_pqueue {
        /** Lock protecting accessess to  members of this structure */
        spinlock_t lock;
 
-       /** The list of requests being processed */
-       struct list_head processing;
+       /** Hash table of requests being processed */
+       struct list_head *processing;
 
        /** The list of requests under I/O */
        struct list_head io;
@@ -476,6 +531,9 @@ struct fuse_conn {
        /** Maximum write size */
        unsigned max_write;
 
+       /** Maxmum number of pages that can be used in a single request */
+       unsigned int max_pages;
+
        /** Input queue */
        struct fuse_iqueue iq;
 
@@ -500,6 +558,10 @@ struct fuse_conn {
        /** The list of background requests set aside for later queuing */
        struct list_head bg_queue;
 
+       /** Protects: max_background, congestion_threshold, num_background,
+        * active_background, bg_queue, blocked */
+       spinlock_t bg_lock;
+
        /** Flag indicating that INIT reply has been received. Allocating
         * any fuse request will be suspended until the flag is set */
        int initialized;
@@ -551,6 +613,9 @@ struct fuse_conn {
        /** handle fs handles killing suid/sgid/cap on write/chown/trunc */
        unsigned handle_killpriv:1;
 
+       /** cache READLINK responses in page cache */
+       unsigned cache_symlinks:1;
+
        /*
         * The following bitfields are only for optimization purposes
         * and hence races in setting them will not cause malfunction
@@ -637,6 +702,9 @@ struct fuse_conn {
        /** Allow other than the mounter user to access the filesystem ? */
        unsigned allow_other:1;
 
+       /** Does the filesystem support copy_file_range? */
+       unsigned no_copy_file_range:1;
+
        /** The number of requests waiting for completion */
        atomic_t num_waiting;
 
@@ -697,6 +765,11 @@ static inline u64 get_node_id(struct inode *inode)
        return get_fuse_inode(inode)->nodeid;
 }
 
+static inline int invalid_nodeid(u64 nodeid)
+{
+       return !nodeid || nodeid == FUSE_ROOT_ID;
+}
+
 /** Device operations */
 extern const struct file_operations fuse_dev_operations;
 
@@ -812,6 +885,10 @@ struct fuse_req *fuse_request_alloc(unsigned npages);
 
 struct fuse_req *fuse_request_alloc_nofs(unsigned npages);
 
+bool fuse_req_realloc_pages(struct fuse_conn *fc, struct fuse_req *req,
+                           gfp_t flags);
+
+
 /**
  * Free a request
  */
@@ -856,9 +933,7 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);
  * Send a request in the background
  */
 void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req);
-
-void fuse_request_send_background_locked(struct fuse_conn *fc,
-                                        struct fuse_req *req);
+bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req);
 
 /* Abort all requests */
 void fuse_abort_conn(struct fuse_conn *fc, bool is_abort);
@@ -873,6 +948,9 @@ void fuse_invalidate_entry_cache(struct dentry *entry);
 
 void fuse_invalidate_atime(struct inode *inode);
 
+u64 entry_attr_timeout(struct fuse_entry_out *o);
+void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o);
+
 /**
  * Acquire reference to fuse_conn
  */
@@ -992,4 +1070,8 @@ struct posix_acl;
 struct posix_acl *fuse_get_acl(struct inode *inode, int type);
 int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type);
 
+
+/* readdir.c */
+int fuse_readdir(struct file *file, struct dir_context *ctx);
+
 #endif /* _FS_FUSE_I_H */
index db9e60b7eb691bc4f0814c694577f60d363f32a1..0b94b23b02d4798d557f09020b5a4c7fda91c15f 100644 (file)
@@ -90,16 +90,12 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
 
        fi = get_fuse_inode(inode);
        fi->i_time = 0;
+       fi->inval_mask = 0;
        fi->nodeid = 0;
        fi->nlookup = 0;
        fi->attr_version = 0;
-       fi->writectr = 0;
        fi->orig_ino = 0;
        fi->state = 0;
-       INIT_LIST_HEAD(&fi->write_files);
-       INIT_LIST_HEAD(&fi->queued_writes);
-       INIT_LIST_HEAD(&fi->writepages);
-       init_waitqueue_head(&fi->page_waitq);
        mutex_init(&fi->mutex);
        fi->forget = fuse_alloc_forget();
        if (!fi->forget) {
@@ -119,8 +115,10 @@ static void fuse_i_callback(struct rcu_head *head)
 static void fuse_destroy_inode(struct inode *inode)
 {
        struct fuse_inode *fi = get_fuse_inode(inode);
-       BUG_ON(!list_empty(&fi->write_files));
-       BUG_ON(!list_empty(&fi->queued_writes));
+       if (S_ISREG(inode->i_mode)) {
+               WARN_ON(!list_empty(&fi->write_files));
+               WARN_ON(!list_empty(&fi->queued_writes));
+       }
        mutex_destroy(&fi->mutex);
        kfree(fi->forget);
        call_rcu(&inode->i_rcu, fuse_i_callback);
@@ -167,6 +165,7 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
 
        fi->attr_version = ++fc->attr_version;
        fi->i_time = attr_valid;
+       WRITE_ONCE(fi->inval_mask, 0);
 
        inode->i_ino     = fuse_squash_ino(attr->ino);
        inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
@@ -594,9 +593,11 @@ static void fuse_iqueue_init(struct fuse_iqueue *fiq)
 
 static void fuse_pqueue_init(struct fuse_pqueue *fpq)
 {
-       memset(fpq, 0, sizeof(struct fuse_pqueue));
+       unsigned int i;
+
        spin_lock_init(&fpq->lock);
-       INIT_LIST_HEAD(&fpq->processing);
+       for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
+               INIT_LIST_HEAD(&fpq->processing[i]);
        INIT_LIST_HEAD(&fpq->io);
        fpq->connected = 1;
 }
@@ -605,6 +606,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns)
 {
        memset(fc, 0, sizeof(*fc));
        spin_lock_init(&fc->lock);
+       spin_lock_init(&fc->bg_lock);
        init_rwsem(&fc->killsb);
        refcount_set(&fc->count, 1);
        atomic_set(&fc->dev_count, 1);
@@ -852,6 +854,7 @@ static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
        sanitize_global_limit(&max_user_bgreq);
        sanitize_global_limit(&max_user_congthresh);
 
+       spin_lock(&fc->bg_lock);
        if (arg->max_background) {
                fc->max_background = arg->max_background;
 
@@ -865,6 +868,7 @@ static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
                    fc->congestion_threshold > max_user_congthresh)
                        fc->congestion_threshold = max_user_congthresh;
        }
+       spin_unlock(&fc->bg_lock);
 }
 
 static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
@@ -924,8 +928,15 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->posix_acl = 1;
                                fc->sb->s_xattr = fuse_acl_xattr_handlers;
                        }
+                       if (arg->flags & FUSE_CACHE_SYMLINKS)
+                               fc->cache_symlinks = 1;
                        if (arg->flags & FUSE_ABORT_ERROR)
                                fc->abort_err = 1;
+                       if (arg->flags & FUSE_MAX_PAGES) {
+                               fc->max_pages =
+                                       min_t(unsigned int, FUSE_MAX_MAX_PAGES,
+                                       max_t(unsigned int, arg->max_pages, 1));
+                       }
                } else {
                        ra_pages = fc->max_read / PAGE_SIZE;
                        fc->no_lock = 1;
@@ -957,7 +968,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
                FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
                FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT |
                FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
-               FUSE_ABORT_ERROR;
+               FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
@@ -1022,17 +1033,26 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
 struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc)
 {
        struct fuse_dev *fud;
+       struct list_head *pq;
 
        fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL);
-       if (fud) {
-               fud->fc = fuse_conn_get(fc);
-               fuse_pqueue_init(&fud->pq);
+       if (!fud)
+               return NULL;
 
-               spin_lock(&fc->lock);
-               list_add_tail(&fud->entry, &fc->devices);
-               spin_unlock(&fc->lock);
+       pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL);
+       if (!pq) {
+               kfree(fud);
+               return NULL;
        }
 
+       fud->pq.processing = pq;
+       fud->fc = fuse_conn_get(fc);
+       fuse_pqueue_init(&fud->pq);
+
+       spin_lock(&fc->lock);
+       list_add_tail(&fud->entry, &fc->devices);
+       spin_unlock(&fc->lock);
+
        return fud;
 }
 EXPORT_SYMBOL_GPL(fuse_dev_alloc);
@@ -1141,6 +1161,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        fc->user_id = d.user_id;
        fc->group_id = d.group_id;
        fc->max_read = max_t(unsigned, 4096, d.max_read);
+       fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
 
        /* Used by get_root_inode() */
        sb->s_fs_info = fc;
diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
new file mode 100644 (file)
index 0000000..ab18b78
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+  FUSE: Filesystem in Userspace
+  Copyright (C) 2001-2018  Miklos Szeredi <miklos@szeredi.hu>
+
+  This program can be distributed under the terms of the GNU GPL.
+  See the file COPYING.
+*/
+
+
+#include "fuse_i.h"
+#include <linux/iversion.h>
+#include <linux/posix_acl.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+
+static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
+{
+       struct fuse_conn *fc = get_fuse_conn(dir);
+       struct fuse_inode *fi = get_fuse_inode(dir);
+
+       if (!fc->do_readdirplus)
+               return false;
+       if (!fc->readdirplus_auto)
+               return true;
+       if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
+               return true;
+       if (ctx->pos == 0)
+               return true;
+       return false;
+}
+
+static void fuse_add_dirent_to_cache(struct file *file,
+                                    struct fuse_dirent *dirent, loff_t pos)
+{
+       struct fuse_inode *fi = get_fuse_inode(file_inode(file));
+       size_t reclen = FUSE_DIRENT_SIZE(dirent);
+       pgoff_t index;
+       struct page *page;
+       loff_t size;
+       u64 version;
+       unsigned int offset;
+       void *addr;
+
+       spin_lock(&fi->rdc.lock);
+       /*
+        * Is cache already completed?  Or this entry does not go at the end of
+        * cache?
+        */
+       if (fi->rdc.cached || pos != fi->rdc.pos) {
+               spin_unlock(&fi->rdc.lock);
+               return;
+       }
+       version = fi->rdc.version;
+       size = fi->rdc.size;
+       offset = size & ~PAGE_MASK;
+       index = size >> PAGE_SHIFT;
+       /* Dirent doesn't fit in current page?  Jump to next page. */
+       if (offset + reclen > PAGE_SIZE) {
+               index++;
+               offset = 0;
+       }
+       spin_unlock(&fi->rdc.lock);
+
+       if (offset) {
+               page = find_lock_page(file->f_mapping, index);
+       } else {
+               page = find_or_create_page(file->f_mapping, index,
+                                          mapping_gfp_mask(file->f_mapping));
+       }
+       if (!page)
+               return;
+
+       spin_lock(&fi->rdc.lock);
+       /* Raced with another readdir */
+       if (fi->rdc.version != version || fi->rdc.size != size ||
+           WARN_ON(fi->rdc.pos != pos))
+               goto unlock;
+
+       addr = kmap_atomic(page);
+       if (!offset)
+               clear_page(addr);
+       memcpy(addr + offset, dirent, reclen);
+       kunmap_atomic(addr);
+       fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen;
+       fi->rdc.pos = dirent->off;
+unlock:
+       spin_unlock(&fi->rdc.lock);
+       unlock_page(page);
+       put_page(page);
+}
+
+static void fuse_readdir_cache_end(struct file *file, loff_t pos)
+{
+       struct fuse_inode *fi = get_fuse_inode(file_inode(file));
+       loff_t end;
+
+       spin_lock(&fi->rdc.lock);
+       /* does cache end position match current position? */
+       if (fi->rdc.pos != pos) {
+               spin_unlock(&fi->rdc.lock);
+               return;
+       }
+
+       fi->rdc.cached = true;
+       end = ALIGN(fi->rdc.size, PAGE_SIZE);
+       spin_unlock(&fi->rdc.lock);
+
+       /* truncate unused tail of cache */
+       truncate_inode_pages(file->f_mapping, end);
+}
+
+static bool fuse_emit(struct file *file, struct dir_context *ctx,
+                     struct fuse_dirent *dirent)
+{
+       struct fuse_file *ff = file->private_data;
+
+       if (ff->open_flags & FOPEN_CACHE_DIR)
+               fuse_add_dirent_to_cache(file, dirent, ctx->pos);
+
+       return dir_emit(ctx, dirent->name, dirent->namelen, dirent->ino,
+                       dirent->type);
+}
+
+static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
+                        struct dir_context *ctx)
+{
+       while (nbytes >= FUSE_NAME_OFFSET) {
+               struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
+               size_t reclen = FUSE_DIRENT_SIZE(dirent);
+               if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
+                       return -EIO;
+               if (reclen > nbytes)
+                       break;
+               if (memchr(dirent->name, '/', dirent->namelen) != NULL)
+                       return -EIO;
+
+               if (!fuse_emit(file, ctx, dirent))
+                       break;
+
+               buf += reclen;
+               nbytes -= reclen;
+               ctx->pos = dirent->off;
+       }
+
+       return 0;
+}
+
+static int fuse_direntplus_link(struct file *file,
+                               struct fuse_direntplus *direntplus,
+                               u64 attr_version)
+{
+       struct fuse_entry_out *o = &direntplus->entry_out;
+       struct fuse_dirent *dirent = &direntplus->dirent;
+       struct dentry *parent = file->f_path.dentry;
+       struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
+       struct dentry *dentry;
+       struct dentry *alias;
+       struct inode *dir = d_inode(parent);
+       struct fuse_conn *fc;
+       struct inode *inode;
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
+
+       if (!o->nodeid) {
+               /*
+                * Unlike in the case of fuse_lookup, zero nodeid does not mean
+                * ENOENT. Instead, it only means the userspace filesystem did
+                * not want to return attributes/handle for this entry.
+                *
+                * So do nothing.
+                */
+               return 0;
+       }
+
+       if (name.name[0] == '.') {
+               /*
+                * We could potentially refresh the attributes of the directory
+                * and its parent?
+                */
+               if (name.len == 1)
+                       return 0;
+               if (name.name[1] == '.' && name.len == 2)
+                       return 0;
+       }
+
+       if (invalid_nodeid(o->nodeid))
+               return -EIO;
+       if (!fuse_valid_type(o->attr.mode))
+               return -EIO;
+
+       fc = get_fuse_conn(dir);
+
+       name.hash = full_name_hash(parent, name.name, name.len);
+       dentry = d_lookup(parent, &name);
+       if (!dentry) {
+retry:
+               dentry = d_alloc_parallel(parent, &name, &wq);
+               if (IS_ERR(dentry))
+                       return PTR_ERR(dentry);
+       }
+       if (!d_in_lookup(dentry)) {
+               struct fuse_inode *fi;
+               inode = d_inode(dentry);
+               if (!inode ||
+                   get_node_id(inode) != o->nodeid ||
+                   ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
+                       d_invalidate(dentry);
+                       dput(dentry);
+                       goto retry;
+               }
+               if (is_bad_inode(inode)) {
+                       dput(dentry);
+                       return -EIO;
+               }
+
+               fi = get_fuse_inode(inode);
+               spin_lock(&fc->lock);
+               fi->nlookup++;
+               spin_unlock(&fc->lock);
+
+               forget_all_cached_acls(inode);
+               fuse_change_attributes(inode, &o->attr,
+                                      entry_attr_timeout(o),
+                                      attr_version);
+               /*
+                * The other branch comes via fuse_iget()
+                * which bumps nlookup inside
+                */
+       } else {
+               inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
+                                 &o->attr, entry_attr_timeout(o),
+                                 attr_version);
+               if (!inode)
+                       inode = ERR_PTR(-ENOMEM);
+
+               alias = d_splice_alias(inode, dentry);
+               d_lookup_done(dentry);
+               if (alias) {
+                       dput(dentry);
+                       dentry = alias;
+               }
+               if (IS_ERR(dentry))
+                       return PTR_ERR(dentry);
+       }
+       if (fc->readdirplus_auto)
+               set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
+       fuse_change_entry_timeout(dentry, o);
+
+       dput(dentry);
+       return 0;
+}
+
+static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
+                            struct dir_context *ctx, u64 attr_version)
+{
+       struct fuse_direntplus *direntplus;
+       struct fuse_dirent *dirent;
+       size_t reclen;
+       int over = 0;
+       int ret;
+
+       while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
+               direntplus = (struct fuse_direntplus *) buf;
+               dirent = &direntplus->dirent;
+               reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
+
+               if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
+                       return -EIO;
+               if (reclen > nbytes)
+                       break;
+               if (memchr(dirent->name, '/', dirent->namelen) != NULL)
+                       return -EIO;
+
+               if (!over) {
+                       /* We fill entries into dstbuf only as much as
+                          it can hold. But we still continue iterating
+                          over remaining entries to link them. If not,
+                          we need to send a FORGET for each of those
+                          which we did not link.
+                       */
+                       over = !fuse_emit(file, ctx, dirent);
+                       if (!over)
+                               ctx->pos = dirent->off;
+               }
+
+               buf += reclen;
+               nbytes -= reclen;
+
+               ret = fuse_direntplus_link(file, direntplus, attr_version);
+               if (ret)
+                       fuse_force_forget(file, direntplus->entry_out.nodeid);
+       }
+
+       return 0;
+}
+
+static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
+{
+       int plus, err;
+       size_t nbytes;
+       struct page *page;
+       struct inode *inode = file_inode(file);
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_req *req;
+       u64 attr_version = 0;
+       bool locked;
+
+       req = fuse_get_req(fc, 1);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       page = alloc_page(GFP_KERNEL);
+       if (!page) {
+               fuse_put_request(fc, req);
+               return -ENOMEM;
+       }
+
+       plus = fuse_use_readdirplus(inode, ctx);
+       req->out.argpages = 1;
+       req->num_pages = 1;
+       req->pages[0] = page;
+       req->page_descs[0].length = PAGE_SIZE;
+       if (plus) {
+               attr_version = fuse_get_attr_version(fc);
+               fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
+                              FUSE_READDIRPLUS);
+       } else {
+               fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
+                              FUSE_READDIR);
+       }
+       locked = fuse_lock_inode(inode);
+       fuse_request_send(fc, req);
+       fuse_unlock_inode(inode, locked);
+       nbytes = req->out.args[0].size;
+       err = req->out.h.error;
+       fuse_put_request(fc, req);
+       if (!err) {
+               if (!nbytes) {
+                       struct fuse_file *ff = file->private_data;
+
+                       if (ff->open_flags & FOPEN_CACHE_DIR)
+                               fuse_readdir_cache_end(file, ctx->pos);
+               } else if (plus) {
+                       err = parse_dirplusfile(page_address(page), nbytes,
+                                               file, ctx, attr_version);
+               } else {
+                       err = parse_dirfile(page_address(page), nbytes, file,
+                                           ctx);
+               }
+       }
+
+       __free_page(page);
+       fuse_invalidate_atime(inode);
+       return err;
+}
+
+enum fuse_parse_result {
+       FOUND_ERR = -1,
+       FOUND_NONE = 0,
+       FOUND_SOME,
+       FOUND_ALL,
+};
+
+static enum fuse_parse_result fuse_parse_cache(struct fuse_file *ff,
+                                              void *addr, unsigned int size,
+                                              struct dir_context *ctx)
+{
+       unsigned int offset = ff->readdir.cache_off & ~PAGE_MASK;
+       enum fuse_parse_result res = FOUND_NONE;
+
+       WARN_ON(offset >= size);
+
+       for (;;) {
+               struct fuse_dirent *dirent = addr + offset;
+               unsigned int nbytes = size - offset;
+               size_t reclen = FUSE_DIRENT_SIZE(dirent);
+
+               if (nbytes < FUSE_NAME_OFFSET || !dirent->namelen)
+                       break;
+
+               if (WARN_ON(dirent->namelen > FUSE_NAME_MAX))
+                       return FOUND_ERR;
+               if (WARN_ON(reclen > nbytes))
+                       return FOUND_ERR;
+               if (WARN_ON(memchr(dirent->name, '/', dirent->namelen) != NULL))
+                       return FOUND_ERR;
+
+               if (ff->readdir.pos == ctx->pos) {
+                       res = FOUND_SOME;
+                       if (!dir_emit(ctx, dirent->name, dirent->namelen,
+                                     dirent->ino, dirent->type))
+                               return FOUND_ALL;
+                       ctx->pos = dirent->off;
+               }
+               ff->readdir.pos = dirent->off;
+               ff->readdir.cache_off += reclen;
+
+               offset += reclen;
+       }
+
+       return res;
+}
+
+static void fuse_rdc_reset(struct inode *inode)
+{
+       struct fuse_inode *fi = get_fuse_inode(inode);
+
+       fi->rdc.cached = false;
+       fi->rdc.version++;
+       fi->rdc.size = 0;
+       fi->rdc.pos = 0;
+}
+
+#define UNCACHED 1
+
+static int fuse_readdir_cached(struct file *file, struct dir_context *ctx)
+{
+       struct fuse_file *ff = file->private_data;
+       struct inode *inode = file_inode(file);
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_inode *fi = get_fuse_inode(inode);
+       enum fuse_parse_result res;
+       pgoff_t index;
+       unsigned int size;
+       struct page *page;
+       void *addr;
+
+       /* Seeked?  If so, reset the cache stream */
+       if (ff->readdir.pos != ctx->pos) {
+               ff->readdir.pos = 0;
+               ff->readdir.cache_off = 0;
+       }
+
+       /*
+        * We're just about to start reading into the cache or reading the
+        * cache; both cases require an up-to-date mtime value.
+        */
+       if (!ctx->pos && fc->auto_inval_data) {
+               int err = fuse_update_attributes(inode, file);
+
+               if (err)
+                       return err;
+       }
+
+retry:
+       spin_lock(&fi->rdc.lock);
+retry_locked:
+       if (!fi->rdc.cached) {
+               /* Starting cache? Set cache mtime. */
+               if (!ctx->pos && !fi->rdc.size) {
+                       fi->rdc.mtime = inode->i_mtime;
+                       fi->rdc.iversion = inode_query_iversion(inode);
+               }
+               spin_unlock(&fi->rdc.lock);
+               return UNCACHED;
+       }
+       /*
+        * When at the beginning of the directory (i.e. just after opendir(3) or
+        * rewinddir(3)), then need to check whether directory contents have
+        * changed, and reset the cache if so.
+        */
+       if (!ctx->pos) {
+               if (inode_peek_iversion(inode) != fi->rdc.iversion ||
+                   !timespec64_equal(&fi->rdc.mtime, &inode->i_mtime)) {
+                       fuse_rdc_reset(inode);
+                       goto retry_locked;
+               }
+       }
+
+       /*
+        * If cache version changed since the last getdents() call, then reset
+        * the cache stream.
+        */
+       if (ff->readdir.version != fi->rdc.version) {
+               ff->readdir.pos = 0;
+               ff->readdir.cache_off = 0;
+       }
+       /*
+        * If at the beginning of the cache, than reset version to
+        * current.
+        */
+       if (ff->readdir.pos == 0)
+               ff->readdir.version = fi->rdc.version;
+
+       WARN_ON(fi->rdc.size < ff->readdir.cache_off);
+
+       index = ff->readdir.cache_off >> PAGE_SHIFT;
+
+       if (index == (fi->rdc.size >> PAGE_SHIFT))
+               size = fi->rdc.size & ~PAGE_MASK;
+       else
+               size = PAGE_SIZE;
+       spin_unlock(&fi->rdc.lock);
+
+       /* EOF? */
+       if ((ff->readdir.cache_off & ~PAGE_MASK) == size)
+               return 0;
+
+       page = find_get_page_flags(file->f_mapping, index,
+                                  FGP_ACCESSED | FGP_LOCK);
+       spin_lock(&fi->rdc.lock);
+       if (!page) {
+               /*
+                * Uh-oh: page gone missing, cache is useless
+                */
+               if (fi->rdc.version == ff->readdir.version)
+                       fuse_rdc_reset(inode);
+               goto retry_locked;
+       }
+
+       /* Make sure it's still the same version after getting the page. */
+       if (ff->readdir.version != fi->rdc.version) {
+               spin_unlock(&fi->rdc.lock);
+               unlock_page(page);
+               put_page(page);
+               goto retry;
+       }
+       spin_unlock(&fi->rdc.lock);
+
+       /*
+        * Contents of the page are now protected against changing by holding
+        * the page lock.
+        */
+       addr = kmap(page);
+       res = fuse_parse_cache(ff, addr, size, ctx);
+       kunmap(page);
+       unlock_page(page);
+       put_page(page);
+
+       if (res == FOUND_ERR)
+               return -EIO;
+
+       if (res == FOUND_ALL)
+               return 0;
+
+       if (size == PAGE_SIZE) {
+               /* We hit end of page: skip to next page. */
+               ff->readdir.cache_off = ALIGN(ff->readdir.cache_off, PAGE_SIZE);
+               goto retry;
+       }
+
+       /*
+        * End of cache reached.  If found position, then we are done, otherwise
+        * need to fall back to uncached, since the position we were looking for
+        * wasn't in the cache.
+        */
+       return res == FOUND_SOME ? 0 : UNCACHED;
+}
+
+int fuse_readdir(struct file *file, struct dir_context *ctx)
+{
+       struct fuse_file *ff = file->private_data;
+       struct inode *inode = file_inode(file);
+       int err;
+
+       if (is_bad_inode(inode))
+               return -EIO;
+
+       mutex_lock(&ff->readdir.lock);
+
+       err = UNCACHED;
+       if (ff->open_flags & FOPEN_CACHE_DIR)
+               err = fuse_readdir_cached(file, ctx);
+       if (err == UNCACHED)
+               err = fuse_readdir_uncached(file, ctx);
+
+       mutex_unlock(&ff->readdir.lock);
+
+       return err;
+}
index 9a8772465a907a5e320a44c8b6ee7ddf61e87410..896396554bcc1785a4400f6f3886d04f5e696153 100644 (file)
@@ -425,6 +425,10 @@ skip:
        if (new_node) {
                __be32 cnid;
 
+               if (!new_node->parent) {
+                       hfs_btree_inc_height(tree);
+                       new_node->parent = tree->root;
+               }
                fd->bnode = hfs_bnode_find(tree, new_node->parent);
                /* create index key and entry */
                hfs_bnode_read_key(new_node, fd->search_key, 14);
@@ -441,6 +445,7 @@ skip:
                        /* restore search_key */
                        hfs_bnode_read_key(node, fd->search_key, 14);
                }
+               new_node = NULL;
        }
 
        if (!rec && node->parent)
index 374b5688e29e5f9bda46fa3ad58e93fd1f743162..98b96ffb95ed3d71dbf598b9aadc1e4363ce68da 100644 (file)
@@ -220,25 +220,17 @@ static struct hfs_bnode *hfs_bmap_new_bmap(struct hfs_bnode *prev, u32 idx)
        return node;
 }
 
-struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
+/* Make sure @tree has enough space for the @rsvd_nodes */
+int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes)
 {
-       struct hfs_bnode *node, *next_node;
-       struct page **pagep;
-       u32 nidx, idx;
-       unsigned off;
-       u16 off16;
-       u16 len;
-       u8 *data, byte, m;
-       int i;
-
-       while (!tree->free_nodes) {
-               struct inode *inode = tree->inode;
-               u32 count;
-               int res;
+       struct inode *inode = tree->inode;
+       u32 count;
+       int res;
 
+       while (tree->free_nodes < rsvd_nodes) {
                res = hfs_extend_file(inode);
                if (res)
-                       return ERR_PTR(res);
+                       return res;
                HFS_I(inode)->phys_size = inode->i_size =
                                (loff_t)HFS_I(inode)->alloc_blocks *
                                HFS_SB(tree->sb)->alloc_blksz;
@@ -246,9 +238,26 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
                                          tree->sb->s_blocksize_bits;
                inode_set_bytes(inode, inode->i_size);
                count = inode->i_size >> tree->node_size_shift;
-               tree->free_nodes = count - tree->node_count;
+               tree->free_nodes += count - tree->node_count;
                tree->node_count = count;
        }
+       return 0;
+}
+
+struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
+{
+       struct hfs_bnode *node, *next_node;
+       struct page **pagep;
+       u32 nidx, idx;
+       unsigned off;
+       u16 off16;
+       u16 len;
+       u8 *data, byte, m;
+       int i, res;
+
+       res = hfs_bmap_reserve(tree, 1);
+       if (res)
+               return ERR_PTR(res);
 
        nidx = 0;
        node = hfs_bnode_find(tree, nidx);
index c8b252dbb26c0ae75b10e848152ab2b10126587a..dcc2aab1b2c43fefc751c1c0b74fcfddac61257a 100644 (file)
@@ -82,6 +82,7 @@ struct hfs_find_data {
 extern struct hfs_btree *hfs_btree_open(struct super_block *, u32, btree_keycmp);
 extern void hfs_btree_close(struct hfs_btree *);
 extern void hfs_btree_write(struct hfs_btree *);
+extern int hfs_bmap_reserve(struct hfs_btree *, int);
 extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *);
 extern void hfs_bmap_free(struct hfs_bnode *node);
 
index 8a66405b0f8b5abddd78bc7b39b783649a44b687..d365bf0b8c77d66d9a2b34c23470539863e1edfd 100644 (file)
@@ -97,6 +97,14 @@ int hfs_cat_create(u32 cnid, struct inode *dir, const struct qstr *str, struct i
        if (err)
                return err;
 
+       /*
+        * Fail early and avoid ENOSPC during the btree operations. We may
+        * have to split the root node at most once.
+        */
+       err = hfs_bmap_reserve(fd.tree, 2 * fd.tree->depth);
+       if (err)
+               goto err2;
+
        hfs_cat_build_key(sb, fd.search_key, cnid, NULL);
        entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ?
                        HFS_CDR_THD : HFS_CDR_FTH,
@@ -295,6 +303,14 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, const struct qstr *src_name,
                return err;
        dst_fd = src_fd;
 
+       /*
+        * Fail early and avoid ENOSPC during the btree operations. We may
+        * have to split the root node at most once.
+        */
+       err = hfs_bmap_reserve(src_fd.tree, 2 * src_fd.tree->depth);
+       if (err)
+               goto out;
+
        /* find the old dir entry and read the data */
        hfs_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name);
        err = hfs_brec_find(&src_fd);
index 5d01826545809de7de454e2615553fc6a637ce70..263d5028d9d18e8c2db8426a5e12c82635160673 100644 (file)
@@ -117,6 +117,10 @@ static int __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd)
        if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) {
                if (res != -ENOENT)
                        return res;
+               /* Fail early and avoid ENOSPC during the btree operation */
+               res = hfs_bmap_reserve(fd->tree, fd->tree->depth + 1);
+               if (res)
+                       return res;
                hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec));
                HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW);
        } else {
@@ -300,7 +304,7 @@ int hfs_free_fork(struct super_block *sb, struct hfs_cat_file *file, int type)
                return 0;
 
        blocks = 0;
-       for (i = 0; i < 3; extent++, i++)
+       for (i = 0; i < 3; i++)
                blocks += be16_to_cpu(extent[i].count);
 
        res = hfs_free_extents(sb, extent, blocks, blocks);
@@ -341,7 +345,9 @@ int hfs_get_block(struct inode *inode, sector_t block,
        ablock = (u32)block / HFS_SB(sb)->fs_div;
 
        if (block >= HFS_I(inode)->fs_blocks) {
-               if (block > HFS_I(inode)->fs_blocks || !create)
+               if (!create)
+                       return 0;
+               if (block > HFS_I(inode)->fs_blocks)
                        return -EIO;
                if (ablock >= HFS_I(inode)->alloc_blocks) {
                        res = hfs_extend_file(inode);
index a2dfa1b2a89c7982deb26ea0fcd8eae46ac0dbbe..da243c84e93b0bcb15db62e825731db600a020f2 100644 (file)
@@ -642,6 +642,8 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
 
                truncate_setsize(inode, attr->ia_size);
                hfs_file_truncate(inode);
+               inode->i_atime = inode->i_mtime = inode->i_ctime =
+                                                 current_time(inode);
        }
 
        setattr_copy(inode, attr);
index 2bab6b3cdba48da8322e0d1dd1c7a0e4f6f071b6..e6d554476db41cf61f1d850682f2aff0583e9122 100644 (file)
@@ -217,6 +217,11 @@ int hfsplus_create_attr(struct inode *inode,
        if (err)
                goto failed_init_create_attr;
 
+       /* Fail early and avoid ENOSPC during the btree operation */
+       err = hfs_bmap_reserve(fd.tree, fd.tree->depth + 1);
+       if (err)
+               goto failed_create_attr;
+
        if (name) {
                err = hfsplus_attr_build_key(sb, fd.search_key,
                                                inode->i_ino, name);
@@ -313,6 +318,11 @@ int hfsplus_delete_attr(struct inode *inode, const char *name)
        if (err)
                return err;
 
+       /* Fail early and avoid ENOSPC during the btree operation */
+       err = hfs_bmap_reserve(fd.tree, fd.tree->depth);
+       if (err)
+               goto out;
+
        if (name) {
                err = hfsplus_attr_build_key(sb, fd.search_key,
                                                inode->i_ino, name);
index ed8eacb34452f02107c253c3d57a9c89532daa93..1918544a78716e7a0949ecdacb51a6e7822d7b0f 100644 (file)
@@ -429,6 +429,10 @@ skip:
        if (new_node) {
                __be32 cnid;
 
+               if (!new_node->parent) {
+                       hfs_btree_inc_height(tree);
+                       new_node->parent = tree->root;
+               }
                fd->bnode = hfs_bnode_find(tree, new_node->parent);
                /* create index key and entry */
                hfs_bnode_read_key(new_node, fd->search_key, 14);
@@ -445,6 +449,7 @@ skip:
                        /* restore search_key */
                        hfs_bnode_read_key(node, fd->search_key, 14);
                }
+               new_node = NULL;
        }
 
        if (!rec && node->parent)
index de14b2b6881bb73c421bea985873848641c8e9a9..236efe51eca6790e8bf05b679f92683f4c1aa35a 100644 (file)
@@ -342,26 +342,21 @@ static struct hfs_bnode *hfs_bmap_new_bmap(struct hfs_bnode *prev, u32 idx)
        return node;
 }
 
-struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
+/* Make sure @tree has enough space for the @rsvd_nodes */
+int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes)
 {
-       struct hfs_bnode *node, *next_node;
-       struct page **pagep;
-       u32 nidx, idx;
-       unsigned off;
-       u16 off16;
-       u16 len;
-       u8 *data, byte, m;
-       int i;
+       struct inode *inode = tree->inode;
+       struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
+       u32 count;
+       int res;
 
-       while (!tree->free_nodes) {
-               struct inode *inode = tree->inode;
-               struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
-               u32 count;
-               int res;
+       if (rsvd_nodes <= 0)
+               return 0;
 
+       while (tree->free_nodes < rsvd_nodes) {
                res = hfsplus_file_extend(inode, hfs_bnode_need_zeroout(tree));
                if (res)
-                       return ERR_PTR(res);
+                       return res;
                hip->phys_size = inode->i_size =
                        (loff_t)hip->alloc_blocks <<
                                HFSPLUS_SB(tree->sb)->alloc_blksz_shift;
@@ -369,9 +364,26 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
                        hip->alloc_blocks << HFSPLUS_SB(tree->sb)->fs_shift;
                inode_set_bytes(inode, inode->i_size);
                count = inode->i_size >> tree->node_size_shift;
-               tree->free_nodes = count - tree->node_count;
+               tree->free_nodes += count - tree->node_count;
                tree->node_count = count;
        }
+       return 0;
+}
+
+struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
+{
+       struct hfs_bnode *node, *next_node;
+       struct page **pagep;
+       u32 nidx, idx;
+       unsigned off;
+       u16 off16;
+       u16 len;
+       u8 *data, byte, m;
+       int i, res;
+
+       res = hfs_bmap_reserve(tree, 1);
+       if (res)
+               return ERR_PTR(res);
 
        nidx = 0;
        node = hfs_bnode_find(tree, nidx);
index a196369ba779f54b22c012c9803d9e4d0e655c59..35472cba750e1df52b180bf46fc85d01dc299768 100644 (file)
@@ -265,6 +265,14 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
        if (err)
                return err;
 
+       /*
+        * Fail early and avoid ENOSPC during the btree operations. We may
+        * have to split the root node at most once.
+        */
+       err = hfs_bmap_reserve(fd.tree, 2 * fd.tree->depth);
+       if (err)
+               goto err2;
+
        hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid);
        entry_size = hfsplus_fill_cat_thread(sb, &entry,
                S_ISDIR(inode->i_mode) ?
@@ -333,6 +341,14 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, const struct qstr *str)
        if (err)
                return err;
 
+       /*
+        * Fail early and avoid ENOSPC during the btree operations. We may
+        * have to split the root node at most once.
+        */
+       err = hfs_bmap_reserve(fd.tree, 2 * (int)fd.tree->depth - 2);
+       if (err)
+               goto out;
+
        if (!str) {
                int len;
 
@@ -433,6 +449,14 @@ int hfsplus_rename_cat(u32 cnid,
                return err;
        dst_fd = src_fd;
 
+       /*
+        * Fail early and avoid ENOSPC during the btree operations. We may
+        * have to split the root node at most twice.
+        */
+       err = hfs_bmap_reserve(src_fd.tree, 4 * (int)src_fd.tree->depth - 1);
+       if (err)
+               goto out;
+
        /* find the old dir entry and read the data */
        err = hfsplus_cat_build_key(sb, src_fd.search_key,
                        src_dir->i_ino, src_name);
index 8e0f59767694b61ecfc0b57cd25d1a23ea1b94d5..a930ddd156819caf54635655382d27ab5998fab9 100644 (file)
@@ -100,6 +100,10 @@ static int __hfsplus_ext_write_extent(struct inode *inode,
        if (hip->extent_state & HFSPLUS_EXT_NEW) {
                if (res != -ENOENT)
                        return res;
+               /* Fail early and avoid ENOSPC during the btree operation */
+               res = hfs_bmap_reserve(fd->tree, fd->tree->depth + 1);
+               if (res)
+                       return res;
                hfs_brec_insert(fd, hip->cached_extents,
                                sizeof(hfsplus_extent_rec));
                hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
@@ -233,7 +237,9 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
        ablock = iblock >> sbi->fs_shift;
 
        if (iblock >= hip->fs_blocks) {
-               if (iblock > hip->fs_blocks || !create)
+               if (!create)
+                       return 0;
+               if (iblock > hip->fs_blocks)
                        return -EIO;
                if (ablock >= hip->alloc_blocks) {
                        res = hfsplus_file_extend(inode, false);
index 8e039435958a82700dd22aea4cf7b99fa80b6448..dd7ad9f13e3aad58f9cd1552b08a67f95def09bc 100644 (file)
@@ -311,6 +311,7 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
 #define hfs_btree_open hfsplus_btree_open
 #define hfs_btree_close hfsplus_btree_close
 #define hfs_btree_write hfsplus_btree_write
+#define hfs_bmap_reserve hfsplus_bmap_reserve
 #define hfs_bmap_alloc hfsplus_bmap_alloc
 #define hfs_bmap_free hfsplus_bmap_free
 #define hfs_bnode_read hfsplus_bnode_read
@@ -395,6 +396,7 @@ u32 hfsplus_calc_btree_clump_size(u32 block_size, u32 node_size, u64 sectors,
 struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id);
 void hfs_btree_close(struct hfs_btree *tree);
 int hfs_btree_write(struct hfs_btree *tree);
+int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes);
 struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree);
 void hfs_bmap_free(struct hfs_bnode *node);
 
index 8e9427a42b8195e95c77fab60eae4e84e8b51674..d7ab9d8c4b674380f6aa9470910e860dd61cc87a 100644 (file)
@@ -261,6 +261,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
                }
                truncate_setsize(inode, attr->ia_size);
                hfsplus_file_truncate(inode);
+               inode->i_mtime = inode->i_ctime = current_time(inode);
        }
 
        setattr_copy(inode, attr);
index 9b808986d44043fae8b4bee0ff40644ef3598555..9e198f00b64c6f59e7e4a50b1bc8ddf4ec73cdbf 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/swap.h>
 #include <linux/security.h>
 #include <linux/cdev.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/fsnotify.h>
 #include <linux/mount.h>
 #include <linux/posix_acl.h>
index d35cd6be067592acd7f2bc8ca50f0dd869e817e5..93fb7cf0b92b631358cf36eab60d5947cc0312a7 100644 (file)
@@ -341,7 +341,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
        };
        struct lockd_net *ln = net_generic(net, lockd_net_id);
 
-       dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__,
+       dprintk("lockd: %s(host='%.*s', vers=%u, proto=%s)\n", __func__,
                        (int)hostname_len, hostname, rqstp->rq_vers,
                        (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp"));
 
index d86830c86ce8199ab0772f146f0a85377a441f92..98d27da43304706f4c8dcc572a397d89ff34cef2 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/uaccess.h>
 #include <linux/proc_ns.h>
 #include <linux/magic.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/task_work.h>
 #include <linux/sched/task.h>
 
index 060c658eab6600ebb0cf2dfa069d70d4e0f152a0..a7d3df85736dfba49c461ed54a17b5db0d3bfa44 100644 (file)
@@ -65,6 +65,7 @@ struct nfs_dns_ent {
 
        struct sockaddr_storage addr;
        size_t addrlen;
+       struct rcu_head rcu_head;
 };
 
 
@@ -101,15 +102,23 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
        }
 }
 
-static void nfs_dns_ent_put(struct kref *ref)
+static void nfs_dns_ent_free_rcu(struct rcu_head *head)
 {
        struct nfs_dns_ent *item;
 
-       item = container_of(ref, struct nfs_dns_ent, h.ref);
+       item = container_of(head, struct nfs_dns_ent, rcu_head);
        kfree(item->hostname);
        kfree(item);
 }
 
+static void nfs_dns_ent_put(struct kref *ref)
+{
+       struct nfs_dns_ent *item;
+
+       item = container_of(ref, struct nfs_dns_ent, h.ref);
+       call_rcu(&item->rcu_head, nfs_dns_ent_free_rcu);
+}
+
 static struct cache_head *nfs_dns_ent_alloc(void)
 {
        struct nfs_dns_ent *item = kmalloc(sizeof(*item), GFP_KERNEL);
@@ -195,7 +204,7 @@ static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd,
 {
        struct cache_head *ch;
 
-       ch = sunrpc_cache_lookup(cd,
+       ch = sunrpc_cache_lookup_rcu(cd,
                        &key->h,
                        nfs_dns_hash(key));
        if (!ch)
index b7559c6f2b9767609f0832f0fb5e0fb80d51fce0..4a98537efb0fd3bfb8b6936624f36cbfa1f6d1d7 100644 (file)
  * is much larger than a sockaddr_in6.
  */
 struct svc_cacherep {
-       struct list_head        c_lru;
+       struct {
+               /* Keep often-read xid, csum in the same cache line: */
+               __be32                  k_xid;
+               __wsum                  k_csum;
+               u32                     k_proc;
+               u32                     k_prot;
+               u32                     k_vers;
+               unsigned int            k_len;
+               struct sockaddr_in6     k_addr;
+       } c_key;
 
+       struct rb_node          c_node;
+       struct list_head        c_lru;
        unsigned char           c_state,        /* unused, inprog, done */
                                c_type,         /* status, buffer */
                                c_secure : 1;   /* req came from port < 1024 */
-       struct sockaddr_in6     c_addr;
-       __be32                  c_xid;
-       u32                     c_prot;
-       u32                     c_proc;
-       u32                     c_vers;
-       unsigned int            c_len;
-       __wsum                  c_csum;
        unsigned long           c_timestamp;
        union {
                struct kvec     u_vec;
index a1143f7c220153c0809cb8dd43da895a685fe98b..802993d8912f79f6a70ab1661ff13ea41815bbbf 100644 (file)
@@ -46,7 +46,7 @@ static void expkey_put(struct kref *ref)
            !test_bit(CACHE_NEGATIVE, &key->h.flags))
                path_put(&key->ek_path);
        auth_domain_put(key->ek_client);
-       kfree(key);
+       kfree_rcu(key, ek_rcu);
 }
 
 static void expkey_request(struct cache_detail *cd,
@@ -265,7 +265,7 @@ svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *item)
        struct cache_head *ch;
        int hash = svc_expkey_hash(item);
 
-       ch = sunrpc_cache_lookup(cd, &item->h, hash);
+       ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
        if (ch)
                return container_of(ch, struct svc_expkey, h);
        else
@@ -314,7 +314,7 @@ static void svc_export_put(struct kref *ref)
        auth_domain_put(exp->ex_client);
        nfsd4_fslocs_free(&exp->ex_fslocs);
        kfree(exp->ex_uuid);
-       kfree(exp);
+       kfree_rcu(exp, ex_rcu);
 }
 
 static void svc_export_request(struct cache_detail *cd,
@@ -780,7 +780,7 @@ svc_export_lookup(struct svc_export *exp)
        struct cache_head *ch;
        int hash = svc_export_hash(exp);
 
-       ch = sunrpc_cache_lookup(exp->cd, &exp->h, hash);
+       ch = sunrpc_cache_lookup_rcu(exp->cd, &exp->h, hash);
        if (ch)
                return container_of(ch, struct svc_export, h);
        else
@@ -1216,9 +1216,9 @@ static int e_show(struct seq_file *m, void *p)
 }
 
 const struct seq_operations nfs_exports_op = {
-       .start  = cache_seq_start,
-       .next   = cache_seq_next,
-       .stop   = cache_seq_stop,
+       .start  = cache_seq_start_rcu,
+       .next   = cache_seq_next_rcu,
+       .stop   = cache_seq_stop_rcu,
        .show   = e_show,
 };
 
index c8b74126ddaa86c4de9ab9233f3ce3552d7e5edf..e7daa1f246f0866beee438abe96533108a978062 100644 (file)
@@ -61,6 +61,7 @@ struct svc_export {
        u32                     ex_layout_types;
        struct nfsd4_deviceid_map *ex_devid_map;
        struct cache_detail     *cd;
+       struct rcu_head         ex_rcu;
 };
 
 /* an "export key" (expkey) maps a filehandlefragement to an
@@ -75,6 +76,7 @@ struct svc_expkey {
        u32                     ek_fsid[6];
 
        struct path             ek_path;
+       struct rcu_head         ek_rcu;
 };
 
 #define EX_ISSYNC(exp)         (!((exp)->ex_flags & NFSEXP_ASYNC))
index 426f550056974d9d58b2868239fce3a74d0fc383..32cb8c027483e943d930117ba037c572597a7ee4 100644 (file)
@@ -123,6 +123,14 @@ struct nfsd_net {
 
        wait_queue_head_t ntf_wq;
        atomic_t ntf_refcnt;
+
+       /*
+        * clientid and stateid data for construction of net unique COPY
+        * stateids.
+        */
+       u32             s2s_cp_cl_id;
+       struct idr      s2s_cp_stateids;
+       spinlock_t      s2s_cp_lock;
 };
 
 /* Simple check to find out if a given net was properly initialized */
index 601bf33c26a0bbdc036bb7b2a195fc07ccfc7fe8..25987bcdf96f81f1611db1dc9ced9d44ff1809c6 100644 (file)
@@ -39,6 +39,7 @@
 #include "state.h"
 #include "netns.h"
 #include "xdr4cb.h"
+#include "xdr4.h"
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
@@ -105,6 +106,7 @@ enum nfs_cb_opnum4 {
        OP_CB_WANTS_CANCELLED           = 12,
        OP_CB_NOTIFY_LOCK               = 13,
        OP_CB_NOTIFY_DEVICEID           = 14,
+       OP_CB_OFFLOAD                   = 15,
        OP_CB_ILLEGAL                   = 10044
 };
 
@@ -682,6 +684,101 @@ static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp,
        return decode_cb_op_status(xdr, OP_CB_NOTIFY_LOCK, &cb->cb_status);
 }
 
+/*
+ * struct write_response4 {
+ *     stateid4        wr_callback_id<1>;
+ *     length4         wr_count;
+ *     stable_how4     wr_committed;
+ *     verifier4       wr_writeverf;
+ * };
+ * union offload_info4 switch (nfsstat4 coa_status) {
+ *     case NFS4_OK:
+ *             write_response4 coa_resok4;
+ *     default:
+ *     length4         coa_bytes_copied;
+ * };
+ * struct CB_OFFLOAD4args {
+ *     nfs_fh4         coa_fh;
+ *     stateid4        coa_stateid;
+ *     offload_info4   coa_offload_info;
+ * };
+ */
+static void encode_offload_info4(struct xdr_stream *xdr,
+                                __be32 nfserr,
+                                const struct nfsd4_copy *cp)
+{
+       __be32 *p;
+
+       p = xdr_reserve_space(xdr, 4);
+       *p++ = nfserr;
+       if (!nfserr) {
+               p = xdr_reserve_space(xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE);
+               p = xdr_encode_empty_array(p);
+               p = xdr_encode_hyper(p, cp->cp_res.wr_bytes_written);
+               *p++ = cpu_to_be32(cp->cp_res.wr_stable_how);
+               p = xdr_encode_opaque_fixed(p, cp->cp_res.wr_verifier.data,
+                                           NFS4_VERIFIER_SIZE);
+       } else {
+               p = xdr_reserve_space(xdr, 8);
+               /* We always return success if bytes were written */
+               p = xdr_encode_hyper(p, 0);
+       }
+}
+
+static void encode_cb_offload4args(struct xdr_stream *xdr,
+                                  __be32 nfserr,
+                                  const struct knfsd_fh *fh,
+                                  const struct nfsd4_copy *cp,
+                                  struct nfs4_cb_compound_hdr *hdr)
+{
+       __be32 *p;
+
+       p = xdr_reserve_space(xdr, 4);
+       *p++ = cpu_to_be32(OP_CB_OFFLOAD);
+       encode_nfs_fh4(xdr, fh);
+       encode_stateid4(xdr, &cp->cp_res.cb_stateid);
+       encode_offload_info4(xdr, nfserr, cp);
+
+       hdr->nops++;
+}
+
+static void nfs4_xdr_enc_cb_offload(struct rpc_rqst *req,
+                                   struct xdr_stream *xdr,
+                                   const void *data)
+{
+       const struct nfsd4_callback *cb = data;
+       const struct nfsd4_copy *cp =
+               container_of(cb, struct nfsd4_copy, cp_cb);
+       struct nfs4_cb_compound_hdr hdr = {
+               .ident = 0,
+               .minorversion = cb->cb_clp->cl_minorversion,
+       };
+
+       encode_cb_compound4args(xdr, &hdr);
+       encode_cb_sequence4args(xdr, cb, &hdr);
+       encode_cb_offload4args(xdr, cp->nfserr, &cp->fh, cp, &hdr);
+       encode_cb_nops(&hdr);
+}
+
+static int nfs4_xdr_dec_cb_offload(struct rpc_rqst *rqstp,
+                                  struct xdr_stream *xdr,
+                                  void *data)
+{
+       struct nfsd4_callback *cb = data;
+       struct nfs4_cb_compound_hdr hdr;
+       int status;
+
+       status = decode_cb_compound4res(xdr, &hdr);
+       if (unlikely(status))
+               return status;
+
+       if (cb) {
+               status = decode_cb_sequence4res(xdr, cb);
+               if (unlikely(status || cb->cb_seq_status))
+                       return status;
+       }
+       return decode_cb_op_status(xdr, OP_CB_OFFLOAD, &cb->cb_status);
+}
 /*
  * RPC procedure tables
  */
@@ -703,6 +800,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
        PROC(CB_LAYOUT, COMPOUND,       cb_layout,      cb_layout),
 #endif
        PROC(CB_NOTIFY_LOCK,    COMPOUND,       cb_notify_lock, cb_notify_lock),
+       PROC(CB_OFFLOAD,        COMPOUND,       cb_offload,     cb_offload),
 };
 
 static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)];
index a5bb76593ce72c280ddbd8e5957beddea49ec413..bf137fec33ff916558ca7c95e2662a46c5880163 100644 (file)
@@ -65,6 +65,7 @@ struct ent {
        u32               id;
        char              name[IDMAP_NAMESZ];
        char              authname[IDMAP_NAMESZ];
+       struct rcu_head   rcu_head;
 };
 
 /* Common entry handling */
@@ -89,7 +90,7 @@ static void
 ent_put(struct kref *ref)
 {
        struct ent *map = container_of(ref, struct ent, h.ref);
-       kfree(map);
+       kfree_rcu(map, rcu_head);
 }
 
 static struct cache_head *
@@ -264,8 +265,8 @@ out:
 static struct ent *
 idtoname_lookup(struct cache_detail *cd, struct ent *item)
 {
-       struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h,
-                                                   idtoname_hash(item));
+       struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
+                                                       idtoname_hash(item));
        if (ch)
                return container_of(ch, struct ent, h);
        else
@@ -422,8 +423,8 @@ out:
 static struct ent *
 nametoid_lookup(struct cache_detail *cd, struct ent *item)
 {
-       struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h,
-                                                   nametoid_hash(item));
+       struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
+                                                       nametoid_hash(item));
        if (ch)
                return container_of(ch, struct ent, h);
        else
index b7bc6e1a85ac3d1472b7867ccd75b5819126f2c8..edff074d38c75c19a06a6ae5c634ba1fd1688d98 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/file.h>
 #include <linux/falloc.h>
 #include <linux/slab.h>
+#include <linux/kthread.h>
 
 #include "idmap.h"
 #include "cache.h"
@@ -1089,36 +1090,254 @@ out:
        return status;
 }
 
+void nfs4_put_copy(struct nfsd4_copy *copy)
+{
+       if (!refcount_dec_and_test(&copy->refcount))
+               return;
+       kfree(copy);
+}
+
+static bool
+check_and_set_stop_copy(struct nfsd4_copy *copy)
+{
+       bool value;
+
+       spin_lock(&copy->cp_clp->async_lock);
+       value = copy->stopped;
+       if (!copy->stopped)
+               copy->stopped = true;
+       spin_unlock(&copy->cp_clp->async_lock);
+       return value;
+}
+
+static void nfsd4_stop_copy(struct nfsd4_copy *copy)
+{
+       /* only 1 thread should stop the copy */
+       if (!check_and_set_stop_copy(copy))
+               kthread_stop(copy->copy_task);
+       nfs4_put_copy(copy);
+}
+
+static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
+{
+       struct nfsd4_copy *copy = NULL;
+
+       spin_lock(&clp->async_lock);
+       if (!list_empty(&clp->async_copies)) {
+               copy = list_first_entry(&clp->async_copies, struct nfsd4_copy,
+                                       copies);
+               refcount_inc(&copy->refcount);
+       }
+       spin_unlock(&clp->async_lock);
+       return copy;
+}
+
+void nfsd4_shutdown_copy(struct nfs4_client *clp)
+{
+       struct nfsd4_copy *copy;
+
+       while ((copy = nfsd4_get_copy(clp)) != NULL)
+               nfsd4_stop_copy(copy);
+}
+
+static void nfsd4_cb_offload_release(struct nfsd4_callback *cb)
+{
+       struct nfsd4_copy *copy = container_of(cb, struct nfsd4_copy, cp_cb);
+
+       nfs4_put_copy(copy);
+}
+
+static int nfsd4_cb_offload_done(struct nfsd4_callback *cb,
+                                struct rpc_task *task)
+{
+       return 1;
+}
+
+static const struct nfsd4_callback_ops nfsd4_cb_offload_ops = {
+       .release = nfsd4_cb_offload_release,
+       .done = nfsd4_cb_offload_done
+};
+
+static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync)
+{
+       copy->cp_res.wr_stable_how = NFS_UNSTABLE;
+       copy->cp_synchronous = sync;
+       gen_boot_verifier(&copy->cp_res.wr_verifier, copy->cp_clp->net);
+}
+
+static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
+{
+       ssize_t bytes_copied = 0;
+       size_t bytes_total = copy->cp_count;
+       u64 src_pos = copy->cp_src_pos;
+       u64 dst_pos = copy->cp_dst_pos;
+
+       do {
+               if (kthread_should_stop())
+                       break;
+               bytes_copied = nfsd_copy_file_range(copy->file_src, src_pos,
+                               copy->file_dst, dst_pos, bytes_total);
+               if (bytes_copied <= 0)
+                       break;
+               bytes_total -= bytes_copied;
+               copy->cp_res.wr_bytes_written += bytes_copied;
+               src_pos += bytes_copied;
+               dst_pos += bytes_copied;
+       } while (bytes_total > 0 && !copy->cp_synchronous);
+       return bytes_copied;
+}
+
+static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync)
+{
+       __be32 status;
+       ssize_t bytes;
+
+       bytes = _nfsd_copy_file_range(copy);
+       /* for async copy, we ignore the error, client can always retry
+        * to get the error
+        */
+       if (bytes < 0 && !copy->cp_res.wr_bytes_written)
+               status = nfserrno(bytes);
+       else {
+               nfsd4_init_copy_res(copy, sync);
+               status = nfs_ok;
+       }
+
+       fput(copy->file_src);
+       fput(copy->file_dst);
+       return status;
+}
+
+static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst)
+{
+       dst->cp_src_pos = src->cp_src_pos;
+       dst->cp_dst_pos = src->cp_dst_pos;
+       dst->cp_count = src->cp_count;
+       dst->cp_synchronous = src->cp_synchronous;
+       memcpy(&dst->cp_res, &src->cp_res, sizeof(src->cp_res));
+       memcpy(&dst->fh, &src->fh, sizeof(src->fh));
+       dst->cp_clp = src->cp_clp;
+       dst->file_dst = get_file(src->file_dst);
+       dst->file_src = get_file(src->file_src);
+       memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid));
+}
+
+static void cleanup_async_copy(struct nfsd4_copy *copy)
+{
+       nfs4_free_cp_state(copy);
+       fput(copy->file_dst);
+       fput(copy->file_src);
+       spin_lock(&copy->cp_clp->async_lock);
+       list_del(&copy->copies);
+       spin_unlock(&copy->cp_clp->async_lock);
+       nfs4_put_copy(copy);
+}
+
+static int nfsd4_do_async_copy(void *data)
+{
+       struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
+       struct nfsd4_copy *cb_copy;
+
+       copy->nfserr = nfsd4_do_copy(copy, 0);
+       cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
+       if (!cb_copy)
+               goto out;
+       memcpy(&cb_copy->cp_res, &copy->cp_res, sizeof(copy->cp_res));
+       cb_copy->cp_clp = copy->cp_clp;
+       cb_copy->nfserr = copy->nfserr;
+       memcpy(&cb_copy->fh, &copy->fh, sizeof(copy->fh));
+       nfsd4_init_cb(&cb_copy->cp_cb, cb_copy->cp_clp,
+                       &nfsd4_cb_offload_ops, NFSPROC4_CLNT_CB_OFFLOAD);
+       nfsd4_run_cb(&cb_copy->cp_cb);
+out:
+       cleanup_async_copy(copy);
+       return 0;
+}
+
 static __be32
 nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                union nfsd4_op_u *u)
 {
        struct nfsd4_copy *copy = &u->copy;
-       struct file *src, *dst;
        __be32 status;
-       ssize_t bytes;
+       struct nfsd4_copy *async_copy = NULL;
 
-       status = nfsd4_verify_copy(rqstp, cstate, &copy->cp_src_stateid, &src,
-                                  &copy->cp_dst_stateid, &dst);
+       status = nfsd4_verify_copy(rqstp, cstate, &copy->cp_src_stateid,
+                                  &copy->file_src, &copy->cp_dst_stateid,
+                                  &copy->file_dst);
        if (status)
                goto out;
 
-       bytes = nfsd_copy_file_range(src, copy->cp_src_pos,
-                       dst, copy->cp_dst_pos, copy->cp_count);
+       copy->cp_clp = cstate->clp;
+       memcpy(&copy->fh, &cstate->current_fh.fh_handle,
+               sizeof(struct knfsd_fh));
+       if (!copy->cp_synchronous) {
+               struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
-       if (bytes < 0)
-               status = nfserrno(bytes);
-       else {
-               copy->cp_res.wr_bytes_written = bytes;
-               copy->cp_res.wr_stable_how = NFS_UNSTABLE;
-               copy->cp_synchronous = 1;
-               gen_boot_verifier(&copy->cp_res.wr_verifier, SVC_NET(rqstp));
+               status = nfserrno(-ENOMEM);
+               async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
+               if (!async_copy)
+                       goto out;
+               if (!nfs4_init_cp_state(nn, copy)) {
+                       kfree(async_copy);
+                       goto out;
+               }
+               refcount_set(&async_copy->refcount, 1);
+               memcpy(&copy->cp_res.cb_stateid, &copy->cp_stateid,
+                       sizeof(copy->cp_stateid));
+               dup_copy_fields(copy, async_copy);
+               async_copy->copy_task = kthread_create(nfsd4_do_async_copy,
+                               async_copy, "%s", "copy thread");
+               if (IS_ERR(async_copy->copy_task))
+                       goto out_err;
+               spin_lock(&async_copy->cp_clp->async_lock);
+               list_add(&async_copy->copies,
+                               &async_copy->cp_clp->async_copies);
+               spin_unlock(&async_copy->cp_clp->async_lock);
+               wake_up_process(async_copy->copy_task);
                status = nfs_ok;
+       } else
+               status = nfsd4_do_copy(copy, 1);
+out:
+       return status;
+out_err:
+       cleanup_async_copy(async_copy);
+       goto out;
+}
+
+struct nfsd4_copy *
+find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
+{
+       struct nfsd4_copy *copy;
+
+       spin_lock(&clp->async_lock);
+       list_for_each_entry(copy, &clp->async_copies, copies) {
+               if (memcmp(&copy->cp_stateid, stateid, NFS4_STATEID_SIZE))
+                       continue;
+               refcount_inc(&copy->refcount);
+               spin_unlock(&clp->async_lock);
+               return copy;
        }
+       spin_unlock(&clp->async_lock);
+       return NULL;
+}
+
+static __be32
+nfsd4_offload_cancel(struct svc_rqst *rqstp,
+                    struct nfsd4_compound_state *cstate,
+                    union nfsd4_op_u *u)
+{
+       struct nfsd4_offload_status *os = &u->offload_status;
+       __be32 status = 0;
+       struct nfsd4_copy *copy;
+       struct nfs4_client *clp = cstate->clp;
+
+       copy = find_async_copy(clp, &os->stateid);
+       if (copy)
+               nfsd4_stop_copy(copy);
+       else
+               status = nfserr_bad_stateid;
 
-       fput(src);
-       fput(dst);
-out:
        return status;
 }
 
@@ -1144,6 +1363,25 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        fput(file);
        return status;
 }
+static __be32
+nfsd4_offload_status(struct svc_rqst *rqstp,
+                    struct nfsd4_compound_state *cstate,
+                    union nfsd4_op_u *u)
+{
+       struct nfsd4_offload_status *os = &u->offload_status;
+       __be32 status = 0;
+       struct nfsd4_copy *copy;
+       struct nfs4_client *clp = cstate->clp;
+
+       copy = find_async_copy(clp, &os->stateid);
+       if (copy) {
+               os->count = copy->cp_res.wr_bytes_written;
+               nfs4_put_copy(copy);
+       } else
+               status = nfserr_bad_stateid;
+
+       return status;
+}
 
 static __be32
 nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
@@ -2047,6 +2285,14 @@ static inline u32 nfsd4_copy_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
                1 /* cr_synchronous */) * sizeof(__be32);
 }
 
+static inline u32 nfsd4_offload_status_rsize(struct svc_rqst *rqstp,
+                                            struct nfsd4_op *op)
+{
+       return (op_encode_hdr_size +
+               2 /* osr_count */ +
+               1 /* osr_complete<1> optional 0 for now */) * sizeof(__be32);
+}
+
 #ifdef CONFIG_NFSD_PNFS
 static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
 {
@@ -2460,6 +2706,17 @@ static const struct nfsd4_operation nfsd4_ops[] = {
                .op_name = "OP_SEEK",
                .op_rsize_bop = nfsd4_seek_rsize,
        },
+       [OP_OFFLOAD_STATUS] = {
+               .op_func = nfsd4_offload_status,
+               .op_name = "OP_OFFLOAD_STATUS",
+               .op_rsize_bop = nfsd4_offload_status_rsize,
+       },
+       [OP_OFFLOAD_CANCEL] = {
+               .op_func = nfsd4_offload_cancel,
+               .op_flags = OP_MODIFIES_SOMETHING,
+               .op_name = "OP_OFFLOAD_CANCEL",
+               .op_rsize_bop = nfsd4_only_status_rsize,
+       },
 };
 
 /**
index b0ca0efd287510417387fe916ea9668c587ddec1..f093fbe471338b06a2d544ebe00983cb065968fa 100644 (file)
@@ -713,6 +713,36 @@ out_free:
        return NULL;
 }
 
+/*
+ * Create a unique stateid_t to represent each COPY.
+ */
+int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy)
+{
+       int new_id;
+
+       idr_preload(GFP_KERNEL);
+       spin_lock(&nn->s2s_cp_lock);
+       new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, copy, 0, 0, GFP_NOWAIT);
+       spin_unlock(&nn->s2s_cp_lock);
+       idr_preload_end();
+       if (new_id < 0)
+               return 0;
+       copy->cp_stateid.si_opaque.so_id = new_id;
+       copy->cp_stateid.si_opaque.so_clid.cl_boot = nn->boot_time;
+       copy->cp_stateid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id;
+       return 1;
+}
+
+void nfs4_free_cp_state(struct nfsd4_copy *copy)
+{
+       struct nfsd_net *nn;
+
+       nn = net_generic(copy->cp_clp->net, nfsd_net_id);
+       spin_lock(&nn->s2s_cp_lock);
+       idr_remove(&nn->s2s_cp_stateids, copy->cp_stateid.si_opaque.so_id);
+       spin_unlock(&nn->s2s_cp_lock);
+}
+
 static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
 {
        struct nfs4_stid *stid;
@@ -1827,6 +1857,8 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
 #ifdef CONFIG_NFSD_PNFS
        INIT_LIST_HEAD(&clp->cl_lo_states);
 #endif
+       INIT_LIST_HEAD(&clp->async_copies);
+       spin_lock_init(&clp->async_lock);
        spin_lock_init(&clp->cl_lock);
        rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
        return clp;
@@ -1942,6 +1974,7 @@ __destroy_client(struct nfs4_client *clp)
                }
        }
        nfsd4_return_all_client_layouts(clp);
+       nfsd4_shutdown_copy(clp);
        nfsd4_shutdown_callback(clp);
        if (clp->cl_cb_conn.cb_xprt)
                svc_xprt_put(clp->cl_cb_conn.cb_xprt);
@@ -2475,7 +2508,8 @@ static bool client_has_state(struct nfs4_client *clp)
                || !list_empty(&clp->cl_lo_states)
 #endif
                || !list_empty(&clp->cl_delegations)
-               || !list_empty(&clp->cl_sessions);
+               || !list_empty(&clp->cl_sessions)
+               || !list_empty(&clp->async_copies);
 }
 
 __be32
@@ -4364,7 +4398,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
 
        fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
        if (!fl)
-               goto out_stid;
+               goto out_clnt_odstate;
 
        status = vfs_setlease(fp->fi_deleg_file, fl->fl_type, &fl, NULL);
        if (fl)
@@ -4389,7 +4423,6 @@ out_unlock:
        vfs_setlease(fp->fi_deleg_file, F_UNLCK, NULL, (void **)&dp);
 out_clnt_odstate:
        put_clnt_odstate(dp->dl_clnt_odstate);
-out_stid:
        nfs4_put_stid(&dp->dl_stid);
 out_delegees:
        put_deleg_file(fp);
@@ -7161,6 +7194,8 @@ static int nfs4_state_create_net(struct net *net)
        INIT_LIST_HEAD(&nn->close_lru);
        INIT_LIST_HEAD(&nn->del_recall_lru);
        spin_lock_init(&nn->client_lock);
+       spin_lock_init(&nn->s2s_cp_lock);
+       idr_init(&nn->s2s_cp_stateids);
 
        spin_lock_init(&nn->blocked_locks_lock);
        INIT_LIST_HEAD(&nn->blocked_locks_lru);
index 418fa9c78186b6b6f5d36ced347d1255ce2505fe..3de42a7290939eac692cc57b66d4e515576641ec 100644 (file)
@@ -1767,6 +1767,13 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
        DECODE_TAIL;
 }
 
+static __be32
+nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
+                           struct nfsd4_offload_status *os)
+{
+       return nfsd4_decode_stateid(argp, &os->stateid);
+}
+
 static __be32
 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 {
@@ -1873,8 +1880,8 @@ static const nfsd4_dec nfsd4_dec_ops[] = {
        [OP_IO_ADVISE]          = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_LAYOUTERROR]        = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_LAYOUTSTATS]        = (nfsd4_dec)nfsd4_decode_notsupp,
-       [OP_OFFLOAD_CANCEL]     = (nfsd4_dec)nfsd4_decode_notsupp,
-       [OP_OFFLOAD_STATUS]     = (nfsd4_dec)nfsd4_decode_notsupp,
+       [OP_OFFLOAD_CANCEL]     = (nfsd4_dec)nfsd4_decode_offload_status,
+       [OP_OFFLOAD_STATUS]     = (nfsd4_dec)nfsd4_decode_offload_status,
        [OP_READ_PLUS]          = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_SEEK]               = (nfsd4_dec)nfsd4_decode_seek,
        [OP_WRITE_SAME]         = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -4224,15 +4231,27 @@ nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
 #endif /* CONFIG_NFSD_PNFS */
 
 static __be32
-nfsd42_encode_write_res(struct nfsd4_compoundres *resp, struct nfsd42_write_res *write)
+nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
+               struct nfsd42_write_res *write, bool sync)
 {
        __be32 *p;
+       p = xdr_reserve_space(&resp->xdr, 4);
+       if (!p)
+               return nfserr_resource;
 
-       p = xdr_reserve_space(&resp->xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE);
+       if (sync)
+               *p++ = cpu_to_be32(0);
+       else {
+               __be32 nfserr;
+               *p++ = cpu_to_be32(1);
+               nfserr = nfsd4_encode_stateid(&resp->xdr, &write->cb_stateid);
+               if (nfserr)
+                       return nfserr;
+       }
+       p = xdr_reserve_space(&resp->xdr, 8 + 4 + NFS4_VERIFIER_SIZE);
        if (!p)
                return nfserr_resource;
 
-       *p++ = cpu_to_be32(0);
        p = xdr_encode_hyper(p, write->wr_bytes_written);
        *p++ = cpu_to_be32(write->wr_stable_how);
        p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
@@ -4246,7 +4265,8 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
 {
        __be32 *p;
 
-       nfserr = nfsd42_encode_write_res(resp, &copy->cp_res);
+       nfserr = nfsd42_encode_write_res(resp, &copy->cp_res,
+                       copy->cp_synchronous);
        if (nfserr)
                return nfserr;
 
@@ -4256,6 +4276,22 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
        return 0;
 }
 
+static __be32
+nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
+                           struct nfsd4_offload_status *os)
+{
+       struct xdr_stream *xdr = &resp->xdr;
+       __be32 *p;
+
+       p = xdr_reserve_space(xdr, 8 + 4);
+       if (!p)
+               return nfserr_resource;
+       p = xdr_encode_hyper(p, os->count);
+       *p++ = cpu_to_be32(0);
+
+       return nfserr;
+}
+
 static __be32
 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
                  struct nfsd4_seek *seek)
@@ -4359,7 +4395,7 @@ static const nfsd4_enc nfsd4_enc_ops[] = {
        [OP_LAYOUTERROR]        = (nfsd4_enc)nfsd4_encode_noop,
        [OP_LAYOUTSTATS]        = (nfsd4_enc)nfsd4_encode_noop,
        [OP_OFFLOAD_CANCEL]     = (nfsd4_enc)nfsd4_encode_noop,
-       [OP_OFFLOAD_STATUS]     = (nfsd4_enc)nfsd4_encode_noop,
+       [OP_OFFLOAD_STATUS]     = (nfsd4_enc)nfsd4_encode_offload_status,
        [OP_READ_PLUS]          = (nfsd4_enc)nfsd4_encode_noop,
        [OP_SEEK]               = (nfsd4_enc)nfsd4_encode_seek,
        [OP_WRITE_SAME]         = (nfsd4_enc)nfsd4_encode_noop,
index dbdeb9d6af0392e3017b1ed73feebc993397c269..e2fe0e9ce0df08973e400db9754c842005ace49a 100644 (file)
@@ -30,6 +30,7 @@
 #define TARGET_BUCKET_SIZE     64
 
 struct nfsd_drc_bucket {
+       struct rb_root rb_head;
        struct list_head lru_head;
        spinlock_t cache_lock;
 };
@@ -121,7 +122,7 @@ nfsd_cache_hash(__be32 xid)
 }
 
 static struct svc_cacherep *
-nfsd_reply_cache_alloc(void)
+nfsd_reply_cache_alloc(struct svc_rqst *rqstp, __wsum csum)
 {
        struct svc_cacherep     *rp;
 
@@ -129,21 +130,35 @@ nfsd_reply_cache_alloc(void)
        if (rp) {
                rp->c_state = RC_UNUSED;
                rp->c_type = RC_NOCACHE;
+               RB_CLEAR_NODE(&rp->c_node);
                INIT_LIST_HEAD(&rp->c_lru);
+
+               memset(&rp->c_key, 0, sizeof(rp->c_key));
+               rp->c_key.k_xid = rqstp->rq_xid;
+               rp->c_key.k_proc = rqstp->rq_proc;
+               rpc_copy_addr((struct sockaddr *)&rp->c_key.k_addr, svc_addr(rqstp));
+               rpc_set_port((struct sockaddr *)&rp->c_key.k_addr, rpc_get_port(svc_addr(rqstp)));
+               rp->c_key.k_prot = rqstp->rq_prot;
+               rp->c_key.k_vers = rqstp->rq_vers;
+               rp->c_key.k_len = rqstp->rq_arg.len;
+               rp->c_key.k_csum = csum;
        }
        return rp;
 }
 
 static void
-nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
+nfsd_reply_cache_free_locked(struct nfsd_drc_bucket *b, struct svc_cacherep *rp)
 {
        if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) {
                drc_mem_usage -= rp->c_replvec.iov_len;
                kfree(rp->c_replvec.iov_base);
        }
-       list_del(&rp->c_lru);
-       atomic_dec(&num_drc_entries);
-       drc_mem_usage -= sizeof(*rp);
+       if (rp->c_state != RC_UNUSED) {
+               rb_erase(&rp->c_node, &b->rb_head);
+               list_del(&rp->c_lru);
+               atomic_dec(&num_drc_entries);
+               drc_mem_usage -= sizeof(*rp);
+       }
        kmem_cache_free(drc_slab, rp);
 }
 
@@ -151,7 +166,7 @@ static void
 nfsd_reply_cache_free(struct nfsd_drc_bucket *b, struct svc_cacherep *rp)
 {
        spin_lock(&b->cache_lock);
-       nfsd_reply_cache_free_locked(rp);
+       nfsd_reply_cache_free_locked(b, rp);
        spin_unlock(&b->cache_lock);
 }
 
@@ -207,7 +222,7 @@ void nfsd_reply_cache_shutdown(void)
                struct list_head *head = &drc_hashtbl[i].lru_head;
                while (!list_empty(head)) {
                        rp = list_first_entry(head, struct svc_cacherep, c_lru);
-                       nfsd_reply_cache_free_locked(rp);
+                       nfsd_reply_cache_free_locked(&drc_hashtbl[i], rp);
                }
        }
 
@@ -246,7 +261,7 @@ prune_bucket(struct nfsd_drc_bucket *b)
                if (atomic_read(&num_drc_entries) <= max_drc_entries &&
                    time_before(jiffies, rp->c_timestamp + RC_EXPIRE))
                        break;
-               nfsd_reply_cache_free_locked(rp);
+               nfsd_reply_cache_free_locked(b, rp);
                freed++;
        }
        return freed;
@@ -318,51 +333,48 @@ nfsd_cache_csum(struct svc_rqst *rqstp)
        return csum;
 }
 
-static bool
-nfsd_cache_match(struct svc_rqst *rqstp, __wsum csum, struct svc_cacherep *rp)
+static int
+nfsd_cache_key_cmp(const struct svc_cacherep *key, const struct svc_cacherep *rp)
 {
-       /* Check RPC XID first */
-       if (rqstp->rq_xid != rp->c_xid)
-               return false;
-       /* compare checksum of NFS data */
-       if (csum != rp->c_csum) {
+       if (key->c_key.k_xid == rp->c_key.k_xid &&
+           key->c_key.k_csum != rp->c_key.k_csum)
                ++payload_misses;
-               return false;
-       }
 
-       /* Other discriminators */
-       if (rqstp->rq_proc != rp->c_proc ||
-           rqstp->rq_prot != rp->c_prot ||
-           rqstp->rq_vers != rp->c_vers ||
-           rqstp->rq_arg.len != rp->c_len ||
-           !rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) ||
-           rpc_get_port(svc_addr(rqstp)) != rpc_get_port((struct sockaddr *)&rp->c_addr))
-               return false;
-
-       return true;
+       return memcmp(&key->c_key, &rp->c_key, sizeof(key->c_key));
 }
 
 /*
  * Search the request hash for an entry that matches the given rqstp.
  * Must be called with cache_lock held. Returns the found entry or
- * NULL on failure.
+ * inserts an empty key on failure.
  */
 static struct svc_cacherep *
-nfsd_cache_search(struct nfsd_drc_bucket *b, struct svc_rqst *rqstp,
-               __wsum csum)
+nfsd_cache_insert(struct nfsd_drc_bucket *b, struct svc_cacherep *key)
 {
-       struct svc_cacherep     *rp, *ret = NULL;
-       struct list_head        *rh = &b->lru_head;
+       struct svc_cacherep     *rp, *ret = key;
+       struct rb_node          **p = &b->rb_head.rb_node,
+                               *parent = NULL;
        unsigned int            entries = 0;
+       int cmp;
 
-       list_for_each_entry(rp, rh, c_lru) {
+       while (*p != NULL) {
                ++entries;
-               if (nfsd_cache_match(rqstp, csum, rp)) {
+               parent = *p;
+               rp = rb_entry(parent, struct svc_cacherep, c_node);
+
+               cmp = nfsd_cache_key_cmp(key, rp);
+               if (cmp < 0)
+                       p = &parent->rb_left;
+               else if (cmp > 0)
+                       p = &parent->rb_right;
+               else {
                        ret = rp;
-                       break;
+                       goto out;
                }
        }
-
+       rb_link_node(&key->c_node, parent, p);
+       rb_insert_color(&key->c_node, &b->rb_head);
+out:
        /* tally hash chain length stats */
        if (entries > longest_chain) {
                longest_chain = entries;
@@ -374,6 +386,7 @@ nfsd_cache_search(struct nfsd_drc_bucket *b, struct svc_rqst *rqstp,
                                atomic_read(&num_drc_entries));
        }
 
+       lru_put_end(b, ret);
        return ret;
 }
 
@@ -389,9 +402,6 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
 {
        struct svc_cacherep     *rp, *found;
        __be32                  xid = rqstp->rq_xid;
-       u32                     proto =  rqstp->rq_prot,
-                               vers = rqstp->rq_vers,
-                               proc = rqstp->rq_proc;
        __wsum                  csum;
        u32 hash = nfsd_cache_hash(xid);
        struct nfsd_drc_bucket *b = &drc_hashtbl[hash];
@@ -410,60 +420,38 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
         * Since the common case is a cache miss followed by an insert,
         * preallocate an entry.
         */
-       rp = nfsd_reply_cache_alloc();
-       spin_lock(&b->cache_lock);
-       if (likely(rp)) {
-               atomic_inc(&num_drc_entries);
-               drc_mem_usage += sizeof(*rp);
+       rp = nfsd_reply_cache_alloc(rqstp, csum);
+       if (!rp) {
+               dprintk("nfsd: unable to allocate DRC entry!\n");
+               return rtn;
        }
 
-       /* go ahead and prune the cache */
-       prune_bucket(b);
-
-       found = nfsd_cache_search(b, rqstp, csum);
-       if (found) {
-               if (likely(rp))
-                       nfsd_reply_cache_free_locked(rp);
+       spin_lock(&b->cache_lock);
+       found = nfsd_cache_insert(b, rp);
+       if (found != rp) {
+               nfsd_reply_cache_free_locked(NULL, rp);
                rp = found;
                goto found_entry;
        }
 
-       if (!rp) {
-               dprintk("nfsd: unable to allocate DRC entry!\n");
-               goto out;
-       }
-
        nfsdstats.rcmisses++;
        rqstp->rq_cacherep = rp;
        rp->c_state = RC_INPROG;
-       rp->c_xid = xid;
-       rp->c_proc = proc;
-       rpc_copy_addr((struct sockaddr *)&rp->c_addr, svc_addr(rqstp));
-       rpc_set_port((struct sockaddr *)&rp->c_addr, rpc_get_port(svc_addr(rqstp)));
-       rp->c_prot = proto;
-       rp->c_vers = vers;
-       rp->c_len = rqstp->rq_arg.len;
-       rp->c_csum = csum;
 
-       lru_put_end(b, rp);
+       atomic_inc(&num_drc_entries);
+       drc_mem_usage += sizeof(*rp);
 
-       /* release any buffer */
-       if (rp->c_type == RC_REPLBUFF) {
-               drc_mem_usage -= rp->c_replvec.iov_len;
-               kfree(rp->c_replvec.iov_base);
-               rp->c_replvec.iov_base = NULL;
-       }
-       rp->c_type = RC_NOCACHE;
+       /* go ahead and prune the cache */
+       prune_bucket(b);
  out:
        spin_unlock(&b->cache_lock);
        return rtn;
 
 found_entry:
-       nfsdstats.rchits++;
        /* We found a matching entry which is either in progress or done. */
-       lru_put_end(b, rp);
-
+       nfsdstats.rchits++;
        rtn = RC_DROPIT;
+
        /* Request being processed */
        if (rp->c_state == RC_INPROG)
                goto out;
@@ -489,7 +477,7 @@ found_entry:
                break;
        default:
                printk(KERN_WARNING "nfsd: bad repcache type %d\n", rp->c_type);
-               nfsd_reply_cache_free_locked(rp);
+               nfsd_reply_cache_free_locked(b, rp);
        }
 
        goto out;
@@ -524,7 +512,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
        if (!rp)
                return;
 
-       hash = nfsd_cache_hash(rp->c_xid);
+       hash = nfsd_cache_hash(rp->c_key.k_xid);
        b = &drc_hashtbl[hash];
 
        len = resv->iov_len - ((char*)statp - (char*)resv->iov_base);
index 7fb9f7c667b11077adc4afacb20d5c75319c5841..6384c9b9489883d0e08cc83e328799782d45dc7c 100644 (file)
@@ -1242,6 +1242,7 @@ static __net_init int nfsd_init_net(struct net *net)
        nn->somebody_reclaimed = false;
        nn->clverifier_counter = prandom_u32();
        nn->clientid_counter = prandom_u32();
+       nn->s2s_cp_cl_id = nn->clientid_counter++;
 
        atomic_set(&nn->ntf_refcnt, 0);
        init_waitqueue_head(&nn->ntf_wq);
index 0b15dac7e609716ce032d4fa6873eefe8e2d4690..6aacb325b6a0f3d1f8cd1fd881d96fccc9499d95 100644 (file)
@@ -355,6 +355,8 @@ struct nfs4_client {
        struct rpc_wait_queue   cl_cb_waitq;    /* backchannel callers may */
                                                /* wait here for slots */
        struct net              *net;
+       struct list_head        async_copies;   /* list of async copies */
+       spinlock_t              async_lock;     /* lock for async copies */
 };
 
 /* struct nfs4_client_reset
@@ -573,6 +575,7 @@ enum nfsd4_cb_op {
        NFSPROC4_CLNT_CB_NULL = 0,
        NFSPROC4_CLNT_CB_RECALL,
        NFSPROC4_CLNT_CB_LAYOUT,
+       NFSPROC4_CLNT_CB_OFFLOAD,
        NFSPROC4_CLNT_CB_SEQUENCE,
        NFSPROC4_CLNT_CB_NOTIFY_LOCK,
 };
@@ -599,6 +602,7 @@ struct nfsd4_blocked_lock {
 
 struct nfsd4_compound_state;
 struct nfsd_net;
+struct nfsd4_copy;
 
 extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *cstate, struct svc_fh *fhp,
@@ -608,6 +612,8 @@ __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
                     struct nfs4_stid **s, struct nfsd_net *nn);
 struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab,
                                  void (*sc_free)(struct nfs4_stid *));
+int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy);
+void nfs4_free_cp_state(struct nfsd4_copy *copy);
 void nfs4_unhash_stid(struct nfs4_stid *s);
 void nfs4_put_stid(struct nfs4_stid *s);
 void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
@@ -626,6 +632,7 @@ extern void nfsd4_run_cb(struct nfsd4_callback *cb);
 extern int nfsd4_create_callback_queue(void);
 extern void nfsd4_destroy_callback_queue(void);
 extern void nfsd4_shutdown_callback(struct nfs4_client *);
+extern void nfsd4_shutdown_copy(struct nfs4_client *clp);
 extern void nfsd4_prepare_cb_recall(struct nfs4_delegation *dp);
 extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
                                                        struct nfsd_net *nn);
@@ -633,6 +640,9 @@ extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn);
 
 struct nfs4_file *find_file(struct knfsd_fh *fh);
 void put_nfs4_file(struct nfs4_file *fi);
+extern void nfs4_put_copy(struct nfsd4_copy *copy);
+extern struct nfsd4_copy *
+find_async_copy(struct nfs4_client *clp, stateid_t *staetid);
 static inline void get_nfs4_file(struct nfs4_file *fi)
 {
        refcount_inc(&fi->fi_ref);
index b53e76391e52539d11daee791bc47cc07b2ae773..2751976704e9388239fbb3742001e261ca09bdfe 100644 (file)
@@ -1276,7 +1276,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                int type, dev_t rdev, struct svc_fh *resfhp)
 {
        struct dentry   *dentry, *dchild = NULL;
-       struct inode    *dirp;
        __be32          err;
        int             host_err;
 
@@ -1288,7 +1287,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                return err;
 
        dentry = fhp->fh_dentry;
-       dirp = d_inode(dentry);
 
        host_err = fh_want_write(fhp);
        if (host_err)
@@ -1409,6 +1407,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                                        *created = 1;
                                break;
                        }
+                       /* fall through */
                case NFS4_CREATE_EXCLUSIVE4_1:
                        if (   d_inode(dchild)->i_mtime.tv_sec == v_mtime
                            && d_inode(dchild)->i_atime.tv_sec == v_atime
@@ -1417,7 +1416,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                                        *created = 1;
                                goto set_attr;
                        }
-                        /* fallthru */
+                       /* fall through */
                case NFS3_CREATE_GUARDED:
                        err = nfserr_exist;
                }
index 17c453a7999c42d5b55a4a7ce05312c655e1c161..feeb6d4bdffda38463bec8f75c6124820a5697ac 100644 (file)
@@ -511,6 +511,7 @@ struct nfsd42_write_res {
        u64                     wr_bytes_written;
        u32                     wr_stable_how;
        nfs4_verifier           wr_verifier;
+       stateid_t               cb_stateid;
 };
 
 struct nfsd4_copy {
@@ -526,6 +527,23 @@ struct nfsd4_copy {
 
        /* response */
        struct nfsd42_write_res cp_res;
+
+       /* for cb_offload */
+       struct nfsd4_callback   cp_cb;
+       __be32                  nfserr;
+       struct knfsd_fh         fh;
+
+       struct nfs4_client      *cp_clp;
+
+       struct file             *file_src;
+       struct file             *file_dst;
+
+       stateid_t               cp_stateid;
+
+       struct list_head        copies;
+       struct task_struct      *copy_task;
+       refcount_t              refcount;
+       bool                    stopped;
 };
 
 struct nfsd4_seek {
@@ -539,6 +557,15 @@ struct nfsd4_seek {
        loff_t          seek_pos;
 };
 
+struct nfsd4_offload_status {
+       /* request */
+       stateid_t       stateid;
+
+       /* response */
+       u64             count;
+       u32             status;
+};
+
 struct nfsd4_op {
        int                                     opnum;
        const struct nfsd4_operation *          opdesc;
@@ -597,6 +624,7 @@ struct nfsd4_op {
                struct nfsd4_fallocate          deallocate;
                struct nfsd4_clone              clone;
                struct nfsd4_copy               copy;
+               struct nfsd4_offload_status     offload_status;
                struct nfsd4_seek               seek;
        } u;
        struct nfs4_replay *                    replay;
index 517239af03027c176eeb9dd73e2c08a0ed9d43bd..547cf07cf4e08c3fbfd4da2a2cb48859e403fdf9 100644 (file)
 #define NFS4_dec_cb_notify_lock_sz     (cb_compound_dec_hdr_sz  +      \
                                        cb_sequence_dec_sz +            \
                                        op_dec_sz)
+#define enc_cb_offload_info_sz         (1 + 1 + 2 + 1 +                \
+                                       XDR_QUADLEN(NFS4_VERIFIER_SIZE))
+#define NFS4_enc_cb_offload_sz         (cb_compound_enc_hdr_sz +       \
+                                       cb_sequence_enc_sz +            \
+                                       enc_nfs4_fh_sz +                \
+                                       enc_stateid_sz +                \
+                                       enc_cb_offload_info_sz)
+#define NFS4_dec_cb_offload_sz         (cb_compound_dec_hdr_sz  +      \
+                                       cb_sequence_dec_sz +            \
+                                       op_dec_sz)
index 94b52157bf8db41371077c91d068b5fb9b3d64bc..5769cf3ff035a4b500154eb4e1a4027d3245cbe3 100644 (file)
@@ -25,7 +25,7 @@ static bool should_merge(struct fsnotify_event *old_fsn,
        old = FANOTIFY_E(old_fsn);
        new = FANOTIFY_E(new_fsn);
 
-       if (old_fsn->inode == new_fsn->inode && old->tgid == new->tgid &&
+       if (old_fsn->inode == new_fsn->inode && old->pid == new->pid &&
            old->path.mnt == new->path.mnt &&
            old->path.dentry == new->path.dentry)
                return true;
@@ -131,8 +131,8 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
            !(marks_mask & FS_ISDIR & ~marks_ignored_mask))
                return false;
 
-       if (event_mask & FAN_ALL_OUTGOING_EVENTS & marks_mask &
-                                ~marks_ignored_mask)
+       if (event_mask & FANOTIFY_OUTGOING_EVENTS &
+           marks_mask & ~marks_ignored_mask)
                return true;
 
        return false;
@@ -171,7 +171,10 @@ struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
                goto out;
 init: __maybe_unused
        fsnotify_init_event(&event->fse, inode, mask);
-       event->tgid = get_pid(task_tgid(current));
+       if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
+               event->pid = get_pid(task_pid(current));
+       else
+               event->pid = get_pid(task_tgid(current));
        if (path) {
                event->path = *path;
                path_get(&event->path);
@@ -205,6 +208,8 @@ static int fanotify_handle_event(struct fsnotify_group *group,
        BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
        BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
 
+       BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 10);
+
        if (!fanotify_should_send_event(iter_info, mask, data, data_type))
                return 0;
 
@@ -236,7 +241,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
        ret = fsnotify_add_event(group, fsn_event, fanotify_merge);
        if (ret) {
                /* Permission events shouldn't be merged */
-               BUG_ON(ret == 1 && mask & FAN_ALL_PERM_EVENTS);
+               BUG_ON(ret == 1 && mask & FANOTIFY_PERM_EVENTS);
                /* Our event wasn't used in the end. Free it. */
                fsnotify_destroy_event(group, fsn_event);
 
@@ -268,7 +273,7 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event)
 
        event = FANOTIFY_E(fsn_event);
        path_put(&event->path);
-       put_pid(event->tgid);
+       put_pid(event->pid);
        if (fanotify_is_perm_event(fsn_event->mask)) {
                kmem_cache_free(fanotify_perm_event_cachep,
                                FANOTIFY_PE(fsn_event));
index 8609ba06f4745769e70a69e61a4f0813b0902477..ea05b8a401e79dc9d9322a2105407bccf56fa834 100644 (file)
@@ -19,7 +19,7 @@ struct fanotify_event_info {
         * during this object's lifetime
         */
        struct path path;
-       struct pid *tgid;
+       struct pid *pid;
 };
 
 /*
@@ -44,7 +44,7 @@ FANOTIFY_PE(struct fsnotify_event *fse)
 static inline bool fanotify_is_perm_event(u32 mask)
 {
        return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) &&
-               mask & FAN_ALL_PERM_EVENTS;
+               mask & FANOTIFY_PERM_EVENTS;
 }
 
 static inline struct fanotify_event_info *FANOTIFY_E(struct fsnotify_event *fse)
index 69054886915b6bd2964393089af00037114966ae..e03be507136258416be1c4de72656f496b18ab7e 100644 (file)
@@ -131,8 +131,8 @@ static int fill_event_metadata(struct fsnotify_group *group,
        metadata->metadata_len = FAN_EVENT_METADATA_LEN;
        metadata->vers = FANOTIFY_METADATA_VERSION;
        metadata->reserved = 0;
-       metadata->mask = fsn_event->mask & FAN_ALL_OUTGOING_EVENTS;
-       metadata->pid = pid_vnr(event->tgid);
+       metadata->mask = fsn_event->mask & FANOTIFY_OUTGOING_EVENTS;
+       metadata->pid = pid_vnr(event->pid);
        if (unlikely(fsn_event->mask & FAN_Q_OVERFLOW))
                metadata->fd = FAN_NOFD;
        else {
@@ -191,7 +191,7 @@ static int process_access_response(struct fsnotify_group *group,
        if (fd < 0)
                return -EINVAL;
 
-       if ((response & FAN_AUDIT) && !group->fanotify_data.audit)
+       if ((response & FAN_AUDIT) && !FAN_GROUP_FLAG(group, FAN_ENABLE_AUDIT))
                return -EINVAL;
 
        event = dequeue_event(group, fd);
@@ -395,7 +395,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
         */
        while (!fsnotify_notify_queue_is_empty(group)) {
                fsn_event = fsnotify_remove_first_event(group);
-               if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS)) {
+               if (!(fsn_event->mask & FANOTIFY_PERM_EVENTS)) {
                        spin_unlock(&group->notification_lock);
                        fsnotify_destroy_event(group, fsn_event);
                        spin_lock(&group->notification_lock);
@@ -506,18 +506,10 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
 
        spin_lock(&fsn_mark->lock);
        if (!(flags & FAN_MARK_IGNORED_MASK)) {
-               __u32 tmask = fsn_mark->mask & ~mask;
-
-               if (flags & FAN_MARK_ONDIR)
-                       tmask &= ~FAN_ONDIR;
-
                oldmask = fsn_mark->mask;
-               fsn_mark->mask = tmask;
+               fsn_mark->mask &= ~mask;
        } else {
-               __u32 tmask = fsn_mark->ignored_mask & ~mask;
-               if (flags & FAN_MARK_ONDIR)
-                       tmask &= ~FAN_ONDIR;
-               fsn_mark->ignored_mask = tmask;
+               fsn_mark->ignored_mask &= ~mask;
        }
        *destroy = !(fsn_mark->mask | fsn_mark->ignored_mask);
        spin_unlock(&fsn_mark->lock);
@@ -563,6 +555,13 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
                                    mask, flags);
 }
 
+static int fanotify_remove_sb_mark(struct fsnotify_group *group,
+                                     struct super_block *sb, __u32 mask,
+                                     unsigned int flags)
+{
+       return fanotify_remove_mark(group, &sb->s_fsnotify_marks, mask, flags);
+}
+
 static int fanotify_remove_inode_mark(struct fsnotify_group *group,
                                      struct inode *inode, __u32 mask,
                                      unsigned int flags)
@@ -579,19 +578,10 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
 
        spin_lock(&fsn_mark->lock);
        if (!(flags & FAN_MARK_IGNORED_MASK)) {
-               __u32 tmask = fsn_mark->mask | mask;
-
-               if (flags & FAN_MARK_ONDIR)
-                       tmask |= FAN_ONDIR;
-
                oldmask = fsn_mark->mask;
-               fsn_mark->mask = tmask;
+               fsn_mark->mask |= mask;
        } else {
-               __u32 tmask = fsn_mark->ignored_mask | mask;
-               if (flags & FAN_MARK_ONDIR)
-                       tmask |= FAN_ONDIR;
-
-               fsn_mark->ignored_mask = tmask;
+               fsn_mark->ignored_mask |= mask;
                if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
                        fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
        }
@@ -658,6 +648,14 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
                                 FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags);
 }
 
+static int fanotify_add_sb_mark(struct fsnotify_group *group,
+                                     struct super_block *sb, __u32 mask,
+                                     unsigned int flags)
+{
+       return fanotify_add_mark(group, &sb->s_fsnotify_marks,
+                                FSNOTIFY_OBJ_TYPE_SB, mask, flags);
+}
+
 static int fanotify_add_inode_mark(struct fsnotify_group *group,
                                   struct inode *inode, __u32 mask,
                                   unsigned int flags)
@@ -686,16 +684,16 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        struct user_struct *user;
        struct fanotify_event_info *oevent;
 
-       pr_debug("%s: flags=%d event_f_flags=%d\n",
-               __func__, flags, event_f_flags);
+       pr_debug("%s: flags=%x event_f_flags=%x\n",
+                __func__, flags, event_f_flags);
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
 #ifdef CONFIG_AUDITSYSCALL
-       if (flags & ~(FAN_ALL_INIT_FLAGS | FAN_ENABLE_AUDIT))
+       if (flags & ~(FANOTIFY_INIT_FLAGS | FAN_ENABLE_AUDIT))
 #else
-       if (flags & ~FAN_ALL_INIT_FLAGS)
+       if (flags & ~FANOTIFY_INIT_FLAGS)
 #endif
                return -EINVAL;
 
@@ -731,6 +729,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        }
 
        group->fanotify_data.user = user;
+       group->fanotify_data.flags = flags;
        atomic_inc(&user->fanotify_listeners);
        group->memcg = get_mem_cgroup_from_mm(current->mm);
 
@@ -746,7 +745,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        group->fanotify_data.f_flags = event_f_flags;
        init_waitqueue_head(&group->fanotify_data.access_waitq);
        INIT_LIST_HEAD(&group->fanotify_data.access_list);
-       switch (flags & FAN_ALL_CLASS_BITS) {
+       switch (flags & FANOTIFY_CLASS_BITS) {
        case FAN_CLASS_NOTIF:
                group->priority = FS_PRIO_0;
                break;
@@ -783,7 +782,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
                fd = -EPERM;
                if (!capable(CAP_AUDIT_WRITE))
                        goto out_destroy_group;
-               group->fanotify_data.audit = true;
        }
 
        fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
@@ -805,7 +803,8 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
        struct fsnotify_group *group;
        struct fd f;
        struct path path;
-       u32 valid_mask = FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD;
+       u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS;
+       unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
        int ret;
 
        pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
@@ -815,8 +814,18 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
        if (mask & ((__u64)0xffffffff << 32))
                return -EINVAL;
 
-       if (flags & ~FAN_ALL_MARK_FLAGS)
+       if (flags & ~FANOTIFY_MARK_FLAGS)
+               return -EINVAL;
+
+       switch (mark_type) {
+       case FAN_MARK_INODE:
+       case FAN_MARK_MOUNT:
+       case FAN_MARK_FILESYSTEM:
+               break;
+       default:
                return -EINVAL;
+       }
+
        switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
        case FAN_MARK_ADD:              /* fallthrough */
        case FAN_MARK_REMOVE:
@@ -824,20 +833,15 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
                        return -EINVAL;
                break;
        case FAN_MARK_FLUSH:
-               if (flags & ~(FAN_MARK_MOUNT | FAN_MARK_FLUSH))
+               if (flags & ~(FANOTIFY_MARK_TYPE_BITS | FAN_MARK_FLUSH))
                        return -EINVAL;
                break;
        default:
                return -EINVAL;
        }
 
-       if (mask & FAN_ONDIR) {
-               flags |= FAN_MARK_ONDIR;
-               mask &= ~FAN_ONDIR;
-       }
-
        if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS))
-               valid_mask |= FAN_ALL_PERM_EVENTS;
+               valid_mask |= FANOTIFY_PERM_EVENTS;
 
        if (mask & ~valid_mask)
                return -EINVAL;
@@ -857,14 +861,16 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
         * allowed to set permissions events.
         */
        ret = -EINVAL;
-       if (mask & FAN_ALL_PERM_EVENTS &&
+       if (mask & FANOTIFY_PERM_EVENTS &&
            group->priority == FS_PRIO_0)
                goto fput_and_out;
 
        if (flags & FAN_MARK_FLUSH) {
                ret = 0;
-               if (flags & FAN_MARK_MOUNT)
+               if (mark_type == FAN_MARK_MOUNT)
                        fsnotify_clear_vfsmount_marks_by_group(group);
+               else if (mark_type == FAN_MARK_FILESYSTEM)
+                       fsnotify_clear_sb_marks_by_group(group);
                else
                        fsnotify_clear_inode_marks_by_group(group);
                goto fput_and_out;
@@ -875,7 +881,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
                goto fput_and_out;
 
        /* inode held in place by reference to path; group by fget on fd */
-       if (!(flags & FAN_MARK_MOUNT))
+       if (mark_type == FAN_MARK_INODE)
                inode = path.dentry->d_inode;
        else
                mnt = path.mnt;
@@ -883,14 +889,18 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
        /* create/update an inode mark */
        switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
        case FAN_MARK_ADD:
-               if (flags & FAN_MARK_MOUNT)
+               if (mark_type == FAN_MARK_MOUNT)
                        ret = fanotify_add_vfsmount_mark(group, mnt, mask, flags);
+               else if (mark_type == FAN_MARK_FILESYSTEM)
+                       ret = fanotify_add_sb_mark(group, mnt->mnt_sb, mask, flags);
                else
                        ret = fanotify_add_inode_mark(group, inode, mask, flags);
                break;
        case FAN_MARK_REMOVE:
-               if (flags & FAN_MARK_MOUNT)
+               if (mark_type == FAN_MARK_MOUNT)
                        ret = fanotify_remove_vfsmount_mark(group, mnt, mask, flags);
+               else if (mark_type == FAN_MARK_FILESYSTEM)
+                       ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask, flags);
                else
                        ret = fanotify_remove_inode_mark(group, inode, mask, flags);
                break;
@@ -934,6 +944,9 @@ COMPAT_SYSCALL_DEFINE6(fanotify_mark,
  */
 static int __init fanotify_user_setup(void)
 {
+       BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 7);
+       BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 9);
+
        fanotify_mark_cache = KMEM_CACHE(fsnotify_mark,
                                         SLAB_PANIC|SLAB_ACCOUNT);
        fanotify_event_cachep = KMEM_CACHE(fanotify_event_info, SLAB_PANIC);
index 86fcf58142798f26c102d0ec8a76e32684ebc8fd..348a184bcdda3483256e74b6f192e9dd7d339220 100644 (file)
@@ -131,37 +131,20 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 
                seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
                           mnt->mnt_id, mflags, mark->mask, mark->ignored_mask);
+       } else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_SB) {
+               struct super_block *sb = fsnotify_conn_sb(mark->connector);
+
+               seq_printf(m, "fanotify sdev:%x mflags:%x mask:%x ignored_mask:%x\n",
+                          sb->s_dev, mflags, mark->mask, mark->ignored_mask);
        }
 }
 
 void fanotify_show_fdinfo(struct seq_file *m, struct file *f)
 {
        struct fsnotify_group *group = f->private_data;
-       unsigned int flags = 0;
-
-       switch (group->priority) {
-       case FS_PRIO_0:
-               flags |= FAN_CLASS_NOTIF;
-               break;
-       case FS_PRIO_1:
-               flags |= FAN_CLASS_CONTENT;
-               break;
-       case FS_PRIO_2:
-               flags |= FAN_CLASS_PRE_CONTENT;
-               break;
-       }
-
-       if (group->max_events == UINT_MAX)
-               flags |= FAN_UNLIMITED_QUEUE;
-
-       if (group->fanotify_data.max_marks == UINT_MAX)
-               flags |= FAN_UNLIMITED_MARKS;
-
-       if (group->fanotify_data.audit)
-               flags |= FAN_ENABLE_AUDIT;
 
        seq_printf(m, "fanotify flags:%x event-flags:%x\n",
-                  flags, group->fanotify_data.f_flags);
+                  group->fanotify_data.flags, group->fanotify_data.f_flags);
 
        show_fdinfo(m, f, fanotify_fdinfo);
 }
index ababdbfab537ef259b20079cd74d7f036e293fc7..2172ba516c61d536f5f05045e0a47d7dae30cfc1 100644 (file)
@@ -48,7 +48,7 @@ void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
  * Called during unmount with no locks held, so needs to be safe against
  * concurrent modifiers. We temporarily drop sb->s_inode_list_lock and CAN block.
  */
-void fsnotify_unmount_inodes(struct super_block *sb)
+static void fsnotify_unmount_inodes(struct super_block *sb)
 {
        struct inode *inode, *iput_inode = NULL;
 
@@ -96,6 +96,15 @@ void fsnotify_unmount_inodes(struct super_block *sb)
 
        if (iput_inode)
                iput(iput_inode);
+       /* Wait for outstanding inode references from connectors */
+       wait_var_event(&sb->s_fsnotify_inode_refs,
+                      !atomic_long_read(&sb->s_fsnotify_inode_refs));
+}
+
+void fsnotify_sb_delete(struct super_block *sb)
+{
+       fsnotify_unmount_inodes(sb);
+       fsnotify_clear_marks_by_sb(sb);
 }
 
 /*
@@ -190,7 +199,7 @@ static int send_to_group(struct inode *to_tell,
                         struct fsnotify_iter_info *iter_info)
 {
        struct fsnotify_group *group = NULL;
-       __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+       __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);
        __u32 marks_mask = 0;
        __u32 marks_ignored_mask = 0;
        struct fsnotify_mark *mark;
@@ -319,15 +328,17 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
             const unsigned char *file_name, u32 cookie)
 {
        struct fsnotify_iter_info iter_info = {};
-       struct mount *mnt;
+       struct super_block *sb = NULL;
+       struct mount *mnt = NULL;
+       __u32 mnt_or_sb_mask = 0;
        int ret = 0;
-       /* global tests shouldn't care about events on child only the specific event */
-       __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+       __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);
 
-       if (data_is == FSNOTIFY_EVENT_PATH)
+       if (data_is == FSNOTIFY_EVENT_PATH) {
                mnt = real_mount(((const struct path *)data)->mnt);
-       else
-               mnt = NULL;
+               sb = mnt->mnt.mnt_sb;
+               mnt_or_sb_mask = mnt->mnt_fsnotify_mask | sb->s_fsnotify_mask;
+       }
 
        /*
         * Optimization: srcu_read_lock() has a memory barrier which can
@@ -337,16 +348,15 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
         * need SRCU to keep them "alive".
         */
        if (!to_tell->i_fsnotify_marks &&
-           (!mnt || !mnt->mnt_fsnotify_marks))
+           (!mnt || (!mnt->mnt_fsnotify_marks && !sb->s_fsnotify_marks)))
                return 0;
        /*
         * if this is a modify event we may need to clear the ignored masks
-        * otherwise return if neither the inode nor the vfsmount care about
+        * otherwise return if neither the inode nor the vfsmount/sb care about
         * this type of event.
         */
        if (!(mask & FS_MODIFY) &&
-           !(test_mask & to_tell->i_fsnotify_mask) &&
-           !(mnt && test_mask & mnt->mnt_fsnotify_mask))
+           !(test_mask & (to_tell->i_fsnotify_mask | mnt_or_sb_mask)))
                return 0;
 
        iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
@@ -356,11 +366,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
        if (mnt) {
                iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] =
                        fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
+               iter_info.marks[FSNOTIFY_OBJ_TYPE_SB] =
+                       fsnotify_first_mark(&sb->s_fsnotify_marks);
        }
 
        /*
-        * We need to merge inode & vfsmount mark lists so that inode mark
-        * ignore masks are properly reflected for mount mark notifications.
+        * We need to merge inode/vfsmount/sb mark lists so that e.g. inode mark
+        * ignore masks are properly reflected for mount/sb mark notifications.
         * That's why this traversal is so complicated...
         */
        while (fsnotify_iter_select_report_types(&iter_info)) {
@@ -386,7 +398,7 @@ static __init int fsnotify_init(void)
 {
        int ret;
 
-       BUG_ON(hweight32(ALL_FSNOTIFY_EVENTS) != 23);
+       BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 23);
 
        ret = init_srcu_struct(&fsnotify_mark_srcu);
        if (ret)
index 7902653dd5771da03e48fb3014ff5fab84d2fd84..5a00121fb2197881c418c6bd7c8ebbec5eb44911 100644 (file)
@@ -21,6 +21,12 @@ static inline struct mount *fsnotify_conn_mount(
        return container_of(conn->obj, struct mount, mnt_fsnotify_marks);
 }
 
+static inline struct super_block *fsnotify_conn_sb(
+                               struct fsnotify_mark_connector *conn)
+{
+       return container_of(conn->obj, struct super_block, s_fsnotify_marks);
+}
+
 /* destroy all events sitting in this groups notification queue */
 extern void fsnotify_flush_notify(struct fsnotify_group *group);
 
@@ -43,6 +49,11 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
 {
        fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks);
 }
+/* run the list of all marks associated with sb and destroy them */
+static inline void fsnotify_clear_marks_by_sb(struct super_block *sb)
+{
+       fsnotify_destroy_marks(&sb->s_fsnotify_marks);
+}
 /* Wait until all marks queued for destruction are destroyed */
 extern void fsnotify_wait_marks_destroyed(void);
 
index ac6978d3208cfae13442ffa5d851d7bacc4950fd..105576daca4abc35f861e89fc7bafc2b0229223b 100644 (file)
@@ -815,7 +815,7 @@ static int __init inotify_user_setup(void)
        BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
        BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
 
-       BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22);
+       BUILD_BUG_ON(HWEIGHT32(ALL_INOTIFY_BITS) != 22);
 
        inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark,
                                               SLAB_PANIC|SLAB_ACCOUNT);
index 59cdb27826defe2ddac7023438132c1b80a49c29..d2dd16cb5989144d4289cc879a4a34d2af81c216 100644 (file)
@@ -115,6 +115,8 @@ static __u32 *fsnotify_conn_mask_p(struct fsnotify_mark_connector *conn)
                return &fsnotify_conn_inode(conn)->i_fsnotify_mask;
        else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
                return &fsnotify_conn_mount(conn)->mnt_fsnotify_mask;
+       else if (conn->type == FSNOTIFY_OBJ_TYPE_SB)
+               return &fsnotify_conn_sb(conn)->s_fsnotify_mask;
        return NULL;
 }
 
@@ -179,19 +181,24 @@ static void fsnotify_connector_destroy_workfn(struct work_struct *work)
        }
 }
 
-static struct inode *fsnotify_detach_connector_from_object(
-                                       struct fsnotify_mark_connector *conn)
+static void *fsnotify_detach_connector_from_object(
+                                       struct fsnotify_mark_connector *conn,
+                                       unsigned int *type)
 {
        struct inode *inode = NULL;
 
+       *type = conn->type;
        if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED)
                return NULL;
 
        if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
                inode = fsnotify_conn_inode(conn);
                inode->i_fsnotify_mask = 0;
+               atomic_long_inc(&inode->i_sb->s_fsnotify_inode_refs);
        } else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
                fsnotify_conn_mount(conn)->mnt_fsnotify_mask = 0;
+       } else if (conn->type == FSNOTIFY_OBJ_TYPE_SB) {
+               fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
        }
 
        rcu_assign_pointer(*(conn->obj), NULL);
@@ -211,10 +218,29 @@ static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark)
        fsnotify_put_group(group);
 }
 
+/* Drop object reference originally held by a connector */
+static void fsnotify_drop_object(unsigned int type, void *objp)
+{
+       struct inode *inode;
+       struct super_block *sb;
+
+       if (!objp)
+               return;
+       /* Currently only inode references are passed to be dropped */
+       if (WARN_ON_ONCE(type != FSNOTIFY_OBJ_TYPE_INODE))
+               return;
+       inode = objp;
+       sb = inode->i_sb;
+       iput(inode);
+       if (atomic_long_dec_and_test(&sb->s_fsnotify_inode_refs))
+               wake_up_var(&sb->s_fsnotify_inode_refs);
+}
+
 void fsnotify_put_mark(struct fsnotify_mark *mark)
 {
        struct fsnotify_mark_connector *conn;
-       struct inode *inode = NULL;
+       void *objp = NULL;
+       unsigned int type = FSNOTIFY_OBJ_TYPE_DETACHED;
        bool free_conn = false;
 
        /* Catch marks that were actually never attached to object */
@@ -234,7 +260,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
        conn = mark->connector;
        hlist_del_init_rcu(&mark->obj_list);
        if (hlist_empty(&conn->list)) {
-               inode = fsnotify_detach_connector_from_object(conn);
+               objp = fsnotify_detach_connector_from_object(conn, &type);
                free_conn = true;
        } else {
                __fsnotify_recalc_mask(conn);
@@ -242,7 +268,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
        mark->connector = NULL;
        spin_unlock(&conn->lock);
 
-       iput(inode);
+       fsnotify_drop_object(type, objp);
 
        if (free_conn) {
                spin_lock(&destroy_lock);
@@ -709,7 +735,8 @@ void fsnotify_destroy_marks(fsnotify_connp_t *connp)
 {
        struct fsnotify_mark_connector *conn;
        struct fsnotify_mark *mark, *old_mark = NULL;
-       struct inode *inode;
+       void *objp;
+       unsigned int type;
 
        conn = fsnotify_grab_connector(connp);
        if (!conn)
@@ -735,11 +762,11 @@ void fsnotify_destroy_marks(fsnotify_connp_t *connp)
         * mark references get dropped. It would lead to strange results such
         * as delaying inode deletion or blocking unmount.
         */
-       inode = fsnotify_detach_connector_from_object(conn);
+       objp = fsnotify_detach_connector_from_object(conn, &type);
        spin_unlock(&conn->lock);
        if (old_mark)
                fsnotify_put_mark(old_mark);
-       iput(inode);
+       fsnotify_drop_object(type, objp);
 }
 
 /*
index d297fe4472a960b29fd62018535400c5b96a975f..bbcc185062bb5c8198f7cefbc85520c5adeac0e2 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
 #include <linux/printk.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
index 792c78a491747e248d99dc613c88e0beb8cffd0c..6c517b11acf829b5a1e2729f9d4748cb9cd56025 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/compiler.h>
 #include <linux/fs.h>
 #include <linux/init.h>
index 91ae16fbd7d591c3bf10e7d40d16a506d60bdff9..3fe90443c1bb8b8ad04dbcad10a08862448fd527 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/printk.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/crash_dump.h>
 #include <linux/list.h>
@@ -423,7 +423,7 @@ static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf)
                if (rc < 0) {
                        unlock_page(page);
                        put_page(page);
-                       return (rc == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
+                       return vmf_error(rc);
                }
                SetPageUptodate(page);
        }
index 503086f7f7c1b1a2890a2db3fa3ab4bacea37051..0d19d191ae70b85daae2276b85a3f42eb48645ac 100644 (file)
@@ -141,7 +141,6 @@ config PSTORE_RAM
        tristate "Log panic/oops to a RAM buffer"
        depends on PSTORE
        depends on HAS_IOMEM
-       depends on HAVE_MEMBLOCK
        select REED_SOLOMON
        select REED_SOLOMON_ENC8
        select REED_SOLOMON_DEC8
index a39a562c1c101b48dba40bea2f5ac24dba07460e..bd29c58ccbd8accad9d179e2079705c32cc3debc 100644 (file)
@@ -26,14 +26,5 @@ ifeq ($(CONFIG_REISERFS_FS_POSIX_ACL),y)
 reiserfs-objs += xattr_acl.o
 endif
 
-# gcc -O2 (the kernel default)  is overaggressive on ppc32 when many inline
-# functions are used.  This causes the compiler to advance the stack
-# pointer out of the available stack space, corrupting kernel space,
-# and causing a panic. Since this behavior only affects ppc32, this ifeq
-# will work around it. If any other architecture displays this behavior,
-# add it here.
-ccflags-$(CONFIG_PPC32) := $(call cc-ifversion, -lt, 0400, -O1)
-
 TAGS:
        etags *.c
-
index 48cdfc81fe10641da6025849c27d8f307f968a50..32d8986c26fb1fa2d3c5140d9fb7629eaf9b865f 100644 (file)
@@ -185,6 +185,7 @@ struct reiserfs_dentry_buf {
        struct dir_context ctx;
        struct dentry *xadir;
        int count;
+       int err;
        struct dentry *dentries[8];
 };
 
@@ -207,6 +208,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
 
        dentry = lookup_one_len(name, dbuf->xadir, namelen);
        if (IS_ERR(dentry)) {
+               dbuf->err = PTR_ERR(dentry);
                return PTR_ERR(dentry);
        } else if (d_really_is_negative(dentry)) {
                /* A directory entry exists, but no file? */
@@ -215,6 +217,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
                               "not found for file %pd.\n",
                               dentry, dbuf->xadir);
                dput(dentry);
+               dbuf->err = -EIO;
                return -EIO;
        }
 
@@ -262,6 +265,10 @@ static int reiserfs_for_each_xattr(struct inode *inode,
                err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx);
                if (err)
                        break;
+               if (buf.err) {
+                       err = buf.err;
+                       break;
+               }
                if (!buf.count)
                        break;
                for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) {
index f3a8c008e16430be1ba08d9f575c1df9faeb0f0a..ca53a08497ed296874ea6761013edb110901708b 100644 (file)
@@ -442,7 +442,7 @@ void generic_shutdown_super(struct super_block *sb)
                sync_filesystem(sb);
                sb->s_flags &= ~SB_ACTIVE;
 
-               fsnotify_unmount_inodes(sb);
+               fsnotify_sb_delete(sb);
                cgroup_writeback_umount();
 
                evict_inodes(sb);
index fcda0fc97b90a14fd53aafbeb15885d85716e3a1..ec85aeaed54ac6e9de18f5cec16f25ad090fd035 100644 (file)
@@ -175,8 +175,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
 {
        struct udf_sb_info *sbi = UDF_SB(sb);
        int alloc_count = 0;
-       int bit, block, block_group, group_start;
-       int nr_groups, bitmap_nr;
+       int bit, block, block_group;
+       int bitmap_nr;
        struct buffer_head *bh;
        __u32 part_len;
 
@@ -189,10 +189,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
                block_count = part_len - first_block;
 
        do {
-               nr_groups = udf_compute_nr_groups(sb, partition);
                block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
                block_group = block >> (sb->s_blocksize_bits + 3);
-               group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
 
                bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
                if (bitmap_nr < 0)
@@ -652,12 +650,6 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
        } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
                udf_table_free_blocks(sb, map->s_uspace.s_table,
                                      bloc, offset, count);
-       } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
-               udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap,
-                                      bloc, offset, count);
-       } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
-               udf_table_free_blocks(sb, map->s_fspace.s_table,
-                                     bloc, offset, count);
        }
 
        if (inode) {
@@ -684,16 +676,6 @@ inline int udf_prealloc_blocks(struct super_block *sb,
                                                      map->s_uspace.s_table,
                                                      partition, first_block,
                                                      block_count);
-       else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
-               allocated = udf_bitmap_prealloc_blocks(sb,
-                                                      map->s_fspace.s_bitmap,
-                                                      partition, first_block,
-                                                      block_count);
-       else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
-               allocated = udf_table_prealloc_blocks(sb,
-                                                     map->s_fspace.s_table,
-                                                     partition, first_block,
-                                                     block_count);
        else
                return 0;
 
@@ -717,14 +699,6 @@ inline udf_pblk_t udf_new_block(struct super_block *sb,
                block = udf_table_new_block(sb,
                                            map->s_uspace.s_table,
                                            partition, goal, err);
-       else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
-               block = udf_bitmap_new_block(sb,
-                                            map->s_fspace.s_bitmap,
-                                            partition, goal, err);
-       else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
-               block = udf_table_new_block(sb,
-                                           map->s_fspace.s_table,
-                                           partition, goal, err);
        else {
                *err = -EIO;
                return 0;
index 6f515651a2c2fe3817c763e3d77d351509a862d9..8f2f56d9a1bbfb8b110812d45167ce7e7b456099 100644 (file)
@@ -290,12 +290,8 @@ static void udf_free_partition(struct udf_part_map *map)
 
        if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
                iput(map->s_uspace.s_table);
-       if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
-               iput(map->s_fspace.s_table);
        if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
                udf_sb_free_bitmap(map->s_uspace.s_bitmap);
-       if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
-               udf_sb_free_bitmap(map->s_fspace.s_bitmap);
        if (map->s_partition_type == UDF_SPARABLE_MAP15)
                for (i = 0; i < 4; i++)
                        brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
@@ -613,14 +609,11 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
        struct udf_options uopt;
        struct udf_sb_info *sbi = UDF_SB(sb);
        int error = 0;
-       struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb);
+
+       if (!(*flags & SB_RDONLY) && UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
+               return -EACCES;
 
        sync_filesystem(sb);
-       if (lvidiu) {
-               int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
-               if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & SB_RDONLY))
-                       return -EACCES;
-       }
 
        uopt.flags = sbi->s_flags;
        uopt.uid   = sbi->s_uid;
@@ -988,12 +981,62 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
        return bitmap;
 }
 
+static int check_partition_desc(struct super_block *sb,
+                               struct partitionDesc *p,
+                               struct udf_part_map *map)
+{
+       bool umap, utable, fmap, ftable;
+       struct partitionHeaderDesc *phd;
+
+       switch (le32_to_cpu(p->accessType)) {
+       case PD_ACCESS_TYPE_READ_ONLY:
+       case PD_ACCESS_TYPE_WRITE_ONCE:
+       case PD_ACCESS_TYPE_REWRITABLE:
+       case PD_ACCESS_TYPE_NONE:
+               goto force_ro;
+       }
+
+       /* No Partition Header Descriptor? */
+       if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
+           strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
+               goto force_ro;
+
+       phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
+       utable = phd->unallocSpaceTable.extLength;
+       umap = phd->unallocSpaceBitmap.extLength;
+       ftable = phd->freedSpaceTable.extLength;
+       fmap = phd->freedSpaceBitmap.extLength;
+
+       /* No allocation info? */
+       if (!utable && !umap && !ftable && !fmap)
+               goto force_ro;
+
+       /* We don't support blocks that require erasing before overwrite */
+       if (ftable || fmap)
+               goto force_ro;
+       /* UDF 2.60: 2.3.3 - no mixing of tables & bitmaps, no VAT. */
+       if (utable && umap)
+               goto force_ro;
+
+       if (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
+           map->s_partition_type == UDF_VIRTUAL_MAP20)
+               goto force_ro;
+
+       return 0;
+force_ro:
+       if (!sb_rdonly(sb))
+               return -EACCES;
+       UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
+       return 0;
+}
+
 static int udf_fill_partdesc_info(struct super_block *sb,
                struct partitionDesc *p, int p_index)
 {
        struct udf_part_map *map;
        struct udf_sb_info *sbi = UDF_SB(sb);
        struct partitionHeaderDesc *phd;
+       int err;
 
        map = &sbi->s_partmaps[p_index];
 
@@ -1013,8 +1056,16 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                  p_index, map->s_partition_type,
                  map->s_partition_root, map->s_partition_len);
 
-       if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
-           strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
+       err = check_partition_desc(sb, p, map);
+       if (err)
+               return err;
+
+       /*
+        * Skip loading allocation info it we cannot ever write to the fs.
+        * This is a correctness thing as we may have decided to force ro mount
+        * to avoid allocation info we don't support.
+        */
+       if (UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT))
                return 0;
 
        phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
@@ -1050,40 +1101,6 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                          p_index, bitmap->s_extPosition);
        }
 
-       if (phd->partitionIntegrityTable.extLength)
-               udf_debug("partitionIntegrityTable (part %d)\n", p_index);
-
-       if (phd->freedSpaceTable.extLength) {
-               struct kernel_lb_addr loc = {
-                       .logicalBlockNum = le32_to_cpu(
-                               phd->freedSpaceTable.extPosition),
-                       .partitionReferenceNum = p_index,
-               };
-               struct inode *inode;
-
-               inode = udf_iget_special(sb, &loc);
-               if (IS_ERR(inode)) {
-                       udf_debug("cannot load freedSpaceTable (part %d)\n",
-                                 p_index);
-                       return PTR_ERR(inode);
-               }
-               map->s_fspace.s_table = inode;
-               map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE;
-               udf_debug("freedSpaceTable (part %d) @ %lu\n",
-                         p_index, map->s_fspace.s_table->i_ino);
-       }
-
-       if (phd->freedSpaceBitmap.extLength) {
-               struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
-               if (!bitmap)
-                       return -ENOMEM;
-               map->s_fspace.s_bitmap = bitmap;
-               bitmap->s_extPosition = le32_to_cpu(
-                               phd->freedSpaceBitmap.extPosition);
-               map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP;
-               udf_debug("freedSpaceBitmap (part %d) @ %u\n",
-                         p_index, bitmap->s_extPosition);
-       }
        return 0;
 }
 
@@ -1257,6 +1274,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
                        ret = -EACCES;
                        goto out_bh;
                }
+               UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
                ret = udf_load_vat(sb, i, type1_idx);
                if (ret < 0)
                        goto out_bh;
@@ -2155,10 +2173,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                                UDF_MAX_READ_VERSION);
                        ret = -EINVAL;
                        goto error_out;
-               } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION &&
-                          !sb_rdonly(sb)) {
-                       ret = -EACCES;
-                       goto error_out;
+               } else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) {
+                       if (!sb_rdonly(sb)) {
+                               ret = -EACCES;
+                               goto error_out;
+                       }
+                       UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
                }
 
                sbi->s_udfrev = minUDFWriteRev;
@@ -2176,10 +2196,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        }
 
        if (sbi->s_partmaps[sbi->s_partition].s_partition_flags &
-                       UDF_PART_FLAG_READ_ONLY &&
-           !sb_rdonly(sb)) {
-               ret = -EACCES;
-               goto error_out;
+                       UDF_PART_FLAG_READ_ONLY) {
+               if (!sb_rdonly(sb)) {
+                       ret = -EACCES;
+                       goto error_out;
+               }
+               UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
        }
 
        if (udf_find_fileset(sb, &fileset, &rootdir)) {
@@ -2433,10 +2455,6 @@ static unsigned int udf_count_free(struct super_block *sb)
                accum += udf_count_free_bitmap(sb,
                                               map->s_uspace.s_bitmap);
        }
-       if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
-               accum += udf_count_free_bitmap(sb,
-                                              map->s_fspace.s_bitmap);
-       }
        if (accum)
                return accum;
 
@@ -2444,11 +2462,6 @@ static unsigned int udf_count_free(struct super_block *sb)
                accum += udf_count_free_table(sb,
                                              map->s_uspace.s_table);
        }
-       if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
-               accum += udf_count_free_table(sb,
-                                             map->s_fspace.s_table);
-       }
-
        return accum;
 }
 
index 9424d7cab7900d869ae9556341d85319e3717327..3d83be54c4748fedda17f55bba989829ca53cb82 100644 (file)
 #define UDF_FLAG_LASTBLOCK_SET 16
 #define UDF_FLAG_BLOCKSIZE_SET 17
 #define UDF_FLAG_INCONSISTENT  18
+#define UDF_FLAG_RW_INCOMPAT   19      /* Set when we find RW incompatible
+                                        * feature */
 
 #define UDF_PART_FLAG_UNALLOC_BITMAP   0x0001
 #define UDF_PART_FLAG_UNALLOC_TABLE    0x0002
-#define UDF_PART_FLAG_FREED_BITMAP     0x0004
-#define UDF_PART_FLAG_FREED_TABLE      0x0008
 #define UDF_PART_FLAG_READ_ONLY                0x0010
 #define UDF_PART_FLAG_WRITE_ONCE       0x0020
 #define UDF_PART_FLAG_REWRITABLE       0x0040
@@ -50,8 +50,6 @@
 
 #define UDF_INVALID_MODE               ((umode_t)-1)
 
-#pragma pack(1) /* XXX(hch): Why?  This file just defines in-core structures */
-
 #define MF_DUPLICATE_MD                0x01
 #define MF_MIRROR_FE_LOADED    0x02
 
@@ -93,10 +91,6 @@ struct udf_part_map {
                struct udf_bitmap       *s_bitmap;
                struct inode            *s_table;
        } s_uspace;
-       union {
-               struct udf_bitmap       *s_bitmap;
-               struct inode            *s_table;
-       } s_fspace;
        __u32   s_partition_root;
        __u32   s_partition_len;
        __u16   s_partition_type;
index 1817a8415a5e82a7bc526a38361cea88566e62bb..c2de013b2cf4bfb2304a0925950383f4bacb4f85 100644 (file)
@@ -62,10 +62,6 @@ extern void setup_per_cpu_areas(void);
 #define PER_CPU_ATTRIBUTES
 #endif
 
-#ifndef PER_CPU_DEF_ATTRIBUTES
-#define PER_CPU_DEF_ATTRIBUTES
-#endif
-
 #define raw_cpu_generic_read(pcp)                                      \
 ({                                                                     \
        *raw_cpu_ptr(&(pcp));                                           \
index b396f00e481db9d4858856c05cc9454677395f7e..86a8806e2140291f3fcca22b695a2ee5066cb096 100644 (file)
@@ -16,6 +16,8 @@
 #define AM3_CLKCTRL_OFFSET     0x0
 #define AM3_CLKCTRL_INDEX(offset)      ((offset) - AM3_CLKCTRL_OFFSET)
 
+/* XXX: Compatibility part begin, remove this once compatibility support is no longer needed */
+
 /* l4_per clocks */
 #define AM3_L4_PER_CLKCTRL_OFFSET      0x14
 #define AM3_L4_PER_CLKCTRL_INDEX(offset)       ((offset) - AM3_L4_PER_CLKCTRL_OFFSET)
 #define AM3_L4_CEFUSE_CLKCTRL_INDEX(offset)    ((offset) - AM3_L4_CEFUSE_CLKCTRL_OFFSET)
 #define AM3_CEFUSE_CLKCTRL     AM3_L4_CEFUSE_CLKCTRL_INDEX(0x20)
 
+/* XXX: Compatibility part end */
+
+/* l4ls clocks */
+#define AM3_L4LS_CLKCTRL_OFFSET        0x38
+#define AM3_L4LS_CLKCTRL_INDEX(offset) ((offset) - AM3_L4LS_CLKCTRL_OFFSET)
+#define AM3_L4LS_UART6_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x38)
+#define AM3_L4LS_MMC1_CLKCTRL  AM3_L4LS_CLKCTRL_INDEX(0x3c)
+#define AM3_L4LS_ELM_CLKCTRL   AM3_L4LS_CLKCTRL_INDEX(0x40)
+#define AM3_L4LS_I2C3_CLKCTRL  AM3_L4LS_CLKCTRL_INDEX(0x44)
+#define AM3_L4LS_I2C2_CLKCTRL  AM3_L4LS_CLKCTRL_INDEX(0x48)
+#define AM3_L4LS_SPI0_CLKCTRL  AM3_L4LS_CLKCTRL_INDEX(0x4c)
+#define AM3_L4LS_SPI1_CLKCTRL  AM3_L4LS_CLKCTRL_INDEX(0x50)
+#define AM3_L4LS_L4_LS_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x60)
+#define AM3_L4LS_UART2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x6c)
+#define AM3_L4LS_UART3_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x70)
+#define AM3_L4LS_UART4_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x74)
+#define AM3_L4LS_UART5_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x78)
+#define AM3_L4LS_TIMER7_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0x7c)
+#define AM3_L4LS_TIMER2_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0x80)
+#define AM3_L4LS_TIMER3_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0x84)
+#define AM3_L4LS_TIMER4_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0x88)
+#define AM3_L4LS_RNG_CLKCTRL   AM3_L4LS_CLKCTRL_INDEX(0x90)
+#define AM3_L4LS_GPIO2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xac)
+#define AM3_L4LS_GPIO3_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xb0)
+#define AM3_L4LS_GPIO4_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xb4)
+#define AM3_L4LS_D_CAN0_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0xc0)
+#define AM3_L4LS_D_CAN1_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0xc4)
+#define AM3_L4LS_EPWMSS1_CLKCTRL       AM3_L4LS_CLKCTRL_INDEX(0xcc)
+#define AM3_L4LS_EPWMSS0_CLKCTRL       AM3_L4LS_CLKCTRL_INDEX(0xd4)
+#define AM3_L4LS_EPWMSS2_CLKCTRL       AM3_L4LS_CLKCTRL_INDEX(0xd8)
+#define AM3_L4LS_TIMER5_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0xec)
+#define AM3_L4LS_TIMER6_CLKCTRL        AM3_L4LS_CLKCTRL_INDEX(0xf0)
+#define AM3_L4LS_MMC2_CLKCTRL  AM3_L4LS_CLKCTRL_INDEX(0xf4)
+#define AM3_L4LS_SPINLOCK_CLKCTRL      AM3_L4LS_CLKCTRL_INDEX(0x10c)
+#define AM3_L4LS_MAILBOX_CLKCTRL       AM3_L4LS_CLKCTRL_INDEX(0x110)
+#define AM3_L4LS_OCPWP_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x130)
+
+/* l3s clocks */
+#define AM3_L3S_CLKCTRL_OFFSET 0x1c
+#define AM3_L3S_CLKCTRL_INDEX(offset)  ((offset) - AM3_L3S_CLKCTRL_OFFSET)
+#define AM3_L3S_USB_OTG_HS_CLKCTRL     AM3_L3S_CLKCTRL_INDEX(0x1c)
+#define AM3_L3S_GPMC_CLKCTRL   AM3_L3S_CLKCTRL_INDEX(0x30)
+#define AM3_L3S_MCASP0_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0x34)
+#define AM3_L3S_MCASP1_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0x68)
+#define AM3_L3S_MMC3_CLKCTRL   AM3_L3S_CLKCTRL_INDEX(0xf8)
+
+/* l3 clocks */
+#define AM3_L3_CLKCTRL_OFFSET  0x24
+#define AM3_L3_CLKCTRL_INDEX(offset)   ((offset) - AM3_L3_CLKCTRL_OFFSET)
+#define AM3_L3_TPTC0_CLKCTRL   AM3_L3_CLKCTRL_INDEX(0x24)
+#define AM3_L3_EMIF_CLKCTRL    AM3_L3_CLKCTRL_INDEX(0x28)
+#define AM3_L3_OCMCRAM_CLKCTRL AM3_L3_CLKCTRL_INDEX(0x2c)
+#define AM3_L3_AES_CLKCTRL     AM3_L3_CLKCTRL_INDEX(0x94)
+#define AM3_L3_SHAM_CLKCTRL    AM3_L3_CLKCTRL_INDEX(0xa0)
+#define AM3_L3_TPCC_CLKCTRL    AM3_L3_CLKCTRL_INDEX(0xbc)
+#define AM3_L3_L3_INSTR_CLKCTRL        AM3_L3_CLKCTRL_INDEX(0xdc)
+#define AM3_L3_L3_MAIN_CLKCTRL AM3_L3_CLKCTRL_INDEX(0xe0)
+#define AM3_L3_TPTC1_CLKCTRL   AM3_L3_CLKCTRL_INDEX(0xfc)
+#define AM3_L3_TPTC2_CLKCTRL   AM3_L3_CLKCTRL_INDEX(0x100)
+
+/* l4hs clocks */
+#define AM3_L4HS_CLKCTRL_OFFSET        0x120
+#define AM3_L4HS_CLKCTRL_INDEX(offset) ((offset) - AM3_L4HS_CLKCTRL_OFFSET)
+#define AM3_L4HS_L4_HS_CLKCTRL AM3_L4HS_CLKCTRL_INDEX(0x120)
+
+/* pruss_ocp clocks */
+#define AM3_PRUSS_OCP_CLKCTRL_OFFSET   0xe8
+#define AM3_PRUSS_OCP_CLKCTRL_INDEX(offset)    ((offset) - AM3_PRUSS_OCP_CLKCTRL_OFFSET)
+#define AM3_PRUSS_OCP_PRUSS_CLKCTRL    AM3_PRUSS_OCP_CLKCTRL_INDEX(0xe8)
+
+/* cpsw_125mhz clocks */
+#define AM3_CPSW_125MHZ_CPGMAC0_CLKCTRL        AM3_CLKCTRL_INDEX(0x14)
+
+/* lcdc clocks */
+#define AM3_LCDC_CLKCTRL_OFFSET        0x18
+#define AM3_LCDC_CLKCTRL_INDEX(offset) ((offset) - AM3_LCDC_CLKCTRL_OFFSET)
+#define AM3_LCDC_LCDC_CLKCTRL  AM3_LCDC_CLKCTRL_INDEX(0x18)
+
+/* clk_24mhz clocks */
+#define AM3_CLK_24MHZ_CLKCTRL_OFFSET   0x14c
+#define AM3_CLK_24MHZ_CLKCTRL_INDEX(offset)    ((offset) - AM3_CLK_24MHZ_CLKCTRL_OFFSET)
+#define AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL        AM3_CLK_24MHZ_CLKCTRL_INDEX(0x14c)
+
+/* l4_wkup clocks */
+#define AM3_L4_WKUP_CONTROL_CLKCTRL    AM3_CLKCTRL_INDEX(0x4)
+#define AM3_L4_WKUP_GPIO1_CLKCTRL      AM3_CLKCTRL_INDEX(0x8)
+#define AM3_L4_WKUP_L4_WKUP_CLKCTRL    AM3_CLKCTRL_INDEX(0xc)
+#define AM3_L4_WKUP_UART1_CLKCTRL      AM3_CLKCTRL_INDEX(0xb4)
+#define AM3_L4_WKUP_I2C1_CLKCTRL       AM3_CLKCTRL_INDEX(0xb8)
+#define AM3_L4_WKUP_ADC_TSC_CLKCTRL    AM3_CLKCTRL_INDEX(0xbc)
+#define AM3_L4_WKUP_SMARTREFLEX0_CLKCTRL       AM3_CLKCTRL_INDEX(0xc0)
+#define AM3_L4_WKUP_TIMER1_CLKCTRL     AM3_CLKCTRL_INDEX(0xc4)
+#define AM3_L4_WKUP_SMARTREFLEX1_CLKCTRL       AM3_CLKCTRL_INDEX(0xc8)
+#define AM3_L4_WKUP_WD_TIMER2_CLKCTRL  AM3_CLKCTRL_INDEX(0xd4)
+
+/* l3_aon clocks */
+#define AM3_L3_AON_CLKCTRL_OFFSET      0x14
+#define AM3_L3_AON_CLKCTRL_INDEX(offset)       ((offset) - AM3_L3_AON_CLKCTRL_OFFSET)
+#define AM3_L3_AON_DEBUGSS_CLKCTRL     AM3_L3_AON_CLKCTRL_INDEX(0x14)
+
+/* l4_wkup_aon clocks */
+#define AM3_L4_WKUP_AON_CLKCTRL_OFFSET 0xb0
+#define AM3_L4_WKUP_AON_CLKCTRL_INDEX(offset)  ((offset) - AM3_L4_WKUP_AON_CLKCTRL_OFFSET)
+#define AM3_L4_WKUP_AON_WKUP_M3_CLKCTRL        AM3_L4_WKUP_AON_CLKCTRL_INDEX(0xb0)
+
+/* mpu clocks */
+#define AM3_MPU_MPU_CLKCTRL    AM3_CLKCTRL_INDEX(0x4)
+
+/* l4_rtc clocks */
+#define AM3_L4_RTC_RTC_CLKCTRL AM3_CLKCTRL_INDEX(0x0)
+
+/* gfx_l3 clocks */
+#define AM3_GFX_L3_GFX_CLKCTRL AM3_CLKCTRL_INDEX(0x4)
+
+/* l4_cefuse clocks */
+#define AM3_L4_CEFUSE_CEFUSE_CLKCTRL   AM3_CLKCTRL_INDEX(0x20)
+
 #endif
index d21df00b32701593a4624eb6b8869a398067a291..0f545b5afd6032fab531542b62c06ea7369115fa 100644 (file)
@@ -16,6 +16,8 @@
 #define AM4_CLKCTRL_OFFSET     0x20
 #define AM4_CLKCTRL_INDEX(offset)      ((offset) - AM4_CLKCTRL_OFFSET)
 
+/* XXX: Compatibility part begin, remove this once compatibility support is no longer needed */
+
 /* l4_wkup clocks */
 #define AM4_ADC_TSC_CLKCTRL    AM4_CLKCTRL_INDEX(0x120)
 #define AM4_L4_WKUP_CLKCTRL    AM4_CLKCTRL_INDEX(0x220)
 #define AM4_DSS_CORE_CLKCTRL   AM4_CLKCTRL_INDEX(0xa20)
 #define AM4_CPGMAC0_CLKCTRL    AM4_CLKCTRL_INDEX(0xb20)
 
+/* XXX: Compatibility part end. */
+
+/* l3s_tsc clocks */
+#define AM4_L3S_TSC_CLKCTRL_OFFSET     0x120
+#define AM4_L3S_TSC_CLKCTRL_INDEX(offset)      ((offset) - AM4_L3S_TSC_CLKCTRL_OFFSET)
+#define AM4_L3S_TSC_ADC_TSC_CLKCTRL    AM4_L3S_TSC_CLKCTRL_INDEX(0x120)
+
+/* l4_wkup_aon clocks */
+#define AM4_L4_WKUP_AON_CLKCTRL_OFFSET 0x228
+#define AM4_L4_WKUP_AON_CLKCTRL_INDEX(offset)  ((offset) - AM4_L4_WKUP_AON_CLKCTRL_OFFSET)
+#define AM4_L4_WKUP_AON_WKUP_M3_CLKCTRL        AM4_L4_WKUP_AON_CLKCTRL_INDEX(0x228)
+#define AM4_L4_WKUP_AON_COUNTER_32K_CLKCTRL    AM4_L4_WKUP_AON_CLKCTRL_INDEX(0x230)
+
+/* l4_wkup clocks */
+#define AM4_L4_WKUP_CLKCTRL_OFFSET     0x220
+#define AM4_L4_WKUP_CLKCTRL_INDEX(offset)      ((offset) - AM4_L4_WKUP_CLKCTRL_OFFSET)
+#define AM4_L4_WKUP_L4_WKUP_CLKCTRL    AM4_L4_WKUP_CLKCTRL_INDEX(0x220)
+#define AM4_L4_WKUP_TIMER1_CLKCTRL     AM4_L4_WKUP_CLKCTRL_INDEX(0x328)
+#define AM4_L4_WKUP_WD_TIMER2_CLKCTRL  AM4_L4_WKUP_CLKCTRL_INDEX(0x338)
+#define AM4_L4_WKUP_I2C1_CLKCTRL       AM4_L4_WKUP_CLKCTRL_INDEX(0x340)
+#define AM4_L4_WKUP_UART1_CLKCTRL      AM4_L4_WKUP_CLKCTRL_INDEX(0x348)
+#define AM4_L4_WKUP_SMARTREFLEX0_CLKCTRL       AM4_L4_WKUP_CLKCTRL_INDEX(0x350)
+#define AM4_L4_WKUP_SMARTREFLEX1_CLKCTRL       AM4_L4_WKUP_CLKCTRL_INDEX(0x358)
+#define AM4_L4_WKUP_CONTROL_CLKCTRL    AM4_L4_WKUP_CLKCTRL_INDEX(0x360)
+#define AM4_L4_WKUP_GPIO1_CLKCTRL      AM4_L4_WKUP_CLKCTRL_INDEX(0x368)
+
+/* mpu clocks */
+#define AM4_MPU_MPU_CLKCTRL    AM4_CLKCTRL_INDEX(0x20)
+
+/* gfx_l3 clocks */
+#define AM4_GFX_L3_GFX_CLKCTRL AM4_CLKCTRL_INDEX(0x20)
+
+/* l4_rtc clocks */
+#define AM4_L4_RTC_RTC_CLKCTRL AM4_CLKCTRL_INDEX(0x20)
+
+/* l3 clocks */
+#define AM4_L3_L3_MAIN_CLKCTRL AM4_CLKCTRL_INDEX(0x20)
+#define AM4_L3_AES_CLKCTRL     AM4_CLKCTRL_INDEX(0x28)
+#define AM4_L3_DES_CLKCTRL     AM4_CLKCTRL_INDEX(0x30)
+#define AM4_L3_L3_INSTR_CLKCTRL        AM4_CLKCTRL_INDEX(0x40)
+#define AM4_L3_OCMCRAM_CLKCTRL AM4_CLKCTRL_INDEX(0x50)
+#define AM4_L3_SHAM_CLKCTRL    AM4_CLKCTRL_INDEX(0x58)
+#define AM4_L3_TPCC_CLKCTRL    AM4_CLKCTRL_INDEX(0x78)
+#define AM4_L3_TPTC0_CLKCTRL   AM4_CLKCTRL_INDEX(0x80)
+#define AM4_L3_TPTC1_CLKCTRL   AM4_CLKCTRL_INDEX(0x88)
+#define AM4_L3_TPTC2_CLKCTRL   AM4_CLKCTRL_INDEX(0x90)
+#define AM4_L3_L4_HS_CLKCTRL   AM4_CLKCTRL_INDEX(0xa0)
+
+/* l3s clocks */
+#define AM4_L3S_CLKCTRL_OFFSET 0x68
+#define AM4_L3S_CLKCTRL_INDEX(offset)  ((offset) - AM4_L3S_CLKCTRL_OFFSET)
+#define AM4_L3S_VPFE0_CLKCTRL  AM4_L3S_CLKCTRL_INDEX(0x68)
+#define AM4_L3S_VPFE1_CLKCTRL  AM4_L3S_CLKCTRL_INDEX(0x70)
+#define AM4_L3S_GPMC_CLKCTRL   AM4_L3S_CLKCTRL_INDEX(0x220)
+#define AM4_L3S_MCASP0_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x238)
+#define AM4_L3S_MCASP1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x240)
+#define AM4_L3S_MMC3_CLKCTRL   AM4_L3S_CLKCTRL_INDEX(0x248)
+#define AM4_L3S_QSPI_CLKCTRL   AM4_L3S_CLKCTRL_INDEX(0x258)
+#define AM4_L3S_USB_OTG_SS0_CLKCTRL    AM4_L3S_CLKCTRL_INDEX(0x260)
+#define AM4_L3S_USB_OTG_SS1_CLKCTRL    AM4_L3S_CLKCTRL_INDEX(0x268)
+
+/* pruss_ocp clocks */
+#define AM4_PRUSS_OCP_CLKCTRL_OFFSET   0x320
+#define AM4_PRUSS_OCP_CLKCTRL_INDEX(offset)    ((offset) - AM4_PRUSS_OCP_CLKCTRL_OFFSET)
+#define AM4_PRUSS_OCP_PRUSS_CLKCTRL    AM4_PRUSS_OCP_CLKCTRL_INDEX(0x320)
+
+/* l4ls clocks */
+#define AM4_L4LS_CLKCTRL_OFFSET        0x420
+#define AM4_L4LS_CLKCTRL_INDEX(offset) ((offset) - AM4_L4LS_CLKCTRL_OFFSET)
+#define AM4_L4LS_L4_LS_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x420)
+#define AM4_L4LS_D_CAN0_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x428)
+#define AM4_L4LS_D_CAN1_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x430)
+#define AM4_L4LS_EPWMSS0_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x438)
+#define AM4_L4LS_EPWMSS1_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x440)
+#define AM4_L4LS_EPWMSS2_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x448)
+#define AM4_L4LS_EPWMSS3_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x450)
+#define AM4_L4LS_EPWMSS4_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x458)
+#define AM4_L4LS_EPWMSS5_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x460)
+#define AM4_L4LS_ELM_CLKCTRL   AM4_L4LS_CLKCTRL_INDEX(0x468)
+#define AM4_L4LS_GPIO2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x478)
+#define AM4_L4LS_GPIO3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x480)
+#define AM4_L4LS_GPIO4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x488)
+#define AM4_L4LS_GPIO5_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x490)
+#define AM4_L4LS_GPIO6_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x498)
+#define AM4_L4LS_HDQ1W_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4a0)
+#define AM4_L4LS_I2C2_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x4a8)
+#define AM4_L4LS_I2C3_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x4b0)
+#define AM4_L4LS_MAILBOX_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x4b8)
+#define AM4_L4LS_MMC1_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x4c0)
+#define AM4_L4LS_MMC2_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x4c8)
+#define AM4_L4LS_RNG_CLKCTRL   AM4_L4LS_CLKCTRL_INDEX(0x4e0)
+#define AM4_L4LS_SPI0_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x500)
+#define AM4_L4LS_SPI1_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x508)
+#define AM4_L4LS_SPI2_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x510)
+#define AM4_L4LS_SPI3_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x518)
+#define AM4_L4LS_SPI4_CLKCTRL  AM4_L4LS_CLKCTRL_INDEX(0x520)
+#define AM4_L4LS_SPINLOCK_CLKCTRL      AM4_L4LS_CLKCTRL_INDEX(0x528)
+#define AM4_L4LS_TIMER2_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x530)
+#define AM4_L4LS_TIMER3_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x538)
+#define AM4_L4LS_TIMER4_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x540)
+#define AM4_L4LS_TIMER5_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x548)
+#define AM4_L4LS_TIMER6_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x550)
+#define AM4_L4LS_TIMER7_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x558)
+#define AM4_L4LS_TIMER8_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x560)
+#define AM4_L4LS_TIMER9_CLKCTRL        AM4_L4LS_CLKCTRL_INDEX(0x568)
+#define AM4_L4LS_TIMER10_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x570)
+#define AM4_L4LS_TIMER11_CLKCTRL       AM4_L4LS_CLKCTRL_INDEX(0x578)
+#define AM4_L4LS_UART2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x580)
+#define AM4_L4LS_UART3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x588)
+#define AM4_L4LS_UART4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x590)
+#define AM4_L4LS_UART5_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x598)
+#define AM4_L4LS_UART6_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x5a0)
+#define AM4_L4LS_OCP2SCP0_CLKCTRL      AM4_L4LS_CLKCTRL_INDEX(0x5b8)
+#define AM4_L4LS_OCP2SCP1_CLKCTRL      AM4_L4LS_CLKCTRL_INDEX(0x5c0)
+
+/* emif clocks */
+#define AM4_EMIF_CLKCTRL_OFFSET        0x720
+#define AM4_EMIF_CLKCTRL_INDEX(offset) ((offset) - AM4_EMIF_CLKCTRL_OFFSET)
+#define AM4_EMIF_EMIF_CLKCTRL  AM4_EMIF_CLKCTRL_INDEX(0x720)
+
+/* dss clocks */
+#define AM4_DSS_CLKCTRL_OFFSET 0xa20
+#define AM4_DSS_CLKCTRL_INDEX(offset)  ((offset) - AM4_DSS_CLKCTRL_OFFSET)
+#define AM4_DSS_DSS_CORE_CLKCTRL       AM4_DSS_CLKCTRL_INDEX(0xa20)
+
+/* cpsw_125mhz clocks */
+#define AM4_CPSW_125MHZ_CLKCTRL_OFFSET 0xb20
+#define AM4_CPSW_125MHZ_CLKCTRL_INDEX(offset)  ((offset) - AM4_CPSW_125MHZ_CLKCTRL_OFFSET)
+#define AM4_CPSW_125MHZ_CPGMAC0_CLKCTRL        AM4_CPSW_125MHZ_CLKCTRL_INDEX(0xb20)
+
 #endif
index ab3ee241d10c50577694ab5eeacabf8c8cabcb39..ed30da28d8203f990dc4d0d21c4d1b9c18af733a 100644 (file)
@@ -9,6 +9,20 @@
 #ifndef _DT_BINDINGS_CLK_AT91_H
 #define _DT_BINDINGS_CLK_AT91_H
 
+#define PMC_TYPE_CORE          0
+#define PMC_TYPE_SYSTEM                1
+#define PMC_TYPE_PERIPHERAL    2
+#define PMC_TYPE_GCK           3
+
+#define PMC_SLOW               0
+#define PMC_MCK                        1
+#define PMC_UTMI               2
+#define PMC_MAIN               3
+#define PMC_MCK2               4
+#define PMC_I2S0_MUX           5
+#define PMC_I2S1_MUX           6
+
+#ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS         0               /* MOSCS Flag */
 #define AT91_PMC_LOCKA         1               /* PLLA Lock */
 #define AT91_PMC_LOCKB         2               /* PLLB Lock */
@@ -19,5 +33,6 @@
 #define AT91_PMC_MOSCRCS       17              /* Main On-Chip RC */
 #define AT91_PMC_CFDEV         18              /* Clock Failure Detector Event */
 #define AT91_PMC_GCKRDY                24              /* Generated Clocks */
+#endif
 
 #endif
index d7549c57cac36c66bae2373eef4e517acb022f7b..ec969b5aeb25d4ce4b5565a658c930a070291896 100644 (file)
 #define DRA7_CLKCTRL_OFFSET    0x20
 #define DRA7_CLKCTRL_INDEX(offset)     ((offset) - DRA7_CLKCTRL_OFFSET)
 
+/* XXX: Compatibility part begin, remove this once compatibility support is no longer needed */
+
 /* mpu clocks */
 #define DRA7_MPU_CLKCTRL       DRA7_CLKCTRL_INDEX(0x20)
 
 /* ipu clocks */
-#define DRA7_IPU_CLKCTRL_OFFSET        0x40
-#define DRA7_IPU_CLKCTRL_INDEX(offset) ((offset) - DRA7_IPU_CLKCTRL_OFFSET)
-#define DRA7_MCASP1_CLKCTRL    DRA7_IPU_CLKCTRL_INDEX(0x50)
-#define DRA7_TIMER5_CLKCTRL    DRA7_IPU_CLKCTRL_INDEX(0x58)
-#define DRA7_TIMER6_CLKCTRL    DRA7_IPU_CLKCTRL_INDEX(0x60)
-#define DRA7_TIMER7_CLKCTRL    DRA7_IPU_CLKCTRL_INDEX(0x68)
-#define DRA7_TIMER8_CLKCTRL    DRA7_IPU_CLKCTRL_INDEX(0x70)
-#define DRA7_I2C5_CLKCTRL      DRA7_IPU_CLKCTRL_INDEX(0x78)
-#define DRA7_UART6_CLKCTRL     DRA7_IPU_CLKCTRL_INDEX(0x80)
+#define _DRA7_IPU_CLKCTRL_OFFSET       0x40
+#define _DRA7_IPU_CLKCTRL_INDEX(offset)        ((offset) - _DRA7_IPU_CLKCTRL_OFFSET)
+#define DRA7_MCASP1_CLKCTRL    _DRA7_IPU_CLKCTRL_INDEX(0x50)
+#define DRA7_TIMER5_CLKCTRL    _DRA7_IPU_CLKCTRL_INDEX(0x58)
+#define DRA7_TIMER6_CLKCTRL    _DRA7_IPU_CLKCTRL_INDEX(0x60)
+#define DRA7_TIMER7_CLKCTRL    _DRA7_IPU_CLKCTRL_INDEX(0x68)
+#define DRA7_TIMER8_CLKCTRL    _DRA7_IPU_CLKCTRL_INDEX(0x70)
+#define DRA7_I2C5_CLKCTRL      _DRA7_IPU_CLKCTRL_INDEX(0x78)
+#define DRA7_UART6_CLKCTRL     _DRA7_IPU_CLKCTRL_INDEX(0x80)
 
 /* rtc clocks */
 #define DRA7_RTC_CLKCTRL_OFFSET        0x40
 #define DRA7_USB_OTG_SS1_CLKCTRL       DRA7_CLKCTRL_INDEX(0xf0)
 
 /* l4per clocks */
-#define DRA7_L4PER_CLKCTRL_OFFSET      0x0
-#define DRA7_L4PER_CLKCTRL_INDEX(offset)       ((offset) - DRA7_L4PER_CLKCTRL_OFFSET)
-#define DRA7_L4_PER2_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0xc)
-#define DRA7_L4_PER3_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0x14)
-#define DRA7_TIMER10_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0x28)
-#define DRA7_TIMER11_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0x30)
-#define DRA7_TIMER2_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x38)
-#define DRA7_TIMER3_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x40)
-#define DRA7_TIMER4_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x48)
-#define DRA7_TIMER9_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x50)
-#define DRA7_ELM_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x58)
-#define DRA7_GPIO2_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x60)
-#define DRA7_GPIO3_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x68)
-#define DRA7_GPIO4_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x70)
-#define DRA7_GPIO5_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x78)
-#define DRA7_GPIO6_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x80)
-#define DRA7_HDQ1W_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x88)
-#define DRA7_EPWMSS1_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0x90)
-#define DRA7_EPWMSS2_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0x98)
-#define DRA7_I2C1_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0xa0)
-#define DRA7_I2C2_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0xa8)
-#define DRA7_I2C3_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0xb0)
-#define DRA7_I2C4_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0xb8)
-#define DRA7_L4_PER1_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0xc0)
-#define DRA7_EPWMSS0_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0xc4)
-#define DRA7_TIMER13_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0xc8)
-#define DRA7_TIMER14_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0xd0)
-#define DRA7_TIMER15_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0xd8)
-#define DRA7_MCSPI1_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0xf0)
-#define DRA7_MCSPI2_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0xf8)
-#define DRA7_MCSPI3_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x100)
-#define DRA7_MCSPI4_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x108)
-#define DRA7_GPIO7_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x110)
-#define DRA7_GPIO8_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x118)
-#define DRA7_MMC3_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x120)
-#define DRA7_MMC4_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x128)
-#define DRA7_TIMER16_CLKCTRL   DRA7_L4PER_CLKCTRL_INDEX(0x130)
-#define DRA7_QSPI_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x138)
-#define DRA7_UART1_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x140)
-#define DRA7_UART2_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x148)
-#define DRA7_UART3_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x150)
-#define DRA7_UART4_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x158)
-#define DRA7_MCASP2_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x160)
-#define DRA7_MCASP3_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x168)
-#define DRA7_UART5_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x170)
-#define DRA7_MCASP5_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x178)
-#define DRA7_MCASP8_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x190)
-#define DRA7_MCASP4_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x198)
-#define DRA7_AES1_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x1a0)
-#define DRA7_AES2_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x1a8)
-#define DRA7_DES_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x1b0)
-#define DRA7_RNG_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x1c0)
-#define DRA7_SHAM_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x1c8)
-#define DRA7_UART7_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x1d0)
-#define DRA7_UART8_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x1e0)
-#define DRA7_UART9_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x1e8)
-#define DRA7_DCAN2_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x1f0)
-#define DRA7_MCASP6_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x204)
-#define DRA7_MCASP7_CLKCTRL    DRA7_L4PER_CLKCTRL_INDEX(0x208)
+#define _DRA7_L4PER_CLKCTRL_OFFSET     0x0
+#define _DRA7_L4PER_CLKCTRL_INDEX(offset)      ((offset) - _DRA7_L4PER_CLKCTRL_OFFSET)
+#define DRA7_L4_PER2_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0xc)
+#define DRA7_L4_PER3_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0x14)
+#define DRA7_TIMER10_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0x28)
+#define DRA7_TIMER11_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0x30)
+#define DRA7_TIMER2_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x38)
+#define DRA7_TIMER3_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x40)
+#define DRA7_TIMER4_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x48)
+#define DRA7_TIMER9_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x50)
+#define DRA7_ELM_CLKCTRL       _DRA7_L4PER_CLKCTRL_INDEX(0x58)
+#define DRA7_GPIO2_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x60)
+#define DRA7_GPIO3_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x68)
+#define DRA7_GPIO4_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x70)
+#define DRA7_GPIO5_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x78)
+#define DRA7_GPIO6_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x80)
+#define DRA7_HDQ1W_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x88)
+#define DRA7_EPWMSS1_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0x90)
+#define DRA7_EPWMSS2_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0x98)
+#define DRA7_I2C1_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0xa0)
+#define DRA7_I2C2_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0xa8)
+#define DRA7_I2C3_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0xb0)
+#define DRA7_I2C4_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0xb8)
+#define DRA7_L4_PER1_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0xc0)
+#define DRA7_EPWMSS0_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0xc4)
+#define DRA7_TIMER13_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0xc8)
+#define DRA7_TIMER14_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0xd0)
+#define DRA7_TIMER15_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0xd8)
+#define DRA7_MCSPI1_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0xf0)
+#define DRA7_MCSPI2_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0xf8)
+#define DRA7_MCSPI3_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x100)
+#define DRA7_MCSPI4_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x108)
+#define DRA7_GPIO7_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x110)
+#define DRA7_GPIO8_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x118)
+#define DRA7_MMC3_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0x120)
+#define DRA7_MMC4_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0x128)
+#define DRA7_TIMER16_CLKCTRL   _DRA7_L4PER_CLKCTRL_INDEX(0x130)
+#define DRA7_QSPI_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0x138)
+#define DRA7_UART1_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x140)
+#define DRA7_UART2_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x148)
+#define DRA7_UART3_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x150)
+#define DRA7_UART4_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x158)
+#define DRA7_MCASP2_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x160)
+#define DRA7_MCASP3_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x168)
+#define DRA7_UART5_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x170)
+#define DRA7_MCASP5_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x178)
+#define DRA7_MCASP8_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x190)
+#define DRA7_MCASP4_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x198)
+#define DRA7_AES1_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0x1a0)
+#define DRA7_AES2_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0x1a8)
+#define DRA7_DES_CLKCTRL       _DRA7_L4PER_CLKCTRL_INDEX(0x1b0)
+#define DRA7_RNG_CLKCTRL       _DRA7_L4PER_CLKCTRL_INDEX(0x1c0)
+#define DRA7_SHAM_CLKCTRL      _DRA7_L4PER_CLKCTRL_INDEX(0x1c8)
+#define DRA7_UART7_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x1d0)
+#define DRA7_UART8_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x1e0)
+#define DRA7_UART9_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x1e8)
+#define DRA7_DCAN2_CLKCTRL     _DRA7_L4PER_CLKCTRL_INDEX(0x1f0)
+#define DRA7_MCASP6_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x204)
+#define DRA7_MCASP7_CLKCTRL    _DRA7_L4PER_CLKCTRL_INDEX(0x208)
 
 /* wkupaon clocks */
 #define DRA7_L4_WKUP_CLKCTRL   DRA7_CLKCTRL_INDEX(0x20)
 #define DRA7_DCAN1_CLKCTRL     DRA7_CLKCTRL_INDEX(0x88)
 #define DRA7_ADC_CLKCTRL       DRA7_CLKCTRL_INDEX(0xa0)
 
+/* XXX: Compatibility part end. */
+
+/* mpu clocks */
+#define DRA7_MPU_MPU_CLKCTRL   DRA7_CLKCTRL_INDEX(0x20)
+
+/* dsp1 clocks */
+#define DRA7_DSP1_MMU0_DSP1_CLKCTRL    DRA7_CLKCTRL_INDEX(0x20)
+
+/* ipu1 clocks */
+#define DRA7_IPU1_MMU_IPU1_CLKCTRL     DRA7_CLKCTRL_INDEX(0x20)
+
+/* ipu clocks */
+#define DRA7_IPU_CLKCTRL_OFFSET        0x50
+#define DRA7_IPU_CLKCTRL_INDEX(offset) ((offset) - DRA7_IPU_CLKCTRL_OFFSET)
+#define DRA7_IPU_MCASP1_CLKCTRL        DRA7_IPU_CLKCTRL_INDEX(0x50)
+#define DRA7_IPU_TIMER5_CLKCTRL        DRA7_IPU_CLKCTRL_INDEX(0x58)
+#define DRA7_IPU_TIMER6_CLKCTRL        DRA7_IPU_CLKCTRL_INDEX(0x60)
+#define DRA7_IPU_TIMER7_CLKCTRL        DRA7_IPU_CLKCTRL_INDEX(0x68)
+#define DRA7_IPU_TIMER8_CLKCTRL        DRA7_IPU_CLKCTRL_INDEX(0x70)
+#define DRA7_IPU_I2C5_CLKCTRL  DRA7_IPU_CLKCTRL_INDEX(0x78)
+#define DRA7_IPU_UART6_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x80)
+
+/* dsp2 clocks */
+#define DRA7_DSP2_MMU0_DSP2_CLKCTRL    DRA7_CLKCTRL_INDEX(0x20)
+
+/* rtc clocks */
+#define DRA7_RTC_RTCSS_CLKCTRL DRA7_CLKCTRL_INDEX(0x44)
+
+/* coreaon clocks */
+#define DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL   DRA7_CLKCTRL_INDEX(0x28)
+#define DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL  DRA7_CLKCTRL_INDEX(0x38)
+
+/* l3main1 clocks */
+#define DRA7_L3MAIN1_L3_MAIN_1_CLKCTRL DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_L3MAIN1_GPMC_CLKCTRL      DRA7_CLKCTRL_INDEX(0x28)
+#define DRA7_L3MAIN1_TPCC_CLKCTRL      DRA7_CLKCTRL_INDEX(0x70)
+#define DRA7_L3MAIN1_TPTC0_CLKCTRL     DRA7_CLKCTRL_INDEX(0x78)
+#define DRA7_L3MAIN1_TPTC1_CLKCTRL     DRA7_CLKCTRL_INDEX(0x80)
+#define DRA7_L3MAIN1_VCP1_CLKCTRL      DRA7_CLKCTRL_INDEX(0x88)
+#define DRA7_L3MAIN1_VCP2_CLKCTRL      DRA7_CLKCTRL_INDEX(0x90)
+
+/* ipu2 clocks */
+#define DRA7_IPU2_MMU_IPU2_CLKCTRL     DRA7_CLKCTRL_INDEX(0x20)
+
+/* dma clocks */
+#define DRA7_DMA_DMA_SYSTEM_CLKCTRL    DRA7_CLKCTRL_INDEX(0x20)
+
+/* emif clocks */
+#define DRA7_EMIF_DMM_CLKCTRL  DRA7_CLKCTRL_INDEX(0x20)
+
+/* atl clocks */
+#define DRA7_ATL_CLKCTRL_OFFSET        0x0
+#define DRA7_ATL_CLKCTRL_INDEX(offset) ((offset) - DRA7_ATL_CLKCTRL_OFFSET)
+#define DRA7_ATL_ATL_CLKCTRL   DRA7_ATL_CLKCTRL_INDEX(0x0)
+
+/* l4cfg clocks */
+#define DRA7_L4CFG_L4_CFG_CLKCTRL      DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_L4CFG_SPINLOCK_CLKCTRL    DRA7_CLKCTRL_INDEX(0x28)
+#define DRA7_L4CFG_MAILBOX1_CLKCTRL    DRA7_CLKCTRL_INDEX(0x30)
+#define DRA7_L4CFG_MAILBOX2_CLKCTRL    DRA7_CLKCTRL_INDEX(0x48)
+#define DRA7_L4CFG_MAILBOX3_CLKCTRL    DRA7_CLKCTRL_INDEX(0x50)
+#define DRA7_L4CFG_MAILBOX4_CLKCTRL    DRA7_CLKCTRL_INDEX(0x58)
+#define DRA7_L4CFG_MAILBOX5_CLKCTRL    DRA7_CLKCTRL_INDEX(0x60)
+#define DRA7_L4CFG_MAILBOX6_CLKCTRL    DRA7_CLKCTRL_INDEX(0x68)
+#define DRA7_L4CFG_MAILBOX7_CLKCTRL    DRA7_CLKCTRL_INDEX(0x70)
+#define DRA7_L4CFG_MAILBOX8_CLKCTRL    DRA7_CLKCTRL_INDEX(0x78)
+#define DRA7_L4CFG_MAILBOX9_CLKCTRL    DRA7_CLKCTRL_INDEX(0x80)
+#define DRA7_L4CFG_MAILBOX10_CLKCTRL   DRA7_CLKCTRL_INDEX(0x88)
+#define DRA7_L4CFG_MAILBOX11_CLKCTRL   DRA7_CLKCTRL_INDEX(0x90)
+#define DRA7_L4CFG_MAILBOX12_CLKCTRL   DRA7_CLKCTRL_INDEX(0x98)
+#define DRA7_L4CFG_MAILBOX13_CLKCTRL   DRA7_CLKCTRL_INDEX(0xa0)
+
+/* l3instr clocks */
+#define DRA7_L3INSTR_L3_MAIN_2_CLKCTRL DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_L3INSTR_L3_INSTR_CLKCTRL  DRA7_CLKCTRL_INDEX(0x28)
+
+/* dss clocks */
+#define DRA7_DSS_DSS_CORE_CLKCTRL      DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_DSS_BB2D_CLKCTRL  DRA7_CLKCTRL_INDEX(0x30)
+
+/* l3init clocks */
+#define DRA7_L3INIT_MMC1_CLKCTRL       DRA7_CLKCTRL_INDEX(0x28)
+#define DRA7_L3INIT_MMC2_CLKCTRL       DRA7_CLKCTRL_INDEX(0x30)
+#define DRA7_L3INIT_USB_OTG_SS2_CLKCTRL        DRA7_CLKCTRL_INDEX(0x40)
+#define DRA7_L3INIT_USB_OTG_SS3_CLKCTRL        DRA7_CLKCTRL_INDEX(0x48)
+#define DRA7_L3INIT_USB_OTG_SS4_CLKCTRL        DRA7_CLKCTRL_INDEX(0x50)
+#define DRA7_L3INIT_SATA_CLKCTRL       DRA7_CLKCTRL_INDEX(0x88)
+#define DRA7_L3INIT_OCP2SCP1_CLKCTRL   DRA7_CLKCTRL_INDEX(0xe0)
+#define DRA7_L3INIT_OCP2SCP3_CLKCTRL   DRA7_CLKCTRL_INDEX(0xe8)
+#define DRA7_L3INIT_USB_OTG_SS1_CLKCTRL        DRA7_CLKCTRL_INDEX(0xf0)
+
+/* pcie clocks */
+#define DRA7_PCIE_CLKCTRL_OFFSET       0xb0
+#define DRA7_PCIE_CLKCTRL_INDEX(offset)        ((offset) - DRA7_PCIE_CLKCTRL_OFFSET)
+#define DRA7_PCIE_PCIE1_CLKCTRL        DRA7_PCIE_CLKCTRL_INDEX(0xb0)
+#define DRA7_PCIE_PCIE2_CLKCTRL        DRA7_PCIE_CLKCTRL_INDEX(0xb8)
+
+/* gmac clocks */
+#define DRA7_GMAC_CLKCTRL_OFFSET       0xd0
+#define DRA7_GMAC_CLKCTRL_INDEX(offset)        ((offset) - DRA7_GMAC_CLKCTRL_OFFSET)
+#define DRA7_GMAC_GMAC_CLKCTRL DRA7_GMAC_CLKCTRL_INDEX(0xd0)
+
+/* l4per clocks */
+#define DRA7_L4PER_CLKCTRL_OFFSET      0x28
+#define DRA7_L4PER_CLKCTRL_INDEX(offset)       ((offset) - DRA7_L4PER_CLKCTRL_OFFSET)
+#define DRA7_L4PER_TIMER10_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x28)
+#define DRA7_L4PER_TIMER11_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0x30)
+#define DRA7_L4PER_TIMER2_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x38)
+#define DRA7_L4PER_TIMER3_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x40)
+#define DRA7_L4PER_TIMER4_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x48)
+#define DRA7_L4PER_TIMER9_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x50)
+#define DRA7_L4PER_ELM_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x58)
+#define DRA7_L4PER_GPIO2_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x60)
+#define DRA7_L4PER_GPIO3_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x68)
+#define DRA7_L4PER_GPIO4_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x70)
+#define DRA7_L4PER_GPIO5_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x78)
+#define DRA7_L4PER_GPIO6_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x80)
+#define DRA7_L4PER_HDQ1W_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x88)
+#define DRA7_L4PER_I2C1_CLKCTRL        DRA7_L4PER_CLKCTRL_INDEX(0xa0)
+#define DRA7_L4PER_I2C2_CLKCTRL        DRA7_L4PER_CLKCTRL_INDEX(0xa8)
+#define DRA7_L4PER_I2C3_CLKCTRL        DRA7_L4PER_CLKCTRL_INDEX(0xb0)
+#define DRA7_L4PER_I2C4_CLKCTRL        DRA7_L4PER_CLKCTRL_INDEX(0xb8)
+#define DRA7_L4PER_L4_PER1_CLKCTRL     DRA7_L4PER_CLKCTRL_INDEX(0xc0)
+#define DRA7_L4PER_MCSPI1_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0xf0)
+#define DRA7_L4PER_MCSPI2_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0xf8)
+#define DRA7_L4PER_MCSPI3_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x100)
+#define DRA7_L4PER_MCSPI4_CLKCTRL      DRA7_L4PER_CLKCTRL_INDEX(0x108)
+#define DRA7_L4PER_GPIO7_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x110)
+#define DRA7_L4PER_GPIO8_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x118)
+#define DRA7_L4PER_MMC3_CLKCTRL        DRA7_L4PER_CLKCTRL_INDEX(0x120)
+#define DRA7_L4PER_MMC4_CLKCTRL        DRA7_L4PER_CLKCTRL_INDEX(0x128)
+#define DRA7_L4PER_UART1_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x140)
+#define DRA7_L4PER_UART2_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x148)
+#define DRA7_L4PER_UART3_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x150)
+#define DRA7_L4PER_UART4_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x158)
+#define DRA7_L4PER_UART5_CLKCTRL       DRA7_L4PER_CLKCTRL_INDEX(0x170)
+
+/* l4sec clocks */
+#define DRA7_L4SEC_CLKCTRL_OFFSET      0x1a0
+#define DRA7_L4SEC_CLKCTRL_INDEX(offset)       ((offset) - DRA7_L4SEC_CLKCTRL_OFFSET)
+#define DRA7_L4SEC_AES1_CLKCTRL        DRA7_L4SEC_CLKCTRL_INDEX(0x1a0)
+#define DRA7_L4SEC_AES2_CLKCTRL        DRA7_L4SEC_CLKCTRL_INDEX(0x1a8)
+#define DRA7_L4SEC_DES_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1b0)
+#define DRA7_L4SEC_RNG_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1c0)
+#define DRA7_L4SEC_SHAM_CLKCTRL        DRA7_L4SEC_CLKCTRL_INDEX(0x1c8)
+
+/* l4per2 clocks */
+#define DRA7_L4PER2_CLKCTRL_OFFSET     0xc
+#define DRA7_L4PER2_CLKCTRL_INDEX(offset)      ((offset) - DRA7_L4PER2_CLKCTRL_OFFSET)
+#define DRA7_L4PER2_L4_PER2_CLKCTRL    DRA7_L4PER2_CLKCTRL_INDEX(0xc)
+#define DRA7_L4PER2_PRUSS1_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x18)
+#define DRA7_L4PER2_PRUSS2_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x20)
+#define DRA7_L4PER2_EPWMSS1_CLKCTRL    DRA7_L4PER2_CLKCTRL_INDEX(0x90)
+#define DRA7_L4PER2_EPWMSS2_CLKCTRL    DRA7_L4PER2_CLKCTRL_INDEX(0x98)
+#define DRA7_L4PER2_EPWMSS0_CLKCTRL    DRA7_L4PER2_CLKCTRL_INDEX(0xc4)
+#define DRA7_L4PER2_QSPI_CLKCTRL       DRA7_L4PER2_CLKCTRL_INDEX(0x138)
+#define DRA7_L4PER2_MCASP2_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x160)
+#define DRA7_L4PER2_MCASP3_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x168)
+#define DRA7_L4PER2_MCASP5_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x178)
+#define DRA7_L4PER2_MCASP8_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x190)
+#define DRA7_L4PER2_MCASP4_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x198)
+#define DRA7_L4PER2_UART7_CLKCTRL      DRA7_L4PER2_CLKCTRL_INDEX(0x1d0)
+#define DRA7_L4PER2_UART8_CLKCTRL      DRA7_L4PER2_CLKCTRL_INDEX(0x1e0)
+#define DRA7_L4PER2_UART9_CLKCTRL      DRA7_L4PER2_CLKCTRL_INDEX(0x1e8)
+#define DRA7_L4PER2_DCAN2_CLKCTRL      DRA7_L4PER2_CLKCTRL_INDEX(0x1f0)
+#define DRA7_L4PER2_MCASP6_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x204)
+#define DRA7_L4PER2_MCASP7_CLKCTRL     DRA7_L4PER2_CLKCTRL_INDEX(0x208)
+
+/* l4per3 clocks */
+#define DRA7_L4PER3_CLKCTRL_OFFSET     0x14
+#define DRA7_L4PER3_CLKCTRL_INDEX(offset)      ((offset) - DRA7_L4PER3_CLKCTRL_OFFSET)
+#define DRA7_L4PER3_L4_PER3_CLKCTRL    DRA7_L4PER3_CLKCTRL_INDEX(0x14)
+#define DRA7_L4PER3_TIMER13_CLKCTRL    DRA7_L4PER3_CLKCTRL_INDEX(0xc8)
+#define DRA7_L4PER3_TIMER14_CLKCTRL    DRA7_L4PER3_CLKCTRL_INDEX(0xd0)
+#define DRA7_L4PER3_TIMER15_CLKCTRL    DRA7_L4PER3_CLKCTRL_INDEX(0xd8)
+#define DRA7_L4PER3_TIMER16_CLKCTRL    DRA7_L4PER3_CLKCTRL_INDEX(0x130)
+
+/* wkupaon clocks */
+#define DRA7_WKUPAON_L4_WKUP_CLKCTRL   DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_WKUPAON_WD_TIMER2_CLKCTRL DRA7_CLKCTRL_INDEX(0x30)
+#define DRA7_WKUPAON_GPIO1_CLKCTRL     DRA7_CLKCTRL_INDEX(0x38)
+#define DRA7_WKUPAON_TIMER1_CLKCTRL    DRA7_CLKCTRL_INDEX(0x40)
+#define DRA7_WKUPAON_TIMER12_CLKCTRL   DRA7_CLKCTRL_INDEX(0x48)
+#define DRA7_WKUPAON_COUNTER_32K_CLKCTRL       DRA7_CLKCTRL_INDEX(0x50)
+#define DRA7_WKUPAON_UART10_CLKCTRL    DRA7_CLKCTRL_INDEX(0x80)
+#define DRA7_WKUPAON_DCAN1_CLKCTRL     DRA7_CLKCTRL_INDEX(0x88)
+#define DRA7_WKUPAON_ADC_CLKCTRL       DRA7_CLKCTRL_INDEX(0xa0)
+
 #endif
index 5b1d685123607c49bcea8f12a6bd7163d6e18a5b..a0439ce8e8d332fc9ced4807d6605dfd712445a4 100644 (file)
 #define CLK_MIPI_HSI           349 /* Exynos4210 only */
 #define CLK_PIXELASYNCM0       351
 #define CLK_PIXELASYNCM1       352
-#define CLK_FIMC_LITE0         353 /* Exynos4x12 only */
-#define CLK_FIMC_LITE1         354 /* Exynos4x12 only */
-#define CLK_PPMUISPX           355 /* Exynos4x12 only */
-#define CLK_PPMUISPMX          356 /* Exynos4x12 only */
-#define CLK_FIMC_ISP           357 /* Exynos4x12 only */
-#define CLK_FIMC_DRC           358 /* Exynos4x12 only */
-#define CLK_FIMC_FD            359 /* Exynos4x12 only */
-#define CLK_MCUISP             360 /* Exynos4x12 only */
-#define CLK_GICISP             361 /* Exynos4x12 only */
-#define CLK_SMMU_ISP           362 /* Exynos4x12 only */
-#define CLK_SMMU_DRC           363 /* Exynos4x12 only */
-#define CLK_SMMU_FD            364 /* Exynos4x12 only */
-#define CLK_SMMU_LITE0         365 /* Exynos4x12 only */
-#define CLK_SMMU_LITE1         366 /* Exynos4x12 only */
-#define CLK_MCUCTL_ISP         367 /* Exynos4x12 only */
-#define CLK_MPWM_ISP           368 /* Exynos4x12 only */
-#define CLK_I2C0_ISP           369 /* Exynos4x12 only */
-#define CLK_I2C1_ISP           370 /* Exynos4x12 only */
-#define CLK_MTCADC_ISP         371 /* Exynos4x12 only */
-#define CLK_PWM_ISP            372 /* Exynos4x12 only */
-#define CLK_WDT_ISP            373 /* Exynos4x12 only */
-#define CLK_UART_ISP           374 /* Exynos4x12 only */
-#define CLK_ASYNCAXIM          375 /* Exynos4x12 only */
-#define CLK_SMMU_ISPCX         376 /* Exynos4x12 only */
-#define CLK_SPI0_ISP           377 /* Exynos4x12 only */
-#define CLK_SPI1_ISP           378 /* Exynos4x12 only */
 #define CLK_PWM_ISP_SCLK       379 /* Exynos4x12 only */
 #define CLK_SPI0_ISP_SCLK      380 /* Exynos4x12 only */
 #define CLK_SPI1_ISP_SCLK      381 /* Exynos4x12 only */
 #define CLK_PPMUACP            415
 
 /* div clocks */
-#define CLK_DIV_ISP0           450 /* Exynos4x12 only */
-#define CLK_DIV_ISP1           451 /* Exynos4x12 only */
-#define CLK_DIV_MCUISP0                452 /* Exynos4x12 only */
-#define CLK_DIV_MCUISP1                453 /* Exynos4x12 only */
 #define CLK_DIV_ACLK200                454 /* Exynos4x12 only */
 #define CLK_DIV_ACLK400_MCUISP 455 /* Exynos4x12 only */
 #define CLK_DIV_ACP            456
diff --git a/include/dt-bindings/clock/hi3670-clock.h b/include/dt-bindings/clock/hi3670-clock.h
new file mode 100644 (file)
index 0000000..fa48583
--- /dev/null
@@ -0,0 +1,348 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Device Tree binding constants for HiSilicon Hi3670 SoC
+ *
+ * Copyright (c) 2001-2021, Huawei Tech. Co., Ltd.
+ * Copyright (c) 2018 Linaro Ltd.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_HI3670_H
+#define __DT_BINDINGS_CLOCK_HI3670_H
+
+/* clk in stub clock */
+#define HI3670_CLK_STUB_CLUSTER0               0
+#define HI3670_CLK_STUB_CLUSTER1               1
+#define HI3670_CLK_STUB_GPU                    2
+#define HI3670_CLK_STUB_DDR                    3
+#define HI3670_CLK_STUB_DDR_VOTE               4
+#define HI3670_CLK_STUB_DDR_LIMIT              5
+#define HI3670_CLK_STUB_NUM                    6
+
+/* clk in crg clock */
+#define HI3670_CLKIN_SYS                       0
+#define HI3670_CLKIN_REF                       1
+#define HI3670_CLK_FLL_SRC                     2
+#define HI3670_CLK_PPLL0                       3
+#define HI3670_CLK_PPLL1                       4
+#define HI3670_CLK_PPLL2                       5
+#define HI3670_CLK_PPLL3                       6
+#define HI3670_CLK_PPLL4                       7
+#define HI3670_CLK_PPLL6                       8
+#define HI3670_CLK_PPLL7                       9
+#define HI3670_CLK_PPLL_PCIE                   10
+#define HI3670_CLK_PCIEPLL_REV                 11
+#define HI3670_CLK_SCPLL                       12
+#define HI3670_PCLK                            13
+#define HI3670_CLK_UART0_DBG                   14
+#define HI3670_CLK_UART6                       15
+#define HI3670_OSC32K                          16
+#define HI3670_OSC19M                          17
+#define HI3670_CLK_480M                                18
+#define HI3670_CLK_INVALID                     19
+#define HI3670_CLK_DIV_SYSBUS                  20
+#define HI3670_CLK_FACTOR_MMC                  21
+#define HI3670_CLK_SD_SYS                      22
+#define HI3670_CLK_SDIO_SYS                    23
+#define HI3670_CLK_DIV_A53HPM                  24
+#define HI3670_CLK_DIV_320M                    25
+#define HI3670_PCLK_GATE_UART0                 26
+#define HI3670_CLK_FACTOR_UART0                        27
+#define HI3670_CLK_FACTOR_USB3PHY_PLL          28
+#define HI3670_CLK_GATE_ABB_USB                        29
+#define HI3670_CLK_GATE_UFSPHY_REF             30
+#define HI3670_ICS_VOLT_HIGH                   31
+#define HI3670_ICS_VOLT_MIDDLE                 32
+#define HI3670_VENC_VOLT_HOLD                  33
+#define HI3670_VDEC_VOLT_HOLD                  34
+#define HI3670_EDC_VOLT_HOLD                   35
+#define HI3670_CLK_ISP_SNCLK_FAC               36
+#define HI3670_CLK_FACTOR_RXDPHY               37
+#define HI3670_AUTODIV_SYSBUS                  38
+#define HI3670_AUTODIV_EMMC0BUS                        39
+#define HI3670_PCLK_ANDGT_MMC1_PCIE            40
+#define HI3670_CLK_GATE_VCODECBUS_GT           41
+#define HI3670_CLK_ANDGT_SD                    42
+#define HI3670_CLK_SD_SYS_GT                   43
+#define HI3670_CLK_ANDGT_SDIO                  44
+#define HI3670_CLK_SDIO_SYS_GT                 45
+#define HI3670_CLK_A53HPM_ANDGT                        46
+#define HI3670_CLK_320M_PLL_GT                 47
+#define HI3670_CLK_ANDGT_UARTH                 48
+#define HI3670_CLK_ANDGT_UARTL                 49
+#define HI3670_CLK_ANDGT_UART0                 50
+#define HI3670_CLK_ANDGT_SPI                   51
+#define HI3670_CLK_ANDGT_PCIEAXI               52
+#define HI3670_CLK_DIV_AO_ASP_GT               53
+#define HI3670_CLK_GATE_CSI_TRANS              54
+#define HI3670_CLK_GATE_DSI_TRANS              55
+#define HI3670_CLK_ANDGT_PTP                   56
+#define HI3670_CLK_ANDGT_OUT0                  57
+#define HI3670_CLK_ANDGT_OUT1                  58
+#define HI3670_CLKGT_DP_AUDIO_PLL_AO           59
+#define HI3670_CLK_ANDGT_VDEC                  60
+#define HI3670_CLK_ANDGT_VENC                  61
+#define HI3670_CLK_ISP_SNCLK_ANGT              62
+#define HI3670_CLK_ANDGT_RXDPHY                        63
+#define HI3670_CLK_ANDGT_ICS                   64
+#define HI3670_AUTODIV_DMABUS                  65
+#define HI3670_CLK_MUX_SYSBUS                  66
+#define HI3670_CLK_MUX_VCODECBUS               67
+#define HI3670_CLK_MUX_SD_SYS                  68
+#define HI3670_CLK_MUX_SD_PLL                  69
+#define HI3670_CLK_MUX_SDIO_SYS                        70
+#define HI3670_CLK_MUX_SDIO_PLL                        71
+#define HI3670_CLK_MUX_A53HPM                  72
+#define HI3670_CLK_MUX_320M                    73
+#define HI3670_CLK_MUX_UARTH                   74
+#define HI3670_CLK_MUX_UARTL                   75
+#define HI3670_CLK_MUX_UART0                   76
+#define HI3670_CLK_MUX_I2C                     77
+#define HI3670_CLK_MUX_SPI                     78
+#define HI3670_CLK_MUX_PCIEAXI                 79
+#define HI3670_CLK_MUX_AO_ASP                  80
+#define HI3670_CLK_MUX_VDEC                    81
+#define HI3670_CLK_MUX_VENC                    82
+#define HI3670_CLK_ISP_SNCLK_MUX0              83
+#define HI3670_CLK_ISP_SNCLK_MUX1              84
+#define HI3670_CLK_ISP_SNCLK_MUX2              85
+#define HI3670_CLK_MUX_RXDPHY_CFG              86
+#define HI3670_CLK_MUX_ICS                     87
+#define HI3670_CLK_DIV_CFGBUS                  88
+#define HI3670_CLK_DIV_MMC0BUS                 89
+#define HI3670_CLK_DIV_MMC1BUS                 90
+#define HI3670_PCLK_DIV_MMC1_PCIE              91
+#define HI3670_CLK_DIV_VCODECBUS               92
+#define HI3670_CLK_DIV_SD                      93
+#define HI3670_CLK_DIV_SDIO                    94
+#define HI3670_CLK_DIV_UARTH                   95
+#define HI3670_CLK_DIV_UARTL                   96
+#define HI3670_CLK_DIV_UART0                   97
+#define HI3670_CLK_DIV_I2C                     98
+#define HI3670_CLK_DIV_SPI                     99
+#define HI3670_CLK_DIV_PCIEAXI                 100
+#define HI3670_CLK_DIV_AO_ASP                  101
+#define HI3670_CLK_DIV_CSI_TRANS               102
+#define HI3670_CLK_DIV_DSI_TRANS               103
+#define HI3670_CLK_DIV_PTP                     104
+#define HI3670_CLK_DIV_CLKOUT0_PLL             105
+#define HI3670_CLK_DIV_CLKOUT1_PLL             106
+#define HI3670_CLKDIV_DP_AUDIO_PLL_AO          107
+#define HI3670_CLK_DIV_VDEC                    108
+#define HI3670_CLK_DIV_VENC                    109
+#define HI3670_CLK_ISP_SNCLK_DIV0              110
+#define HI3670_CLK_ISP_SNCLK_DIV1              111
+#define HI3670_CLK_ISP_SNCLK_DIV2              112
+#define HI3670_CLK_DIV_ICS                     113
+#define HI3670_PPLL1_EN_ACPU                   114
+#define HI3670_PPLL2_EN_ACPU                   115
+#define HI3670_PPLL3_EN_ACPU                   116
+#define HI3670_PPLL1_GT_CPU                    117
+#define HI3670_PPLL2_GT_CPU                    118
+#define HI3670_PPLL3_GT_CPU                    119
+#define HI3670_CLK_GATE_PPLL2_MEDIA            120
+#define HI3670_CLK_GATE_PPLL3_MEDIA            121
+#define HI3670_CLK_GATE_PPLL4_MEDIA            122
+#define HI3670_CLK_GATE_PPLL6_MEDIA            123
+#define HI3670_CLK_GATE_PPLL7_MEDIA            124
+#define HI3670_PCLK_GPIO0                      125
+#define HI3670_PCLK_GPIO1                      126
+#define HI3670_PCLK_GPIO2                      127
+#define HI3670_PCLK_GPIO3                      128
+#define HI3670_PCLK_GPIO4                      129
+#define HI3670_PCLK_GPIO5                      130
+#define HI3670_PCLK_GPIO6                      131
+#define HI3670_PCLK_GPIO7                      132
+#define HI3670_PCLK_GPIO8                      133
+#define HI3670_PCLK_GPIO9                      134
+#define HI3670_PCLK_GPIO10                     135
+#define HI3670_PCLK_GPIO11                     136
+#define HI3670_PCLK_GPIO12                     137
+#define HI3670_PCLK_GPIO13                     138
+#define HI3670_PCLK_GPIO14                     139
+#define HI3670_PCLK_GPIO15                     140
+#define HI3670_PCLK_GPIO16                     141
+#define HI3670_PCLK_GPIO17                     142
+#define HI3670_PCLK_GPIO20                     143
+#define HI3670_PCLK_GPIO21                     144
+#define HI3670_PCLK_GATE_DSI0                  145
+#define HI3670_PCLK_GATE_DSI1                  146
+#define HI3670_HCLK_GATE_USB3OTG               147
+#define HI3670_ACLK_GATE_USB3DVFS              148
+#define HI3670_HCLK_GATE_SDIO                  149
+#define HI3670_PCLK_GATE_PCIE_SYS              150
+#define HI3670_PCLK_GATE_PCIE_PHY              151
+#define HI3670_PCLK_GATE_MMC1_PCIE             152
+#define HI3670_PCLK_GATE_MMC0_IOC              153
+#define HI3670_PCLK_GATE_MMC1_IOC              154
+#define HI3670_CLK_GATE_DMAC                   155
+#define HI3670_CLK_GATE_VCODECBUS2DDR          156
+#define HI3670_CLK_CCI400_BYPASS               157
+#define HI3670_CLK_GATE_CCI400                 158
+#define HI3670_CLK_GATE_SD                     159
+#define HI3670_HCLK_GATE_SD                    160
+#define HI3670_CLK_GATE_SDIO                   161
+#define HI3670_CLK_GATE_A57HPM                 162
+#define HI3670_CLK_GATE_A53HPM                 163
+#define HI3670_CLK_GATE_PA_A53                 164
+#define HI3670_CLK_GATE_PA_A57                 165
+#define HI3670_CLK_GATE_PA_G3D                 166
+#define HI3670_CLK_GATE_GPUHPM                 167
+#define HI3670_CLK_GATE_PERIHPM                        168
+#define HI3670_CLK_GATE_AOHPM                  169
+#define HI3670_CLK_GATE_UART1                  170
+#define HI3670_CLK_GATE_UART4                  171
+#define HI3670_PCLK_GATE_UART1                 172
+#define HI3670_PCLK_GATE_UART4                 173
+#define HI3670_CLK_GATE_UART2                  174
+#define HI3670_CLK_GATE_UART5                  175
+#define HI3670_PCLK_GATE_UART2                 176
+#define HI3670_PCLK_GATE_UART5                 177
+#define HI3670_CLK_GATE_UART0                  178
+#define HI3670_CLK_GATE_I2C3                   179
+#define HI3670_CLK_GATE_I2C4                   180
+#define HI3670_CLK_GATE_I2C7                   181
+#define HI3670_PCLK_GATE_I2C3                  182
+#define HI3670_PCLK_GATE_I2C4                  183
+#define HI3670_PCLK_GATE_I2C7                  184
+#define HI3670_CLK_GATE_SPI1                   185
+#define HI3670_CLK_GATE_SPI4                   186
+#define HI3670_PCLK_GATE_SPI1                  187
+#define HI3670_PCLK_GATE_SPI4                  188
+#define HI3670_CLK_GATE_USB3OTG_REF            189
+#define HI3670_CLK_GATE_USB2PHY_REF            190
+#define HI3670_CLK_GATE_PCIEAUX                        191
+#define HI3670_ACLK_GATE_PCIE                  192
+#define HI3670_CLK_GATE_MMC1_PCIEAXI           193
+#define HI3670_CLK_GATE_PCIEPHY_REF            194
+#define HI3670_CLK_GATE_PCIE_DEBOUNCE          195
+#define HI3670_CLK_GATE_PCIEIO                 196
+#define HI3670_CLK_GATE_PCIE_HP                        197
+#define HI3670_CLK_GATE_AO_ASP                 198
+#define HI3670_PCLK_GATE_PCTRL                 199
+#define HI3670_CLK_CSI_TRANS_GT                        200
+#define HI3670_CLK_DSI_TRANS_GT                        201
+#define HI3670_CLK_GATE_PWM                    202
+#define HI3670_ABB_AUDIO_EN0                   203
+#define HI3670_ABB_AUDIO_EN1                   204
+#define HI3670_ABB_AUDIO_GT_EN0                        205
+#define HI3670_ABB_AUDIO_GT_EN1                        206
+#define HI3670_CLK_GATE_DP_AUDIO_PLL_AO                207
+#define HI3670_PERI_VOLT_HOLD                  208
+#define HI3670_PERI_VOLT_MIDDLE                        209
+#define HI3670_CLK_GATE_ISP_SNCLK0             210
+#define HI3670_CLK_GATE_ISP_SNCLK1             211
+#define HI3670_CLK_GATE_ISP_SNCLK2             212
+#define HI3670_CLK_GATE_RXDPHY0_CFG            213
+#define HI3670_CLK_GATE_RXDPHY1_CFG            214
+#define HI3670_CLK_GATE_RXDPHY2_CFG            215
+#define HI3670_CLK_GATE_TXDPHY0_CFG            216
+#define HI3670_CLK_GATE_TXDPHY0_REF            217
+#define HI3670_CLK_GATE_TXDPHY1_CFG            218
+#define HI3670_CLK_GATE_TXDPHY1_REF            219
+#define HI3670_CLK_GATE_MEDIA_TCXO             220
+
+/* clk in sctrl */
+#define HI3670_CLK_ANDGT_IOPERI                        0
+#define HI3670_CLKANDGT_ASP_SUBSYS_PERI                1
+#define HI3670_CLK_ANGT_ASP_SUBSYS             2
+#define HI3670_CLK_MUX_UFS_SUBSYS              3
+#define HI3670_CLK_MUX_CLKOUT0                 4
+#define HI3670_CLK_MUX_CLKOUT1                 5
+#define HI3670_CLK_MUX_ASP_SUBSYS_PERI         6
+#define HI3670_CLK_MUX_ASP_PLL                 7
+#define HI3670_CLK_DIV_AOBUS                   8
+#define HI3670_CLK_DIV_UFS_SUBSYS              9
+#define HI3670_CLK_DIV_IOPERI                  10
+#define HI3670_CLK_DIV_CLKOUT0_TCXO            11
+#define HI3670_CLK_DIV_CLKOUT1_TCXO            12
+#define HI3670_CLK_ASP_SUBSYS_PERI_DIV         13
+#define HI3670_CLK_DIV_ASP_SUBSYS              14
+#define HI3670_PPLL0_EN_ACPU                   15
+#define HI3670_PPLL0_GT_CPU                    16
+#define HI3670_CLK_GATE_PPLL0_MEDIA            17
+#define HI3670_PCLK_GPIO18                     18
+#define HI3670_PCLK_GPIO19                     19
+#define HI3670_CLK_GATE_SPI                    20
+#define HI3670_PCLK_GATE_SPI                   21
+#define HI3670_CLK_GATE_UFS_SUBSYS             22
+#define HI3670_CLK_GATE_UFSIO_REF              23
+#define HI3670_PCLK_AO_GPIO0                   24
+#define HI3670_PCLK_AO_GPIO1                   25
+#define HI3670_PCLK_AO_GPIO2                   26
+#define HI3670_PCLK_AO_GPIO3                   27
+#define HI3670_PCLK_AO_GPIO4                   28
+#define HI3670_PCLK_AO_GPIO5                   29
+#define HI3670_PCLK_AO_GPIO6                   30
+#define HI3670_CLK_GATE_OUT0                   31
+#define HI3670_CLK_GATE_OUT1                   32
+#define HI3670_PCLK_GATE_SYSCNT                        33
+#define HI3670_CLK_GATE_SYSCNT                 34
+#define HI3670_CLK_GATE_ASP_SUBSYS_PERI                35
+#define HI3670_CLK_GATE_ASP_SUBSYS             36
+#define HI3670_CLK_GATE_ASP_TCXO               37
+#define HI3670_CLK_GATE_DP_AUDIO_PLL           38
+
+/* clk in pmuctrl */
+#define HI3670_GATE_ABB_192                    0
+
+/* clk in pctrl */
+#define HI3670_GATE_UFS_TCXO_EN                        0
+#define HI3670_GATE_USB_TCXO_EN                        1
+
+/* clk in iomcu */
+#define HI3670_CLK_GATE_I2C0                   0
+#define HI3670_CLK_GATE_I2C1                   1
+#define HI3670_CLK_GATE_I2C2                   2
+#define HI3670_CLK_GATE_SPI0                   3
+#define HI3670_CLK_GATE_SPI2                   4
+#define HI3670_CLK_GATE_UART3                  5
+#define HI3670_CLK_I2C0_GATE_IOMCU             6
+#define HI3670_CLK_I2C1_GATE_IOMCU             7
+#define HI3670_CLK_I2C2_GATE_IOMCU             8
+#define HI3670_CLK_SPI0_GATE_IOMCU             9
+#define HI3670_CLK_SPI2_GATE_IOMCU             10
+#define HI3670_CLK_UART3_GATE_IOMCU            11
+#define HI3670_CLK_GATE_PERI0_IOMCU            12
+
+/* clk in media1 */
+#define HI3670_CLK_GATE_VIVOBUS_ANDGT          0
+#define HI3670_CLK_ANDGT_EDC0                  1
+#define HI3670_CLK_ANDGT_LDI0                  2
+#define HI3670_CLK_ANDGT_LDI1                  3
+#define HI3670_CLK_MMBUF_PLL_ANDGT             4
+#define HI3670_PCLK_MMBUF_ANDGT                        5
+#define HI3670_CLK_MUX_VIVOBUS                 6
+#define HI3670_CLK_MUX_EDC0                    7
+#define HI3670_CLK_MUX_LDI0                    8
+#define HI3670_CLK_MUX_LDI1                    9
+#define HI3670_CLK_SW_MMBUF                    10
+#define HI3670_CLK_DIV_VIVOBUS                 11
+#define HI3670_CLK_DIV_EDC0                    12
+#define HI3670_CLK_DIV_LDI0                    13
+#define HI3670_CLK_DIV_LDI1                    14
+#define HI3670_ACLK_DIV_MMBUF                  15
+#define HI3670_PCLK_DIV_MMBUF                  16
+#define HI3670_ACLK_GATE_NOC_DSS               17
+#define HI3670_PCLK_GATE_NOC_DSS_CFG           18
+#define HI3670_PCLK_GATE_MMBUF_CFG             19
+#define HI3670_PCLK_GATE_DISP_NOC_SUBSYS       20
+#define HI3670_ACLK_GATE_DISP_NOC_SUBSYS       21
+#define HI3670_PCLK_GATE_DSS                   22
+#define HI3670_ACLK_GATE_DSS                   23
+#define HI3670_CLK_GATE_VIVOBUSFREQ            24
+#define HI3670_CLK_GATE_EDC0                   25
+#define HI3670_CLK_GATE_LDI0                   26
+#define HI3670_CLK_GATE_LDI1FREQ               27
+#define HI3670_CLK_GATE_BRG                    28
+#define HI3670_ACLK_GATE_ASC                   29
+#define HI3670_CLK_GATE_DSS_AXI_MM             30
+#define HI3670_CLK_GATE_MMBUF                  31
+#define HI3670_PCLK_GATE_MMBUF                 32
+#define HI3670_CLK_GATE_ATDIV_VIVO             33
+
+/* clk in media2 */
+#define HI3670_CLK_GATE_VDECFREQ               0
+#define HI3670_CLK_GATE_VENCFREQ               1
+#define HI3670_CLK_GATE_ICSFREQ                        2
+
+#endif /* __DT_BINDINGS_CLOCK_HI3670_H */
index 7ad171b8f3bfc0e7e72b67083e7110a5fee4d02c..87b068f4a9982785e30f80e23c2c33952fd17bb9 100644 (file)
 #define IMX6QDL_CLK_MLB_PODF                   260
 #define IMX6QDL_CLK_EPIT1                      261
 #define IMX6QDL_CLK_EPIT2                      262
-#define IMX6QDL_CLK_END                                263
+#define IMX6QDL_CLK_MMDC_P0_IPG                        263
+#define IMX6QDL_CLK_END                                264
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
index e14573e293c5a0ae56953445ad73bc616dac6485..cfbfc39d1878ab4c920875da810590bd4438fbbb 100644 (file)
 #define IMX6SL_CLK_SSI2_IPG            162
 #define IMX6SL_CLK_SSI3_IPG            163
 #define IMX6SL_CLK_SPDIF_GCLK          164
-#define IMX6SL_CLK_END                 165
+#define IMX6SL_CLK_MMDC_P0_IPG         165
+#define IMX6SL_CLK_MMDC_P1_IPG         166
+#define IMX6SL_CLK_END                 167
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
index 1036475f997d8436c944aca18d3a46a72a0de5c9..f446710fe63d0a56cd894a3bca13d95479e1b39a 100644 (file)
 #define IMX6SLL_CLK_GPIO4               176
 #define IMX6SLL_CLK_GPIO5               177
 #define IMX6SLL_CLK_GPIO6               178
+#define IMX6SLL_CLK_MMDC_P1_IPG                179
 
-#define IMX6SLL_CLK_END                        179
+#define IMX6SLL_CLK_END                        180
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */
index cd2d6c570e866ad745a9bfa865aeb479162ebfd0..fb420c73477412373be4090b233ba61d0cf822cc 100644 (file)
 #define IMX6SX_CLK_LVDS2_OUT           266
 #define IMX6SX_CLK_LVDS2_IN            267
 #define IMX6SX_CLK_ANACLK2             268
-#define IMX6SX_CLK_CLK_END             269
+#define IMX6SX_CLK_MMDC_P1_IPG         269
+#define IMX6SX_CLK_CLK_END             270
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */
index f8e0476a3a0eb00189b102b06f7566738d929184..f718aac9b9dad25b104743bc160fc80e3867e0ba 100644 (file)
 #define IMX6UL_CLK_GPIO3               246
 #define IMX6UL_CLK_GPIO4               247
 #define IMX6UL_CLK_GPIO5               248
+#define IMX6UL_CLK_MMDC_P1_IPG         249
 
-#define IMX6UL_CLK_END                 249
+#define IMX6UL_CLK_END                 250
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
diff --git a/include/dt-bindings/clock/jz4725b-cgu.h b/include/dt-bindings/clock/jz4725b-cgu.h
new file mode 100644 (file)
index 0000000..460bbef
--- /dev/null
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides clock numbers for the ingenic,jz4725b-cgu DT binding.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4725B_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4725B_CGU_H__
+
+#define JZ4725B_CLK_EXT                0
+#define JZ4725B_CLK_OSC32K     1
+#define JZ4725B_CLK_PLL                2
+#define JZ4725B_CLK_PLL_HALF   3
+#define JZ4725B_CLK_CCLK       4
+#define JZ4725B_CLK_HCLK       5
+#define JZ4725B_CLK_PCLK       6
+#define JZ4725B_CLK_MCLK       7
+#define JZ4725B_CLK_IPU                8
+#define JZ4725B_CLK_LCD                9
+#define JZ4725B_CLK_I2S                10
+#define JZ4725B_CLK_SPI                11
+#define JZ4725B_CLK_MMC_MUX    12
+#define JZ4725B_CLK_UDC                13
+#define JZ4725B_CLK_UART       14
+#define JZ4725B_CLK_DMA                15
+#define JZ4725B_CLK_ADC                16
+#define JZ4725B_CLK_I2C                17
+#define JZ4725B_CLK_AIC                18
+#define JZ4725B_CLK_MMC0       19
+#define JZ4725B_CLK_MMC1       20
+#define JZ4725B_CLK_BCH                21
+#define JZ4725B_CLK_TCU                22
+#define JZ4725B_CLK_EXT512     23
+#define JZ4725B_CLK_RTC                24
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4725B_CGU_H__ */
index 7b28b09058699a31b2c6441189fc222667680c79..af8261dcace1dc9e58d78b92bd58529ddf959daf 100644 (file)
@@ -1,10 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2014 Google, Inc
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Device Tree binding constants clocks for the Maxim 77686 PMIC.
  */
 
index 997312edcbb5b059375f1c31e745bb66568411ed..51adcbaed697ad3cc564545439f803d1fbd956e0 100644 (file)
@@ -1,10 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2014 Google, Inc
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Device Tree binding constants clocks for the Maxim 77802 PMIC.
  */
 
diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h b/include/dt-bindings/clock/qcom,camcc-sdm845.h
new file mode 100644 (file)
index 0000000..4f7a2d2
--- /dev/null
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H
+#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H
+
+/* CAM_CC clock registers */
+#define CAM_CC_BPS_AHB_CLK                             0
+#define CAM_CC_BPS_AREG_CLK                            1
+#define CAM_CC_BPS_AXI_CLK                             2
+#define CAM_CC_BPS_CLK                                 3
+#define CAM_CC_BPS_CLK_SRC                             4
+#define CAM_CC_CAMNOC_ATB_CLK                          5
+#define CAM_CC_CAMNOC_AXI_CLK                          6
+#define CAM_CC_CCI_CLK                                 7
+#define CAM_CC_CCI_CLK_SRC                             8
+#define CAM_CC_CPAS_AHB_CLK                            9
+#define CAM_CC_CPHY_RX_CLK_SRC                         10
+#define CAM_CC_CSI0PHYTIMER_CLK                                11
+#define CAM_CC_CSI0PHYTIMER_CLK_SRC                    12
+#define CAM_CC_CSI1PHYTIMER_CLK                                13
+#define CAM_CC_CSI1PHYTIMER_CLK_SRC                    14
+#define CAM_CC_CSI2PHYTIMER_CLK                                15
+#define CAM_CC_CSI2PHYTIMER_CLK_SRC                    16
+#define CAM_CC_CSI3PHYTIMER_CLK                                17
+#define CAM_CC_CSI3PHYTIMER_CLK_SRC                    18
+#define CAM_CC_CSIPHY0_CLK                             19
+#define CAM_CC_CSIPHY1_CLK                             20
+#define CAM_CC_CSIPHY2_CLK                             21
+#define CAM_CC_CSIPHY3_CLK                             22
+#define CAM_CC_FAST_AHB_CLK_SRC                                23
+#define CAM_CC_FD_CORE_CLK                             24
+#define CAM_CC_FD_CORE_CLK_SRC                         25
+#define CAM_CC_FD_CORE_UAR_CLK                         26
+#define CAM_CC_ICP_APB_CLK                             27
+#define CAM_CC_ICP_ATB_CLK                             28
+#define CAM_CC_ICP_CLK                                 29
+#define CAM_CC_ICP_CLK_SRC                             30
+#define CAM_CC_ICP_CTI_CLK                             31
+#define CAM_CC_ICP_TS_CLK                              32
+#define CAM_CC_IFE_0_AXI_CLK                           33
+#define CAM_CC_IFE_0_CLK                               34
+#define CAM_CC_IFE_0_CLK_SRC                           35
+#define CAM_CC_IFE_0_CPHY_RX_CLK                       36
+#define CAM_CC_IFE_0_CSID_CLK                          37
+#define CAM_CC_IFE_0_CSID_CLK_SRC                      38
+#define CAM_CC_IFE_0_DSP_CLK                           39
+#define CAM_CC_IFE_1_AXI_CLK                           40
+#define CAM_CC_IFE_1_CLK                               41
+#define CAM_CC_IFE_1_CLK_SRC                           42
+#define CAM_CC_IFE_1_CPHY_RX_CLK                       43
+#define CAM_CC_IFE_1_CSID_CLK                          44
+#define CAM_CC_IFE_1_CSID_CLK_SRC                      45
+#define CAM_CC_IFE_1_DSP_CLK                           46
+#define CAM_CC_IFE_LITE_CLK                            47
+#define CAM_CC_IFE_LITE_CLK_SRC                                48
+#define CAM_CC_IFE_LITE_CPHY_RX_CLK                    49
+#define CAM_CC_IFE_LITE_CSID_CLK                       50
+#define CAM_CC_IFE_LITE_CSID_CLK_SRC                   51
+#define CAM_CC_IPE_0_AHB_CLK                           52
+#define CAM_CC_IPE_0_AREG_CLK                          53
+#define CAM_CC_IPE_0_AXI_CLK                           54
+#define CAM_CC_IPE_0_CLK                               55
+#define CAM_CC_IPE_0_CLK_SRC                           56
+#define CAM_CC_IPE_1_AHB_CLK                           57
+#define CAM_CC_IPE_1_AREG_CLK                          58
+#define CAM_CC_IPE_1_AXI_CLK                           59
+#define CAM_CC_IPE_1_CLK                               60
+#define CAM_CC_IPE_1_CLK_SRC                           61
+#define CAM_CC_JPEG_CLK                                        62
+#define CAM_CC_JPEG_CLK_SRC                            63
+#define CAM_CC_LRME_CLK                                        64
+#define CAM_CC_LRME_CLK_SRC                            65
+#define CAM_CC_MCLK0_CLK                               66
+#define CAM_CC_MCLK0_CLK_SRC                           67
+#define CAM_CC_MCLK1_CLK                               68
+#define CAM_CC_MCLK1_CLK_SRC                           69
+#define CAM_CC_MCLK2_CLK                               70
+#define CAM_CC_MCLK2_CLK_SRC                           71
+#define CAM_CC_MCLK3_CLK                               72
+#define CAM_CC_MCLK3_CLK_SRC                           73
+#define CAM_CC_PLL0                                    74
+#define CAM_CC_PLL0_OUT_EVEN                           75
+#define CAM_CC_PLL1                                    76
+#define CAM_CC_PLL1_OUT_EVEN                           77
+#define CAM_CC_PLL2                                    78
+#define CAM_CC_PLL2_OUT_EVEN                           79
+#define CAM_CC_PLL3                                    80
+#define CAM_CC_PLL3_OUT_EVEN                           81
+#define CAM_CC_SLOW_AHB_CLK_SRC                                82
+#define CAM_CC_SOC_AHB_CLK                             83
+#define CAM_CC_SYS_TMR_CLK                             84
+
+/* CAM_CC Resets */
+#define TITAN_CAM_CC_CCI_BCR                           0
+#define TITAN_CAM_CC_CPAS_BCR                          1
+#define TITAN_CAM_CC_CSI0PHY_BCR                       2
+#define TITAN_CAM_CC_CSI1PHY_BCR                       3
+#define TITAN_CAM_CC_CSI2PHY_BCR                       4
+#define TITAN_CAM_CC_MCLK0_BCR                         5
+#define TITAN_CAM_CC_MCLK1_BCR                         6
+#define TITAN_CAM_CC_MCLK2_BCR                         7
+#define TITAN_CAM_CC_MCLK3_BCR                         8
+#define TITAN_CAM_CC_TITAN_TOP_BCR                     9
+
+/* CAM_CC GDSCRs */
+#define BPS_GDSC                                       0
+#define IPE_0_GDSC                                     1
+#define IPE_1_GDSC                                     2
+#define IFE_0_GDSC                                     3
+#define IFE_1_GDSC                                     4
+#define TITAN_TOP_GDSC                                 5
+
+#endif
index 7d20eedfee9898592ce7265da188d0482e04420d..e02742fc81cc76b9db8450ca7e828bb698b42c68 100644 (file)
 #define CE3_SRC                                        303
 #define CE3_CORE_CLK                           304
 #define CE3_H_CLK                              305
+#define PLL16                                  306
+#define PLL17                                  307
 
 #endif
index 75b07cf5eed0f9a2941f0367af601b77c0bd1599..db80f2ee571b22fdbf77b9fa8a2477fc7747d528 100644 (file)
 #define GCC_RX1_USB2_CLKREF_CLK                                        218
 #define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK                     219
 #define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK                     220
+#define GCC_EDP_CLKREF_CLK                                     221
+#define GCC_MSS_CFG_AHB_CLK                                    222
+#define GCC_MSS_Q6_BIMC_AXI_CLK                                        223
+#define GCC_MSS_SNOC_AXI_CLK                                   224
+#define GCC_MSS_MNOC_BIMC_AXI_CLK                              225
+#define GCC_DCC_AHB_CLK                                                226
+#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK                         227
+#define GCC_MMSS_GPLL0_DIV_CLK                                 228
+#define GCC_MSS_GPLL0_DIV_CLK                                  229
 
 #define GCC_SYSTEM_NOC_BCR                                     0
 #define GCC_CONFIG_NOC_BCR                                     1
diff --git a/include/dt-bindings/clock/qcom,gcc-qcs404.h b/include/dt-bindings/clock/qcom,gcc-qcs404.h
new file mode 100644 (file)
index 0000000..6ceb55e
--- /dev/null
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GCC_QCS404_H
+#define _DT_BINDINGS_CLK_QCOM_GCC_QCS404_H
+
+#define GCC_APSS_AHB_CLK_SRC                           0
+#define GCC_BLSP1_QUP0_I2C_APPS_CLK_SRC                        1
+#define GCC_BLSP1_QUP0_SPI_APPS_CLK_SRC                        2
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC                        3
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC                        4
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC                        5
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC                        6
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC                        7
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC                        8
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC                        9
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC                        10
+#define GCC_BLSP1_UART0_APPS_CLK_SRC                   11
+#define GCC_BLSP1_UART1_APPS_CLK_SRC                   12
+#define GCC_BLSP1_UART2_APPS_CLK_SRC                   13
+#define GCC_BLSP1_UART3_APPS_CLK_SRC                   14
+#define GCC_BLSP2_QUP0_I2C_APPS_CLK_SRC                        15
+#define GCC_BLSP2_QUP0_SPI_APPS_CLK_SRC                        16
+#define GCC_BLSP2_UART0_APPS_CLK_SRC                   17
+#define GCC_BYTE0_CLK_SRC                              18
+#define GCC_EMAC_CLK_SRC                               19
+#define GCC_EMAC_PTP_CLK_SRC                           20
+#define GCC_ESC0_CLK_SRC                               21
+#define GCC_APSS_AHB_CLK                               22
+#define GCC_APSS_AXI_CLK                               23
+#define GCC_BIMC_APSS_AXI_CLK                          24
+#define GCC_BIMC_GFX_CLK                               25
+#define GCC_BIMC_MDSS_CLK                              26
+#define GCC_BLSP1_AHB_CLK                              27
+#define GCC_BLSP1_QUP0_I2C_APPS_CLK                    28
+#define GCC_BLSP1_QUP0_SPI_APPS_CLK                    29
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK                    30
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK                    31
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK                    32
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK                    33
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK                    34
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK                    35
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK                    36
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK                    37
+#define GCC_BLSP1_UART0_APPS_CLK                       38
+#define GCC_BLSP1_UART1_APPS_CLK                       39
+#define GCC_BLSP1_UART2_APPS_CLK                       40
+#define GCC_BLSP1_UART3_APPS_CLK                       41
+#define GCC_BLSP2_AHB_CLK                              42
+#define GCC_BLSP2_QUP0_I2C_APPS_CLK                    43
+#define GCC_BLSP2_QUP0_SPI_APPS_CLK                    44
+#define GCC_BLSP2_UART0_APPS_CLK                       45
+#define GCC_BOOT_ROM_AHB_CLK                           46
+#define GCC_DCC_CLK                                    47
+#define GCC_GENI_IR_H_CLK                              48
+#define GCC_ETH_AXI_CLK                                        49
+#define GCC_ETH_PTP_CLK                                        50
+#define GCC_ETH_RGMII_CLK                              51
+#define GCC_ETH_SLAVE_AHB_CLK                          52
+#define GCC_GENI_IR_S_CLK                              53
+#define GCC_GP1_CLK                                    54
+#define GCC_GP2_CLK                                    55
+#define GCC_GP3_CLK                                    56
+#define GCC_MDSS_AHB_CLK                               57
+#define GCC_MDSS_AXI_CLK                               58
+#define GCC_MDSS_BYTE0_CLK                             59
+#define GCC_MDSS_ESC0_CLK                              60
+#define GCC_MDSS_HDMI_APP_CLK                          61
+#define GCC_MDSS_HDMI_PCLK_CLK                         62
+#define GCC_MDSS_MDP_CLK                               63
+#define GCC_MDSS_PCLK0_CLK                             64
+#define GCC_MDSS_VSYNC_CLK                             65
+#define GCC_OXILI_AHB_CLK                              66
+#define GCC_OXILI_GFX3D_CLK                            67
+#define GCC_PCIE_0_AUX_CLK                             68
+#define GCC_PCIE_0_CFG_AHB_CLK                         69
+#define GCC_PCIE_0_MSTR_AXI_CLK                                70
+#define GCC_PCIE_0_PIPE_CLK                            71
+#define GCC_PCIE_0_SLV_AXI_CLK                         72
+#define GCC_PCNOC_USB2_CLK                             73
+#define GCC_PCNOC_USB3_CLK                             74
+#define GCC_PDM2_CLK                                   75
+#define GCC_PDM_AHB_CLK                                        76
+#define GCC_VSYNC_CLK_SRC                              77
+#define GCC_PRNG_AHB_CLK                               78
+#define GCC_PWM0_XO512_CLK                             79
+#define GCC_PWM1_XO512_CLK                             80
+#define GCC_PWM2_XO512_CLK                             81
+#define GCC_SDCC1_AHB_CLK                              82
+#define GCC_SDCC1_APPS_CLK                             83
+#define GCC_SDCC1_ICE_CORE_CLK                         84
+#define GCC_SDCC2_AHB_CLK                              85
+#define GCC_SDCC2_APPS_CLK                             86
+#define GCC_SYS_NOC_USB3_CLK                           87
+#define GCC_USB20_MOCK_UTMI_CLK                                88
+#define GCC_USB2A_PHY_SLEEP_CLK                                89
+#define GCC_USB30_MASTER_CLK                           90
+#define GCC_USB30_MOCK_UTMI_CLK                                91
+#define GCC_USB30_SLEEP_CLK                            92
+#define GCC_USB3_PHY_AUX_CLK                           93
+#define GCC_USB3_PHY_PIPE_CLK                          94
+#define GCC_USB_HS_PHY_CFG_AHB_CLK                     95
+#define GCC_USB_HS_SYSTEM_CLK                          96
+#define GCC_GFX3D_CLK_SRC                              97
+#define GCC_GP1_CLK_SRC                                        98
+#define GCC_GP2_CLK_SRC                                        99
+#define GCC_GP3_CLK_SRC                                        100
+#define GCC_GPLL0_OUT_MAIN                             101
+#define GCC_GPLL1_OUT_MAIN                             102
+#define GCC_GPLL3_OUT_MAIN                             103
+#define GCC_GPLL4_OUT_MAIN                             104
+#define GCC_HDMI_APP_CLK_SRC                           105
+#define GCC_HDMI_PCLK_CLK_SRC                          106
+#define GCC_MDP_CLK_SRC                                        107
+#define GCC_PCIE_0_AUX_CLK_SRC                         108
+#define GCC_PCIE_0_PIPE_CLK_SRC                                109
+#define GCC_PCLK0_CLK_SRC                              110
+#define GCC_PDM2_CLK_SRC                               111
+#define GCC_SDCC1_APPS_CLK_SRC                         112
+#define GCC_SDCC1_ICE_CORE_CLK_SRC                     113
+#define GCC_SDCC2_APPS_CLK_SRC                         114
+#define GCC_USB20_MOCK_UTMI_CLK_SRC                    115
+#define GCC_USB30_MASTER_CLK_SRC                       116
+#define GCC_USB30_MOCK_UTMI_CLK_SRC                    117
+#define GCC_USB3_PHY_AUX_CLK_SRC                       118
+#define GCC_USB_HS_SYSTEM_CLK_SRC                      119
+#define GCC_GPLL0_AO_CLK_SRC                           120
+#define GCC_USB_HS_INACTIVITY_TIMERS_CLK               122
+#define GCC_GPLL0_AO_OUT_MAIN                          123
+#define GCC_GPLL0_SLEEP_CLK_SRC                                124
+#define GCC_GPLL6                                      125
+#define GCC_GPLL6_OUT_AUX                              126
+#define GCC_MDSS_MDP_VOTE_CLK                          127
+#define GCC_MDSS_ROTATOR_VOTE_CLK                      128
+#define GCC_BIMC_GPU_CLK                               129
+#define GCC_GTCU_AHB_CLK                               130
+#define GCC_GFX_TCU_CLK                                        131
+#define GCC_GFX_TBU_CLK                                        132
+#define GCC_SMMU_CFG_CLK                               133
+#define GCC_APSS_TCU_CLK                               134
+#define GCC_CRYPTO_AHB_CLK                             135
+#define GCC_CRYPTO_AXI_CLK                             136
+#define GCC_CRYPTO_CLK                                 137
+#define GCC_MDP_TBU_CLK                                        138
+#define GCC_QDSS_DAP_CLK                               139
+#define GCC_DCC_XO_CLK                                 140
+
+#define GCC_GENI_IR_BCR                                        0
+#define GCC_USB_HS_BCR                                 1
+#define GCC_USB2_HS_PHY_ONLY_BCR                       2
+#define GCC_QUSB2_PHY_BCR                              3
+#define GCC_USB_HS_PHY_CFG_AHB_BCR                     4
+#define GCC_USB2A_PHY_BCR                              5
+#define GCC_USB3_PHY_BCR                               6
+#define GCC_USB_30_BCR                                 7
+#define GCC_USB3PHY_PHY_BCR                            8
+#define GCC_PCIE_0_BCR                                 9
+#define GCC_PCIE_0_PHY_BCR                             10
+#define GCC_PCIE_0_LINK_DOWN_BCR                       11
+#define GCC_PCIEPHY_0_PHY_BCR                          12
+#define GCC_EMAC_BCR                                   13
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h
new file mode 100644 (file)
index 0000000..4683022
--- /dev/null
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, Craig Tatlor.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MSM_GCC_660_H
+#define _DT_BINDINGS_CLK_MSM_GCC_660_H
+
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC            0
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC            1
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC            2
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC            3
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC            4
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC            5
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC            6
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC            7
+#define BLSP1_UART1_APPS_CLK_SRC               8
+#define BLSP1_UART2_APPS_CLK_SRC               9
+#define BLSP2_QUP1_I2C_APPS_CLK_SRC            10
+#define BLSP2_QUP1_SPI_APPS_CLK_SRC            11
+#define BLSP2_QUP2_I2C_APPS_CLK_SRC            12
+#define BLSP2_QUP2_SPI_APPS_CLK_SRC            13
+#define BLSP2_QUP3_I2C_APPS_CLK_SRC            14
+#define BLSP2_QUP3_SPI_APPS_CLK_SRC            15
+#define BLSP2_QUP4_I2C_APPS_CLK_SRC            16
+#define BLSP2_QUP4_SPI_APPS_CLK_SRC            17
+#define BLSP2_UART1_APPS_CLK_SRC               18
+#define BLSP2_UART2_APPS_CLK_SRC               19
+#define GCC_AGGRE2_UFS_AXI_CLK                 20
+#define GCC_AGGRE2_USB3_AXI_CLK                        21
+#define GCC_BIMC_GFX_CLK                       22
+#define GCC_BIMC_HMSS_AXI_CLK                  23
+#define GCC_BIMC_MSS_Q6_AXI_CLK                        24
+#define GCC_BLSP1_AHB_CLK                      25
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK            26
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK            27
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK            28
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK            29
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK            30
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK            31
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK            32
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK            33
+#define GCC_BLSP1_UART1_APPS_CLK               34
+#define GCC_BLSP1_UART2_APPS_CLK               35
+#define GCC_BLSP2_AHB_CLK                      36
+#define GCC_BLSP2_QUP1_I2C_APPS_CLK            37
+#define GCC_BLSP2_QUP1_SPI_APPS_CLK            38
+#define GCC_BLSP2_QUP2_I2C_APPS_CLK            39
+#define GCC_BLSP2_QUP2_SPI_APPS_CLK            40
+#define GCC_BLSP2_QUP3_I2C_APPS_CLK            41
+#define GCC_BLSP2_QUP3_SPI_APPS_CLK            42
+#define GCC_BLSP2_QUP4_I2C_APPS_CLK            43
+#define GCC_BLSP2_QUP4_SPI_APPS_CLK            44
+#define GCC_BLSP2_UART1_APPS_CLK               45
+#define GCC_BLSP2_UART2_APPS_CLK               46
+#define GCC_BOOT_ROM_AHB_CLK                   47
+#define GCC_CFG_NOC_USB2_AXI_CLK               48
+#define GCC_CFG_NOC_USB3_AXI_CLK               49
+#define GCC_DCC_AHB_CLK                                50
+#define GCC_GP1_CLK                            51
+#define GCC_GP2_CLK                            52
+#define GCC_GP3_CLK                            53
+#define GCC_GPU_BIMC_GFX_CLK                   54
+#define GCC_GPU_CFG_AHB_CLK                    55
+#define GCC_GPU_GPLL0_CLK                      56
+#define GCC_GPU_GPLL0_DIV_CLK                  57
+#define GCC_HMSS_DVM_BUS_CLK                   58
+#define GCC_HMSS_RBCPR_CLK                     59
+#define GCC_MMSS_GPLL0_CLK                     60
+#define GCC_MMSS_GPLL0_DIV_CLK                 61
+#define GCC_MMSS_NOC_CFG_AHB_CLK               62
+#define GCC_MMSS_SYS_NOC_AXI_CLK               63
+#define GCC_MSS_CFG_AHB_CLK                    64
+#define GCC_MSS_GPLL0_DIV_CLK                  65
+#define GCC_MSS_MNOC_BIMC_AXI_CLK              66
+#define GCC_MSS_Q6_BIMC_AXI_CLK                        67
+#define GCC_MSS_SNOC_AXI_CLK                   68
+#define GCC_PDM2_CLK                           69
+#define GCC_PDM_AHB_CLK                                70
+#define GCC_PRNG_AHB_CLK                       71
+#define GCC_QSPI_AHB_CLK                       72
+#define GCC_QSPI_SER_CLK                       73
+#define GCC_SDCC1_AHB_CLK                      74
+#define GCC_SDCC1_APPS_CLK                     75
+#define GCC_SDCC1_ICE_CORE_CLK                 76
+#define GCC_SDCC2_AHB_CLK                      77
+#define GCC_SDCC2_APPS_CLK                     78
+#define GCC_UFS_AHB_CLK                                79
+#define GCC_UFS_AXI_CLK                                80
+#define GCC_UFS_CLKREF_CLK                     81
+#define GCC_UFS_ICE_CORE_CLK                   82
+#define GCC_UFS_PHY_AUX_CLK                    83
+#define GCC_UFS_RX_SYMBOL_0_CLK                        84
+#define GCC_UFS_RX_SYMBOL_1_CLK                        85
+#define GCC_UFS_TX_SYMBOL_0_CLK                        86
+#define GCC_UFS_UNIPRO_CORE_CLK                        87
+#define GCC_USB20_MASTER_CLK                   88
+#define GCC_USB20_MOCK_UTMI_CLK                        89
+#define GCC_USB20_SLEEP_CLK                    90
+#define GCC_USB30_MASTER_CLK                   91
+#define GCC_USB30_MOCK_UTMI_CLK                        92
+#define GCC_USB30_SLEEP_CLK                    93
+#define GCC_USB3_CLKREF_CLK                    94
+#define GCC_USB3_PHY_AUX_CLK                   95
+#define GCC_USB3_PHY_PIPE_CLK                  96
+#define GCC_USB_PHY_CFG_AHB2PHY_CLK            97
+#define GP1_CLK_SRC                            98
+#define GP2_CLK_SRC                            99
+#define GP3_CLK_SRC                            100
+#define GPLL0                                  101
+#define GPLL0_EARLY                            102
+#define GPLL1                                  103
+#define GPLL1_EARLY                            104
+#define GPLL4                                  105
+#define GPLL4_EARLY                            106
+#define HMSS_GPLL0_CLK_SRC                     107
+#define HMSS_GPLL4_CLK_SRC                     108
+#define HMSS_RBCPR_CLK_SRC                     109
+#define PDM2_CLK_SRC                           110
+#define QSPI_SER_CLK_SRC                       111
+#define SDCC1_APPS_CLK_SRC                     112
+#define SDCC1_ICE_CORE_CLK_SRC                 113
+#define SDCC2_APPS_CLK_SRC                     114
+#define UFS_AXI_CLK_SRC                                115
+#define UFS_ICE_CORE_CLK_SRC                   116
+#define UFS_PHY_AUX_CLK_SRC                    117
+#define UFS_UNIPRO_CORE_CLK_SRC                        118
+#define USB20_MASTER_CLK_SRC                   119
+#define USB20_MOCK_UTMI_CLK_SRC                        120
+#define USB30_MASTER_CLK_SRC                   121
+#define USB30_MOCK_UTMI_CLK_SRC                        122
+#define USB3_PHY_AUX_CLK_SRC                   123
+#define GPLL0_OUT_MSSCC                                124
+#define GCC_UFS_AXI_HW_CTL_CLK                 125
+#define GCC_UFS_ICE_CORE_HW_CTL_CLK            126
+#define GCC_UFS_PHY_AUX_HW_CTL_CLK             127
+#define GCC_UFS_UNIPRO_CORE_HW_CTL_CLK         128
+#define GCC_RX0_USB2_CLKREF_CLK                        129
+#define GCC_RX1_USB2_CLKREF_CLK                        130
+
+#define PCIE_0_GDSC    0
+#define UFS_GDSC       1
+#define USB_30_GDSC    2
+
+#define GCC_QUSB2PHY_PRIM_BCR          0
+#define GCC_QUSB2PHY_SEC_BCR           1
+#define GCC_UFS_BCR                    2
+#define GCC_USB3_DP_PHY_BCR            3
+#define GCC_USB3_PHY_BCR               4
+#define GCC_USB3PHY_PHY_BCR            5
+#define GCC_USB_20_BCR                  6
+#define GCC_USB_30_BCR                 7
+#define GCC_USB_PHY_CFG_AHB2PHY_BCR    8
+
+#endif
index f96fc2dbf60e0dd74b03b1b8d48394e2fd957b52..b8eae5a76503079b18374348cfdcd1992f84479e 100644 (file)
 #define GPLL4                                                  184
 #define GCC_CPUSS_DVM_BUS_CLK                                  185
 #define GCC_CPUSS_GNOC_CLK                                     186
+#define GCC_QSPI_CORE_CLK_SRC                                  187
+#define GCC_QSPI_CORE_CLK                                      188
+#define GCC_QSPI_CNOC_PERIPH_AHB_CLK                           189
 
 /* GCC Resets */
 #define GCC_MMSS_BCR                                           0
index 0dcb3e87d44c121ec55b8614cee46fae6b1417d7..a267ac25014355493fa29b5830824c5a5982884c 100644 (file)
@@ -1,10 +1,7 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * Copyright (C) 2014 Renesas Solutions Corp.
  * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R7S72100_H__
diff --git a/include/dt-bindings/clock/r7s9210-cpg-mssr.h b/include/dt-bindings/clock/r7s9210-cpg-mssr.h
new file mode 100644 (file)
index 0000000..b6f85ca
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* R7S9210 CPG Core Clocks */
+#define R7S9210_CLK_I                  0
+#define R7S9210_CLK_G                  1
+#define R7S9210_CLK_B                  2
+#define R7S9210_CLK_P1                 3
+#define R7S9210_CLK_P1C                        4
+#define R7S9210_CLK_P0                 5
+
+#endif /* __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ */
index e1d1f3c6a99ea95c72bd3500cead514aef40d3f8..3ba936029d9fbaee5a3180d7855c368d73944c72 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2016 Cogent Embedded Inc.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2016 Cogent Embedded Inc.
  */
 #ifndef __DT_BINDINGS_CLOCK_R8A7743_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_R8A7743_CPG_MSSR_H__
diff --git a/include/dt-bindings/clock/r8a7744-cpg-mssr.h b/include/dt-bindings/clock/r8a7744-cpg-mssr.h
new file mode 100644 (file)
index 0000000..2690be0
--- /dev/null
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A7744_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7744_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7744 CPG Core Clocks */
+#define R8A7744_CLK_Z          0
+#define R8A7744_CLK_ZG         1
+#define R8A7744_CLK_ZTR                2
+#define R8A7744_CLK_ZTRD2      3
+#define R8A7744_CLK_ZT         4
+#define R8A7744_CLK_ZX         5
+#define R8A7744_CLK_ZS         6
+#define R8A7744_CLK_HP         7
+#define R8A7744_CLK_B          9
+#define R8A7744_CLK_LB         10
+#define R8A7744_CLK_P          11
+#define R8A7744_CLK_CL         12
+#define R8A7744_CLK_M2         13
+#define R8A7744_CLK_ZB3                15
+#define R8A7744_CLK_ZB3D2      16
+#define R8A7744_CLK_DDR                17
+#define R8A7744_CLK_SDH                18
+#define R8A7744_CLK_SD0                19
+#define R8A7744_CLK_SD2                20
+#define R8A7744_CLK_SD3                21
+#define R8A7744_CLK_MMC0       22
+#define R8A7744_CLK_MP         23
+#define R8A7744_CLK_QSPI       26
+#define R8A7744_CLK_CP         27
+#define R8A7744_CLK_RCAN       28
+#define R8A7744_CLK_R          29
+#define R8A7744_CLK_OSC                30
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7744_CPG_MSSR_H__ */
index 56ad6f0c67606d74bd99098a6ed5d401d5799c39..f81066c9d19234b7c439708cdc38c30c4d4a26f4 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2016 Cogent Embedded Inc.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2016 Cogent Embedded Inc.
  */
 #ifndef __DT_BINDINGS_CLOCK_R8A7745_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_R8A7745_CPG_MSSR_H__
diff --git a/include/dt-bindings/clock/r8a774a1-cpg-mssr.h b/include/dt-bindings/clock/r8a774a1-cpg-mssr.h
new file mode 100644 (file)
index 0000000..9bc5d45
--- /dev/null
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a774a1 CPG Core Clocks */
+#define R8A774A1_CLK_Z                 0
+#define R8A774A1_CLK_Z2                        1
+#define R8A774A1_CLK_ZG                        2
+#define R8A774A1_CLK_ZTR               3
+#define R8A774A1_CLK_ZTRD2             4
+#define R8A774A1_CLK_ZT                        5
+#define R8A774A1_CLK_ZX                        6
+#define R8A774A1_CLK_S0D1              7
+#define R8A774A1_CLK_S0D2              8
+#define R8A774A1_CLK_S0D3              9
+#define R8A774A1_CLK_S0D4              10
+#define R8A774A1_CLK_S0D6              11
+#define R8A774A1_CLK_S0D8              12
+#define R8A774A1_CLK_S0D12             13
+#define R8A774A1_CLK_S1D2              14
+#define R8A774A1_CLK_S1D4              15
+#define R8A774A1_CLK_S2D1              16
+#define R8A774A1_CLK_S2D2              17
+#define R8A774A1_CLK_S2D4              18
+#define R8A774A1_CLK_S3D1              19
+#define R8A774A1_CLK_S3D2              20
+#define R8A774A1_CLK_S3D4              21
+#define R8A774A1_CLK_LB                        22
+#define R8A774A1_CLK_CL                        23
+#define R8A774A1_CLK_ZB3               24
+#define R8A774A1_CLK_ZB3D2             25
+#define R8A774A1_CLK_ZB3D4             26
+#define R8A774A1_CLK_CR                        27
+#define R8A774A1_CLK_CRD2              28
+#define R8A774A1_CLK_SD0H              29
+#define R8A774A1_CLK_SD0               30
+#define R8A774A1_CLK_SD1H              31
+#define R8A774A1_CLK_SD1               32
+#define R8A774A1_CLK_SD2H              33
+#define R8A774A1_CLK_SD2               34
+#define R8A774A1_CLK_SD3H              35
+#define R8A774A1_CLK_SD3               36
+#define R8A774A1_CLK_RPC               37
+#define R8A774A1_CLK_RPCD2             38
+#define R8A774A1_CLK_MSO               39
+#define R8A774A1_CLK_HDMI              40
+#define R8A774A1_CLK_CSI0              41
+#define R8A774A1_CLK_CP                        42
+#define R8A774A1_CLK_CPEX              43
+#define R8A774A1_CLK_R                 44
+#define R8A774A1_CLK_OSC               45
+
+#endif /* __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a774c0-cpg-mssr.h b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h
new file mode 100644 (file)
index 0000000..8fe51b6
--- /dev/null
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a774c0 CPG Core Clocks */
+#define R8A774C0_CLK_Z2                        0
+#define R8A774C0_CLK_ZG                        1
+#define R8A774C0_CLK_ZTR               2
+#define R8A774C0_CLK_ZT                        3
+#define R8A774C0_CLK_ZX                        4
+#define R8A774C0_CLK_S0D1              5
+#define R8A774C0_CLK_S0D3              6
+#define R8A774C0_CLK_S0D6              7
+#define R8A774C0_CLK_S0D12             8
+#define R8A774C0_CLK_S0D24             9
+#define R8A774C0_CLK_S1D1              10
+#define R8A774C0_CLK_S1D2              11
+#define R8A774C0_CLK_S1D4              12
+#define R8A774C0_CLK_S2D1              13
+#define R8A774C0_CLK_S2D2              14
+#define R8A774C0_CLK_S2D4              15
+#define R8A774C0_CLK_S3D1              16
+#define R8A774C0_CLK_S3D2              17
+#define R8A774C0_CLK_S3D4              18
+#define R8A774C0_CLK_S0D6C             19
+#define R8A774C0_CLK_S3D1C             20
+#define R8A774C0_CLK_S3D2C             21
+#define R8A774C0_CLK_S3D4C             22
+#define R8A774C0_CLK_LB                        23
+#define R8A774C0_CLK_CL                        24
+#define R8A774C0_CLK_ZB3               25
+#define R8A774C0_CLK_ZB3D2             26
+#define R8A774C0_CLK_CR                        27
+#define R8A774C0_CLK_CRD2              28
+#define R8A774C0_CLK_SD0H              29
+#define R8A774C0_CLK_SD0               30
+#define R8A774C0_CLK_SD1H              31
+#define R8A774C0_CLK_SD1               32
+#define R8A774C0_CLK_SD3H              33
+#define R8A774C0_CLK_SD3               34
+#define R8A774C0_CLK_RPC               35
+#define R8A774C0_CLK_RPCD2             36
+#define R8A774C0_CLK_ZA2               37
+#define R8A774C0_CLK_ZA8               38
+#define R8A774C0_CLK_Z2D               39
+#define R8A774C0_CLK_MSO               40
+#define R8A774C0_CLK_R                 41
+#define R8A774C0_CLK_OSC               42
+#define R8A774C0_CLK_LV0               43
+#define R8A774C0_CLK_LV1               44
+#define R8A774C0_CLK_CSI0              45
+#define R8A774C0_CLK_CP                        46
+#define R8A774C0_CLK_CPEX              47
+
+#endif /* __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ */
index 1625b8bf34822b6e8f41f1dbdead56c8ce13bff6..c5955b56b36d80876e7cf6cd037a3d018909f1ef 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__
index e8823410c01c5a09d0676ddf547c1821b42cf619..aadd06c566c043e7e1909a3dc23fa70514022de1 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__
index 72ce85cb2f94b0abb206145d9332dc14a47f738c..829c44db0271c27a95b788a740bd728a733bb41b 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__
index 7318d45d4e7e9888c41aa1fb66def087b4cb6ff4..49c66d8ed1782fc06d06000f6af96c8a2b464262 100644 (file)
@@ -1,16 +1,8 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
  * r8a7793 clock definition
  *
  * Copyright (C) 2014  Renesas Electronics Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7793_H__
index 8809b0f62d615457f07a463a3c4699d0276a0250..d1ff646c31f2355bf0e67d28c563a827a9df94a6 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__
index 93e99c3ffc8dafebef94d0644cb15532c86ab1b4..649f005782d05213ae3760124e67e4913c5b419c 100644 (file)
@@ -1,11 +1,7 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  * Copyright (C) 2014 Renesas Electronics Corporation
  * Copyright 2013 Ideas On Board SPRL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7794_H__
index 9d720311ae3a229a324febbeeaf698f0ec977c5c..6314e23b51af5be9a019a89ac2791c03bf69c57a 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__
index f047eaf261f34ac783b2187997894daffe552572..9483896415654706de2f8820c327fc4512ffa81f 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 #ifndef __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__
index 1e5942695f0dd057e0e3976824e0205b357eb6b9..e6087f2f7e3aff4adcb4bf7ec6c949242e68d44a 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2016 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2016 Renesas Electronics Corp.
  */
 #ifndef __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__
index 4146395595b10bda7a255d7c309ec17b29dc552b..6145ebe66361574256e630e2d2711b6007399b59 100644 (file)
@@ -1,11 +1,7 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__
index 4e8ae3dee5901b01374e6fd609e7e988d4107676..1eb11acfa563dbd81056d997d8cf0df2d3637d50 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2017 Glider bvba
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2017 Glider bvba
  */
 #ifndef __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__
index 569a3cc33ffb5bc7ed35cc2bd1948a8651d2e62a..8169ad063f0a03c760ea53ecf3bf5d7a5257577b 100644 (file)
@@ -1,10 +1,6 @@
-/*
- * Copyright (C) 2015 Renesas Electronics Corp.
+/* SPDX-License-Identifier: GPL-2.0+
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2015 Renesas Electronics Corp.
  */
 #ifndef __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__
 #define __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__
index b9462b7d3dfe67bf495431786d19f53b61f4a8cf..dc2101a634befe28eb2d240c7a38055cd806de79 100644 (file)
 #define HCLK_CIF1              470
 #define HCLK_VEPU              471
 #define HCLK_VDPU              472
+#define HCLK_HDMI              473
 
-#define CLK_NR_CLKS            (HCLK_VDPU + 1)
+#define CLK_NR_CLKS            (HCLK_HDMI + 1)
 
 /* soft-reset indices */
 #define SRST_MCORE             2
index b903d7de27c92e2fda9ca66b685c9fea953a372d..5ece35d429ffeb30f6e7cbf41951cf8e16e9a091 100644 (file)
@@ -1,10 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2015 Markus Reichl
  *
- * 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.
- *
  * Device Tree binding constants clocks for the Samsung S2MPS11 PMIC.
  */
 
index ad95c7f50090c749c32c7fe6f7936f179f240606..19d233f37e2fab7c6d5ee78953228200292e1036 100644 (file)
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2013 Tomasz Figa <tomasz.figa at gmail.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Device Tree binding constants for Samsung S3C64xx clock controller.
-*/
+ */
 
 #ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
 #define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
index d66432c6e6759730fff0a705edacb88be94fd40b..a8ac4cfcdcbc3e912bf2549d8b30da45b61bf86a 100644 (file)
@@ -43,6 +43,7 @@
 #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_
 #define _DT_BINDINGS_CLK_SUN50I_A64_H_
 
+#define CLK_PLL_VIDEO0         7
 #define CLK_PLL_PERIPH0                11
 
 #define CLK_BUS_MIPI_DSI       28
diff --git a/include/dt-bindings/clock/xlnx,zynqmp-clk.h b/include/dt-bindings/clock/xlnx,zynqmp-clk.h
new file mode 100644 (file)
index 0000000..4aebe6e
--- /dev/null
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Xilinx Zynq MPSoC Firmware layer
+ *
+ *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_CLK_ZYNQMP_H
+#define _DT_BINDINGS_CLK_ZYNQMP_H
+
+#define IOPLL                  0
+#define RPLL                   1
+#define APLL                   2
+#define DPLL                   3
+#define VPLL                   4
+#define IOPLL_TO_FPD           5
+#define RPLL_TO_FPD            6
+#define APLL_TO_LPD            7
+#define DPLL_TO_LPD            8
+#define VPLL_TO_LPD            9
+#define ACPU                   10
+#define ACPU_HALF              11
+#define DBF_FPD                        12
+#define DBF_LPD                        13
+#define DBG_TRACE              14
+#define DBG_TSTMP              15
+#define DP_VIDEO_REF           16
+#define DP_AUDIO_REF           17
+#define DP_STC_REF             18
+#define GDMA_REF               19
+#define DPDMA_REF              20
+#define DDR_REF                        21
+#define SATA_REF               22
+#define PCIE_REF               23
+#define GPU_REF                        24
+#define GPU_PP0_REF            25
+#define GPU_PP1_REF            26
+#define TOPSW_MAIN             27
+#define TOPSW_LSBUS            28
+#define GTGREF0_REF            29
+#define LPD_SWITCH             30
+#define LPD_LSBUS              31
+#define USB0_BUS_REF           32
+#define USB1_BUS_REF           33
+#define USB3_DUAL_REF          34
+#define USB0                   35
+#define USB1                   36
+#define CPU_R5                 37
+#define CPU_R5_CORE            38
+#define CSU_SPB                        39
+#define CSU_PLL                        40
+#define PCAP                   41
+#define IOU_SWITCH             42
+#define GEM_TSU_REF            43
+#define GEM_TSU                        44
+#define GEM0_REF               45
+#define GEM1_REF               46
+#define GEM2_REF               47
+#define GEM3_REF               48
+#define GEM0_TX                        49
+#define GEM1_TX                        50
+#define GEM2_TX                        51
+#define GEM3_TX                        52
+#define QSPI_REF               53
+#define SDIO0_REF              54
+#define SDIO1_REF              55
+#define UART0_REF              56
+#define UART1_REF              57
+#define SPI0_REF               58
+#define SPI1_REF               59
+#define NAND_REF               60
+#define I2C0_REF               61
+#define I2C1_REF               62
+#define CAN0_REF               63
+#define CAN1_REF               64
+#define CAN0                   65
+#define CAN1                   66
+#define DLL_REF                        67
+#define ADMA_REF               68
+#define TIMESTAMP_REF          69
+#define AMS_REF                        70
+#define PL0_REF                        71
+#define PL1_REF                        72
+#define PL2_REF                        73
+#define PL3_REF                        74
+#define WDT                    75
+#define IOPLL_INT              76
+#define IOPLL_PRE_SRC          77
+#define IOPLL_HALF             78
+#define IOPLL_INT_MUX          79
+#define IOPLL_POST_SRC         80
+#define RPLL_INT               81
+#define RPLL_PRE_SRC           82
+#define RPLL_HALF              83
+#define RPLL_INT_MUX           84
+#define RPLL_POST_SRC          85
+#define APLL_INT               86
+#define APLL_PRE_SRC           87
+#define APLL_HALF              88
+#define APLL_INT_MUX           89
+#define APLL_POST_SRC          90
+#define DPLL_INT               91
+#define DPLL_PRE_SRC           92
+#define DPLL_HALF              93
+#define DPLL_INT_MUX           94
+#define DPLL_POST_SRC          95
+#define VPLL_INT               96
+#define VPLL_PRE_SRC           97
+#define VPLL_HALF              98
+#define VPLL_INT_MUX           99
+#define VPLL_POST_SRC          100
+#define CAN0_MIO               101
+#define CAN1_MIO               102
+
+#endif
index 42121fa238fafbf96919b3b93678f949d9e69d22..61d556db154276abef5f103629d15369ed60a3d2 100644 (file)
@@ -1,14 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Copyright (c) 2012-2014,2018 The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DT_BINDINGS_QCOM_SPMI_VADC_H
 #define VADC_LR_MUX10_PU1_PU2_AMUX_USB_ID      0xf9
 #define VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM      0xfc
 
+/* ADC channels for SPMI PMIC5 */
+
+#define ADC5_REF_GND                           0x00
+#define ADC5_1P25VREF                          0x01
+#define ADC5_VREF_VADC                         0x02
+#define ADC5_VREF_VADC5_DIV_3                  0x82
+#define ADC5_VPH_PWR                           0x83
+#define ADC5_VBAT_SNS                          0x84
+#define ADC5_VCOIN                             0x85
+#define ADC5_DIE_TEMP                          0x06
+#define ADC5_USB_IN_I                          0x07
+#define ADC5_USB_IN_V_16                       0x08
+#define ADC5_CHG_TEMP                          0x09
+#define ADC5_BAT_THERM                         0x0a
+#define ADC5_BAT_ID                            0x0b
+#define ADC5_XO_THERM                          0x0c
+#define ADC5_AMUX_THM1                         0x0d
+#define ADC5_AMUX_THM2                         0x0e
+#define ADC5_AMUX_THM3                         0x0f
+#define ADC5_AMUX_THM4                         0x10
+#define ADC5_AMUX_THM5                         0x11
+#define ADC5_GPIO1                             0x12
+#define ADC5_GPIO2                             0x13
+#define ADC5_GPIO3                             0x14
+#define ADC5_GPIO4                             0x15
+#define ADC5_GPIO5                             0x16
+#define ADC5_GPIO6                             0x17
+#define ADC5_GPIO7                             0x18
+#define ADC5_SBUx                              0x99
+#define ADC5_MID_CHG_DIV6                      0x1e
+#define ADC5_OFF                               0xff
+
+/* 30k pull-up1 */
+#define ADC5_BAT_THERM_30K_PU                  0x2a
+#define ADC5_BAT_ID_30K_PU                     0x2b
+#define ADC5_XO_THERM_30K_PU                   0x2c
+#define ADC5_AMUX_THM1_30K_PU                  0x2d
+#define ADC5_AMUX_THM2_30K_PU                  0x2e
+#define ADC5_AMUX_THM3_30K_PU                  0x2f
+#define ADC5_AMUX_THM4_30K_PU                  0x30
+#define ADC5_AMUX_THM5_30K_PU                  0x31
+#define ADC5_GPIO1_30K_PU                      0x32
+#define ADC5_GPIO2_30K_PU                      0x33
+#define ADC5_GPIO3_30K_PU                      0x34
+#define ADC5_GPIO4_30K_PU                      0x35
+#define ADC5_GPIO5_30K_PU                      0x36
+#define ADC5_GPIO6_30K_PU                      0x37
+#define ADC5_GPIO7_30K_PU                      0x38
+#define ADC5_SBUx_30K_PU                       0x39
+
+/* 100k pull-up2 */
+#define ADC5_BAT_THERM_100K_PU                 0x4a
+#define ADC5_BAT_ID_100K_PU                    0x4b
+#define ADC5_XO_THERM_100K_PU                  0x4c
+#define ADC5_AMUX_THM1_100K_PU                 0x4d
+#define ADC5_AMUX_THM2_100K_PU                 0x4e
+#define ADC5_AMUX_THM3_100K_PU                 0x4f
+#define ADC5_AMUX_THM4_100K_PU                 0x50
+#define ADC5_AMUX_THM5_100K_PU                 0x51
+#define ADC5_GPIO1_100K_PU                     0x52
+#define ADC5_GPIO2_100K_PU                     0x53
+#define ADC5_GPIO3_100K_PU                     0x54
+#define ADC5_GPIO4_100K_PU                     0x55
+#define ADC5_GPIO5_100K_PU                     0x56
+#define ADC5_GPIO6_100K_PU                     0x57
+#define ADC5_GPIO7_100K_PU                     0x58
+#define ADC5_SBUx_100K_PU                      0x59
+
+/* 400k pull-up3 */
+#define ADC5_BAT_THERM_400K_PU                 0x6a
+#define ADC5_BAT_ID_400K_PU                    0x6b
+#define ADC5_XO_THERM_400K_PU                  0x6c
+#define ADC5_AMUX_THM1_400K_PU                 0x6d
+#define ADC5_AMUX_THM2_400K_PU                 0x6e
+#define ADC5_AMUX_THM3_400K_PU                 0x6f
+#define ADC5_AMUX_THM4_400K_PU                 0x70
+#define ADC5_AMUX_THM5_400K_PU                 0x71
+#define ADC5_GPIO1_400K_PU                     0x72
+#define ADC5_GPIO2_400K_PU                     0x73
+#define ADC5_GPIO3_400K_PU                     0x74
+#define ADC5_GPIO4_400K_PU                     0x75
+#define ADC5_GPIO5_400K_PU                     0x76
+#define ADC5_GPIO6_400K_PU                     0x77
+#define ADC5_GPIO7_400K_PU                     0x78
+#define ADC5_SBUx_400K_PU                      0x79
+
+/* 1/3 Divider */
+#define ADC5_GPIO1_DIV3                                0x92
+#define ADC5_GPIO2_DIV3                                0x93
+#define ADC5_GPIO3_DIV3                                0x94
+#define ADC5_GPIO4_DIV3                                0x95
+#define ADC5_GPIO5_DIV3                                0x96
+#define ADC5_GPIO6_DIV3                                0x97
+#define ADC5_GPIO7_DIV3                                0x98
+#define ADC5_SBUx_DIV3                         0x99
+
+/* Current and combined current/voltage channels */
+#define ADC5_INT_EXT_ISENSE                    0xa1
+#define ADC5_PARALLEL_ISENSE                   0xa5
+#define ADC5_CUR_REPLICA_VDS                   0xa7
+#define ADC5_CUR_SENS_BATFET_VDS_OFFSET                0xa9
+#define ADC5_CUR_SENS_REPLICA_VDS_OFFSET       0xab
+#define ADC5_EXT_SENS_OFFSET                   0xad
+
+#define ADC5_INT_EXT_ISENSE_VBAT_VDATA         0xb0
+#define ADC5_INT_EXT_ISENSE_VBAT_IDATA         0xb1
+#define ADC5_EXT_ISENSE_VBAT_VDATA             0xb2
+#define ADC5_EXT_ISENSE_VBAT_IDATA             0xb3
+#define ADC5_PARALLEL_ISENSE_VBAT_VDATA                0xb4
+#define ADC5_PARALLEL_ISENSE_VBAT_IDATA                0xb5
+
+#define ADC5_MAX_CHANNEL                       0xc0
+
 #endif /* _DT_BINDINGS_QCOM_SPMI_VADC_H */
diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h b/include/dt-bindings/pinctrl/pinctrl-tegra-io-pad.h
new file mode 100644 (file)
index 0000000..20f4340
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * pinctrl-tegra-io-pad.h: Tegra I/O pad source voltage configuration constants
+ * pinctrl bindings.
+ *
+ * Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Author: Aapo Vienamo <avienamo@nvidia.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H
+#define _DT_BINDINGS_PINCTRL_TEGRA_IO_PAD_H
+
+/* Voltage levels of the I/O pad's source rail */
+#define TEGRA_IO_PAD_VOLTAGE_1V8       0
+#define TEGRA_IO_PAD_VOLTAGE_3V3       1
+
+#endif
diff --git a/include/dt-bindings/power/owl-s900-powergate.h b/include/dt-bindings/power/owl-s900-powergate.h
new file mode 100644 (file)
index 0000000..d939bd9
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) */
+/*
+ * Actions Semi S900 SPS
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ */
+#ifndef DT_BINDINGS_POWER_OWL_S900_POWERGATE_H
+#define DT_BINDINGS_POWER_OWL_S900_POWERGATE_H
+
+#define S900_PD_GPU_B  0
+#define S900_PD_VCE    1
+#define S900_PD_SENSOR 2
+#define S900_PD_VDE    3
+#define S900_PD_HDE    4
+#define S900_PD_USB3   5
+#define S900_PD_DDR0   6
+#define S900_PD_DDR1   7
+#define S900_PD_DE     8
+#define S900_PD_NAND   9
+#define S900_PD_USB2_H0        10
+#define S900_PD_USB2_H1        11
+
+#endif
diff --git a/include/dt-bindings/power/r8a7744-sysc.h b/include/dt-bindings/power/r8a7744-sysc.h
new file mode 100644 (file)
index 0000000..8b65297
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A7744_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A7744_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ *
+ * Note that RZ/G1N is identical to RZ/G2M w.r.t. power domains.
+ */
+
+#define R8A7744_PD_CA15_CPU0            0
+#define R8A7744_PD_CA15_CPU1            1
+#define R8A7744_PD_CA15_SCU            12
+#define R8A7744_PD_SGX                 20
+
+/* Always-on power area */
+#define R8A7744_PD_ALWAYS_ON           32
+
+#endif /* __DT_BINDINGS_POWER_R8A7744_SYSC_H__ */
diff --git a/include/dt-bindings/power/r8a774a1-sysc.h b/include/dt-bindings/power/r8a774a1-sysc.h
new file mode 100644 (file)
index 0000000..580f431
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A774A1_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A774A1_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A774A1_PD_CA57_CPU0           0
+#define R8A774A1_PD_CA57_CPU1           1
+#define R8A774A1_PD_CA53_CPU0           5
+#define R8A774A1_PD_CA53_CPU1           6
+#define R8A774A1_PD_CA53_CPU2           7
+#define R8A774A1_PD_CA53_CPU3           8
+#define R8A774A1_PD_CA57_SCU           12
+#define R8A774A1_PD_A3VC               14
+#define R8A774A1_PD_3DG_A              17
+#define R8A774A1_PD_3DG_B              18
+#define R8A774A1_PD_CA53_SCU           21
+#define R8A774A1_PD_A2VC0              25
+#define R8A774A1_PD_A2VC1              26
+
+/* Always-on power area */
+#define R8A774A1_PD_ALWAYS_ON          32
+
+#endif /* __DT_BINDINGS_POWER_R8A774A1_SYSC_H__ */
diff --git a/include/dt-bindings/power/r8a774c0-sysc.h b/include/dt-bindings/power/r8a774c0-sysc.h
new file mode 100644 (file)
index 0000000..9922d4c
--- /dev/null
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A774C0_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A774C0_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A774C0_PD_CA53_CPU0          5
+#define R8A774C0_PD_CA53_CPU1          6
+#define R8A774C0_PD_A3VC               14
+#define R8A774C0_PD_3DG_A              17
+#define R8A774C0_PD_3DG_B              18
+#define R8A774C0_PD_CA53_SCU           21
+#define R8A774C0_PD_A2VC1              26
+
+/* Always-on power area */
+#define R8A774C0_PD_ALWAYS_ON          32
+
+#endif /* __DT_BINDINGS_POWER_R8A774C0_SYSC_H__ */
diff --git a/include/dt-bindings/reset/actions,s700-reset.h b/include/dt-bindings/reset/actions,s700-reset.h
new file mode 100644 (file)
index 0000000..5e3b16b
--- /dev/null
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+//
+// Device Tree binding constants for Actions Semi S700 Reset Management Unit
+//
+// Copyright (c) 2018 Linaro Ltd.
+
+#ifndef __DT_BINDINGS_ACTIONS_S700_RESET_H
+#define __DT_BINDINGS_ACTIONS_S700_RESET_H
+
+#define RESET_AUDIO                            0
+#define RESET_CSI                              1
+#define RESET_DE                               2
+#define RESET_DSI                              3
+#define RESET_GPIO                             4
+#define RESET_I2C0                             5
+#define RESET_I2C1                             6
+#define RESET_I2C2                             7
+#define RESET_I2C3                             8
+#define RESET_KEY                              9
+#define RESET_LCD0                             10
+#define RESET_SI                               11
+#define RESET_SPI0                             12
+#define RESET_SPI1                             13
+#define RESET_SPI2                             14
+#define RESET_SPI3                             15
+#define RESET_UART0                            16
+#define RESET_UART1                            17
+#define RESET_UART2                            18
+#define RESET_UART3                            19
+#define RESET_UART4                            20
+#define RESET_UART5                            21
+#define RESET_UART6                            22
+
+#endif /* __DT_BINDINGS_ACTIONS_S700_RESET_H */
diff --git a/include/dt-bindings/reset/actions,s900-reset.h b/include/dt-bindings/reset/actions,s900-reset.h
new file mode 100644 (file)
index 0000000..42c19d0
--- /dev/null
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+//
+// Device Tree binding constants for Actions Semi S900 Reset Management Unit
+//
+// Copyright (c) 2018 Linaro Ltd.
+
+#ifndef __DT_BINDINGS_ACTIONS_S900_RESET_H
+#define __DT_BINDINGS_ACTIONS_S900_RESET_H
+
+#define RESET_CHIPID                           0
+#define RESET_CPU_SCNT                         1
+#define RESET_SRAMI                            2
+#define RESET_DDR_CTL_PHY                      3
+#define RESET_DMAC                             4
+#define RESET_GPIO                             5
+#define RESET_BISP_AXI                         6
+#define RESET_CSI0                             7
+#define RESET_CSI1                             8
+#define RESET_DE                               9
+#define RESET_DSI                              10
+#define RESET_GPU3D_PA                         11
+#define RESET_GPU3D_PB                         12
+#define RESET_HDE                              13
+#define RESET_I2C0                             14
+#define RESET_I2C1                             15
+#define RESET_I2C2                             16
+#define RESET_I2C3                             17
+#define RESET_I2C4                             18
+#define RESET_I2C5                             19
+#define RESET_IMX                              20
+#define RESET_NANDC0                           21
+#define RESET_NANDC1                           22
+#define RESET_SD0                              23
+#define RESET_SD1                              24
+#define RESET_SD2                              25
+#define RESET_SD3                              26
+#define RESET_SPI0                             27
+#define RESET_SPI1                             28
+#define RESET_SPI2                             29
+#define RESET_SPI3                             30
+#define RESET_UART0                            31
+#define RESET_UART1                            32
+#define RESET_UART2                            33
+#define RESET_UART3                            34
+#define RESET_UART4                            35
+#define RESET_UART5                            36
+#define RESET_UART6                            37
+#define RESET_HDMI                             38
+#define RESET_LVDS                             39
+#define RESET_EDP                              40
+#define RESET_USB2HUB                          41
+#define RESET_USB2HSIC                         42
+#define RESET_USB3                             43
+#define RESET_PCM1                             44
+#define RESET_AUDIO                            45
+#define RESET_PCM0                             46
+#define RESET_SE                               47
+#define RESET_GIC                              48
+#define RESET_DDR_CTL_PHY_AXI                  49
+#define RESET_CMU_DDR                          50
+#define RESET_DMM                              51
+#define RESET_HDCP2TX                          52
+#define RESET_ETHERNET                         53
+
+#endif /* __DT_BINDINGS_ACTIONS_S900_RESET_H */
diff --git a/include/dt-bindings/reset/qcom,sdm845-pdc.h b/include/dt-bindings/reset/qcom,sdm845-pdc.h
new file mode 100644 (file)
index 0000000..53c37f9
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_RESET_PDC_SDM_845_H
+#define _DT_BINDINGS_RESET_PDC_SDM_845_H
+
+#define PDC_APPS_SYNC_RESET    0
+#define PDC_SP_SYNC_RESET      1
+#define PDC_AUDIO_SYNC_RESET   2
+#define PDC_SENSORS_SYNC_RESET 3
+#define PDC_AOP_SYNC_RESET     4
+#define PDC_DEBUG_SYNC_RESET   5
+#define PDC_GPU_SYNC_RESET     6
+#define PDC_DISPLAY_SYNC_RESET 7
+#define PDC_COMPUTE_SYNC_RESET 8
+#define PDC_MODEM_SYNC_RESET   9
+
+#endif
index acf5e8df3504fc347cc1bdac552c4f631c55a6dd..f58e97446abcf5e3d75f2896af9d0acb7a6a9b5e 100644 (file)
@@ -28,8 +28,8 @@
  * The available bitmap operations and their rough meaning in the
  * case that the bitmap is a single unsigned long are thus:
  *
- * Note that nbits should be always a compile time evaluable constant.
- * Otherwise many inlines will generate horrible code.
+ * The generated code is more efficient when nbits is known at
+ * compile-time and at most BITS_PER_LONG.
  *
  * ::
  *
@@ -204,38 +204,31 @@ extern int bitmap_print_to_pagebuf(bool list, char *buf,
 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
 #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
 
+/*
+ * The static inlines below do not handle constant nbits==0 correctly,
+ * so make such users (should any ever turn up) call the out-of-line
+ * versions.
+ */
 #define small_const_nbits(nbits) \
-       (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
+       (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG && (nbits) > 0)
 
 static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
 {
-       if (small_const_nbits(nbits))
-               *dst = 0UL;
-       else {
-               unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
-               memset(dst, 0, len);
-       }
+       unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+       memset(dst, 0, len);
 }
 
 static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
 {
-       if (small_const_nbits(nbits))
-               *dst = ~0UL;
-       else {
-               unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
-               memset(dst, 0xff, len);
-       }
+       unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+       memset(dst, 0xff, len);
 }
 
 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
                        unsigned int nbits)
 {
-       if (small_const_nbits(nbits))
-               *dst = *src;
-       else {
-               unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
-               memcpy(dst, src, len);
-       }
+       unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+       memcpy(dst, src, len);
 }
 
 /*
@@ -398,7 +391,7 @@ static __always_inline void bitmap_clear(unsigned long *map, unsigned int start,
 }
 
 static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src,
-                               unsigned int shift, int nbits)
+                               unsigned int shift, unsigned int nbits)
 {
        if (small_const_nbits(nbits))
                *dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift;
index 7ddb1349394dbc4472779592ce590366d7571094..705f7c44269177d232a57c8f25ca00ba7faf9482 100644 (file)
@@ -236,33 +236,33 @@ static __always_inline void __assign_bit(long nr, volatile unsigned long *addr,
 #ifdef __KERNEL__
 
 #ifndef set_mask_bits
-#define set_mask_bits(ptr, _mask, _bits)       \
+#define set_mask_bits(ptr, mask, bits) \
 ({                                                             \
-       const typeof(*ptr) mask = (_mask), bits = (_bits);      \
-       typeof(*ptr) old, new;                                  \
+       const typeof(*(ptr)) mask__ = (mask), bits__ = (bits);  \
+       typeof(*(ptr)) old__, new__;                            \
                                                                \
        do {                                                    \
-               old = READ_ONCE(*ptr);                  \
-               new = (old & ~mask) | bits;                     \
-       } while (cmpxchg(ptr, old, new) != old);                \
+               old__ = READ_ONCE(*(ptr));                      \
+               new__ = (old__ & ~mask__) | bits__;             \
+       } while (cmpxchg(ptr, old__, new__) != old__);          \
                                                                \
-       new;                                                    \
+       new__;                                                  \
 })
 #endif
 
 #ifndef bit_clear_unless
-#define bit_clear_unless(ptr, _clear, _test)   \
+#define bit_clear_unless(ptr, clear, test)     \
 ({                                                             \
-       const typeof(*ptr) clear = (_clear), test = (_test);    \
-       typeof(*ptr) old, new;                                  \
+       const typeof(*(ptr)) clear__ = (clear), test__ = (test);\
+       typeof(*(ptr)) old__, new__;                            \
                                                                \
        do {                                                    \
-               old = READ_ONCE(*ptr);                  \
-               new = old & ~clear;                             \
-       } while (!(old & test) &&                               \
-                cmpxchg(ptr, old, new) != old);                \
+               old__ = READ_ONCE(*(ptr));                      \
+               new__ = old__ & ~clear__;                       \
+       } while (!(old__ & test__) &&                           \
+                cmpxchg(ptr, old__, new__) != old__);          \
                                                                \
-       !(old & test);                                          \
+       !(old__ & test__);                                      \
 })
 #endif
 
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
deleted file mode 100644 (file)
index 4251519..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
- */
-#ifndef _LINUX_BOOTMEM_H
-#define _LINUX_BOOTMEM_H
-
-#include <linux/mmzone.h>
-#include <linux/mm_types.h>
-#include <asm/dma.h>
-#include <asm/processor.h>
-
-/*
- *  simple boot-time physical memory area allocator.
- */
-
-extern unsigned long max_low_pfn;
-extern unsigned long min_low_pfn;
-
-/*
- * highest page
- */
-extern unsigned long max_pfn;
-/*
- * highest possible page
- */
-extern unsigned long long max_possible_pfn;
-
-#ifndef CONFIG_NO_BOOTMEM
-/**
- * struct bootmem_data - per-node information used by the bootmem allocator
- * @node_min_pfn: the starting physical address of the node's memory
- * @node_low_pfn: the end physical address of the directly addressable memory
- * @node_bootmem_map: is a bitmap pointer - the bits represent all physical
- *                   memory pages (including holes) on the node.
- * @last_end_off: the offset within the page of the end of the last allocation;
- *                if 0, the page used is full
- * @hint_idx: the PFN of the page used with the last allocation;
- *            together with using this with the @last_end_offset field,
- *            a test can be made to see if allocations can be merged
- *            with the page used for the last allocation rather than
- *            using up a full new page.
- * @list: list entry in the linked list ordered by the memory addresses
- */
-typedef struct bootmem_data {
-       unsigned long node_min_pfn;
-       unsigned long node_low_pfn;
-       void *node_bootmem_map;
-       unsigned long last_end_off;
-       unsigned long hint_idx;
-       struct list_head list;
-} bootmem_data_t;
-
-extern bootmem_data_t bootmem_node_data[];
-#endif
-
-extern unsigned long bootmem_bootmap_pages(unsigned long);
-
-extern unsigned long init_bootmem_node(pg_data_t *pgdat,
-                                      unsigned long freepfn,
-                                      unsigned long startpfn,
-                                      unsigned long endpfn);
-extern unsigned long init_bootmem(unsigned long addr, unsigned long memend);
-
-extern unsigned long free_all_bootmem(void);
-extern void reset_node_managed_pages(pg_data_t *pgdat);
-extern void reset_all_zones_managed_pages(void);
-
-extern void free_bootmem_node(pg_data_t *pgdat,
-                             unsigned long addr,
-                             unsigned long size);
-extern void free_bootmem(unsigned long physaddr, unsigned long size);
-extern void free_bootmem_late(unsigned long physaddr, unsigned long size);
-
-/*
- * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
- * the architecture-specific code should honor this).
- *
- * If flags is BOOTMEM_DEFAULT, then the return value is always 0 (success).
- * If flags contains BOOTMEM_EXCLUSIVE, then -EBUSY is returned if the memory
- * already was reserved.
- */
-#define BOOTMEM_DEFAULT                0
-#define BOOTMEM_EXCLUSIVE      (1<<0)
-
-extern int reserve_bootmem(unsigned long addr,
-                          unsigned long size,
-                          int flags);
-extern int reserve_bootmem_node(pg_data_t *pgdat,
-                               unsigned long physaddr,
-                               unsigned long size,
-                               int flags);
-
-extern void *__alloc_bootmem(unsigned long size,
-                            unsigned long align,
-                            unsigned long goal);
-extern void *__alloc_bootmem_nopanic(unsigned long size,
-                                    unsigned long align,
-                                    unsigned long goal) __malloc;
-extern void *__alloc_bootmem_node(pg_data_t *pgdat,
-                                 unsigned long size,
-                                 unsigned long align,
-                                 unsigned long goal) __malloc;
-void *__alloc_bootmem_node_high(pg_data_t *pgdat,
-                                 unsigned long size,
-                                 unsigned long align,
-                                 unsigned long goal) __malloc;
-extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat,
-                                 unsigned long size,
-                                 unsigned long align,
-                                 unsigned long goal) __malloc;
-void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
-                                 unsigned long size,
-                                 unsigned long align,
-                                 unsigned long goal,
-                                 unsigned long limit) __malloc;
-extern void *__alloc_bootmem_low(unsigned long size,
-                                unsigned long align,
-                                unsigned long goal) __malloc;
-void *__alloc_bootmem_low_nopanic(unsigned long size,
-                                unsigned long align,
-                                unsigned long goal) __malloc;
-extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
-                                     unsigned long size,
-                                     unsigned long align,
-                                     unsigned long goal) __malloc;
-
-#ifdef CONFIG_NO_BOOTMEM
-/* We are using top down, so it is safe to use 0 here */
-#define BOOTMEM_LOW_LIMIT 0
-#else
-#define BOOTMEM_LOW_LIMIT __pa(MAX_DMA_ADDRESS)
-#endif
-
-#ifndef ARCH_LOW_ADDRESS_LIMIT
-#define ARCH_LOW_ADDRESS_LIMIT  0xffffffffUL
-#endif
-
-#define alloc_bootmem(x) \
-       __alloc_bootmem(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_align(x, align) \
-       __alloc_bootmem(x, align, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_nopanic(x) \
-       __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_pages(x) \
-       __alloc_bootmem(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_pages_nopanic(x) \
-       __alloc_bootmem_nopanic(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_node(pgdat, x) \
-       __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_node_nopanic(pgdat, x) \
-       __alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_pages_node(pgdat, x) \
-       __alloc_bootmem_node(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
-#define alloc_bootmem_pages_node_nopanic(pgdat, x) \
-       __alloc_bootmem_node_nopanic(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT)
-
-#define alloc_bootmem_low(x) \
-       __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0)
-#define alloc_bootmem_low_pages_nopanic(x) \
-       __alloc_bootmem_low_nopanic(x, PAGE_SIZE, 0)
-#define alloc_bootmem_low_pages(x) \
-       __alloc_bootmem_low(x, PAGE_SIZE, 0)
-#define alloc_bootmem_low_pages_node(pgdat, x) \
-       __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0)
-
-
-#if defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM)
-
-/* FIXME: use MEMBLOCK_ALLOC_* variants here */
-#define BOOTMEM_ALLOC_ACCESSIBLE       0
-#define BOOTMEM_ALLOC_ANYWHERE         (~(phys_addr_t)0)
-
-/* FIXME: Move to memblock.h at a point where we remove nobootmem.c */
-void *memblock_virt_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align,
-                                     phys_addr_t min_addr,
-                                     phys_addr_t max_addr, int nid);
-void *memblock_virt_alloc_try_nid_nopanic(phys_addr_t size,
-               phys_addr_t align, phys_addr_t min_addr,
-               phys_addr_t max_addr, int nid);
-void *memblock_virt_alloc_try_nid(phys_addr_t size, phys_addr_t align,
-               phys_addr_t min_addr, phys_addr_t max_addr, int nid);
-void __memblock_free_early(phys_addr_t base, phys_addr_t size);
-void __memblock_free_late(phys_addr_t base, phys_addr_t size);
-
-static inline void * __init memblock_virt_alloc(
-                                       phys_addr_t size,  phys_addr_t align)
-{
-       return memblock_virt_alloc_try_nid(size, align, BOOTMEM_LOW_LIMIT,
-                                           BOOTMEM_ALLOC_ACCESSIBLE,
-                                           NUMA_NO_NODE);
-}
-
-static inline void * __init memblock_virt_alloc_raw(
-                                       phys_addr_t size,  phys_addr_t align)
-{
-       return memblock_virt_alloc_try_nid_raw(size, align, BOOTMEM_LOW_LIMIT,
-                                           BOOTMEM_ALLOC_ACCESSIBLE,
-                                           NUMA_NO_NODE);
-}
-
-static inline void * __init memblock_virt_alloc_nopanic(
-                                       phys_addr_t size, phys_addr_t align)
-{
-       return memblock_virt_alloc_try_nid_nopanic(size, align,
-                                                   BOOTMEM_LOW_LIMIT,
-                                                   BOOTMEM_ALLOC_ACCESSIBLE,
-                                                   NUMA_NO_NODE);
-}
-
-static inline void * __init memblock_virt_alloc_low(
-                                       phys_addr_t size, phys_addr_t align)
-{
-       return memblock_virt_alloc_try_nid(size, align,
-                                                  BOOTMEM_LOW_LIMIT,
-                                                  ARCH_LOW_ADDRESS_LIMIT,
-                                                  NUMA_NO_NODE);
-}
-static inline void * __init memblock_virt_alloc_low_nopanic(
-                                       phys_addr_t size, phys_addr_t align)
-{
-       return memblock_virt_alloc_try_nid_nopanic(size, align,
-                                                  BOOTMEM_LOW_LIMIT,
-                                                  ARCH_LOW_ADDRESS_LIMIT,
-                                                  NUMA_NO_NODE);
-}
-
-static inline void * __init memblock_virt_alloc_from_nopanic(
-               phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
-{
-       return memblock_virt_alloc_try_nid_nopanic(size, align, min_addr,
-                                                   BOOTMEM_ALLOC_ACCESSIBLE,
-                                                   NUMA_NO_NODE);
-}
-
-static inline void * __init memblock_virt_alloc_node(
-                                               phys_addr_t size, int nid)
-{
-       return memblock_virt_alloc_try_nid(size, 0, BOOTMEM_LOW_LIMIT,
-                                           BOOTMEM_ALLOC_ACCESSIBLE, nid);
-}
-
-static inline void * __init memblock_virt_alloc_node_nopanic(
-                                               phys_addr_t size, int nid)
-{
-       return memblock_virt_alloc_try_nid_nopanic(size, 0, BOOTMEM_LOW_LIMIT,
-                                                   BOOTMEM_ALLOC_ACCESSIBLE,
-                                                   nid);
-}
-
-static inline void __init memblock_free_early(
-                                       phys_addr_t base, phys_addr_t size)
-{
-       __memblock_free_early(base, size);
-}
-
-static inline void __init memblock_free_early_nid(
-                               phys_addr_t base, phys_addr_t size, int nid)
-{
-       __memblock_free_early(base, size);
-}
-
-static inline void __init memblock_free_late(
-                                       phys_addr_t base, phys_addr_t size)
-{
-       __memblock_free_late(base, size);
-}
-
-#else
-
-#define BOOTMEM_ALLOC_ACCESSIBLE       0
-
-
-/* Fall back to all the existing bootmem APIs */
-static inline void * __init memblock_virt_alloc(
-                                       phys_addr_t size,  phys_addr_t align)
-{
-       if (!align)
-               align = SMP_CACHE_BYTES;
-       return __alloc_bootmem(size, align, BOOTMEM_LOW_LIMIT);
-}
-
-static inline void * __init memblock_virt_alloc_raw(
-                                       phys_addr_t size,  phys_addr_t align)
-{
-       if (!align)
-               align = SMP_CACHE_BYTES;
-       return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT);
-}
-
-static inline void * __init memblock_virt_alloc_nopanic(
-                                       phys_addr_t size, phys_addr_t align)
-{
-       if (!align)
-               align = SMP_CACHE_BYTES;
-       return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT);
-}
-
-static inline void * __init memblock_virt_alloc_low(
-                                       phys_addr_t size, phys_addr_t align)
-{
-       if (!align)
-               align = SMP_CACHE_BYTES;
-       return __alloc_bootmem_low(size, align, 0);
-}
-
-static inline void * __init memblock_virt_alloc_low_nopanic(
-                                       phys_addr_t size, phys_addr_t align)
-{
-       if (!align)
-               align = SMP_CACHE_BYTES;
-       return __alloc_bootmem_low_nopanic(size, align, 0);
-}
-
-static inline void * __init memblock_virt_alloc_from_nopanic(
-               phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
-{
-       return __alloc_bootmem_nopanic(size, align, min_addr);
-}
-
-static inline void * __init memblock_virt_alloc_node(
-                                               phys_addr_t size, int nid)
-{
-       return __alloc_bootmem_node(NODE_DATA(nid), size, SMP_CACHE_BYTES,
-                                    BOOTMEM_LOW_LIMIT);
-}
-
-static inline void * __init memblock_virt_alloc_node_nopanic(
-                                               phys_addr_t size, int nid)
-{
-       return __alloc_bootmem_node_nopanic(NODE_DATA(nid), size,
-                                            SMP_CACHE_BYTES,
-                                            BOOTMEM_LOW_LIMIT);
-}
-
-static inline void * __init memblock_virt_alloc_try_nid(phys_addr_t size,
-       phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid)
-{
-       return __alloc_bootmem_node_high(NODE_DATA(nid), size, align,
-                                         min_addr);
-}
-
-static inline void * __init memblock_virt_alloc_try_nid_raw(
-                       phys_addr_t size, phys_addr_t align,
-                       phys_addr_t min_addr, phys_addr_t max_addr, int nid)
-{
-       return ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, align,
-                               min_addr, max_addr);
-}
-
-static inline void * __init memblock_virt_alloc_try_nid_nopanic(
-                       phys_addr_t size, phys_addr_t align,
-                       phys_addr_t min_addr, phys_addr_t max_addr, int nid)
-{
-       return ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, align,
-                               min_addr, max_addr);
-}
-
-static inline void __init memblock_free_early(
-                                       phys_addr_t base, phys_addr_t size)
-{
-       free_bootmem(base, size);
-}
-
-static inline void __init memblock_free_early_nid(
-                               phys_addr_t base, phys_addr_t size, int nid)
-{
-       free_bootmem_node(NODE_DATA(nid), base, size);
-}
-
-static inline void __init memblock_free_late(
-                                       phys_addr_t base, phys_addr_t size)
-{
-       free_bootmem_late(base, size);
-}
-#endif /* defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM) */
-
-extern void *alloc_large_system_hash(const char *tablename,
-                                    unsigned long bucketsize,
-                                    unsigned long numentries,
-                                    int scale,
-                                    int flags,
-                                    unsigned int *_hash_shift,
-                                    unsigned int *_hash_mask,
-                                    unsigned long low_limit,
-                                    unsigned long high_limit);
-
-#define HASH_EARLY     0x00000001      /* Allocating during early boot? */
-#define HASH_SMALL     0x00000002      /* sub-page allocation allowed, min
-                                        * shift passed via *_hash_shift */
-#define HASH_ZERO      0x00000004      /* Zero allocated hash table */
-
-/* Only NUMA needs hash distribution. 64bit NUMA architectures have
- * sufficient vmalloc space.
- */
-#ifdef CONFIG_NUMA
-#define HASHDIST_DEFAULT IS_ENABLED(CONFIG_64BIT)
-extern int hashdist;           /* Distribute hashes across NUMA nodes? */
-#else
-#define hashdist (0)
-#endif
-
-
-#endif /* _LINUX_BOOTMEM_H */
index 49c93b9308d70543c865f437bd3390ef6e7be73e..68bb09c29ce898319dfef708108eaf032f2e513c 100644 (file)
@@ -81,7 +81,13 @@ struct ceph_options {
 
 #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
 #define CEPH_MSG_MAX_MIDDLE_LEN        (16*1024*1024)
-#define CEPH_MSG_MAX_DATA_LEN  (16*1024*1024)
+
+/*
+ * Handle the largest possible rbd object in one message.
+ * There is no limit on the size of cephfs objects, but it has to obey
+ * rsize and wsize mount options anyway.
+ */
+#define CEPH_MSG_MAX_DATA_LEN  (32*1024*1024)
 
 #define CEPH_AUTH_NAME_DEFAULT   "guest"
 
index fc2b4491ee0aac1101ef553b6bf4e88d9807b7bb..800a2128d411b3a1f39ec0ab4f2068a4b4d76a52 100644 (file)
@@ -82,22 +82,6 @@ enum ceph_msg_data_type {
        CEPH_MSG_DATA_BVECS,    /* data source/destination is a bio_vec array */
 };
 
-static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type)
-{
-       switch (type) {
-       case CEPH_MSG_DATA_NONE:
-       case CEPH_MSG_DATA_PAGES:
-       case CEPH_MSG_DATA_PAGELIST:
-#ifdef CONFIG_BLOCK
-       case CEPH_MSG_DATA_BIO:
-#endif /* CONFIG_BLOCK */
-       case CEPH_MSG_DATA_BVECS:
-               return true;
-       default:
-               return false;
-       }
-}
-
 #ifdef CONFIG_BLOCK
 
 struct ceph_bio_iter {
@@ -181,7 +165,6 @@ struct ceph_bvec_iter {
 } while (0)
 
 struct ceph_msg_data {
-       struct list_head                links;  /* ceph_msg->data */
        enum ceph_msg_data_type         type;
        union {
 #ifdef CONFIG_BLOCK
@@ -202,7 +185,6 @@ struct ceph_msg_data {
 
 struct ceph_msg_data_cursor {
        size_t                  total_resid;    /* across all data items */
-       struct list_head        *data_head;     /* = &ceph_msg->data */
 
        struct ceph_msg_data    *data;          /* current data item */
        size_t                  resid;          /* bytes not yet consumed */
@@ -240,7 +222,9 @@ struct ceph_msg {
        struct ceph_buffer *middle;
 
        size_t                          data_length;
-       struct list_head                data;
+       struct ceph_msg_data            *data;
+       int                             num_data_items;
+       int                             max_data_items;
        struct ceph_msg_data_cursor     cursor;
 
        struct ceph_connection *con;
@@ -381,6 +365,8 @@ void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos,
 void ceph_msg_data_add_bvecs(struct ceph_msg *msg,
                             struct ceph_bvec_iter *bvec_pos);
 
+struct ceph_msg *ceph_msg_new2(int type, int front_len, int max_data_items,
+                              gfp_t flags, bool can_fail);
 extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
                                     bool can_fail);
 
index 76c98a51275884f74a78161293e32bc50690f65a..729cdf700eae363728a8057b7b710fa59387ce75 100644 (file)
@@ -13,14 +13,15 @@ struct ceph_msgpool {
        mempool_t *pool;
        int type;               /* preallocated message type */
        int front_len;          /* preallocated payload size */
+       int max_data_items;
 };
 
-extern int ceph_msgpool_init(struct ceph_msgpool *pool, int type,
-                            int front_len, int size, bool blocking,
-                            const char *name);
+int ceph_msgpool_init(struct ceph_msgpool *pool, int type,
+                     int front_len, int max_data_items, int size,
+                     const char *name);
 extern void ceph_msgpool_destroy(struct ceph_msgpool *pool);
-extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *,
-                                        int front_len);
+struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len,
+                                 int max_data_items);
 extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *);
 
 #endif
index 02096da01845c992d5b8217a9291337fed3ff6cd..7a2af5034278f1d4f868a2617e615d1d0eb71d4f 100644 (file)
@@ -136,6 +136,13 @@ struct ceph_osd_req_op {
                        u64 expected_object_size;
                        u64 expected_write_size;
                } alloc_hint;
+               struct {
+                       u64 snapid;
+                       u64 src_version;
+                       u8 flags;
+                       u32 src_fadvise_flags;
+                       struct ceph_osd_data osd_data;
+               } copy_from;
        };
 };
 
@@ -444,9 +451,8 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *,
                                        struct page **pages, u64 length,
                                        u32 alignment, bool pages_from_pool,
                                        bool own_pages);
-extern int osd_req_op_cls_init(struct ceph_osd_request *osd_req,
-                                       unsigned int which, u16 opcode,
-                                       const char *class, const char *method);
+int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
+                       const char *class, const char *method);
 extern int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
                                 u16 opcode, const char *name, const void *value,
                                 size_t size, u8 cmp_op, u8 cmp_mode);
@@ -511,6 +517,16 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
                                struct timespec64 *mtime,
                                struct page **pages, int nr_pages);
 
+int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
+                       u64 src_snapid, u64 src_version,
+                       struct ceph_object_id *src_oid,
+                       struct ceph_object_locator *src_oloc,
+                       u32 src_fadvise_flags,
+                       struct ceph_object_id *dst_oid,
+                       struct ceph_object_locator *dst_oloc,
+                       u32 dst_fadvise_flags,
+                       u8 copy_from_flags);
+
 /* watch/notify */
 struct ceph_osd_linger_request *
 ceph_osdc_watch(struct ceph_osd_client *osdc,
index d0223364349f772ae4086ddc1304e02cf53a9d89..5dead8486fd8f38e9ac2c9333374b6da2b1d21f7 100644 (file)
@@ -23,16 +23,7 @@ struct ceph_pagelist_cursor {
        size_t room;                /* room remaining to reset to */
 };
 
-static inline void ceph_pagelist_init(struct ceph_pagelist *pl)
-{
-       INIT_LIST_HEAD(&pl->head);
-       pl->mapped_tail = NULL;
-       pl->length = 0;
-       pl->room = 0;
-       INIT_LIST_HEAD(&pl->free_list);
-       pl->num_pages_free = 0;
-       refcount_set(&pl->refcnt, 1);
-}
+struct ceph_pagelist *ceph_pagelist_alloc(gfp_t gfp_flags);
 
 extern void ceph_pagelist_release(struct ceph_pagelist *pl);
 
index f1988387c5ad03882decfa12f444f250fe905134..3eb0e55665b4c5344a04d652b42307219d6589c0 100644 (file)
@@ -410,6 +410,14 @@ enum {
 enum {
        CEPH_OSD_OP_FLAG_EXCL = 1,      /* EXCL object create */
        CEPH_OSD_OP_FLAG_FAILOK = 2,    /* continue despite failure */
+       CEPH_OSD_OP_FLAG_FADVISE_RANDOM     = 0x4, /* the op is random */
+       CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL = 0x8, /* the op is sequential */
+       CEPH_OSD_OP_FLAG_FADVISE_WILLNEED   = 0x10,/* data will be accessed in
+                                                     the near future */
+       CEPH_OSD_OP_FLAG_FADVISE_DONTNEED   = 0x20,/* data will not be accessed
+                                                     in the near future */
+       CEPH_OSD_OP_FLAG_FADVISE_NOCACHE    = 0x40,/* data will be accessed only
+                                                     once by this client */
 };
 
 #define EOLDSNAPC    ERESTART  /* ORDERSNAP flag set; writer has old snapc*/
@@ -431,6 +439,15 @@ enum {
        CEPH_OSD_CMPXATTR_MODE_U64    = 2
 };
 
+enum {
+       CEPH_OSD_COPY_FROM_FLAG_FLUSH = 1,       /* part of a flush operation */
+       CEPH_OSD_COPY_FROM_FLAG_IGNORE_OVERLAY = 2, /* ignore pool overlay */
+       CEPH_OSD_COPY_FROM_FLAG_IGNORE_CACHE = 4,   /* ignore osd cache logic */
+       CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE = 8, /* map snap direct to
+                                                    * cloneid */
+       CEPH_OSD_COPY_FROM_FLAG_RWORDERED = 16,     /* order with write */
+};
+
 enum {
        CEPH_OSD_WATCH_OP_UNWATCH = 0,
        CEPH_OSD_WATCH_OP_LEGACY_WATCH = 1,
@@ -497,6 +514,17 @@ struct ceph_osd_op {
                        __le64 expected_object_size;
                        __le64 expected_write_size;
                } __attribute__ ((packed)) alloc_hint;
+               struct {
+                       __le64 snapid;
+                       __le64 src_version;
+                       __u8 flags; /* CEPH_OSD_COPY_FROM_FLAG_* */
+                       /*
+                        * CEPH_OSD_OP_FLAG_FADVISE_*: fadvise flags
+                        * for src object, flags for dest object are in
+                        * ceph_osd_op::flags.
+                        */
+                       __le32 src_fadvise_flags;
+               } __attribute__ ((packed)) copy_from;
        };
        __le32 payload_len;
 } __attribute__ ((packed));
index 08b1aa70a38d30a30cb4ae0f58bf7a68be92b15b..60c51871b04be87b67235c952edb85f8b26b6217 100644 (file)
@@ -119,6 +119,11 @@ struct clk_duty {
  *             Called with enable_lock held.  This function must not
  *             sleep.
  *
+ * @save_context: Save the context of the clock in prepration for poweroff.
+ *
+ * @restore_context: Restore the context of the clock after a restoration
+ *             of power.
+ *
  * @recalc_rate        Recalculate the rate of this clock, by querying hardware. The
  *             parent rate is an input parameter.  It is up to the caller to
  *             ensure that the prepare_mutex is held across this call.
@@ -223,6 +228,8 @@ struct clk_ops {
        void            (*disable)(struct clk_hw *hw);
        int             (*is_enabled)(struct clk_hw *hw);
        void            (*disable_unused)(struct clk_hw *hw);
+       int             (*save_context)(struct clk_hw *hw);
+       void            (*restore_context)(struct clk_hw *hw);
        unsigned long   (*recalc_rate)(struct clk_hw *hw,
                                        unsigned long parent_rate);
        long            (*round_rate)(struct clk_hw *hw, unsigned long rate,
@@ -1011,5 +1018,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)
 
 #endif /* platform dependent I/O accessors */
 
+void clk_gate_restore_context(struct clk_hw *hw);
+
 #endif /* CONFIG_COMMON_CLK */
 #endif /* CLK_PROVIDER_H */
index 4f750c481b82b29d05e136d9cea42e51e58199b9..a7773b5c0b9fb4b3e9c08966c83b3441ef240760 100644 (file)
@@ -312,7 +312,26 @@ struct clk *clk_get(struct device *dev, const char *id);
  */
 int __must_check clk_bulk_get(struct device *dev, int num_clks,
                              struct clk_bulk_data *clks);
-
+/**
+ * clk_bulk_get_all - lookup and obtain all available references to clock
+ *                   producer.
+ * @dev: device for clock "consumer"
+ * @clks: pointer to the clk_bulk_data table of consumer
+ *
+ * This helper function allows drivers to get all clk consumers in one
+ * operation. If any of the clk cannot be acquired then any clks
+ * that were obtained will be freed before returning to the caller.
+ *
+ * Returns a positive value for the number of clocks obtained while the
+ * clock references are stored in the clk_bulk_data table in @clks field.
+ * Returns 0 if there're none and a negative value if something failed.
+ *
+ * Drivers must assume that the clock source is not enabled.
+ *
+ * clk_bulk_get should not be called from within interrupt context.
+ */
+int __must_check clk_bulk_get_all(struct device *dev,
+                                 struct clk_bulk_data **clks);
 /**
  * devm_clk_bulk_get - managed get multiple clk consumers
  * @dev: device for clock "consumer"
@@ -327,6 +346,22 @@ int __must_check clk_bulk_get(struct device *dev, int num_clks,
  */
 int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
                                   struct clk_bulk_data *clks);
+/**
+ * devm_clk_bulk_get_all - managed get multiple clk consumers
+ * @dev: device for clock "consumer"
+ * @clks: pointer to the clk_bulk_data table of consumer
+ *
+ * Returns a positive value for the number of clocks obtained while the
+ * clock references are stored in the clk_bulk_data table in @clks field.
+ * Returns 0 if there're none and a negative value if something failed.
+ *
+ * This helper function allows drivers to get several clk
+ * consumers in one operation with management, the clks will
+ * automatically be freed when the device is unbound.
+ */
+
+int __must_check devm_clk_bulk_get_all(struct device *dev,
+                                      struct clk_bulk_data **clks);
 
 /**
  * devm_clk_get - lookup and obtain a managed reference to a clock producer.
@@ -487,6 +522,19 @@ void clk_put(struct clk *clk);
  */
 void clk_bulk_put(int num_clks, struct clk_bulk_data *clks);
 
+/**
+ * clk_bulk_put_all - "free" all the clock source
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table of consumer
+ *
+ * Note: drivers must ensure that all clk_bulk_enable calls made on this
+ * clock source are balanced by clk_bulk_disable calls prior to calling
+ * this function.
+ *
+ * clk_bulk_put_all should not be called from within interrupt context.
+ */
+void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks);
+
 /**
  * devm_clk_put        - "free" a managed clock source
  * @dev: device used to acquire the clock
@@ -629,6 +677,23 @@ struct clk *clk_get_parent(struct clk *clk);
  */
 struct clk *clk_get_sys(const char *dev_id, const char *con_id);
 
+/**
+ * clk_save_context - save clock context for poweroff
+ *
+ * Saves the context of the clock register for powerstates in which the
+ * contents of the registers will be lost. Occurs deep within the suspend
+ * code so locking is not necessary.
+ */
+int clk_save_context(void);
+
+/**
+ * clk_restore_context - restore clock context after poweroff
+ *
+ * This occurs with all clocks enabled. Occurs deep within the resume code
+ * so locking is not necessary.
+ */
+void clk_restore_context(void);
+
 #else /* !CONFIG_HAVE_CLK */
 
 static inline struct clk *clk_get(struct device *dev, const char *id)
@@ -642,6 +707,12 @@ static inline int __must_check clk_bulk_get(struct device *dev, int num_clks,
        return 0;
 }
 
+static inline int __must_check clk_bulk_get_all(struct device *dev,
+                                        struct clk_bulk_data **clks)
+{
+       return 0;
+}
+
 static inline struct clk *devm_clk_get(struct device *dev, const char *id)
 {
        return NULL;
@@ -653,6 +724,13 @@ static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clk
        return 0;
 }
 
+static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
+                                                    struct clk_bulk_data **clks)
+{
+
+       return 0;
+}
+
 static inline struct clk *devm_get_clk_from_child(struct device *dev,
                                struct device_node *np, const char *con_id)
 {
@@ -663,6 +741,8 @@ static inline void clk_put(struct clk *clk) {}
 
 static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {}
 
+static inline void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) {}
+
 static inline void devm_clk_put(struct device *dev, struct clk *clk) {}
 
 
@@ -728,6 +808,14 @@ static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 {
        return NULL;
 }
+
+static inline int clk_save_context(void)
+{
+       return 0;
+}
+
+static inline void clk_restore_context(void) {}
+
 #endif
 
 /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
index 9ebf1f8243bb57af54b0d5adc3b22408c858d103..0ebbe2f0b45e785440dcc0f5962d86faf331f1fd 100644 (file)
@@ -1,14 +1,10 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0+
+ *
  * Copyright 2013 Ideas On Board SPRL
  * Copyright 2013, 2014 Horms Solutions Ltd.
  *
  * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  * Contact: Simon Horman <horms@verge.net.au>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #ifndef __LINUX_CLK_RENESAS_H_
index a8faa38b1ed60bd5a7a306abda6b39413e677090..eacc5df57b99fd28cba56081e03f8fa0cccf576b 100644 (file)
@@ -159,6 +159,7 @@ struct clk_hw_omap {
        const char              *clkdm_name;
        struct clockdomain      *clkdm;
        const struct clk_hw_omap_ops    *ops;
+       u32                     context;
 };
 
 /*
@@ -290,9 +291,15 @@ struct ti_clk_features {
 #define TI_CLK_DPLL4_DENY_REPROGRAM            BIT(1)
 #define TI_CLK_DISABLE_CLKDM_CONTROL           BIT(2)
 #define TI_CLK_ERRATA_I810                     BIT(3)
+#define TI_CLK_CLKCTRL_COMPAT                  BIT(4)
 
 void ti_clk_setup_features(struct ti_clk_features *features);
 const struct ti_clk_features *ti_clk_get_features(void);
+int omap3_noncore_dpll_save_context(struct clk_hw *hw);
+void omap3_noncore_dpll_restore_context(struct clk_hw *hw);
+
+int omap3_core_dpll_save_context(struct clk_hw *hw);
+void omap3_core_dpll_restore_context(struct clk_hw *hw);
 
 extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
 
index d30e4dbd4be249cf89eb7273de364f03ff81287a..06e77473f17593dc1fac4ad01af652776735b6ef 100644 (file)
@@ -488,8 +488,11 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
        compat_sigset_t v;
        switch (_NSIG_WORDS) {
        case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
+               /* fall through */
        case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2];
+               /* fall through */
        case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1];
+               /* fall through */
        case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0];
        }
        return copy_to_user(compat, &v, size) ? -EFAULT : 0;
index 096c96f4f16af0f94a54e5e237e3f36fe9883778..a5a60691e48b5a65f5f07f8e11baf6f97a594b5e 100644 (file)
@@ -4,6 +4,61 @@
 
 #include <uapi/linux/fanotify.h>
 
-/* not valid from userspace, only kernel internal */
-#define FAN_MARK_ONDIR         0x00000100
+#define FAN_GROUP_FLAG(group, flag) \
+       ((group)->fanotify_data.flags & (flag))
+
+/*
+ * Flags allowed to be passed from/to userspace.
+ *
+ * We intentionally do not add new bits to the old FAN_ALL_* constants, because
+ * they are uapi exposed constants. If there are programs out there using
+ * these constant, the programs may break if re-compiled with new uapi headers
+ * and then run on an old kernel.
+ */
+#define FANOTIFY_CLASS_BITS    (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
+                                FAN_CLASS_PRE_CONTENT)
+
+#define FANOTIFY_INIT_FLAGS    (FANOTIFY_CLASS_BITS | \
+                                FAN_REPORT_TID | \
+                                FAN_CLOEXEC | FAN_NONBLOCK | \
+                                FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
+
+#define FANOTIFY_MARK_TYPE_BITS        (FAN_MARK_INODE | FAN_MARK_MOUNT | \
+                                FAN_MARK_FILESYSTEM)
+
+#define FANOTIFY_MARK_FLAGS    (FANOTIFY_MARK_TYPE_BITS | \
+                                FAN_MARK_ADD | \
+                                FAN_MARK_REMOVE | \
+                                FAN_MARK_DONT_FOLLOW | \
+                                FAN_MARK_ONLYDIR | \
+                                FAN_MARK_IGNORED_MASK | \
+                                FAN_MARK_IGNORED_SURV_MODIFY | \
+                                FAN_MARK_FLUSH)
+
+/* Events that user can request to be notified on */
+#define FANOTIFY_EVENTS                (FAN_ACCESS | FAN_MODIFY | \
+                                FAN_CLOSE | FAN_OPEN)
+
+/* Events that require a permission response from user */
+#define FANOTIFY_PERM_EVENTS   (FAN_OPEN_PERM | FAN_ACCESS_PERM)
+
+/* Extra flags that may be reported with event or control handling of events */
+#define FANOTIFY_EVENT_FLAGS   (FAN_EVENT_ON_CHILD | FAN_ONDIR)
+
+/* Events that may be reported to user */
+#define FANOTIFY_OUTGOING_EVENTS       (FANOTIFY_EVENTS | \
+                                        FANOTIFY_PERM_EVENTS | \
+                                        FAN_Q_OVERFLOW)
+
+#define ALL_FANOTIFY_EVENT_BITS                (FANOTIFY_OUTGOING_EVENTS | \
+                                        FANOTIFY_EVENT_FLAGS)
+
+/* Do not use these old uapi constants internally */
+#undef FAN_ALL_CLASS_BITS
+#undef FAN_ALL_INIT_FLAGS
+#undef FAN_ALL_MARK_FLAGS
+#undef FAN_ALL_EVENTS
+#undef FAN_ALL_PERM_EVENTS
+#undef FAN_ALL_OUTGOING_EVENTS
+
 #endif /* _LINUX_FANOTIFY_H */
diff --git a/include/linux/firmware/imx/ipc.h b/include/linux/firmware/imx/ipc.h
new file mode 100644 (file)
index 0000000..6312c8c
--- /dev/null
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018 NXP
+ *
+ * Header file for the IPC implementation.
+ */
+
+#ifndef _SC_IPC_H
+#define _SC_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+
+#define IMX_SC_RPC_VERSION     1
+#define IMX_SC_RPC_MAX_MSG     8
+
+struct imx_sc_ipc;
+
+enum imx_sc_rpc_svc {
+       IMX_SC_RPC_SVC_UNKNOWN = 0,
+       IMX_SC_RPC_SVC_RETURN = 1,
+       IMX_SC_RPC_SVC_PM = 2,
+       IMX_SC_RPC_SVC_RM = 3,
+       IMX_SC_RPC_SVC_TIMER = 5,
+       IMX_SC_RPC_SVC_PAD = 6,
+       IMX_SC_RPC_SVC_MISC = 7,
+       IMX_SC_RPC_SVC_IRQ = 8,
+       IMX_SC_RPC_SVC_ABORT = 9
+};
+
+struct imx_sc_rpc_msg {
+       uint8_t ver;
+       uint8_t size;
+       uint8_t svc;
+       uint8_t func;
+};
+
+/*
+ * This is an function to send an RPC message over an IPC channel.
+ * It is called by client-side SCFW API function shims.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in,out] msg         handle to a message
+ * @param[in]     have_resp   response flag
+ *
+ * If have_resp is true then this function waits for a response
+ * and returns the result in msg.
+ */
+int imx_scu_call_rpc(struct imx_sc_ipc *ipc, void *msg, bool have_resp);
+
+/*
+ * This function gets the default ipc handle used by SCU
+ *
+ * @param[out] ipc     sc ipc handle
+ *
+ * @return Returns an error code (0 = success, failed if < 0)
+ */
+int imx_scu_get_handle(struct imx_sc_ipc **ipc);
+#endif /* _SC_IPC_H */
diff --git a/include/linux/firmware/imx/sci.h b/include/linux/firmware/imx/sci.h
new file mode 100644 (file)
index 0000000..29ada60
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *
+ * Header file containing the public System Controller Interface (SCI)
+ * definitions.
+ */
+
+#ifndef _SC_SCI_H
+#define _SC_SCI_H
+
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/types.h>
+
+#include <linux/firmware/imx/svc/misc.h>
+#endif /* _SC_SCI_H */
diff --git a/include/linux/firmware/imx/svc/misc.h b/include/linux/firmware/imx/svc/misc.h
new file mode 100644 (file)
index 0000000..e21c49a
--- /dev/null
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ */
+
+#ifndef _SC_MISC_API_H
+#define _SC_MISC_API_H
+
+#include <linux/firmware/imx/sci.h>
+
+/*
+ * This type is used to indicate RPC MISC function calls.
+ */
+enum imx_misc_func {
+       IMX_SC_MISC_FUNC_UNKNOWN = 0,
+       IMX_SC_MISC_FUNC_SET_CONTROL = 1,
+       IMX_SC_MISC_FUNC_GET_CONTROL = 2,
+       IMX_SC_MISC_FUNC_SET_MAX_DMA_GROUP = 4,
+       IMX_SC_MISC_FUNC_SET_DMA_GROUP = 5,
+       IMX_SC_MISC_FUNC_SECO_IMAGE_LOAD = 8,
+       IMX_SC_MISC_FUNC_SECO_AUTHENTICATE = 9,
+       IMX_SC_MISC_FUNC_DEBUG_OUT = 10,
+       IMX_SC_MISC_FUNC_WAVEFORM_CAPTURE = 6,
+       IMX_SC_MISC_FUNC_BUILD_INFO = 15,
+       IMX_SC_MISC_FUNC_UNIQUE_ID = 19,
+       IMX_SC_MISC_FUNC_SET_ARI = 3,
+       IMX_SC_MISC_FUNC_BOOT_STATUS = 7,
+       IMX_SC_MISC_FUNC_BOOT_DONE = 14,
+       IMX_SC_MISC_FUNC_OTP_FUSE_READ = 11,
+       IMX_SC_MISC_FUNC_OTP_FUSE_WRITE = 17,
+       IMX_SC_MISC_FUNC_SET_TEMP = 12,
+       IMX_SC_MISC_FUNC_GET_TEMP = 13,
+       IMX_SC_MISC_FUNC_GET_BOOT_DEV = 16,
+       IMX_SC_MISC_FUNC_GET_BUTTON_STATUS = 18,
+};
+
+/*
+ * Control Functions
+ */
+
+int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource,
+                           u8 ctrl, u32 val);
+
+int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource,
+                           u8 ctrl, u32 *val);
+
+#endif /* _SC_MISC_API_H */
diff --git a/include/linux/firmware/imx/types.h b/include/linux/firmware/imx/types.h
new file mode 100644 (file)
index 0000000..9cbf0c4
--- /dev/null
@@ -0,0 +1,617 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017~2018 NXP
+ *
+ * Header file containing types used across multiple service APIs.
+ */
+
+#ifndef _SC_TYPES_H
+#define _SC_TYPES_H
+
+/*
+ * This type is used to indicate a resource. Resources include peripherals
+ * and bus masters (but not memory regions). Note items from list should
+ * never be changed or removed (only added to at the end of the list).
+ */
+enum imx_sc_rsrc {
+       IMX_SC_R_A53 = 0,
+       IMX_SC_R_A53_0 = 1,
+       IMX_SC_R_A53_1 = 2,
+       IMX_SC_R_A53_2 = 3,
+       IMX_SC_R_A53_3 = 4,
+       IMX_SC_R_A72 = 5,
+       IMX_SC_R_A72_0 = 6,
+       IMX_SC_R_A72_1 = 7,
+       IMX_SC_R_A72_2 = 8,
+       IMX_SC_R_A72_3 = 9,
+       IMX_SC_R_CCI = 10,
+       IMX_SC_R_DB = 11,
+       IMX_SC_R_DRC_0 = 12,
+       IMX_SC_R_DRC_1 = 13,
+       IMX_SC_R_GIC_SMMU = 14,
+       IMX_SC_R_IRQSTR_M4_0 = 15,
+       IMX_SC_R_IRQSTR_M4_1 = 16,
+       IMX_SC_R_SMMU = 17,
+       IMX_SC_R_GIC = 18,
+       IMX_SC_R_DC_0_BLIT0 = 19,
+       IMX_SC_R_DC_0_BLIT1 = 20,
+       IMX_SC_R_DC_0_BLIT2 = 21,
+       IMX_SC_R_DC_0_BLIT_OUT = 22,
+       IMX_SC_R_DC_0_CAPTURE0 = 23,
+       IMX_SC_R_DC_0_CAPTURE1 = 24,
+       IMX_SC_R_DC_0_WARP = 25,
+       IMX_SC_R_DC_0_INTEGRAL0 = 26,
+       IMX_SC_R_DC_0_INTEGRAL1 = 27,
+       IMX_SC_R_DC_0_VIDEO0 = 28,
+       IMX_SC_R_DC_0_VIDEO1 = 29,
+       IMX_SC_R_DC_0_FRAC0 = 30,
+       IMX_SC_R_DC_0_FRAC1 = 31,
+       IMX_SC_R_DC_0 = 32,
+       IMX_SC_R_GPU_2_PID0 = 33,
+       IMX_SC_R_DC_0_PLL_0 = 34,
+       IMX_SC_R_DC_0_PLL_1 = 35,
+       IMX_SC_R_DC_1_BLIT0 = 36,
+       IMX_SC_R_DC_1_BLIT1 = 37,
+       IMX_SC_R_DC_1_BLIT2 = 38,
+       IMX_SC_R_DC_1_BLIT_OUT = 39,
+       IMX_SC_R_DC_1_CAPTURE0 = 40,
+       IMX_SC_R_DC_1_CAPTURE1 = 41,
+       IMX_SC_R_DC_1_WARP = 42,
+       IMX_SC_R_DC_1_INTEGRAL0 = 43,
+       IMX_SC_R_DC_1_INTEGRAL1 = 44,
+       IMX_SC_R_DC_1_VIDEO0 = 45,
+       IMX_SC_R_DC_1_VIDEO1 = 46,
+       IMX_SC_R_DC_1_FRAC0 = 47,
+       IMX_SC_R_DC_1_FRAC1 = 48,
+       IMX_SC_R_DC_1 = 49,
+       IMX_SC_R_GPU_3_PID0 = 50,
+       IMX_SC_R_DC_1_PLL_0 = 51,
+       IMX_SC_R_DC_1_PLL_1 = 52,
+       IMX_SC_R_SPI_0 = 53,
+       IMX_SC_R_SPI_1 = 54,
+       IMX_SC_R_SPI_2 = 55,
+       IMX_SC_R_SPI_3 = 56,
+       IMX_SC_R_UART_0 = 57,
+       IMX_SC_R_UART_1 = 58,
+       IMX_SC_R_UART_2 = 59,
+       IMX_SC_R_UART_3 = 60,
+       IMX_SC_R_UART_4 = 61,
+       IMX_SC_R_EMVSIM_0 = 62,
+       IMX_SC_R_EMVSIM_1 = 63,
+       IMX_SC_R_DMA_0_CH0 = 64,
+       IMX_SC_R_DMA_0_CH1 = 65,
+       IMX_SC_R_DMA_0_CH2 = 66,
+       IMX_SC_R_DMA_0_CH3 = 67,
+       IMX_SC_R_DMA_0_CH4 = 68,
+       IMX_SC_R_DMA_0_CH5 = 69,
+       IMX_SC_R_DMA_0_CH6 = 70,
+       IMX_SC_R_DMA_0_CH7 = 71,
+       IMX_SC_R_DMA_0_CH8 = 72,
+       IMX_SC_R_DMA_0_CH9 = 73,
+       IMX_SC_R_DMA_0_CH10 = 74,
+       IMX_SC_R_DMA_0_CH11 = 75,
+       IMX_SC_R_DMA_0_CH12 = 76,
+       IMX_SC_R_DMA_0_CH13 = 77,
+       IMX_SC_R_DMA_0_CH14 = 78,
+       IMX_SC_R_DMA_0_CH15 = 79,
+       IMX_SC_R_DMA_0_CH16 = 80,
+       IMX_SC_R_DMA_0_CH17 = 81,
+       IMX_SC_R_DMA_0_CH18 = 82,
+       IMX_SC_R_DMA_0_CH19 = 83,
+       IMX_SC_R_DMA_0_CH20 = 84,
+       IMX_SC_R_DMA_0_CH21 = 85,
+       IMX_SC_R_DMA_0_CH22 = 86,
+       IMX_SC_R_DMA_0_CH23 = 87,
+       IMX_SC_R_DMA_0_CH24 = 88,
+       IMX_SC_R_DMA_0_CH25 = 89,
+       IMX_SC_R_DMA_0_CH26 = 90,
+       IMX_SC_R_DMA_0_CH27 = 91,
+       IMX_SC_R_DMA_0_CH28 = 92,
+       IMX_SC_R_DMA_0_CH29 = 93,
+       IMX_SC_R_DMA_0_CH30 = 94,
+       IMX_SC_R_DMA_0_CH31 = 95,
+       IMX_SC_R_I2C_0 = 96,
+       IMX_SC_R_I2C_1 = 97,
+       IMX_SC_R_I2C_2 = 98,
+       IMX_SC_R_I2C_3 = 99,
+       IMX_SC_R_I2C_4 = 100,
+       IMX_SC_R_ADC_0 = 101,
+       IMX_SC_R_ADC_1 = 102,
+       IMX_SC_R_FTM_0 = 103,
+       IMX_SC_R_FTM_1 = 104,
+       IMX_SC_R_CAN_0 = 105,
+       IMX_SC_R_CAN_1 = 106,
+       IMX_SC_R_CAN_2 = 107,
+       IMX_SC_R_DMA_1_CH0 = 108,
+       IMX_SC_R_DMA_1_CH1 = 109,
+       IMX_SC_R_DMA_1_CH2 = 110,
+       IMX_SC_R_DMA_1_CH3 = 111,
+       IMX_SC_R_DMA_1_CH4 = 112,
+       IMX_SC_R_DMA_1_CH5 = 113,
+       IMX_SC_R_DMA_1_CH6 = 114,
+       IMX_SC_R_DMA_1_CH7 = 115,
+       IMX_SC_R_DMA_1_CH8 = 116,
+       IMX_SC_R_DMA_1_CH9 = 117,
+       IMX_SC_R_DMA_1_CH10 = 118,
+       IMX_SC_R_DMA_1_CH11 = 119,
+       IMX_SC_R_DMA_1_CH12 = 120,
+       IMX_SC_R_DMA_1_CH13 = 121,
+       IMX_SC_R_DMA_1_CH14 = 122,
+       IMX_SC_R_DMA_1_CH15 = 123,
+       IMX_SC_R_DMA_1_CH16 = 124,
+       IMX_SC_R_DMA_1_CH17 = 125,
+       IMX_SC_R_DMA_1_CH18 = 126,
+       IMX_SC_R_DMA_1_CH19 = 127,
+       IMX_SC_R_DMA_1_CH20 = 128,
+       IMX_SC_R_DMA_1_CH21 = 129,
+       IMX_SC_R_DMA_1_CH22 = 130,
+       IMX_SC_R_DMA_1_CH23 = 131,
+       IMX_SC_R_DMA_1_CH24 = 132,
+       IMX_SC_R_DMA_1_CH25 = 133,
+       IMX_SC_R_DMA_1_CH26 = 134,
+       IMX_SC_R_DMA_1_CH27 = 135,
+       IMX_SC_R_DMA_1_CH28 = 136,
+       IMX_SC_R_DMA_1_CH29 = 137,
+       IMX_SC_R_DMA_1_CH30 = 138,
+       IMX_SC_R_DMA_1_CH31 = 139,
+       IMX_SC_R_UNUSED1 = 140,
+       IMX_SC_R_UNUSED2 = 141,
+       IMX_SC_R_UNUSED3 = 142,
+       IMX_SC_R_UNUSED4 = 143,
+       IMX_SC_R_GPU_0_PID0 = 144,
+       IMX_SC_R_GPU_0_PID1 = 145,
+       IMX_SC_R_GPU_0_PID2 = 146,
+       IMX_SC_R_GPU_0_PID3 = 147,
+       IMX_SC_R_GPU_1_PID0 = 148,
+       IMX_SC_R_GPU_1_PID1 = 149,
+       IMX_SC_R_GPU_1_PID2 = 150,
+       IMX_SC_R_GPU_1_PID3 = 151,
+       IMX_SC_R_PCIE_A = 152,
+       IMX_SC_R_SERDES_0 = 153,
+       IMX_SC_R_MATCH_0 = 154,
+       IMX_SC_R_MATCH_1 = 155,
+       IMX_SC_R_MATCH_2 = 156,
+       IMX_SC_R_MATCH_3 = 157,
+       IMX_SC_R_MATCH_4 = 158,
+       IMX_SC_R_MATCH_5 = 159,
+       IMX_SC_R_MATCH_6 = 160,
+       IMX_SC_R_MATCH_7 = 161,
+       IMX_SC_R_MATCH_8 = 162,
+       IMX_SC_R_MATCH_9 = 163,
+       IMX_SC_R_MATCH_10 = 164,
+       IMX_SC_R_MATCH_11 = 165,
+       IMX_SC_R_MATCH_12 = 166,
+       IMX_SC_R_MATCH_13 = 167,
+       IMX_SC_R_MATCH_14 = 168,
+       IMX_SC_R_PCIE_B = 169,
+       IMX_SC_R_SATA_0 = 170,
+       IMX_SC_R_SERDES_1 = 171,
+       IMX_SC_R_HSIO_GPIO = 172,
+       IMX_SC_R_MATCH_15 = 173,
+       IMX_SC_R_MATCH_16 = 174,
+       IMX_SC_R_MATCH_17 = 175,
+       IMX_SC_R_MATCH_18 = 176,
+       IMX_SC_R_MATCH_19 = 177,
+       IMX_SC_R_MATCH_20 = 178,
+       IMX_SC_R_MATCH_21 = 179,
+       IMX_SC_R_MATCH_22 = 180,
+       IMX_SC_R_MATCH_23 = 181,
+       IMX_SC_R_MATCH_24 = 182,
+       IMX_SC_R_MATCH_25 = 183,
+       IMX_SC_R_MATCH_26 = 184,
+       IMX_SC_R_MATCH_27 = 185,
+       IMX_SC_R_MATCH_28 = 186,
+       IMX_SC_R_LCD_0 = 187,
+       IMX_SC_R_LCD_0_PWM_0 = 188,
+       IMX_SC_R_LCD_0_I2C_0 = 189,
+       IMX_SC_R_LCD_0_I2C_1 = 190,
+       IMX_SC_R_PWM_0 = 191,
+       IMX_SC_R_PWM_1 = 192,
+       IMX_SC_R_PWM_2 = 193,
+       IMX_SC_R_PWM_3 = 194,
+       IMX_SC_R_PWM_4 = 195,
+       IMX_SC_R_PWM_5 = 196,
+       IMX_SC_R_PWM_6 = 197,
+       IMX_SC_R_PWM_7 = 198,
+       IMX_SC_R_GPIO_0 = 199,
+       IMX_SC_R_GPIO_1 = 200,
+       IMX_SC_R_GPIO_2 = 201,
+       IMX_SC_R_GPIO_3 = 202,
+       IMX_SC_R_GPIO_4 = 203,
+       IMX_SC_R_GPIO_5 = 204,
+       IMX_SC_R_GPIO_6 = 205,
+       IMX_SC_R_GPIO_7 = 206,
+       IMX_SC_R_GPT_0 = 207,
+       IMX_SC_R_GPT_1 = 208,
+       IMX_SC_R_GPT_2 = 209,
+       IMX_SC_R_GPT_3 = 210,
+       IMX_SC_R_GPT_4 = 211,
+       IMX_SC_R_KPP = 212,
+       IMX_SC_R_MU_0A = 213,
+       IMX_SC_R_MU_1A = 214,
+       IMX_SC_R_MU_2A = 215,
+       IMX_SC_R_MU_3A = 216,
+       IMX_SC_R_MU_4A = 217,
+       IMX_SC_R_MU_5A = 218,
+       IMX_SC_R_MU_6A = 219,
+       IMX_SC_R_MU_7A = 220,
+       IMX_SC_R_MU_8A = 221,
+       IMX_SC_R_MU_9A = 222,
+       IMX_SC_R_MU_10A = 223,
+       IMX_SC_R_MU_11A = 224,
+       IMX_SC_R_MU_12A = 225,
+       IMX_SC_R_MU_13A = 226,
+       IMX_SC_R_MU_5B = 227,
+       IMX_SC_R_MU_6B = 228,
+       IMX_SC_R_MU_7B = 229,
+       IMX_SC_R_MU_8B = 230,
+       IMX_SC_R_MU_9B = 231,
+       IMX_SC_R_MU_10B = 232,
+       IMX_SC_R_MU_11B = 233,
+       IMX_SC_R_MU_12B = 234,
+       IMX_SC_R_MU_13B = 235,
+       IMX_SC_R_ROM_0 = 236,
+       IMX_SC_R_FSPI_0 = 237,
+       IMX_SC_R_FSPI_1 = 238,
+       IMX_SC_R_IEE = 239,
+       IMX_SC_R_IEE_R0 = 240,
+       IMX_SC_R_IEE_R1 = 241,
+       IMX_SC_R_IEE_R2 = 242,
+       IMX_SC_R_IEE_R3 = 243,
+       IMX_SC_R_IEE_R4 = 244,
+       IMX_SC_R_IEE_R5 = 245,
+       IMX_SC_R_IEE_R6 = 246,
+       IMX_SC_R_IEE_R7 = 247,
+       IMX_SC_R_SDHC_0 = 248,
+       IMX_SC_R_SDHC_1 = 249,
+       IMX_SC_R_SDHC_2 = 250,
+       IMX_SC_R_ENET_0 = 251,
+       IMX_SC_R_ENET_1 = 252,
+       IMX_SC_R_MLB_0 = 253,
+       IMX_SC_R_DMA_2_CH0 = 254,
+       IMX_SC_R_DMA_2_CH1 = 255,
+       IMX_SC_R_DMA_2_CH2 = 256,
+       IMX_SC_R_DMA_2_CH3 = 257,
+       IMX_SC_R_DMA_2_CH4 = 258,
+       IMX_SC_R_USB_0 = 259,
+       IMX_SC_R_USB_1 = 260,
+       IMX_SC_R_USB_0_PHY = 261,
+       IMX_SC_R_USB_2 = 262,
+       IMX_SC_R_USB_2_PHY = 263,
+       IMX_SC_R_DTCP = 264,
+       IMX_SC_R_NAND = 265,
+       IMX_SC_R_LVDS_0 = 266,
+       IMX_SC_R_LVDS_0_PWM_0 = 267,
+       IMX_SC_R_LVDS_0_I2C_0 = 268,
+       IMX_SC_R_LVDS_0_I2C_1 = 269,
+       IMX_SC_R_LVDS_1 = 270,
+       IMX_SC_R_LVDS_1_PWM_0 = 271,
+       IMX_SC_R_LVDS_1_I2C_0 = 272,
+       IMX_SC_R_LVDS_1_I2C_1 = 273,
+       IMX_SC_R_LVDS_2 = 274,
+       IMX_SC_R_LVDS_2_PWM_0 = 275,
+       IMX_SC_R_LVDS_2_I2C_0 = 276,
+       IMX_SC_R_LVDS_2_I2C_1 = 277,
+       IMX_SC_R_M4_0_PID0 = 278,
+       IMX_SC_R_M4_0_PID1 = 279,
+       IMX_SC_R_M4_0_PID2 = 280,
+       IMX_SC_R_M4_0_PID3 = 281,
+       IMX_SC_R_M4_0_PID4 = 282,
+       IMX_SC_R_M4_0_RGPIO = 283,
+       IMX_SC_R_M4_0_SEMA42 = 284,
+       IMX_SC_R_M4_0_TPM = 285,
+       IMX_SC_R_M4_0_PIT = 286,
+       IMX_SC_R_M4_0_UART = 287,
+       IMX_SC_R_M4_0_I2C = 288,
+       IMX_SC_R_M4_0_INTMUX = 289,
+       IMX_SC_R_M4_0_SIM = 290,
+       IMX_SC_R_M4_0_WDOG = 291,
+       IMX_SC_R_M4_0_MU_0B = 292,
+       IMX_SC_R_M4_0_MU_0A0 = 293,
+       IMX_SC_R_M4_0_MU_0A1 = 294,
+       IMX_SC_R_M4_0_MU_0A2 = 295,
+       IMX_SC_R_M4_0_MU_0A3 = 296,
+       IMX_SC_R_M4_0_MU_1A = 297,
+       IMX_SC_R_M4_1_PID0 = 298,
+       IMX_SC_R_M4_1_PID1 = 299,
+       IMX_SC_R_M4_1_PID2 = 300,
+       IMX_SC_R_M4_1_PID3 = 301,
+       IMX_SC_R_M4_1_PID4 = 302,
+       IMX_SC_R_M4_1_RGPIO = 303,
+       IMX_SC_R_M4_1_SEMA42 = 304,
+       IMX_SC_R_M4_1_TPM = 305,
+       IMX_SC_R_M4_1_PIT = 306,
+       IMX_SC_R_M4_1_UART = 307,
+       IMX_SC_R_M4_1_I2C = 308,
+       IMX_SC_R_M4_1_INTMUX = 309,
+       IMX_SC_R_M4_1_SIM = 310,
+       IMX_SC_R_M4_1_WDOG = 311,
+       IMX_SC_R_M4_1_MU_0B = 312,
+       IMX_SC_R_M4_1_MU_0A0 = 313,
+       IMX_SC_R_M4_1_MU_0A1 = 314,
+       IMX_SC_R_M4_1_MU_0A2 = 315,
+       IMX_SC_R_M4_1_MU_0A3 = 316,
+       IMX_SC_R_M4_1_MU_1A = 317,
+       IMX_SC_R_SAI_0 = 318,
+       IMX_SC_R_SAI_1 = 319,
+       IMX_SC_R_SAI_2 = 320,
+       IMX_SC_R_IRQSTR_SCU2 = 321,
+       IMX_SC_R_IRQSTR_DSP = 322,
+       IMX_SC_R_UNUSED5 = 323,
+       IMX_SC_R_UNUSED6 = 324,
+       IMX_SC_R_AUDIO_PLL_0 = 325,
+       IMX_SC_R_PI_0 = 326,
+       IMX_SC_R_PI_0_PWM_0 = 327,
+       IMX_SC_R_PI_0_PWM_1 = 328,
+       IMX_SC_R_PI_0_I2C_0 = 329,
+       IMX_SC_R_PI_0_PLL = 330,
+       IMX_SC_R_PI_1 = 331,
+       IMX_SC_R_PI_1_PWM_0 = 332,
+       IMX_SC_R_PI_1_PWM_1 = 333,
+       IMX_SC_R_PI_1_I2C_0 = 334,
+       IMX_SC_R_PI_1_PLL = 335,
+       IMX_SC_R_SC_PID0 = 336,
+       IMX_SC_R_SC_PID1 = 337,
+       IMX_SC_R_SC_PID2 = 338,
+       IMX_SC_R_SC_PID3 = 339,
+       IMX_SC_R_SC_PID4 = 340,
+       IMX_SC_R_SC_SEMA42 = 341,
+       IMX_SC_R_SC_TPM = 342,
+       IMX_SC_R_SC_PIT = 343,
+       IMX_SC_R_SC_UART = 344,
+       IMX_SC_R_SC_I2C = 345,
+       IMX_SC_R_SC_MU_0B = 346,
+       IMX_SC_R_SC_MU_0A0 = 347,
+       IMX_SC_R_SC_MU_0A1 = 348,
+       IMX_SC_R_SC_MU_0A2 = 349,
+       IMX_SC_R_SC_MU_0A3 = 350,
+       IMX_SC_R_SC_MU_1A = 351,
+       IMX_SC_R_SYSCNT_RD = 352,
+       IMX_SC_R_SYSCNT_CMP = 353,
+       IMX_SC_R_DEBUG = 354,
+       IMX_SC_R_SYSTEM = 355,
+       IMX_SC_R_SNVS = 356,
+       IMX_SC_R_OTP = 357,
+       IMX_SC_R_VPU_PID0 = 358,
+       IMX_SC_R_VPU_PID1 = 359,
+       IMX_SC_R_VPU_PID2 = 360,
+       IMX_SC_R_VPU_PID3 = 361,
+       IMX_SC_R_VPU_PID4 = 362,
+       IMX_SC_R_VPU_PID5 = 363,
+       IMX_SC_R_VPU_PID6 = 364,
+       IMX_SC_R_VPU_PID7 = 365,
+       IMX_SC_R_VPU_UART = 366,
+       IMX_SC_R_VPUCORE = 367,
+       IMX_SC_R_VPUCORE_0 = 368,
+       IMX_SC_R_VPUCORE_1 = 369,
+       IMX_SC_R_VPUCORE_2 = 370,
+       IMX_SC_R_VPUCORE_3 = 371,
+       IMX_SC_R_DMA_4_CH0 = 372,
+       IMX_SC_R_DMA_4_CH1 = 373,
+       IMX_SC_R_DMA_4_CH2 = 374,
+       IMX_SC_R_DMA_4_CH3 = 375,
+       IMX_SC_R_DMA_4_CH4 = 376,
+       IMX_SC_R_ISI_CH0 = 377,
+       IMX_SC_R_ISI_CH1 = 378,
+       IMX_SC_R_ISI_CH2 = 379,
+       IMX_SC_R_ISI_CH3 = 380,
+       IMX_SC_R_ISI_CH4 = 381,
+       IMX_SC_R_ISI_CH5 = 382,
+       IMX_SC_R_ISI_CH6 = 383,
+       IMX_SC_R_ISI_CH7 = 384,
+       IMX_SC_R_MJPEG_DEC_S0 = 385,
+       IMX_SC_R_MJPEG_DEC_S1 = 386,
+       IMX_SC_R_MJPEG_DEC_S2 = 387,
+       IMX_SC_R_MJPEG_DEC_S3 = 388,
+       IMX_SC_R_MJPEG_ENC_S0 = 389,
+       IMX_SC_R_MJPEG_ENC_S1 = 390,
+       IMX_SC_R_MJPEG_ENC_S2 = 391,
+       IMX_SC_R_MJPEG_ENC_S3 = 392,
+       IMX_SC_R_MIPI_0 = 393,
+       IMX_SC_R_MIPI_0_PWM_0 = 394,
+       IMX_SC_R_MIPI_0_I2C_0 = 395,
+       IMX_SC_R_MIPI_0_I2C_1 = 396,
+       IMX_SC_R_MIPI_1 = 397,
+       IMX_SC_R_MIPI_1_PWM_0 = 398,
+       IMX_SC_R_MIPI_1_I2C_0 = 399,
+       IMX_SC_R_MIPI_1_I2C_1 = 400,
+       IMX_SC_R_CSI_0 = 401,
+       IMX_SC_R_CSI_0_PWM_0 = 402,
+       IMX_SC_R_CSI_0_I2C_0 = 403,
+       IMX_SC_R_CSI_1 = 404,
+       IMX_SC_R_CSI_1_PWM_0 = 405,
+       IMX_SC_R_CSI_1_I2C_0 = 406,
+       IMX_SC_R_HDMI = 407,
+       IMX_SC_R_HDMI_I2S = 408,
+       IMX_SC_R_HDMI_I2C_0 = 409,
+       IMX_SC_R_HDMI_PLL_0 = 410,
+       IMX_SC_R_HDMI_RX = 411,
+       IMX_SC_R_HDMI_RX_BYPASS = 412,
+       IMX_SC_R_HDMI_RX_I2C_0 = 413,
+       IMX_SC_R_ASRC_0 = 414,
+       IMX_SC_R_ESAI_0 = 415,
+       IMX_SC_R_SPDIF_0 = 416,
+       IMX_SC_R_SPDIF_1 = 417,
+       IMX_SC_R_SAI_3 = 418,
+       IMX_SC_R_SAI_4 = 419,
+       IMX_SC_R_SAI_5 = 420,
+       IMX_SC_R_GPT_5 = 421,
+       IMX_SC_R_GPT_6 = 422,
+       IMX_SC_R_GPT_7 = 423,
+       IMX_SC_R_GPT_8 = 424,
+       IMX_SC_R_GPT_9 = 425,
+       IMX_SC_R_GPT_10 = 426,
+       IMX_SC_R_DMA_2_CH5 = 427,
+       IMX_SC_R_DMA_2_CH6 = 428,
+       IMX_SC_R_DMA_2_CH7 = 429,
+       IMX_SC_R_DMA_2_CH8 = 430,
+       IMX_SC_R_DMA_2_CH9 = 431,
+       IMX_SC_R_DMA_2_CH10 = 432,
+       IMX_SC_R_DMA_2_CH11 = 433,
+       IMX_SC_R_DMA_2_CH12 = 434,
+       IMX_SC_R_DMA_2_CH13 = 435,
+       IMX_SC_R_DMA_2_CH14 = 436,
+       IMX_SC_R_DMA_2_CH15 = 437,
+       IMX_SC_R_DMA_2_CH16 = 438,
+       IMX_SC_R_DMA_2_CH17 = 439,
+       IMX_SC_R_DMA_2_CH18 = 440,
+       IMX_SC_R_DMA_2_CH19 = 441,
+       IMX_SC_R_DMA_2_CH20 = 442,
+       IMX_SC_R_DMA_2_CH21 = 443,
+       IMX_SC_R_DMA_2_CH22 = 444,
+       IMX_SC_R_DMA_2_CH23 = 445,
+       IMX_SC_R_DMA_2_CH24 = 446,
+       IMX_SC_R_DMA_2_CH25 = 447,
+       IMX_SC_R_DMA_2_CH26 = 448,
+       IMX_SC_R_DMA_2_CH27 = 449,
+       IMX_SC_R_DMA_2_CH28 = 450,
+       IMX_SC_R_DMA_2_CH29 = 451,
+       IMX_SC_R_DMA_2_CH30 = 452,
+       IMX_SC_R_DMA_2_CH31 = 453,
+       IMX_SC_R_ASRC_1 = 454,
+       IMX_SC_R_ESAI_1 = 455,
+       IMX_SC_R_SAI_6 = 456,
+       IMX_SC_R_SAI_7 = 457,
+       IMX_SC_R_AMIX = 458,
+       IMX_SC_R_MQS_0 = 459,
+       IMX_SC_R_DMA_3_CH0 = 460,
+       IMX_SC_R_DMA_3_CH1 = 461,
+       IMX_SC_R_DMA_3_CH2 = 462,
+       IMX_SC_R_DMA_3_CH3 = 463,
+       IMX_SC_R_DMA_3_CH4 = 464,
+       IMX_SC_R_DMA_3_CH5 = 465,
+       IMX_SC_R_DMA_3_CH6 = 466,
+       IMX_SC_R_DMA_3_CH7 = 467,
+       IMX_SC_R_DMA_3_CH8 = 468,
+       IMX_SC_R_DMA_3_CH9 = 469,
+       IMX_SC_R_DMA_3_CH10 = 470,
+       IMX_SC_R_DMA_3_CH11 = 471,
+       IMX_SC_R_DMA_3_CH12 = 472,
+       IMX_SC_R_DMA_3_CH13 = 473,
+       IMX_SC_R_DMA_3_CH14 = 474,
+       IMX_SC_R_DMA_3_CH15 = 475,
+       IMX_SC_R_DMA_3_CH16 = 476,
+       IMX_SC_R_DMA_3_CH17 = 477,
+       IMX_SC_R_DMA_3_CH18 = 478,
+       IMX_SC_R_DMA_3_CH19 = 479,
+       IMX_SC_R_DMA_3_CH20 = 480,
+       IMX_SC_R_DMA_3_CH21 = 481,
+       IMX_SC_R_DMA_3_CH22 = 482,
+       IMX_SC_R_DMA_3_CH23 = 483,
+       IMX_SC_R_DMA_3_CH24 = 484,
+       IMX_SC_R_DMA_3_CH25 = 485,
+       IMX_SC_R_DMA_3_CH26 = 486,
+       IMX_SC_R_DMA_3_CH27 = 487,
+       IMX_SC_R_DMA_3_CH28 = 488,
+       IMX_SC_R_DMA_3_CH29 = 489,
+       IMX_SC_R_DMA_3_CH30 = 490,
+       IMX_SC_R_DMA_3_CH31 = 491,
+       IMX_SC_R_AUDIO_PLL_1 = 492,
+       IMX_SC_R_AUDIO_CLK_0 = 493,
+       IMX_SC_R_AUDIO_CLK_1 = 494,
+       IMX_SC_R_MCLK_OUT_0 = 495,
+       IMX_SC_R_MCLK_OUT_1 = 496,
+       IMX_SC_R_PMIC_0 = 497,
+       IMX_SC_R_PMIC_1 = 498,
+       IMX_SC_R_SECO = 499,
+       IMX_SC_R_CAAM_JR1 = 500,
+       IMX_SC_R_CAAM_JR2 = 501,
+       IMX_SC_R_CAAM_JR3 = 502,
+       IMX_SC_R_SECO_MU_2 = 503,
+       IMX_SC_R_SECO_MU_3 = 504,
+       IMX_SC_R_SECO_MU_4 = 505,
+       IMX_SC_R_HDMI_RX_PWM_0 = 506,
+       IMX_SC_R_A35 = 507,
+       IMX_SC_R_A35_0 = 508,
+       IMX_SC_R_A35_1 = 509,
+       IMX_SC_R_A35_2 = 510,
+       IMX_SC_R_A35_3 = 511,
+       IMX_SC_R_DSP = 512,
+       IMX_SC_R_DSP_RAM = 513,
+       IMX_SC_R_CAAM_JR1_OUT = 514,
+       IMX_SC_R_CAAM_JR2_OUT = 515,
+       IMX_SC_R_CAAM_JR3_OUT = 516,
+       IMX_SC_R_VPU_DEC_0 = 517,
+       IMX_SC_R_VPU_ENC_0 = 518,
+       IMX_SC_R_CAAM_JR0 = 519,
+       IMX_SC_R_CAAM_JR0_OUT = 520,
+       IMX_SC_R_PMIC_2 = 521,
+       IMX_SC_R_DBLOGIC = 522,
+       IMX_SC_R_HDMI_PLL_1 = 523,
+       IMX_SC_R_BOARD_R0 = 524,
+       IMX_SC_R_BOARD_R1 = 525,
+       IMX_SC_R_BOARD_R2 = 526,
+       IMX_SC_R_BOARD_R3 = 527,
+       IMX_SC_R_BOARD_R4 = 528,
+       IMX_SC_R_BOARD_R5 = 529,
+       IMX_SC_R_BOARD_R6 = 530,
+       IMX_SC_R_BOARD_R7 = 531,
+       IMX_SC_R_MJPEG_DEC_MP = 532,
+       IMX_SC_R_MJPEG_ENC_MP = 533,
+       IMX_SC_R_VPU_TS_0 = 534,
+       IMX_SC_R_VPU_MU_0 = 535,
+       IMX_SC_R_VPU_MU_1 = 536,
+       IMX_SC_R_VPU_MU_2 = 537,
+       IMX_SC_R_VPU_MU_3 = 538,
+       IMX_SC_R_VPU_ENC_1 = 539,
+       IMX_SC_R_VPU = 540,
+       IMX_SC_R_LAST
+};
+
+/* NOTE - please add by replacing some of the UNUSED from above! */
+
+/*
+ * This type is used to indicate a control.
+ */
+enum imx_sc_ctrl {
+       IMX_SC_C_TEMP = 0,
+       IMX_SC_C_TEMP_HI = 1,
+       IMX_SC_C_TEMP_LOW = 2,
+       IMX_SC_C_PXL_LINK_MST1_ADDR = 3,
+       IMX_SC_C_PXL_LINK_MST2_ADDR = 4,
+       IMX_SC_C_PXL_LINK_MST_ENB = 5,
+       IMX_SC_C_PXL_LINK_MST1_ENB = 6,
+       IMX_SC_C_PXL_LINK_MST2_ENB = 7,
+       IMX_SC_C_PXL_LINK_SLV1_ADDR = 8,
+       IMX_SC_C_PXL_LINK_SLV2_ADDR = 9,
+       IMX_SC_C_PXL_LINK_MST_VLD = 10,
+       IMX_SC_C_PXL_LINK_MST1_VLD = 11,
+       IMX_SC_C_PXL_LINK_MST2_VLD = 12,
+       IMX_SC_C_SINGLE_MODE = 13,
+       IMX_SC_C_ID = 14,
+       IMX_SC_C_PXL_CLK_POLARITY = 15,
+       IMX_SC_C_LINESTATE = 16,
+       IMX_SC_C_PCIE_G_RST = 17,
+       IMX_SC_C_PCIE_BUTTON_RST = 18,
+       IMX_SC_C_PCIE_PERST = 19,
+       IMX_SC_C_PHY_RESET = 20,
+       IMX_SC_C_PXL_LINK_RATE_CORRECTION = 21,
+       IMX_SC_C_PANIC = 22,
+       IMX_SC_C_PRIORITY_GROUP = 23,
+       IMX_SC_C_TXCLK = 24,
+       IMX_SC_C_CLKDIV = 25,
+       IMX_SC_C_DISABLE_50 = 26,
+       IMX_SC_C_DISABLE_125 = 27,
+       IMX_SC_C_SEL_125 = 28,
+       IMX_SC_C_MODE = 29,
+       IMX_SC_C_SYNC_CTRL0 = 30,
+       IMX_SC_C_KACHUNK_CNT = 31,
+       IMX_SC_C_KACHUNK_SEL = 32,
+       IMX_SC_C_SYNC_CTRL1 = 33,
+       IMX_SC_C_DPI_RESET = 34,
+       IMX_SC_C_MIPI_RESET = 35,
+       IMX_SC_C_DUAL_MODE = 36,
+       IMX_SC_C_VOLTAGE = 37,
+       IMX_SC_C_PXL_LINK_SEL = 38,
+       IMX_SC_C_OFS_SEL = 39,
+       IMX_SC_C_OFS_AUDIO = 40,
+       IMX_SC_C_OFS_PERIPH = 41,
+       IMX_SC_C_OFS_IRQ = 42,
+       IMX_SC_C_RST0 = 43,
+       IMX_SC_C_RST1 = 44,
+       IMX_SC_C_SEL0 = 45,
+       IMX_SC_C_LAST
+};
+
+#endif /* _SC_TYPES_H */
index 37a5eaea69dde299a18855ffc99b1227513b25da..f98c20dd266ed4da026b598257728da3d067a2f0 100644 (file)
@@ -17,6 +17,7 @@ enum {
        SM_EFUSE_READ,
        SM_EFUSE_WRITE,
        SM_EFUSE_USER_MAX,
+       SM_GET_CHIP_ID,
 };
 
 struct meson_sm_firmware;
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
new file mode 100644 (file)
index 0000000..3c3c28e
--- /dev/null
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Xilinx Zynq MPSoC Firmware layer
+ *
+ *  Copyright (C) 2014-2018 Xilinx
+ *
+ *  Michal Simek <michal.simek@xilinx.com>
+ *  Davorin Mista <davorin.mista@aggios.com>
+ *  Jolly Shah <jollys@xilinx.com>
+ *  Rajan Vaja <rajanv@xilinx.com>
+ */
+
+#ifndef __FIRMWARE_ZYNQMP_H__
+#define __FIRMWARE_ZYNQMP_H__
+
+#define ZYNQMP_PM_VERSION_MAJOR        1
+#define ZYNQMP_PM_VERSION_MINOR        0
+
+#define ZYNQMP_PM_VERSION      ((ZYNQMP_PM_VERSION_MAJOR << 16) | \
+                                       ZYNQMP_PM_VERSION_MINOR)
+
+#define ZYNQMP_TZ_VERSION_MAJOR        1
+#define ZYNQMP_TZ_VERSION_MINOR        0
+
+#define ZYNQMP_TZ_VERSION      ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
+                                       ZYNQMP_TZ_VERSION_MINOR)
+
+/* SMC SIP service Call Function Identifier Prefix */
+#define PM_SIP_SVC                     0xC2000000
+#define PM_GET_TRUSTZONE_VERSION       0xa03
+
+/* Number of 32bits values in payload */
+#define PAYLOAD_ARG_CNT        4U
+
+enum pm_api_id {
+       PM_GET_API_VERSION = 1,
+       PM_IOCTL = 34,
+       PM_QUERY_DATA,
+       PM_CLOCK_ENABLE,
+       PM_CLOCK_DISABLE,
+       PM_CLOCK_GETSTATE,
+       PM_CLOCK_SETDIVIDER,
+       PM_CLOCK_GETDIVIDER,
+       PM_CLOCK_SETRATE,
+       PM_CLOCK_GETRATE,
+       PM_CLOCK_SETPARENT,
+       PM_CLOCK_GETPARENT,
+};
+
+/* PMU-FW return status codes */
+enum pm_ret_status {
+       XST_PM_SUCCESS = 0,
+       XST_PM_INTERNAL = 2000,
+       XST_PM_CONFLICT,
+       XST_PM_NO_ACCESS,
+       XST_PM_INVALID_NODE,
+       XST_PM_DOUBLE_REQ,
+       XST_PM_ABORT_SUSPEND,
+};
+
+enum pm_ioctl_id {
+       IOCTL_SET_PLL_FRAC_MODE = 8,
+       IOCTL_GET_PLL_FRAC_MODE,
+       IOCTL_SET_PLL_FRAC_DATA,
+       IOCTL_GET_PLL_FRAC_DATA,
+};
+
+enum pm_query_id {
+       PM_QID_INVALID,
+       PM_QID_CLOCK_GET_NAME,
+       PM_QID_CLOCK_GET_TOPOLOGY,
+       PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
+       PM_QID_CLOCK_GET_PARENTS,
+       PM_QID_CLOCK_GET_ATTRIBUTES,
+       PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
+};
+
+/**
+ * struct zynqmp_pm_query_data - PM query data
+ * @qid:       query ID
+ * @arg1:      Argument 1 of query data
+ * @arg2:      Argument 2 of query data
+ * @arg3:      Argument 3 of query data
+ */
+struct zynqmp_pm_query_data {
+       u32 qid;
+       u32 arg1;
+       u32 arg2;
+       u32 arg3;
+};
+
+struct zynqmp_eemi_ops {
+       int (*get_api_version)(u32 *version);
+       int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out);
+       int (*clock_enable)(u32 clock_id);
+       int (*clock_disable)(u32 clock_id);
+       int (*clock_getstate)(u32 clock_id, u32 *state);
+       int (*clock_setdivider)(u32 clock_id, u32 divider);
+       int (*clock_getdivider)(u32 clock_id, u32 *divider);
+       int (*clock_setrate)(u32 clock_id, u64 rate);
+       int (*clock_getrate)(u32 clock_id, u64 *rate);
+       int (*clock_setparent)(u32 clock_id, u32 parent_id);
+       int (*clock_getparent)(u32 clock_id, u32 *parent_id);
+       int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out);
+};
+
+#if IS_REACHABLE(CONFIG_ARCH_ZYNQMP)
+const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void);
+#else
+static inline struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void)
+{
+       return NULL;
+}
+#endif
+
+#endif /* __FIRMWARE_ZYNQMP_H__ */
index 771341470bcebd249b023be7cc8f6a22e09b2d31..8252df30b9a16afe53c269b912b47e17edac7b41 100644 (file)
@@ -1412,17 +1412,26 @@ struct super_block {
 
        struct sb_writers       s_writers;
 
+       /*
+        * Keep s_fs_info, s_time_gran, s_fsnotify_mask, and
+        * s_fsnotify_marks together for cache efficiency. They are frequently
+        * accessed and rarely modified.
+        */
+       void                    *s_fs_info;     /* Filesystem private info */
+
+       /* Granularity of c/m/atime in ns (cannot be worse than a second) */
+       u32                     s_time_gran;
+#ifdef CONFIG_FSNOTIFY
+       __u32                   s_fsnotify_mask;
+       struct fsnotify_mark_connector __rcu    *s_fsnotify_marks;
+#endif
+
        char                    s_id[32];       /* Informational name */
        uuid_t                  s_uuid;         /* UUID */
 
-       void                    *s_fs_info;     /* Filesystem private info */
        unsigned int            s_max_links;
        fmode_t                 s_mode;
 
-       /* Granularity of c/m/atime in ns.
-          Cannot be worse than a second */
-       u32                s_time_gran;
-
        /*
         * The next field is for VFS *only*. No filesystems have any business
         * even looking at it. You had been warned.
@@ -1447,6 +1456,9 @@ struct super_block {
        /* Number of inodes with nlink == 0 but still referenced */
        atomic_long_t s_remove_count;
 
+       /* Pending fsnotify inode refs */
+       atomic_long_t s_fsnotify_inode_refs;
+
        /* Being remounted read-only */
        int s_readonly_remount;
 
index b8f4182f42f1d5e14813bb54d068db3873b5e3b7..135b973e44d18420074331dfbada3bd1f43009f5 100644 (file)
 
 #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
 
+/* Events that can be reported to backends */
 #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
                             FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
                             FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
                             FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
                             FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
-                            FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \
-                            FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
+                            FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME)
+
+/* Extra flags that may be reported with event or control handling of events */
+#define ALL_FSNOTIFY_FLAGS  (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \
                             FS_DN_MULTISHOT | FS_EVENT_ON_CHILD)
 
+#define ALL_FSNOTIFY_BITS   (ALL_FSNOTIFY_EVENTS | ALL_FSNOTIFY_FLAGS)
+
 struct fsnotify_group;
 struct fsnotify_event;
 struct fsnotify_mark;
@@ -189,10 +194,10 @@ struct fsnotify_group {
                        /* allows a group to block waiting for a userspace response */
                        struct list_head access_list;
                        wait_queue_head_t access_waitq;
-                       int f_flags;
+                       int flags;           /* flags from fanotify_init() */
+                       int f_flags; /* event_f_flags from fanotify_init() */
                        unsigned int max_marks;
                        struct user_struct *user;
-                       bool audit;
                } fanotify_data;
 #endif /* CONFIG_FANOTIFY */
        };
@@ -206,12 +211,14 @@ struct fsnotify_group {
 enum fsnotify_obj_type {
        FSNOTIFY_OBJ_TYPE_INODE,
        FSNOTIFY_OBJ_TYPE_VFSMOUNT,
+       FSNOTIFY_OBJ_TYPE_SB,
        FSNOTIFY_OBJ_TYPE_COUNT,
        FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
 };
 
 #define FSNOTIFY_OBJ_TYPE_INODE_FL     (1U << FSNOTIFY_OBJ_TYPE_INODE)
 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL  (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
+#define FSNOTIFY_OBJ_TYPE_SB_FL                (1U << FSNOTIFY_OBJ_TYPE_SB)
 #define FSNOTIFY_OBJ_ALL_TYPES_MASK    ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
 
 static inline bool fsnotify_valid_obj_type(unsigned int type)
@@ -255,6 +262,7 @@ static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \
 
 FSNOTIFY_ITER_FUNCS(inode, INODE)
 FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
+FSNOTIFY_ITER_FUNCS(sb, SB)
 
 #define fsnotify_foreach_obj_type(type) \
        for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++)
@@ -267,8 +275,8 @@ struct fsnotify_mark_connector;
 typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t;
 
 /*
- * Inode / vfsmount point to this structure which tracks all marks attached to
- * the inode / vfsmount. The reference to inode / vfsmount is held by this
+ * Inode/vfsmount/sb point to this structure which tracks all marks attached to
+ * the inode/vfsmount/sb. The reference to inode/vfsmount/sb is held by this
  * structure. We destroy this structure when there are no more marks attached
  * to it. The structure is protected by fsnotify_mark_srcu.
  */
@@ -335,6 +343,7 @@ extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int dat
 extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask);
 extern void __fsnotify_inode_delete(struct inode *inode);
 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
+extern void fsnotify_sb_delete(struct super_block *sb);
 extern u32 fsnotify_get_cookie(void);
 
 static inline int fsnotify_inode_watches_children(struct inode *inode)
@@ -455,9 +464,13 @@ static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *gr
 {
        fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
 }
+/* run all the marks in a group, and clear all of the sn marks */
+static inline void fsnotify_clear_sb_marks_by_group(struct fsnotify_group *group)
+{
+       fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_SB_FL);
+}
 extern void fsnotify_get_mark(struct fsnotify_mark *mark);
 extern void fsnotify_put_mark(struct fsnotify_mark *mark);
-extern void fsnotify_unmount_inodes(struct super_block *sb);
 extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
 extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
 
@@ -484,6 +497,9 @@ static inline void __fsnotify_inode_delete(struct inode *inode)
 static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
 {}
 
+static inline void fsnotify_sb_delete(struct super_block *sb)
+{}
+
 static inline void fsnotify_update_flags(struct dentry *dentry)
 {}
 
index d271ff23984f41cdb5a90d71d34bbdadc07dd4a1..4f3febc0f971cbf603bd5a905d4a2693fba8d3df 100644 (file)
@@ -101,8 +101,8 @@ enum hdmi_extended_colorimetry {
        HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
        HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
        HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
-       HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
-       HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
+       HDMI_EXTENDED_COLORIMETRY_OPYCC_601,
+       HDMI_EXTENDED_COLORIMETRY_OPRGB,
 
        /* The following EC values are only defined in CEA-861-F. */
        HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM,
index dde947083d4e30f68e842b0efa77bf454f3d7072..c6fb869a81c0e1ca3b6086bb709ba493532bad8a 100644 (file)
@@ -11,7 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * Authors: JÃ\83©rÃ\83´me Glisse <jglisse@redhat.com>
+ * Authors: Jérôme Glisse <jglisse@redhat.com>
  */
 /*
  * Heterogeneous Memory Management (HMM)
@@ -274,13 +274,28 @@ static inline uint64_t hmm_pfn_from_pfn(const struct hmm_range *range,
 struct hmm_mirror;
 
 /*
- * enum hmm_update_type - type of update
+ * enum hmm_update_event - type of update
  * @HMM_UPDATE_INVALIDATE: invalidate range (no indication as to why)
  */
-enum hmm_update_type {
+enum hmm_update_event {
        HMM_UPDATE_INVALIDATE,
 };
 
+/*
+ * struct hmm_update - HMM update informations for callback
+ *
+ * @start: virtual start address of the range to update
+ * @end: virtual end address of the range to update
+ * @event: event triggering the update (what is happening)
+ * @blockable: can the callback block/sleep ?
+ */
+struct hmm_update {
+       unsigned long start;
+       unsigned long end;
+       enum hmm_update_event event;
+       bool blockable;
+};
+
 /*
  * struct hmm_mirror_ops - HMM mirror device operations callback
  *
@@ -300,9 +315,9 @@ struct hmm_mirror_ops {
        /* sync_cpu_device_pagetables() - synchronize page tables
         *
         * @mirror: pointer to struct hmm_mirror
-        * @update_type: type of update that occurred to the CPU page table
-        * @start: virtual start address of the range to update
-        * @end: virtual end address of the range to update
+        * @update: update informations (see struct hmm_update)
+        * Returns: -EAGAIN if update.blockable false and callback need to
+        *          block, 0 otherwise.
         *
         * This callback ultimately originates from mmu_notifiers when the CPU
         * page table is updated. The device driver must update its page table
@@ -313,10 +328,8 @@ struct hmm_mirror_ops {
         * page tables are completely updated (TLBs flushed, etc); this is a
         * synchronous call.
         */
-       void (*sync_cpu_device_pagetables)(struct hmm_mirror *mirror,
-                                          enum hmm_update_type update_type,
-                                          unsigned long start,
-                                          unsigned long end);
+       int (*sync_cpu_device_pagetables)(struct hmm_mirror *mirror,
+                                         const struct hmm_update *update);
 };
 
 /*
index 2acdd046df2d5dda3edd9b30e9e4bd7700f42dca..aee299a6aa76d328f4d0bcf3494a5ad93b496ee9 100644 (file)
@@ -2,7 +2,6 @@
 #define _LINUX_MEMBLOCK_H
 #ifdef __KERNEL__
 
-#ifdef CONFIG_HAVE_MEMBLOCK
 /*
  * Logical memory blocks.
  *
 
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <asm/dma.h>
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+
+/*
+ * highest page
+ */
+extern unsigned long max_pfn;
+/*
+ * highest possible page
+ */
+extern unsigned long long max_possible_pfn;
 
 #define INIT_MEMBLOCK_REGIONS  128
 #define INIT_PHYSMEM_REGIONS   4
@@ -120,6 +132,10 @@ int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
 int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
 enum memblock_flags choose_memblock_flags(void);
 
+unsigned long memblock_free_all(void);
+void reset_node_managed_pages(pg_data_t *pgdat);
+void reset_all_zones_managed_pages(void);
+
 /* Low level functions */
 int memblock_add_range(struct memblock_type *type,
                       phys_addr_t base, phys_addr_t size,
@@ -301,10 +317,116 @@ static inline int memblock_get_region_node(const struct memblock_region *r)
 }
 #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
 
-phys_addr_t memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid);
-phys_addr_t memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid);
+/* Flags for memblock allocation APIs */
+#define MEMBLOCK_ALLOC_ANYWHERE        (~(phys_addr_t)0)
+#define MEMBLOCK_ALLOC_ACCESSIBLE      0
+
+/* We are using top down, so it is safe to use 0 here */
+#define MEMBLOCK_LOW_LIMIT 0
+
+#ifndef ARCH_LOW_ADDRESS_LIMIT
+#define ARCH_LOW_ADDRESS_LIMIT  0xffffffffUL
+#endif
+
+phys_addr_t memblock_phys_alloc_nid(phys_addr_t size, phys_addr_t align, int nid);
+phys_addr_t memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid);
+
+phys_addr_t memblock_phys_alloc(phys_addr_t size, phys_addr_t align);
+
+void *memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align,
+                                phys_addr_t min_addr, phys_addr_t max_addr,
+                                int nid);
+void *memblock_alloc_try_nid_nopanic(phys_addr_t size, phys_addr_t align,
+                                    phys_addr_t min_addr, phys_addr_t max_addr,
+                                    int nid);
+void *memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align,
+                            phys_addr_t min_addr, phys_addr_t max_addr,
+                            int nid);
+
+static inline void * __init memblock_alloc(phys_addr_t size,  phys_addr_t align)
+{
+       return memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT,
+                                     MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE);
+}
+
+static inline void * __init memblock_alloc_raw(phys_addr_t size,
+                                              phys_addr_t align)
+{
+       return memblock_alloc_try_nid_raw(size, align, MEMBLOCK_LOW_LIMIT,
+                                         MEMBLOCK_ALLOC_ACCESSIBLE,
+                                         NUMA_NO_NODE);
+}
+
+static inline void * __init memblock_alloc_from(phys_addr_t size,
+                                               phys_addr_t align,
+                                               phys_addr_t min_addr)
+{
+       return memblock_alloc_try_nid(size, align, min_addr,
+                                     MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE);
+}
+
+static inline void * __init memblock_alloc_nopanic(phys_addr_t size,
+                                                  phys_addr_t align)
+{
+       return memblock_alloc_try_nid_nopanic(size, align, MEMBLOCK_LOW_LIMIT,
+                                             MEMBLOCK_ALLOC_ACCESSIBLE,
+                                             NUMA_NO_NODE);
+}
+
+static inline void * __init memblock_alloc_low(phys_addr_t size,
+                                              phys_addr_t align)
+{
+       return memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT,
+                                     ARCH_LOW_ADDRESS_LIMIT, NUMA_NO_NODE);
+}
+static inline void * __init memblock_alloc_low_nopanic(phys_addr_t size,
+                                                      phys_addr_t align)
+{
+       return memblock_alloc_try_nid_nopanic(size, align, MEMBLOCK_LOW_LIMIT,
+                                             ARCH_LOW_ADDRESS_LIMIT,
+                                             NUMA_NO_NODE);
+}
+
+static inline void * __init memblock_alloc_from_nopanic(phys_addr_t size,
+                                                       phys_addr_t align,
+                                                       phys_addr_t min_addr)
+{
+       return memblock_alloc_try_nid_nopanic(size, align, min_addr,
+                                             MEMBLOCK_ALLOC_ACCESSIBLE,
+                                             NUMA_NO_NODE);
+}
+
+static inline void * __init memblock_alloc_node(phys_addr_t size,
+                                               phys_addr_t align, int nid)
+{
+       return memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT,
+                                     MEMBLOCK_ALLOC_ACCESSIBLE, nid);
+}
+
+static inline void * __init memblock_alloc_node_nopanic(phys_addr_t size,
+                                                       int nid)
+{
+       return memblock_alloc_try_nid_nopanic(size, SMP_CACHE_BYTES,
+                                             MEMBLOCK_LOW_LIMIT,
+                                             MEMBLOCK_ALLOC_ACCESSIBLE, nid);
+}
+
+static inline void __init memblock_free_early(phys_addr_t base,
+                                             phys_addr_t size)
+{
+       __memblock_free_early(base, size);
+}
+
+static inline void __init memblock_free_early_nid(phys_addr_t base,
+                                                 phys_addr_t size, int nid)
+{
+       __memblock_free_early(base, size);
+}
 
-phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align);
+static inline void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
+{
+       __memblock_free_late(base, size);
+}
 
 /*
  * Set the allocation direction to bottom-up or top-down.
@@ -324,10 +446,6 @@ static inline bool memblock_bottom_up(void)
        return memblock.bottom_up;
 }
 
-/* Flags for memblock_alloc_base() amd __memblock_alloc_base() */
-#define MEMBLOCK_ALLOC_ANYWHERE        (~(phys_addr_t)0)
-#define MEMBLOCK_ALLOC_ACCESSIBLE      0
-
 phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
                                        phys_addr_t start, phys_addr_t end,
                                        enum memblock_flags flags);
@@ -433,6 +551,31 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo
             i < memblock_type->cnt;                                    \
             i++, rgn = &memblock_type->regions[i])
 
+extern void *alloc_large_system_hash(const char *tablename,
+                                    unsigned long bucketsize,
+                                    unsigned long numentries,
+                                    int scale,
+                                    int flags,
+                                    unsigned int *_hash_shift,
+                                    unsigned int *_hash_mask,
+                                    unsigned long low_limit,
+                                    unsigned long high_limit);
+
+#define HASH_EARLY     0x00000001      /* Allocating during early boot? */
+#define HASH_SMALL     0x00000002      /* sub-page allocation allowed, min
+                                        * shift passed via *_hash_shift */
+#define HASH_ZERO      0x00000004      /* Zero allocated hash table */
+
+/* Only NUMA needs hash distribution. 64bit NUMA architectures have
+ * sufficient vmalloc space.
+ */
+#ifdef CONFIG_NUMA
+#define HASHDIST_DEFAULT IS_ENABLED(CONFIG_64BIT)
+extern int hashdist;           /* Distribute hashes across NUMA nodes? */
+#else
+#define hashdist (0)
+#endif
+
 #ifdef CONFIG_MEMTEST
 extern void early_memtest(phys_addr_t start, phys_addr_t end);
 #else
@@ -440,12 +583,6 @@ static inline void early_memtest(phys_addr_t start, phys_addr_t end)
 {
 }
 #endif
-#else
-static inline phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align)
-{
-       return 0;
-}
-#endif /* CONFIG_HAVE_MEMBLOCK */
 
 #endif /* __KERNEL__ */
 
index 34a28227068dcba6cba30feb13e15aeff9f69b08..ffd9cd10fcf35fb20b8728e6294eff42d90c135e 100644 (file)
@@ -301,6 +301,7 @@ extern bool is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);
 extern void try_offline_node(int nid);
 extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
 extern void remove_memory(int nid, u64 start, u64 size);
+extern void __remove_memory(int nid, u64 start, u64 size);
 
 #else
 static inline bool is_mem_section_removable(unsigned long pfn,
@@ -317,11 +318,13 @@ static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
 }
 
 static inline void remove_memory(int nid, u64 start, u64 size) {}
+static inline void __remove_memory(int nid, u64 start, u64 size) {}
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
 extern void __ref free_area_init_core_hotplug(int nid);
 extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
                void *arg, int (*func)(struct memory_block *, void *));
+extern int __add_memory(int nid, u64 start, u64 size);
 extern int add_memory(int nid, u64 start, u64 size);
 extern int add_memory_resource(int nid, struct resource *resource, bool online);
 extern int arch_add_memory(int nid, u64 start, u64 size,
@@ -330,7 +333,6 @@ extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
                unsigned long nr_pages, struct vmem_altmap *altmap);
 extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
 extern bool is_memblock_offlined(struct memory_block *mem);
-extern void remove_memory(int nid, u64 start, u64 size);
 extern int sparse_add_one_section(struct pglist_data *pgdat,
                unsigned long start_pfn, struct vmem_altmap *altmap);
 extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
index 20949dde35cdff149f259a526e2fadb8fa9f3a34..e44e3ec8a9c7d0e4c389a4c65360dbc3e14ab86a 100644 (file)
@@ -36,7 +36,7 @@
  * I2C requires 1 additional byte for requests.
  * I2C requires 2 additional bytes for responses.
  * SPI requires up to 32 additional bytes for responses.
- * */
+ */
 #define EC_PROTO_VERSION_UNKNOWN       0
 #define EC_MAX_REQUEST_OVERHEAD                1
 #define EC_MAX_RESPONSE_OVERHEAD       32
@@ -58,13 +58,14 @@ enum {
        EC_MAX_MSG_BYTES                = 64 * 1024,
 };
 
-/*
- * @version: Command version number (often 0)
- * @command: Command to send (EC_CMD_...)
- * @outsize: Outgoing length in bytes
- * @insize: Max number of bytes to accept from EC
- * @result: EC's response to the command (separate from communication failure)
- * @data: Where to put the incoming data from EC and outgoing data to EC
+/**
+ * struct cros_ec_command - Information about a ChromeOS EC command.
+ * @version: Command version number (often 0).
+ * @command: Command to send (EC_CMD_...).
+ * @outsize: Outgoing length in bytes.
+ * @insize: Max number of bytes to accept from the EC.
+ * @result: EC's response to the command (separate from communication failure).
+ * @data: Where to put the incoming data from EC and outgoing data to EC.
  */
 struct cros_ec_command {
        uint32_t version;
@@ -76,48 +77,55 @@ struct cros_ec_command {
 };
 
 /**
- * struct cros_ec_device - Information about a ChromeOS EC device
- *
- * @phys_name: name of physical comms layer (e.g. 'i2c-4')
+ * struct cros_ec_device - Information about a ChromeOS EC device.
+ * @phys_name: Name of physical comms layer (e.g. 'i2c-4').
  * @dev: Device pointer for physical comms device
- * @was_wake_device: true if this device was set to wake the system from
- * sleep at the last suspend
- * @cmd_readmem: direct read of the EC memory-mapped region, if supported
- *     @offset is within EC_LPC_ADDR_MEMMAP region.
- *     @bytes: number of bytes to read. zero means "read a string" (including
- *     the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be read.
- *     Caller must ensure that the buffer is large enough for the result when
- *     reading a string.
- *
- * @priv: Private data
- * @irq: Interrupt to use
- * @id: Device id
- * @din: input buffer (for data from EC)
- * @dout: output buffer (for data to EC)
- * \note
- * These two buffers will always be dword-aligned and include enough
- * space for up to 7 word-alignment bytes also, so we can ensure that
- * the body of the message is always dword-aligned (64-bit).
- * We use this alignment to keep ARM and x86 happy. Probably word
- * alignment would be OK, there might be a small performance advantage
- * to using dword.
- * @din_size: size of din buffer to allocate (zero to use static din)
- * @dout_size: size of dout buffer to allocate (zero to use static dout)
- * @wake_enabled: true if this device can wake the system from sleep
- * @suspended: true if this device had been suspended
- * @cmd_xfer: send command to EC and get response
- *     Returns the number of bytes received if the communication succeeded, but
- *     that doesn't mean the EC was happy with the command. The caller
- *     should check msg.result for the EC's result code.
- * @pkt_xfer: send packet to EC and get response
- * @lock: one transaction at a time
- * @mkbp_event_supported: true if this EC supports the MKBP event protocol.
- * @event_notifier: interrupt event notifier for transport devices.
- * @event_data: raw payload transferred with the MKBP event.
- * @event_size: size in bytes of the event data.
+ * @was_wake_device: True if this device was set to wake the system from
+ *                   sleep at the last suspend.
+ * @cros_class: The class structure for this device.
+ * @cmd_readmem: Direct read of the EC memory-mapped region, if supported.
+ *     @offset: Is within EC_LPC_ADDR_MEMMAP region.
+ *     @bytes: Number of bytes to read. zero means "read a string" (including
+ *             the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be
+ *             read. Caller must ensure that the buffer is large enough for the
+ *             result when reading a string.
+ * @max_request: Max size of message requested.
+ * @max_response: Max size of message response.
+ * @max_passthru: Max sice of passthru message.
+ * @proto_version: The protocol version used for this device.
+ * @priv: Private data.
+ * @irq: Interrupt to use.
+ * @id: Device id.
+ * @din: Input buffer (for data from EC). This buffer will always be
+ *       dword-aligned and include enough space for up to 7 word-alignment
+ *       bytes also, so we can ensure that the body of the message is always
+ *       dword-aligned (64-bit). We use this alignment to keep ARM and x86
+ *       happy. Probably word alignment would be OK, there might be a small
+ *       performance advantage to using dword.
+ * @dout: Output buffer (for data to EC). This buffer will always be
+ *        dword-aligned and include enough space for up to 7 word-alignment
+ *        bytes also, so we can ensure that the body of the message is always
+ *        dword-aligned (64-bit). We use this alignment to keep ARM and x86
+ *        happy. Probably word alignment would be OK, there might be a small
+ *        performance advantage to using dword.
+ * @din_size: Size of din buffer to allocate (zero to use static din).
+ * @dout_size: Size of dout buffer to allocate (zero to use static dout).
+ * @wake_enabled: True if this device can wake the system from sleep.
+ * @suspended: True if this device had been suspended.
+ * @cmd_xfer: Send command to EC and get response.
+ *            Returns the number of bytes received if the communication
+ *            succeeded, but that doesn't mean the EC was happy with the
+ *            command. The caller should check msg.result for the EC's result
+ *            code.
+ * @pkt_xfer: Send packet to EC and get response.
+ * @lock: One transaction at a time.
+ * @mkbp_event_supported: True if this EC supports the MKBP event protocol.
+ * @event_notifier: Interrupt event notifier for transport devices.
+ * @event_data: Raw payload transferred with the MKBP event.
+ * @event_size: Size in bytes of the event data.
+ * @host_event_wake_mask: Mask of host events that cause wake from suspend.
  */
 struct cros_ec_device {
-
        /* These are used by other drivers that want to talk to the EC */
        const char *phys_name;
        struct device *dev;
@@ -153,20 +161,19 @@ struct cros_ec_device {
 };
 
 /**
- * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information
- *
+ * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information.
  * @sensor_num: Id of the sensor, as reported by the EC.
  */
 struct cros_ec_sensor_platform {
        u8 sensor_num;
 };
 
-/* struct cros_ec_platform - ChromeOS EC platform information
- *
- * @ec_name: name of EC device (e.g. 'cros-ec', 'cros-pd', ...)
- * used in /dev/ and sysfs.
- * @cmd_offset: offset to apply for each command. Set when
- * registering a devicde behind another one.
+/**
+ * struct cros_ec_platform - ChromeOS EC platform information.
+ * @ec_name: Name of EC device (e.g. 'cros-ec', 'cros-pd', ...)
+ *           used in /dev/ and sysfs.
+ * @cmd_offset: Offset to apply for each command. Set when
+ *              registering a device behind another one.
  */
 struct cros_ec_platform {
        const char *ec_name;
@@ -175,16 +182,16 @@ struct cros_ec_platform {
 
 struct cros_ec_debugfs;
 
-/*
- * struct cros_ec_dev - ChromeOS EC device entry point
- *
- * @class_dev: Device structure used in sysfs
- * @cdev: Character device structure in /dev
- * @ec_dev: cros_ec_device structure to talk to the physical device
- * @dev: pointer to the platform device
- * @debug_info: cros_ec_debugfs structure for debugging information
- * @has_kb_wake_angle: true if at least 2 accelerometer are connected to the EC.
- * @cmd_offset: offset to apply for each command.
+/**
+ * struct cros_ec_dev - ChromeOS EC device entry point.
+ * @class_dev: Device structure used in sysfs.
+ * @cdev: Character device structure in /dev.
+ * @ec_dev: cros_ec_device structure to talk to the physical device.
+ * @dev: Pointer to the platform device.
+ * @debug_info: cros_ec_debugfs structure for debugging information.
+ * @has_kb_wake_angle: True if at least 2 accelerometer are connected to the EC.
+ * @cmd_offset: Offset to apply for each command.
+ * @features: Features supported by the EC.
  */
 struct cros_ec_dev {
        struct device class_dev;
@@ -200,124 +207,129 @@ struct cros_ec_dev {
 #define to_cros_ec_dev(dev)  container_of(dev, struct cros_ec_dev, class_dev)
 
 /**
- * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device
+ * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device.
+ * @ec_dev: Device to suspend.
  *
  * This can be called by drivers to handle a suspend event.
  *
- * ec_dev: Device to suspend
- * @return 0 if ok, -ve on error
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_suspend(struct cros_ec_device *ec_dev);
 
 /**
- * cros_ec_resume - Handle a resume operation for the ChromeOS EC device
+ * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device.
+ * @ec_dev: Device to resume.
  *
  * This can be called by drivers to handle a resume event.
  *
- * @ec_dev: Device to resume
- * @return 0 if ok, -ve on error
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_resume(struct cros_ec_device *ec_dev);
 
 /**
- * cros_ec_prepare_tx - Prepare an outgoing message in the output buffer
+ * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer.
+ * @ec_dev: Device to register.
+ * @msg: Message to write.
  *
  * This is intended to be used by all ChromeOS EC drivers, but at present
  * only SPI uses it. Once LPC uses the same protocol it can start using it.
  * I2C could use it now, with a refactor of the existing code.
  *
- * @ec_dev: Device to register
- * @msg: Message to write
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
                       struct cros_ec_command *msg);
 
 /**
- * cros_ec_check_result - Check ec_msg->result
+ * cros_ec_check_result() - Check ec_msg->result.
+ * @ec_dev: EC device.
+ * @msg: Message to check.
  *
  * This is used by ChromeOS EC drivers to check the ec_msg->result for
  * errors and to warn about them.
  *
- * @ec_dev: EC device
- * @msg: Message to check
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_check_result(struct cros_ec_device *ec_dev,
                         struct cros_ec_command *msg);
 
 /**
- * cros_ec_cmd_xfer - Send a command to the ChromeOS EC
+ * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC.
+ * @ec_dev: EC device.
+ * @msg: Message to write.
  *
  * Call this to send a command to the ChromeOS EC.  This should be used
  * instead of calling the EC's cmd_xfer() callback directly.
  *
- * @ec_dev: EC device
- * @msg: Message to write
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
                     struct cros_ec_command *msg);
 
 /**
- * cros_ec_cmd_xfer_status - Send a command to the ChromeOS EC
+ * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC.
+ * @ec_dev: EC device.
+ * @msg: Message to write.
  *
  * This function is identical to cros_ec_cmd_xfer, except it returns success
  * status only if both the command was transmitted successfully and the EC
  * replied with success status. It's not necessary to check msg->result when
  * using this function.
  *
- * @ec_dev: EC device
- * @msg: Message to write
- * @return: Num. of bytes transferred on success, <0 on failure
+ * Return: The number of bytes transferred on success or negative error code.
  */
 int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
                            struct cros_ec_command *msg);
 
 /**
- * cros_ec_remove - Remove a ChromeOS EC
+ * cros_ec_remove() - Remove a ChromeOS EC.
+ * @ec_dev: Device to register.
  *
  * Call this to deregister a ChromeOS EC, then clean up any private data.
  *
- * @ec_dev: Device to register
- * @return 0 if ok, -ve on error
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_remove(struct cros_ec_device *ec_dev);
 
 /**
- * cros_ec_register - Register a new ChromeOS EC, using the provided info
+ * cros_ec_register() - Register a new ChromeOS EC, using the provided info.
+ * @ec_dev: Device to register.
  *
  * Before calling this, allocate a pointer to a new device and then fill
  * in all the fields up to the --private-- marker.
  *
- * @ec_dev: Device to register
- * @return 0 if ok, -ve on error
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_register(struct cros_ec_device *ec_dev);
 
 /**
- * cros_ec_query_all -  Query the protocol version supported by the ChromeOS EC
+ * cros_ec_query_all() -  Query the protocol version supported by the
+ *         ChromeOS EC.
+ * @ec_dev: Device to register.
  *
- * @ec_dev: Device to register
- * @return 0 if ok, -ve on error
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_query_all(struct cros_ec_device *ec_dev);
 
 /**
- * cros_ec_get_next_event -  Fetch next event from the ChromeOS EC
- *
- * @ec_dev: Device to fetch event from
+ * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC.
+ * @ec_dev: Device to fetch event from.
  * @wake_event: Pointer to a bool set to true upon return if the event might be
  *              treated as a wake event. Ignored if null.
  *
- * Returns: 0 on success, Linux error number on failure
+ * Return: 0 on success or negative error code.
  */
 int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event);
 
 /**
- * cros_ec_get_host_event - Return a mask of event set by the EC.
+ * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC.
+ * @ec_dev: Device to fetch event from.
  *
- * When MKBP is supported, when the EC raises an interrupt,
- * We collect the events raised and call the functions in the ec notifier.
+ * When MKBP is supported, when the EC raises an interrupt, we collect the
+ * events raised and call the functions in the ec notifier. This function
+ * is a helper to know which events are raised.
  *
- * This function is a helper to know which events are raised.
+ * Return: 0 on success or negative error code.
  */
 u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev);
 
index 5fd0e429f47202cce036218562f2e4c4b445a4cb..9a9631f0559e295763105520c1918abd9895b6dd 100644 (file)
@@ -306,15 +306,18 @@ enum host_event_code {
 /* Host event mask */
 #define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1))
 
-/* Arguments at EC_LPC_ADDR_HOST_ARGS */
+/**
+ * struct ec_lpc_host_args - Arguments at EC_LPC_ADDR_HOST_ARGS
+ * @flags: The host argument flags.
+ * @command_version: Command version.
+ * @data_size: The length of data.
+ * @checksum: Checksum; sum of command + flags + command_version + data_size +
+ *            all params/response data bytes.
+ */
 struct ec_lpc_host_args {
        uint8_t flags;
        uint8_t command_version;
        uint8_t data_size;
-       /*
-        * Checksum; sum of command + flags + command_version + data_size +
-        * all params/response data bytes.
-        */
        uint8_t checksum;
 } __packed;
 
@@ -468,54 +471,43 @@ struct ec_lpc_host_args {
 
 #define EC_HOST_REQUEST_VERSION 3
 
-/* Version 3 request from host */
+/**
+ * struct ec_host_request - Version 3 request from host.
+ * @struct_version: Should be 3. The EC will return EC_RES_INVALID_HEADER if it
+ *                  receives a header with a version it doesn't know how to
+ *                  parse.
+ * @checksum: Checksum of request and data; sum of all bytes including checksum
+ *            should total to 0.
+ * @command: Command to send (EC_CMD_...)
+ * @command_version: Command version.
+ * @reserved: Unused byte in current protocol version; set to 0.
+ * @data_len: Length of data which follows this header.
+ */
 struct ec_host_request {
-       /* Struct version (=3)
-        *
-        * EC will return EC_RES_INVALID_HEADER if it receives a header with a
-        * version it doesn't know how to parse.
-        */
        uint8_t struct_version;
-
-       /*
-        * Checksum of request and data; sum of all bytes including checksum
-        * should total to 0.
-        */
        uint8_t checksum;
-
-       /* Command code */
        uint16_t command;
-
-       /* Command version */
        uint8_t command_version;
-
-       /* Unused byte in current protocol version; set to 0 */
        uint8_t reserved;
-
-       /* Length of data which follows this header */
        uint16_t data_len;
 } __packed;
 
 #define EC_HOST_RESPONSE_VERSION 3
 
-/* Version 3 response from EC */
+/**
+ * struct ec_host_response - Version 3 response from EC.
+ * @struct_version: Struct version (=3).
+ * @checksum: Checksum of response and data; sum of all bytes including
+ *            checksum should total to 0.
+ * @result: EC's response to the command (separate from communication failure)
+ * @data_len: Length of data which follows this header.
+ * @reserved: Unused bytes in current protocol version; set to 0.
+ */
 struct ec_host_response {
-       /* Struct version (=3) */
        uint8_t struct_version;
-
-       /*
-        * Checksum of response and data; sum of all bytes including checksum
-        * should total to 0.
-        */
        uint8_t checksum;
-
-       /* Result code (EC_RES_*) */
        uint16_t result;
-
-       /* Length of data which follows this header */
        uint16_t data_len;
-
-       /* Unused bytes in current protocol version; set to 0 */
        uint16_t reserved;
 } __packed;
 
@@ -540,6 +532,10 @@ struct ec_host_response {
  */
 #define EC_CMD_PROTO_VERSION 0x00
 
+/**
+ * struct ec_response_proto_version - Response to the proto version command.
+ * @version: The protocol version.
+ */
 struct ec_response_proto_version {
        uint32_t version;
 } __packed;
@@ -550,12 +546,20 @@ struct ec_response_proto_version {
  */
 #define EC_CMD_HELLO 0x01
 
+/**
+ * struct ec_params_hello - Parameters to the hello command.
+ * @in_data: Pass anything here.
+ */
 struct ec_params_hello {
-       uint32_t in_data;  /* Pass anything here */
+       uint32_t in_data;
 } __packed;
 
+/**
+ * struct ec_response_hello - Response to the hello command.
+ * @out_data: Output will be in_data + 0x01020304.
+ */
 struct ec_response_hello {
-       uint32_t out_data;  /* Output will be in_data + 0x01020304 */
+       uint32_t out_data;
 } __packed;
 
 /* Get version number */
@@ -567,22 +571,37 @@ enum ec_current_image {
        EC_IMAGE_RW
 };
 
+/**
+ * struct ec_response_get_version - Response to the get version command.
+ * @version_string_ro: Null-terminated RO firmware version string.
+ * @version_string_rw: Null-terminated RW firmware version string.
+ * @reserved: Unused bytes; was previously RW-B firmware version string.
+ * @current_image: One of ec_current_image.
+ */
 struct ec_response_get_version {
-       /* Null-terminated version strings for RO, RW */
        char version_string_ro[32];
        char version_string_rw[32];
-       char reserved[32];       /* Was previously RW-B string */
-       uint32_t current_image;  /* One of ec_current_image */
+       char reserved[32];
+       uint32_t current_image;
 } __packed;
 
 /* Read test */
 #define EC_CMD_READ_TEST 0x03
 
+/**
+ * struct ec_params_read_test - Parameters for the read test command.
+ * @offset: Starting value for read buffer.
+ * @size: Size to read in bytes.
+ */
 struct ec_params_read_test {
-       uint32_t offset;   /* Starting value for read buffer */
-       uint32_t size;     /* Size to read in bytes */
+       uint32_t offset;
+       uint32_t size;
 } __packed;
 
+/**
+ * struct ec_response_read_test - Response to the read test command.
+ * @data: Data returned by the read test command.
+ */
 struct ec_response_read_test {
        uint32_t data[32];
 } __packed;
@@ -597,18 +616,27 @@ struct ec_response_read_test {
 /* Get chip info */
 #define EC_CMD_GET_CHIP_INFO 0x05
 
+/**
+ * struct ec_response_get_chip_info - Response to the get chip info command.
+ * @vendor: Null-terminated string for chip vendor.
+ * @name: Null-terminated string for chip name.
+ * @revision: Null-terminated string for chip mask version.
+ */
 struct ec_response_get_chip_info {
-       /* Null-terminated strings */
        char vendor[32];
        char name[32];
-       char revision[32];  /* Mask version */
+       char revision[32];
 } __packed;
 
 /* Get board HW version */
 #define EC_CMD_GET_BOARD_VERSION 0x06
 
+/**
+ * struct ec_response_board_version - Response to the board version command.
+ * @board_version: A monotonously incrementing number.
+ */
 struct ec_response_board_version {
-       uint16_t board_version;  /* A monotonously incrementing number. */
+       uint16_t board_version;
 } __packed;
 
 /*
@@ -621,27 +649,42 @@ struct ec_response_board_version {
  */
 #define EC_CMD_READ_MEMMAP 0x07
 
+/**
+ * struct ec_params_read_memmap - Parameters for the read memory map command.
+ * @offset: Offset in memmap (EC_MEMMAP_*).
+ * @size: Size to read in bytes.
+ */
 struct ec_params_read_memmap {
-       uint8_t offset;   /* Offset in memmap (EC_MEMMAP_*) */
-       uint8_t size;     /* Size to read in bytes */
+       uint8_t offset;
+       uint8_t size;
 } __packed;
 
 /* Read versions supported for a command */
 #define EC_CMD_GET_CMD_VERSIONS 0x08
 
+/**
+ * struct ec_params_get_cmd_versions - Parameters for the get command versions.
+ * @cmd: Command to check.
+ */
 struct ec_params_get_cmd_versions {
-       uint8_t cmd;      /* Command to check */
+       uint8_t cmd;
 } __packed;
 
+/**
+ * struct ec_params_get_cmd_versions_v1 - Parameters for the get command
+ *         versions (v1)
+ * @cmd: Command to check.
+ */
 struct ec_params_get_cmd_versions_v1 {
-       uint16_t cmd;     /* Command to check */
+       uint16_t cmd;
 } __packed;
 
+/**
+ * struct ec_response_get_cmd_version - Response to the get command versions.
+ * @version_mask: Mask of supported versions; use EC_VER_MASK() to compare with
+ *                a desired version.
+ */
 struct ec_response_get_cmd_versions {
-       /*
-        * Mask of supported versions; use EC_VER_MASK() to compare with a
-        * desired version.
-        */
        uint32_t version_mask;
 } __packed;
 
@@ -659,6 +702,11 @@ enum ec_comms_status {
        EC_COMMS_STATUS_PROCESSING      = 1 << 0,       /* Processing cmd */
 };
 
+/**
+ * struct ec_response_get_comms_status - Response to the get comms status
+ *         command.
+ * @flags: Mask of enum ec_comms_status.
+ */
 struct ec_response_get_comms_status {
        uint32_t flags;         /* Mask of enum ec_comms_status */
 } __packed;
@@ -685,19 +733,19 @@ struct ec_response_test_protocol {
 /* EC_RES_IN_PROGRESS may be returned if a command is slow */
 #define EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED (1 << 0)
 
+/**
+ * struct ec_response_get_protocol_info - Response to the get protocol info.
+ * @protocol_versions: Bitmask of protocol versions supported (1 << n means
+ *                     version n).
+ * @max_request_packet_size: Maximum request packet size in bytes.
+ * @max_response_packet_size: Maximum response packet size in bytes.
+ * @flags: see EC_PROTOCOL_INFO_*
+ */
 struct ec_response_get_protocol_info {
        /* Fields which exist if at least protocol version 3 supported */
-
-       /* Bitmask of protocol versions supported (1 << n means version n)*/
        uint32_t protocol_versions;
-
-       /* Maximum request packet size, in bytes */
        uint16_t max_request_packet_size;
-
-       /* Maximum response packet size, in bytes */
        uint16_t max_response_packet_size;
-
-       /* Flags; see EC_PROTOCOL_INFO_* */
        uint32_t flags;
 } __packed;
 
@@ -708,8 +756,10 @@ struct ec_response_get_protocol_info {
 /* The upper byte of .flags tells what to do (nothing means "get") */
 #define EC_GSV_SET        0x80000000
 
-/* The lower three bytes of .flags identifies the parameter, if that has
-   meaning for an individual command. */
+/*
+ * The lower three bytes of .flags identifies the parameter, if that has
+ * meaning for an individual command.
+ */
 #define EC_GSV_PARAM_MASK 0x00ffffff
 
 struct ec_params_get_set_value {
@@ -810,6 +860,7 @@ enum ec_feature_code {
 
 #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
 #define EC_FEATURE_MASK_1(event_code) (1UL << (event_code - 32))
+
 struct ec_response_get_features {
        uint32_t flags[2];
 } __packed;
@@ -820,24 +871,22 @@ struct ec_response_get_features {
 /* Get flash info */
 #define EC_CMD_FLASH_INFO 0x10
 
-/* Version 0 returns these fields */
+/**
+ * struct ec_response_flash_info - Response to the flash info command.
+ * @flash_size: Usable flash size in bytes.
+ * @write_block_size: Write block size. Write offset and size must be a
+ *                    multiple of this.
+ * @erase_block_size: Erase block size. Erase offset and size must be a
+ *                    multiple of this.
+ * @protect_block_size: Protection block size. Protection offset and size
+ *                      must be a multiple of this.
+ *
+ * Version 0 returns these fields.
+ */
 struct ec_response_flash_info {
-       /* Usable flash size, in bytes */
        uint32_t flash_size;
-       /*
-        * Write block size.  Write offset and size must be a multiple
-        * of this.
-        */
        uint32_t write_block_size;
-       /*
-        * Erase block size.  Erase offset and size must be a multiple
-        * of this.
-        */
        uint32_t erase_block_size;
-       /*
-        * Protection block size.  Protection offset and size must be a
-        * multiple of this.
-        */
        uint32_t protect_block_size;
 } __packed;
 
@@ -845,7 +894,22 @@ struct ec_response_flash_info {
 /* EC flash erases bits to 0 instead of 1 */
 #define EC_FLASH_INFO_ERASE_TO_0 (1 << 0)
 
-/*
+/**
+ * struct ec_response_flash_info_1 - Response to the flash info v1 command.
+ * @flash_size: Usable flash size in bytes.
+ * @write_block_size: Write block size. Write offset and size must be a
+ *                    multiple of this.
+ * @erase_block_size: Erase block size. Erase offset and size must be a
+ *                    multiple of this.
+ * @protect_block_size: Protection block size. Protection offset and size
+ *                      must be a multiple of this.
+ * @write_ideal_size: Ideal write size in bytes.  Writes will be fastest if
+ *                    size is exactly this and offset is a multiple of this.
+ *                    For example, an EC may have a write buffer which can do
+ *                    half-page operations if data is aligned, and a slower
+ *                    word-at-a-time write mode.
+ * @flags: Flags; see EC_FLASH_INFO_*
+ *
  * Version 1 returns the same initial fields as version 0, with additional
  * fields following.
  *
@@ -860,15 +924,7 @@ struct ec_response_flash_info_1 {
        uint32_t protect_block_size;
 
        /* Version 1 adds these fields: */
-       /*
-        * Ideal write size in bytes.  Writes will be fastest if size is
-        * exactly this and offset is a multiple of this.  For example, an EC
-        * may have a write buffer which can do half-page operations if data is
-        * aligned, and a slower word-at-a-time write mode.
-        */
        uint32_t write_ideal_size;
-
-       /* Flags; see EC_FLASH_INFO_* */
        uint32_t flags;
 } __packed;
 
@@ -879,9 +935,14 @@ struct ec_response_flash_info_1 {
  */
 #define EC_CMD_FLASH_READ 0x11
 
+/**
+ * struct ec_params_flash_read - Parameters for the flash read command.
+ * @offset: Byte offset to read.
+ * @size: Size to read in bytes.
+ */
 struct ec_params_flash_read {
-       uint32_t offset;   /* Byte offset to read */
-       uint32_t size;     /* Size to read in bytes */
+       uint32_t offset;
+       uint32_t size;
 } __packed;
 
 /* Write flash */
@@ -891,18 +952,28 @@ struct ec_params_flash_read {
 /* Version 0 of the flash command supported only 64 bytes of data */
 #define EC_FLASH_WRITE_VER0_SIZE 64
 
+/**
+ * struct ec_params_flash_write - Parameters for the flash write command.
+ * @offset: Byte offset to write.
+ * @size: Size to write in bytes.
+ */
 struct ec_params_flash_write {
-       uint32_t offset;   /* Byte offset to write */
-       uint32_t size;     /* Size to write in bytes */
+       uint32_t offset;
+       uint32_t size;
        /* Followed by data to write */
 } __packed;
 
 /* Erase flash */
 #define EC_CMD_FLASH_ERASE 0x13
 
+/**
+ * struct ec_params_flash_erase - Parameters for the flash erase command.
+ * @offset: Byte offset to erase.
+ * @size: Size to erase in bytes.
+ */
 struct ec_params_flash_erase {
-       uint32_t offset;   /* Byte offset to erase */
-       uint32_t size;     /* Size to erase in bytes */
+       uint32_t offset;
+       uint32_t size;
 } __packed;
 
 /*
@@ -941,21 +1012,28 @@ struct ec_params_flash_erase {
 /* Entile flash code protected when the EC boots */
 #define EC_FLASH_PROTECT_ALL_AT_BOOT        (1 << 6)
 
+/**
+ * struct ec_params_flash_protect - Parameters for the flash protect command.
+ * @mask: Bits in flags to apply.
+ * @flags: New flags to apply.
+ */
 struct ec_params_flash_protect {
-       uint32_t mask;   /* Bits in flags to apply */
-       uint32_t flags;  /* New flags to apply */
+       uint32_t mask;
+       uint32_t flags;
 } __packed;
 
+/**
+ * struct ec_response_flash_protect - Response to the flash protect command.
+ * @flags: Current value of flash protect flags.
+ * @valid_flags: Flags which are valid on this platform. This allows the
+ *               caller to distinguish between flags which aren't set vs. flags
+ *               which can't be set on this platform.
+ * @writable_flags: Flags which can be changed given the current protection
+ *                  state.
+ */
 struct ec_response_flash_protect {
-       /* Current value of flash protect flags */
        uint32_t flags;
-       /*
-        * Flags which are valid on this platform.  This allows the caller
-        * to distinguish between flags which aren't set vs. flags which can't
-        * be set on this platform.
-        */
        uint32_t valid_flags;
-       /* Flags which can be changed given the current protection state */
        uint32_t writable_flags;
 } __packed;
 
@@ -982,8 +1060,13 @@ enum ec_flash_region {
        EC_FLASH_REGION_COUNT,
 };
 
+/**
+ * struct ec_params_flash_region_info - Parameters for the flash region info
+ *         command.
+ * @region: Flash region; see EC_FLASH_REGION_*
+ */
 struct ec_params_flash_region_info {
-       uint32_t region;  /* enum ec_flash_region */
+       uint32_t region;
 } __packed;
 
 struct ec_response_flash_region_info {
@@ -1094,7 +1177,9 @@ struct rgb_s {
 };
 
 #define LB_BATTERY_LEVELS 4
-/* List of tweakable parameters. NOTE: It's __packed so it can be sent in a
+
+/*
+ * List of tweakable parameters. NOTE: It's __packed so it can be sent in a
  * host command, but the alignment is the same regardless. Keep it that way.
  */
 struct lightbar_params_v0 {
diff --git a/include/linux/mfd/cros_ec_lpc_mec.h b/include/linux/mfd/cros_ec_lpc_mec.h
deleted file mode 100644 (file)
index 176496d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * cros_ec_lpc_mec - LPC variant I/O for Microchip EC
- *
- * Copyright (C) 2016 Google, Inc
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * This driver uses the Chrome OS EC byte-level message-based protocol for
- * communicating the keyboard state (which keys are pressed) from a keyboard EC
- * to the AP over some bus (such as i2c, lpc, spi).  The EC does debouncing,
- * but everything else (including deghosting) is done here.  The main
- * motivation for this is to keep the EC firmware as simple as possible, since
- * it cannot be easily upgraded and EC flash/IRAM space is relatively
- * expensive.
- */
-
-#ifndef __LINUX_MFD_CROS_EC_MEC_H
-#define __LINUX_MFD_CROS_EC_MEC_H
-
-#include <linux/mfd/cros_ec_commands.h>
-
-enum cros_ec_lpc_mec_emi_access_mode {
-       /* 8-bit access */
-       ACCESS_TYPE_BYTE = 0x0,
-       /* 16-bit access */
-       ACCESS_TYPE_WORD = 0x1,
-       /* 32-bit access */
-       ACCESS_TYPE_LONG = 0x2,
-       /*
-        * 32-bit access, read or write of MEC_EMI_EC_DATA_B3 causes the
-        * EC data register to be incremented.
-        */
-       ACCESS_TYPE_LONG_AUTO_INCREMENT = 0x3,
-};
-
-enum cros_ec_lpc_mec_io_type {
-       MEC_IO_READ,
-       MEC_IO_WRITE,
-};
-
-/* Access IO ranges 0x800 thru 0x9ff using EMI interface instead of LPC */
-#define MEC_EMI_RANGE_START EC_HOST_CMD_REGION0
-#define MEC_EMI_RANGE_END   (EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE)
-
-/* EMI registers are relative to base */
-#define MEC_EMI_BASE 0x800
-#define MEC_EMI_HOST_TO_EC (MEC_EMI_BASE + 0)
-#define MEC_EMI_EC_TO_HOST (MEC_EMI_BASE + 1)
-#define MEC_EMI_EC_ADDRESS_B0 (MEC_EMI_BASE + 2)
-#define MEC_EMI_EC_ADDRESS_B1 (MEC_EMI_BASE + 3)
-#define MEC_EMI_EC_DATA_B0 (MEC_EMI_BASE + 4)
-#define MEC_EMI_EC_DATA_B1 (MEC_EMI_BASE + 5)
-#define MEC_EMI_EC_DATA_B2 (MEC_EMI_BASE + 6)
-#define MEC_EMI_EC_DATA_B3 (MEC_EMI_BASE + 7)
-
-/*
- * cros_ec_lpc_mec_init
- *
- * Initialize MEC I/O.
- */
-void cros_ec_lpc_mec_init(void);
-
-/*
- * cros_ec_lpc_mec_destroy
- *
- * Cleanup MEC I/O.
- */
-void cros_ec_lpc_mec_destroy(void);
-
-/**
- * cros_ec_lpc_io_bytes_mec - Read / write bytes to MEC EMI port
- *
- * @io_type: MEC_IO_READ or MEC_IO_WRITE, depending on request
- * @offset:  Base read / write address
- * @length:  Number of bytes to read / write
- * @buf:     Destination / source buffer
- *
- * @return 8-bit checksum of all bytes read / written
- */
-u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
-                           unsigned int offset, unsigned int length, u8 *buf);
-
-#endif /* __LINUX_MFD_CROS_EC_MEC_H */
diff --git a/include/linux/mfd/cros_ec_lpc_reg.h b/include/linux/mfd/cros_ec_lpc_reg.h
deleted file mode 100644 (file)
index 5560bef..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * cros_ec_lpc_reg - LPC access to the Chrome OS Embedded Controller
- *
- * Copyright (C) 2016 Google, Inc
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * This driver uses the Chrome OS EC byte-level message-based protocol for
- * communicating the keyboard state (which keys are pressed) from a keyboard EC
- * to the AP over some bus (such as i2c, lpc, spi).  The EC does debouncing,
- * but everything else (including deghosting) is done here.  The main
- * motivation for this is to keep the EC firmware as simple as possible, since
- * it cannot be easily upgraded and EC flash/IRAM space is relatively
- * expensive.
- */
-
-#ifndef __LINUX_MFD_CROS_EC_REG_H
-#define __LINUX_MFD_CROS_EC_REG_H
-
-/**
- * cros_ec_lpc_read_bytes - Read bytes from a given LPC-mapped address.
- * Returns 8-bit checksum of all bytes read.
- *
- * @offset: Base read address
- * @length: Number of bytes to read
- * @dest: Destination buffer
- */
-u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest);
-
-/**
- * cros_ec_lpc_write_bytes - Write bytes to a given LPC-mapped address.
- * Returns 8-bit checksum of all bytes written.
- *
- * @offset: Base write address
- * @length: Number of bytes to write
- * @msg: Write data buffer
- */
-u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, u8 *msg);
-
-/**
- * cros_ec_lpc_reg_init
- *
- * Initialize register I/O.
- */
-void cros_ec_lpc_reg_init(void);
-
-/**
- * cros_ec_lpc_reg_destroy
- *
- * Cleanup reg I/O.
- */
-void cros_ec_lpc_reg_destroy(void);
-
-#endif /* __LINUX_MFD_CROS_EC_REG_H */
index 1e52b8fd168593fb85356afedb07a29b66d95aac..fcf9cc9d535faf54c6b0fa463b6cf09643d0e5c4 100644 (file)
@@ -2163,7 +2163,7 @@ extern int __meminit __early_pfn_to_nid(unsigned long pfn,
                                        struct mminit_pfnnid_cache *state);
 #endif
 
-#if defined(CONFIG_HAVE_MEMBLOCK) && !defined(CONFIG_FLAT_NODE_MEM_MAP)
+#if !defined(CONFIG_FLAT_NODE_MEM_MAP)
 void zero_resv_unavail(void);
 #else
 static inline void zero_resv_unavail(void) {}
index 9f0caccd58332011e8b256abcfc14185e1e3fb35..847705a6d0ec2dba2a82ca87bba54c797bb0b956 100644 (file)
@@ -633,9 +633,6 @@ typedef struct pglist_data {
        struct page_ext *node_page_ext;
 #endif
 #endif
-#ifndef CONFIG_NO_BOOTMEM
-       struct bootmem_data *bdata;
-#endif
 #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT)
        /*
         * Must be held any time you expect node_start_pfn, node_present_pages
@@ -869,7 +866,7 @@ static inline int is_highmem_idx(enum zone_type idx)
 }
 
 /**
- * is_highmem - helper function to quickly check if a struct zone is a 
+ * is_highmem - helper function to quickly check if a struct zone is a
  *              highmem zone or not.  This is an attempt to keep references
  *              to ZONE_{DMA/NORMAL/HIGHMEM/etc} in general code to a minimum.
  * @zone - pointer to struct zone variable
index ab96025b238243ae3e8ebc4604749bceb744680b..a5aee3c438ade1e592411b875aa4bd0c064fdbc4 100644 (file)
@@ -388,6 +388,9 @@ extern int of_phandle_iterator_args(struct of_phandle_iterator *it,
 extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
 extern int of_alias_get_id(struct device_node *np, const char *stem);
 extern int of_alias_get_highest_id(const char *stem);
+extern int of_alias_get_alias_list(const struct of_device_id *matches,
+                                  const char *stem, unsigned long *bitmap,
+                                  unsigned int nbits);
 
 extern int of_machine_is_compatible(const char *compat);
 
@@ -898,6 +901,13 @@ static inline int of_alias_get_highest_id(const char *stem)
        return -ENOSYS;
 }
 
+static inline int of_alias_get_alias_list(const struct of_device_id *matches,
+                                         const char *stem, unsigned long *bitmap,
+                                         unsigned int nbits)
+{
+       return -ENOSYS;
+}
+
 static inline int of_machine_is_compatible(const char *compat)
 {
        return 0;
index 2d2096ba1cfeca2672b8c368cb49975985d67363..1ce8e264a2699876a468eeef460c8ac079d45788 100644 (file)
@@ -91,8 +91,7 @@
        extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name;            \
        __PCPU_DUMMY_ATTRS char __pcpu_unique_##name;                   \
        extern __PCPU_ATTRS(sec) __typeof__(type) name;                 \
-       __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES __weak                 \
-       __typeof__(type) name
+       __PCPU_ATTRS(sec) __weak __typeof__(type) name
 #else
 /*
  * Normal declaration and definition macros.
        extern __PCPU_ATTRS(sec) __typeof__(type) name
 
 #define DEFINE_PER_CPU_SECTION(type, name, sec)                                \
-       __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES                        \
-       __typeof__(type) name
+       __PCPU_ATTRS(sec) __typeof__(type) name
 #endif
 
 /*
index 8485c6a9a383203be7517fc39cbed734d1648927..6d07eebb3f75907efa50bf5fadd92dd568da8ec6 100644 (file)
 #ifndef __ASM_ARCH_OMAP_GPIO_H
 #define __ASM_ARCH_OMAP_GPIO_H
 
+#ifndef __ASSEMBLER__
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#endif
 
 #define OMAP1_MPUIO_BASE                       0xfffb5000
 
 #define OMAP_MPUIO(nr)         (OMAP_MAX_GPIO_LINES + (nr))
 #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES)
 
+#ifndef __ASSEMBLER__
 struct omap_gpio_reg_offs {
        u16 revision;
        u16 direction;
@@ -205,4 +208,6 @@ struct omap_gpio_platform_data {
        int (*get_context_loss_count)(struct device *dev);
 };
 
+#endif /* __ASSEMBLER__ */
+
 #endif
index 2efa3470a451b9d1d3fc3f082d0c59bcfd247c17..1ea3aab972b42c315bf41a6775739c393a441d94 100644 (file)
@@ -46,7 +46,6 @@ struct sysc_regbits {
        s8 emufree_shift;
 };
 
-#define SYSC_QUIRK_RESOURCE_PROVIDER   BIT(9)
 #define SYSC_QUIRK_LEGACY_IDLE         BIT(8)
 #define SYSC_QUIRK_RESET_STATUS                BIT(7)
 #define SYSC_QUIRK_NO_IDLE_ON_INIT     BIT(6)
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
new file mode 100644 (file)
index 0000000..53dfc25
--- /dev/null
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PLATFORM_DATA_X86_ASUS_WMI_H
+#define __PLATFORM_DATA_X86_ASUS_WMI_H
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+/* WMI Methods */
+#define ASUS_WMI_METHODID_SPEC         0x43455053 /* BIOS SPECification */
+#define ASUS_WMI_METHODID_SFBD         0x44424653 /* Set First Boot Device */
+#define ASUS_WMI_METHODID_GLCD         0x44434C47 /* Get LCD status */
+#define ASUS_WMI_METHODID_GPID         0x44495047 /* Get Panel ID?? (Resol) */
+#define ASUS_WMI_METHODID_QMOD         0x444F4D51 /* Quiet MODe */
+#define ASUS_WMI_METHODID_SPLV         0x4C425053 /* Set Panel Light Value */
+#define ASUS_WMI_METHODID_AGFN         0x4E464741 /* FaN? */
+#define ASUS_WMI_METHODID_SFUN         0x4E554653 /* FUNCtionalities */
+#define ASUS_WMI_METHODID_SDSP         0x50534453 /* Set DiSPlay output */
+#define ASUS_WMI_METHODID_GDSP         0x50534447 /* Get DiSPlay output */
+#define ASUS_WMI_METHODID_DEVP         0x50564544 /* DEVice Policy */
+#define ASUS_WMI_METHODID_OSVR         0x5256534F /* OS VeRsion */
+#define ASUS_WMI_METHODID_DSTS         0x53544344 /* Device STatuS */
+#define ASUS_WMI_METHODID_DSTS2                0x53545344 /* Device STatuS #2*/
+#define ASUS_WMI_METHODID_BSTS         0x53545342 /* Bios STatuS ? */
+#define ASUS_WMI_METHODID_DEVS         0x53564544 /* DEVice Set */
+#define ASUS_WMI_METHODID_CFVS         0x53564643 /* CPU Frequency Volt Set */
+#define ASUS_WMI_METHODID_KBFT         0x5446424B /* KeyBoard FilTer */
+#define ASUS_WMI_METHODID_INIT         0x54494E49 /* INITialize */
+#define ASUS_WMI_METHODID_HKEY         0x59454B48 /* Hot KEY ?? */
+
+#define ASUS_WMI_UNSUPPORTED_METHOD    0xFFFFFFFE
+
+/* Wireless */
+#define ASUS_WMI_DEVID_HW_SWITCH       0x00010001
+#define ASUS_WMI_DEVID_WIRELESS_LED    0x00010002
+#define ASUS_WMI_DEVID_CWAP            0x00010003
+#define ASUS_WMI_DEVID_WLAN            0x00010011
+#define ASUS_WMI_DEVID_WLAN_LED                0x00010012
+#define ASUS_WMI_DEVID_BLUETOOTH       0x00010013
+#define ASUS_WMI_DEVID_GPS             0x00010015
+#define ASUS_WMI_DEVID_WIMAX           0x00010017
+#define ASUS_WMI_DEVID_WWAN3G          0x00010019
+#define ASUS_WMI_DEVID_UWB             0x00010021
+
+/* Leds */
+/* 0x000200XX and 0x000400XX */
+#define ASUS_WMI_DEVID_LED1            0x00020011
+#define ASUS_WMI_DEVID_LED2            0x00020012
+#define ASUS_WMI_DEVID_LED3            0x00020013
+#define ASUS_WMI_DEVID_LED4            0x00020014
+#define ASUS_WMI_DEVID_LED5            0x00020015
+#define ASUS_WMI_DEVID_LED6            0x00020016
+
+/* Backlight and Brightness */
+#define ASUS_WMI_DEVID_ALS_ENABLE      0x00050001 /* Ambient Light Sensor */
+#define ASUS_WMI_DEVID_BACKLIGHT       0x00050011
+#define ASUS_WMI_DEVID_BRIGHTNESS      0x00050012
+#define ASUS_WMI_DEVID_KBD_BACKLIGHT   0x00050021
+#define ASUS_WMI_DEVID_LIGHT_SENSOR    0x00050022 /* ?? */
+#define ASUS_WMI_DEVID_LIGHTBAR                0x00050025
+
+/* Misc */
+#define ASUS_WMI_DEVID_CAMERA          0x00060013
+
+/* Storage */
+#define ASUS_WMI_DEVID_CARDREADER      0x00080013
+
+/* Input */
+#define ASUS_WMI_DEVID_TOUCHPAD                0x00100011
+#define ASUS_WMI_DEVID_TOUCHPAD_LED    0x00100012
+
+/* Fan, Thermal */
+#define ASUS_WMI_DEVID_THERMAL_CTRL    0x00110011
+#define ASUS_WMI_DEVID_FAN_CTRL                0x00110012
+
+/* Power */
+#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
+
+/* Deep S3 / Resume on LID open */
+#define ASUS_WMI_DEVID_LID_RESUME      0x00120031
+
+/* DSTS masks */
+#define ASUS_WMI_DSTS_STATUS_BIT       0x00000001
+#define ASUS_WMI_DSTS_UNKNOWN_BIT      0x00000002
+#define ASUS_WMI_DSTS_PRESENCE_BIT     0x00010000
+#define ASUS_WMI_DSTS_USER_BIT         0x00020000
+#define ASUS_WMI_DSTS_BIOS_BIT         0x00040000
+#define ASUS_WMI_DSTS_BRIGHTNESS_MASK  0x000000FF
+#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK  0x0000FF00
+#define ASUS_WMI_DSTS_LIGHTBAR_MASK    0x0000000F
+
+#if IS_REACHABLE(CONFIG_ASUS_WMI)
+int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
+#else
+static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
+                                          u32 *retval)
+{
+       return -ENODEV;
+}
+#endif
+
+#endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
index af8a61be2d8d500206687249f1e428c23dceb5fe..9510c677ac70f55eead3d8c9c3ddde4c2ca194e0 100644 (file)
@@ -51,8 +51,8 @@ extern void __rb_insert_augmented(struct rb_node *node,
  *
  * On insertion, the user must update the augmented information on the path
  * leading to the inserted node, then call rb_link_node() as usual and
- * rb_augment_inserted() instead of the usual rb_insert_color() call.
- * If rb_augment_inserted() rebalances the rbtree, it will callback into
+ * rb_insert_augmented() instead of the usual rb_insert_color() call.
+ * If rb_insert_augmented() rebalances the rbtree, it will callback into
  * a user provided function to update the augmented information on the
  * affected subtrees.
  */
index e3c5d856b6da52f367873271db0e436d5b371284..507a2b5242085f458da932f955020f9a53567267 100644 (file)
@@ -305,14 +305,22 @@ struct fw_rsc_vdev {
        struct fw_rsc_vdev_vring vring[0];
 } __packed;
 
+struct rproc;
+
 /**
  * struct rproc_mem_entry - memory entry descriptor
  * @va:        virtual address
  * @dma: dma address
  * @len: length, in bytes
  * @da: device address
+ * @release: release associated memory
  * @priv: associated data
+ * @name: associated memory region name (optional)
  * @node: list node
+ * @rsc_offset: offset in resource table
+ * @flags: iommu protection flags
+ * @of_resm_idx: reserved memory phandle index
+ * @alloc: specific memory allocator function
  */
 struct rproc_mem_entry {
        void *va;
@@ -320,10 +328,15 @@ struct rproc_mem_entry {
        int len;
        u32 da;
        void *priv;
+       char name[32];
        struct list_head node;
+       u32 rsc_offset;
+       u32 flags;
+       u32 of_resm_idx;
+       int (*alloc)(struct rproc *rproc, struct rproc_mem_entry *mem);
+       int (*release)(struct rproc *rproc, struct rproc_mem_entry *mem);
 };
 
-struct rproc;
 struct firmware;
 
 /**
@@ -399,6 +412,9 @@ enum rproc_crash_type {
  * @node:      list node related to the rproc segment list
  * @da:                device address of the segment
  * @size:      size of the segment
+ * @priv:      private data associated with the dump_segment
+ * @dump:      custom dump function to fill device memory segment associated
+ *             with coredump
  */
 struct rproc_dump_segment {
        struct list_head node;
@@ -406,6 +422,9 @@ struct rproc_dump_segment {
        dma_addr_t da;
        size_t size;
 
+       void *priv;
+       void (*dump)(struct rproc *rproc, struct rproc_dump_segment *segment,
+                    void *dest);
        loff_t offset;
 };
 
@@ -439,7 +458,9 @@ struct rproc_dump_segment {
  * @cached_table: copy of the resource table
  * @table_sz: size of @cached_table
  * @has_iommu: flag to indicate if remote processor is behind an MMU
+ * @auto_boot: flag to indicate if remote processor should be auto-started
  * @dump_segments: list of segments in the firmware
+ * @nb_vdev: number of vdev currently handled by rproc
  */
 struct rproc {
        struct list_head node;
@@ -472,6 +493,7 @@ struct rproc {
        bool has_iommu;
        bool auto_boot;
        struct list_head dump_segments;
+       int nb_vdev;
 };
 
 /**
@@ -499,7 +521,6 @@ struct rproc_subdev {
 /**
  * struct rproc_vring - remoteproc vring state
  * @va:        virtual address
- * @dma: dma address
  * @len: length, in bytes
  * @da: device address
  * @align: vring alignment
@@ -509,7 +530,6 @@ struct rproc_subdev {
  */
 struct rproc_vring {
        void *va;
-       dma_addr_t dma;
        int len;
        u32 da;
        u32 align;
@@ -528,6 +548,7 @@ struct rproc_vring {
  * @vdev: the virio device
  * @vring: the vrings for this vdev
  * @rsc_offset: offset of the vdev's resource entry
+ * @index: vdev position versus other vdev declared in resource table
  */
 struct rproc_vdev {
        struct kref refcount;
@@ -540,6 +561,7 @@ struct rproc_vdev {
        struct virtio_device vdev;
        struct rproc_vring vring[RVDEV_NUM_VRINGS];
        u32 rsc_offset;
+       u32 index;
 };
 
 struct rproc *rproc_get_by_phandle(phandle phandle);
@@ -553,10 +575,29 @@ int rproc_add(struct rproc *rproc);
 int rproc_del(struct rproc *rproc);
 void rproc_free(struct rproc *rproc);
 
+void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem);
+
+struct rproc_mem_entry *
+rproc_mem_entry_init(struct device *dev,
+                    void *va, dma_addr_t dma, int len, u32 da,
+                    int (*alloc)(struct rproc *, struct rproc_mem_entry *),
+                    int (*release)(struct rproc *, struct rproc_mem_entry *),
+                    const char *name, ...);
+
+struct rproc_mem_entry *
+rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, int len,
+                            u32 da, const char *name, ...);
+
 int rproc_boot(struct rproc *rproc);
 void rproc_shutdown(struct rproc *rproc);
 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
 int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size);
+int rproc_coredump_add_custom_segment(struct rproc *rproc,
+                                     dma_addr_t da, size_t size,
+                                     void (*dumpfn)(struct rproc *rproc,
+                                                    struct rproc_dump_segment *segment,
+                                                    void *dest),
+                                     void *priv);
 
 static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
 {
index 09732c36f3515a1e497dead9efe1df8297826486..29af6d6b2f4b8103b1afe509612b825d7a7994d9 100644 (file)
@@ -116,7 +116,7 @@ static inline int device_reset_optional(struct device *dev)
  * @id: reset line name
  *
  * Returns a struct reset_control or IS_ERR() condition containing errno.
- * If this function is called more then once for the same reset_control it will
+ * If this function is called more than once for the same reset_control it will
  * return -EBUSY.
  *
  * See reset_control_get_shared for details on shared references to
index 04f1321d14c49d9e5ce1e63f59a7b7224c83fcaa..f30954cc059dfd8e60870c1b4328949272947bf3 100644 (file)
@@ -20,7 +20,6 @@ extern unsigned long nr_running(void);
 extern bool single_task_running(void);
 extern unsigned long nr_iowait(void);
 extern unsigned long nr_iowait_cpu(int cpu);
-extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load);
 
 static inline int sched_info_on(void)
 {
index f4c9fc0fc7555a226a7607758b816b1c9486d5f6..3105055c00a7ee204adfe750432e5e474897812f 100644 (file)
@@ -91,6 +91,8 @@ struct scmi_clk_ops {
  *     to sustained performance level mapping
  * @freq_get: gets the frequency for a given device using sustained frequency
  *     to sustained performance level mapping
+ * @est_power_get: gets the estimated power cost for a given performance domain
+ *     at a given frequency
  */
 struct scmi_perf_ops {
        int (*limits_set)(const struct scmi_handle *handle, u32 domain,
@@ -110,6 +112,8 @@ struct scmi_perf_ops {
                        unsigned long rate, bool poll);
        int (*freq_get)(const struct scmi_handle *handle, u32 domain,
                        unsigned long *rate, bool poll);
+       int (*est_power_get)(const struct scmi_handle *handle, u32 domain,
+                            unsigned long *rate, unsigned long *power);
 };
 
 /**
index 406edae44ca3070151c36ed04a72c7dda2e24305..047fa67d039bedfc505f1c4be4574beb2db58ca5 100644 (file)
@@ -144,6 +144,8 @@ struct uart_port {
        void                    (*handle_break)(struct uart_port *);
        int                     (*rs485_config)(struct uart_port *,
                                                struct serial_rs485 *rs485);
+       int                     (*iso7816_config)(struct uart_port *,
+                                                 struct serial_iso7816 *iso7816);
        unsigned int            irq;                    /* irq number */
        unsigned long           irqflags;               /* irq flags  */
        unsigned int            uartclk;                /* base uart clock */
@@ -260,6 +262,7 @@ struct uart_port {
        struct attribute_group  *attr_group;            /* port specific attributes */
        const struct attribute_group **tty_groups;      /* all attributes (serial core use only) */
        struct serial_rs485     rs485;
+       struct serial_iso7816   iso7816;
        void                    *private_data;          /* generic platform data pointer */
 };
 
index 200ed96a05afea6b72781960fd11e2f4a0b62217..f428e86f480075fe0c2a8a71938616fdd6ee8dcc 100644 (file)
@@ -129,9 +129,11 @@ static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
                b3 = b->sig[3]; b2 = b->sig[2];                         \
                r->sig[3] = op(a3, b3);                                 \
                r->sig[2] = op(a2, b2);                                 \
+               /* fall through */                                      \
        case 2:                                                         \
                a1 = a->sig[1]; b1 = b->sig[1];                         \
                r->sig[1] = op(a1, b1);                                 \
+               /* fall through */                                      \
        case 1:                                                         \
                a0 = a->sig[0]; b0 = b->sig[0];                         \
                r->sig[0] = op(a0, b0);                                 \
@@ -161,7 +163,9 @@ static inline void name(sigset_t *set)                                      \
        switch (_NSIG_WORDS) {                                          \
        case 4: set->sig[3] = op(set->sig[3]);                          \
                set->sig[2] = op(set->sig[2]);                          \
+               /* fall through */                                      \
        case 2: set->sig[1] = op(set->sig[1]);                          \
+               /* fall through */                                      \
        case 1: set->sig[0] = op(set->sig[0]);                          \
                    break;                                              \
        default:                                                        \
@@ -182,6 +186,7 @@ static inline void sigemptyset(sigset_t *set)
                memset(set, 0, sizeof(sigset_t));
                break;
        case 2: set->sig[1] = 0;
+               /* fall through */
        case 1: set->sig[0] = 0;
                break;
        }
@@ -194,6 +199,7 @@ static inline void sigfillset(sigset_t *set)
                memset(set, -1, sizeof(sigset_t));
                break;
        case 2: set->sig[1] = -1;
+               /* fall through */
        case 1: set->sig[0] = -1;
                break;
        }
diff --git a/include/linux/soc/amlogic/meson-canvas.h b/include/linux/soc/amlogic/meson-canvas.h
new file mode 100644 (file)
index 0000000..b4dde2f
--- /dev/null
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ */
+#ifndef __SOC_MESON_CANVAS_H
+#define __SOC_MESON_CANVAS_H
+
+#include <linux/kernel.h>
+
+#define MESON_CANVAS_WRAP_NONE 0x00
+#define MESON_CANVAS_WRAP_X    0x01
+#define MESON_CANVAS_WRAP_Y    0x02
+
+#define MESON_CANVAS_BLKMODE_LINEAR    0x00
+#define MESON_CANVAS_BLKMODE_32x32     0x01
+#define MESON_CANVAS_BLKMODE_64x64     0x02
+
+#define MESON_CANVAS_ENDIAN_SWAP16     0x1
+#define MESON_CANVAS_ENDIAN_SWAP32     0x3
+#define MESON_CANVAS_ENDIAN_SWAP64     0x7
+#define MESON_CANVAS_ENDIAN_SWAP128    0xf
+
+struct meson_canvas;
+
+/**
+ * meson_canvas_get() - get a canvas provider instance
+ *
+ * @dev: consumer device pointer
+ */
+struct meson_canvas *meson_canvas_get(struct device *dev);
+
+/**
+ * meson_canvas_alloc() - take ownership of a canvas
+ *
+ * @canvas: canvas provider instance retrieved from meson_canvas_get()
+ * @canvas_index: will be filled with the canvas ID
+ */
+int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index);
+
+/**
+ * meson_canvas_free() - remove ownership from a canvas
+ *
+ * @canvas: canvas provider instance retrieved from meson_canvas_get()
+ * @canvas_index: canvas ID that was obtained via meson_canvas_alloc()
+ */
+int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index);
+
+/**
+ * meson_canvas_config() - configure a canvas
+ *
+ * @canvas: canvas provider instance retrieved from meson_canvas_get()
+ * @canvas_index: canvas ID that was obtained via meson_canvas_alloc()
+ * @addr: physical address to the pixel buffer
+ * @stride: width of the buffer
+ * @height: height of the buffer
+ * @wrap: undocumented
+ * @blkmode: block mode (linear, 32x32, 64x64)
+ * @endian: byte swapping (swap16, swap32, swap64, swap128)
+ */
+int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index,
+                       u32 addr, u32 stride, u32 height,
+                       unsigned int wrap, unsigned int blkmode,
+                       unsigned int endian);
+
+#endif
index 7e3b9c605ab2cd5b8c9a2a40d686826de96a3c56..69c285b1c9905496ff8b4f1d05c6b5221278075e 100644 (file)
@@ -70,25 +70,51 @@ struct llcc_slice_config {
 /**
  * llcc_drv_data - Data associated with the llcc driver
  * @regmap: regmap associated with the llcc device
+ * @bcast_regmap: regmap associated with llcc broadcast offset
  * @cfg: pointer to the data structure for slice configuration
  * @lock: mutex associated with each slice
  * @cfg_size: size of the config data table
  * @max_slices: max slices as read from device tree
- * @bcast_off: Offset of the broadcast bank
  * @num_banks: Number of llcc banks
  * @bitmap: Bit map to track the active slice ids
  * @offsets: Pointer to the bank offsets array
+ * @ecc_irq: interrupt for llcc cache error detection and reporting
  */
 struct llcc_drv_data {
        struct regmap *regmap;
+       struct regmap *bcast_regmap;
        const struct llcc_slice_config *cfg;
        struct mutex lock;
        u32 cfg_size;
        u32 max_slices;
-       u32 bcast_off;
        u32 num_banks;
        unsigned long *bitmap;
        u32 *offsets;
+       int ecc_irq;
+};
+
+/**
+ * llcc_edac_reg_data - llcc edac registers data for each error type
+ * @name: Name of the error
+ * @synd_reg: Syndrome register address
+ * @count_status_reg: Status register address to read the error count
+ * @ways_status_reg: Status register address to read the error ways
+ * @reg_cnt: Number of registers
+ * @count_mask: Mask value to get the error count
+ * @ways_mask: Mask value to get the error ways
+ * @count_shift: Shift value to get the error count
+ * @ways_shift: Shift value to get the error ways
+ */
+struct llcc_edac_reg_data {
+       char *name;
+       u64 synd_reg;
+       u64 count_status_reg;
+       u64 ways_status_reg;
+       u32 reg_cnt;
+       u32 count_mask;
+       u32 ways_mask;
+       u8  count_shift;
+       u8  ways_shift;
 };
 
 #if IS_ENABLED(CONFIG_QCOM_LLCC)
index 40d2822f0e2f1d1a6aa1a84e2ec820a8f9df392e..5a3e95017fc60968da060b318f97dde648f020b4 100644 (file)
@@ -67,7 +67,7 @@ struct cache_detail {
        struct module *         owner;
        int                     hash_size;
        struct hlist_head *     hash_table;
-       rwlock_t                hash_lock;
+       spinlock_t              hash_lock;
 
        char                    *name;
        void                    (*cache_put)(struct kref *);
@@ -168,8 +168,8 @@ extern const struct file_operations content_file_operations_pipefs;
 extern const struct file_operations cache_flush_operations_pipefs;
 
 extern struct cache_head *
-sunrpc_cache_lookup(struct cache_detail *detail,
-                   struct cache_head *key, int hash);
+sunrpc_cache_lookup_rcu(struct cache_detail *detail,
+                       struct cache_head *key, int hash);
 extern struct cache_head *
 sunrpc_cache_update(struct cache_detail *detail,
                    struct cache_head *new, struct cache_head *old, int hash);
@@ -186,6 +186,12 @@ static inline struct cache_head  *cache_get(struct cache_head *h)
        return h;
 }
 
+static inline struct cache_head  *cache_get_rcu(struct cache_head *h)
+{
+       if (kref_get_unless_zero(&h->ref))
+               return h;
+       return NULL;
+}
 
 static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
 {
@@ -224,9 +230,9 @@ extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
 extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *);
 
 /* Must store cache_detail in seq_file->private if using next three functions */
-extern void *cache_seq_start(struct seq_file *file, loff_t *pos);
-extern void *cache_seq_next(struct seq_file *file, void *p, loff_t *pos);
-extern void cache_seq_stop(struct seq_file *file, void *p);
+extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
+extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos);
+extern void cache_seq_stop_rcu(struct seq_file *file, void *p);
 
 extern void qword_add(char **bpp, int *lp, char *str);
 extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
index fd78f78df5c662b61430b93858bb5295fec45480..e6e26918504c1ee6644b52604bd25c223303a3ce 100644 (file)
@@ -113,13 +113,14 @@ struct svcxprt_rdma {
 /* sc_flags */
 #define RDMAXPRT_CONN_PENDING  3
 
-#define RPCRDMA_LISTEN_BACKLOG  10
-#define RPCRDMA_MAX_REQUESTS    32
-
-/* Typical ULP usage of BC requests is NFSv4.1 backchannel. Our
- * current NFSv4.1 implementation supports one backchannel slot.
+/*
+ * Default connection parameters
  */
-#define RPCRDMA_MAX_BC_REQUESTS        2
+enum {
+       RPCRDMA_LISTEN_BACKLOG  = 10,
+       RPCRDMA_MAX_REQUESTS    = 64,
+       RPCRDMA_MAX_BC_REQUESTS = 2,
+};
 
 #define RPCSVC_MAXPAYLOAD_RDMA RPCSVC_MAXPAYLOAD
 
index 04e404a0788222be04f12f84724a5595f52acfe4..3e53a6e2ada746e1ba7b3eaf2a34b39ad3f46194 100644 (file)
@@ -82,6 +82,7 @@ struct auth_domain {
        struct hlist_node       hash;
        char                    *name;
        struct auth_ops         *flavour;
+       struct rcu_head         rcu_head;
 };
 
 /*
index a2b3dfcee0b55d231d457ea24baa5e2080585569..6cfe05893a76b31280face250abc23e7ec9caaa6 100644 (file)
@@ -453,6 +453,79 @@ static inline int tee_shm_get_id(struct tee_shm *shm)
  */
 struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
 
+/**
+ * tee_client_open_context() - Open a TEE context
+ * @start:     if not NULL, continue search after this context
+ * @match:     function to check TEE device
+ * @data:      data for match function
+ * @vers:      if not NULL, version data of TEE device of the context returned
+ *
+ * This function does an operation similar to open("/dev/teeX") in user space.
+ * A returned context must be released with tee_client_close_context().
+ *
+ * Returns a TEE context of the first TEE device matched by the match()
+ * callback or an ERR_PTR.
+ */
+struct tee_context *
+tee_client_open_context(struct tee_context *start,
+                       int (*match)(struct tee_ioctl_version_data *,
+                                    const void *),
+                       const void *data, struct tee_ioctl_version_data *vers);
+
+/**
+ * tee_client_close_context() - Close a TEE context
+ * @ctx:       TEE context to close
+ *
+ * Note that all sessions previously opened with this context will be
+ * closed when this function is called.
+ */
+void tee_client_close_context(struct tee_context *ctx);
+
+/**
+ * tee_client_get_version() - Query version of TEE
+ * @ctx:       TEE context to TEE to query
+ * @vers:      Pointer to version data
+ */
+void tee_client_get_version(struct tee_context *ctx,
+                           struct tee_ioctl_version_data *vers);
+
+/**
+ * tee_client_open_session() - Open a session to a Trusted Application
+ * @ctx:       TEE context
+ * @arg:       Open session arguments, see description of
+ *             struct tee_ioctl_open_session_arg
+ * @param:     Parameters passed to the Trusted Application
+ *
+ * Returns < 0 on error else see @arg->ret for result. If @arg->ret
+ * is TEEC_SUCCESS the session identifier is available in @arg->session.
+ */
+int tee_client_open_session(struct tee_context *ctx,
+                           struct tee_ioctl_open_session_arg *arg,
+                           struct tee_param *param);
+
+/**
+ * tee_client_close_session() - Close a session to a Trusted Application
+ * @ctx:       TEE Context
+ * @session:   Session id
+ *
+ * Return < 0 on error else 0, regardless the session will not be
+ * valid after this function has returned.
+ */
+int tee_client_close_session(struct tee_context *ctx, u32 session);
+
+/**
+ * tee_client_invoke_func() - Invoke a function in a Trusted Application
+ * @ctx:       TEE Context
+ * @arg:       Invoke arguments, see description of
+ *             struct tee_ioctl_invoke_arg
+ * @param:     Parameters passed to the Trusted Application
+ *
+ * Returns < 0 on error else see @arg->ret for result.
+ */
+int tee_client_invoke_func(struct tee_context *ctx,
+                          struct tee_ioctl_invoke_arg *arg,
+                          struct tee_param *param);
+
 static inline bool tee_param_is_memref(struct tee_param *param)
 {
        switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
index 78a010e19ed41818796145cfe81f4d18f76f95e9..4130a5497d40523c0f01a52d1235edb31a3ee4f2 100644 (file)
@@ -575,7 +575,8 @@ extern int bpf_get_kprobe_info(const struct perf_event *event,
                               bool perf_type_tracepoint);
 #endif
 #ifdef CONFIG_UPROBE_EVENTS
-extern int  perf_uprobe_init(struct perf_event *event, bool is_retprobe);
+extern int  perf_uprobe_init(struct perf_event *event,
+                            unsigned long ref_ctr_offset, bool is_retprobe);
 extern void perf_uprobe_destroy(struct perf_event *event);
 extern int bpf_get_uprobe_info(const struct perf_event *event,
                               u32 *fd_type, const char **filename,
index bb9d2084af03a5d464abce0ad7c66ab59ed5cf9e..103a48a48872cfb16478408ebecafd37da063e37 100644 (file)
@@ -123,6 +123,7 @@ extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs);
 extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs);
 extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t);
 extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
+extern int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc);
 extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool);
 extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
 extern int uprobe_mmap(struct vm_area_struct *vma);
@@ -160,6 +161,10 @@ uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
 {
        return -ENOSYS;
 }
+static inline int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc)
+{
+       return -ENOSYS;
+}
 static inline int
 uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add)
 {
index ff9847f7f99d28f83af74d832b1a2d604ccb0657..3fe5e5d2bb7e50b67b98dbbceae5ab2521591b90 100644 (file)
@@ -63,7 +63,6 @@ struct cec_data {
        struct delayed_work work;
        struct completion c;
        u8 attempts;
-       bool new_initiator;
        bool blocking;
        bool completed;
 };
@@ -174,6 +173,7 @@ struct cec_adapter {
        bool is_configuring;
        bool is_configured;
        bool cec_pin_is_high;
+       u8 last_initiator;
        u32 monitor_all_cnt;
        u32 monitor_pin_cnt;
        u32 follower_cnt;
@@ -198,9 +198,7 @@ struct cec_adapter {
        u16 phys_addrs[15];
        u32 sequence;
 
-       char device_name[32];
        char input_phys[32];
-       char input_drv[32];
 };
 
 static inline void *cec_get_drvdata(const struct cec_adapter *adap)
@@ -332,67 +330,6 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
 u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
                           unsigned int *offset);
 
-/**
- * cec_set_edid_phys_addr() - find and set the physical address
- *
- * @edid:      pointer to the EDID data
- * @size:      size in bytes of the EDID data
- * @phys_addr: the new physical address
- *
- * This function finds the location of the physical address in the EDID
- * and fills in the given physical address and updates the checksum
- * at the end of the EDID block. It does nothing if the EDID doesn't
- * contain a physical address.
- */
-void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr);
-
-/**
- * cec_phys_addr_for_input() - calculate the PA for an input
- *
- * @phys_addr: the physical address of the parent
- * @input:     the number of the input port, must be between 1 and 15
- *
- * This function calculates a new physical address based on the input
- * port number. For example:
- *
- * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0
- *
- * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0
- *
- * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5
- *
- * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth.
- *
- * Return: the new physical address or CEC_PHYS_ADDR_INVALID.
- */
-u16 cec_phys_addr_for_input(u16 phys_addr, u8 input);
-
-/**
- * cec_phys_addr_validate() - validate a physical address from an EDID
- *
- * @phys_addr: the physical address to validate
- * @parent:    if not %NULL, then this is filled with the parents PA.
- * @port:      if not %NULL, then this is filled with the input port.
- *
- * This validates a physical address as read from an EDID. If the
- * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end),
- * then it will return -EINVAL.
- *
- * The parent PA is passed into %parent and the input port is passed into
- * %port. For example:
- *
- * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0.
- *
- * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1.
- *
- * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2.
- *
- * PA = f.f.f.f: has parent f.f.f.f and input port 0.
- *
- * Return: 0 if the PA is valid, -EINVAL if not.
- */
-int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
-
 #else
 
 static inline int cec_register_adapter(struct cec_adapter *adap,
@@ -427,25 +364,6 @@ static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
        return CEC_PHYS_ADDR_INVALID;
 }
 
-static inline void cec_set_edid_phys_addr(u8 *edid, unsigned int size,
-                                         u16 phys_addr)
-{
-}
-
-static inline u16 cec_phys_addr_for_input(u16 phys_addr, u8 input)
-{
-       return CEC_PHYS_ADDR_INVALID;
-}
-
-static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
-{
-       if (parent)
-               *parent = phys_addr;
-       if (port)
-               *port = 0;
-       return 0;
-}
-
 #endif
 
 /**
@@ -461,4 +379,74 @@ static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
        cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
 }
 
+/**
+ * cec_get_edid_spa_location() - find location of the Source Physical Address
+ *
+ * @edid: the EDID
+ * @size: the size of the EDID
+ *
+ * This EDID is expected to be a CEA-861 compliant, which means that there are
+ * at least two blocks and one or more of the extensions blocks are CEA-861
+ * blocks.
+ *
+ * The returned location is guaranteed to be <= size-2.
+ *
+ * This is an inline function since it is used by both CEC and V4L2.
+ * Ideally this would go in a module shared by both, but it is overkill to do
+ * that for just a single function.
+ */
+static inline unsigned int cec_get_edid_spa_location(const u8 *edid,
+                                                    unsigned int size)
+{
+       unsigned int blocks = size / 128;
+       unsigned int block;
+       u8 d;
+
+       /* Sanity check: at least 2 blocks and a multiple of the block size */
+       if (blocks < 2 || size % 128)
+               return 0;
+
+       /*
+        * If there are fewer extension blocks than the size, then update
+        * 'blocks'. It is allowed to have more extension blocks than the size,
+        * since some hardware can only read e.g. 256 bytes of the EDID, even
+        * though more blocks are present. The first CEA-861 extension block
+        * should normally be in block 1 anyway.
+        */
+       if (edid[0x7e] + 1 < blocks)
+               blocks = edid[0x7e] + 1;
+
+       for (block = 1; block < blocks; block++) {
+               unsigned int offset = block * 128;
+
+               /* Skip any non-CEA-861 extension blocks */
+               if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
+                       continue;
+
+               /* search Vendor Specific Data Block (tag 3) */
+               d = edid[offset + 2] & 0x7f;
+               /* Check if there are Data Blocks */
+               if (d <= 4)
+                       continue;
+               if (d > 4) {
+                       unsigned int i = offset + 4;
+                       unsigned int end = offset + d;
+
+                       /* Note: 'end' is always < 'size' */
+                       do {
+                               u8 tag = edid[i] >> 5;
+                               u8 len = edid[i] & 0x1f;
+
+                               if (tag == 3 && len >= 5 && i + len <= end &&
+                                   edid[i + 1] == 0x03 &&
+                                   edid[i + 2] == 0x0c &&
+                                   edid[i + 3] == 0x00)
+                                       return i + 4;
+                               i += len + 1;
+                       } while (i < end);
+               }
+       }
+       return 0;
+}
+
 #endif /* _MEDIA_CEC_H */
index bcc6ec434f1ff515df90d724efd71c22be724425..c8ddbfe8b74c28024e6c081894f9cd44234250bc 100644 (file)
@@ -27,6 +27,7 @@
 
 struct ida;
 struct device;
+struct media_device;
 
 /**
  * struct media_entity_notify - Media Entity Notify
@@ -50,10 +51,32 @@ struct media_entity_notify {
  * struct media_device_ops - Media device operations
  * @link_notify: Link state change notification callback. This callback is
  *              called with the graph_mutex held.
+ * @req_alloc: Allocate a request. Set this if you need to allocate a struct
+ *            larger then struct media_request. @req_alloc and @req_free must
+ *            either both be set or both be NULL.
+ * @req_free: Free a request. Set this if @req_alloc was set as well, leave
+ *           to NULL otherwise.
+ * @req_validate: Validate a request, but do not queue yet. The req_queue_mutex
+ *               lock is held when this op is called.
+ * @req_queue: Queue a validated request, cannot fail. If something goes
+ *            wrong when queueing this request then it should be marked
+ *            as such internally in the driver and any related buffers
+ *            must eventually return to vb2 with state VB2_BUF_STATE_ERROR.
+ *            The req_queue_mutex lock is held when this op is called.
+ *            It is important that vb2 buffer objects are queued last after
+ *            all other object types are queued: queueing a buffer kickstarts
+ *            the request processing, so all other objects related to the
+ *            request (and thus the buffer) must be available to the driver.
+ *            And once a buffer is queued, then the driver can complete
+ *            or delete objects from the request before req_queue exits.
  */
 struct media_device_ops {
        int (*link_notify)(struct media_link *link, u32 flags,
                           unsigned int notification);
+       struct media_request *(*req_alloc)(struct media_device *mdev);
+       void (*req_free)(struct media_request *req);
+       int (*req_validate)(struct media_request *req);
+       void (*req_queue)(struct media_request *req);
 };
 
 /**
@@ -88,6 +111,9 @@ struct media_device_ops {
  * @disable_source: Disable Source Handler function pointer
  *
  * @ops:       Operation handler callbacks
+ * @req_queue_mutex: Serialise the MEDIA_REQUEST_IOC_QUEUE ioctl w.r.t.
+ *                  other operations that stop or start streaming.
+ * @request_id: Used to generate unique request IDs
  *
  * This structure represents an abstract high-level media device. It allows easy
  * access to entities and provides basic media device-level support. The
@@ -158,6 +184,9 @@ struct media_device {
        void (*disable_source)(struct media_entity *entity);
 
        const struct media_device_ops *ops;
+
+       struct mutex req_queue_mutex;
+       atomic_t request_id;
 };
 
 /* We don't need to include pci.h or usb.h here */
index 3aa3d58d1d586dc2c0417bb8ecb76c7f7c19e2e8..e5f6960d92f6cdd49a84c5c2c36b9cfe59454409 100644 (file)
@@ -155,12 +155,41 @@ struct media_link {
        bool is_backlink;
 };
 
+/**
+ * enum media_pad_signal_type - type of the signal inside a media pad
+ *
+ * @PAD_SIGNAL_DEFAULT:
+ *     Default signal. Use this when all inputs or all outputs are
+ *     uniquely identified by the pad number.
+ * @PAD_SIGNAL_ANALOG:
+ *     The pad contains an analog signal. It can be Radio Frequency,
+ *     Intermediate Frequency, a baseband signal or sub-cariers.
+ *     Tuner inputs, IF-PLL demodulators, composite and s-video signals
+ *     should use it.
+ * @PAD_SIGNAL_DV:
+ *     Contains a digital video signal, with can be a bitstream of samples
+ *     taken from an analog TV video source. On such case, it usually
+ *     contains the VBI data on it.
+ * @PAD_SIGNAL_AUDIO:
+ *     Contains an Intermediate Frequency analog signal from an audio
+ *     sub-carrier or an audio bitstream. IF signals are provided by tuners
+ *     and consumed by audio AM/FM decoders. Bitstream audio is provided by
+ *     an audio decoder.
+ */
+enum media_pad_signal_type {
+       PAD_SIGNAL_DEFAULT = 0,
+       PAD_SIGNAL_ANALOG,
+       PAD_SIGNAL_DV,
+       PAD_SIGNAL_AUDIO,
+};
+
 /**
  * struct media_pad - A media pad graph object.
  *
  * @graph_obj: Embedded structure containing the media object common data
  * @entity:    Entity this pad belongs to
  * @index:     Pad index in the entity pads array, numbered from 0 to n
+ * @sig_type:  Type of the signal inside a media pad
  * @flags:     Pad flags, as defined in
  *             :ref:`include/uapi/linux/media.h <media_header>`
  *             (seek for ``MEDIA_PAD_FL_*``)
@@ -169,6 +198,7 @@ struct media_pad {
        struct media_gobj graph_obj;    /* must be first field in struct */
        struct media_entity *entity;
        u16 index;
+       enum media_pad_signal_type sig_type;
        unsigned long flags;
 };
 
@@ -640,6 +670,24 @@ static inline void media_entity_cleanup(struct media_entity *entity) {}
 #define media_entity_cleanup(entity) do { } while (false)
 #endif
 
+/**
+ * media_get_pad_index() - retrieves a pad index from an entity
+ *
+ * @entity:    entity where the pads belong
+ * @is_sink:   true if the pad is a sink, false if it is a source
+ * @sig_type:  type of signal of the pad to be search
+ *
+ * This helper function finds the first pad index inside an entity that
+ * satisfies both @is_sink and @sig_type conditions.
+ *
+ * Return:
+ *
+ * On success, return the pad number. If the pad was not found or the media
+ * entity is a NULL pointer, return -EINVAL.
+ */
+int media_get_pad_index(struct media_entity *entity, bool is_sink,
+                       enum media_pad_signal_type sig_type);
+
 /**
  * media_create_pad_link() - creates a link between two entities.
  *
diff --git a/include/media/media-request.h b/include/media/media-request.h
new file mode 100644 (file)
index 0000000..0ce75c3
--- /dev/null
@@ -0,0 +1,442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Media device request objects
+ *
+ * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Author: Hans Verkuil <hans.verkuil@cisco.com>
+ * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
+ */
+
+#ifndef MEDIA_REQUEST_H
+#define MEDIA_REQUEST_H
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/refcount.h>
+
+#include <media/media-device.h>
+
+/**
+ * enum media_request_state - media request state
+ *
+ * @MEDIA_REQUEST_STATE_IDLE:          Idle
+ * @MEDIA_REQUEST_STATE_VALIDATING:    Validating the request, no state changes
+ *                                     allowed
+ * @MEDIA_REQUEST_STATE_QUEUED:                Queued
+ * @MEDIA_REQUEST_STATE_COMPLETE:      Completed, the request is done
+ * @MEDIA_REQUEST_STATE_CLEANING:      Cleaning, the request is being re-inited
+ * @MEDIA_REQUEST_STATE_UPDATING:      The request is being updated, i.e.
+ *                                     request objects are being added,
+ *                                     modified or removed
+ * @NR_OF_MEDIA_REQUEST_STATE:         The number of media request states, used
+ *                                     internally for sanity check purposes
+ */
+enum media_request_state {
+       MEDIA_REQUEST_STATE_IDLE,
+       MEDIA_REQUEST_STATE_VALIDATING,
+       MEDIA_REQUEST_STATE_QUEUED,
+       MEDIA_REQUEST_STATE_COMPLETE,
+       MEDIA_REQUEST_STATE_CLEANING,
+       MEDIA_REQUEST_STATE_UPDATING,
+       NR_OF_MEDIA_REQUEST_STATE,
+};
+
+struct media_request_object;
+
+/**
+ * struct media_request - Media device request
+ * @mdev: Media device this request belongs to
+ * @kref: Reference count
+ * @debug_str: Prefix for debug messages (process name:fd)
+ * @state: The state of the request
+ * @updating_count: count the number of request updates that are in progress
+ * @access_count: count the number of request accesses that are in progress
+ * @objects: List of @struct media_request_object request objects
+ * @num_incomplete_objects: The number of incomplete objects in the request
+ * @poll_wait: Wait queue for poll
+ * @lock: Serializes access to this struct
+ */
+struct media_request {
+       struct media_device *mdev;
+       struct kref kref;
+       char debug_str[TASK_COMM_LEN + 11];
+       enum media_request_state state;
+       unsigned int updating_count;
+       unsigned int access_count;
+       struct list_head objects;
+       unsigned int num_incomplete_objects;
+       struct wait_queue_head poll_wait;
+       spinlock_t lock;
+};
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+
+/**
+ * media_request_lock_for_access - Lock the request to access its objects
+ *
+ * @req: The media request
+ *
+ * Use before accessing a completed request. A reference to the request must
+ * be held during the access. This usually takes place automatically through
+ * a file handle. Use @media_request_unlock_for_access when done.
+ */
+static inline int __must_check
+media_request_lock_for_access(struct media_request *req)
+{
+       unsigned long flags;
+       int ret = -EBUSY;
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (req->state == MEDIA_REQUEST_STATE_COMPLETE) {
+               req->access_count++;
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&req->lock, flags);
+
+       return ret;
+}
+
+/**
+ * media_request_unlock_for_access - Unlock a request previously locked for
+ *                                  access
+ *
+ * @req: The media request
+ *
+ * Unlock a request that has previously been locked using
+ * @media_request_lock_for_access.
+ */
+static inline void media_request_unlock_for_access(struct media_request *req)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (!WARN_ON(!req->access_count))
+               req->access_count--;
+       spin_unlock_irqrestore(&req->lock, flags);
+}
+
+/**
+ * media_request_lock_for_update - Lock the request for updating its objects
+ *
+ * @req: The media request
+ *
+ * Use before updating a request, i.e. adding, modifying or removing a request
+ * object in it. A reference to the request must be held during the update. This
+ * usually takes place automatically through a file handle. Use
+ * @media_request_unlock_for_update when done.
+ */
+static inline int __must_check
+media_request_lock_for_update(struct media_request *req)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&req->lock, flags);
+       if (req->state == MEDIA_REQUEST_STATE_IDLE ||
+           req->state == MEDIA_REQUEST_STATE_UPDATING) {
+               req->state = MEDIA_REQUEST_STATE_UPDATING;
+               req->updating_count++;
+       } else {
+               ret = -EBUSY;
+       }
+       spin_unlock_irqrestore(&req->lock, flags);
+
+       return ret;
+}
+
+/**
+ * media_request_unlock_for_update - Unlock a request previously locked for
+ *                                  update
+ *
+ * @req: The media request
+ *
+ * Unlock a request that has previously been locked using
+ * @media_request_lock_for_update.
+ */
+static inline void media_request_unlock_for_update(struct media_request *req)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&req->lock, flags);
+       WARN_ON(req->updating_count <= 0);
+       if (!--req->updating_count)
+               req->state = MEDIA_REQUEST_STATE_IDLE;
+       spin_unlock_irqrestore(&req->lock, flags);
+}
+
+/**
+ * media_request_get - Get the media request
+ *
+ * @req: The media request
+ *
+ * Get the media request.
+ */
+static inline void media_request_get(struct media_request *req)
+{
+       kref_get(&req->kref);
+}
+
+/**
+ * media_request_put - Put the media request
+ *
+ * @req: The media request
+ *
+ * Put the media request. The media request will be released
+ * when the refcount reaches 0.
+ */
+void media_request_put(struct media_request *req);
+
+/**
+ * media_request_get_by_fd - Get a media request by fd
+ *
+ * @mdev: Media device this request belongs to
+ * @request_fd: The file descriptor of the request
+ *
+ * Get the request represented by @request_fd that is owned
+ * by the media device.
+ *
+ * Return a -EACCES error pointer if requests are not supported
+ * by this driver. Return -EINVAL if the request was not found.
+ * Return the pointer to the request if found: the caller will
+ * have to call @media_request_put when it finished using the
+ * request.
+ */
+struct media_request *
+media_request_get_by_fd(struct media_device *mdev, int request_fd);
+
+/**
+ * media_request_alloc - Allocate the media request
+ *
+ * @mdev: Media device this request belongs to
+ * @alloc_fd: Store the request's file descriptor in this int
+ *
+ * Allocated the media request and put the fd in @alloc_fd.
+ */
+int media_request_alloc(struct media_device *mdev,
+                       int *alloc_fd);
+
+#else
+
+static inline void media_request_get(struct media_request *req)
+{
+}
+
+static inline void media_request_put(struct media_request *req)
+{
+}
+
+static inline struct media_request *
+media_request_get_by_fd(struct media_device *mdev, int request_fd)
+{
+       return ERR_PTR(-EACCES);
+}
+
+#endif
+
+/**
+ * struct media_request_object_ops - Media request object operations
+ * @prepare: Validate and prepare the request object, optional.
+ * @unprepare: Unprepare the request object, optional.
+ * @queue: Queue the request object, optional.
+ * @unbind: Unbind the request object, optional.
+ * @release: Release the request object, required.
+ */
+struct media_request_object_ops {
+       int (*prepare)(struct media_request_object *object);
+       void (*unprepare)(struct media_request_object *object);
+       void (*queue)(struct media_request_object *object);
+       void (*unbind)(struct media_request_object *object);
+       void (*release)(struct media_request_object *object);
+};
+
+/**
+ * struct media_request_object - An opaque object that belongs to a media
+ *                              request
+ *
+ * @ops: object's operations
+ * @priv: object's priv pointer
+ * @req: the request this object belongs to (can be NULL)
+ * @list: List entry of the object for @struct media_request
+ * @kref: Reference count of the object, acquire before releasing req->lock
+ * @completed: If true, then this object was completed.
+ *
+ * An object related to the request. This struct is always embedded in
+ * another struct that contains the actual data for this request object.
+ */
+struct media_request_object {
+       const struct media_request_object_ops *ops;
+       void *priv;
+       struct media_request *req;
+       struct list_head list;
+       struct kref kref;
+       bool completed;
+};
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+
+/**
+ * media_request_object_get - Get a media request object
+ *
+ * @obj: The object
+ *
+ * Get a media request object.
+ */
+static inline void media_request_object_get(struct media_request_object *obj)
+{
+       kref_get(&obj->kref);
+}
+
+/**
+ * media_request_object_put - Put a media request object
+ *
+ * @obj: The object
+ *
+ * Put a media request object. Once all references are gone, the
+ * object's memory is released.
+ */
+void media_request_object_put(struct media_request_object *obj);
+
+/**
+ * media_request_object_find - Find an object in a request
+ *
+ * @req: The media request
+ * @ops: Find an object with this ops value
+ * @priv: Find an object with this priv value
+ *
+ * Both @ops and @priv must be non-NULL.
+ *
+ * Returns the object pointer or NULL if not found. The caller must
+ * call media_request_object_put() once it finished using the object.
+ *
+ * Since this function needs to walk the list of objects it takes
+ * the @req->lock spin lock to make this safe.
+ */
+struct media_request_object *
+media_request_object_find(struct media_request *req,
+                         const struct media_request_object_ops *ops,
+                         void *priv);
+
+/**
+ * media_request_object_init - Initialise a media request object
+ *
+ * @obj: The object
+ *
+ * Initialise a media request object. The object will be released using the
+ * release callback of the ops once it has no references (this function
+ * initialises references to one).
+ */
+void media_request_object_init(struct media_request_object *obj);
+
+/**
+ * media_request_object_bind - Bind a media request object to a request
+ *
+ * @req: The media request
+ * @ops: The object ops for this object
+ * @priv: A driver-specific priv pointer associated with this object
+ * @is_buffer: Set to true if the object a buffer object.
+ * @obj: The object
+ *
+ * Bind this object to the request and set the ops and priv values of
+ * the object so it can be found later with media_request_object_find().
+ *
+ * Every bound object must be unbound or completed by the kernel at some
+ * point in time, otherwise the request will never complete. When the
+ * request is released all completed objects will be unbound by the
+ * request core code.
+ *
+ * Buffer objects will be added to the end of the request's object
+ * list, non-buffer objects will be added to the front of the list.
+ * This ensures that all buffer objects are at the end of the list
+ * and that all non-buffer objects that they depend on are processed
+ * first.
+ */
+int media_request_object_bind(struct media_request *req,
+                             const struct media_request_object_ops *ops,
+                             void *priv, bool is_buffer,
+                             struct media_request_object *obj);
+
+/**
+ * media_request_object_unbind - Unbind a media request object
+ *
+ * @obj: The object
+ *
+ * Unbind the media request object from the request.
+ */
+void media_request_object_unbind(struct media_request_object *obj);
+
+/**
+ * media_request_object_complete - Mark the media request object as complete
+ *
+ * @obj: The object
+ *
+ * Mark the media request object as complete. Only bound objects can
+ * be completed.
+ */
+void media_request_object_complete(struct media_request_object *obj);
+
+#else
+
+static inline int __must_check
+media_request_lock_for_access(struct media_request *req)
+{
+       return -EINVAL;
+}
+
+static inline void media_request_unlock_for_access(struct media_request *req)
+{
+}
+
+static inline int __must_check
+media_request_lock_for_update(struct media_request *req)
+{
+       return -EINVAL;
+}
+
+static inline void media_request_unlock_for_update(struct media_request *req)
+{
+}
+
+static inline void media_request_object_get(struct media_request_object *obj)
+{
+}
+
+static inline void media_request_object_put(struct media_request_object *obj)
+{
+}
+
+static inline struct media_request_object *
+media_request_object_find(struct media_request *req,
+                         const struct media_request_object_ops *ops,
+                         void *priv)
+{
+       return NULL;
+}
+
+static inline void media_request_object_init(struct media_request_object *obj)
+{
+       obj->ops = NULL;
+       obj->req = NULL;
+}
+
+static inline int media_request_object_bind(struct media_request *req,
+                              const struct media_request_object_ops *ops,
+                              void *priv, bool is_buffer,
+                              struct media_request_object *obj)
+{
+       return 0;
+}
+
+static inline void media_request_object_unbind(struct media_request_object *obj)
+{
+}
+
+static inline void media_request_object_complete(struct media_request_object *obj)
+{
+}
+
+#endif
+
+#endif
index 61571773a98d072f539bebd82ec2351953d6d2d6..c0cfbe16a8546ebffaaf45fd35c358905231d92a 100644 (file)
@@ -317,13 +317,6 @@ struct ir_raw_event {
        unsigned                carrier_report:1;
 };
 
-#define DEFINE_IR_RAW_EVENT(event) struct ir_raw_event event = {}
-
-static inline void init_ir_raw_event(struct ir_raw_event *ev)
-{
-       memset(ev, 0, sizeof(*ev));
-}
-
 #define IR_DEFAULT_TIMEOUT     MS_TO_NS(125)
 #define IR_MAX_DURATION         500000000      /* 500 ms */
 #define US_TO_NS(usec)         ((usec) * 1000)
@@ -344,9 +337,7 @@ int ir_raw_encode_carrier(enum rc_proto protocol);
 
 static inline void ir_raw_event_reset(struct rc_dev *dev)
 {
-       struct ir_raw_event ev = { .reset = true };
-
-       ir_raw_event_store(dev, &ev);
+       ir_raw_event_store(dev, &((struct ir_raw_event) { .reset = true }));
        dev->idle = true;
        ir_raw_event_handle(dev);
 }
index b60a7b176c371a931ea2c91cfb9797c97e906fcd..179240fb163bd2e7cc347e559f99bae943bf0e34 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * rcar-fcp.h  --  R-Car Frame Compression Processor Driver
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __MEDIA_RCAR_FCP_H__
 #define __MEDIA_RCAR_FCP_H__
index 1592d323c577d7125c1cf851b668a170112f753d..1497bda66c3b65d62e3a5b8dd74a4b805b9d56f7 100644 (file)
@@ -20,9 +20,6 @@ struct v4l2_device;
 struct v4l2_subdev;
 struct v4l2_async_notifier;
 
-/* A random max subdevice number, used to allocate an array on stack */
-#define V4L2_MAX_SUBDEVS 128U
-
 /**
  * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used
  *     in order to identify a match
@@ -73,6 +70,8 @@ enum v4l2_async_match_type {
  * @match.custom.priv:
  *             Driver-specific private struct with match parameters
  *             to be used if %V4L2_ASYNC_MATCH_CUSTOM.
+ * @asd_list:  used to add struct v4l2_async_subdev objects to the
+ *             master notifier @asd_list
  * @list:      used to link struct v4l2_async_subdev objects, waiting to be
  *             probed, to a notifier->waiting list
  *
@@ -90,14 +89,15 @@ struct v4l2_async_subdev {
                        unsigned short address;
                } i2c;
                struct {
-                       bool (*match)(struct device *,
-                                     struct v4l2_async_subdev *);
+                       bool (*match)(struct device *dev,
+                                     struct v4l2_async_subdev *sd);
                        void *priv;
                } custom;
        } match;
 
        /* v4l2-async core private: not to be used by drivers */
        struct list_head list;
+       struct list_head asd_list;
 };
 
 /**
@@ -121,29 +121,107 @@ struct v4l2_async_notifier_operations {
  * struct v4l2_async_notifier - v4l2_device notifier data
  *
  * @ops:       notifier operations
- * @num_subdevs: number of subdevices used in the subdevs array
- * @max_subdevs: number of subdevices allocated in the subdevs array
- * @subdevs:   array of pointers to subdevice descriptors
  * @v4l2_dev:  v4l2_device of the root notifier, NULL otherwise
  * @sd:                sub-device that registered the notifier, NULL otherwise
  * @parent:    parent notifier
+ * @asd_list:  master list of struct v4l2_async_subdev
  * @waiting:   list of struct v4l2_async_subdev, waiting for their drivers
  * @done:      list of struct v4l2_subdev, already probed
  * @list:      member in a global list of notifiers
  */
 struct v4l2_async_notifier {
        const struct v4l2_async_notifier_operations *ops;
-       unsigned int num_subdevs;
-       unsigned int max_subdevs;
-       struct v4l2_async_subdev **subdevs;
        struct v4l2_device *v4l2_dev;
        struct v4l2_subdev *sd;
        struct v4l2_async_notifier *parent;
+       struct list_head asd_list;
        struct list_head waiting;
        struct list_head done;
        struct list_head list;
 };
 
+/**
+ * v4l2_async_notifier_init - Initialize a notifier.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ *
+ * This function initializes the notifier @asd_list. It must be called
+ * before the first call to @v4l2_async_notifier_add_subdev.
+ */
+void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_notifier_add_subdev - Add an async subdev to the
+ *                             notifier's master asd list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @asd: pointer to &struct v4l2_async_subdev
+ *
+ * Call this function before registering a notifier to link the
+ * provided asd to the notifiers master @asd_list.
+ */
+int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+                                  struct v4l2_async_subdev *asd);
+
+/**
+ * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async
+ *                             subdev to the notifier's master asd_list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @fwnode: fwnode handle of the sub-device to be matched
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ *
+ * Allocate a fwnode-matched asd of size asd_struct_size, and add it
+ * to the notifiers @asd_list.
+ */
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+                                     struct fwnode_handle *fwnode,
+                                     unsigned int asd_struct_size);
+
+/**
+ * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async
+ *                             subdev to the notifier's master asd_list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @adapter_id: I2C adapter ID to be matched
+ * @address: I2C address of sub-device to be matched
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ *
+ * Same as above but for I2C matched sub-devices.
+ */
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+                                  int adapter_id, unsigned short address,
+                                  unsigned int asd_struct_size);
+
+/**
+ * v4l2_async_notifier_add_devname_subdev - Allocate and add a device-name
+ *                             async subdev to the notifier's master asd_list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @device_name: device name string to be matched
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ *
+ * Same as above but for device-name matched sub-devices.
+ */
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier,
+                                      const char *device_name,
+                                      unsigned int asd_struct_size);
+
 /**
  * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
  *
@@ -164,7 +242,8 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
                                        struct v4l2_async_notifier *notifier);
 
 /**
- * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier
+ * v4l2_async_notifier_unregister - unregisters a subdevice
+ *     asynchronous notifier
  *
  * @notifier: pointer to &struct v4l2_async_notifier
  */
@@ -177,7 +256,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
  * Release memory resources related to a notifier, including the async
  * sub-devices allocated for the purposes of the notifier but not the notifier
  * itself. The user is responsible for calling this function to clean up the
- * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
+ * notifier after calling
+ * @v4l2_async_notifier_add_subdev,
+ * @v4l2_async_notifier_parse_fwnode_endpoints or
  * @v4l2_fwnode_reference_parse_sensor_common.
  *
  * There is no harm from calling v4l2_async_notifier_cleanup in other
@@ -213,8 +294,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);
  * An error is returned if the module is no longer loaded on any attempts
  * to register it.
  */
-int __must_check v4l2_async_register_subdev_sensor_common(
-       struct v4l2_subdev *sd);
+int __must_check
+v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd);
 
 /**
  * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
index cdc87ec61e54c85614576d99be71641e6c55f969..82715645617b8e563dc7a22cb0a9349f5909c011 100644 (file)
@@ -154,6 +154,18 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
                struct i2c_adapter *adapter, struct i2c_board_info *info,
                const unsigned short *probe_addrs);
 
+/**
+ * v4l2_i2c_subdev_set_name - Set name for an I²C sub-device
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @client: pointer to struct i2c_client
+ * @devname: the name of the device; if NULL, the I²C device's name will be used
+ * @postfix: sub-device specific string to put right after the I²C device name;
+ *          may be NULL
+ */
+void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
+                             const char *devname, const char *postfix);
+
 /**
  * v4l2_i2c_subdev_init - Initializes a &struct v4l2_subdev with data from
  *     an i2c_client struct.
@@ -283,7 +295,7 @@ struct v4l2_priv_tun_config {
  * @height:    pointer to height that will be adjusted if needed.
  * @hmin:      minimum height.
  * @hmax:      maximum height.
- * @halign:    least significant bit on width.
+ * @halign:    least significant bit on height.
  * @salign:    least significant bit for the image size (e. g.
  *             :math:`width * height`).
  *
index f615ba1b29dd9dedb18bede9d4e91e0633a603b5..83ce0593b275c7462ff787a98156d59d6f6833e0 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
+#include <media/media-request.h>
 
 /* forward references */
 struct file;
@@ -34,13 +35,15 @@ struct poll_table_struct;
 
 /**
  * union v4l2_ctrl_ptr - A pointer to a control value.
- * @p_s32:     Pointer to a 32-bit signed value.
- * @p_s64:     Pointer to a 64-bit signed value.
- * @p_u8:      Pointer to a 8-bit unsigned value.
- * @p_u16:     Pointer to a 16-bit unsigned value.
- * @p_u32:     Pointer to a 32-bit unsigned value.
- * @p_char:    Pointer to a string.
- * @p:         Pointer to a compound value.
+ * @p_s32:                     Pointer to a 32-bit signed value.
+ * @p_s64:                     Pointer to a 64-bit signed value.
+ * @p_u8:                      Pointer to a 8-bit unsigned value.
+ * @p_u16:                     Pointer to a 16-bit unsigned value.
+ * @p_u32:                     Pointer to a 32-bit unsigned value.
+ * @p_char:                    Pointer to a string.
+ * @p_mpeg2_slice_params:      Pointer to a MPEG2 slice parameters structure.
+ * @p_mpeg2_quantization:      Pointer to a MPEG2 quantization data structure.
+ * @p:                         Pointer to a compound value.
  */
 union v4l2_ctrl_ptr {
        s32 *p_s32;
@@ -49,6 +52,8 @@ union v4l2_ctrl_ptr {
        u16 *p_u16;
        u32 *p_u32;
        char *p_char;
+       struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
+       struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
        void *p;
 };
 
@@ -247,6 +252,19 @@ struct v4l2_ctrl {
  * @ctrl:      The actual control information.
  * @helper:    Pointer to helper struct. Used internally in
  *             ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``.
+ * @from_other_dev: If true, then @ctrl was defined in another
+ *             device than the &struct v4l2_ctrl_handler.
+ * @req_done:  Internal flag: if the control handler containing this control
+ *             reference is bound to a media request, then this is set when
+ *             the control has been applied. This prevents applying controls
+ *             from a cluster with multiple controls twice (when the first
+ *             control of a cluster is applied, they all are).
+ * @req:       If set, this refers to another request that sets this control.
+ * @p_req:     If the control handler containing this control reference
+ *             is bound to a media request, then this points to the
+ *             value of the control that should be applied when the request
+ *             is executed, or to the value of the control at the time
+ *             that the request was completed.
  *
  * Each control handler has a list of these refs. The list_head is used to
  * keep a sorted-by-control-ID list of all controls, while the next pointer
@@ -257,6 +275,10 @@ struct v4l2_ctrl_ref {
        struct v4l2_ctrl_ref *next;
        struct v4l2_ctrl *ctrl;
        struct v4l2_ctrl_helper *helper;
+       bool from_other_dev;
+       bool req_done;
+       struct v4l2_ctrl_ref *req;
+       union v4l2_ctrl_ptr p_req;
 };
 
 /**
@@ -280,6 +302,17 @@ struct v4l2_ctrl_ref {
  * @notify_priv: Passed as argument to the v4l2_ctrl notify callback.
  * @nr_of_buckets: Total number of buckets in the array.
  * @error:     The error code of the first failed control addition.
+ * @request_is_queued: True if the request was queued.
+ * @requests:  List to keep track of open control handler request objects.
+ *             For the parent control handler (@req_obj.req == NULL) this
+ *             is the list header. When the parent control handler is
+ *             removed, it has to unbind and put all these requests since
+ *             they refer to the parent.
+ * @requests_queued: List of the queued requests. This determines the order
+ *             in which these controls are applied. Once the request is
+ *             completed it is removed from this list.
+ * @req_obj:   The &struct media_request_object, used to link into a
+ *             &struct media_request. This request object has a refcount.
  */
 struct v4l2_ctrl_handler {
        struct mutex _lock;
@@ -292,6 +325,10 @@ struct v4l2_ctrl_handler {
        void *notify_priv;
        u16 nr_of_buckets;
        int error;
+       bool request_is_queued;
+       struct list_head requests;
+       struct list_head requests_queued;
+       struct media_request_object req_obj;
 };
 
 /**
@@ -633,6 +670,8 @@ typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl);
  * @add:       The control handler whose controls you want to add to
  *             the @hdl control handler.
  * @filter:    This function will filter which controls should be added.
+ * @from_other_dev: If true, then the controls in @add were defined in another
+ *             device than @hdl.
  *
  * Does nothing if either of the two handlers is a NULL pointer.
  * If @filter is NULL, then all controls are added. Otherwise only those
@@ -642,7 +681,8 @@ typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl);
  */
 int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
                          struct v4l2_ctrl_handler *add,
-                         v4l2_ctrl_filter filter);
+                         v4l2_ctrl_filter filter,
+                         bool from_other_dev);
 
 /**
  * v4l2_ctrl_radio_filter() - Standard filter for radio controls.
@@ -728,6 +768,22 @@ struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id);
  */
 void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
 
+/**
+ * __v4l2_ctrl_grab() - Unlocked variant of v4l2_ctrl_grab.
+ *
+ * @ctrl:      The control to (de)activate.
+ * @grabbed:   True if the control should become grabbed.
+ *
+ * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically.
+ * Does nothing if @ctrl == NULL.
+ * The V4L2_EVENT_CTRL event will be generated afterwards.
+ * This will usually be called when starting or stopping streaming in the
+ * driver.
+ *
+ * This function assumes that the control handler is locked by the caller.
+ */
+void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
+
 /**
  * v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed.
  *
@@ -743,7 +799,15 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
  * This function assumes that the control handler is not locked and will
  * take the lock itself.
  */
-void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
+static inline void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
+{
+       if (!ctrl)
+               return;
+
+       v4l2_ctrl_lock(ctrl);
+       __v4l2_ctrl_grab(ctrl, grabbed);
+       v4l2_ctrl_unlock(ctrl);
+}
 
 /**
  *__v4l2_ctrl_modify_range() - Unlocked variant of v4l2_ctrl_modify_range()
@@ -1046,6 +1110,84 @@ int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
  */
 __poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait);
 
+/**
+ * v4l2_ctrl_request_setup - helper function to apply control values in a request
+ *
+ * @req: The request
+ * @parent: The parent control handler ('priv' in media_request_object_find())
+ *
+ * This is a helper function to call the control handler's s_ctrl callback with
+ * the control values contained in the request. Do note that this approach of
+ * applying control values in a request is only applicable to memory-to-memory
+ * devices.
+ */
+void v4l2_ctrl_request_setup(struct media_request *req,
+                            struct v4l2_ctrl_handler *parent);
+
+/**
+ * v4l2_ctrl_request_complete - Complete a control handler request object
+ *
+ * @req: The request
+ * @parent: The parent control handler ('priv' in media_request_object_find())
+ *
+ * This function is to be called on each control handler that may have had a
+ * request object associated with it, i.e. control handlers of a driver that
+ * supports requests.
+ *
+ * The function first obtains the values of any volatile controls in the control
+ * handler and attach them to the request. Then, the function completes the
+ * request object.
+ */
+void v4l2_ctrl_request_complete(struct media_request *req,
+                               struct v4l2_ctrl_handler *parent);
+
+/**
+ * v4l2_ctrl_request_hdl_find - Find the control handler in the request
+ *
+ * @req: The request
+ * @parent: The parent control handler ('priv' in media_request_object_find())
+ *
+ * This function finds the control handler in the request. It may return
+ * NULL if not found. When done, you must call v4l2_ctrl_request_put_hdl()
+ * with the returned handler pointer.
+ *
+ * If the request is not in state VALIDATING or QUEUED, then this function
+ * will always return NULL.
+ *
+ * Note that in state VALIDATING the req_queue_mutex is held, so
+ * no objects can be added or deleted from the request.
+ *
+ * In state QUEUED it is the driver that will have to ensure this.
+ */
+struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req,
+                                       struct v4l2_ctrl_handler *parent);
+
+/**
+ * v4l2_ctrl_request_hdl_put - Put the control handler
+ *
+ * @hdl: Put this control handler
+ *
+ * This function released the control handler previously obtained from'
+ * v4l2_ctrl_request_hdl_find().
+ */
+static inline void v4l2_ctrl_request_hdl_put(struct v4l2_ctrl_handler *hdl)
+{
+       if (hdl)
+               media_request_object_put(&hdl->req_obj);
+}
+
+/**
+ * v4l2_ctrl_request_ctrl_find() - Find a control with the given ID.
+ *
+ * @hdl: The control handler from the request.
+ * @id: The ID of the control to find.
+ *
+ * This function returns a pointer to the control if this control is
+ * part of the request or NULL otherwise.
+ */
+struct v4l2_ctrl *
+v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id);
+
 /* Helpers for ioctl_ops */
 
 /**
@@ -1112,11 +1254,12 @@ int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
  *     :ref:`VIDIOC_G_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
  *
  * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @mdev: pointer to &struct media_device
  * @c: pointer to &struct v4l2_ext_controls
  *
  * If hdl == NULL then they will all return -EINVAL.
  */
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
                     struct v4l2_ext_controls *c);
 
 /**
@@ -1124,11 +1267,13 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl,
  *     :ref:`VIDIOC_TRY_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
  *
  * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @mdev: pointer to &struct media_device
  * @c: pointer to &struct v4l2_ext_controls
  *
  * If hdl == NULL then they will all return -EINVAL.
  */
 int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+                      struct media_device *mdev,
                       struct v4l2_ext_controls *c);
 
 /**
@@ -1137,11 +1282,13 @@ int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
  *
  * @fh: pointer to &struct v4l2_fh
  * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @mdev: pointer to &struct media_device
  * @c: pointer to &struct v4l2_ext_controls
  *
  * If hdl == NULL then they will all return -EINVAL.
  */
 int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+                    struct media_device *mdev,
                     struct v4l2_ext_controls *c);
 
 /**
index b330e4a08a6b805e6613dc626ae4e569d3b89b1f..ac7677a183ff2ffce02c5676bbc332ae57ab03dc 100644 (file)
@@ -211,6 +211,17 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
                sd->v4l2_dev->notify(sd, notification, arg);
 }
 
+/**
+ * v4l2_device_supports_requests - Test if requests are supported.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ */
+static inline bool v4l2_device_supports_requests(struct v4l2_device *v4l2_dev)
+{
+       return v4l2_dev->mdev && v4l2_dev->mdev->ops &&
+              v4l2_dev->mdev->ops->req_queue;
+}
+
 /* Helper macros to iterate over all subdevs. */
 
 /**
index 17cb27df1b813412146c7503c3429de0224c99d2..2cc0cabc124fc9f5a5425a511a5d80c9fe8849a6 100644 (file)
 
 #include <linux/videodev2.h>
 
+/**
+ * v4l2_calc_timeperframe - helper function to calculate timeperframe based
+ *     v4l2_dv_timings fields.
+ * @t: Timings for the video mode.
+ *
+ * Calculates the expected timeperframe using the pixel clock value and
+ * horizontal/vertical measures. This means that v4l2_dv_timings structure
+ * must be correctly and fully filled.
+ */
+struct v4l2_fract v4l2_calc_timeperframe(const struct v4l2_dv_timings *t);
+
 /*
  * v4l2_dv_timings_presets: list of all dv_timings presets.
  */
@@ -234,4 +245,10 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
                         const struct hdmi_vendor_infoframe *hdmi,
                         unsigned int height);
 
+u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size,
+                           unsigned int *offset);
+void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr);
+u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input);
+int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
+
 #endif
index 9cccab618b98e19b0976d355c2f524ceb0a9da47..6d9d9f1839ac3f37c77d3429f5b8b66b70a47c0a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 
 #include <media/v4l2-mediabus.h>
+#include <media/v4l2-subdev.h>
 
 struct fwnode_handle;
 struct v4l2_async_notifier;
@@ -70,8 +71,8 @@ struct v4l2_fwnode_bus_parallel {
  * @clock_lane: the number of the clock lane
  */
 struct v4l2_fwnode_bus_mipi_csi1 {
-       bool clock_inv;
-       bool strobe;
+       unsigned char clock_inv:1;
+       unsigned char strobe:1;
        bool lane_polarity[2];
        unsigned char data_lane;
        unsigned char clock_lane;
@@ -130,19 +131,30 @@ struct v4l2_fwnode_link {
  * @fwnode: pointer to the endpoint's fwnode handle
  * @vep: pointer to the V4L2 fwnode data structure
  *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
+ * This function parses the V4L2 fwnode endpoint specific parameters from the
+ * firmware. The caller is responsible for assigning @vep.bus_type to a valid
+ * media bus type. The caller may also set the default configuration for the
+ * endpoint --- a configuration that shall be in line with the DT binding
+ * documentation. Should a device support multiple bus types, the caller may
+ * call this function once the correct type is found --- with a default
+ * configuration valid for that type.
+ *
+ * As a compatibility means guessing the bus type is also supported by setting
+ * @vep.bus_type to V4L2_MBUS_UNKNOWN. The caller may not provide a default
+ * configuration in this case as the defaults are specific to a given bus type.
+ * This functionality is deprecated and should not be used in new drivers and it
+ * is only supported for CSI-2 D-PHY, parallel and Bt.656 busses.
+ *
+ * The function does not change the V4L2 fwnode endpoint state if it fails.
  *
  * NOTE: This function does not parse properties the size of which is variable
  * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in
  * new drivers instead.
  *
- * Return: 0 on success or a negative error code on failure.
+ * Return: %0 on success or a negative error code on failure:
+ *        %-ENOMEM on memory allocation failure
+ *        %-EINVAL on parsing failure
+ *        %-ENXIO on mismatching bus types
  */
 int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
                               struct v4l2_fwnode_endpoint *vep);
@@ -160,14 +172,23 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep);
 /**
  * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
  * @fwnode: pointer to the endpoint's fwnode handle
+ * @vep: pointer to the V4L2 fwnode data structure
  *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
+ * This function parses the V4L2 fwnode endpoint specific parameters from the
+ * firmware. The caller is responsible for assigning @vep.bus_type to a valid
+ * media bus type. The caller may also set the default configuration for the
+ * endpoint --- a configuration that shall be in line with the DT binding
+ * documentation. Should a device support multiple bus types, the caller may
+ * call this function once the correct type is found --- with a default
+ * configuration valid for that type.
+ *
+ * As a compatibility means guessing the bus type is also supported by setting
+ * @vep.bus_type to V4L2_MBUS_UNKNOWN. The caller may not provide a default
+ * configuration in this case as the defaults are specific to a given bus type.
+ * This functionality is deprecated and should not be used in new drivers and it
+ * is only supported for CSI-2 D-PHY, parallel and Bt.656 busses.
+ *
+ * The function does not change the V4L2 fwnode endpoint state if it fails.
  *
  * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
  * v4l2_fwnode_endpoint_parse():
@@ -177,11 +198,13 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep);
  * 2. The memory it has allocated to store the variable size data must be freed
  *    using v4l2_fwnode_endpoint_free() when no longer needed.
  *
- * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer
- * on error.
+ * Return: %0 on success or a negative error code on failure:
+ *        %-ENOMEM on memory allocation failure
+ *        %-EINVAL on parsing failure
+ *        %-ENXIO on mismatching bus types
  */
-struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
-       struct fwnode_handle *fwnode);
+int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode,
+                                    struct v4l2_fwnode_endpoint *vep);
 
 /**
  * v4l2_fwnode_parse_link() - parse a link between two endpoints
@@ -213,7 +236,6 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
  */
 void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
 
-
 /**
  * typedef parse_endpoint_func - Driver's callback function to be called on
  *     each V4L2 fwnode endpoint.
@@ -232,7 +254,6 @@ typedef int (*parse_endpoint_func)(struct device *dev,
                                  struct v4l2_fwnode_endpoint *vep,
                                  struct v4l2_async_subdev *asd);
 
-
 /**
  * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a
  *                                             device node
@@ -247,7 +268,7 @@ typedef int (*parse_endpoint_func)(struct device *dev,
  *                 endpoint. Optional.
  *
  * Parse the fwnode endpoints of the @dev device and populate the async sub-
- * devices array of the notifier. The @parse_endpoint callback function is
+ * devices list in the notifier. The @parse_endpoint callback function is
  * called for each endpoint with the corresponding async sub-device pointer to
  * let the caller initialize the driver-specific part of the async sub-device
  * structure.
@@ -258,11 +279,6 @@ typedef int (*parse_endpoint_func)(struct device *dev,
  * This function may not be called on a registered notifier and may be called on
  * a notifier only once.
  *
- * Do not change the notifier's subdevs array, take references to the subdevs
- * array itself or change the notifier's num_subdevs field. This is because this
- * function allocates and reallocates the subdevs array based on parsing
- * endpoints.
- *
  * The &struct v4l2_fwnode_endpoint passed to the callback function
  * @parse_endpoint is released once the function is finished. If there is a need
  * to retain that configuration, the user needs to allocate memory for it.
@@ -276,10 +292,11 @@ typedef int (*parse_endpoint_func)(struct device *dev,
  *        %-EINVAL if graph or endpoint parsing failed
  *        Other error codes as returned by @parse_endpoint
  */
-int v4l2_async_notifier_parse_fwnode_endpoints(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       size_t asd_struct_size,
-       parse_endpoint_func parse_endpoint);
+int
+v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev,
+                                          struct v4l2_async_notifier *notifier,
+                                          size_t asd_struct_size,
+                                          parse_endpoint_func parse_endpoint);
 
 /**
  * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode
@@ -303,7 +320,7 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
  * devices). In this case the driver must know which ports to parse.
  *
  * Parse the fwnode endpoints of the @dev device on a given @port and populate
- * the async sub-devices array of the notifier. The @parse_endpoint callback
+ * the async sub-devices list of the notifier. The @parse_endpoint callback
  * function is called for each endpoint with the corresponding async sub-device
  * pointer to let the caller initialize the driver-specific part of the async
  * sub-device structure.
@@ -314,11 +331,6 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
  * This function may not be called on a registered notifier and may be called on
  * a notifier only once per port.
  *
- * Do not change the notifier's subdevs array, take references to the subdevs
- * array itself or change the notifier's num_subdevs field. This is because this
- * function allocates and reallocates the subdevs array based on parsing
- * endpoints.
- *
  * The &struct v4l2_fwnode_endpoint passed to the callback function
  * @parse_endpoint is released once the function is finished. If there is a need
  * to retain that configuration, the user needs to allocate memory for it.
@@ -332,10 +344,12 @@ int v4l2_async_notifier_parse_fwnode_endpoints(
  *        %-EINVAL if graph or endpoint parsing failed
  *        Other error codes as returned by @parse_endpoint
  */
-int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
-       struct device *dev, struct v4l2_async_notifier *notifier,
-       size_t asd_struct_size, unsigned int port,
-       parse_endpoint_func parse_endpoint);
+int
+v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev,
+                                                  struct v4l2_async_notifier *notifier,
+                                                  size_t asd_struct_size,
+                                                  unsigned int port,
+                                                  parse_endpoint_func parse_endpoint);
 
 /**
  * v4l2_fwnode_reference_parse_sensor_common - parse common references on
@@ -355,7 +369,44 @@ int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
  *        -ENOMEM if memory allocation failed
  *        -EINVAL if property parsing failed
  */
-int v4l2_async_notifier_parse_fwnode_sensor_common(
-       struct device *dev, struct v4l2_async_notifier *notifier);
+int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
+                                                  struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_register_fwnode_subdev - registers a sub-device to the
+ *                                     asynchronous sub-device framework
+ *                                     and parses fwnode endpoints
+ *
+ * @sd: pointer to struct &v4l2_subdev
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ * @ports: array of port id's to parse for fwnode endpoints. If NULL, will
+ *        parse all ports owned by the sub-device.
+ * @num_ports: number of ports in @ports array. Ignored if @ports is NULL.
+ * @parse_endpoint: Driver's callback function called on each V4L2 fwnode
+ *                 endpoint. Optional.
+ *
+ * This function is just like v4l2_async_register_subdev() with the
+ * exception that calling it will also allocate a notifier for the
+ * sub-device, parse the sub-device's firmware node endpoints using
+ * v4l2_async_notifier_parse_fwnode_endpoints() or
+ * v4l2_async_notifier_parse_fwnode_endpoints_by_port(), and
+ * registers the sub-device notifier. The sub-device is similarly
+ * unregistered by calling v4l2_async_unregister_subdev().
+ *
+ * While registered, the subdev module is marked as in-use.
+ *
+ * An error is returned if the module is no longer loaded on any attempts
+ * to register it.
+ */
+int
+v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
+                                 size_t asd_struct_size,
+                                 unsigned int *ports,
+                                 unsigned int num_ports,
+                                 parse_endpoint_func parse_endpoint);
 
 #endif /* _V4L2_FWNODE_H */
index 2634d9dc9916e3c4925844e8c797e500d877cdef..bf5043c1ab6b3a326f894c817ec59b244a451397 100644 (file)
 #include <media/v4l2-dev.h>
 #include <linux/types.h>
 
-/**
- * enum tuner_pad_index - tuner pad index for MEDIA_ENT_F_TUNER
- *
- * @TUNER_PAD_RF_INPUT:        Radiofrequency (RF) sink pad, usually linked to a
- *                     RF connector entity.
- * @TUNER_PAD_OUTPUT:  Tuner video output source pad. Contains the video
- *                     chrominance and luminance or the hole bandwidth
- *                     of the signal converted to an Intermediate Frequency
- *                     (IF) or to baseband (on zero-IF tuners).
- * @TUNER_PAD_AUD_OUT: Tuner audio output source pad. Tuners used to decode
- *                     analog TV signals have an extra pad for audio output.
- *                     Old tuners use an analog stage with a saw filter for
- *                     the audio IF frequency. The output of the pad is, in
- *                     this case, the audio IF, with should be decoded either
- *                     by the bridge chipset (that's the case of cx2388x
- *                     chipsets) or may require an external IF sound
- *                     processor, like msp34xx. On modern silicon tuners,
- *                     the audio IF decoder is usually incorporated at the
- *                     tuner. On such case, the output of this pad is an
- *                     audio sampled data.
- * @TUNER_NUM_PADS:    Number of pads of the tuner.
- */
-enum tuner_pad_index {
-       TUNER_PAD_RF_INPUT,
-       TUNER_PAD_OUTPUT,
-       TUNER_PAD_AUD_OUT,
-       TUNER_NUM_PADS
-};
-
-/**
- * enum if_vid_dec_pad_index - video IF-PLL pad index for
- *                        MEDIA_ENT_F_IF_VID_DECODER
- *
- * @IF_VID_DEC_PAD_IF_INPUT:   video Intermediate Frequency (IF) sink pad
- * @IF_VID_DEC_PAD_OUT:                IF-PLL video output source pad. Contains the
- *                             video chrominance and luminance IF signals.
- * @IF_VID_DEC_PAD_NUM_PADS:   Number of pads of the video IF-PLL.
- */
-enum if_vid_dec_pad_index {
-       IF_VID_DEC_PAD_IF_INPUT,
-       IF_VID_DEC_PAD_OUT,
-       IF_VID_DEC_PAD_NUM_PADS
-};
-
-/**
- * enum if_aud_dec_pad_index - audio/sound IF-PLL pad index for
- *                        MEDIA_ENT_F_IF_AUD_DECODER
- *
- * @IF_AUD_DEC_PAD_IF_INPUT:   audio Intermediate Frequency (IF) sink pad
- * @IF_AUD_DEC_PAD_OUT:                IF-PLL audio output source pad. Contains the
- *                             audio sampled stream data, usually connected
- *                             to the bridge bus via an Inter-IC Sound (I2S)
- *                             bus.
- * @IF_AUD_DEC_PAD_NUM_PADS:   Number of pads of the audio IF-PLL.
- */
-enum if_aud_dec_pad_index {
-       IF_AUD_DEC_PAD_IF_INPUT,
-       IF_AUD_DEC_PAD_OUT,
-       IF_AUD_DEC_PAD_NUM_PADS
-};
-
-/**
- * enum demod_pad_index - analog TV pad index for MEDIA_ENT_F_ATV_DECODER
- *
- * @DEMOD_PAD_IF_INPUT:        IF input sink pad.
- * @DEMOD_PAD_VID_OUT: Video output source pad.
- * @DEMOD_PAD_VBI_OUT: Vertical Blank Interface (VBI) output source pad.
- * @DEMOD_PAD_AUDIO_OUT: Audio output source pad.
- * @DEMOD_NUM_PADS:    Maximum number of output pads.
- */
-enum demod_pad_index {
-       DEMOD_PAD_IF_INPUT,
-       DEMOD_PAD_VID_OUT,
-       DEMOD_PAD_VBI_OUT,
-       DEMOD_PAD_AUDIO_OUT,
-       DEMOD_NUM_PADS
-};
-
 /* We don't need to include pci.h or usb.h here */
 struct pci_dev;
 struct usb_device;
index 4bbb5f3d2b02572ef85504a5ab64b1b25a34b0aa..66cb746ceeb5258bfc83f5fcae03c34e4f9dd841 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/v4l2-mediabus.h>
 #include <linux/bitops.h>
 
-
 /* Parallel flags */
 /*
  * Can the client run in master or in slave mode. By "Master mode" an operation
 #define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK                BIT(8)
 #define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK     BIT(9)
 
-#define V4L2_MBUS_CSI2_LANES           (V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \
-                                        V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE)
-#define V4L2_MBUS_CSI2_CHANNELS                (V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CHANNEL_1 | \
-                                        V4L2_MBUS_CSI2_CHANNEL_2 | V4L2_MBUS_CSI2_CHANNEL_3)
+#define V4L2_MBUS_CSI2_LANES           (V4L2_MBUS_CSI2_1_LANE | \
+                                        V4L2_MBUS_CSI2_2_LANE | \
+                                        V4L2_MBUS_CSI2_3_LANE | \
+                                        V4L2_MBUS_CSI2_4_LANE)
+#define V4L2_MBUS_CSI2_CHANNELS                (V4L2_MBUS_CSI2_CHANNEL_0 | \
+                                        V4L2_MBUS_CSI2_CHANNEL_1 | \
+                                        V4L2_MBUS_CSI2_CHANNEL_2 | \
+                                        V4L2_MBUS_CSI2_CHANNEL_3)
 
 /**
  * enum v4l2_mbus_type - media bus type
+ * @V4L2_MBUS_UNKNOWN: unknown bus type, no V4L2 mediabus configuration
  * @V4L2_MBUS_PARALLEL:        parallel interface with hsync and vsync
  * @V4L2_MBUS_BT656:   parallel interface with embedded synchronisation, can
  *                     also be used for BT.1120
  * @V4L2_MBUS_CSI1:    MIPI CSI-1 serial interface
  * @V4L2_MBUS_CCP2:    CCP2 (Compact Camera Port 2)
- * @V4L2_MBUS_CSI2:    MIPI CSI-2 serial interface
+ * @V4L2_MBUS_CSI2_DPHY: MIPI CSI-2 serial interface, with D-PHY
+ * @V4L2_MBUS_CSI2_CPHY: MIPI CSI-2 serial interface, with C-PHY
  */
 enum v4l2_mbus_type {
+       V4L2_MBUS_UNKNOWN,
        V4L2_MBUS_PARALLEL,
        V4L2_MBUS_BT656,
        V4L2_MBUS_CSI1,
        V4L2_MBUS_CCP2,
-       V4L2_MBUS_CSI2,
+       V4L2_MBUS_CSI2_DPHY,
+       V4L2_MBUS_CSI2_CPHY,
 };
 
 /**
@@ -102,8 +109,9 @@ struct v4l2_mbus_config {
  * @pix_fmt:   pointer to &struct v4l2_pix_format to be filled
  * @mbus_fmt:  pointer to &struct v4l2_mbus_framefmt to be used as model
  */
-static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
-                               const struct v4l2_mbus_framefmt *mbus_fmt)
+static inline void
+v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
+                    const struct v4l2_mbus_framefmt *mbus_fmt)
 {
        pix_fmt->width = mbus_fmt->width;
        pix_fmt->height = mbus_fmt->height;
@@ -124,7 +132,7 @@ static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
  * @code:      data format code (from &enum v4l2_mbus_pixelcode)
  */
 static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
-                          const struct v4l2_pix_format *pix_fmt,
+                                        const struct v4l2_pix_format *pix_fmt,
                           u32 code)
 {
        mbus_fmt->width = pix_fmt->width;
@@ -144,9 +152,9 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
  * @pix_mp_fmt:        pointer to &struct v4l2_pix_format_mplane to be filled
  * @mbus_fmt:  pointer to &struct v4l2_mbus_framefmt to be used as model
  */
-static inline void v4l2_fill_pix_format_mplane(
-                               struct v4l2_pix_format_mplane *pix_mp_fmt,
-                               const struct v4l2_mbus_framefmt *mbus_fmt)
+static inline void
+v4l2_fill_pix_format_mplane(struct v4l2_pix_format_mplane *pix_mp_fmt,
+                           const struct v4l2_mbus_framefmt *mbus_fmt)
 {
        pix_mp_fmt->width = mbus_fmt->width;
        pix_mp_fmt->height = mbus_fmt->height;
@@ -164,9 +172,9 @@ static inline void v4l2_fill_pix_format_mplane(
  * @mbus_fmt:  pointer to &struct v4l2_mbus_framefmt to be filled
  * @pix_mp_fmt:        pointer to &struct v4l2_pix_format_mplane to be used as model
  */
-static inline void v4l2_fill_mbus_format_mplane(
-                               struct v4l2_mbus_framefmt *mbus_fmt,
-                               const struct v4l2_pix_format_mplane *pix_mp_fmt)
+static inline void
+v4l2_fill_mbus_format_mplane(struct v4l2_mbus_framefmt *mbus_fmt,
+                            const struct v4l2_pix_format_mplane *pix_mp_fmt)
 {
        mbus_fmt->width = pix_mp_fmt->width;
        mbus_fmt->height = pix_mp_fmt->height;
index d655720e16a1502dbfeb3571412c8a98b489002e..58c1ecf3d6489cda2cfd77a5f7de47abc7d90d3a 100644 (file)
@@ -622,6 +622,10 @@ v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
        return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
 }
 
+/* v4l2 request helper */
+
+void vb2_m2m_request_queue(struct media_request *req);
+
 /* v4l2 ioctl helpers */
 
 int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
index 595c3ba05f2396f8c05d2f9d92655afb0a0b1cb3..c86474dc7b552a09efff06326cbc8db95e29bc23 100644 (file)
@@ -82,6 +82,32 @@ static inline bool v4l2_rect_same_size(const struct v4l2_rect *r1,
        return r1->width == r2->width && r1->height == r2->height;
 }
 
+/**
+ * v4l2_rect_same_position() - return true if r1 has the same position as r2
+ * @r1: rectangle.
+ * @r2: rectangle.
+ *
+ * Return true if both rectangles have the same position
+ */
+static inline bool v4l2_rect_same_position(const struct v4l2_rect *r1,
+                                          const struct v4l2_rect *r2)
+{
+       return r1->top == r2->top && r1->left == r2->left;
+}
+
+/**
+ * v4l2_rect_equal() - return true if r1 equals r2
+ * @r1: rectangle.
+ * @r2: rectangle.
+ *
+ * Return true if both rectangles have the same size and position.
+ */
+static inline bool v4l2_rect_equal(const struct v4l2_rect *r1,
+                                  const struct v4l2_rect *r2)
+{
+       return v4l2_rect_same_size(r1, r2) && v4l2_rect_same_position(r1, r2);
+}
+
 /**
  * v4l2_rect_intersect() - calculate the intersection of two rects.
  * @r: intersection of @r1 and @r2.
index f6818f732f347fecfe2f6e48b2c59dfde5b4817c..e86981d615ae4930968cb22b0c85c28f38dfb74f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/poll.h>
 #include <linux/dma-buf.h>
 #include <linux/bitops.h>
+#include <media/media-request.h>
 
 #define VB2_MAX_FRAME  (32)
 #define VB2_MAX_PLANES (8)
@@ -203,8 +204,8 @@ enum vb2_io_modes {
 /**
  * enum vb2_buffer_state - current video buffer state.
  * @VB2_BUF_STATE_DEQUEUED:    buffer under userspace control.
+ * @VB2_BUF_STATE_IN_REQUEST:  buffer is queued in media request.
  * @VB2_BUF_STATE_PREPARING:   buffer is being prepared in videobuf.
- * @VB2_BUF_STATE_PREPARED:    buffer prepared in videobuf and by the driver.
  * @VB2_BUF_STATE_QUEUED:      buffer queued in videobuf, but not in driver.
  * @VB2_BUF_STATE_REQUEUEING:  re-queue a buffer to the driver.
  * @VB2_BUF_STATE_ACTIVE:      buffer queued in driver and possibly used
@@ -217,8 +218,8 @@ enum vb2_io_modes {
  */
 enum vb2_buffer_state {
        VB2_BUF_STATE_DEQUEUED,
+       VB2_BUF_STATE_IN_REQUEST,
        VB2_BUF_STATE_PREPARING,
-       VB2_BUF_STATE_PREPARED,
        VB2_BUF_STATE_QUEUED,
        VB2_BUF_STATE_REQUEUEING,
        VB2_BUF_STATE_ACTIVE,
@@ -238,6 +239,8 @@ struct vb2_queue;
  * @num_planes:                number of planes in the buffer
  *                     on an internal driver queue.
  * @timestamp:         frame timestamp in ns.
+ * @req_obj:           used to bind this buffer to a request. This
+ *                     request object has a refcount.
  */
 struct vb2_buffer {
        struct vb2_queue        *vb2_queue;
@@ -246,10 +249,17 @@ struct vb2_buffer {
        unsigned int            memory;
        unsigned int            num_planes;
        u64                     timestamp;
+       struct media_request_object     req_obj;
 
        /* private: internal use only
         *
         * state:               current buffer state; do not change
+        * synced:              this buffer has been synced for DMA, i.e. the
+        *                      'prepare' memop was called. It is cleared again
+        *                      after the 'finish' memop is called.
+        * prepared:            this buffer has been prepared, i.e. the
+        *                      buf_prepare op was called. It is cleared again
+        *                      after the 'buf_finish' op is called.
         * queued_entry:        entry on the queued buffers list, which holds
         *                      all buffers queued from userspace
         * done_entry:          entry on the list that stores all buffers ready
@@ -257,6 +267,8 @@ struct vb2_buffer {
         * vb2_plane:           per-plane information; do not change
         */
        enum vb2_buffer_state   state;
+       bool                    synced;
+       bool                    prepared;
 
        struct vb2_plane        planes[VB2_MAX_PLANES];
        struct list_head        queued_entry;
@@ -287,6 +299,7 @@ struct vb2_buffer {
        u32             cnt_buf_finish;
        u32             cnt_buf_cleanup;
        u32             cnt_buf_queue;
+       u32             cnt_buf_request_complete;
 
        /* This counts the number of calls to vb2_buffer_done() */
        u32             cnt_buf_done;
@@ -380,6 +393,11 @@ struct vb2_buffer {
  *                     ioctl; might be called before @start_streaming callback
  *                     if user pre-queued buffers before calling
  *                     VIDIOC_STREAMON().
+ * @buf_request_complete: a buffer that was never queued to the driver but is
+ *                     associated with a queued request was canceled.
+ *                     The driver will have to mark associated objects in the
+ *                     request as completed; required if requests are
+ *                     supported.
  */
 struct vb2_ops {
        int (*queue_setup)(struct vb2_queue *q,
@@ -398,6 +416,8 @@ struct vb2_ops {
        void (*stop_streaming)(struct vb2_queue *q);
 
        void (*buf_queue)(struct vb2_buffer *vb);
+
+       void (*buf_request_complete)(struct vb2_buffer *vb);
 };
 
 /**
@@ -406,6 +426,9 @@ struct vb2_ops {
  * @verify_planes_array: Verify that a given user space structure contains
  *                     enough planes for the buffer. This is called
  *                     for each dequeued buffer.
+ * @init_buffer:       given a &vb2_buffer initialize the extra data after
+ *                     struct vb2_buffer.
+ *                     For V4L2 this is a &struct vb2_v4l2_buffer.
  * @fill_user_buffer:  given a &vb2_buffer fill in the userspace structure.
  *                     For V4L2 this is a &struct v4l2_buffer.
  * @fill_vb2_buffer:   given a userspace structure, fill in the &vb2_buffer.
@@ -416,9 +439,9 @@ struct vb2_ops {
  */
 struct vb2_buf_ops {
        int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
+       void (*init_buffer)(struct vb2_buffer *vb);
        void (*fill_user_buffer)(struct vb2_buffer *vb, void *pb);
-       int (*fill_vb2_buffer)(struct vb2_buffer *vb, const void *pb,
-                               struct vb2_plane *planes);
+       int (*fill_vb2_buffer)(struct vb2_buffer *vb, struct vb2_plane *planes);
        void (*copy_timestamp)(struct vb2_buffer *vb, const void *pb);
 };
 
@@ -449,6 +472,13 @@ struct vb2_buf_ops {
  * @quirk_poll_must_check_waiting_for_buffers: Return %EPOLLERR at poll when QBUF
  *              has not been called. This is a vb1 idiom that has been adopted
  *              also by vb2.
+ * @supports_requests: this queue supports the Request API.
+ * @uses_qbuf: qbuf was used directly for this queue. Set to 1 the first
+ *             time this is called. Set to 0 when the queue is canceled.
+ *             If this is 1, then you cannot queue buffers from a request.
+ * @uses_requests: requests are used for this queue. Set to 1 the first time
+ *             a request is queued. Set to 0 when the queue is canceled.
+ *             If this is 1, then you cannot queue buffers directly.
  * @lock:      pointer to a mutex that protects the &struct vb2_queue. The
  *             driver can set this to a mutex to let the v4l2 core serialize
  *             the queuing ioctls. If the driver wants to handle locking
@@ -516,6 +546,9 @@ struct vb2_queue {
        unsigned                        fileio_write_immediately:1;
        unsigned                        allow_zero_bytesused:1;
        unsigned                   quirk_poll_must_check_waiting_for_buffers:1;
+       unsigned                        supports_requests:1;
+       unsigned                        uses_qbuf:1;
+       unsigned                        uses_requests:1;
 
        struct mutex                    *lock;
        void                            *owner;
@@ -752,12 +785,17 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb);
  * @index:     id number of the buffer
  * @pb:                buffer structure passed from userspace to
  *             v4l2_ioctl_ops->vidioc_qbuf handler in driver
+ * @req:       pointer to &struct media_request, may be NULL.
  *
  * Videobuf2 core helper to implement VIDIOC_QBUF() operation. It is called
  * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
  *
  * This function:
  *
+ * #) If @req is non-NULL, then the buffer will be bound to this
+ *    media request and it returns. The buffer will be prepared and
+ *    queued to the driver (i.e. the next two steps) when the request
+ *    itself is queued.
  * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
  *    (if provided), in which driver-specific buffer initialization can
  *    be performed;
@@ -766,7 +804,8 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb);
  *
  * Return: returns zero on success; an error code otherwise.
  */
-int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb);
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb,
+                 struct media_request *req);
 
 /**
  * vb2_core_dqbuf() - Dequeue a buffer to the userspace
@@ -1143,4 +1182,19 @@ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
  */
 int vb2_verify_memory_type(struct vb2_queue *q,
                enum vb2_memory memory, unsigned int type);
+
+/**
+ * vb2_request_object_is_buffer() - return true if the object is a buffer
+ *
+ * @obj:       the request object.
+ */
+bool vb2_request_object_is_buffer(struct media_request_object *obj);
+
+/**
+ * vb2_request_buffer_cnt() - return the number of buffers in the request
+ *
+ * @req:       the request.
+ */
+unsigned int vb2_request_buffer_cnt(struct media_request *req);
+
 #endif /* _MEDIA_VIDEOBUF2_CORE_H */
index 3d5e2d739f057679ad2176e458b77b445e01d266..727855463838c9e1773897ae66427a0226e09ede 100644 (file)
@@ -32,6 +32,8 @@
  *             &enum v4l2_field.
  * @timecode:  frame timecode.
  * @sequence:  sequence count of this frame.
+ * @request_fd:        the request_fd associated with this buffer
+ * @planes:    plane information (userptr/fd, length, bytesused, data_offset).
  *
  * Should contain enough information to be able to cover all the fields
  * of &struct v4l2_buffer at ``videodev2.h``.
@@ -43,6 +45,8 @@ struct vb2_v4l2_buffer {
        __u32                   field;
        struct v4l2_timecode    timecode;
        __u32                   sequence;
+       __s32                   request_fd;
+       struct vb2_plane        planes[VB2_MAX_PLANES];
 };
 
 /*
@@ -77,6 +81,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
  * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
  *
  * @q:         pointer to &struct vb2_queue with videobuf2 queue.
+ * @mdev:      pointer to &struct media_device, may be NULL.
  * @b:         buffer structure passed from userspace to
  *             &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver
  *
@@ -88,15 +93,19 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
  * #) verifies the passed buffer,
  * #) calls &vb2_ops->buf_prepare callback in the driver (if provided),
  *    in which driver-specific buffer initialization can be performed.
+ * #) if @b->request_fd is non-zero and @mdev->ops->req_queue is set,
+ *    then bind the prepared buffer to the request.
  *
  * The return values from this function are intended to be directly returned
  * from &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
  */
-int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
+                   struct v4l2_buffer *b);
 
 /**
  * vb2_qbuf() - Queue a buffer from userspace
  * @q:         pointer to &struct vb2_queue with videobuf2 queue.
+ * @mdev:      pointer to &struct media_device, may be NULL.
  * @b:         buffer structure passed from userspace to
  *             &v4l2_ioctl_ops->vidioc_qbuf handler in driver
  *
@@ -105,6 +114,8 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
  * This function:
  *
  * #) verifies the passed buffer;
+ * #) if @b->request_fd is non-zero and @mdev->ops->req_queue is set,
+ *    then bind the buffer to the request.
  * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
  *    (if provided), in which driver-specific buffer initialization can
  *    be performed;
@@ -114,7 +125,8 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
  * The return values from this function are intended to be directly returned
  * from &v4l2_ioctl_ops->vidioc_qbuf handler in driver.
  */
-int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev,
+            struct v4l2_buffer *b);
 
 /**
  * vb2_expbuf() - Export a buffer as a file descriptor
@@ -291,4 +303,8 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq);
  */
 void vb2_ops_wait_finish(struct vb2_queue *vq);
 
+struct media_request;
+int vb2_request_validate(struct media_request *req);
+void vb2_request_queue(struct media_request *req);
+
 #endif /* _MEDIA_VIDEOBUF2_V4L2_H */
index 3093b9cb9067e0a9599fdfd5d081e1ff08029f7b..1cf8683607010dd76db3f6ba8aa61b7e3cc3e0f7 100644 (file)
@@ -1,14 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * vsp1.h  --  R-Car VSP1 API
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  *
  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #ifndef __MEDIA_VSP1_H__
 #define __MEDIA_VSP1_H__
@@ -46,7 +42,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
 /**
  * struct vsp1_du_atomic_config - VSP atomic configuration parameters
  * @pixelformat: plane pixel format (V4L2 4CC)
- * @pitch: line pitch in bytes, for all planes
+ * @pitch: line pitch in bytes for the first plane
  * @mem: DMA memory address for each plane of the frame buffer
  * @src: source rectangle in the frame buffer (integer coordinates)
  * @dst: destination rectangle on the display (integer coordinates)
index b8eb51a661e5606b41a18fb04456ed86d2ba8fc7..beede1e1a919a7ac52e6df1c54df9e15844e30e9 100644 (file)
@@ -336,6 +336,9 @@ enum p9_qid_t {
 #define P9_NOFID       (u32)(~0)
 #define P9_MAXWELEM    16
 
+/* Minimal header size: size[4] type[1] tag[2] */
+#define P9_HDRSZ       7
+
 /* ample room for Twrite/Rread header */
 #define P9_IOHDRSZ     24
 
@@ -558,19 +561,12 @@ struct p9_fcall {
        size_t offset;
        size_t capacity;
 
+       struct kmem_cache *cache;
        u8 *sdata;
 };
 
-struct p9_idpool;
-
 int p9_errstr2errno(char *errstr, int len);
 
-struct p9_idpool *p9_idpool_create(void);
-void p9_idpool_destroy(struct p9_idpool *);
-int p9_idpool_get(struct p9_idpool *p);
-void p9_idpool_put(int id, struct p9_idpool *p);
-int p9_idpool_check(int id, struct p9_idpool *p);
-
 int p9_error_init(void);
 int p9_trans_fd_init(void);
 void p9_trans_fd_exit(void);
index 0fa0fbab33b0a71a6e2dacf15c217c3a18568385..947a570307a6fb5def03e111f12cefebb93a842c 100644 (file)
@@ -64,22 +64,15 @@ enum p9_trans_status {
 
 /**
  * enum p9_req_status_t - status of a request
- * @REQ_STATUS_IDLE: request slot unused
  * @REQ_STATUS_ALLOC: request has been allocated but not sent
  * @REQ_STATUS_UNSENT: request waiting to be sent
  * @REQ_STATUS_SENT: request sent to server
  * @REQ_STATUS_RCVD: response received from server
  * @REQ_STATUS_FLSHD: request has been flushed
  * @REQ_STATUS_ERROR: request encountered an error on the client side
- *
- * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
- * but use is actually tracked by the idpool structure which handles tag
- * id allocation.
- *
  */
 
 enum p9_req_status_t {
-       REQ_STATUS_IDLE,
        REQ_STATUS_ALLOC,
        REQ_STATUS_UNSENT,
        REQ_STATUS_SENT,
@@ -92,70 +85,46 @@ enum p9_req_status_t {
  * struct p9_req_t - request slots
  * @status: status of this request slot
  * @t_err: transport error
- * @flush_tag: tag of request being flushed (for flush requests)
  * @wq: wait_queue for the client to block on for this request
  * @tc: the request fcall structure
  * @rc: the response fcall structure
  * @aux: transport specific data (provided for trans_fd migration)
  * @req_list: link for higher level objects to chain requests
- *
- * Transport use an array to track outstanding requests
- * instead of a list.  While this may incurr overhead during initial
- * allocation or expansion, it makes request lookup much easier as the
- * tag id is a index into an array.  (We use tag+1 so that we can accommodate
- * the -1 tag for the T_VERSION request).
- * This also has the nice effect of only having to allocate wait_queues
- * once, instead of constantly allocating and freeing them.  Its possible
- * other resources could benefit from this scheme as well.
- *
  */
-
 struct p9_req_t {
        int status;
        int t_err;
+       struct kref refcount;
        wait_queue_head_t wq;
-       struct p9_fcall *tc;
-       struct p9_fcall *rc;
+       struct p9_fcall tc;
+       struct p9_fcall rc;
        void *aux;
-
        struct list_head req_list;
 };
 
 /**
  * struct p9_client - per client instance state
- * @lock: protect @fidlist
+ * @lock: protect @fids and @reqs
  * @msize: maximum data size negotiated by protocol
- * @dotu: extension flags negotiated by protocol
  * @proto_version: 9P protocol version to use
  * @trans_mod: module API instantiated with this client
+ * @status: connection state
  * @trans: tranport instance state and API
  * @fids: All active FID handles
- * @tagpool - transaction id accounting for session
- * @reqs - 2D array of requests
- * @max_tag - current maximum tag id allocated
- * @name - node name used as client id
+ * @reqs: All active requests.
+ * @name: node name used as client id
  *
  * The client structure is used to keep track of various per-client
  * state that has been instantiated.
- * In order to minimize per-transaction overhead we use a
- * simple array to lookup requests instead of a hash table
- * or linked list.  In order to support larger number of
- * transactions, we make this a 2D array, allocating new rows
- * when we need to grow the total number of the transactions.
- *
- * Each row is 256 requests and we'll support up to 256 rows for
- * a total of 64k concurrent requests per session.
- *
- * Bugs: duplicated data and potentially unnecessary elements.
  */
-
 struct p9_client {
-       spinlock_t lock; /* protect client structure */
+       spinlock_t lock;
        unsigned int msize;
        unsigned char proto_version;
        struct p9_trans_module *trans_mod;
        enum p9_trans_status status;
        void *trans;
+       struct kmem_cache *fcall_cache;
 
        union {
                struct {
@@ -170,10 +139,7 @@ struct p9_client {
        } trans_opts;
 
        struct idr fids;
-
-       struct p9_idpool *tagpool;
-       struct p9_req_t *reqs[P9_ROW_MAXTAG];
-       int max_tag;
+       struct idr reqs;
 
        char name[__NEW_UTS_LEN + 1];
 };
@@ -266,7 +232,21 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
                                kgid_t gid, struct p9_qid *);
 int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
 int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
+void p9_fcall_fini(struct p9_fcall *fc);
 struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
+
+static inline void p9_req_get(struct p9_req_t *r)
+{
+       kref_get(&r->refcount);
+}
+
+static inline int p9_req_try_get(struct p9_req_t *r)
+{
+       return kref_get_unless_zero(&r->refcount);
+}
+
+int p9_req_put(struct p9_req_t *r);
+
 void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
 
 int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int);
@@ -279,4 +259,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *);
 int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int);
 int p9_client_readlink(struct p9_fid *fid, char **target);
 
+int p9_client_init(void);
+void p9_client_exit(void);
+
 #endif /* NET_9P_CLIENT_H */
index 597783b8a3a074e758ddff99adaabe42cbe85b2b..56877660d5ba34df26dd9cd177fb729868a718b8 100644 (file)
@@ -1194,4 +1194,32 @@ int qman_release_cgrid(u32 id);
  */
 int qman_is_probed(void);
 
+/**
+ * qman_dqrr_get_ithresh - Get coalesce interrupt threshold
+ * @portal: portal to get the value for
+ * @ithresh: threshold pointer
+ */
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh);
+
+/**
+ * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
+ * @portal: portal to set the new value on
+ * @ithresh: new threshold value
+ */
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
+
+/**
+ * qman_dqrr_get_iperiod - Get coalesce interrupt period
+ * @portal: portal to get the value for
+ * @iperiod: period pointer
+ */
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod);
+
+/**
+ * qman_dqrr_set_iperiod - Set coalesce interrupt period
+ * @portal: portal to set the new value on
+ * @ithresh: new period value
+ */
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
+
 #endif /* __FSL_QMAN_H */
index c32bf91c23e6f81422434057901db1aa8ee25808..562426812ab2a1adac08b03cc3791d71009a5b72 100644 (file)
@@ -134,22 +134,13 @@ enum tegra_io_pad {
        TEGRA_IO_PAD_USB2,
        TEGRA_IO_PAD_USB3,
        TEGRA_IO_PAD_USB_BIAS,
+       TEGRA_IO_PAD_AO_HV,
 };
 
 /* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */
 #define TEGRA_IO_RAIL_HDMI     TEGRA_IO_PAD_HDMI
 #define TEGRA_IO_RAIL_LVDS     TEGRA_IO_PAD_LVDS
 
-/**
- * enum tegra_io_pad_voltage - voltage level of the I/O pad's source rail
- * @TEGRA_IO_PAD_1800000UV: 1.8 V
- * @TEGRA_IO_PAD_3300000UV: 3.3 V
- */
-enum tegra_io_pad_voltage {
-       TEGRA_IO_PAD_1800000UV,
-       TEGRA_IO_PAD_3300000UV,
-};
-
 #ifdef CONFIG_SOC_TEGRA_PMC
 int tegra_powergate_is_powered(unsigned int id);
 int tegra_powergate_power_on(unsigned int id);
@@ -162,9 +153,6 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
 
 int tegra_io_pad_power_enable(enum tegra_io_pad id);
 int tegra_io_pad_power_disable(enum tegra_io_pad id);
-int tegra_io_pad_set_voltage(enum tegra_io_pad id,
-                            enum tegra_io_pad_voltage voltage);
-int tegra_io_pad_get_voltage(enum tegra_io_pad id);
 
 /* deprecated, use tegra_io_pad_power_{enable,disable}() instead */
 int tegra_io_rail_power_on(unsigned int id);
@@ -212,12 +200,6 @@ static inline int tegra_io_pad_power_disable(enum tegra_io_pad id)
        return -ENOSYS;
 }
 
-static inline int tegra_io_pad_set_voltage(enum tegra_io_pad id,
-                                          enum tegra_io_pad_voltage voltage)
-{
-       return -ENOSYS;
-}
-
 static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id)
 {
        return -ENOSYS;
index 040651735662983693d51f5645f311f128fe63f4..cdc9f4ca8c27504d7058903a2f8fc4de877a82bd 100644 (file)
@@ -79,6 +79,8 @@
 #define TIOCGPTLCK     _IOR('T', 0x39, int) /* Get Pty lock state */
 #define TIOCGEXCL      _IOR('T', 0x40, int) /* Get exclusive mode state */
 #define TIOCGPTPEER    _IO('T', 0x41) /* Safely open the slave */
+#define TIOCGISO7816   _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816   _IOWR('T', 0x43, struct serial_iso7816)
 
 #define FIONCLEX       0x5450
 #define FIOCLEX                0x5451
index 097fcd81247189f355968a6545dd8a1a5d8e55d0..3094af68b6e76cdf24855c77553de8c3bb599c91 100644 (file)
@@ -152,10 +152,13 @@ static inline void cec_msg_set_reply_to(struct cec_msg *msg,
 #define CEC_TX_STATUS_LOW_DRIVE                (1 << 3)
 #define CEC_TX_STATUS_ERROR            (1 << 4)
 #define CEC_TX_STATUS_MAX_RETRIES      (1 << 5)
+#define CEC_TX_STATUS_ABORTED          (1 << 6)
+#define CEC_TX_STATUS_TIMEOUT          (1 << 7)
 
 #define CEC_RX_STATUS_OK               (1 << 0)
 #define CEC_RX_STATUS_TIMEOUT          (1 << 1)
 #define CEC_RX_STATUS_FEATURE_ABORT    (1 << 2)
+#define CEC_RX_STATUS_ABORTED          (1 << 3)
 
 static inline int cec_msg_status_is_ok(const struct cec_msg *msg)
 {
index 31aa101783351547469f4efc67b0bb9c9e0f10f1..93722e60204c607377bf20efeca54df08e78bbd4 100644 (file)
@@ -41,6 +41,7 @@
 #define EM_TILEPRO     188     /* Tilera TILEPro */
 #define EM_MICROBLAZE  189     /* Xilinx MicroBlaze */
 #define EM_TILEGX      191     /* Tilera TILE-Gx */
+#define EM_RISCV       243     /* RISC-V */
 #define EM_BPF         247     /* Linux BPF - in-kernel virtual machine */
 #define EM_FRV         0x5441  /* Fujitsu FR-V */
 
index 74247917de044db54b10ae16584139d85a4db207..b86740d1c50a4bcde370f953cf5400d31a89bafb 100644 (file)
 #define FAN_CLOEXEC            0x00000001
 #define FAN_NONBLOCK           0x00000002
 
-/* These are NOT bitwise flags.  Both bits are used togther.  */
+/* These are NOT bitwise flags.  Both bits are used together.  */
 #define FAN_CLASS_NOTIF                0x00000000
 #define FAN_CLASS_CONTENT      0x00000004
 #define FAN_CLASS_PRE_CONTENT  0x00000008
+
+/* Deprecated - do not use this in programs and do not add new flags here! */
 #define FAN_ALL_CLASS_BITS     (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
                                 FAN_CLASS_PRE_CONTENT)
 
 #define FAN_UNLIMITED_MARKS    0x00000020
 #define FAN_ENABLE_AUDIT       0x00000040
 
+/* Flags to determine fanotify event format */
+#define FAN_REPORT_TID         0x00000100      /* event->pid is thread id */
+
+/* Deprecated - do not use this in programs and do not add new flags here! */
 #define FAN_ALL_INIT_FLAGS     (FAN_CLOEXEC | FAN_NONBLOCK | \
                                 FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
                                 FAN_UNLIMITED_MARKS)
 #define FAN_MARK_REMOVE                0x00000002
 #define FAN_MARK_DONT_FOLLOW   0x00000004
 #define FAN_MARK_ONLYDIR       0x00000008
-#define FAN_MARK_MOUNT         0x00000010
+/* FAN_MARK_MOUNT is           0x00000010 */
 #define FAN_MARK_IGNORED_MASK  0x00000020
 #define FAN_MARK_IGNORED_SURV_MODIFY   0x00000040
 #define FAN_MARK_FLUSH         0x00000080
+/* FAN_MARK_FILESYSTEM is      0x00000100 */
 
+/* These are NOT bitwise flags.  Both bits can be used togther.  */
+#define FAN_MARK_INODE         0x00000000
+#define FAN_MARK_MOUNT         0x00000010
+#define FAN_MARK_FILESYSTEM    0x00000100
+
+/* Deprecated - do not use this in programs and do not add new flags here! */
 #define FAN_ALL_MARK_FLAGS     (FAN_MARK_ADD |\
                                 FAN_MARK_REMOVE |\
                                 FAN_MARK_DONT_FOLLOW |\
                                 FAN_MARK_IGNORED_SURV_MODIFY |\
                                 FAN_MARK_FLUSH)
 
-/*
- * All of the events - we build the list by hand so that we can add flags in
- * the future and not break backward compatibility.  Apps will get only the
- * events that they originally wanted.  Be sure to add new events here!
- */
+/* Deprecated - do not use this in programs and do not add new flags here! */
 #define FAN_ALL_EVENTS (FAN_ACCESS |\
                        FAN_MODIFY |\
                        FAN_CLOSE |\
 /*
  * All events which require a permission response from userspace
  */
+/* Deprecated - do not use this in programs and do not add new flags here! */
 #define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\
                             FAN_ACCESS_PERM)
 
+/* Deprecated - do not use this in programs and do not add new flags here! */
 #define FAN_ALL_OUTGOING_EVENTS        (FAN_ALL_EVENTS |\
                                 FAN_ALL_PERM_EVENTS |\
                                 FAN_Q_OVERFLOW)
index 92fa24c24c926554397bc8fd0db0b449d7c55532..b4967d48bfdaf90ec19d3767a61c91157855678f 100644 (file)
  *
  *  7.27
  *  - add FUSE_ABORT_ERROR
+ *
+ *  7.28
+ *  - add FUSE_COPY_FILE_RANGE
+ *  - add FOPEN_CACHE_DIR
+ *  - add FUSE_MAX_PAGES, add max_pages to init_out
+ *  - add FUSE_CACHE_SYMLINKS
  */
 
 #ifndef _LINUX_FUSE_H
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 27
+#define FUSE_KERNEL_MINOR_VERSION 28
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -219,10 +225,12 @@ struct fuse_file_lock {
  * FOPEN_DIRECT_IO: bypass page cache for this open file
  * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
  * FOPEN_NONSEEKABLE: the file is not seekable
+ * FOPEN_CACHE_DIR: allow caching this directory
  */
 #define FOPEN_DIRECT_IO                (1 << 0)
 #define FOPEN_KEEP_CACHE       (1 << 1)
 #define FOPEN_NONSEEKABLE      (1 << 2)
+#define FOPEN_CACHE_DIR                (1 << 3)
 
 /**
  * INIT request/reply flags
@@ -249,6 +257,8 @@ struct fuse_file_lock {
  * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc
  * FUSE_POSIX_ACL: filesystem supports posix acls
  * FUSE_ABORT_ERROR: reading the device after abort returns ECONNABORTED
+ * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages
+ * FUSE_CACHE_SYMLINKS: cache READLINK responses
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
@@ -272,6 +282,8 @@ struct fuse_file_lock {
 #define FUSE_HANDLE_KILLPRIV   (1 << 19)
 #define FUSE_POSIX_ACL         (1 << 20)
 #define FUSE_ABORT_ERROR       (1 << 21)
+#define FUSE_MAX_PAGES         (1 << 22)
+#define FUSE_CACHE_SYMLINKS    (1 << 23)
 
 /**
  * CUSE INIT request/reply flags
@@ -337,53 +349,54 @@ struct fuse_file_lock {
 #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
 
 enum fuse_opcode {
-       FUSE_LOOKUP        = 1,
-       FUSE_FORGET        = 2,  /* no reply */
-       FUSE_GETATTR       = 3,
-       FUSE_SETATTR       = 4,
-       FUSE_READLINK      = 5,
-       FUSE_SYMLINK       = 6,
-       FUSE_MKNOD         = 8,
-       FUSE_MKDIR         = 9,
-       FUSE_UNLINK        = 10,
-       FUSE_RMDIR         = 11,
-       FUSE_RENAME        = 12,
-       FUSE_LINK          = 13,
-       FUSE_OPEN          = 14,
-       FUSE_READ          = 15,
-       FUSE_WRITE         = 16,
-       FUSE_STATFS        = 17,
-       FUSE_RELEASE       = 18,
-       FUSE_FSYNC         = 20,
-       FUSE_SETXATTR      = 21,
-       FUSE_GETXATTR      = 22,
-       FUSE_LISTXATTR     = 23,
-       FUSE_REMOVEXATTR   = 24,
-       FUSE_FLUSH         = 25,
-       FUSE_INIT          = 26,
-       FUSE_OPENDIR       = 27,
-       FUSE_READDIR       = 28,
-       FUSE_RELEASEDIR    = 29,
-       FUSE_FSYNCDIR      = 30,
-       FUSE_GETLK         = 31,
-       FUSE_SETLK         = 32,
-       FUSE_SETLKW        = 33,
-       FUSE_ACCESS        = 34,
-       FUSE_CREATE        = 35,
-       FUSE_INTERRUPT     = 36,
-       FUSE_BMAP          = 37,
-       FUSE_DESTROY       = 38,
-       FUSE_IOCTL         = 39,
-       FUSE_POLL          = 40,
-       FUSE_NOTIFY_REPLY  = 41,
-       FUSE_BATCH_FORGET  = 42,
-       FUSE_FALLOCATE     = 43,
-       FUSE_READDIRPLUS   = 44,
-       FUSE_RENAME2       = 45,
-       FUSE_LSEEK         = 46,
+       FUSE_LOOKUP             = 1,
+       FUSE_FORGET             = 2,  /* no reply */
+       FUSE_GETATTR            = 3,
+       FUSE_SETATTR            = 4,
+       FUSE_READLINK           = 5,
+       FUSE_SYMLINK            = 6,
+       FUSE_MKNOD              = 8,
+       FUSE_MKDIR              = 9,
+       FUSE_UNLINK             = 10,
+       FUSE_RMDIR              = 11,
+       FUSE_RENAME             = 12,
+       FUSE_LINK               = 13,
+       FUSE_OPEN               = 14,
+       FUSE_READ               = 15,
+       FUSE_WRITE              = 16,
+       FUSE_STATFS             = 17,
+       FUSE_RELEASE            = 18,
+       FUSE_FSYNC              = 20,
+       FUSE_SETXATTR           = 21,
+       FUSE_GETXATTR           = 22,
+       FUSE_LISTXATTR          = 23,
+       FUSE_REMOVEXATTR        = 24,
+       FUSE_FLUSH              = 25,
+       FUSE_INIT               = 26,
+       FUSE_OPENDIR            = 27,
+       FUSE_READDIR            = 28,
+       FUSE_RELEASEDIR         = 29,
+       FUSE_FSYNCDIR           = 30,
+       FUSE_GETLK              = 31,
+       FUSE_SETLK              = 32,
+       FUSE_SETLKW             = 33,
+       FUSE_ACCESS             = 34,
+       FUSE_CREATE             = 35,
+       FUSE_INTERRUPT          = 36,
+       FUSE_BMAP               = 37,
+       FUSE_DESTROY            = 38,
+       FUSE_IOCTL              = 39,
+       FUSE_POLL               = 40,
+       FUSE_NOTIFY_REPLY       = 41,
+       FUSE_BATCH_FORGET       = 42,
+       FUSE_FALLOCATE          = 43,
+       FUSE_READDIRPLUS        = 44,
+       FUSE_RENAME2            = 45,
+       FUSE_LSEEK              = 46,
+       FUSE_COPY_FILE_RANGE    = 47,
 
        /* CUSE specific operations */
-       CUSE_INIT          = 4096,
+       CUSE_INIT               = 4096,
 };
 
 enum fuse_notify_code {
@@ -610,7 +623,9 @@ struct fuse_init_out {
        uint16_t        congestion_threshold;
        uint32_t        max_write;
        uint32_t        time_gran;
-       uint32_t        unused[9];
+       uint16_t        max_pages;
+       uint16_t        padding;
+       uint32_t        unused[8];
 };
 
 #define CUSE_INIT_INFO_MAX 4096
@@ -792,4 +807,14 @@ struct fuse_lseek_out {
        uint64_t        offset;
 };
 
+struct fuse_copy_file_range_in {
+       uint64_t        fh_in;
+       uint64_t        off_in;
+       uint64_t        nodeid_out;
+       uint64_t        fh_out;
+       uint64_t        off_out;
+       uint64_t        len;
+       uint64_t        flags;
+};
+
 #endif /* _LINUX_FUSE_H */
index 36f76e777ef96caacc90d42848905e1418362765..e5d0c5c611b57439ec4d757460399c6b4ec3ed34 100644 (file)
@@ -369,6 +369,14 @@ struct media_v2_topology {
 #define MEDIA_IOC_ENUM_LINKS   _IOWR('|', 0x02, struct media_links_enum)
 #define MEDIA_IOC_SETUP_LINK   _IOWR('|', 0x03, struct media_link_desc)
 #define MEDIA_IOC_G_TOPOLOGY   _IOWR('|', 0x04, struct media_v2_topology)
+#define MEDIA_IOC_REQUEST_ALLOC        _IOR ('|', 0x05, int)
+
+/*
+ * These ioctls are called on the request file descriptor as returned
+ * by MEDIA_IOC_REQUEST_ALLOC.
+ */
+#define MEDIA_REQUEST_IOC_QUEUE                _IO('|',  0x80)
+#define MEDIA_REQUEST_IOC_REINIT       _IO('|',  0x81)
 
 #ifndef __KERNEL__
 
index 3fdd0dee8b41bb053c02b8b1ece649e386e7fb95..93eb3c496ff1e85a6af59c539596775c4c9bf35e 100644 (file)
@@ -132,4 +132,21 @@ struct serial_rs485 {
                                           are a royal PITA .. */
 };
 
+/*
+ * Serial interface for controlling ISO7816 settings on chips with suitable
+ * support. Set with TIOCSISO7816 and get with TIOCGISO7816 if supported by
+ * your platform.
+ */
+struct serial_iso7816 {
+       __u32   flags;                  /* ISO7816 feature flags */
+#define SER_ISO7816_ENABLED            (1 << 0)
+#define SER_ISO7816_T_PARAM            (0x0f << 4)
+#define SER_ISO7816_T(t)               (((t) & 0x0f) << 4)
+       __u32   tg;
+       __u32   sc_fi;
+       __u32   sc_di;
+       __u32   clk;
+       __u32   reserved[5];
+};
+
 #endif /* _UAPI_LINUX_SERIAL_H */
index e4ee10ee917de1e12dbc3d732120711a394f4dae..51b095898f4b5952178205b5c517c7e383066164 100644 (file)
@@ -402,6 +402,9 @@ enum v4l2_mpeg_video_multi_slice_mode {
 #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE          (V4L2_CID_MPEG_BASE+228)
 #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME            (V4L2_CID_MPEG_BASE+229)
 
+#define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS         (V4L2_CID_MPEG_BASE+250)
+#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION         (V4L2_CID_MPEG_BASE+251)
+
 #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP            (V4L2_CID_MPEG_BASE+300)
 #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP            (V4L2_CID_MPEG_BASE+301)
 #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP            (V4L2_CID_MPEG_BASE+302)
@@ -1092,4 +1095,66 @@ enum v4l2_detect_md_mode {
 #define V4L2_CID_DETECT_MD_THRESHOLD_GRID      (V4L2_CID_DETECT_CLASS_BASE + 3)
 #define V4L2_CID_DETECT_MD_REGION_GRID         (V4L2_CID_DETECT_CLASS_BASE + 4)
 
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_I       1
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_P       2
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_B       3
+#define V4L2_MPEG2_PICTURE_CODING_TYPE_D       4
+
+struct v4l2_mpeg2_sequence {
+       /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */
+       __u16   horizontal_size;
+       __u16   vertical_size;
+       __u32   vbv_buffer_size;
+
+       /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */
+       __u8    profile_and_level_indication;
+       __u8    progressive_sequence;
+       __u8    chroma_format;
+};
+
+struct v4l2_mpeg2_picture {
+       /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */
+       __u8    picture_coding_type;
+
+       /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */
+       __u8    f_code[2][2];
+       __u8    intra_dc_precision;
+       __u8    picture_structure;
+       __u8    top_field_first;
+       __u8    frame_pred_frame_dct;
+       __u8    concealment_motion_vectors;
+       __u8    q_scale_type;
+       __u8    intra_vlc_format;
+       __u8    alternate_scan;
+       __u8    repeat_first_field;
+       __u8    progressive_frame;
+};
+
+struct v4l2_ctrl_mpeg2_slice_params {
+       __u32   bit_size;
+       __u32   data_bit_offset;
+
+       struct v4l2_mpeg2_sequence sequence;
+       struct v4l2_mpeg2_picture picture;
+
+       /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */
+       __u8    quantiser_scale_code;
+
+       __u8    backward_ref_index;
+       __u8    forward_ref_index;
+};
+
+struct v4l2_ctrl_mpeg2_quantization {
+       /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */
+       __u8    load_intra_quantiser_matrix;
+       __u8    load_non_intra_quantiser_matrix;
+       __u8    load_chroma_intra_quantiser_matrix;
+       __u8    load_chroma_non_intra_quantiser_matrix;
+
+       __u8    intra_quantiser_matrix[64];
+       __u8    non_intra_quantiser_matrix[64];
+       __u8    chroma_intra_quantiser_matrix[64];
+       __u8    chroma_non_intra_quantiser_matrix[64];
+};
+
 #endif
index f378b9802d8b5d2276387406d57b084e3ebd3211..813102810f53eaf37552d13f512b5d54ccff7aad 100644 (file)
@@ -303,6 +303,56 @@ struct vfio_region_info_cap_type {
 #define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
 #define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG  (3)
 
+#define VFIO_REGION_TYPE_GFX                    (1)
+#define VFIO_REGION_SUBTYPE_GFX_EDID            (1)
+
+/**
+ * struct vfio_region_gfx_edid - EDID region layout.
+ *
+ * Set display link state and EDID blob.
+ *
+ * The EDID blob has monitor information such as brand, name, serial
+ * number, physical size, supported video modes and more.
+ *
+ * This special region allows userspace (typically qemu) set a virtual
+ * EDID for the virtual monitor, which allows a flexible display
+ * configuration.
+ *
+ * For the edid blob spec look here:
+ *    https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
+ *
+ * On linux systems you can find the EDID blob in sysfs:
+ *    /sys/class/drm/${card}/${connector}/edid
+ *
+ * You can use the edid-decode ulility (comes with xorg-x11-utils) to
+ * decode the EDID blob.
+ *
+ * @edid_offset: location of the edid blob, relative to the
+ *               start of the region (readonly).
+ * @edid_max_size: max size of the edid blob (readonly).
+ * @edid_size: actual edid size (read/write).
+ * @link_state: display link state (read/write).
+ * VFIO_DEVICE_GFX_LINK_STATE_UP: Monitor is turned on.
+ * VFIO_DEVICE_GFX_LINK_STATE_DOWN: Monitor is turned off.
+ * @max_xres: max display width (0 == no limitation, readonly).
+ * @max_yres: max display height (0 == no limitation, readonly).
+ *
+ * EDID update protocol:
+ *   (1) set link-state to down.
+ *   (2) update edid blob and size.
+ *   (3) set link-state to up.
+ */
+struct vfio_region_gfx_edid {
+       __u32 edid_offset;
+       __u32 edid_max_size;
+       __u32 edid_size;
+       __u32 max_xres;
+       __u32 max_yres;
+       __u32 link_state;
+#define VFIO_DEVICE_GFX_LINK_STATE_UP    1
+#define VFIO_DEVICE_GFX_LINK_STATE_DOWN  2
+};
+
 /*
  * The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
  * which allows direct access to non-MSIX registers which happened to be within
index 5d1a3685bea95a2d937019ef76a21ae39a448aaf..c8e8ff810190c22ad1bec8a6af068109106415b7 100644 (file)
@@ -225,8 +225,8 @@ enum v4l2_colorspace {
        /* For RGB colorspaces such as produces by most webcams. */
        V4L2_COLORSPACE_SRGB          = 8,
 
-       /* AdobeRGB colorspace */
-       V4L2_COLORSPACE_ADOBERGB      = 9,
+       /* opRGB colorspace */
+       V4L2_COLORSPACE_OPRGB         = 9,
 
        /* BT.2020 colorspace, used for UHDTV. */
        V4L2_COLORSPACE_BT2020        = 10,
@@ -258,7 +258,7 @@ enum v4l2_xfer_func {
         *
         * V4L2_COLORSPACE_SRGB, V4L2_COLORSPACE_JPEG: V4L2_XFER_FUNC_SRGB
         *
-        * V4L2_COLORSPACE_ADOBERGB: V4L2_XFER_FUNC_ADOBERGB
+        * V4L2_COLORSPACE_OPRGB: V4L2_XFER_FUNC_OPRGB
         *
         * V4L2_COLORSPACE_SMPTE240M: V4L2_XFER_FUNC_SMPTE240M
         *
@@ -269,7 +269,7 @@ enum v4l2_xfer_func {
        V4L2_XFER_FUNC_DEFAULT     = 0,
        V4L2_XFER_FUNC_709         = 1,
        V4L2_XFER_FUNC_SRGB        = 2,
-       V4L2_XFER_FUNC_ADOBERGB    = 3,
+       V4L2_XFER_FUNC_OPRGB       = 3,
        V4L2_XFER_FUNC_SMPTE240M   = 4,
        V4L2_XFER_FUNC_NONE        = 5,
        V4L2_XFER_FUNC_DCI_P3      = 6,
@@ -281,7 +281,7 @@ enum v4l2_xfer_func {
  * This depends on the colorspace.
  */
 #define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) \
-       ((colsp) == V4L2_COLORSPACE_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : \
+       ((colsp) == V4L2_COLORSPACE_OPRGB ? V4L2_XFER_FUNC_OPRGB : \
         ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : \
          ((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : \
           ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : \
@@ -295,7 +295,7 @@ enum v4l2_ycbcr_encoding {
         *
         * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M,
         * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_SRGB,
-        * V4L2_COLORSPACE_ADOBERGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601
+        * V4L2_COLORSPACE_OPRGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601
         *
         * V4L2_COLORSPACE_REC709 and V4L2_COLORSPACE_DCI_P3: V4L2_YCBCR_ENC_709
         *
@@ -382,6 +382,17 @@ enum v4l2_quantization {
         (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \
         V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE))
 
+/*
+ * Deprecated names for opRGB colorspace (IEC 61966-2-5)
+ *
+ * WARNING: Please don't use these deprecated defines in your code, as
+ * there is a chance we have to remove them in the future.
+ */
+#ifndef __KERNEL__
+#define V4L2_COLORSPACE_ADOBERGB V4L2_COLORSPACE_OPRGB
+#define V4L2_XFER_FUNC_ADOBERGB  V4L2_XFER_FUNC_OPRGB
+#endif
+
 enum v4l2_priority {
        V4L2_PRIORITY_UNSET       = 0,  /* not initialized */
        V4L2_PRIORITY_BACKGROUND  = 1,
@@ -635,6 +646,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_H263     v4l2_fourcc('H', '2', '6', '3') /* H263          */
 #define V4L2_PIX_FMT_MPEG1    v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES     */
 #define V4L2_PIX_FMT_MPEG2    v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES     */
+#define V4L2_PIX_FMT_MPEG2_SLICE v4l2_fourcc('M', 'G', '2', 'S') /* MPEG-2 parsed slice data */
 #define V4L2_PIX_FMT_MPEG4    v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */
 #define V4L2_PIX_FMT_XVID     v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid           */
 #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
@@ -676,6 +688,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_Z16      v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */
 #define V4L2_PIX_FMT_MT21C    v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode  */
 #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
+#define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
 
 /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
 #define V4L2_PIX_FMT_IPU3_SBGGR10      v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
@@ -703,6 +716,7 @@ struct v4l2_pix_format {
 #define V4L2_META_FMT_VSP1_HGO    v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */
 #define V4L2_META_FMT_VSP1_HGT    v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */
 #define V4L2_META_FMT_UVC         v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */
+#define V4L2_META_FMT_D4XX        v4l2_fourcc('D', '4', 'X', 'X') /* D4XX Payload Header metadata */
 
 /* priv field value to indicates that subsequent fields are valid. */
 #define V4L2_PIX_FMT_PRIV_MAGIC                0xfeedcafe
@@ -856,9 +870,16 @@ struct v4l2_requestbuffers {
        __u32                   count;
        __u32                   type;           /* enum v4l2_buf_type */
        __u32                   memory;         /* enum v4l2_memory */
-       __u32                   reserved[2];
+       __u32                   capabilities;
+       __u32                   reserved[1];
 };
 
+/* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */
+#define V4L2_BUF_CAP_SUPPORTS_MMAP     (1 << 0)
+#define V4L2_BUF_CAP_SUPPORTS_USERPTR  (1 << 1)
+#define V4L2_BUF_CAP_SUPPORTS_DMABUF   (1 << 2)
+#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
+
 /**
  * struct v4l2_plane - plane info for multi-planar buffers
  * @bytesused:         number of bytes occupied by data in the plane (payload)
@@ -917,6 +938,7 @@ struct v4l2_plane {
  * @length:    size in bytes of the buffer (NOT its payload) for single-plane
  *             buffers (when type != *_MPLANE); number of elements in the
  *             planes array for multi-plane buffers
+ * @request_fd: fd of the request that this buffer should use
  *
  * Contains data exchanged by application and driver using one of the Streaming
  * I/O methods.
@@ -941,7 +963,10 @@ struct v4l2_buffer {
        } m;
        __u32                   length;
        __u32                   reserved2;
-       __u32                   reserved;
+       union {
+               __s32           request_fd;
+               __u32           reserved;
+       };
 };
 
 /*  Flags for 'flags' field */
@@ -959,6 +984,8 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_BFRAME                   0x00000020
 /* Buffer is ready, but the data contained within is corrupted. */
 #define V4L2_BUF_FLAG_ERROR                    0x00000040
+/* Buffer is added to an unqueued request */
+#define V4L2_BUF_FLAG_IN_REQUEST               0x00000080
 /* timecode field is valid */
 #define V4L2_BUF_FLAG_TIMECODE                 0x00000100
 /* Buffer is prepared for queuing */
@@ -977,6 +1004,8 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE           0x00010000
 /* mem2mem encoder/decoder */
 #define V4L2_BUF_FLAG_LAST                     0x00100000
+/* request_fd is valid */
+#define V4L2_BUF_FLAG_REQUEST_FD               0x00800000
 
 /**
  * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
@@ -1400,6 +1429,13 @@ struct v4l2_bt_timings {
  * InfoFrame).
  */
 #define V4L2_DV_FL_HAS_HDMI_VIC                        (1 << 8)
+/*
+ * CEA-861 specific: only valid for video receivers.
+ * If set, then HW can detect the difference between regular FPS and
+ * 1000/1001 FPS. Note: This flag is only valid for HDMI VIC codes with
+ * the V4L2_DV_FL_CAN_REDUCE_FPS flag set.
+ */
+#define V4L2_DV_FL_CAN_DETECT_REDUCED_FPS      (1 << 9)
 
 /* A few useful defines to calculate the total blanking and frame sizes */
 #define V4L2_DV_BT_BLANKING_WIDTH(bt) \
@@ -1586,6 +1622,8 @@ struct v4l2_ext_control {
                __u8 __user *p_u8;
                __u16 __user *p_u16;
                __u32 __user *p_u32;
+               struct v4l2_ctrl_mpeg2_slice_params __user *p_mpeg2_slice_params;
+               struct v4l2_ctrl_mpeg2_quantization __user *p_mpeg2_quantization;
                void __user *ptr;
        };
 } __attribute__ ((packed));
@@ -1599,7 +1637,8 @@ struct v4l2_ext_controls {
        };
        __u32 count;
        __u32 error_idx;
-       __u32 reserved[2];
+       __s32 request_fd;
+       __u32 reserved[1];
        struct v4l2_ext_control *controls;
 };
 
@@ -1612,6 +1651,7 @@ struct v4l2_ext_controls {
 #define V4L2_CTRL_MAX_DIMS       (4)
 #define V4L2_CTRL_WHICH_CUR_VAL   0
 #define V4L2_CTRL_WHICH_DEF_VAL   0x0f000000
+#define V4L2_CTRL_WHICH_REQUEST_VAL 0x0f010000
 
 enum v4l2_ctrl_type {
        V4L2_CTRL_TYPE_INTEGER       = 1,
@@ -1629,6 +1669,8 @@ enum v4l2_ctrl_type {
        V4L2_CTRL_TYPE_U8            = 0x0100,
        V4L2_CTRL_TYPE_U16           = 0x0101,
        V4L2_CTRL_TYPE_U32           = 0x0102,
+       V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS = 0x0103,
+       V4L2_CTRL_TYPE_MPEG2_QUANTIZATION = 0x0104,
 };
 
 /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
@@ -2302,6 +2344,7 @@ struct v4l2_dbg_chip_info {
  *             return: number of created buffers
  * @memory:    enum v4l2_memory; buffer memory type
  * @format:    frame format, for which buffers are requested
+ * @capabilities: capabilities of this buffer type.
  * @reserved:  future extensions
  */
 struct v4l2_create_buffers {
@@ -2309,7 +2352,8 @@ struct v4l2_create_buffers {
        __u32                   count;
        __u32                   memory;
        struct v4l2_format      format;
-       __u32                   reserved[8];
+       __u32                   capabilities;
+       __u32                   reserved[7];
 };
 
 /*
index 3abd327bada64c0fd089131192edcb88da26e916..7d09e54ae54e0f2b1dab07d76cf0be4718f20369 100644 (file)
@@ -36,12 +36,9 @@ struct dlfb_data {
        struct usb_device *udev;
        struct fb_info *info;
        struct urb_list urbs;
-       struct kref kref;
        char *backing_buffer;
        int fb_count;
        bool virtualized; /* true when physical usb device not present */
-       struct delayed_work init_framebuffer_work;
-       struct delayed_work free_framebuffer_work;
        atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
        atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
        char *edid; /* null until we read edid from hw or get from sysfs */
index e1c9afa9d8c9103fa1463a45a425c9468e4c1628..a754e3ba9831f73b0791e2d9267dfc551b04369c 100644 (file)
@@ -167,6 +167,24 @@ done:
        }
        return res;
 }
+
+/**
+ * match_dev_by_label - callback for finding a partition using its label
+ * @dev:       device passed in by the caller
+ * @data:      opaque pointer to the label to match
+ *
+ * Returns 1 if the device matches, and 0 otherwise.
+ */
+static int match_dev_by_label(struct device *dev, const void *data)
+{
+       const char *label = data;
+       struct hd_struct *part = dev_to_part(dev);
+
+       if (part->info && !strcmp(label, part->info->volname))
+               return 1;
+
+       return 0;
+}
 #endif
 
 /*
@@ -190,6 +208,8 @@ done:
  *        a partition with a known unique id.
  *     8) <major>:<minor> major and minor number of the device separated by
  *        a colon.
+ *     9) PARTLABEL=<name> with name being the GPT partition label.
+ *        MSDOS partitions do not support labels!
  *
  *     If name doesn't have fall into the categories above, we return (0,0).
  *     block_class is used to check if something is a disk name. If the disk
@@ -211,6 +231,17 @@ dev_t name_to_dev_t(const char *name)
                if (!res)
                        goto fail;
                goto done;
+       } else if (strncmp(name, "PARTLABEL=", 10) == 0) {
+               struct device *dev;
+
+               dev = class_find_device(&block_class, NULL, name + 10,
+                                       &match_dev_by_label);
+               if (!dev)
+                       goto fail;
+
+               res = dev->devt;
+               put_device(dev);
+               goto done;
        }
 #endif
 
index 1c3f902642809fe8a2e332bef30cdd8226c0e9ae..ee147103ba1bae45798b06ba2705a917bc5cc8d6 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/initrd.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/acpi.h>
 #include <linux/console.h>
 #include <linux/nmi.h>
@@ -375,10 +375,11 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
 static void __init setup_command_line(char *command_line)
 {
        saved_command_line =
-               memblock_virt_alloc(strlen(boot_command_line) + 1, 0);
+               memblock_alloc(strlen(boot_command_line) + 1, SMP_CACHE_BYTES);
        initcall_command_line =
-               memblock_virt_alloc(strlen(boot_command_line) + 1, 0);
-       static_command_line = memblock_virt_alloc(strlen(command_line) + 1, 0);
+               memblock_alloc(strlen(boot_command_line) + 1, SMP_CACHE_BYTES);
+       static_command_line = memblock_alloc(strlen(command_line) + 1,
+                                            SMP_CACHE_BYTES);
        strcpy(saved_command_line, boot_command_line);
        strcpy(static_command_line, command_line);
 }
@@ -773,8 +774,10 @@ static int __init initcall_blacklist(char *str)
                str_entry = strsep(&str, ",");
                if (str_entry) {
                        pr_debug("blacklisting initcall %s\n", str_entry);
-                       entry = alloc_bootmem(sizeof(*entry));
-                       entry->buf = alloc_bootmem(strlen(str_entry) + 1);
+                       entry = memblock_alloc(sizeof(*entry),
+                                              SMP_CACHE_BYTES);
+                       entry->buf = memblock_alloc(strlen(str_entry) + 1,
+                                                   SMP_CACHE_BYTES);
                        strcpy(entry->buf, str_entry);
                        list_add(&entry->next, &blacklisted_initcalls);
                }
index 8ad93c29f511033dc4a6df1b2a26398ea78c9104..49f9bf4ffc7f1ae09bc04b833891fcc7d7a5a5a5 100644 (file)
@@ -88,17 +88,39 @@ static int proc_ipc_auto_msgmni(struct ctl_table *table, int write,
        return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
 }
 
+static int proc_ipc_sem_dointvec(struct ctl_table *table, int write,
+       void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       int ret, semmni;
+       struct ipc_namespace *ns = current->nsproxy->ipc_ns;
+
+       semmni = ns->sem_ctls[3];
+       ret = proc_ipc_dointvec(table, write, buffer, lenp, ppos);
+
+       if (!ret)
+               ret = sem_check_semmni(current->nsproxy->ipc_ns);
+
+       /*
+        * Reset the semmni value if an error happens.
+        */
+       if (ret)
+               ns->sem_ctls[3] = semmni;
+       return ret;
+}
+
 #else
 #define proc_ipc_doulongvec_minmax NULL
 #define proc_ipc_dointvec         NULL
 #define proc_ipc_dointvec_minmax   NULL
 #define proc_ipc_dointvec_minmax_orphans   NULL
 #define proc_ipc_auto_msgmni      NULL
+#define proc_ipc_sem_dointvec     NULL
 #endif
 
 static int zero;
 static int one = 1;
 static int int_max = INT_MAX;
+static int ipc_mni = IPCMNI;
 
 static struct ctl_table ipc_kern_table[] = {
        {
@@ -120,7 +142,9 @@ static struct ctl_table ipc_kern_table[] = {
                .data           = &init_ipc_ns.shm_ctlmni,
                .maxlen         = sizeof(init_ipc_ns.shm_ctlmni),
                .mode           = 0644,
-               .proc_handler   = proc_ipc_dointvec,
+               .proc_handler   = proc_ipc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &ipc_mni,
        },
        {
                .procname       = "shm_rmid_forced",
@@ -147,7 +171,7 @@ static struct ctl_table ipc_kern_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_ipc_dointvec_minmax,
                .extra1         = &zero,
-               .extra2         = &int_max,
+               .extra2         = &ipc_mni,
        },
        {
                .procname       = "auto_msgmni",
@@ -172,7 +196,7 @@ static struct ctl_table ipc_kern_table[] = {
                .data           = &init_ipc_ns.sem_ctls,
                .maxlen         = 4*sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_ipc_dointvec,
+               .proc_handler   = proc_ipc_sem_dointvec,
        },
 #ifdef CONFIG_CHECKPOINT_RESTORE
        {
index 1ee81bce25e97f45ff03987d9940f7a96aaf993d..d768fdbed5154a10b279e061b8cc66eff7e166da 100644 (file)
@@ -217,6 +217,15 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
 void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
                void (*free)(struct ipc_namespace *, struct kern_ipc_perm *));
 
+static inline int sem_check_semmni(struct ipc_namespace *ns) {
+       /*
+        * Check semmni range [0, IPCMNI]
+        * semmni is the last element of sem_ctls[4] array
+        */
+       return ((ns->sem_ctls[3] < 0) || (ns->sem_ctls[3] > IPCMNI))
+               ? -ERANGE : 0;
+}
+
 #ifdef CONFIG_COMPAT
 #include <linux/compat.h>
 struct compat_ipc_perm {
index c373e887c0664b7206004ea806b1f2a8a00b8b87..9795d75b09b2323306ad6a058a6350a87a251443 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/log2.h>
 #include <linux/spinlock_types.h>
 
-void foo(void)
+int main(void)
 {
        /* The enum constants to put into include/generated/bounds.h */
        DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS);
@@ -23,4 +23,6 @@ void foo(void)
 #endif
        DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
        /* End of constants */
+
+       return 0;
 }
index f14c376937e5708d9b0d980130866631012dde8e..22a12ab5a5e9aaac7ac5207d70b059bd75e48965 100644 (file)
@@ -4,7 +4,7 @@
  *
  * DMA operations that map physical memory directly without using an IOMMU.
  */
-#include <linux/bootmem.h> /* for max_pfn */
+#include <linux/memblock.h> /* for max_pfn */
 #include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/dma-direct.h>
index ebecaf255ea29ed204586101e37d4baa9c626893..5731daa09a32edc2175657384aee68b60a365a2a 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/dma.h>
 
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/iommu-helper.h>
 
 #define CREATE_TRACE_POINTS
@@ -204,10 +204,10 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
         * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
         * between io_tlb_start and io_tlb_end.
         */
-       io_tlb_list = memblock_virt_alloc(
+       io_tlb_list = memblock_alloc(
                                PAGE_ALIGN(io_tlb_nslabs * sizeof(int)),
                                PAGE_SIZE);
-       io_tlb_orig_addr = memblock_virt_alloc(
+       io_tlb_orig_addr = memblock_alloc(
                                PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t)),
                                PAGE_SIZE);
        for (i = 0; i < io_tlb_nslabs; i++) {
@@ -242,7 +242,7 @@ swiotlb_init(int verbose)
        bytes = io_tlb_nslabs << IO_TLB_SHIFT;
 
        /* Get IO TLB memory from the low pages */
-       vstart = memblock_virt_alloc_low_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE);
+       vstart = memblock_alloc_low_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE);
        if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose))
                return;
 
index 5a97f34bc14c8e2e31a452cb6fdcd38774a3b9a1..8c490130c4fb0072838801534948d9ec6b9a285f 100644 (file)
@@ -8376,30 +8376,39 @@ static struct pmu perf_tracepoint = {
  *
  * PERF_PROBE_CONFIG_IS_RETPROBE if set, create kretprobe/uretprobe
  *                               if not set, create kprobe/uprobe
+ *
+ * The following values specify a reference counter (or semaphore in the
+ * terminology of tools like dtrace, systemtap, etc.) Userspace Statically
+ * Defined Tracepoints (USDT). Currently, we use 40 bit for the offset.
+ *
+ * PERF_UPROBE_REF_CTR_OFFSET_BITS     # of bits in config as th offset
+ * PERF_UPROBE_REF_CTR_OFFSET_SHIFT    # of bits to shift left
  */
 enum perf_probe_config {
        PERF_PROBE_CONFIG_IS_RETPROBE = 1U << 0,  /* [k,u]retprobe */
+       PERF_UPROBE_REF_CTR_OFFSET_BITS = 32,
+       PERF_UPROBE_REF_CTR_OFFSET_SHIFT = 64 - PERF_UPROBE_REF_CTR_OFFSET_BITS,
 };
 
 PMU_FORMAT_ATTR(retprobe, "config:0");
+#endif
 
-static struct attribute *probe_attrs[] = {
+#ifdef CONFIG_KPROBE_EVENTS
+static struct attribute *kprobe_attrs[] = {
        &format_attr_retprobe.attr,
        NULL,
 };
 
-static struct attribute_group probe_format_group = {
+static struct attribute_group kprobe_format_group = {
        .name = "format",
-       .attrs = probe_attrs,
+       .attrs = kprobe_attrs,
 };
 
-static const struct attribute_group *probe_attr_groups[] = {
-       &probe_format_group,
+static const struct attribute_group *kprobe_attr_groups[] = {
+       &kprobe_format_group,
        NULL,
 };
-#endif
 
-#ifdef CONFIG_KPROBE_EVENTS
 static int perf_kprobe_event_init(struct perf_event *event);
 static struct pmu perf_kprobe = {
        .task_ctx_nr    = perf_sw_context,
@@ -8409,7 +8418,7 @@ static struct pmu perf_kprobe = {
        .start          = perf_swevent_start,
        .stop           = perf_swevent_stop,
        .read           = perf_swevent_read,
-       .attr_groups    = probe_attr_groups,
+       .attr_groups    = kprobe_attr_groups,
 };
 
 static int perf_kprobe_event_init(struct perf_event *event)
@@ -8441,6 +8450,24 @@ static int perf_kprobe_event_init(struct perf_event *event)
 #endif /* CONFIG_KPROBE_EVENTS */
 
 #ifdef CONFIG_UPROBE_EVENTS
+PMU_FORMAT_ATTR(ref_ctr_offset, "config:32-63");
+
+static struct attribute *uprobe_attrs[] = {
+       &format_attr_retprobe.attr,
+       &format_attr_ref_ctr_offset.attr,
+       NULL,
+};
+
+static struct attribute_group uprobe_format_group = {
+       .name = "format",
+       .attrs = uprobe_attrs,
+};
+
+static const struct attribute_group *uprobe_attr_groups[] = {
+       &uprobe_format_group,
+       NULL,
+};
+
 static int perf_uprobe_event_init(struct perf_event *event);
 static struct pmu perf_uprobe = {
        .task_ctx_nr    = perf_sw_context,
@@ -8450,12 +8477,13 @@ static struct pmu perf_uprobe = {
        .start          = perf_swevent_start,
        .stop           = perf_swevent_stop,
        .read           = perf_swevent_read,
-       .attr_groups    = probe_attr_groups,
+       .attr_groups    = uprobe_attr_groups,
 };
 
 static int perf_uprobe_event_init(struct perf_event *event)
 {
        int err;
+       unsigned long ref_ctr_offset;
        bool is_retprobe;
 
        if (event->attr.type != perf_uprobe.type)
@@ -8471,7 +8499,8 @@ static int perf_uprobe_event_init(struct perf_event *event)
                return -EOPNOTSUPP;
 
        is_retprobe = event->attr.config & PERF_PROBE_CONFIG_IS_RETPROBE;
-       err = perf_uprobe_init(event, is_retprobe);
+       ref_ctr_offset = event->attr.config >> PERF_UPROBE_REF_CTR_OFFSET_SHIFT;
+       err = perf_uprobe_init(event, ref_ctr_offset, is_retprobe);
        if (err)
                return err;
 
index 2bf792d22087caa979b7de851097aae90b0fd040..96d4bee83489b113a1f37452aeffb8e13461b230 100644 (file)
@@ -73,6 +73,7 @@ struct uprobe {
        struct uprobe_consumer  *consumers;
        struct inode            *inode;         /* Also hold a ref to inode */
        loff_t                  offset;
+       loff_t                  ref_ctr_offset;
        unsigned long           flags;
 
        /*
@@ -88,6 +89,15 @@ struct uprobe {
        struct arch_uprobe      arch;
 };
 
+struct delayed_uprobe {
+       struct list_head list;
+       struct uprobe *uprobe;
+       struct mm_struct *mm;
+};
+
+static DEFINE_MUTEX(delayed_uprobe_lock);
+static LIST_HEAD(delayed_uprobe_list);
+
 /*
  * Execute out of line area: anonymous executable mapping installed
  * by the probed task to execute the copy of the original instruction
@@ -282,6 +292,166 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t
        return 1;
 }
 
+static struct delayed_uprobe *
+delayed_uprobe_check(struct uprobe *uprobe, struct mm_struct *mm)
+{
+       struct delayed_uprobe *du;
+
+       list_for_each_entry(du, &delayed_uprobe_list, list)
+               if (du->uprobe == uprobe && du->mm == mm)
+                       return du;
+       return NULL;
+}
+
+static int delayed_uprobe_add(struct uprobe *uprobe, struct mm_struct *mm)
+{
+       struct delayed_uprobe *du;
+
+       if (delayed_uprobe_check(uprobe, mm))
+               return 0;
+
+       du  = kzalloc(sizeof(*du), GFP_KERNEL);
+       if (!du)
+               return -ENOMEM;
+
+       du->uprobe = uprobe;
+       du->mm = mm;
+       list_add(&du->list, &delayed_uprobe_list);
+       return 0;
+}
+
+static void delayed_uprobe_delete(struct delayed_uprobe *du)
+{
+       if (WARN_ON(!du))
+               return;
+       list_del(&du->list);
+       kfree(du);
+}
+
+static void delayed_uprobe_remove(struct uprobe *uprobe, struct mm_struct *mm)
+{
+       struct list_head *pos, *q;
+       struct delayed_uprobe *du;
+
+       if (!uprobe && !mm)
+               return;
+
+       list_for_each_safe(pos, q, &delayed_uprobe_list) {
+               du = list_entry(pos, struct delayed_uprobe, list);
+
+               if (uprobe && du->uprobe != uprobe)
+                       continue;
+               if (mm && du->mm != mm)
+                       continue;
+
+               delayed_uprobe_delete(du);
+       }
+}
+
+static bool valid_ref_ctr_vma(struct uprobe *uprobe,
+                             struct vm_area_struct *vma)
+{
+       unsigned long vaddr = offset_to_vaddr(vma, uprobe->ref_ctr_offset);
+
+       return uprobe->ref_ctr_offset &&
+               vma->vm_file &&
+               file_inode(vma->vm_file) == uprobe->inode &&
+               (vma->vm_flags & (VM_WRITE|VM_SHARED)) == VM_WRITE &&
+               vma->vm_start <= vaddr &&
+               vma->vm_end > vaddr;
+}
+
+static struct vm_area_struct *
+find_ref_ctr_vma(struct uprobe *uprobe, struct mm_struct *mm)
+{
+       struct vm_area_struct *tmp;
+
+       for (tmp = mm->mmap; tmp; tmp = tmp->vm_next)
+               if (valid_ref_ctr_vma(uprobe, tmp))
+                       return tmp;
+
+       return NULL;
+}
+
+static int
+__update_ref_ctr(struct mm_struct *mm, unsigned long vaddr, short d)
+{
+       void *kaddr;
+       struct page *page;
+       struct vm_area_struct *vma;
+       int ret;
+       short *ptr;
+
+       if (!vaddr || !d)
+               return -EINVAL;
+
+       ret = get_user_pages_remote(NULL, mm, vaddr, 1,
+                       FOLL_WRITE, &page, &vma, NULL);
+       if (unlikely(ret <= 0)) {
+               /*
+                * We are asking for 1 page. If get_user_pages_remote() fails,
+                * it may return 0, in that case we have to return error.
+                */
+               return ret == 0 ? -EBUSY : ret;
+       }
+
+       kaddr = kmap_atomic(page);
+       ptr = kaddr + (vaddr & ~PAGE_MASK);
+
+       if (unlikely(*ptr + d < 0)) {
+               pr_warn("ref_ctr going negative. vaddr: 0x%lx, "
+                       "curr val: %d, delta: %d\n", vaddr, *ptr, d);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       *ptr += d;
+       ret = 0;
+out:
+       kunmap_atomic(kaddr);
+       put_page(page);
+       return ret;
+}
+
+static void update_ref_ctr_warn(struct uprobe *uprobe,
+                               struct mm_struct *mm, short d)
+{
+       pr_warn("ref_ctr %s failed for inode: 0x%lx offset: "
+               "0x%llx ref_ctr_offset: 0x%llx of mm: 0x%pK\n",
+               d > 0 ? "increment" : "decrement", uprobe->inode->i_ino,
+               (unsigned long long) uprobe->offset,
+               (unsigned long long) uprobe->ref_ctr_offset, mm);
+}
+
+static int update_ref_ctr(struct uprobe *uprobe, struct mm_struct *mm,
+                         short d)
+{
+       struct vm_area_struct *rc_vma;
+       unsigned long rc_vaddr;
+       int ret = 0;
+
+       rc_vma = find_ref_ctr_vma(uprobe, mm);
+
+       if (rc_vma) {
+               rc_vaddr = offset_to_vaddr(rc_vma, uprobe->ref_ctr_offset);
+               ret = __update_ref_ctr(mm, rc_vaddr, d);
+               if (ret)
+                       update_ref_ctr_warn(uprobe, mm, d);
+
+               if (d > 0)
+                       return ret;
+       }
+
+       mutex_lock(&delayed_uprobe_lock);
+       if (d > 0)
+               ret = delayed_uprobe_add(uprobe, mm);
+       else
+               delayed_uprobe_remove(uprobe, mm);
+       mutex_unlock(&delayed_uprobe_lock);
+
+       return ret;
+}
+
 /*
  * NOTE:
  * Expect the breakpoint instruction to be the smallest size instruction for
@@ -302,9 +472,13 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t
 int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
                        unsigned long vaddr, uprobe_opcode_t opcode)
 {
+       struct uprobe *uprobe;
        struct page *old_page, *new_page;
        struct vm_area_struct *vma;
-       int ret;
+       int ret, is_register, ref_ctr_updated = 0;
+
+       is_register = is_swbp_insn(&opcode);
+       uprobe = container_of(auprobe, struct uprobe, arch);
 
 retry:
        /* Read the page with vaddr into memory */
@@ -317,6 +491,15 @@ retry:
        if (ret <= 0)
                goto put_old;
 
+       /* We are going to replace instruction, update ref_ctr. */
+       if (!ref_ctr_updated && uprobe->ref_ctr_offset) {
+               ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1);
+               if (ret)
+                       goto put_old;
+
+               ref_ctr_updated = 1;
+       }
+
        ret = anon_vma_prepare(vma);
        if (ret)
                goto put_old;
@@ -337,6 +520,11 @@ put_old:
 
        if (unlikely(ret == -EAGAIN))
                goto retry;
+
+       /* Revert back reference counter if instruction update failed. */
+       if (ret && is_register && ref_ctr_updated)
+               update_ref_ctr(uprobe, mm, -1);
+
        return ret;
 }
 
@@ -378,8 +566,15 @@ static struct uprobe *get_uprobe(struct uprobe *uprobe)
 
 static void put_uprobe(struct uprobe *uprobe)
 {
-       if (atomic_dec_and_test(&uprobe->ref))
+       if (atomic_dec_and_test(&uprobe->ref)) {
+               /*
+                * If application munmap(exec_vma) before uprobe_unregister()
+                * gets called, we don't get a chance to remove uprobe from
+                * delayed_uprobe_list from remove_breakpoint(). Do it here.
+                */
+               delayed_uprobe_remove(uprobe, NULL);
                kfree(uprobe);
+       }
 }
 
 static int match_uprobe(struct uprobe *l, struct uprobe *r)
@@ -484,7 +679,18 @@ static struct uprobe *insert_uprobe(struct uprobe *uprobe)
        return u;
 }
 
-static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
+static void
+ref_ctr_mismatch_warn(struct uprobe *cur_uprobe, struct uprobe *uprobe)
+{
+       pr_warn("ref_ctr_offset mismatch. inode: 0x%lx offset: 0x%llx "
+               "ref_ctr_offset(old): 0x%llx ref_ctr_offset(new): 0x%llx\n",
+               uprobe->inode->i_ino, (unsigned long long) uprobe->offset,
+               (unsigned long long) cur_uprobe->ref_ctr_offset,
+               (unsigned long long) uprobe->ref_ctr_offset);
+}
+
+static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset,
+                                  loff_t ref_ctr_offset)
 {
        struct uprobe *uprobe, *cur_uprobe;
 
@@ -494,6 +700,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
 
        uprobe->inode = inode;
        uprobe->offset = offset;
+       uprobe->ref_ctr_offset = ref_ctr_offset;
        init_rwsem(&uprobe->register_rwsem);
        init_rwsem(&uprobe->consumer_rwsem);
 
@@ -501,6 +708,12 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
        cur_uprobe = insert_uprobe(uprobe);
        /* a uprobe exists for this inode:offset combination */
        if (cur_uprobe) {
+               if (cur_uprobe->ref_ctr_offset != uprobe->ref_ctr_offset) {
+                       ref_ctr_mismatch_warn(cur_uprobe, uprobe);
+                       put_uprobe(cur_uprobe);
+                       kfree(uprobe);
+                       return ERR_PTR(-EINVAL);
+               }
                kfree(uprobe);
                uprobe = cur_uprobe;
        }
@@ -895,7 +1108,7 @@ EXPORT_SYMBOL_GPL(uprobe_unregister);
  * else return 0 (success)
  */
 static int __uprobe_register(struct inode *inode, loff_t offset,
-                            struct uprobe_consumer *uc)
+                            loff_t ref_ctr_offset, struct uprobe_consumer *uc)
 {
        struct uprobe *uprobe;
        int ret;
@@ -912,9 +1125,12 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
                return -EINVAL;
 
  retry:
-       uprobe = alloc_uprobe(inode, offset);
+       uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
        if (!uprobe)
                return -ENOMEM;
+       if (IS_ERR(uprobe))
+               return PTR_ERR(uprobe);
+
        /*
         * We can race with uprobe_unregister()->delete_uprobe().
         * Check uprobe_is_active() and retry if it is false.
@@ -938,10 +1154,17 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
 int uprobe_register(struct inode *inode, loff_t offset,
                    struct uprobe_consumer *uc)
 {
-       return __uprobe_register(inode, offset, uc);
+       return __uprobe_register(inode, offset, 0, uc);
 }
 EXPORT_SYMBOL_GPL(uprobe_register);
 
+int uprobe_register_refctr(struct inode *inode, loff_t offset,
+                          loff_t ref_ctr_offset, struct uprobe_consumer *uc)
+{
+       return __uprobe_register(inode, offset, ref_ctr_offset, uc);
+}
+EXPORT_SYMBOL_GPL(uprobe_register_refctr);
+
 /*
  * uprobe_apply - unregister an already registered probe.
  * @inode: the file in which the probe has to be removed.
@@ -1060,6 +1283,35 @@ static void build_probe_list(struct inode *inode,
        spin_unlock(&uprobes_treelock);
 }
 
+/* @vma contains reference counter, not the probed instruction. */
+static int delayed_ref_ctr_inc(struct vm_area_struct *vma)
+{
+       struct list_head *pos, *q;
+       struct delayed_uprobe *du;
+       unsigned long vaddr;
+       int ret = 0, err = 0;
+
+       mutex_lock(&delayed_uprobe_lock);
+       list_for_each_safe(pos, q, &delayed_uprobe_list) {
+               du = list_entry(pos, struct delayed_uprobe, list);
+
+               if (du->mm != vma->vm_mm ||
+                   !valid_ref_ctr_vma(du->uprobe, vma))
+                       continue;
+
+               vaddr = offset_to_vaddr(vma, du->uprobe->ref_ctr_offset);
+               ret = __update_ref_ctr(vma->vm_mm, vaddr, 1);
+               if (ret) {
+                       update_ref_ctr_warn(du->uprobe, vma->vm_mm, 1);
+                       if (!err)
+                               err = ret;
+               }
+               delayed_uprobe_delete(du);
+       }
+       mutex_unlock(&delayed_uprobe_lock);
+       return err;
+}
+
 /*
  * Called from mmap_region/vma_adjust with mm->mmap_sem acquired.
  *
@@ -1072,7 +1324,15 @@ int uprobe_mmap(struct vm_area_struct *vma)
        struct uprobe *uprobe, *u;
        struct inode *inode;
 
-       if (no_uprobe_events() || !valid_vma(vma, true))
+       if (no_uprobe_events())
+               return 0;
+
+       if (vma->vm_file &&
+           (vma->vm_flags & (VM_WRITE|VM_SHARED)) == VM_WRITE &&
+           test_bit(MMF_HAS_UPROBES, &vma->vm_mm->flags))
+               delayed_ref_ctr_inc(vma);
+
+       if (!valid_vma(vma, true))
                return 0;
 
        inode = file_inode(vma->vm_file);
@@ -1246,6 +1506,10 @@ void uprobe_clear_state(struct mm_struct *mm)
 {
        struct xol_area *area = mm->uprobes_state.xol_area;
 
+       mutex_lock(&delayed_uprobe_lock);
+       delayed_uprobe_remove(NULL, mm);
+       mutex_unlock(&delayed_uprobe_lock);
+
        if (!area)
                return;
 
index bc80a4e268c0bc27132ecb782df98276b282b237..17f75b545f665c6df331c88ee5d6b6e19112ddb6 100644 (file)
@@ -173,8 +173,7 @@ static void fei_debugfs_remove_attr(struct fei_attr *attr)
        struct dentry *dir;
 
        dir = debugfs_lookup(attr->kp.symbol_name, fei_debugfs_dir);
-       if (dir)
-               debugfs_remove_recursive(dir);
+       debugfs_remove_recursive(dir);
 }
 
 static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
index 3e2de8fc1891267111372d9edd71fa1f2494d6ed..f423f9b6577eb23849ebbbf87ee9549d74e62da2 100644 (file)
@@ -65,7 +65,7 @@
 #include <linux/sched/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/freezer.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/fault-inject.h>
 
 #include <asm/futex.h>
index b9132d1269ef1967950a804f7e21f3922cb491c8..cb8e3e8ac7b90b14b2bb0dd97dcdc7c5d02c3afe 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/lockdep.h>
 #include <linux/export.h>
 #include <linux/sysctl.h>
+#include <linux/suspend.h>
 #include <linux/utsname.h>
 #include <linux/sched/signal.h>
 #include <linux/sched/debug.h>
@@ -242,6 +243,28 @@ void reset_hung_task_detector(void)
 }
 EXPORT_SYMBOL_GPL(reset_hung_task_detector);
 
+static bool hung_detector_suspended;
+
+static int hungtask_pm_notify(struct notifier_block *self,
+                             unsigned long action, void *hcpu)
+{
+       switch (action) {
+       case PM_SUSPEND_PREPARE:
+       case PM_HIBERNATION_PREPARE:
+       case PM_RESTORE_PREPARE:
+               hung_detector_suspended = true;
+               break;
+       case PM_POST_SUSPEND:
+       case PM_POST_HIBERNATION:
+       case PM_POST_RESTORE:
+               hung_detector_suspended = false;
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
+
 /*
  * kthread which checks for tasks stuck in D state
  */
@@ -261,7 +284,8 @@ static int watchdog(void *dummy)
                interval = min_t(unsigned long, interval, timeout);
                t = hung_timeout_jiffies(hung_last_checked, interval);
                if (t <= 0) {
-                       if (!atomic_xchg(&reset_hung_task, 0))
+                       if (!atomic_xchg(&reset_hung_task, 0) &&
+                           !hung_detector_suspended)
                                check_hung_uninterruptible_tasks(timeout);
                        hung_last_checked = jiffies;
                        continue;
@@ -275,6 +299,10 @@ static int watchdog(void *dummy)
 static int __init hung_task_init(void)
 {
        atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+
+       /* Disable hung task detector on suspend */
+       pm_notifier(hungtask_pm_notify, 0);
+
        watchdog_task = kthread_run(watchdog, NULL, "khungtaskd");
 
        return 0;
index 0130e488ebfeffb606f13da9fe4d46e66e675bbe..8f36c27c17948c8e34b8488af540b60c35e77a22 100644 (file)
@@ -4,7 +4,7 @@
 #endif
 
 #include <linux/hash.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/debug_locks.h>
 
 /*
index 8b2e002d52eb0e6c927876077bddfcd0565d7929..f6d549a29a5c85cfdc2de0f07e6f0e956a1268ce 100644 (file)
@@ -136,7 +136,7 @@ void panic(const char *fmt, ...)
 {
        static char buf[1024];
        va_list args;
-       long i, i_next = 0;
+       long i, i_next = 0, len;
        int state = 0;
        int old_cpu, this_cpu;
        bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
@@ -173,8 +173,12 @@ void panic(const char *fmt, ...)
        console_verbose();
        bust_spinlocks(1);
        va_start(args, fmt);
-       vsnprintf(buf, sizeof(buf), fmt, args);
+       len = vscnprintf(buf, sizeof(buf), fmt, args);
        va_end(args);
+
+       if (len && buf[len - 1] == '\n')
+               buf[len - 1] = '\0';
+
        pr_emerg("Kernel panic - not syncing: %s\n", buf);
 #ifdef CONFIG_DEBUG_BUGVERBOSE
        /*
@@ -631,7 +635,7 @@ device_initcall(register_warn_debugfs);
  */
 __visible void __stack_chk_fail(void)
 {
-       panic("stack-protector: Kernel stack is corrupted in: %pB\n",
+       panic("stack-protector: Kernel stack is corrupted in: %pB",
                __builtin_return_address(0));
 }
 EXPORT_SYMBOL(__stack_chk_fail);
index cdf63e53a01425182d66f1c8883a249cedbaaa88..b2f6c506035da7c75b6b7e277f8d7c1a7ee244a2 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rculist.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/hash.h>
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
index 3d37c279c09008b74c41a71abb850bfcdaa99e99..b0308a2c6000d3bf34b897a5a2d248049cb4c492 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/pm.h>
 #include <linux/device.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/nmi.h>
 #include <linux/syscalls.h>
 #include <linux/console.h>
@@ -963,7 +963,8 @@ void __init __register_nosave_region(unsigned long start_pfn,
                BUG_ON(!region);
        } else {
                /* This allocation cannot fail */
-               region = memblock_virt_alloc(sizeof(struct nosave_region), 0);
+               region = memblock_alloc(sizeof(struct nosave_region),
+                                       SMP_CACHE_BYTES);
        }
        region->start_pfn = start_pfn;
        region->end_pfn = end_pfn;
index b77150ad1965a20b106e238f00c3c982b9eb3eef..1b2a029360b7ac2f4832c2e4cdeafca6dd803b14 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/delay.h>
 #include <linux/smp.h>
 #include <linux/security.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/syscalls.h>
 #include <linux/crash_core.h>
@@ -1111,9 +1110,9 @@ void __init setup_log_buf(int early)
 
        if (early) {
                new_log_buf =
-                       memblock_virt_alloc(new_log_buf_len, LOG_ALIGN);
+                       memblock_alloc(new_log_buf_len, LOG_ALIGN);
        } else {
-               new_log_buf = memblock_virt_alloc_nopanic(new_log_buf_len,
+               new_log_buf = memblock_alloc_nopanic(new_log_buf_len,
                                                          LOG_ALIGN);
        }
 
index 9aa2a4445b0d2a21c736b844f2df7acebe7b2158..9c08a2c7cb1d3567d2162128c51d52db00f9eaa5 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <linux/export.h>
 #include <linux/profile.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/notifier.h>
 #include <linux/mm.h>
 #include <linux/cpumask.h>
index fd2fce8a001be7375d4064de04dab71ac7eab307..f12225f26b70a630ac185cfccba2b140f191c47e 100644 (file)
@@ -2880,6 +2880,18 @@ unsigned long long nr_context_switches(void)
        return sum;
 }
 
+/*
+ * Consumers of these two interfaces, like for example the cpuidle menu
+ * governor, are using nonsensical data. Preferring shallow idle state selection
+ * for a CPU that has IO-wait which might not even end up running the task when
+ * it does become runnable.
+ */
+
+unsigned long nr_iowait_cpu(int cpu)
+{
+       return atomic_read(&cpu_rq(cpu)->nr_iowait);
+}
+
 /*
  * IO-wait accounting, and how its mostly bollocks (on SMP).
  *
@@ -2915,31 +2927,11 @@ unsigned long nr_iowait(void)
        unsigned long i, sum = 0;
 
        for_each_possible_cpu(i)
-               sum += atomic_read(&cpu_rq(i)->nr_iowait);
+               sum += nr_iowait_cpu(i);
 
        return sum;
 }
 
-/*
- * Consumers of these two interfaces, like for example the cpuidle menu
- * governor, are using nonsensical data. Preferring shallow idle state selection
- * for a CPU that has IO-wait which might not even end up running the task when
- * it does become runnable.
- */
-
-unsigned long nr_iowait_cpu(int cpu)
-{
-       struct rq *this = cpu_rq(cpu);
-       return atomic_read(&this->nr_iowait);
-}
-
-void get_iowait_load(unsigned long *nr_waiters, unsigned long *load)
-{
-       struct rq *rq = this_rq();
-       *nr_waiters = atomic_read(&rq->nr_iowait);
-       *load = rq->load.weight;
-}
-
 #ifdef CONFIG_SMP
 
 /*
index 17565240b1c620fb5b5ca4c2047412bd817cba1c..9a32bc2088c90c709cc2acc336f0ac3d68342931 100644 (file)
@@ -892,7 +892,7 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
                        /*
                         * The first thread which returns from do_signal_stop()
                         * will take ->siglock, notice SIGNAL_CLD_MASK, and
-                        * notify its parent. See get_signal_to_deliver().
+                        * notify its parent. See get_signal().
                         */
                        signal_set_stop_flags(signal, why | SIGNAL_STOP_CONTINUED);
                        signal->group_stop_count = 0;
index bf6f1d70484dc02a449fa71b73b753649b698715..ff1c4b20cd0a6d29209950fa006542c71b8c43ef 100644 (file)
@@ -2727,6 +2727,7 @@ void trace_dump_stack(int skip)
        __ftrace_trace_stack(global_trace.trace_buffer.buffer,
                             flags, skip, preempt_count(), NULL);
 }
+EXPORT_SYMBOL_GPL(trace_dump_stack);
 
 static DEFINE_PER_CPU(int, user_stack_count);
 
@@ -4621,13 +4622,18 @@ static const char readme_msg[] =
   "place (kretprobe): [<module>:]<symbol>[+<offset>]|<memaddr>\n"
 #endif
 #ifdef CONFIG_UPROBE_EVENTS
-       "\t    place: <path>:<offset>\n"
+  "   place (uprobe): <path>:<offset>[(ref_ctr_offset)]\n"
 #endif
        "\t     args: <name>=fetcharg[:type]\n"
        "\t fetcharg: %<register>, @<address>, @<symbol>[+|-<offset>],\n"
+#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
+       "\t           $stack<index>, $stack, $retval, $comm, $arg<N>\n"
+#else
        "\t           $stack<index>, $stack, $retval, $comm\n"
-       "\t     type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string,\n"
-       "\t           b<bit-width>@<bit-offset>/<container-size>\n"
+#endif
+       "\t     type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n"
+       "\t           b<bit-width>@<bit-offset>/<container-size>,\n"
+       "\t           <type>\\[<array-size>\\]\n"
 #endif
        "  events/\t\t- Directory containing all trace event subsystems:\n"
        "      enable\t\t- Write 0/1 to enable/disable tracing of all events\n"
index 69a3fe926e8cf9aeb28bb3d4fb712398fe12d2d5..76217bbef8154895b556c46a2ec51374f0ce5d70 100644 (file)
@@ -290,7 +290,8 @@ void perf_kprobe_destroy(struct perf_event *p_event)
 #endif /* CONFIG_KPROBE_EVENTS */
 
 #ifdef CONFIG_UPROBE_EVENTS
-int perf_uprobe_init(struct perf_event *p_event, bool is_retprobe)
+int perf_uprobe_init(struct perf_event *p_event,
+                    unsigned long ref_ctr_offset, bool is_retprobe)
 {
        int ret;
        char *path = NULL;
@@ -312,8 +313,8 @@ int perf_uprobe_init(struct perf_event *p_event, bool is_retprobe)
                goto out;
        }
 
-       tp_event = create_local_trace_uprobe(
-               path, p_event->attr.probe_offset, is_retprobe);
+       tp_event = create_local_trace_uprobe(path, p_event->attr.probe_offset,
+                                            ref_ctr_offset, is_retprobe);
        if (IS_ERR(tp_event)) {
                ret = PTR_ERR(tp_event);
                goto out;
index d239004aaf29052eec50aaf61772c2b0de7c7947..eb908ef2ececf336fc2ed8996439005a32f5afc9 100644 (file)
@@ -1063,8 +1063,10 @@ static int create_synth_event(int argc, char **argv)
                event = NULL;
                ret = -EEXIST;
                goto out;
-       } else if (delete_event)
+       } else if (delete_event) {
+               ret = -ENOENT;
                goto out;
+       }
 
        if (argc < 2) {
                ret = -EINVAL;
index c30032367aab4a5c83a013d615830cda97a82f8a..fec67188c4d28542f0b88f9ca9aca5fee5668e8d 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "trace_kprobe_selftest.h"
 #include "trace_probe.h"
+#include "trace_probe_tmpl.h"
 
 #define KPROBE_EVENT_SYSTEM "kprobes"
 #define KRETPROBE_MAXACTIVE_MAX 4096
@@ -61,9 +62,23 @@ static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
        return strncmp(mod->name, name, len) == 0 && name[len] == ':';
 }
 
-static nokprobe_inline bool trace_kprobe_is_on_module(struct trace_kprobe *tk)
+static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
 {
-       return !!strchr(trace_kprobe_symbol(tk), ':');
+       char *p;
+       bool ret;
+
+       if (!tk->symbol)
+               return false;
+       p = strchr(tk->symbol, ':');
+       if (!p)
+               return true;
+       *p = '\0';
+       mutex_lock(&module_mutex);
+       ret = !!find_module(tk->symbol);
+       mutex_unlock(&module_mutex);
+       *p = ':';
+
+       return ret;
 }
 
 static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
@@ -120,184 +135,6 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
 static int kretprobe_dispatcher(struct kretprobe_instance *ri,
                                struct pt_regs *regs);
 
-/* Memory fetching by symbol */
-struct symbol_cache {
-       char            *symbol;
-       long            offset;
-       unsigned long   addr;
-};
-
-unsigned long update_symbol_cache(struct symbol_cache *sc)
-{
-       sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
-
-       if (sc->addr)
-               sc->addr += sc->offset;
-
-       return sc->addr;
-}
-
-void free_symbol_cache(struct symbol_cache *sc)
-{
-       kfree(sc->symbol);
-       kfree(sc);
-}
-
-struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
-{
-       struct symbol_cache *sc;
-
-       if (!sym || strlen(sym) == 0)
-               return NULL;
-
-       sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
-       if (!sc)
-               return NULL;
-
-       sc->symbol = kstrdup(sym, GFP_KERNEL);
-       if (!sc->symbol) {
-               kfree(sc);
-               return NULL;
-       }
-       sc->offset = offset;
-       update_symbol_cache(sc);
-
-       return sc;
-}
-
-/*
- * Kprobes-specific fetch functions
- */
-#define DEFINE_FETCH_stack(type)                                       \
-static void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,         \
-                                         void *offset, void *dest)     \
-{                                                                      \
-       *(type *)dest = (type)regs_get_kernel_stack_nth(regs,           \
-                               (unsigned int)((unsigned long)offset)); \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(stack, type));
-
-DEFINE_BASIC_FETCH_FUNCS(stack)
-/* No string on the stack entry */
-#define fetch_stack_string     NULL
-#define fetch_stack_string_size        NULL
-
-#define DEFINE_FETCH_memory(type)                                      \
-static void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,                \
-                                         void *addr, void *dest)       \
-{                                                                      \
-       type retval;                                                    \
-       if (probe_kernel_address(addr, retval))                         \
-               *(type *)dest = 0;                                      \
-       else                                                            \
-               *(type *)dest = retval;                                 \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, type));
-
-DEFINE_BASIC_FETCH_FUNCS(memory)
-/*
- * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
- * length and relative data location.
- */
-static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
-                                           void *addr, void *dest)
-{
-       int maxlen = get_rloc_len(*(u32 *)dest);
-       u8 *dst = get_rloc_data(dest);
-       long ret;
-
-       if (!maxlen)
-               return;
-
-       /*
-        * Try to get string again, since the string can be changed while
-        * probing.
-        */
-       ret = strncpy_from_unsafe(dst, addr, maxlen);
-
-       if (ret < 0) {  /* Failed to fetch string */
-               dst[0] = '\0';
-               *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
-       } else {
-               *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest));
-       }
-}
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string));
-
-/* Return the length of string -- including null terminal byte */
-static void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
-                                                void *addr, void *dest)
-{
-       mm_segment_t old_fs;
-       int ret, len = 0;
-       u8 c;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       pagefault_disable();
-
-       do {
-               ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
-               len++;
-       } while (c && ret == 0 && len < MAX_STRING_SIZE);
-
-       pagefault_enable();
-       set_fs(old_fs);
-
-       if (ret < 0)    /* Failed to check the length */
-               *(u32 *)dest = 0;
-       else
-               *(u32 *)dest = len;
-}
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string_size));
-
-#define DEFINE_FETCH_symbol(type)                                      \
-void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs, void *data, void *dest)\
-{                                                                      \
-       struct symbol_cache *sc = data;                                 \
-       if (sc->addr)                                                   \
-               fetch_memory_##type(regs, (void *)sc->addr, dest);      \
-       else                                                            \
-               *(type *)dest = 0;                                      \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(symbol, type));
-
-DEFINE_BASIC_FETCH_FUNCS(symbol)
-DEFINE_FETCH_symbol(string)
-DEFINE_FETCH_symbol(string_size)
-
-/* kprobes don't support file_offset fetch methods */
-#define fetch_file_offset_u8           NULL
-#define fetch_file_offset_u16          NULL
-#define fetch_file_offset_u32          NULL
-#define fetch_file_offset_u64          NULL
-#define fetch_file_offset_string       NULL
-#define fetch_file_offset_string_size  NULL
-
-/* Fetch type information table */
-static const struct fetch_type kprobes_fetch_type_table[] = {
-       /* Special types */
-       [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
-                                       sizeof(u32), 1, "__data_loc char[]"),
-       [FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
-                                       string_size, sizeof(u32), 0, "u32"),
-       /* Basic types */
-       ASSIGN_FETCH_TYPE(u8,  u8,  0),
-       ASSIGN_FETCH_TYPE(u16, u16, 0),
-       ASSIGN_FETCH_TYPE(u32, u32, 0),
-       ASSIGN_FETCH_TYPE(u64, u64, 0),
-       ASSIGN_FETCH_TYPE(s8,  u8,  1),
-       ASSIGN_FETCH_TYPE(s16, u16, 1),
-       ASSIGN_FETCH_TYPE(s32, u32, 1),
-       ASSIGN_FETCH_TYPE(s64, u64, 1),
-       ASSIGN_FETCH_TYPE_ALIAS(x8,  u8,  u8,  0),
-       ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
-       ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
-       ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
-
-       ASSIGN_FETCH_TYPE_END
-};
-
 /*
  * Allocate new trace_probe and initialize it (including kprobes).
  */
@@ -540,8 +377,11 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
                return -EINVAL;
        }
 
-       for (i = 0; i < tk->tp.nr_args; i++)
-               traceprobe_update_arg(&tk->tp.args[i]);
+       for (i = 0; i < tk->tp.nr_args; i++) {
+               ret = traceprobe_update_arg(&tk->tp.args[i]);
+               if (ret)
+                       return ret;
+       }
 
        /* Set/clear disabled flag according to tp->flag */
        if (trace_probe_is_enabled(&tk->tp))
@@ -554,19 +394,13 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
        else
                ret = register_kprobe(&tk->rp.kp);
 
-       if (ret == 0)
+       if (ret == 0) {
                tk->tp.flags |= TP_FLAG_REGISTERED;
-       else {
-               if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) {
-                       pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
-                       ret = 0;
-               } else if (ret == -EILSEQ) {
-                       pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
-                               tk->rp.kp.addr);
-                       ret = -EINVAL;
-               }
+       } else if (ret == -EILSEQ) {
+               pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
+                       tk->rp.kp.addr);
+               ret = -EINVAL;
        }
-
        return ret;
 }
 
@@ -629,6 +463,11 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
 
        /* Register k*probe */
        ret = __register_trace_kprobe(tk);
+       if (ret == -ENOENT && !trace_kprobe_module_exist(tk)) {
+               pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
+               ret = 0;
+       }
+
        if (ret < 0)
                unregister_kprobe_event(tk);
        else
@@ -713,13 +552,15 @@ static int create_trace_kprobe(int argc, char **argv)
        long offset = 0;
        void *addr = NULL;
        char buf[MAX_EVENT_NAME_LEN];
+       unsigned int flags = TPARG_FL_KERNEL;
 
        /* argc must be >= 1 */
        if (argv[0][0] == 'p')
                is_return = false;
-       else if (argv[0][0] == 'r')
+       else if (argv[0][0] == 'r') {
                is_return = true;
-       else if (argv[0][0] == '-')
+               flags |= TPARG_FL_RETURN;
+       } else if (argv[0][0] == '-')
                is_delete = true;
        else {
                pr_info("Probe definition must be started with 'p', 'r' or"
@@ -749,10 +590,13 @@ static int create_trace_kprobe(int argc, char **argv)
        }
 
        if (event) {
-               if (strchr(event, '/')) {
+               char *slash;
+
+               slash = strchr(event, '/');
+               if (slash) {
                        group = event;
-                       event = strchr(group, '/') + 1;
-                       event[-1] = '\0';
+                       event = slash + 1;
+                       slash[0] = '\0';
                        if (strlen(group) == 0) {
                                pr_info("Group name is not specified\n");
                                return -EINVAL;
@@ -802,8 +646,9 @@ static int create_trace_kprobe(int argc, char **argv)
                        pr_info("Failed to parse either an address or a symbol.\n");
                        return ret;
                }
-               if (offset && is_return &&
-                   !kprobe_on_func_entry(NULL, symbol, offset)) {
+               if (kprobe_on_func_entry(NULL, symbol, offset))
+                       flags |= TPARG_FL_FENTRY;
+               if (offset && is_return && !(flags & TPARG_FL_FENTRY)) {
                        pr_info("Given offset is not valid for return probe.\n");
                        return -EINVAL;
                }
@@ -873,8 +718,7 @@ static int create_trace_kprobe(int argc, char **argv)
 
                /* Parse fetch argument */
                ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg,
-                                               is_return, true,
-                                               kprobes_fetch_type_table);
+                                                flags);
                if (ret) {
                        pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
                        goto error;
@@ -1028,6 +872,106 @@ static const struct file_operations kprobe_profile_ops = {
        .release        = seq_release,
 };
 
+/* Kprobe specific fetch functions */
+
+/* Return the length of string -- including null terminal byte */
+static nokprobe_inline int
+fetch_store_strlen(unsigned long addr)
+{
+       mm_segment_t old_fs;
+       int ret, len = 0;
+       u8 c;
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       pagefault_disable();
+
+       do {
+               ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
+               len++;
+       } while (c && ret == 0 && len < MAX_STRING_SIZE);
+
+       pagefault_enable();
+       set_fs(old_fs);
+
+       return (ret < 0) ? ret : len;
+}
+
+/*
+ * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
+ * length and relative data location.
+ */
+static nokprobe_inline int
+fetch_store_string(unsigned long addr, void *dest, void *base)
+{
+       int maxlen = get_loc_len(*(u32 *)dest);
+       u8 *dst = get_loc_data(dest, base);
+       long ret;
+
+       if (unlikely(!maxlen))
+               return -ENOMEM;
+       /*
+        * Try to get string again, since the string can be changed while
+        * probing.
+        */
+       ret = strncpy_from_unsafe(dst, (void *)addr, maxlen);
+
+       if (ret >= 0)
+               *(u32 *)dest = make_data_loc(ret, (void *)dst - base);
+       return ret;
+}
+
+static nokprobe_inline int
+probe_mem_read(void *dest, void *src, size_t size)
+{
+       return probe_kernel_read(dest, src, size);
+}
+
+/* Note that we don't verify it, since the code does not come from user space */
+static int
+process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
+                  void *base)
+{
+       unsigned long val;
+
+retry:
+       /* 1st stage: get value from context */
+       switch (code->op) {
+       case FETCH_OP_REG:
+               val = regs_get_register(regs, code->param);
+               break;
+       case FETCH_OP_STACK:
+               val = regs_get_kernel_stack_nth(regs, code->param);
+               break;
+       case FETCH_OP_STACKP:
+               val = kernel_stack_pointer(regs);
+               break;
+       case FETCH_OP_RETVAL:
+               val = regs_return_value(regs);
+               break;
+       case FETCH_OP_IMM:
+               val = code->immediate;
+               break;
+       case FETCH_OP_COMM:
+               val = (unsigned long)current->comm;
+               break;
+#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
+       case FETCH_OP_ARG:
+               val = regs_get_kernel_argument(regs, code->param);
+               break;
+#endif
+       case FETCH_NOP_SYMBOL:  /* Ignore a place holder */
+               code++;
+               goto retry;
+       default:
+               return -EILSEQ;
+       }
+       code++;
+
+       return process_fetch_insn_bottom(code, val, dest, base);
+}
+NOKPROBE_SYMBOL(process_fetch_insn)
+
 /* Kprobe handler */
 static nokprobe_inline void
 __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
@@ -1059,7 +1003,7 @@ __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
 
        entry = ring_buffer_event_data(event);
        entry->ip = (unsigned long)tk->rp.kp.addr;
-       store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
+       store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
 
        event_trigger_unlock_commit_regs(trace_file, buffer, event,
                                         entry, irq_flags, pc, regs);
@@ -1108,7 +1052,7 @@ __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
        entry = ring_buffer_event_data(event);
        entry->func = (unsigned long)tk->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
-       store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
+       store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
 
        event_trigger_unlock_commit_regs(trace_file, buffer, event,
                                         entry, irq_flags, pc, regs);
@@ -1133,8 +1077,6 @@ print_kprobe_event(struct trace_iterator *iter, int flags,
        struct kprobe_trace_entry_head *field;
        struct trace_seq *s = &iter->seq;
        struct trace_probe *tp;
-       u8 *data;
-       int i;
 
        field = (struct kprobe_trace_entry_head *)iter->ent;
        tp = container_of(event, struct trace_probe, call.event);
@@ -1146,11 +1088,9 @@ print_kprobe_event(struct trace_iterator *iter, int flags,
 
        trace_seq_putc(s, ')');
 
-       data = (u8 *)&field[1];
-       for (i = 0; i < tp->nr_args; i++)
-               if (!tp->args[i].type->print(s, tp->args[i].name,
-                                            data + tp->args[i].offset, field))
-                       goto out;
+       if (print_probe_args(s, tp->args, tp->nr_args,
+                            (u8 *)&field[1], field) < 0)
+               goto out;
 
        trace_seq_putc(s, '\n');
  out:
@@ -1164,8 +1104,6 @@ print_kretprobe_event(struct trace_iterator *iter, int flags,
        struct kretprobe_trace_entry_head *field;
        struct trace_seq *s = &iter->seq;
        struct trace_probe *tp;
-       u8 *data;
-       int i;
 
        field = (struct kretprobe_trace_entry_head *)iter->ent;
        tp = container_of(event, struct trace_probe, call.event);
@@ -1182,11 +1120,9 @@ print_kretprobe_event(struct trace_iterator *iter, int flags,
 
        trace_seq_putc(s, ')');
 
-       data = (u8 *)&field[1];
-       for (i = 0; i < tp->nr_args; i++)
-               if (!tp->args[i].type->print(s, tp->args[i].name,
-                                            data + tp->args[i].offset, field))
-                       goto out;
+       if (print_probe_args(s, tp->args, tp->nr_args,
+                            (u8 *)&field[1], field) < 0)
+               goto out;
 
        trace_seq_putc(s, '\n');
 
@@ -1197,49 +1133,25 @@ print_kretprobe_event(struct trace_iterator *iter, int flags,
 
 static int kprobe_event_define_fields(struct trace_event_call *event_call)
 {
-       int ret, i;
+       int ret;
        struct kprobe_trace_entry_head field;
        struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
 
        DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
-       /* Set argument names as fields */
-       for (i = 0; i < tk->tp.nr_args; i++) {
-               struct probe_arg *parg = &tk->tp.args[i];
 
-               ret = trace_define_field(event_call, parg->type->fmttype,
-                                        parg->name,
-                                        sizeof(field) + parg->offset,
-                                        parg->type->size,
-                                        parg->type->is_signed,
-                                        FILTER_OTHER);
-               if (ret)
-                       return ret;
-       }
-       return 0;
+       return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
 }
 
 static int kretprobe_event_define_fields(struct trace_event_call *event_call)
 {
-       int ret, i;
+       int ret;
        struct kretprobe_trace_entry_head field;
        struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
 
        DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
        DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
-       /* Set argument names as fields */
-       for (i = 0; i < tk->tp.nr_args; i++) {
-               struct probe_arg *parg = &tk->tp.args[i];
 
-               ret = trace_define_field(event_call, parg->type->fmttype,
-                                        parg->name,
-                                        sizeof(field) + parg->offset,
-                                        parg->type->size,
-                                        parg->type->is_signed,
-                                        FILTER_OTHER);
-               if (ret)
-                       return ret;
-       }
-       return 0;
+       return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
 }
 
 #ifdef CONFIG_PERF_EVENTS
@@ -1286,7 +1198,7 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
 
        entry->ip = (unsigned long)tk->rp.kp.addr;
        memset(&entry[1], 0, dsize);
-       store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
+       store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
        perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
                              head, NULL);
        return 0;
@@ -1322,7 +1234,7 @@ kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
 
        entry->func = (unsigned long)tk->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
-       store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
+       store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
        perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
                              head, NULL);
 }
@@ -1457,7 +1369,7 @@ static int register_kprobe_event(struct trace_kprobe *tk)
 
        init_trace_event_call(tk, call);
 
-       if (set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0)
+       if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0)
                return -ENOMEM;
        ret = register_trace_event(&call->event);
        if (!ret) {
@@ -1514,7 +1426,7 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
 
        init_trace_event_call(tk, &tk->tp.call);
 
-       if (set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
+       if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
                ret = -ENOMEM;
                goto error;
        }
index b0875b327f5c3d5c733f79337bef40d5d600fbd1..c3fd849d4a8f93c27d18713ae1e492faa5d24ec9 100644 (file)
@@ -115,7 +115,7 @@ static int module_trace_bprintk_format_notify(struct notifier_block *self,
  * section, then we need to read the link list pointers. The trick is
  * we pass the address of the string to the seq function just like
  * we do for the kernel core formats. To get back the structure that
- * holds the format, we simply use containerof() and then go to the
+ * holds the format, we simply use container_of() and then go to the
  * next format in the list.
  */
 static const char **
index e99c3ce7aa6541144da74e50a011e230bd25e0b0..3ef15a6683c002bc2c5402b5be8ad07c903021bc 100644 (file)
@@ -26,14 +26,12 @@ const char *reserved_field_names[] = {
 
 /* Printing  in basic type function template */
 #define DEFINE_BASIC_PRINT_TYPE_FUNC(tname, type, fmt)                 \
-int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, const char *name, \
-                               void *data, void *ent)                  \
+int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, void *data, void *ent)\
 {                                                                      \
-       trace_seq_printf(s, " %s=" fmt, name, *(type *)data);           \
+       trace_seq_printf(s, fmt, *(type *)data);                        \
        return !trace_seq_has_overflowed(s);                            \
 }                                                                      \
-const char PRINT_TYPE_FMT_NAME(tname)[] = fmt;                         \
-NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(tname));
+const char PRINT_TYPE_FMT_NAME(tname)[] = fmt;
 
 DEFINE_BASIC_PRINT_TYPE_FUNC(u8,  u8,  "%u")
 DEFINE_BASIC_PRINT_TYPE_FUNC(u16, u16, "%u")
@@ -48,193 +46,52 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x")
 DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x")
 DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx")
 
+int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent)
+{
+       trace_seq_printf(s, "%pS", (void *)*(unsigned long *)data);
+       return !trace_seq_has_overflowed(s);
+}
+const char PRINT_TYPE_FMT_NAME(symbol)[] = "%pS";
+
 /* Print type function for string type */
-int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, const char *name,
-                                void *data, void *ent)
+int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent)
 {
        int len = *(u32 *)data >> 16;
 
        if (!len)
-               trace_seq_printf(s, " %s=(fault)", name);
+               trace_seq_puts(s, "(fault)");
        else
-               trace_seq_printf(s, " %s=\"%s\"", name,
+               trace_seq_printf(s, "\"%s\"",
                                 (const char *)get_loc_data(data, ent));
        return !trace_seq_has_overflowed(s);
 }
-NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(string));
 
 const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
 
-#define CHECK_FETCH_FUNCS(method, fn)                  \
-       (((FETCH_FUNC_NAME(method, u8) == fn) ||        \
-         (FETCH_FUNC_NAME(method, u16) == fn) ||       \
-         (FETCH_FUNC_NAME(method, u32) == fn) ||       \
-         (FETCH_FUNC_NAME(method, u64) == fn) ||       \
-         (FETCH_FUNC_NAME(method, string) == fn) ||    \
-         (FETCH_FUNC_NAME(method, string_size) == fn)) \
-        && (fn != NULL))
-
-/* Data fetch function templates */
-#define DEFINE_FETCH_reg(type)                                         \
-void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, void *offset, void *dest)        \
-{                                                                      \
-       *(type *)dest = (type)regs_get_register(regs,                   \
-                               (unsigned int)((unsigned long)offset)); \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(reg, type));
-DEFINE_BASIC_FETCH_FUNCS(reg)
-/* No string on the register */
-#define fetch_reg_string       NULL
-#define fetch_reg_string_size  NULL
-
-#define DEFINE_FETCH_retval(type)                                      \
-void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,               \
-                                  void *dummy, void *dest)             \
-{                                                                      \
-       *(type *)dest = (type)regs_return_value(regs);                  \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(retval, type));
-DEFINE_BASIC_FETCH_FUNCS(retval)
-/* No string on the retval */
-#define fetch_retval_string            NULL
-#define fetch_retval_string_size       NULL
-
-/* Dereference memory access function */
-struct deref_fetch_param {
-       struct fetch_param      orig;
-       long                    offset;
-       fetch_func_t            fetch;
-       fetch_func_t            fetch_size;
+/* Fetch type information table */
+static const struct fetch_type probe_fetch_types[] = {
+       /* Special types */
+       __ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1,
+                           "__data_loc char[]"),
+       /* Basic types */
+       ASSIGN_FETCH_TYPE(u8,  u8,  0),
+       ASSIGN_FETCH_TYPE(u16, u16, 0),
+       ASSIGN_FETCH_TYPE(u32, u32, 0),
+       ASSIGN_FETCH_TYPE(u64, u64, 0),
+       ASSIGN_FETCH_TYPE(s8,  u8,  1),
+       ASSIGN_FETCH_TYPE(s16, u16, 1),
+       ASSIGN_FETCH_TYPE(s32, u32, 1),
+       ASSIGN_FETCH_TYPE(s64, u64, 1),
+       ASSIGN_FETCH_TYPE_ALIAS(x8,  u8,  u8,  0),
+       ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
+       ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
+       ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
+       ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0),
+
+       ASSIGN_FETCH_TYPE_END
 };
 
-#define DEFINE_FETCH_deref(type)                                       \
-void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,                        \
-                                 void *data, void *dest)               \
-{                                                                      \
-       struct deref_fetch_param *dprm = data;                          \
-       unsigned long addr;                                             \
-       call_fetch(&dprm->orig, regs, &addr);                           \
-       if (addr) {                                                     \
-               addr += dprm->offset;                                   \
-               dprm->fetch(regs, (void *)addr, dest);                  \
-       } else                                                          \
-               *(type *)dest = 0;                                      \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, type));
-DEFINE_BASIC_FETCH_FUNCS(deref)
-DEFINE_FETCH_deref(string)
-
-void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs,
-                                        void *data, void *dest)
-{
-       struct deref_fetch_param *dprm = data;
-       unsigned long addr;
-
-       call_fetch(&dprm->orig, regs, &addr);
-       if (addr && dprm->fetch_size) {
-               addr += dprm->offset;
-               dprm->fetch_size(regs, (void *)addr, dest);
-       } else
-               *(string_size *)dest = 0;
-}
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, string_size));
-
-static void update_deref_fetch_param(struct deref_fetch_param *data)
-{
-       if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-               update_deref_fetch_param(data->orig.data);
-       else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-               update_symbol_cache(data->orig.data);
-}
-NOKPROBE_SYMBOL(update_deref_fetch_param);
-
-static void free_deref_fetch_param(struct deref_fetch_param *data)
-{
-       if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-               free_deref_fetch_param(data->orig.data);
-       else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-               free_symbol_cache(data->orig.data);
-       kfree(data);
-}
-NOKPROBE_SYMBOL(free_deref_fetch_param);
-
-/* Bitfield fetch function */
-struct bitfield_fetch_param {
-       struct fetch_param      orig;
-       unsigned char           hi_shift;
-       unsigned char           low_shift;
-};
-
-#define DEFINE_FETCH_bitfield(type)                                    \
-void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,             \
-                                    void *data, void *dest)            \
-{                                                                      \
-       struct bitfield_fetch_param *bprm = data;                       \
-       type buf = 0;                                                   \
-       call_fetch(&bprm->orig, regs, &buf);                            \
-       if (buf) {                                                      \
-               buf <<= bprm->hi_shift;                                 \
-               buf >>= bprm->low_shift;                                \
-       }                                                               \
-       *(type *)dest = buf;                                            \
-}                                                                      \
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(bitfield, type));
-DEFINE_BASIC_FETCH_FUNCS(bitfield)
-#define fetch_bitfield_string          NULL
-#define fetch_bitfield_string_size     NULL
-
-static void
-update_bitfield_fetch_param(struct bitfield_fetch_param *data)
-{
-       /*
-        * Don't check the bitfield itself, because this must be the
-        * last fetch function.
-        */
-       if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-               update_deref_fetch_param(data->orig.data);
-       else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-               update_symbol_cache(data->orig.data);
-}
-
-static void
-free_bitfield_fetch_param(struct bitfield_fetch_param *data)
-{
-       /*
-        * Don't check the bitfield itself, because this must be the
-        * last fetch function.
-        */
-       if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-               free_deref_fetch_param(data->orig.data);
-       else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-               free_symbol_cache(data->orig.data);
-
-       kfree(data);
-}
-
-void FETCH_FUNC_NAME(comm, string)(struct pt_regs *regs,
-                                         void *data, void *dest)
-{
-       int maxlen = get_rloc_len(*(u32 *)dest);
-       u8 *dst = get_rloc_data(dest);
-       long ret;
-
-       if (!maxlen)
-               return;
-
-       ret = strlcpy(dst, current->comm, maxlen);
-       *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest));
-}
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string));
-
-void FETCH_FUNC_NAME(comm, string_size)(struct pt_regs *regs,
-                                              void *data, void *dest)
-{
-       *(u32 *)dest = strlen(current->comm) + 1;
-}
-NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string_size));
-
-static const struct fetch_type *find_fetch_type(const char *type,
-                                               const struct fetch_type *ftbl)
+static const struct fetch_type *find_fetch_type(const char *type)
 {
        int i;
 
@@ -255,58 +112,27 @@ static const struct fetch_type *find_fetch_type(const char *type,
 
                switch (bs) {
                case 8:
-                       return find_fetch_type("u8", ftbl);
+                       return find_fetch_type("u8");
                case 16:
-                       return find_fetch_type("u16", ftbl);
+                       return find_fetch_type("u16");
                case 32:
-                       return find_fetch_type("u32", ftbl);
+                       return find_fetch_type("u32");
                case 64:
-                       return find_fetch_type("u64", ftbl);
+                       return find_fetch_type("u64");
                default:
                        goto fail;
                }
        }
 
-       for (i = 0; ftbl[i].name; i++) {
-               if (strcmp(type, ftbl[i].name) == 0)
-                       return &ftbl[i];
+       for (i = 0; probe_fetch_types[i].name; i++) {
+               if (strcmp(type, probe_fetch_types[i].name) == 0)
+                       return &probe_fetch_types[i];
        }
 
 fail:
        return NULL;
 }
 
-/* Special function : only accept unsigned long */
-static void fetch_kernel_stack_address(struct pt_regs *regs, void *dummy, void *dest)
-{
-       *(unsigned long *)dest = kernel_stack_pointer(regs);
-}
-NOKPROBE_SYMBOL(fetch_kernel_stack_address);
-
-static void fetch_user_stack_address(struct pt_regs *regs, void *dummy, void *dest)
-{
-       *(unsigned long *)dest = user_stack_pointer(regs);
-}
-NOKPROBE_SYMBOL(fetch_user_stack_address);
-
-static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
-                                           fetch_func_t orig_fn,
-                                           const struct fetch_type *ftbl)
-{
-       int i;
-
-       if (type != &ftbl[FETCH_TYPE_STRING])
-               return NULL;    /* Only string type needs size function */
-
-       for (i = 0; i < FETCH_MTD_END; i++)
-               if (type->fetch[i] == orig_fn)
-                       return ftbl[FETCH_TYPE_STRSIZE].fetch[i];
-
-       WARN_ON(1);     /* This should not happen */
-
-       return NULL;
-}
-
 /* Split symbol and offset. */
 int traceprobe_split_symbol_offset(char *symbol, long *offset)
 {
@@ -331,41 +157,44 @@ int traceprobe_split_symbol_offset(char *symbol, long *offset)
 #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
 
 static int parse_probe_vars(char *arg, const struct fetch_type *t,
-                           struct fetch_param *f, bool is_return,
-                           bool is_kprobe)
+                           struct fetch_insn *code, unsigned int flags)
 {
        int ret = 0;
        unsigned long param;
 
        if (strcmp(arg, "retval") == 0) {
-               if (is_return)
-                       f->fn = t->fetch[FETCH_MTD_retval];
+               if (flags & TPARG_FL_RETURN)
+                       code->op = FETCH_OP_RETVAL;
                else
                        ret = -EINVAL;
        } else if (strncmp(arg, "stack", 5) == 0) {
                if (arg[5] == '\0') {
-                       if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR))
-                               return -EINVAL;
-
-                       if (is_kprobe)
-                               f->fn = fetch_kernel_stack_address;
-                       else
-                               f->fn = fetch_user_stack_address;
+                       code->op = FETCH_OP_STACKP;
                } else if (isdigit(arg[5])) {
                        ret = kstrtoul(arg + 5, 10, &param);
-                       if (ret || (is_kprobe && param > PARAM_MAX_STACK))
+                       if (ret || ((flags & TPARG_FL_KERNEL) &&
+                                   param > PARAM_MAX_STACK))
                                ret = -EINVAL;
                        else {
-                               f->fn = t->fetch[FETCH_MTD_stack];
-                               f->data = (void *)param;
+                               code->op = FETCH_OP_STACK;
+                               code->param = (unsigned int)param;
                        }
                } else
                        ret = -EINVAL;
        } else if (strcmp(arg, "comm") == 0) {
-               if (strcmp(t->name, "string") != 0 &&
-                   strcmp(t->name, "string_size") != 0)
+               code->op = FETCH_OP_COMM;
+#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
+       } else if (((flags & TPARG_FL_MASK) ==
+                   (TPARG_FL_KERNEL | TPARG_FL_FENTRY)) &&
+                  strncmp(arg, "arg", 3) == 0) {
+               if (!isdigit(arg[3]))
+                       return -EINVAL;
+               ret = kstrtoul(arg + 3, 10, &param);
+               if (ret || !param || param > PARAM_MAX_STACK)
                        return -EINVAL;
-               f->fn = t->fetch[FETCH_MTD_comm];
+               code->op = FETCH_OP_ARG;
+               code->param = (unsigned int)param - 1;
+#endif
        } else
                ret = -EINVAL;
 
@@ -373,25 +202,27 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
 }
 
 /* Recursive argument parser */
-static int parse_probe_arg(char *arg, const struct fetch_type *t,
-                    struct fetch_param *f, bool is_return, bool is_kprobe,
-                    const struct fetch_type *ftbl)
+static int
+parse_probe_arg(char *arg, const struct fetch_type *type,
+               struct fetch_insn **pcode, struct fetch_insn *end,
+               unsigned int flags)
 {
+       struct fetch_insn *code = *pcode;
        unsigned long param;
-       long offset;
+       long offset = 0;
        char *tmp;
        int ret = 0;
 
        switch (arg[0]) {
        case '$':
-               ret = parse_probe_vars(arg + 1, t, f, is_return, is_kprobe);
+               ret = parse_probe_vars(arg + 1, type, code, flags);
                break;
 
        case '%':       /* named register */
                ret = regs_query_register_offset(arg + 1);
                if (ret >= 0) {
-                       f->fn = t->fetch[FETCH_MTD_reg];
-                       f->data = (void *)(unsigned long)ret;
+                       code->op = FETCH_OP_REG;
+                       code->param = (unsigned int)ret;
                        ret = 0;
                }
                break;
@@ -401,33 +232,42 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
                        ret = kstrtoul(arg + 1, 0, &param);
                        if (ret)
                                break;
-
-                       f->fn = t->fetch[FETCH_MTD_memory];
-                       f->data = (void *)param;
+                       /* load address */
+                       code->op = FETCH_OP_IMM;
+                       code->immediate = param;
                } else if (arg[1] == '+') {
                        /* kprobes don't support file offsets */
-                       if (is_kprobe)
+                       if (flags & TPARG_FL_KERNEL)
                                return -EINVAL;
 
                        ret = kstrtol(arg + 2, 0, &offset);
                        if (ret)
                                break;
 
-                       f->fn = t->fetch[FETCH_MTD_file_offset];
-                       f->data = (void *)offset;
+                       code->op = FETCH_OP_FOFFS;
+                       code->immediate = (unsigned long)offset;  // imm64?
                } else {
                        /* uprobes don't support symbols */
-                       if (!is_kprobe)
+                       if (!(flags & TPARG_FL_KERNEL))
                                return -EINVAL;
 
-                       ret = traceprobe_split_symbol_offset(arg + 1, &offset);
-                       if (ret)
-                               break;
+                       /* Preserve symbol for updating */
+                       code->op = FETCH_NOP_SYMBOL;
+                       code->data = kstrdup(arg + 1, GFP_KERNEL);
+                       if (!code->data)
+                               return -ENOMEM;
+                       if (++code == end)
+                               return -E2BIG;
 
-                       f->data = alloc_symbol_cache(arg + 1, offset);
-                       if (f->data)
-                               f->fn = t->fetch[FETCH_MTD_symbol];
+                       code->op = FETCH_OP_IMM;
+                       code->immediate = 0;
                }
+               /* These are fetching from memory */
+               if (++code == end)
+                       return -E2BIG;
+               *pcode = code;
+               code->op = FETCH_OP_DEREF;
+               code->offset = offset;
                break;
 
        case '+':       /* deref memory */
@@ -435,11 +275,10 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
        case '-':
                tmp = strchr(arg, '(');
                if (!tmp)
-                       break;
+                       return -EINVAL;
 
                *tmp = '\0';
                ret = kstrtol(arg, 0, &offset);
-
                if (ret)
                        break;
 
@@ -447,36 +286,27 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
                tmp = strrchr(arg, ')');
 
                if (tmp) {
-                       struct deref_fetch_param        *dprm;
-                       const struct fetch_type         *t2;
+                       const struct fetch_type *t2 = find_fetch_type(NULL);
 
-                       t2 = find_fetch_type(NULL, ftbl);
                        *tmp = '\0';
-                       dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL);
-
-                       if (!dprm)
-                               return -ENOMEM;
-
-                       dprm->offset = offset;
-                       dprm->fetch = t->fetch[FETCH_MTD_memory];
-                       dprm->fetch_size = get_fetch_size_function(t,
-                                                       dprm->fetch, ftbl);
-                       ret = parse_probe_arg(arg, t2, &dprm->orig, is_return,
-                                                       is_kprobe, ftbl);
+                       ret = parse_probe_arg(arg, t2, &code, end, flags);
                        if (ret)
-                               kfree(dprm);
-                       else {
-                               f->fn = t->fetch[FETCH_MTD_deref];
-                               f->data = (void *)dprm;
-                       }
+                               break;
+                       if (code->op == FETCH_OP_COMM)
+                               return -EINVAL;
+                       if (++code == end)
+                               return -E2BIG;
+                       *pcode = code;
+
+                       code->op = FETCH_OP_DEREF;
+                       code->offset = offset;
                }
                break;
        }
-       if (!ret && !f->fn) {   /* Parsed, but do not find fetch method */
-               pr_info("%s type has no corresponding fetch method.\n", t->name);
+       if (!ret && code->op == FETCH_OP_NOP) {
+               /* Parsed, but do not find fetch method */
                ret = -EINVAL;
        }
-
        return ret;
 }
 
@@ -485,22 +315,15 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
 /* Bitfield type needs to be parsed into a fetch function */
 static int __parse_bitfield_probe_arg(const char *bf,
                                      const struct fetch_type *t,
-                                     struct fetch_param *f)
+                                     struct fetch_insn **pcode)
 {
-       struct bitfield_fetch_param *bprm;
+       struct fetch_insn *code = *pcode;
        unsigned long bw, bo;
        char *tail;
 
        if (*bf != 'b')
                return 0;
 
-       bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
-       if (!bprm)
-               return -ENOMEM;
-
-       bprm->orig = *f;
-       f->fn = t->fetch[FETCH_MTD_bitfield];
-       f->data = (void *)bprm;
        bw = simple_strtoul(bf + 1, &tail, 0);  /* Use simple one */
 
        if (bw == 0 || *tail != '@')
@@ -511,20 +334,26 @@ static int __parse_bitfield_probe_arg(const char *bf,
 
        if (tail == bf || *tail != '/')
                return -EINVAL;
+       code++;
+       if (code->op != FETCH_OP_NOP)
+               return -E2BIG;
+       *pcode = code;
 
-       bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo);
-       bprm->low_shift = bprm->hi_shift + bo;
+       code->op = FETCH_OP_MOD_BF;
+       code->lshift = BYTES_TO_BITS(t->size) - (bw + bo);
+       code->rshift = BYTES_TO_BITS(t->size) - bw;
+       code->basesize = t->size;
 
        return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
 }
 
 /* String length checking wrapper */
 int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
-               struct probe_arg *parg, bool is_return, bool is_kprobe,
-               const struct fetch_type *ftbl)
+               struct probe_arg *parg, unsigned int flags)
 {
-       const char *t;
-       int ret;
+       struct fetch_insn *code, *scode, *tmp = NULL;
+       char *t, *t2;
+       int ret, len;
 
        if (strlen(arg) > MAX_ARGSTR_LEN) {
                pr_info("Argument is too long.: %s\n",  arg);
@@ -535,36 +364,128 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
                pr_info("Failed to allocate memory for command '%s'.\n", arg);
                return -ENOMEM;
        }
-       t = strchr(parg->comm, ':');
+       t = strchr(arg, ':');
        if (t) {
-               arg[t - parg->comm] = '\0';
-               t++;
+               *t = '\0';
+               t2 = strchr(++t, '[');
+               if (t2) {
+                       *t2 = '\0';
+                       parg->count = simple_strtoul(t2 + 1, &t2, 0);
+                       if (strcmp(t2, "]") || parg->count == 0)
+                               return -EINVAL;
+                       if (parg->count > MAX_ARRAY_LEN)
+                               return -E2BIG;
+               }
        }
        /*
         * The default type of $comm should be "string", and it can't be
         * dereferenced.
         */
        if (!t && strcmp(arg, "$comm") == 0)
-               t = "string";
-       parg->type = find_fetch_type(t, ftbl);
+               parg->type = find_fetch_type("string");
+       else
+               parg->type = find_fetch_type(t);
        if (!parg->type) {
                pr_info("Unsupported type: %s\n", t);
                return -EINVAL;
        }
        parg->offset = *size;
-       *size += parg->type->size;
-       ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return,
-                             is_kprobe, ftbl);
-
-       if (ret >= 0 && t != NULL)
-               ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
-
-       if (ret >= 0) {
-               parg->fetch_size.fn = get_fetch_size_function(parg->type,
-                                                             parg->fetch.fn,
-                                                             ftbl);
-               parg->fetch_size.data = parg->fetch.data;
+       *size += parg->type->size * (parg->count ?: 1);
+
+       if (parg->count) {
+               len = strlen(parg->type->fmttype) + 6;
+               parg->fmt = kmalloc(len, GFP_KERNEL);
+               if (!parg->fmt)
+                       return -ENOMEM;
+               snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
+                        parg->count);
+       }
+
+       code = tmp = kzalloc(sizeof(*code) * FETCH_INSN_MAX, GFP_KERNEL);
+       if (!code)
+               return -ENOMEM;
+       code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;
+
+       ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1],
+                             flags);
+       if (ret)
+               goto fail;
+
+       /* Store operation */
+       if (!strcmp(parg->type->name, "string")) {
+               if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM &&
+                   code->op != FETCH_OP_COMM) {
+                       pr_info("string only accepts memory or address.\n");
+                       ret = -EINVAL;
+                       goto fail;
+               }
+               if (code->op != FETCH_OP_DEREF || parg->count) {
+                       /*
+                        * IMM and COMM is pointing actual address, those must
+                        * be kept, and if parg->count != 0, this is an array
+                        * of string pointers instead of string address itself.
+                        */
+                       code++;
+                       if (code->op != FETCH_OP_NOP) {
+                               ret = -E2BIG;
+                               goto fail;
+                       }
+               }
+               code->op = FETCH_OP_ST_STRING;  /* In DEREF case, replace it */
+               code->size = parg->type->size;
+               parg->dynamic = true;
+       } else if (code->op == FETCH_OP_DEREF) {
+               code->op = FETCH_OP_ST_MEM;
+               code->size = parg->type->size;
+       } else {
+               code++;
+               if (code->op != FETCH_OP_NOP) {
+                       ret = -E2BIG;
+                       goto fail;
+               }
+               code->op = FETCH_OP_ST_RAW;
+               code->size = parg->type->size;
+       }
+       scode = code;
+       /* Modify operation */
+       if (t != NULL) {
+               ret = __parse_bitfield_probe_arg(t, parg->type, &code);
+               if (ret)
+                       goto fail;
        }
+       /* Loop(Array) operation */
+       if (parg->count) {
+               if (scode->op != FETCH_OP_ST_MEM &&
+                   scode->op != FETCH_OP_ST_STRING) {
+                       pr_info("array only accepts memory or address\n");
+                       ret = -EINVAL;
+                       goto fail;
+               }
+               code++;
+               if (code->op != FETCH_OP_NOP) {
+                       ret = -E2BIG;
+                       goto fail;
+               }
+               code->op = FETCH_OP_LP_ARRAY;
+               code->param = parg->count;
+       }
+       code++;
+       code->op = FETCH_OP_END;
+
+       /* Shrink down the code buffer */
+       parg->code = kzalloc(sizeof(*code) * (code - tmp + 1), GFP_KERNEL);
+       if (!parg->code)
+               ret = -ENOMEM;
+       else
+               memcpy(parg->code, tmp, sizeof(*code) * (code - tmp + 1));
+
+fail:
+       if (ret) {
+               for (code = tmp; code < tmp + FETCH_INSN_MAX; code++)
+                       if (code->op == FETCH_NOP_SYMBOL)
+                               kfree(code->data);
+       }
+       kfree(tmp);
 
        return ret;
 }
@@ -586,35 +507,63 @@ int traceprobe_conflict_field_name(const char *name,
        return 0;
 }
 
-void traceprobe_update_arg(struct probe_arg *arg)
-{
-       if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
-               update_bitfield_fetch_param(arg->fetch.data);
-       else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
-               update_deref_fetch_param(arg->fetch.data);
-       else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
-               update_symbol_cache(arg->fetch.data);
-}
-
 void traceprobe_free_probe_arg(struct probe_arg *arg)
 {
-       if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
-               free_bitfield_fetch_param(arg->fetch.data);
-       else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
-               free_deref_fetch_param(arg->fetch.data);
-       else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
-               free_symbol_cache(arg->fetch.data);
+       struct fetch_insn *code = arg->code;
 
+       while (code && code->op != FETCH_OP_END) {
+               if (code->op == FETCH_NOP_SYMBOL)
+                       kfree(code->data);
+               code++;
+       }
+       kfree(arg->code);
        kfree(arg->name);
        kfree(arg->comm);
+       kfree(arg->fmt);
 }
 
+int traceprobe_update_arg(struct probe_arg *arg)
+{
+       struct fetch_insn *code = arg->code;
+       long offset;
+       char *tmp;
+       char c;
+       int ret = 0;
+
+       while (code && code->op != FETCH_OP_END) {
+               if (code->op == FETCH_NOP_SYMBOL) {
+                       if (code[1].op != FETCH_OP_IMM)
+                               return -EINVAL;
+
+                       tmp = strpbrk("+-", code->data);
+                       if (tmp)
+                               c = *tmp;
+                       ret = traceprobe_split_symbol_offset(code->data,
+                                                            &offset);
+                       if (ret)
+                               return ret;
+
+                       code[1].immediate =
+                               (unsigned long)kallsyms_lookup_name(code->data);
+                       if (tmp)
+                               *tmp = c;
+                       if (!code[1].immediate)
+                               return -ENOENT;
+                       code[1].immediate += offset;
+               }
+               code++;
+       }
+       return 0;
+}
+
+/* When len=0, we just calculate the needed length */
+#define LEN_OR_ZERO (len ? len - pos : 0)
 static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
                           bool is_return)
 {
-       int i;
+       struct probe_arg *parg;
+       int i, j;
        int pos = 0;
-
        const char *fmt, *arg;
 
        if (!is_return) {
@@ -625,35 +574,51 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
                arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
        }
 
-       /* When len=0, we just calculate the needed length */
-#define LEN_OR_ZERO (len ? len - pos : 0)
-
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
 
        for (i = 0; i < tp->nr_args; i++) {
-               pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
-                               tp->args[i].name, tp->args[i].type->fmt);
+               parg = tp->args + i;
+               pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=", parg->name);
+               if (parg->count) {
+                       pos += snprintf(buf + pos, LEN_OR_ZERO, "{%s",
+                                       parg->type->fmt);
+                       for (j = 1; j < parg->count; j++)
+                               pos += snprintf(buf + pos, LEN_OR_ZERO, ",%s",
+                                               parg->type->fmt);
+                       pos += snprintf(buf + pos, LEN_OR_ZERO, "}");
+               } else
+                       pos += snprintf(buf + pos, LEN_OR_ZERO, "%s",
+                                       parg->type->fmt);
        }
 
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
 
        for (i = 0; i < tp->nr_args; i++) {
-               if (strcmp(tp->args[i].type->name, "string") == 0)
+               parg = tp->args + i;
+               if (parg->count) {
+                       if (strcmp(parg->type->name, "string") == 0)
+                               fmt = ", __get_str(%s[%d])";
+                       else
+                               fmt = ", REC->%s[%d]";
+                       for (j = 0; j < parg->count; j++)
+                               pos += snprintf(buf + pos, LEN_OR_ZERO,
+                                               fmt, parg->name, j);
+               } else {
+                       if (strcmp(parg->type->name, "string") == 0)
+                               fmt = ", __get_str(%s)";
+                       else
+                               fmt = ", REC->%s";
                        pos += snprintf(buf + pos, LEN_OR_ZERO,
-                                       ", __get_str(%s)",
-                                       tp->args[i].name);
-               else
-                       pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
-                                       tp->args[i].name);
+                                       fmt, parg->name);
+               }
        }
 
-#undef LEN_OR_ZERO
-
        /* return the length of print_fmt */
        return pos;
 }
+#undef LEN_OR_ZERO
 
-int set_print_fmt(struct trace_probe *tp, bool is_return)
+int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return)
 {
        int len;
        char *print_fmt;
@@ -670,3 +635,28 @@ int set_print_fmt(struct trace_probe *tp, bool is_return)
 
        return 0;
 }
+
+int traceprobe_define_arg_fields(struct trace_event_call *event_call,
+                                size_t offset, struct trace_probe *tp)
+{
+       int ret, i;
+
+       /* Set argument names as fields */
+       for (i = 0; i < tp->nr_args; i++) {
+               struct probe_arg *parg = &tp->args[i];
+               const char *fmt = parg->type->fmttype;
+               int size = parg->type->size;
+
+               if (parg->fmt)
+                       fmt = parg->fmt;
+               if (parg->count)
+                       size *= parg->count;
+               ret = trace_define_field(event_call, fmt, parg->name,
+                                        offset + parg->offset, size,
+                                        parg->type->is_signed,
+                                        FILTER_OTHER);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
index 5f52668e165d9f8dfa3c0e0737b8c6495007fa9b..974afc1a3e73eaed3be4d7f925e0fd9ae6fc5c25 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/stringify.h>
 #include <linux/limits.h>
 #include <linux/uaccess.h>
+#include <linux/bitops.h>
 #include <asm/bitsperlong.h>
 
 #include "trace.h"
@@ -30,6 +31,7 @@
 
 #define MAX_TRACE_ARGS         128
 #define MAX_ARGSTR_LEN         63
+#define MAX_ARRAY_LEN          64
 #define MAX_STRING_SIZE                PATH_MAX
 
 /* Reserved field names */
 #define TP_FLAG_PROFILE                2
 #define TP_FLAG_REGISTERED     4
 
+/* data_loc: data location, compatible with u32 */
+#define make_data_loc(len, offs)       \
+       (((u32)(len) << 16) | ((u32)(offs) & 0xffff))
+#define get_loc_len(dl)                ((u32)(dl) >> 16)
+#define get_loc_offs(dl)       ((u32)(dl) & 0xffff)
 
-/* data_rloc: data relative location, compatible with u32 */
-#define make_data_rloc(len, roffs)     \
-       (((u32)(len) << 16) | ((u32)(roffs) & 0xffff))
-#define get_rloc_len(dl)               ((u32)(dl) >> 16)
-#define get_rloc_offs(dl)              ((u32)(dl) & 0xffff)
-
-/*
- * Convert data_rloc to data_loc:
- *  data_rloc stores the offset from data_rloc itself, but data_loc
- *  stores the offset from event entry.
- */
-#define convert_rloc_to_loc(dl, offs)  ((u32)(dl) + (offs))
-
-static nokprobe_inline void *get_rloc_data(u32 *dl)
+static nokprobe_inline void *get_loc_data(u32 *dl, void *ent)
 {
-       return (u8 *)dl + get_rloc_offs(*dl);
+       return (u8 *)ent + get_loc_offs(*dl);
 }
 
-/* For data_loc conversion */
-static nokprobe_inline void *get_loc_data(u32 *dl, void *ent)
+static nokprobe_inline u32 update_data_loc(u32 loc, int consumed)
 {
-       return (u8 *)ent + get_rloc_offs(*dl);
+       u32 maxlen = get_loc_len(loc);
+       u32 offset = get_loc_offs(loc);
+
+       return make_data_loc(maxlen - consumed, offset + consumed);
 }
 
-/* Data fetch function type */
-typedef        void (*fetch_func_t)(struct pt_regs *, void *, void *);
 /* Printing function type */
-typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *, void *);
-
-/* Fetch types */
-enum {
-       FETCH_MTD_reg = 0,
-       FETCH_MTD_stack,
-       FETCH_MTD_retval,
-       FETCH_MTD_comm,
-       FETCH_MTD_memory,
-       FETCH_MTD_symbol,
-       FETCH_MTD_deref,
-       FETCH_MTD_bitfield,
-       FETCH_MTD_file_offset,
-       FETCH_MTD_END,
+typedef int (*print_type_func_t)(struct trace_seq *, void *, void *);
+
+enum fetch_op {
+       FETCH_OP_NOP = 0,
+       // Stage 1 (load) ops
+       FETCH_OP_REG,           /* Register : .param = offset */
+       FETCH_OP_STACK,         /* Stack : .param = index */
+       FETCH_OP_STACKP,        /* Stack pointer */
+       FETCH_OP_RETVAL,        /* Return value */
+       FETCH_OP_IMM,           /* Immediate : .immediate */
+       FETCH_OP_COMM,          /* Current comm */
+       FETCH_OP_ARG,           /* Function argument : .param */
+       FETCH_OP_FOFFS,         /* File offset: .immediate */
+       // Stage 2 (dereference) op
+       FETCH_OP_DEREF,         /* Dereference: .offset */
+       // Stage 3 (store) ops
+       FETCH_OP_ST_RAW,        /* Raw: .size */
+       FETCH_OP_ST_MEM,        /* Mem: .offset, .size */
+       FETCH_OP_ST_STRING,     /* String: .offset, .size */
+       // Stage 4 (modify) op
+       FETCH_OP_MOD_BF,        /* Bitfield: .basesize, .lshift, .rshift */
+       // Stage 5 (loop) op
+       FETCH_OP_LP_ARRAY,      /* Array: .param = loop count */
+       FETCH_OP_END,
+       FETCH_NOP_SYMBOL,       /* Unresolved Symbol holder */
 };
 
+struct fetch_insn {
+       enum fetch_op op;
+       union {
+               unsigned int param;
+               struct {
+                       unsigned int size;
+                       int offset;
+               };
+               struct {
+                       unsigned char basesize;
+                       unsigned char lshift;
+                       unsigned char rshift;
+               };
+               unsigned long immediate;
+               void *data;
+       };
+};
+
+/* fetch + deref*N + store + mod + end <= 16, this allows N=12, enough */
+#define FETCH_INSN_MAX 16
+
 /* Fetch type information table */
 struct fetch_type {
        const char              *name;          /* Name of type */
@@ -106,13 +132,6 @@ struct fetch_type {
        print_type_func_t       print;          /* Print functions */
        const char              *fmt;           /* Fromat string */
        const char              *fmttype;       /* Name in format file */
-       /* Fetch functions */
-       fetch_func_t            fetch[FETCH_MTD_END];
-};
-
-struct fetch_param {
-       fetch_func_t            fn;
-       void                    *data;
 };
 
 /* For defining macros, define string/string_size types */
@@ -124,8 +143,7 @@ typedef u32 string_size;
 
 /* Printing  in basic type function template */
 #define DECLARE_BASIC_PRINT_TYPE_FUNC(type)                            \
-int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, const char *name,  \
-                               void *data, void *ent);                 \
+int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, void *data, void *ent);\
 extern const char PRINT_TYPE_FMT_NAME(type)[]
 
 DECLARE_BASIC_PRINT_TYPE_FUNC(u8);
@@ -142,57 +160,7 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(x32);
 DECLARE_BASIC_PRINT_TYPE_FUNC(x64);
 
 DECLARE_BASIC_PRINT_TYPE_FUNC(string);
-
-#define FETCH_FUNC_NAME(method, type)  fetch_##method##_##type
-
-/* Declare macro for basic types */
-#define DECLARE_FETCH_FUNC(method, type)                               \
-extern void FETCH_FUNC_NAME(method, type)(struct pt_regs *regs,        \
-                                         void *data, void *dest)
-
-#define DECLARE_BASIC_FETCH_FUNCS(method)      \
-DECLARE_FETCH_FUNC(method, u8);                        \
-DECLARE_FETCH_FUNC(method, u16);               \
-DECLARE_FETCH_FUNC(method, u32);               \
-DECLARE_FETCH_FUNC(method, u64)
-
-DECLARE_BASIC_FETCH_FUNCS(reg);
-#define fetch_reg_string                       NULL
-#define fetch_reg_string_size                  NULL
-
-DECLARE_BASIC_FETCH_FUNCS(retval);
-#define fetch_retval_string                    NULL
-#define fetch_retval_string_size               NULL
-
-DECLARE_BASIC_FETCH_FUNCS(symbol);
-DECLARE_FETCH_FUNC(symbol, string);
-DECLARE_FETCH_FUNC(symbol, string_size);
-
-DECLARE_BASIC_FETCH_FUNCS(deref);
-DECLARE_FETCH_FUNC(deref, string);
-DECLARE_FETCH_FUNC(deref, string_size);
-
-DECLARE_BASIC_FETCH_FUNCS(bitfield);
-#define fetch_bitfield_string                  NULL
-#define fetch_bitfield_string_size             NULL
-
-/* comm only makes sense as a string */
-#define fetch_comm_u8          NULL
-#define fetch_comm_u16         NULL
-#define fetch_comm_u32         NULL
-#define fetch_comm_u64         NULL
-DECLARE_FETCH_FUNC(comm, string);
-DECLARE_FETCH_FUNC(comm, string_size);
-
-/*
- * Define macro for basic types - we don't need to define s* types, because
- * we have to care only about bitwidth at recording time.
- */
-#define DEFINE_BASIC_FETCH_FUNCS(method) \
-DEFINE_FETCH_##method(u8)              \
-DEFINE_FETCH_##method(u16)             \
-DEFINE_FETCH_##method(u32)             \
-DEFINE_FETCH_##method(u64)
+DECLARE_BASIC_PRINT_TYPE_FUNC(symbol);
 
 /* Default (unsigned long) fetch type */
 #define __DEFAULT_FETCH_TYPE(t) x##t
@@ -200,8 +168,9 @@ DEFINE_FETCH_##method(u64)
 #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
 #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
 
-#define ASSIGN_FETCH_FUNC(method, type)        \
-       [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
+#define __ADDR_FETCH_TYPE(t) u##t
+#define _ADDR_FETCH_TYPE(t) __ADDR_FETCH_TYPE(t)
+#define ADDR_FETCH_TYPE _ADDR_FETCH_TYPE(BITS_PER_LONG)
 
 #define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)        \
        {.name = _name,                         \
@@ -210,64 +179,23 @@ DEFINE_FETCH_##method(u64)
         .print = PRINT_TYPE_FUNC_NAME(ptype),          \
         .fmt = PRINT_TYPE_FMT_NAME(ptype),             \
         .fmttype = _fmttype,                           \
-        .fetch = {                                     \
-ASSIGN_FETCH_FUNC(reg, ftype),                         \
-ASSIGN_FETCH_FUNC(stack, ftype),                       \
-ASSIGN_FETCH_FUNC(retval, ftype),                      \
-ASSIGN_FETCH_FUNC(comm, ftype),                                \
-ASSIGN_FETCH_FUNC(memory, ftype),                      \
-ASSIGN_FETCH_FUNC(symbol, ftype),                      \
-ASSIGN_FETCH_FUNC(deref, ftype),                       \
-ASSIGN_FETCH_FUNC(bitfield, ftype),                    \
-ASSIGN_FETCH_FUNC(file_offset, ftype),                 \
-         }                                             \
        }
-
+#define _ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \
+       __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, #_fmttype)
 #define ASSIGN_FETCH_TYPE(ptype, ftype, sign)                  \
-       __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
+       _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, ptype)
 
 /* If ptype is an alias of atype, use this macro (show atype in format) */
 #define ASSIGN_FETCH_TYPE_ALIAS(ptype, atype, ftype, sign)             \
-       __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #atype)
+       _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, atype)
 
 #define ASSIGN_FETCH_TYPE_END {}
-
-#define FETCH_TYPE_STRING      0
-#define FETCH_TYPE_STRSIZE     1
+#define MAX_ARRAY_LEN  64
 
 #ifdef CONFIG_KPROBE_EVENTS
-struct symbol_cache;
-unsigned long update_symbol_cache(struct symbol_cache *sc);
-void free_symbol_cache(struct symbol_cache *sc);
-struct symbol_cache *alloc_symbol_cache(const char *sym, long offset);
 bool trace_kprobe_on_func_entry(struct trace_event_call *call);
 bool trace_kprobe_error_injectable(struct trace_event_call *call);
 #else
-/* uprobes do not support symbol fetch methods */
-#define fetch_symbol_u8                        NULL
-#define fetch_symbol_u16               NULL
-#define fetch_symbol_u32               NULL
-#define fetch_symbol_u64               NULL
-#define fetch_symbol_string            NULL
-#define fetch_symbol_string_size       NULL
-
-struct symbol_cache {
-};
-static inline unsigned long __used update_symbol_cache(struct symbol_cache *sc)
-{
-       return 0;
-}
-
-static inline void __used free_symbol_cache(struct symbol_cache *sc)
-{
-}
-
-static inline struct symbol_cache * __used
-alloc_symbol_cache(const char *sym, long offset)
-{
-       return NULL;
-}
-
 static inline bool trace_kprobe_on_func_entry(struct trace_event_call *call)
 {
        return false;
@@ -280,11 +208,13 @@ static inline bool trace_kprobe_error_injectable(struct trace_event_call *call)
 #endif /* CONFIG_KPROBE_EVENTS */
 
 struct probe_arg {
-       struct fetch_param      fetch;
-       struct fetch_param      fetch_size;
+       struct fetch_insn       *code;
+       bool                    dynamic;/* Dynamic array (string) is used */
        unsigned int            offset; /* Offset from argument entry */
+       unsigned int            count;  /* Array count */
        const char              *name;  /* Name of this argument */
        const char              *comm;  /* Command of this argument */
+       char                    *fmt;   /* Format string if needed */
        const struct fetch_type *type;  /* Type of this argument */
 };
 
@@ -313,12 +243,6 @@ static inline bool trace_probe_is_registered(struct trace_probe *tp)
        return !!(tp->flags & TP_FLAG_REGISTERED);
 }
 
-static nokprobe_inline void call_fetch(struct fetch_param *fprm,
-                                struct pt_regs *regs, void *dest)
-{
-       return fprm->fn(regs, fprm->data, dest);
-}
-
 /* Check the name is good for event/group/fields */
 static inline bool is_good_name(const char *name)
 {
@@ -343,67 +267,23 @@ find_event_file_link(struct trace_probe *tp, struct trace_event_file *file)
        return NULL;
 }
 
+#define TPARG_FL_RETURN BIT(0)
+#define TPARG_FL_KERNEL BIT(1)
+#define TPARG_FL_FENTRY BIT(2)
+#define TPARG_FL_MASK  GENMASK(2, 0)
+
 extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
-                  struct probe_arg *parg, bool is_return, bool is_kprobe,
-                  const struct fetch_type *ftbl);
+                  struct probe_arg *parg, unsigned int flags);
 
 extern int traceprobe_conflict_field_name(const char *name,
                               struct probe_arg *args, int narg);
 
-extern void traceprobe_update_arg(struct probe_arg *arg);
+extern int traceprobe_update_arg(struct probe_arg *arg);
 extern void traceprobe_free_probe_arg(struct probe_arg *arg);
 
 extern int traceprobe_split_symbol_offset(char *symbol, long *offset);
 
-/* Sum up total data length for dynamic arraies (strings) */
-static nokprobe_inline int
-__get_data_size(struct trace_probe *tp, struct pt_regs *regs)
-{
-       int i, ret = 0;
-       u32 len;
-
-       for (i = 0; i < tp->nr_args; i++)
-               if (unlikely(tp->args[i].fetch_size.fn)) {
-                       call_fetch(&tp->args[i].fetch_size, regs, &len);
-                       ret += len;
-               }
-
-       return ret;
-}
-
-/* Store the value of each argument */
-static nokprobe_inline void
-store_trace_args(int ent_size, struct trace_probe *tp, struct pt_regs *regs,
-                u8 *data, int maxlen)
-{
-       int i;
-       u32 end = tp->size;
-       u32 *dl;        /* Data (relative) location */
-
-       for (i = 0; i < tp->nr_args; i++) {
-               if (unlikely(tp->args[i].fetch_size.fn)) {
-                       /*
-                        * First, we set the relative location and
-                        * maximum data length to *dl
-                        */
-                       dl = (u32 *)(data + tp->args[i].offset);
-                       *dl = make_data_rloc(maxlen, end - tp->args[i].offset);
-                       /* Then try to fetch string or dynamic array data */
-                       call_fetch(&tp->args[i].fetch, regs, dl);
-                       /* Reduce maximum length */
-                       end += get_rloc_len(*dl);
-                       maxlen -= get_rloc_len(*dl);
-                       /* Trick here, convert data_rloc to data_loc */
-                       *dl = convert_rloc_to_loc(*dl,
-                                ent_size + tp->args[i].offset);
-               } else
-                       /* Just fetching data normally */
-                       call_fetch(&tp->args[i].fetch, regs,
-                                  data + tp->args[i].offset);
-       }
-}
-
-extern int set_print_fmt(struct trace_probe *tp, bool is_return);
+extern int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return);
 
 #ifdef CONFIG_PERF_EVENTS
 extern struct trace_event_call *
@@ -412,6 +292,9 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
 extern void destroy_local_trace_kprobe(struct trace_event_call *event_call);
 
 extern struct trace_event_call *
-create_local_trace_uprobe(char *name, unsigned long offs, bool is_return);
+create_local_trace_uprobe(char *name, unsigned long offs,
+                         unsigned long ref_ctr_offset, bool is_return);
 extern void destroy_local_trace_uprobe(struct trace_event_call *event_call);
 #endif
+extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
+                                       size_t offset, struct trace_probe *tp);
diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h
new file mode 100644 (file)
index 0000000..5c56afc
--- /dev/null
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Traceprobe fetch helper inlines
+ */
+
+static nokprobe_inline void
+fetch_store_raw(unsigned long val, struct fetch_insn *code, void *buf)
+{
+       switch (code->size) {
+       case 1:
+               *(u8 *)buf = (u8)val;
+               break;
+       case 2:
+               *(u16 *)buf = (u16)val;
+               break;
+       case 4:
+               *(u32 *)buf = (u32)val;
+               break;
+       case 8:
+               //TBD: 32bit signed
+               *(u64 *)buf = (u64)val;
+               break;
+       default:
+               *(unsigned long *)buf = val;
+       }
+}
+
+static nokprobe_inline void
+fetch_apply_bitfield(struct fetch_insn *code, void *buf)
+{
+       switch (code->basesize) {
+       case 1:
+               *(u8 *)buf <<= code->lshift;
+               *(u8 *)buf >>= code->rshift;
+               break;
+       case 2:
+               *(u16 *)buf <<= code->lshift;
+               *(u16 *)buf >>= code->rshift;
+               break;
+       case 4:
+               *(u32 *)buf <<= code->lshift;
+               *(u32 *)buf >>= code->rshift;
+               break;
+       case 8:
+               *(u64 *)buf <<= code->lshift;
+               *(u64 *)buf >>= code->rshift;
+               break;
+       }
+}
+
+/*
+ * These functions must be defined for each callsite.
+ * Return consumed dynamic data size (>= 0), or error (< 0).
+ * If dest is NULL, don't store result and return required dynamic data size.
+ */
+static int
+process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs,
+                  void *dest, void *base);
+static nokprobe_inline int fetch_store_strlen(unsigned long addr);
+static nokprobe_inline int
+fetch_store_string(unsigned long addr, void *dest, void *base);
+static nokprobe_inline int
+probe_mem_read(void *dest, void *src, size_t size);
+
+/* From the 2nd stage, routine is same */
+static nokprobe_inline int
+process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
+                          void *dest, void *base)
+{
+       struct fetch_insn *s3 = NULL;
+       int total = 0, ret = 0, i = 0;
+       u32 loc = 0;
+       unsigned long lval = val;
+
+stage2:
+       /* 2nd stage: dereference memory if needed */
+       while (code->op == FETCH_OP_DEREF) {
+               lval = val;
+               ret = probe_mem_read(&val, (void *)val + code->offset,
+                                       sizeof(val));
+               if (ret)
+                       return ret;
+               code++;
+       }
+
+       s3 = code;
+stage3:
+       /* 3rd stage: store value to buffer */
+       if (unlikely(!dest)) {
+               if (code->op == FETCH_OP_ST_STRING) {
+                       ret += fetch_store_strlen(val + code->offset);
+                       code++;
+                       goto array;
+               } else
+                       return -EILSEQ;
+       }
+
+       switch (code->op) {
+       case FETCH_OP_ST_RAW:
+               fetch_store_raw(val, code, dest);
+               break;
+       case FETCH_OP_ST_MEM:
+               probe_mem_read(dest, (void *)val + code->offset, code->size);
+               break;
+       case FETCH_OP_ST_STRING:
+               loc = *(u32 *)dest;
+               ret = fetch_store_string(val + code->offset, dest, base);
+               break;
+       default:
+               return -EILSEQ;
+       }
+       code++;
+
+       /* 4th stage: modify stored value if needed */
+       if (code->op == FETCH_OP_MOD_BF) {
+               fetch_apply_bitfield(code, dest);
+               code++;
+       }
+
+array:
+       /* the last stage: Loop on array */
+       if (code->op == FETCH_OP_LP_ARRAY) {
+               total += ret;
+               if (++i < code->param) {
+                       code = s3;
+                       if (s3->op != FETCH_OP_ST_STRING) {
+                               dest += s3->size;
+                               val += s3->size;
+                               goto stage3;
+                       }
+                       code--;
+                       val = lval + sizeof(char *);
+                       if (dest) {
+                               dest += sizeof(u32);
+                               *(u32 *)dest = update_data_loc(loc, ret);
+                       }
+                       goto stage2;
+               }
+               code++;
+               ret = total;
+       }
+
+       return code->op == FETCH_OP_END ? ret : -EILSEQ;
+}
+
+/* Sum up total data length for dynamic arraies (strings) */
+static nokprobe_inline int
+__get_data_size(struct trace_probe *tp, struct pt_regs *regs)
+{
+       struct probe_arg *arg;
+       int i, len, ret = 0;
+
+       for (i = 0; i < tp->nr_args; i++) {
+               arg = tp->args + i;
+               if (unlikely(arg->dynamic)) {
+                       len = process_fetch_insn(arg->code, regs, NULL, NULL);
+                       if (len > 0)
+                               ret += len;
+               }
+       }
+
+       return ret;
+}
+
+/* Store the value of each argument */
+static nokprobe_inline void
+store_trace_args(void *data, struct trace_probe *tp, struct pt_regs *regs,
+                int header_size, int maxlen)
+{
+       struct probe_arg *arg;
+       void *base = data - header_size;
+       void *dyndata = data + tp->size;
+       u32 *dl;        /* Data location */
+       int ret, i;
+
+       for (i = 0; i < tp->nr_args; i++) {
+               arg = tp->args + i;
+               dl = data + arg->offset;
+               /* Point the dynamic data area if needed */
+               if (unlikely(arg->dynamic))
+                       *dl = make_data_loc(maxlen, dyndata - base);
+               ret = process_fetch_insn(arg->code, regs, dl, base);
+               if (unlikely(ret < 0 && arg->dynamic))
+                       *dl = make_data_loc(0, dyndata - base);
+               else
+                       dyndata += ret;
+       }
+}
+
+static inline int
+print_probe_args(struct trace_seq *s, struct probe_arg *args, int nr_args,
+                u8 *data, void *field)
+{
+       void *p;
+       int i, j;
+
+       for (i = 0; i < nr_args; i++) {
+               struct probe_arg *a = args + i;
+
+               trace_seq_printf(s, " %s=", a->name);
+               if (likely(!a->count)) {
+                       if (!a->type->print(s, data + a->offset, field))
+                               return -ENOMEM;
+                       continue;
+               }
+               trace_seq_putc(s, '{');
+               p = data + a->offset;
+               for (j = 0; j < a->count; j++) {
+                       if (!a->type->print(s, p, field))
+                               return -ENOMEM;
+                       trace_seq_putc(s, j == a->count - 1 ? '}' : ',');
+                       p += a->type->size;
+               }
+       }
+       return 0;
+}
index 4237eba4ef2020c6debb9df2851702b859ae515f..2b0d1ee3241cb515e441e88389ed1da459cc2c15 100644 (file)
@@ -111,7 +111,7 @@ check_stack(unsigned long ip, unsigned long *stack)
        stack_trace_max_size = this_size;
 
        stack_trace_max.nr_entries = 0;
-       stack_trace_max.skip = 3;
+       stack_trace_max.skip = 0;
 
        save_stack_trace(&stack_trace_max);
 
index e696667da29a49aa2f94372fa301b8ab1e7ec373..31ea48eceda184ed5e807f9fe22394f831980982 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/rculist.h>
 
 #include "trace_probe.h"
+#include "trace_probe_tmpl.h"
 
 #define UPROBE_EVENT_SYSTEM    "uprobes"
 
@@ -47,6 +48,7 @@ struct trace_uprobe {
        struct inode                    *inode;
        char                            *filename;
        unsigned long                   offset;
+       unsigned long                   ref_ctr_offset;
        unsigned long                   nhit;
        struct trace_probe              tp;
 };
@@ -98,74 +100,52 @@ static unsigned long get_user_stack_nth(struct pt_regs *regs, unsigned int n)
 /*
  * Uprobes-specific fetch functions
  */
-#define DEFINE_FETCH_stack(type)                                       \
-static void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,         \
-                                        void *offset, void *dest)      \
-{                                                                      \
-       *(type *)dest = (type)get_user_stack_nth(regs,                  \
-                                             ((unsigned long)offset)); \
-}
-DEFINE_BASIC_FETCH_FUNCS(stack)
-/* No string on the stack entry */
-#define fetch_stack_string     NULL
-#define fetch_stack_string_size        NULL
-
-#define DEFINE_FETCH_memory(type)                                      \
-static void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,                \
-                                         void *addr, void *dest)       \
-{                                                                      \
-       type retval;                                                    \
-       void __user *vaddr = (void __force __user *) addr;              \
-                                                                       \
-       if (copy_from_user(&retval, vaddr, sizeof(type)))               \
-               *(type *)dest = 0;                                      \
-       else                                                            \
-               *(type *) dest = retval;                                \
+static nokprobe_inline int
+probe_mem_read(void *dest, void *src, size_t size)
+{
+       void __user *vaddr = (void __force __user *)src;
+
+       return copy_from_user(dest, vaddr, size) ? -EFAULT : 0;
 }
-DEFINE_BASIC_FETCH_FUNCS(memory)
 /*
  * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
  * length and relative data location.
  */
-static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
-                                           void *addr, void *dest)
+static nokprobe_inline int
+fetch_store_string(unsigned long addr, void *dest, void *base)
 {
        long ret;
-       u32 rloc = *(u32 *)dest;
-       int maxlen  = get_rloc_len(rloc);
-       u8 *dst = get_rloc_data(dest);
+       u32 loc = *(u32 *)dest;
+       int maxlen  = get_loc_len(loc);
+       u8 *dst = get_loc_data(dest, base);
        void __user *src = (void __force __user *) addr;
 
-       if (!maxlen)
-               return;
+       if (unlikely(!maxlen))
+               return -ENOMEM;
 
        ret = strncpy_from_user(dst, src, maxlen);
-       if (ret == maxlen)
-               dst[--ret] = '\0';
-
-       if (ret < 0) {  /* Failed to fetch string */
-               ((u8 *)get_rloc_data(dest))[0] = '\0';
-               *(u32 *)dest = make_data_rloc(0, get_rloc_offs(rloc));
-       } else {
-               *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(rloc));
+       if (ret >= 0) {
+               if (ret == maxlen)
+                       dst[ret - 1] = '\0';
+               *(u32 *)dest = make_data_loc(ret, (void *)dst - base);
        }
+
+       return ret;
 }
 
-static void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
-                                                void *addr, void *dest)
+/* Return the length of string -- including null terminal byte */
+static nokprobe_inline int
+fetch_store_strlen(unsigned long addr)
 {
        int len;
        void __user *vaddr = (void __force __user *) addr;
 
        len = strnlen_user(vaddr, MAX_STRING_SIZE);
 
-       if (len == 0 || len > MAX_STRING_SIZE)  /* Failed to check length */
-               *(u32 *)dest = 0;
-       else
-               *(u32 *)dest = len;
+       return (len > MAX_STRING_SIZE) ? 0 : len;
 }
 
-static unsigned long translate_user_vaddr(void *file_offset)
+static unsigned long translate_user_vaddr(unsigned long file_offset)
 {
        unsigned long base_addr;
        struct uprobe_dispatch_data *udd;
@@ -173,44 +153,44 @@ static unsigned long translate_user_vaddr(void *file_offset)
        udd = (void *) current->utask->vaddr;
 
        base_addr = udd->bp_addr - udd->tu->offset;
-       return base_addr + (unsigned long)file_offset;
+       return base_addr + file_offset;
 }
 
-#define DEFINE_FETCH_file_offset(type)                                 \
-static void FETCH_FUNC_NAME(file_offset, type)(struct pt_regs *regs,   \
-                                              void *offset, void *dest)\
-{                                                                      \
-       void *vaddr = (void *)translate_user_vaddr(offset);             \
-                                                                       \
-       FETCH_FUNC_NAME(memory, type)(regs, vaddr, dest);               \
+/* Note that we don't verify it, since the code does not come from user space */
+static int
+process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
+                  void *base)
+{
+       unsigned long val;
+
+       /* 1st stage: get value from context */
+       switch (code->op) {
+       case FETCH_OP_REG:
+               val = regs_get_register(regs, code->param);
+               break;
+       case FETCH_OP_STACK:
+               val = get_user_stack_nth(regs, code->param);
+               break;
+       case FETCH_OP_STACKP:
+               val = user_stack_pointer(regs);
+               break;
+       case FETCH_OP_RETVAL:
+               val = regs_return_value(regs);
+               break;
+       case FETCH_OP_IMM:
+               val = code->immediate;
+               break;
+       case FETCH_OP_FOFFS:
+               val = translate_user_vaddr(code->immediate);
+               break;
+       default:
+               return -EILSEQ;
+       }
+       code++;
+
+       return process_fetch_insn_bottom(code, val, dest, base);
 }
-DEFINE_BASIC_FETCH_FUNCS(file_offset)
-DEFINE_FETCH_file_offset(string)
-DEFINE_FETCH_file_offset(string_size)
-
-/* Fetch type information table */
-static const struct fetch_type uprobes_fetch_type_table[] = {
-       /* Special types */
-       [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
-                                       sizeof(u32), 1, "__data_loc char[]"),
-       [FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
-                                       string_size, sizeof(u32), 0, "u32"),
-       /* Basic types */
-       ASSIGN_FETCH_TYPE(u8,  u8,  0),
-       ASSIGN_FETCH_TYPE(u16, u16, 0),
-       ASSIGN_FETCH_TYPE(u32, u32, 0),
-       ASSIGN_FETCH_TYPE(u64, u64, 0),
-       ASSIGN_FETCH_TYPE(s8,  u8,  1),
-       ASSIGN_FETCH_TYPE(s16, u16, 1),
-       ASSIGN_FETCH_TYPE(s32, u32, 1),
-       ASSIGN_FETCH_TYPE(s64, u64, 1),
-       ASSIGN_FETCH_TYPE_ALIAS(x8,  u8,  u8,  0),
-       ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
-       ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
-       ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
-
-       ASSIGN_FETCH_TYPE_END
-};
+NOKPROBE_SYMBOL(process_fetch_insn)
 
 static inline void init_trace_uprobe_filter(struct trace_uprobe_filter *filter)
 {
@@ -311,6 +291,35 @@ static int unregister_trace_uprobe(struct trace_uprobe *tu)
        return 0;
 }
 
+/*
+ * Uprobe with multiple reference counter is not allowed. i.e.
+ * If inode and offset matches, reference counter offset *must*
+ * match as well. Though, there is one exception: If user is
+ * replacing old trace_uprobe with new one(same group/event),
+ * then we allow same uprobe with new reference counter as far
+ * as the new one does not conflict with any other existing
+ * ones.
+ */
+static struct trace_uprobe *find_old_trace_uprobe(struct trace_uprobe *new)
+{
+       struct trace_uprobe *tmp, *old = NULL;
+       struct inode *new_inode = d_real_inode(new->path.dentry);
+
+       old = find_probe_event(trace_event_name(&new->tp.call),
+                               new->tp.call.class->system);
+
+       list_for_each_entry(tmp, &uprobe_list, list) {
+               if ((old ? old != tmp : true) &&
+                   new_inode == d_real_inode(tmp->path.dentry) &&
+                   new->offset == tmp->offset &&
+                   new->ref_ctr_offset != tmp->ref_ctr_offset) {
+                       pr_warn("Reference counter offset mismatch.");
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+       return old;
+}
+
 /* Register a trace_uprobe and probe_event */
 static int register_trace_uprobe(struct trace_uprobe *tu)
 {
@@ -320,8 +329,12 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
        mutex_lock(&uprobe_lock);
 
        /* register as an event */
-       old_tu = find_probe_event(trace_event_name(&tu->tp.call),
-                       tu->tp.call.class->system);
+       old_tu = find_old_trace_uprobe(tu);
+       if (IS_ERR(old_tu)) {
+               ret = PTR_ERR(old_tu);
+               goto end;
+       }
+
        if (old_tu) {
                /* delete old event */
                ret = unregister_trace_uprobe(old_tu);
@@ -352,10 +365,10 @@ end:
 static int create_trace_uprobe(int argc, char **argv)
 {
        struct trace_uprobe *tu;
-       char *arg, *event, *group, *filename;
+       char *arg, *event, *group, *filename, *rctr, *rctr_end;
        char buf[MAX_EVENT_NAME_LEN];
        struct path path;
-       unsigned long offset;
+       unsigned long offset, ref_ctr_offset;
        bool is_delete, is_return;
        int i, ret;
 
@@ -364,6 +377,7 @@ static int create_trace_uprobe(int argc, char **argv)
        is_return = false;
        event = NULL;
        group = NULL;
+       ref_ctr_offset = 0;
 
        /* argc must be >= 1 */
        if (argv[0][0] == '-')
@@ -438,6 +452,26 @@ static int create_trace_uprobe(int argc, char **argv)
                goto fail_address_parse;
        }
 
+       /* Parse reference counter offset if specified. */
+       rctr = strchr(arg, '(');
+       if (rctr) {
+               rctr_end = strchr(rctr, ')');
+               if (rctr > rctr_end || *(rctr_end + 1) != 0) {
+                       ret = -EINVAL;
+                       pr_info("Invalid reference counter offset.\n");
+                       goto fail_address_parse;
+               }
+
+               *rctr++ = '\0';
+               *rctr_end = '\0';
+               ret = kstrtoul(rctr, 0, &ref_ctr_offset);
+               if (ret) {
+                       pr_info("Invalid reference counter offset.\n");
+                       goto fail_address_parse;
+               }
+       }
+
+       /* Parse uprobe offset. */
        ret = kstrtoul(arg, 0, &offset);
        if (ret)
                goto fail_address_parse;
@@ -472,6 +506,7 @@ static int create_trace_uprobe(int argc, char **argv)
                goto fail_address_parse;
        }
        tu->offset = offset;
+       tu->ref_ctr_offset = ref_ctr_offset;
        tu->path = path;
        tu->filename = kstrdup(filename, GFP_KERNEL);
 
@@ -522,8 +557,7 @@ static int create_trace_uprobe(int argc, char **argv)
 
                /* Parse fetch argument */
                ret = traceprobe_parse_probe_arg(arg, &tu->tp.size, parg,
-                                                is_return, false,
-                                                uprobes_fetch_type_table);
+                                       is_return ? TPARG_FL_RETURN : 0);
                if (ret) {
                        pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
                        goto error;
@@ -590,6 +624,9 @@ static int probes_seq_show(struct seq_file *m, void *v)
                        trace_event_name(&tu->tp.call), tu->filename,
                        (int)(sizeof(void *) * 2), tu->offset);
 
+       if (tu->ref_ctr_offset)
+               seq_printf(m, "(0x%lx)", tu->ref_ctr_offset);
+
        for (i = 0; i < tu->tp.nr_args; i++)
                seq_printf(m, " %s=%s", tu->tp.args[i].name, tu->tp.args[i].comm);
 
@@ -833,7 +870,6 @@ print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *e
        struct trace_seq *s = &iter->seq;
        struct trace_uprobe *tu;
        u8 *data;
-       int i;
 
        entry = (struct uprobe_trace_entry_head *)iter->ent;
        tu = container_of(event, struct trace_uprobe, tp.call.event);
@@ -850,12 +886,8 @@ print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *e
                data = DATAOF_TRACE_ENTRY(entry, false);
        }
 
-       for (i = 0; i < tu->tp.nr_args; i++) {
-               struct probe_arg *parg = &tu->tp.args[i];
-
-               if (!parg->type->print(s, parg->name, data + parg->offset, entry))
-                       goto out;
-       }
+       if (print_probe_args(s, tu->tp.args, tu->tp.nr_args, data, entry) < 0)
+               goto out;
 
        trace_seq_putc(s, '\n');
 
@@ -905,7 +937,13 @@ probe_event_enable(struct trace_uprobe *tu, struct trace_event_file *file,
 
        tu->consumer.filter = filter;
        tu->inode = d_real_inode(tu->path.dentry);
-       ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
+       if (tu->ref_ctr_offset) {
+               ret = uprobe_register_refctr(tu->inode, tu->offset,
+                               tu->ref_ctr_offset, &tu->consumer);
+       } else {
+               ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
+       }
+
        if (ret)
                goto err_buffer;
 
@@ -958,7 +996,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file)
 
 static int uprobe_event_define_fields(struct trace_event_call *event_call)
 {
-       int ret, i, size;
+       int ret, size;
        struct uprobe_trace_entry_head field;
        struct trace_uprobe *tu = event_call->data;
 
@@ -970,19 +1008,8 @@ static int uprobe_event_define_fields(struct trace_event_call *event_call)
                DEFINE_FIELD(unsigned long, vaddr[0], FIELD_STRING_IP, 0);
                size = SIZEOF_TRACE_ENTRY(false);
        }
-       /* Set argument names as fields */
-       for (i = 0; i < tu->tp.nr_args; i++) {
-               struct probe_arg *parg = &tu->tp.args[i];
-
-               ret = trace_define_field(event_call, parg->type->fmttype,
-                                        parg->name, size + parg->offset,
-                                        parg->type->size, parg->type->is_signed,
-                                        FILTER_OTHER);
 
-               if (ret)
-                       return ret;
-       }
-       return 0;
+       return traceprobe_define_arg_fields(event_call, size, &tu->tp);
 }
 
 #ifdef CONFIG_PERF_EVENTS
@@ -1233,7 +1260,7 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
        esize = SIZEOF_TRACE_ENTRY(is_ret_probe(tu));
 
        ucb = uprobe_buffer_get();
-       store_trace_args(esize, &tu->tp, regs, ucb->buf, dsize);
+       store_trace_args(ucb->buf, &tu->tp, regs, esize, dsize);
 
        if (tu->tp.flags & TP_FLAG_TRACE)
                ret |= uprobe_trace_func(tu, regs, ucb, dsize);
@@ -1268,7 +1295,7 @@ static int uretprobe_dispatcher(struct uprobe_consumer *con,
        esize = SIZEOF_TRACE_ENTRY(is_ret_probe(tu));
 
        ucb = uprobe_buffer_get();
-       store_trace_args(esize, &tu->tp, regs, ucb->buf, dsize);
+       store_trace_args(ucb->buf, &tu->tp, regs, esize, dsize);
 
        if (tu->tp.flags & TP_FLAG_TRACE)
                uretprobe_trace_func(tu, func, regs, ucb, dsize);
@@ -1304,7 +1331,7 @@ static int register_uprobe_event(struct trace_uprobe *tu)
 
        init_trace_event_call(tu, call);
 
-       if (set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0)
+       if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0)
                return -ENOMEM;
 
        ret = register_trace_event(&call->event);
@@ -1340,7 +1367,8 @@ static int unregister_uprobe_event(struct trace_uprobe *tu)
 
 #ifdef CONFIG_PERF_EVENTS
 struct trace_event_call *
-create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
+create_local_trace_uprobe(char *name, unsigned long offs,
+                         unsigned long ref_ctr_offset, bool is_return)
 {
        struct trace_uprobe *tu;
        struct path path;
@@ -1372,10 +1400,11 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
 
        tu->offset = offs;
        tu->path = path;
+       tu->ref_ctr_offset = ref_ctr_offset;
        tu->filename = kstrdup(name, GFP_KERNEL);
        init_trace_event_call(tu, &tu->tp.call);
 
-       if (set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) {
+       if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) {
                ret = -ENOMEM;
                goto error;
        }
index d1573a16aa926cc2446b0629e6a5cec573de97d5..a9965f4af4dd391cce6fb3875bd48332560e3598 100644 (file)
@@ -624,6 +624,3 @@ config GENERIC_LIB_CMPDI2
 
 config GENERIC_LIB_UCMPDI2
        bool
-
-config GENERIC_LIB_UMODDI3
-       bool
index e0ba05e6f6bd151aea1ae5353a13f749ff0848c2..1af29b8224fdff289c210af95d3d9228769dbd2e 100644 (file)
@@ -1292,7 +1292,7 @@ config DEBUG_KOBJECT
        depends on DEBUG_KERNEL
        help
          If you say Y here, some extra kobject debugging messages will be sent
-         to the syslog. 
+         to the syslog.
 
 config DEBUG_KOBJECT_RELEASE
        bool "kobject release debugging"
@@ -1980,7 +1980,6 @@ endif # RUNTIME_TESTING_MENU
 
 config MEMTEST
        bool "Memtest"
-       depends on HAVE_MEMBLOCK
        ---help---
          This option adds a kernel parameter 'memtest', which allows memtest
          to be set.
index 988949c4fd3a7f49df646f3fcd195d0d1ad01dec..db06d123789834252c41e58f183e134bb127ae59 100644 (file)
@@ -274,4 +274,3 @@ obj-$(CONFIG_GENERIC_LIB_LSHRDI3) += lshrdi3.o
 obj-$(CONFIG_GENERIC_LIB_MULDI3) += muldi3.o
 obj-$(CONFIG_GENERIC_LIB_CMPDI2) += cmpdi2.o
 obj-$(CONFIG_GENERIC_LIB_UCMPDI2) += ucmpdi2.o
-obj-$(CONFIG_GENERIC_LIB_UMODDI3) += umoddi3.o udivmoddi4.o
index 2fd07f6df0b85e417f340576f530878a9d6ddcfc..eead55aa71706b385bb76830ba20ba043a076927 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/kernel.h>
+#include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/uaccess.h>
  * carefully filter out these unused bits from impacting their
  * results.
  *
- * These operations actually hold to a slightly stronger rule:
- * if you don't input any bitmaps to these ops that have some
- * unused bits set, then they won't output any set unused bits
- * in output bitmaps.
- *
  * The byte ordering of bitmaps is more natural on little
  * endian architectures.  See the big-endian headers
  * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h
@@ -466,20 +462,18 @@ EXPORT_SYMBOL(bitmap_parse_user);
  * ranges if list is specified or hex digits grouped into comma-separated
  * sets of 8 digits/set. Returns the number of characters written to buf.
  *
- * It is assumed that @buf is a pointer into a PAGE_SIZE area and that
- * sufficient storage remains at @buf to accommodate the
- * bitmap_print_to_pagebuf() output.
+ * It is assumed that @buf is a pointer into a PAGE_SIZE, page-aligned
+ * area and that sufficient storage remains at @buf to accommodate the
+ * bitmap_print_to_pagebuf() output. Returns the number of characters
+ * actually printed to @buf, excluding terminating '\0'.
  */
 int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
                            int nmaskbits)
 {
-       ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
-       int n = 0;
+       ptrdiff_t len = PAGE_SIZE - offset_in_page(buf);
 
-       if (len > 1)
-               n = list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) :
-                          scnprintf(buf, len, "%*pb\n", nmaskbits, maskp);
-       return n;
+       return list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) :
+                     scnprintf(buf, len, "%*pb\n", nmaskbits, maskp);
 }
 EXPORT_SYMBOL(bitmap_print_to_pagebuf);
 
index beca6244671a4ea066569e817bdbd912507b25db..8d666ab84b5c38fbcc0df25d7e6b0dbe0e81d68c 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/bitops.h>
 #include <linux/cpumask.h>
 #include <linux/export.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 /**
  * cpumask_next - get the next cpu in a cpumask
@@ -163,7 +163,7 @@ EXPORT_SYMBOL(zalloc_cpumask_var);
  */
 void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask)
 {
-       *mask = memblock_virt_alloc(cpumask_size(), 0);
+       *mask = memblock_alloc(cpumask_size(), SMP_CACHE_BYTES);
 }
 
 /**
index 661a1e807bd1ac89616ee1eff4ac395c05d617d8..1006bf70bf74c0ee514cc04d6085502933551b05 100644 (file)
@@ -175,7 +175,7 @@ int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
        rv = kstrtoull(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (unsigned long long)(unsigned long)tmp)
+       if (tmp != (unsigned long)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -191,7 +191,7 @@ int _kstrtol(const char *s, unsigned int base, long *res)
        rv = kstrtoll(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (long long)(long)tmp)
+       if (tmp != (long)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -222,7 +222,7 @@ int kstrtouint(const char *s, unsigned int base, unsigned int *res)
        rv = kstrtoull(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (unsigned long long)(unsigned int)tmp)
+       if (tmp != (unsigned int)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -253,7 +253,7 @@ int kstrtoint(const char *s, unsigned int base, int *res)
        rv = kstrtoll(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (long long)(int)tmp)
+       if (tmp != (int)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -268,7 +268,7 @@ int kstrtou16(const char *s, unsigned int base, u16 *res)
        rv = kstrtoull(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (unsigned long long)(u16)tmp)
+       if (tmp != (u16)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -283,7 +283,7 @@ int kstrtos16(const char *s, unsigned int base, s16 *res)
        rv = kstrtoll(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (long long)(s16)tmp)
+       if (tmp != (s16)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -298,7 +298,7 @@ int kstrtou8(const char *s, unsigned int base, u8 *res)
        rv = kstrtoull(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (unsigned long long)(u8)tmp)
+       if (tmp != (u8)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
@@ -313,7 +313,7 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
        rv = kstrtoll(s, base, &tmp);
        if (rv < 0)
                return rv;
-       if (tmp != (long long)(s8)tmp)
+       if (tmp != (s8)tmp)
                return -ERANGE;
        *res = tmp;
        return 0;
index 141734d255e4b941f888e32ee53885c26cfc8fbd..0c9d3ad17e0fc7b25b75b92d1ebec2c94ce8ecee 100644 (file)
 /*-*****************************
  *     Decompression functions
  *******************************/
-/* LZ4_decompress_generic() :
- * This generic decompression function cover all use cases.
- * It shall be instantiated several times, using different sets of directives
- * Note that it is important this generic function is really inlined,
+
+#define DEBUGLOG(l, ...) {}    /* disabled */
+
+#ifndef assert
+#define assert(condition) ((void)0)
+#endif
+
+/*
+ * LZ4_decompress_generic() :
+ * This generic decompression function covers all use cases.
+ * It shall be instantiated several times, using different sets of directives.
+ * Note that it is important for performance that this function really get inlined,
  * in order to remove useless branches during compilation optimization.
  */
 static FORCE_INLINE int LZ4_decompress_generic(
-        const char * const source,
-        char * const dest,
-        int inputSize,
+        const char * const src,
+        char * const dst,
+        int srcSize,
                /*
                 * If endOnInput == endOnInputSize,
-                * this value is the max size of Output Buffer.
+                * this value is `dstCapacity`
                 */
         int outputSize,
         /* endOnOutputSize, endOnInputSize */
-        int endOnInput,
+        endCondition_directive endOnInput,
         /* full, partial */
-        int partialDecoding,
-        /* only used if partialDecoding == partial */
-        int targetOutputSize,
+        earlyEnd_directive partialDecoding,
         /* noDict, withPrefix64k, usingExtDict */
-        int dict,
-        /* == dest when no prefix */
+        dict_directive dict,
+        /* always <= dst, == dst when no prefix */
         const BYTE * const lowPrefix,
         /* only if dict == usingExtDict */
         const BYTE * const dictStart,
@@ -74,35 +80,43 @@ static FORCE_INLINE int LZ4_decompress_generic(
         const size_t dictSize
         )
 {
-       /* Local Variables */
-       const BYTE *ip = (const BYTE *) source;
-       const BYTE * const iend = ip + inputSize;
+       const BYTE *ip = (const BYTE *) src;
+       const BYTE * const iend = ip + srcSize;
 
-       BYTE *op = (BYTE *) dest;
+       BYTE *op = (BYTE *) dst;
        BYTE * const oend = op + outputSize;
        BYTE *cpy;
-       BYTE *oexit = op + targetOutputSize;
-       const BYTE * const lowLimit = lowPrefix - dictSize;
 
        const BYTE * const dictEnd = (const BYTE *)dictStart + dictSize;
-       static const unsigned int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };
-       static const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
+       static const unsigned int inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4};
+       static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
 
        const int safeDecode = (endOnInput == endOnInputSize);
        const int checkOffset = ((safeDecode) && (dictSize < (int)(64 * KB)));
 
+       /* Set up the "end" pointers for the shortcut. */
+       const BYTE *const shortiend = iend -
+               (endOnInput ? 14 : 8) /*maxLL*/ - 2 /*offset*/;
+       const BYTE *const shortoend = oend -
+               (endOnInput ? 14 : 8) /*maxLL*/ - 18 /*maxML*/;
+
+       DEBUGLOG(5, "%s (srcSize:%i, dstSize:%i)", __func__,
+                srcSize, outputSize);
+
        /* Special cases */
-       /* targetOutputSize too high => decode everything */
-       if ((partialDecoding) && (oexit > oend - MFLIMIT))
-               oexit = oend - MFLIMIT;
+       assert(lowPrefix <= op);
+       assert(src != NULL);
 
        /* Empty output buffer */
        if ((endOnInput) && (unlikely(outputSize == 0)))
-               return ((inputSize == 1) && (*ip == 0)) ? 0 : -1;
+               return ((srcSize == 1) && (*ip == 0)) ? 0 : -1;
 
        if ((!endOnInput) && (unlikely(outputSize == 0)))
                return (*ip == 0 ? 1 : -1);
 
+       if ((endOnInput) && unlikely(srcSize == 0))
+               return -1;
+
        /* Main Loop : decode sequences */
        while (1) {
                size_t length;
@@ -111,12 +125,74 @@ static FORCE_INLINE int LZ4_decompress_generic(
 
                /* get literal length */
                unsigned int const token = *ip++;
-
                length = token>>ML_BITS;
 
+               /* ip < iend before the increment */
+               assert(!endOnInput || ip <= iend);
+
+               /*
+                * A two-stage shortcut for the most common case:
+                * 1) If the literal length is 0..14, and there is enough
+                * space, enter the shortcut and copy 16 bytes on behalf
+                * of the literals (in the fast mode, only 8 bytes can be
+                * safely copied this way).
+                * 2) Further if the match length is 4..18, copy 18 bytes
+                * in a similar manner; but we ensure that there's enough
+                * space in the output for those 18 bytes earlier, upon
+                * entering the shortcut (in other words, there is a
+                * combined check for both stages).
+                */
+               if ((endOnInput ? length != RUN_MASK : length <= 8)
+                  /*
+                   * strictly "less than" on input, to re-enter
+                   * the loop with at least one byte
+                   */
+                  && likely((endOnInput ? ip < shortiend : 1) &
+                            (op <= shortoend))) {
+                       /* Copy the literals */
+                       memcpy(op, ip, endOnInput ? 16 : 8);
+                       op += length; ip += length;
+
+                       /*
+                        * The second stage:
+                        * prepare for match copying, decode full info.
+                        * If it doesn't work out, the info won't be wasted.
+                        */
+                       length = token & ML_MASK; /* match length */
+                       offset = LZ4_readLE16(ip);
+                       ip += 2;
+                       match = op - offset;
+                       assert(match <= op); /* check overflow */
+
+                       /* Do not deal with overlapping matches. */
+                       if ((length != ML_MASK) &&
+                           (offset >= 8) &&
+                           (dict == withPrefix64k || match >= lowPrefix)) {
+                               /* Copy the match. */
+                               memcpy(op + 0, match + 0, 8);
+                               memcpy(op + 8, match + 8, 8);
+                               memcpy(op + 16, match + 16, 2);
+                               op += length + MINMATCH;
+                               /* Both stages worked, load the next token. */
+                               continue;
+                       }
+
+                       /*
+                        * The second stage didn't work out, but the info
+                        * is ready. Propel it right to the point of match
+                        * copying.
+                        */
+                       goto _copy_match;
+               }
+
+               /* decode literal length */
                if (length == RUN_MASK) {
                        unsigned int s;
 
+                       if (unlikely(endOnInput ? ip >= iend - RUN_MASK : 0)) {
+                               /* overflow detection */
+                               goto _output_error;
+                       }
                        do {
                                s = *ip++;
                                length += s;
@@ -125,14 +201,14 @@ static FORCE_INLINE int LZ4_decompress_generic(
                                : 1) & (s == 255));
 
                        if ((safeDecode)
-                               && unlikely(
-                                       (size_t)(op + length) < (size_t)(op))) {
+                           && unlikely((uptrval)(op) +
+                                       length < (uptrval)(op))) {
                                /* overflow detection */
                                goto _output_error;
                        }
                        if ((safeDecode)
-                               && unlikely(
-                                       (size_t)(ip + length) < (size_t)(ip))) {
+                           && unlikely((uptrval)(ip) +
+                                       length < (uptrval)(ip))) {
                                /* overflow detection */
                                goto _output_error;
                        }
@@ -140,16 +216,19 @@ static FORCE_INLINE int LZ4_decompress_generic(
 
                /* copy literals */
                cpy = op + length;
-               if (((endOnInput) && ((cpy > (partialDecoding ? oexit : oend - MFLIMIT))
+               LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
+
+               if (((endOnInput) && ((cpy > oend - MFLIMIT)
                        || (ip + length > iend - (2 + 1 + LASTLITERALS))))
                        || ((!endOnInput) && (cpy > oend - WILDCOPYLENGTH))) {
                        if (partialDecoding) {
                                if (cpy > oend) {
                                        /*
-                                        * Error :
-                                        * write attempt beyond end of output buffer
+                                        * Partial decoding :
+                                        * stop in the middle of literal segment
                                         */
-                                       goto _output_error;
+                                       cpy = oend;
+                                       length = oend - op;
                                }
                                if ((endOnInput)
                                        && (ip + length > iend)) {
@@ -184,29 +263,43 @@ static FORCE_INLINE int LZ4_decompress_generic(
                        memcpy(op, ip, length);
                        ip += length;
                        op += length;
+
                        /* Necessarily EOF, due to parsing restrictions */
-                       break;
+                       if (!partialDecoding || (cpy == oend))
+                               break;
+               } else {
+                       /* may overwrite up to WILDCOPYLENGTH beyond cpy */
+                       LZ4_wildCopy(op, ip, cpy);
+                       ip += length;
+                       op = cpy;
                }
 
-               LZ4_wildCopy(op, ip, cpy);
-               ip += length;
-               op = cpy;
-
                /* get offset */
                offset = LZ4_readLE16(ip);
                ip += 2;
                match = op - offset;
 
-               if ((checkOffset) && (unlikely(match < lowLimit))) {
+               /* get matchlength */
+               length = token & ML_MASK;
+
+_copy_match:
+               if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) {
                        /* Error : offset outside buffers */
                        goto _output_error;
                }
 
                /* costs ~1%; silence an msan warning when offset == 0 */
-               LZ4_write32(op, (U32)offset);
+               /*
+                * note : when partialDecoding, there is no guarantee that
+                * at least 4 bytes remain available in output buffer
+                */
+               if (!partialDecoding) {
+                       assert(oend > op);
+                       assert(oend - op >= 4);
+
+                       LZ4_write32(op, (U32)offset);
+               }
 
-               /* get matchlength */
-               length = token & ML_MASK;
                if (length == ML_MASK) {
                        unsigned int s;
 
@@ -221,7 +314,7 @@ static FORCE_INLINE int LZ4_decompress_generic(
 
                        if ((safeDecode)
                                && unlikely(
-                                       (size_t)(op + length) < (size_t)op)) {
+                                       (uptrval)(op) + length < (uptrval)op)) {
                                /* overflow detection */
                                goto _output_error;
                        }
@@ -229,24 +322,26 @@ static FORCE_INLINE int LZ4_decompress_generic(
 
                length += MINMATCH;
 
-               /* check external dictionary */
+               /* match starting within external dictionary */
                if ((dict == usingExtDict) && (match < lowPrefix)) {
                        if (unlikely(op + length > oend - LASTLITERALS)) {
                                /* doesn't respect parsing restriction */
-                               goto _output_error;
+                               if (!partialDecoding)
+                                       goto _output_error;
+                               length = min(length, (size_t)(oend - op));
                        }
 
                        if (length <= (size_t)(lowPrefix - match)) {
                                /*
-                                * match can be copied as a single segment
-                                * from external dictionary
+                                * match fits entirely within external
+                                * dictionary : just copy
                                 */
                                memmove(op, dictEnd - (lowPrefix - match),
                                        length);
                                op += length;
                        } else {
                                /*
-                                * match encompass external
+                                * match stretches into both external
                                 * dictionary and current block
                                 */
                                size_t const copySize = (size_t)(lowPrefix - match);
@@ -254,7 +349,6 @@ static FORCE_INLINE int LZ4_decompress_generic(
 
                                memcpy(op, dictEnd - copySize, copySize);
                                op += copySize;
-
                                if (restSize > (size_t)(op - lowPrefix)) {
                                        /* overlap copy */
                                        BYTE * const endOfMatch = op + restSize;
@@ -267,23 +361,44 @@ static FORCE_INLINE int LZ4_decompress_generic(
                                        op += restSize;
                                }
                        }
-
                        continue;
                }
 
                /* copy match within block */
                cpy = op + length;
 
-               if (unlikely(offset < 8)) {
-                       const int dec64 = dec64table[offset];
+               /*
+                * partialDecoding :
+                * may not respect endBlock parsing restrictions
+                */
+               assert(op <= oend);
+               if (partialDecoding &&
+                   (cpy > oend - MATCH_SAFEGUARD_DISTANCE)) {
+                       size_t const mlen = min(length, (size_t)(oend - op));
+                       const BYTE * const matchEnd = match + mlen;
+                       BYTE * const copyEnd = op + mlen;
+
+                       if (matchEnd > op) {
+                               /* overlap copy */
+                               while (op < copyEnd)
+                                       *op++ = *match++;
+                       } else {
+                               memcpy(op, match, mlen);
+                       }
+                       op = copyEnd;
+                       if (op == oend)
+                               break;
+                       continue;
+               }
 
+               if (unlikely(offset < 8)) {
                        op[0] = match[0];
                        op[1] = match[1];
                        op[2] = match[2];
                        op[3] = match[3];
-                       match += dec32table[offset];
+                       match += inc32table[offset];
                        memcpy(op + 4, match, 4);
-                       match -= dec64;
+                       match -= dec64table[offset];
                } else {
                        LZ4_copy8(op, match);
                        match += 8;
@@ -291,7 +406,7 @@ static FORCE_INLINE int LZ4_decompress_generic(
 
                op += 8;
 
-               if (unlikely(cpy > oend - 12)) {
+               if (unlikely(cpy > oend - MATCH_SAFEGUARD_DISTANCE)) {
                        BYTE * const oCopyLimit = oend - (WILDCOPYLENGTH - 1);
 
                        if (cpy > oend - LASTLITERALS) {
@@ -307,60 +422,139 @@ static FORCE_INLINE int LZ4_decompress_generic(
                                match += oCopyLimit - op;
                                op = oCopyLimit;
                        }
-
                        while (op < cpy)
                                *op++ = *match++;
                } else {
                        LZ4_copy8(op, match);
-
                        if (length > 16)
                                LZ4_wildCopy(op + 8, match + 8, cpy);
                }
-
-               op = cpy; /* correction */
+               op = cpy; /* wildcopy correction */
        }
 
        /* end of decoding */
        if (endOnInput) {
                /* Nb of output bytes decoded */
-               return (int) (((char *)op) - dest);
+               return (int) (((char *)op) - dst);
        } else {
                /* Nb of input bytes read */
-               return (int) (((const char *)ip) - source);
+               return (int) (((const char *)ip) - src);
        }
 
        /* Overflow error detected */
 _output_error:
-       return -1;
+       return (int) (-(((const char *)ip) - src)) - 1;
 }
 
 int LZ4_decompress_safe(const char *source, char *dest,
        int compressedSize, int maxDecompressedSize)
 {
-       return LZ4_decompress_generic(source, dest, compressedSize,
-               maxDecompressedSize, endOnInputSize, full, 0,
-               noDict, (BYTE *)dest, NULL, 0);
+       return LZ4_decompress_generic(source, dest,
+                                     compressedSize, maxDecompressedSize,
+                                     endOnInputSize, decode_full_block,
+                                     noDict, (BYTE *)dest, NULL, 0);
 }
 
-int LZ4_decompress_safe_partial(const char *source, char *dest,
-       int compressedSize, int targetOutputSize, int maxDecompressedSize)
+int LZ4_decompress_safe_partial(const char *src, char *dst,
+       int compressedSize, int targetOutputSize, int dstCapacity)
 {
-       return LZ4_decompress_generic(source, dest, compressedSize,
-               maxDecompressedSize, endOnInputSize, partial,
-               targetOutputSize, noDict, (BYTE *)dest, NULL, 0);
+       dstCapacity = min(targetOutputSize, dstCapacity);
+       return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity,
+                                     endOnInputSize, partial_decode,
+                                     noDict, (BYTE *)dst, NULL, 0);
 }
 
 int LZ4_decompress_fast(const char *source, char *dest, int originalSize)
 {
        return LZ4_decompress_generic(source, dest, 0, originalSize,
-               endOnOutputSize, full, 0, withPrefix64k,
-               (BYTE *)(dest - 64 * KB), NULL, 64 * KB);
+                                     endOnOutputSize, decode_full_block,
+                                     withPrefix64k,
+                                     (BYTE *)dest - 64 * KB, NULL, 0);
+}
+
+/* ===== Instantiate a few more decoding cases, used more than once. ===== */
+
+int LZ4_decompress_safe_withPrefix64k(const char *source, char *dest,
+                                     int compressedSize, int maxOutputSize)
+{
+       return LZ4_decompress_generic(source, dest,
+                                     compressedSize, maxOutputSize,
+                                     endOnInputSize, decode_full_block,
+                                     withPrefix64k,
+                                     (BYTE *)dest - 64 * KB, NULL, 0);
+}
+
+static int LZ4_decompress_safe_withSmallPrefix(const char *source, char *dest,
+                                              int compressedSize,
+                                              int maxOutputSize,
+                                              size_t prefixSize)
+{
+       return LZ4_decompress_generic(source, dest,
+                                     compressedSize, maxOutputSize,
+                                     endOnInputSize, decode_full_block,
+                                     noDict,
+                                     (BYTE *)dest - prefixSize, NULL, 0);
+}
+
+int LZ4_decompress_safe_forceExtDict(const char *source, char *dest,
+                                    int compressedSize, int maxOutputSize,
+                                    const void *dictStart, size_t dictSize)
+{
+       return LZ4_decompress_generic(source, dest,
+                                     compressedSize, maxOutputSize,
+                                     endOnInputSize, decode_full_block,
+                                     usingExtDict, (BYTE *)dest,
+                                     (const BYTE *)dictStart, dictSize);
 }
 
+static int LZ4_decompress_fast_extDict(const char *source, char *dest,
+                                      int originalSize,
+                                      const void *dictStart, size_t dictSize)
+{
+       return LZ4_decompress_generic(source, dest,
+                                     0, originalSize,
+                                     endOnOutputSize, decode_full_block,
+                                     usingExtDict, (BYTE *)dest,
+                                     (const BYTE *)dictStart, dictSize);
+}
+
+/*
+ * The "double dictionary" mode, for use with e.g. ring buffers: the first part
+ * of the dictionary is passed as prefix, and the second via dictStart + dictSize.
+ * These routines are used only once, in LZ4_decompress_*_continue().
+ */
+static FORCE_INLINE
+int LZ4_decompress_safe_doubleDict(const char *source, char *dest,
+                                  int compressedSize, int maxOutputSize,
+                                  size_t prefixSize,
+                                  const void *dictStart, size_t dictSize)
+{
+       return LZ4_decompress_generic(source, dest,
+                                     compressedSize, maxOutputSize,
+                                     endOnInputSize, decode_full_block,
+                                     usingExtDict, (BYTE *)dest - prefixSize,
+                                     (const BYTE *)dictStart, dictSize);
+}
+
+static FORCE_INLINE
+int LZ4_decompress_fast_doubleDict(const char *source, char *dest,
+                                  int originalSize, size_t prefixSize,
+                                  const void *dictStart, size_t dictSize)
+{
+       return LZ4_decompress_generic(source, dest,
+                                     0, originalSize,
+                                     endOnOutputSize, decode_full_block,
+                                     usingExtDict, (BYTE *)dest - prefixSize,
+                                     (const BYTE *)dictStart, dictSize);
+}
+
+/* ===== streaming decompression functions ===== */
+
 int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode,
        const char *dictionary, int dictSize)
 {
-       LZ4_streamDecode_t_internal *lz4sd = (LZ4_streamDecode_t_internal *) LZ4_streamDecode;
+       LZ4_streamDecode_t_internal *lz4sd =
+               &LZ4_streamDecode->internal_donotuse;
 
        lz4sd->prefixSize = (size_t) dictSize;
        lz4sd->prefixEnd = (const BYTE *) dictionary + dictSize;
@@ -382,35 +576,51 @@ int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode,
 int LZ4_decompress_safe_continue(LZ4_streamDecode_t *LZ4_streamDecode,
        const char *source, char *dest, int compressedSize, int maxOutputSize)
 {
-       LZ4_streamDecode_t_internal *lz4sd = &LZ4_streamDecode->internal_donotuse;
+       LZ4_streamDecode_t_internal *lz4sd =
+               &LZ4_streamDecode->internal_donotuse;
        int result;
 
-       if (lz4sd->prefixEnd == (BYTE *)dest) {
-               result = LZ4_decompress_generic(source, dest,
-                       compressedSize,
-                       maxOutputSize,
-                       endOnInputSize, full, 0,
-                       usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize,
-                       lz4sd->externalDict,
-                       lz4sd->extDictSize);
-
+       if (lz4sd->prefixSize == 0) {
+               /* The first call, no dictionary yet. */
+               assert(lz4sd->extDictSize == 0);
+               result = LZ4_decompress_safe(source, dest,
+                       compressedSize, maxOutputSize);
+               if (result <= 0)
+                       return result;
+               lz4sd->prefixSize = result;
+               lz4sd->prefixEnd = (BYTE *)dest + result;
+       } else if (lz4sd->prefixEnd == (BYTE *)dest) {
+               /* They're rolling the current segment. */
+               if (lz4sd->prefixSize >= 64 * KB - 1)
+                       result = LZ4_decompress_safe_withPrefix64k(source, dest,
+                               compressedSize, maxOutputSize);
+               else if (lz4sd->extDictSize == 0)
+                       result = LZ4_decompress_safe_withSmallPrefix(source,
+                               dest, compressedSize, maxOutputSize,
+                               lz4sd->prefixSize);
+               else
+                       result = LZ4_decompress_safe_doubleDict(source, dest,
+                               compressedSize, maxOutputSize,
+                               lz4sd->prefixSize,
+                               lz4sd->externalDict, lz4sd->extDictSize);
                if (result <= 0)
                        return result;
-
                lz4sd->prefixSize += result;
-               lz4sd->prefixEnd        += result;
+               lz4sd->prefixEnd  += result;
        } else {
+               /*
+                * The buffer wraps around, or they're
+                * switching to another buffer.
+                */
                lz4sd->extDictSize = lz4sd->prefixSize;
                lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
-               result = LZ4_decompress_generic(source, dest,
+               result = LZ4_decompress_safe_forceExtDict(source, dest,
                        compressedSize, maxOutputSize,
-                       endOnInputSize, full, 0,
-                       usingExtDict, (BYTE *)dest,
                        lz4sd->externalDict, lz4sd->extDictSize);
                if (result <= 0)
                        return result;
                lz4sd->prefixSize = result;
-               lz4sd->prefixEnd        = (BYTE *)dest + result;
+               lz4sd->prefixEnd  = (BYTE *)dest + result;
        }
 
        return result;
@@ -422,75 +632,66 @@ int LZ4_decompress_fast_continue(LZ4_streamDecode_t *LZ4_streamDecode,
        LZ4_streamDecode_t_internal *lz4sd = &LZ4_streamDecode->internal_donotuse;
        int result;
 
-       if (lz4sd->prefixEnd == (BYTE *)dest) {
-               result = LZ4_decompress_generic(source, dest, 0, originalSize,
-                       endOnOutputSize, full, 0,
-                       usingExtDict,
-                       lz4sd->prefixEnd - lz4sd->prefixSize,
-                       lz4sd->externalDict, lz4sd->extDictSize);
-
+       if (lz4sd->prefixSize == 0) {
+               assert(lz4sd->extDictSize == 0);
+               result = LZ4_decompress_fast(source, dest, originalSize);
+               if (result <= 0)
+                       return result;
+               lz4sd->prefixSize = originalSize;
+               lz4sd->prefixEnd = (BYTE *)dest + originalSize;
+       } else if (lz4sd->prefixEnd == (BYTE *)dest) {
+               if (lz4sd->prefixSize >= 64 * KB - 1 ||
+                   lz4sd->extDictSize == 0)
+                       result = LZ4_decompress_fast(source, dest,
+                                                    originalSize);
+               else
+                       result = LZ4_decompress_fast_doubleDict(source, dest,
+                               originalSize, lz4sd->prefixSize,
+                               lz4sd->externalDict, lz4sd->extDictSize);
                if (result <= 0)
                        return result;
-
                lz4sd->prefixSize += originalSize;
-               lz4sd->prefixEnd        += originalSize;
+               lz4sd->prefixEnd  += originalSize;
        } else {
                lz4sd->extDictSize = lz4sd->prefixSize;
                lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
-               result = LZ4_decompress_generic(source, dest, 0, originalSize,
-                       endOnOutputSize, full, 0,
-                       usingExtDict, (BYTE *)dest,
-                       lz4sd->externalDict, lz4sd->extDictSize);
+               result = LZ4_decompress_fast_extDict(source, dest,
+                       originalSize, lz4sd->externalDict, lz4sd->extDictSize);
                if (result <= 0)
                        return result;
                lz4sd->prefixSize = originalSize;
-               lz4sd->prefixEnd        = (BYTE *)dest + originalSize;
+               lz4sd->prefixEnd = (BYTE *)dest + originalSize;
        }
-
        return result;
 }
 
-/*
- * Advanced decoding functions :
- * *_usingDict() :
- * These decoding functions work the same as "_continue" ones,
- * the dictionary must be explicitly provided within parameters
- */
-static FORCE_INLINE int LZ4_decompress_usingDict_generic(const char *source,
-       char *dest, int compressedSize, int maxOutputSize, int safe,
-       const char *dictStart, int dictSize)
+int LZ4_decompress_safe_usingDict(const char *source, char *dest,
+                                 int compressedSize, int maxOutputSize,
+                                 const char *dictStart, int dictSize)
 {
        if (dictSize == 0)
-               return LZ4_decompress_generic(source, dest,
-                       compressedSize, maxOutputSize, safe, full, 0,
-                       noDict, (BYTE *)dest, NULL, 0);
-       if (dictStart + dictSize == dest) {
-               if (dictSize >= (int)(64 * KB - 1))
-                       return LZ4_decompress_generic(source, dest,
-                               compressedSize, maxOutputSize, safe, full, 0,
-                               withPrefix64k, (BYTE *)dest - 64 * KB, NULL, 0);
-               return LZ4_decompress_generic(source, dest, compressedSize,
-                       maxOutputSize, safe, full, 0, noDict,
-                       (BYTE *)dest - dictSize, NULL, 0);
+               return LZ4_decompress_safe(source, dest,
+                                          compressedSize, maxOutputSize);
+       if (dictStart+dictSize == dest) {
+               if (dictSize >= 64 * KB - 1)
+                       return LZ4_decompress_safe_withPrefix64k(source, dest,
+                               compressedSize, maxOutputSize);
+               return LZ4_decompress_safe_withSmallPrefix(source, dest,
+                       compressedSize, maxOutputSize, dictSize);
        }
-       return LZ4_decompress_generic(source, dest, compressedSize,
-               maxOutputSize, safe, full, 0, usingExtDict,
-               (BYTE *)dest, (const BYTE *)dictStart, dictSize);
-}
-
-int LZ4_decompress_safe_usingDict(const char *source, char *dest,
-       int compressedSize, int maxOutputSize,
-       const char *dictStart, int dictSize)
-{
-       return LZ4_decompress_usingDict_generic(source, dest,
-               compressedSize, maxOutputSize, 1, dictStart, dictSize);
+       return LZ4_decompress_safe_forceExtDict(source, dest,
+               compressedSize, maxOutputSize, dictStart, dictSize);
 }
 
 int LZ4_decompress_fast_usingDict(const char *source, char *dest,
-       int originalSize, const char *dictStart, int dictSize)
+                                 int originalSize,
+                                 const char *dictStart, int dictSize)
 {
-       return LZ4_decompress_usingDict_generic(source, dest, 0,
-               originalSize, 0, dictStart, dictSize);
+       if (dictSize == 0 || dictStart + dictSize == dest)
+               return LZ4_decompress_fast(source, dest, originalSize);
+
+       return LZ4_decompress_fast_extDict(source, dest, originalSize,
+               dictStart, dictSize);
 }
 
 #ifndef STATIC
index 00a0b58a0871bc3c1f0afca8aa9bbd03aab09edd..1a7fa9d9170fb6007eb66a14b3425570294c92d9 100644 (file)
@@ -75,6 +75,11 @@ typedef uintptr_t uptrval;
 #define WILDCOPYLENGTH 8
 #define LASTLITERALS 5
 #define MFLIMIT (WILDCOPYLENGTH + MINMATCH)
+/*
+ * ensure it's possible to write 2 x wildcopyLength
+ * without overflowing output buffer
+ */
+#define MATCH_SAFEGUARD_DISTANCE  ((2 * WILDCOPYLENGTH) - MINMATCH)
 
 /* Increase this value ==> compression run slower on incompressible data */
 #define LZ4_SKIPTRIGGER 6
@@ -222,6 +227,8 @@ typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
 typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
 
 typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
-typedef enum { full = 0, partial = 1 } earlyEnd_directive;
+typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive;
+
+#define LZ4_STATIC_ASSERT(c)   BUILD_BUG_ON(!(c))
 
 #endif
index 3278958b472a990bd777842c1b11ea0c4bb969bd..dd70e5e6c9e2fa7178b2b338cbd73671339b48d4 100644 (file)
@@ -131,13 +131,10 @@ static int match_number(substring_t *s, int *result, int base)
        char *buf;
        int ret;
        long val;
-       size_t len = s->to - s->from;
 
-       buf = kmalloc(len + 1, GFP_KERNEL);
+       buf = match_strdup(s);
        if (!buf)
                return -ENOMEM;
-       memcpy(buf, s->from, len);
-       buf[len] = '\0';
 
        ret = 0;
        val = simple_strtol(buf, &endp, base);
@@ -166,13 +163,10 @@ static int match_u64int(substring_t *s, u64 *result, int base)
        char *buf;
        int ret;
        u64 val;
-       size_t len = s->to - s->from;
 
-       buf = kmalloc(len + 1, GFP_KERNEL);
+       buf = match_strdup(s);
        if (!buf)
                return -ENOMEM;
-       memcpy(buf, s->from, len);
-       buf[len] = '\0';
 
        ret = kstrtoull(buf, base, &val);
        if (!ret)
@@ -327,10 +321,6 @@ EXPORT_SYMBOL(match_strlcpy);
  */
 char *match_strdup(const substring_t *s)
 {
-       size_t sz = s->to - s->from + 1;
-       char *p = kmalloc(sz, GFP_KERNEL);
-       if (p)
-               match_strlcpy(p, s, sz);
-       return p;
+       return kmemdup_nul(s->from, s->to - s->from, GFP_KERNEL);
 }
 EXPORT_SYMBOL(match_strdup);
index 6dd30615a201fde0e8f5c9a74a4a62427aa09c4e..d1c1e6388eaa735b6e6ec0b60b1ee9130ef40e82 100644 (file)
@@ -148,10 +148,9 @@ static __init int sg_pool_init(void)
 cleanup_sdb:
        for (i = 0; i < SG_MEMPOOL_NR; i++) {
                struct sg_pool *sgp = sg_pools + i;
-               if (sgp->pool)
-                       mempool_destroy(sgp->pool);
-               if (sgp->slab)
-                       kmem_cache_destroy(sgp->slab);
+
+               mempool_destroy(sgp->pool);
+               kmem_cache_destroy(sgp->slab);
        }
 
        return -ENOMEM;
diff --git a/lib/udivmoddi4.c b/lib/udivmoddi4.c
deleted file mode 100644 (file)
index c08bc8a..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.
- */
-
-#include <linux/libgcc.h>
-
-#define count_leading_zeros(COUNT, X)   ((COUNT) = __builtin_clz(X))
-
-#define W_TYPE_SIZE 32
-
-#define __ll_B ((unsigned long) 1 << (W_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((unsigned long) (t) & (__ll_B - 1))
-#define __ll_highpart(t) ((unsigned long) (t) >> (W_TYPE_SIZE / 2))
-
-/* If we still don't have umul_ppmm, define it using plain C. */
-#if !defined(umul_ppmm)
-#define umul_ppmm(w1, w0, u, v)                                                \
-       do {                                                            \
-               unsigned long __x0, __x1, __x2, __x3;                   \
-               unsigned short __ul, __vl, __uh, __vh;                  \
-                                                                       \
-               __ul = __ll_lowpart(u);                                 \
-               __uh = __ll_highpart(u);                                \
-               __vl = __ll_lowpart(v);                                 \
-               __vh = __ll_highpart(v);                                \
-                                                                       \
-               __x0 = (unsigned long) __ul * __vl;                     \
-               __x1 = (unsigned long) __ul * __vh;                     \
-               __x2 = (unsigned long) __uh * __vl;                     \
-               __x3 = (unsigned long) __uh * __vh;                     \
-                                                                       \
-               __x1 += __ll_highpart(__x0);                            \
-               __x1 += __x2;                                           \
-               if (__x1 < __x2)                                        \
-                       __x3 += __ll_B;                                 \
-                                                                       \
-               (w1) = __x3 + __ll_highpart(__x1);                      \
-               (w0) = __ll_lowpart(__x1) * __ll_B + __ll_lowpart(__x0);\
-       } while (0)
-#endif
-
-#if !defined(sub_ddmmss)
-#define sub_ddmmss(sh, sl, ah, al, bh, bl)                             \
-       do {                                                            \
-               unsigned long __x;                                      \
-               __x = (al) - (bl);                                      \
-               (sh) = (ah) - (bh) - (__x > (al));                      \
-               (sl) = __x;                                             \
-       } while (0)
-#endif
-
-/* Define this unconditionally, so it can be used for debugging. */
-#define __udiv_qrnnd_c(q, r, n1, n0, d)                                        \
-       do {                                                            \
-               unsigned long __d1, __d0, __q1, __q0;                   \
-               unsigned long __r1, __r0, __m;                          \
-               __d1 = __ll_highpart(d);                                \
-               __d0 = __ll_lowpart(d);                         \
-                                                                       \
-               __r1 = (n1) % __d1;                                     \
-               __q1 = (n1) / __d1;                                     \
-               __m = (unsigned long) __q1 * __d0;                      \
-               __r1 = __r1 * __ll_B | __ll_highpart(n0);               \
-               if (__r1 < __m) {                                       \
-                       __q1--, __r1 += (d);                            \
-                       if (__r1 >= (d))                                \
-                               if (__r1 < __m)                         \
-                                       __q1--, __r1 += (d);            \
-               }                                                       \
-               __r1 -= __m;                                            \
-                                                                       \
-               __r0 = __r1 % __d1;                                     \
-               __q0 = __r1 / __d1;                                     \
-               __m = (unsigned long) __q0 * __d0;                      \
-               __r0 = __r0 * __ll_B | __ll_lowpart(n0);                \
-               if (__r0 < __m) {                                       \
-                       __q0--, __r0 += (d);                            \
-                       if (__r0 >= (d))                                \
-                               if (__r0 < __m)                         \
-                                       __q0--, __r0 += (d);            \
-               }                                                       \
-               __r0 -= __m;                                            \
-                                                                       \
-               (q) = (unsigned long) __q1 * __ll_B | __q0;             \
-               (r) = __r0;                                             \
-       } while (0)
-
-/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
-#if !defined(udiv_qrnnd)
-#define UDIV_NEEDS_NORMALIZATION 1
-#define udiv_qrnnd __udiv_qrnnd_c
-#endif
-
-unsigned long long __udivmoddi4(unsigned long long u, unsigned long long v,
-                               unsigned long long *rp)
-{
-       const DWunion nn = {.ll = u };
-       const DWunion dd = {.ll = v };
-       DWunion rr, ww;
-       unsigned long d0, d1, n0, n1, n2;
-       unsigned long q0 = 0, q1 = 0;
-       unsigned long b, bm;
-
-       d0 = dd.s.low;
-       d1 = dd.s.high;
-       n0 = nn.s.low;
-       n1 = nn.s.high;
-
-#if !UDIV_NEEDS_NORMALIZATION
-
-       if (d1 == 0) {
-               if (d0 > n1) {
-                       /* 0q = nn / 0D */
-
-                       udiv_qrnnd(q0, n0, n1, n0, d0);
-                       q1 = 0;
-
-                       /* Remainder in n0. */
-               } else {
-                       /* qq = NN / 0d */
-
-                       if (d0 == 0)
-                               /* Divide intentionally by zero. */
-                               d0 = 1 / d0;
-
-                       udiv_qrnnd(q1, n1, 0, n1, d0);
-                       udiv_qrnnd(q0, n0, n1, n0, d0);
-
-                       /* Remainder in n0. */
-               }
-
-               if (rp != 0) {
-                       rr.s.low = n0;
-                       rr.s.high = 0;
-                       *rp = rr.ll;
-               }
-
-#else /* UDIV_NEEDS_NORMALIZATION */
-
-       if (d1 == 0) {
-               if (d0 > n1) {
-                       /* 0q = nn / 0D */
-
-                       count_leading_zeros(bm, d0);
-
-                       if (bm != 0) {
-                               /*
-                                * Normalize, i.e. make the most significant bit
-                                * of the denominator set.
-                                */
-
-                               d0 = d0 << bm;
-                               n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
-                               n0 = n0 << bm;
-                       }
-
-                       udiv_qrnnd(q0, n0, n1, n0, d0);
-                       q1 = 0;
-
-                       /* Remainder in n0 >> bm. */
-               } else {
-                       /* qq = NN / 0d */
-
-                       if (d0 == 0)
-                               /* Divide intentionally by zero. */
-                               d0 = 1 / d0;
-
-                       count_leading_zeros(bm, d0);
-
-                       if (bm == 0) {
-                               /*
-                                * From (n1 >= d0) /\ (the most significant bit
-                                * of d0 is set), conclude (the most significant
-                                * bit of n1 is set) /\ (theleading quotient
-                                * digit q1 = 1).
-                                *
-                                * This special case is necessary, not an
-                                * optimization. (Shifts counts of W_TYPE_SIZE
-                                * are undefined.)
-                                */
-
-                               n1 -= d0;
-                               q1 = 1;
-                       } else {
-                               /* Normalize. */
-
-                               b = W_TYPE_SIZE - bm;
-
-                               d0 = d0 << bm;
-                               n2 = n1 >> b;
-                               n1 = (n1 << bm) | (n0 >> b);
-                               n0 = n0 << bm;
-
-                               udiv_qrnnd(q1, n1, n2, n1, d0);
-                       }
-
-                       /* n1 != d0... */
-
-                       udiv_qrnnd(q0, n0, n1, n0, d0);
-
-                       /* Remainder in n0 >> bm. */
-               }
-
-               if (rp != 0) {
-                       rr.s.low = n0 >> bm;
-                       rr.s.high = 0;
-                       *rp = rr.ll;
-               }
-
-#endif /* UDIV_NEEDS_NORMALIZATION */
-
-       } else {
-               if (d1 > n1) {
-                       /* 00 = nn / DD */
-
-                       q0 = 0;
-                       q1 = 0;
-
-                       /* Remainder in n1n0. */
-                       if (rp != 0) {
-                               rr.s.low = n0;
-                               rr.s.high = n1;
-                               *rp = rr.ll;
-                       }
-               } else {
-                       /* 0q = NN / dd */
-
-                       count_leading_zeros(bm, d1);
-                       if (bm == 0) {
-                               /*
-                                * From (n1 >= d1) /\ (the most significant bit
-                                * of d1 is set), conclude (the most significant
-                                * bit of n1 is set) /\ (the quotient digit q0 =
-                                * 0 or 1).
-                                *
-                                * This special case is necessary, not an
-                                * optimization.
-                                */
-
-                               /*
-                                * The condition on the next line takes
-                                * advantage of that n1 >= d1 (true due to
-                                * program flow).
-                                */
-                               if (n1 > d1 || n0 >= d0) {
-                                       q0 = 1;
-                                       sub_ddmmss(n1, n0, n1, n0, d1, d0);
-                               } else {
-                                       q0 = 0;
-                               }
-
-                               q1 = 0;
-
-                               if (rp != 0) {
-                                       rr.s.low = n0;
-                                       rr.s.high = n1;
-                                       *rp = rr.ll;
-                               }
-                       } else {
-                               unsigned long m1, m0;
-                               /* Normalize. */
-
-                               b = W_TYPE_SIZE - bm;
-
-                               d1 = (d1 << bm) | (d0 >> b);
-                               d0 = d0 << bm;
-                               n2 = n1 >> b;
-                               n1 = (n1 << bm) | (n0 >> b);
-                               n0 = n0 << bm;
-
-                               udiv_qrnnd(q0, n1, n2, n1, d1);
-                               umul_ppmm(m1, m0, q0, d0);
-
-                               if (m1 > n1 || (m1 == n1 && m0 > n0)) {
-                                       q0--;
-                                       sub_ddmmss(m1, m0, m1, m0, d1, d0);
-                               }
-
-                               q1 = 0;
-
-                               /* Remainder in (n1n0 - m1m0) >> bm. */
-                               if (rp != 0) {
-                                       sub_ddmmss(n1, n0, n1, n0, m1, m0);
-                                       rr.s.low = (n1 << b) | (n0 >> bm);
-                                       rr.s.high = n1 >> bm;
-                                       *rp = rr.ll;
-                               }
-                       }
-               }
-       }
-
-       ww.s.low = q0;
-       ww.s.high = q1;
-
-       return ww.ll;
-}
diff --git a/lib/umoddi3.c b/lib/umoddi3.c
deleted file mode 100644 (file)
index d7bbf0f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.
- */
-
-#include <linux/module.h>
-#include <linux/libgcc.h>
-
-extern unsigned long long __udivmoddi4(unsigned long long u,
-                                      unsigned long long v,
-                                      unsigned long long *rp);
-
-unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
-{
-       unsigned long long w;
-       (void)__udivmoddi4(u, v, &w);
-       return w;
-}
-EXPORT_SYMBOL(__umoddi3);
index 58a733b1038740f2faefca7efb40de57131e5ac6..48f14cd58c77647d20e60ba9b5fc0ac81198254c 100644 (file)
@@ -382,6 +382,7 @@ int zlib_inflate(z_streamp strm, int flush)
             strm->adler = state->check = REVERSE(hold);
             INITBITS();
             state->mode = DICT;
+           /* fall through */
         case DICT:
             if (state->havedict == 0) {
                 RESTORE();
@@ -389,8 +390,10 @@ int zlib_inflate(z_streamp strm, int flush)
             }
             strm->adler = state->check = zlib_adler32(0L, NULL, 0);
             state->mode = TYPE;
+           /* fall through */
         case TYPE:
             if (flush == Z_BLOCK) goto inf_leave;
+           /* fall through */
         case TYPEDO:
             if (state->last) {
                 BYTEBITS();
@@ -428,6 +431,7 @@ int zlib_inflate(z_streamp strm, int flush)
             state->length = (unsigned)hold & 0xffff;
             INITBITS();
             state->mode = COPY;
+           /* fall through */
         case COPY:
             copy = state->length;
             if (copy) {
@@ -461,6 +465,7 @@ int zlib_inflate(z_streamp strm, int flush)
 #endif
             state->have = 0;
             state->mode = LENLENS;
+           /* fall through */
         case LENLENS:
             while (state->have < state->ncode) {
                 NEEDBITS(3);
@@ -481,6 +486,7 @@ int zlib_inflate(z_streamp strm, int flush)
             }
             state->have = 0;
             state->mode = CODELENS;
+           /* fall through */
         case CODELENS:
             while (state->have < state->nlen + state->ndist) {
                 for (;;) {
@@ -554,6 +560,7 @@ int zlib_inflate(z_streamp strm, int flush)
                 break;
             }
             state->mode = LEN;
+           /* fall through */
         case LEN:
             if (have >= 6 && left >= 258) {
                 RESTORE();
@@ -593,6 +600,7 @@ int zlib_inflate(z_streamp strm, int flush)
             }
             state->extra = (unsigned)(this.op) & 15;
             state->mode = LENEXT;
+           /* fall through */
         case LENEXT:
             if (state->extra) {
                 NEEDBITS(state->extra);
@@ -600,6 +608,7 @@ int zlib_inflate(z_streamp strm, int flush)
                 DROPBITS(state->extra);
             }
             state->mode = DIST;
+           /* fall through */
         case DIST:
             for (;;) {
                 this = state->distcode[BITS(state->distbits)];
@@ -625,6 +634,7 @@ int zlib_inflate(z_streamp strm, int flush)
             state->offset = (unsigned)this.val;
             state->extra = (unsigned)(this.op) & 15;
             state->mode = DISTEXT;
+           /* fall through */
         case DISTEXT:
             if (state->extra) {
                 NEEDBITS(state->extra);
@@ -644,6 +654,7 @@ int zlib_inflate(z_streamp strm, int flush)
                 break;
             }
             state->mode = MATCH;
+           /* fall through */
         case MATCH:
             if (left == 0) goto inf_leave;
             copy = out - left;
@@ -694,6 +705,7 @@ int zlib_inflate(z_streamp strm, int flush)
                 INITBITS();
             }
             state->mode = DONE;
+           /* fall through */
         case DONE:
             ret = Z_STREAM_END;
             goto inf_leave;
index 02301a89089eb80098e1c3efda4aef5b7e5e758e..d85e39da47aed166d58f7bba669d60afb12bad59 100644 (file)
@@ -127,9 +127,6 @@ config SPARSEMEM_VMEMMAP
         pfn_to_page and page_to_pfn operations.  This is the most
         efficient option when sufficient kernel resources are available.
 
-config HAVE_MEMBLOCK
-       bool
-
 config HAVE_MEMBLOCK_NODE_MAP
        bool
 
@@ -142,9 +139,6 @@ config HAVE_GENERIC_GUP
 config ARCH_DISCARD_MEMBLOCK
        bool
 
-config NO_BOOTMEM
-       bool
-
 config MEMORY_ISOLATION
        bool
 
@@ -481,7 +475,7 @@ config FRONTSWAP
 
 config CMA
        bool "Contiguous Memory Allocator"
-       depends on HAVE_MEMBLOCK && MMU
+       depends on MMU
        select MIGRATION
        select MEMORY_ISOLATION
        help
@@ -634,7 +628,6 @@ config MAX_STACK_SIZE_MB
 config DEFERRED_STRUCT_PAGE_INIT
        bool "Defer initialisation of struct pages to kthreads"
        default n
-       depends on NO_BOOTMEM
        depends on SPARSEMEM
        depends on !NEED_PER_CPU_KM
        depends on 64BIT
index 6485d5745dd7cde92379861e6995af47a1f4abab..d210cc9d6f800711a08523d364ecfa42431cdf39 100644 (file)
@@ -42,17 +42,11 @@ obj-y                       := filemap.o mempool.o oom_kill.o fadvise.o \
                           debug.o $(mmu-y)
 
 obj-y += init-mm.o
-
-ifdef CONFIG_NO_BOOTMEM
-       obj-y           += nobootmem.o
-else
-       obj-y           += bootmem.o
-endif
+obj-y += memblock.o
 
 ifdef CONFIG_MMU
        obj-$(CONFIG_ADVISE_SYSCALLS)   += madvise.o
 endif
-obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
 
 obj-$(CONFIG_SWAP)     += page_io.o swap_state.o swapfile.o swap_slots.o
 obj-$(CONFIG_FRONTSWAP)        += frontswap.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
deleted file mode 100644 (file)
index 97db0e8..0000000
+++ /dev/null
@@ -1,811 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *  bootmem - A boot-time physical memory allocator and configurator
- *
- *  Copyright (C) 1999 Ingo Molnar
- *                1999 Kanoj Sarcar, SGI
- *                2008 Johannes Weiner
- *
- * Access to this subsystem has to be serialized externally (which is true
- * for the boot process anyway).
- */
-#include <linux/init.h>
-#include <linux/pfn.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/kmemleak.h>
-#include <linux/range.h>
-#include <linux/bug.h>
-#include <linux/io.h>
-#include <linux/bootmem.h>
-
-#include "internal.h"
-
-/**
- * DOC: bootmem overview
- *
- * Bootmem is a boot-time physical memory allocator and configurator.
- *
- * It is used early in the boot process before the page allocator is
- * set up.
- *
- * Bootmem is based on the most basic of allocators, a First Fit
- * allocator which uses a bitmap to represent memory. If a bit is 1,
- * the page is allocated and 0 if unallocated. To satisfy allocations
- * of sizes smaller than a page, the allocator records the Page Frame
- * Number (PFN) of the last allocation and the offset the allocation
- * ended at. Subsequent small allocations are merged together and
- * stored on the same page.
- *
- * The information used by the bootmem allocator is represented by
- * :c:type:`struct bootmem_data`. An array to hold up to %MAX_NUMNODES
- * such structures is statically allocated and then it is discarded
- * when the system initialization completes. Each entry in this array
- * corresponds to a node with memory. For UMA systems only entry 0 is
- * used.
- *
- * The bootmem allocator is initialized during early architecture
- * specific setup. Each architecture is required to supply a
- * :c:func:`setup_arch` function which, among other tasks, is
- * responsible for acquiring the necessary parameters to initialise
- * the boot memory allocator. These parameters define limits of usable
- * physical memory:
- *
- * * @min_low_pfn - the lowest PFN that is available in the system
- * * @max_low_pfn - the highest PFN that may be addressed by low
- *   memory (%ZONE_NORMAL)
- * * @max_pfn - the last PFN available to the system.
- *
- * After those limits are determined, the :c:func:`init_bootmem` or
- * :c:func:`init_bootmem_node` function should be called to initialize
- * the bootmem allocator. The UMA case should use the `init_bootmem`
- * function. It will initialize ``contig_page_data`` structure that
- * represents the only memory node in the system. In the NUMA case the
- * `init_bootmem_node` function should be called to initialize the
- * bootmem allocator for each node.
- *
- * Once the allocator is set up, it is possible to use either single
- * node or NUMA variant of the allocation APIs.
- */
-
-#ifndef CONFIG_NEED_MULTIPLE_NODES
-struct pglist_data __refdata contig_page_data = {
-       .bdata = &bootmem_node_data[0]
-};
-EXPORT_SYMBOL(contig_page_data);
-#endif
-
-unsigned long max_low_pfn;
-unsigned long min_low_pfn;
-unsigned long max_pfn;
-unsigned long long max_possible_pfn;
-
-bootmem_data_t bootmem_node_data[MAX_NUMNODES] __initdata;
-
-static struct list_head bdata_list __initdata = LIST_HEAD_INIT(bdata_list);
-
-static int bootmem_debug;
-
-static int __init bootmem_debug_setup(char *buf)
-{
-       bootmem_debug = 1;
-       return 0;
-}
-early_param("bootmem_debug", bootmem_debug_setup);
-
-#define bdebug(fmt, args...) ({                                \
-       if (unlikely(bootmem_debug))                    \
-               pr_info("bootmem::%s " fmt,             \
-                       __func__, ## args);             \
-})
-
-static unsigned long __init bootmap_bytes(unsigned long pages)
-{
-       unsigned long bytes = DIV_ROUND_UP(pages, BITS_PER_BYTE);
-
-       return ALIGN(bytes, sizeof(long));
-}
-
-/**
- * bootmem_bootmap_pages - calculate bitmap size in pages
- * @pages: number of pages the bitmap has to represent
- *
- * Return: the number of pages needed to hold the bitmap.
- */
-unsigned long __init bootmem_bootmap_pages(unsigned long pages)
-{
-       unsigned long bytes = bootmap_bytes(pages);
-
-       return PAGE_ALIGN(bytes) >> PAGE_SHIFT;
-}
-
-/*
- * link bdata in order
- */
-static void __init link_bootmem(bootmem_data_t *bdata)
-{
-       bootmem_data_t *ent;
-
-       list_for_each_entry(ent, &bdata_list, list) {
-               if (bdata->node_min_pfn < ent->node_min_pfn) {
-                       list_add_tail(&bdata->list, &ent->list);
-                       return;
-               }
-       }
-
-       list_add_tail(&bdata->list, &bdata_list);
-}
-
-/*
- * Called once to set up the allocator itself.
- */
-static unsigned long __init init_bootmem_core(bootmem_data_t *bdata,
-       unsigned long mapstart, unsigned long start, unsigned long end)
-{
-       unsigned long mapsize;
-
-       mminit_validate_memmodel_limits(&start, &end);
-       bdata->node_bootmem_map = phys_to_virt(PFN_PHYS(mapstart));
-       bdata->node_min_pfn = start;
-       bdata->node_low_pfn = end;
-       link_bootmem(bdata);
-
-       /*
-        * Initially all pages are reserved - setup_arch() has to
-        * register free RAM areas explicitly.
-        */
-       mapsize = bootmap_bytes(end - start);
-       memset(bdata->node_bootmem_map, 0xff, mapsize);
-
-       bdebug("nid=%td start=%lx map=%lx end=%lx mapsize=%lx\n",
-               bdata - bootmem_node_data, start, mapstart, end, mapsize);
-
-       return mapsize;
-}
-
-/**
- * init_bootmem_node - register a node as boot memory
- * @pgdat: node to register
- * @freepfn: pfn where the bitmap for this node is to be placed
- * @startpfn: first pfn on the node
- * @endpfn: first pfn after the node
- *
- * Return: the number of bytes needed to hold the bitmap for this node.
- */
-unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
-                               unsigned long startpfn, unsigned long endpfn)
-{
-       return init_bootmem_core(pgdat->bdata, freepfn, startpfn, endpfn);
-}
-
-/**
- * init_bootmem - register boot memory
- * @start: pfn where the bitmap is to be placed
- * @pages: number of available physical pages
- *
- * Return: the number of bytes needed to hold the bitmap.
- */
-unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
-{
-       max_low_pfn = pages;
-       min_low_pfn = start;
-       return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
-}
-
-void __init free_bootmem_late(unsigned long physaddr, unsigned long size)
-{
-       unsigned long cursor, end;
-
-       kmemleak_free_part_phys(physaddr, size);
-
-       cursor = PFN_UP(physaddr);
-       end = PFN_DOWN(physaddr + size);
-
-       for (; cursor < end; cursor++) {
-               __free_pages_bootmem(pfn_to_page(cursor), cursor, 0);
-               totalram_pages++;
-       }
-}
-
-static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
-{
-       struct page *page;
-       unsigned long *map, start, end, pages, cur, count = 0;
-
-       if (!bdata->node_bootmem_map)
-               return 0;
-
-       map = bdata->node_bootmem_map;
-       start = bdata->node_min_pfn;
-       end = bdata->node_low_pfn;
-
-       bdebug("nid=%td start=%lx end=%lx\n",
-               bdata - bootmem_node_data, start, end);
-
-       while (start < end) {
-               unsigned long idx, vec;
-               unsigned shift;
-
-               idx = start - bdata->node_min_pfn;
-               shift = idx & (BITS_PER_LONG - 1);
-               /*
-                * vec holds at most BITS_PER_LONG map bits,
-                * bit 0 corresponds to start.
-                */
-               vec = ~map[idx / BITS_PER_LONG];
-
-               if (shift) {
-                       vec >>= shift;
-                       if (end - start >= BITS_PER_LONG)
-                               vec |= ~map[idx / BITS_PER_LONG + 1] <<
-                                       (BITS_PER_LONG - shift);
-               }
-               /*
-                * If we have a properly aligned and fully unreserved
-                * BITS_PER_LONG block of pages in front of us, free
-                * it in one go.
-                */
-               if (IS_ALIGNED(start, BITS_PER_LONG) && vec == ~0UL) {
-                       int order = ilog2(BITS_PER_LONG);
-
-                       __free_pages_bootmem(pfn_to_page(start), start, order);
-                       count += BITS_PER_LONG;
-                       start += BITS_PER_LONG;
-               } else {
-                       cur = start;
-
-                       start = ALIGN(start + 1, BITS_PER_LONG);
-                       while (vec && cur != start) {
-                               if (vec & 1) {
-                                       page = pfn_to_page(cur);
-                                       __free_pages_bootmem(page, cur, 0);
-                                       count++;
-                               }
-                               vec >>= 1;
-                               ++cur;
-                       }
-               }
-       }
-
-       cur = bdata->node_min_pfn;
-       page = virt_to_page(bdata->node_bootmem_map);
-       pages = bdata->node_low_pfn - bdata->node_min_pfn;
-       pages = bootmem_bootmap_pages(pages);
-       count += pages;
-       while (pages--)
-               __free_pages_bootmem(page++, cur++, 0);
-       bdata->node_bootmem_map = NULL;
-
-       bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
-
-       return count;
-}
-
-static int reset_managed_pages_done __initdata;
-
-void reset_node_managed_pages(pg_data_t *pgdat)
-{
-       struct zone *z;
-
-       for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
-               z->managed_pages = 0;
-}
-
-void __init reset_all_zones_managed_pages(void)
-{
-       struct pglist_data *pgdat;
-
-       if (reset_managed_pages_done)
-               return;
-
-       for_each_online_pgdat(pgdat)
-               reset_node_managed_pages(pgdat);
-
-       reset_managed_pages_done = 1;
-}
-
-unsigned long __init free_all_bootmem(void)
-{
-       unsigned long total_pages = 0;
-       bootmem_data_t *bdata;
-
-       reset_all_zones_managed_pages();
-
-       list_for_each_entry(bdata, &bdata_list, list)
-               total_pages += free_all_bootmem_core(bdata);
-
-       totalram_pages += total_pages;
-
-       return total_pages;
-}
-
-static void __init __free(bootmem_data_t *bdata,
-                       unsigned long sidx, unsigned long eidx)
-{
-       unsigned long idx;
-
-       bdebug("nid=%td start=%lx end=%lx\n", bdata - bootmem_node_data,
-               sidx + bdata->node_min_pfn,
-               eidx + bdata->node_min_pfn);
-
-       if (WARN_ON(bdata->node_bootmem_map == NULL))
-               return;
-
-       if (bdata->hint_idx > sidx)
-               bdata->hint_idx = sidx;
-
-       for (idx = sidx; idx < eidx; idx++)
-               if (!test_and_clear_bit(idx, bdata->node_bootmem_map))
-                       BUG();
-}
-
-static int __init __reserve(bootmem_data_t *bdata, unsigned long sidx,
-                       unsigned long eidx, int flags)
-{
-       unsigned long idx;
-       int exclusive = flags & BOOTMEM_EXCLUSIVE;
-
-       bdebug("nid=%td start=%lx end=%lx flags=%x\n",
-               bdata - bootmem_node_data,
-               sidx + bdata->node_min_pfn,
-               eidx + bdata->node_min_pfn,
-               flags);
-
-       if (WARN_ON(bdata->node_bootmem_map == NULL))
-               return 0;
-
-       for (idx = sidx; idx < eidx; idx++)
-               if (test_and_set_bit(idx, bdata->node_bootmem_map)) {
-                       if (exclusive) {
-                               __free(bdata, sidx, idx);
-                               return -EBUSY;
-                       }
-                       bdebug("silent double reserve of PFN %lx\n",
-                               idx + bdata->node_min_pfn);
-               }
-       return 0;
-}
-
-static int __init mark_bootmem_node(bootmem_data_t *bdata,
-                               unsigned long start, unsigned long end,
-                               int reserve, int flags)
-{
-       unsigned long sidx, eidx;
-
-       bdebug("nid=%td start=%lx end=%lx reserve=%d flags=%x\n",
-               bdata - bootmem_node_data, start, end, reserve, flags);
-
-       BUG_ON(start < bdata->node_min_pfn);
-       BUG_ON(end > bdata->node_low_pfn);
-
-       sidx = start - bdata->node_min_pfn;
-       eidx = end - bdata->node_min_pfn;
-
-       if (reserve)
-               return __reserve(bdata, sidx, eidx, flags);
-       else
-               __free(bdata, sidx, eidx);
-       return 0;
-}
-
-static int __init mark_bootmem(unsigned long start, unsigned long end,
-                               int reserve, int flags)
-{
-       unsigned long pos;
-       bootmem_data_t *bdata;
-
-       pos = start;
-       list_for_each_entry(bdata, &bdata_list, list) {
-               int err;
-               unsigned long max;
-
-               if (pos < bdata->node_min_pfn ||
-                   pos >= bdata->node_low_pfn) {
-                       BUG_ON(pos != start);
-                       continue;
-               }
-
-               max = min(bdata->node_low_pfn, end);
-
-               err = mark_bootmem_node(bdata, pos, max, reserve, flags);
-               if (reserve && err) {
-                       mark_bootmem(start, pos, 0, 0);
-                       return err;
-               }
-
-               if (max == end)
-                       return 0;
-               pos = bdata->node_low_pfn;
-       }
-       BUG();
-}
-
-void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
-                             unsigned long size)
-{
-       unsigned long start, end;
-
-       kmemleak_free_part_phys(physaddr, size);
-
-       start = PFN_UP(physaddr);
-       end = PFN_DOWN(physaddr + size);
-
-       mark_bootmem_node(pgdat->bdata, start, end, 0, 0);
-}
-
-void __init free_bootmem(unsigned long physaddr, unsigned long size)
-{
-       unsigned long start, end;
-
-       kmemleak_free_part_phys(physaddr, size);
-
-       start = PFN_UP(physaddr);
-       end = PFN_DOWN(physaddr + size);
-
-       mark_bootmem(start, end, 0, 0);
-}
-
-/**
- * reserve_bootmem_node - mark a page range as reserved
- * @pgdat: node the range resides on
- * @physaddr: starting address of the range
- * @size: size of the range in bytes
- * @flags: reservation flags (see linux/bootmem.h)
- *
- * Partial pages will be reserved.
- *
- * The range must reside completely on the specified node.
- *
- * Return: 0 on success, -errno on failure.
- */
-int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
-                                unsigned long size, int flags)
-{
-       unsigned long start, end;
-
-       start = PFN_DOWN(physaddr);
-       end = PFN_UP(physaddr + size);
-
-       return mark_bootmem_node(pgdat->bdata, start, end, 1, flags);
-}
-
-/**
- * reserve_bootmem - mark a page range as reserved
- * @addr: starting address of the range
- * @size: size of the range in bytes
- * @flags: reservation flags (see linux/bootmem.h)
- *
- * Partial pages will be reserved.
- *
- * The range must be contiguous but may span node boundaries.
- *
- * Return: 0 on success, -errno on failure.
- */
-int __init reserve_bootmem(unsigned long addr, unsigned long size,
-                           int flags)
-{
-       unsigned long start, end;
-
-       start = PFN_DOWN(addr);
-       end = PFN_UP(addr + size);
-
-       return mark_bootmem(start, end, 1, flags);
-}
-
-static unsigned long __init align_idx(struct bootmem_data *bdata,
-                                     unsigned long idx, unsigned long step)
-{
-       unsigned long base = bdata->node_min_pfn;
-
-       /*
-        * Align the index with respect to the node start so that the
-        * combination of both satisfies the requested alignment.
-        */
-
-       return ALIGN(base + idx, step) - base;
-}
-
-static unsigned long __init align_off(struct bootmem_data *bdata,
-                                     unsigned long off, unsigned long align)
-{
-       unsigned long base = PFN_PHYS(bdata->node_min_pfn);
-
-       /* Same as align_idx for byte offsets */
-
-       return ALIGN(base + off, align) - base;
-}
-
-static void * __init alloc_bootmem_bdata(struct bootmem_data *bdata,
-                                       unsigned long size, unsigned long align,
-                                       unsigned long goal, unsigned long limit)
-{
-       unsigned long fallback = 0;
-       unsigned long min, max, start, sidx, midx, step;
-
-       bdebug("nid=%td size=%lx [%lu pages] align=%lx goal=%lx limit=%lx\n",
-               bdata - bootmem_node_data, size, PAGE_ALIGN(size) >> PAGE_SHIFT,
-               align, goal, limit);
-
-       BUG_ON(!size);
-       BUG_ON(align & (align - 1));
-       BUG_ON(limit && goal + size > limit);
-
-       if (!bdata->node_bootmem_map)
-               return NULL;
-
-       min = bdata->node_min_pfn;
-       max = bdata->node_low_pfn;
-
-       goal >>= PAGE_SHIFT;
-       limit >>= PAGE_SHIFT;
-
-       if (limit && max > limit)
-               max = limit;
-       if (max <= min)
-               return NULL;
-
-       step = max(align >> PAGE_SHIFT, 1UL);
-
-       if (goal && min < goal && goal < max)
-               start = ALIGN(goal, step);
-       else
-               start = ALIGN(min, step);
-
-       sidx = start - bdata->node_min_pfn;
-       midx = max - bdata->node_min_pfn;
-
-       if (bdata->hint_idx > sidx) {
-               /*
-                * Handle the valid case of sidx being zero and still
-                * catch the fallback below.
-                */
-               fallback = sidx + 1;
-               sidx = align_idx(bdata, bdata->hint_idx, step);
-       }
-
-       while (1) {
-               int merge;
-               void *region;
-               unsigned long eidx, i, start_off, end_off;
-find_block:
-               sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx);
-               sidx = align_idx(bdata, sidx, step);
-               eidx = sidx + PFN_UP(size);
-
-               if (sidx >= midx || eidx > midx)
-                       break;
-
-               for (i = sidx; i < eidx; i++)
-                       if (test_bit(i, bdata->node_bootmem_map)) {
-                               sidx = align_idx(bdata, i, step);
-                               if (sidx == i)
-                                       sidx += step;
-                               goto find_block;
-                       }
-
-               if (bdata->last_end_off & (PAGE_SIZE - 1) &&
-                               PFN_DOWN(bdata->last_end_off) + 1 == sidx)
-                       start_off = align_off(bdata, bdata->last_end_off, align);
-               else
-                       start_off = PFN_PHYS(sidx);
-
-               merge = PFN_DOWN(start_off) < sidx;
-               end_off = start_off + size;
-
-               bdata->last_end_off = end_off;
-               bdata->hint_idx = PFN_UP(end_off);
-
-               /*
-                * Reserve the area now:
-                */
-               if (__reserve(bdata, PFN_DOWN(start_off) + merge,
-                               PFN_UP(end_off), BOOTMEM_EXCLUSIVE))
-                       BUG();
-
-               region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) +
-                               start_off);
-               memset(region, 0, size);
-               /*
-                * The min_count is set to 0 so that bootmem allocated blocks
-                * are never reported as leaks.
-                */
-               kmemleak_alloc(region, size, 0, 0);
-               return region;
-       }
-
-       if (fallback) {
-               sidx = align_idx(bdata, fallback - 1, step);
-               fallback = 0;
-               goto find_block;
-       }
-
-       return NULL;
-}
-
-static void * __init alloc_bootmem_core(unsigned long size,
-                                       unsigned long align,
-                                       unsigned long goal,
-                                       unsigned long limit)
-{
-       bootmem_data_t *bdata;
-       void *region;
-
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc(size, GFP_NOWAIT);
-
-       list_for_each_entry(bdata, &bdata_list, list) {
-               if (goal && bdata->node_low_pfn <= PFN_DOWN(goal))
-                       continue;
-               if (limit && bdata->node_min_pfn >= PFN_DOWN(limit))
-                       break;
-
-               region = alloc_bootmem_bdata(bdata, size, align, goal, limit);
-               if (region)
-                       return region;
-       }
-
-       return NULL;
-}
-
-static void * __init ___alloc_bootmem_nopanic(unsigned long size,
-                                             unsigned long align,
-                                             unsigned long goal,
-                                             unsigned long limit)
-{
-       void *ptr;
-
-restart:
-       ptr = alloc_bootmem_core(size, align, goal, limit);
-       if (ptr)
-               return ptr;
-       if (goal) {
-               goal = 0;
-               goto restart;
-       }
-
-       return NULL;
-}
-
-void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
-                                       unsigned long goal)
-{
-       unsigned long limit = 0;
-
-       return ___alloc_bootmem_nopanic(size, align, goal, limit);
-}
-
-static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
-                                       unsigned long goal, unsigned long limit)
-{
-       void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
-
-       if (mem)
-               return mem;
-       /*
-        * Whoops, we cannot satisfy the allocation request.
-        */
-       pr_alert("bootmem alloc of %lu bytes failed!\n", size);
-       panic("Out of memory");
-       return NULL;
-}
-
-void * __init __alloc_bootmem(unsigned long size, unsigned long align,
-                             unsigned long goal)
-{
-       unsigned long limit = 0;
-
-       return ___alloc_bootmem(size, align, goal, limit);
-}
-
-void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
-                               unsigned long size, unsigned long align,
-                               unsigned long goal, unsigned long limit)
-{
-       void *ptr;
-
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-again:
-
-       /* do not panic in alloc_bootmem_bdata() */
-       if (limit && goal + size > limit)
-               limit = 0;
-
-       ptr = alloc_bootmem_bdata(pgdat->bdata, size, align, goal, limit);
-       if (ptr)
-               return ptr;
-
-       ptr = alloc_bootmem_core(size, align, goal, limit);
-       if (ptr)
-               return ptr;
-
-       if (goal) {
-               goal = 0;
-               goto again;
-       }
-
-       return NULL;
-}
-
-void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
-                                  unsigned long align, unsigned long goal)
-{
-       return ___alloc_bootmem_node_nopanic(pgdat, size, align, goal, 0);
-}
-
-void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-                                   unsigned long align, unsigned long goal,
-                                   unsigned long limit)
-{
-       void *ptr;
-
-       ptr = ___alloc_bootmem_node_nopanic(pgdat, size, align, goal, 0);
-       if (ptr)
-               return ptr;
-
-       pr_alert("bootmem alloc of %lu bytes failed!\n", size);
-       panic("Out of memory");
-       return NULL;
-}
-
-void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-                                  unsigned long align, unsigned long goal)
-{
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-
-       return  ___alloc_bootmem_node(pgdat, size, align, goal, 0);
-}
-
-void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
-                                  unsigned long align, unsigned long goal)
-{
-#ifdef MAX_DMA32_PFN
-       unsigned long end_pfn;
-
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-
-       /* update goal according ...MAX_DMA32_PFN */
-       end_pfn = pgdat_end_pfn(pgdat);
-
-       if (end_pfn > MAX_DMA32_PFN + (128 >> (20 - PAGE_SHIFT)) &&
-           (goal >> PAGE_SHIFT) < MAX_DMA32_PFN) {
-               void *ptr;
-               unsigned long new_goal;
-
-               new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
-               ptr = alloc_bootmem_bdata(pgdat->bdata, size, align,
-                                                new_goal, 0);
-               if (ptr)
-                       return ptr;
-       }
-#endif
-
-       return __alloc_bootmem_node(pgdat, size, align, goal);
-
-}
-
-void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
-                                 unsigned long goal)
-{
-       return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
-}
-
-void * __init __alloc_bootmem_low_nopanic(unsigned long size,
-                                         unsigned long align,
-                                         unsigned long goal)
-{
-       return ___alloc_bootmem_nopanic(size, align, goal,
-                                       ARCH_LOW_ADDRESS_LIMIT);
-}
-
-void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
-                                      unsigned long align, unsigned long goal)
-{
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-
-       return ___alloc_bootmem_node(pgdat, size, align,
-                                    goal, ARCH_LOW_ADDRESS_LIMIT);
-}
index 841d7ef5359195b2de3758b098155788c230e543..f76e77a2d34b79afec5f3032366a6bd954d1aead 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1817,8 +1817,8 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
         * interrupts disabled by get_futex_key.
         *
         * With interrupts disabled, we block page table pages from being
-        * freed from under us. See mmu_gather_tlb in asm-generic/tlb.h
-        * for more details.
+        * freed from under us. See struct mmu_table_batch comments in
+        * include/asm-generic/tlb.h for more details.
         *
         * We do not adopt an rcu_read_lock(.) here as we also want to
         * block IPIs that come from THPs splitting.
index debf11388a600d0f445ed1ac055e14bf0d55790d..5b42d3d4b60aa3a921002abf8f2872bc6e0764f8 100644 (file)
@@ -27,6 +27,9 @@ static int __gup_benchmark_ioctl(unsigned int cmd,
        int nr;
        struct page **pages;
 
+       if (gup->size > ULONG_MAX)
+               return -EINVAL;
+
        nr_pages = gup->size / PAGE_SIZE;
        pages = kvcalloc(nr_pages, sizeof(void *), GFP_KERNEL);
        if (!pages)
index 774d684fa2b470ed710440c8bdb4fc0efd412b72..90c34f3d1243aa5ec18970ec7aac095d8f657d32 100644 (file)
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -11,7 +11,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * Authors: JÃ\83©rÃ\83´me Glisse <jglisse@redhat.com>
+ * Authors: Jérôme Glisse <jglisse@redhat.com>
  */
 /*
  * Refer to include/linux/hmm.h for information about heterogeneous memory
@@ -43,7 +43,6 @@ static const struct mmu_notifier_ops hmm_mmu_notifier_ops;
  *
  * @mm: mm struct this HMM struct is bound to
  * @lock: lock protecting ranges list
- * @sequence: we track updates to the CPU page table with a sequence number
  * @ranges: list of range being snapshotted
  * @mirrors: list of mirrors for this mm
  * @mmu_notifier: mmu notifier to track updates to CPU page table
@@ -52,7 +51,6 @@ static const struct mmu_notifier_ops hmm_mmu_notifier_ops;
 struct hmm {
        struct mm_struct        *mm;
        spinlock_t              lock;
-       atomic_t                sequence;
        struct list_head        ranges;
        struct list_head        mirrors;
        struct mmu_notifier     mmu_notifier;
@@ -85,22 +83,11 @@ static struct hmm *hmm_register(struct mm_struct *mm)
                return NULL;
        INIT_LIST_HEAD(&hmm->mirrors);
        init_rwsem(&hmm->mirrors_sem);
-       atomic_set(&hmm->sequence, 0);
        hmm->mmu_notifier.ops = NULL;
        INIT_LIST_HEAD(&hmm->ranges);
        spin_lock_init(&hmm->lock);
        hmm->mm = mm;
 
-       /*
-        * We should only get here if hold the mmap_sem in write mode ie on
-        * registration of first mirror through hmm_mirror_register()
-        */
-       hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops;
-       if (__mmu_notifier_register(&hmm->mmu_notifier, mm)) {
-               kfree(hmm);
-               return NULL;
-       }
-
        spin_lock(&mm->page_table_lock);
        if (!mm->hmm)
                mm->hmm = hmm;
@@ -108,12 +95,27 @@ static struct hmm *hmm_register(struct mm_struct *mm)
                cleanup = true;
        spin_unlock(&mm->page_table_lock);
 
-       if (cleanup) {
-               mmu_notifier_unregister(&hmm->mmu_notifier, mm);
-               kfree(hmm);
-       }
+       if (cleanup)
+               goto error;
+
+       /*
+        * We should only get here if hold the mmap_sem in write mode ie on
+        * registration of first mirror through hmm_mirror_register()
+        */
+       hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops;
+       if (__mmu_notifier_register(&hmm->mmu_notifier, mm))
+               goto error_mm;
 
        return mm->hmm;
+
+error_mm:
+       spin_lock(&mm->page_table_lock);
+       if (mm->hmm == hmm)
+               mm->hmm = NULL;
+       spin_unlock(&mm->page_table_lock);
+error:
+       kfree(hmm);
+       return NULL;
 }
 
 void hmm_mm_destroy(struct mm_struct *mm)
@@ -121,10 +123,8 @@ void hmm_mm_destroy(struct mm_struct *mm)
        kfree(mm->hmm);
 }
 
-static void hmm_invalidate_range(struct hmm *hmm,
-                                enum hmm_update_type action,
-                                unsigned long start,
-                                unsigned long end)
+static int hmm_invalidate_range(struct hmm *hmm, bool device,
+                               const struct hmm_update *update)
 {
        struct hmm_mirror *mirror;
        struct hmm_range *range;
@@ -133,22 +133,33 @@ static void hmm_invalidate_range(struct hmm *hmm,
        list_for_each_entry(range, &hmm->ranges, list) {
                unsigned long addr, idx, npages;
 
-               if (end < range->start || start >= range->end)
+               if (update->end < range->start || update->start >= range->end)
                        continue;
 
                range->valid = false;
-               addr = max(start, range->start);
+               addr = max(update->start, range->start);
                idx = (addr - range->start) >> PAGE_SHIFT;
-               npages = (min(range->end, end) - addr) >> PAGE_SHIFT;
+               npages = (min(range->end, update->end) - addr) >> PAGE_SHIFT;
                memset(&range->pfns[idx], 0, sizeof(*range->pfns) * npages);
        }
        spin_unlock(&hmm->lock);
 
+       if (!device)
+               return 0;
+
        down_read(&hmm->mirrors_sem);
-       list_for_each_entry(mirror, &hmm->mirrors, list)
-               mirror->ops->sync_cpu_device_pagetables(mirror, action,
-                                                       start, end);
+       list_for_each_entry(mirror, &hmm->mirrors, list) {
+               int ret;
+
+               ret = mirror->ops->sync_cpu_device_pagetables(mirror, update);
+               if (!update->blockable && ret == -EAGAIN) {
+                       up_read(&hmm->mirrors_sem);
+                       return -EAGAIN;
+               }
+       }
        up_read(&hmm->mirrors_sem);
+
+       return 0;
 }
 
 static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm)
@@ -178,18 +189,21 @@ static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm)
 }
 
 static int hmm_invalidate_range_start(struct mmu_notifier *mn,
-                                      struct mm_struct *mm,
-                                      unsigned long start,
-                                      unsigned long end,
-                                      bool blockable)
+                                     struct mm_struct *mm,
+                                     unsigned long start,
+                                     unsigned long end,
+                                     bool blockable)
 {
+       struct hmm_update update;
        struct hmm *hmm = mm->hmm;
 
        VM_BUG_ON(!hmm);
 
-       atomic_inc(&hmm->sequence);
-
-       return 0;
+       update.start = start;
+       update.end = end;
+       update.event = HMM_UPDATE_INVALIDATE;
+       update.blockable = blockable;
+       return hmm_invalidate_range(hmm, true, &update);
 }
 
 static void hmm_invalidate_range_end(struct mmu_notifier *mn,
@@ -197,11 +211,16 @@ static void hmm_invalidate_range_end(struct mmu_notifier *mn,
                                     unsigned long start,
                                     unsigned long end)
 {
+       struct hmm_update update;
        struct hmm *hmm = mm->hmm;
 
        VM_BUG_ON(!hmm);
 
-       hmm_invalidate_range(mm->hmm, HMM_UPDATE_INVALIDATE, start, end);
+       update.start = start;
+       update.end = end;
+       update.event = HMM_UPDATE_INVALIDATE;
+       update.blockable = true;
+       hmm_invalidate_range(hmm, false, &update);
 }
 
 static const struct mmu_notifier_ops hmm_mmu_notifier_ops = {
@@ -278,12 +297,13 @@ void hmm_mirror_unregister(struct hmm_mirror *mirror)
        if (!should_unregister || mm == NULL)
                return;
 
+       mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm);
+
        spin_lock(&mm->page_table_lock);
        if (mm->hmm == hmm)
                mm->hmm = NULL;
        spin_unlock(&mm->page_table_lock);
 
-       mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm);
        kfree(hmm);
 }
 EXPORT_SYMBOL(hmm_mirror_unregister);
@@ -571,22 +591,42 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp,
 {
        struct hmm_vma_walk *hmm_vma_walk = walk->private;
        struct hmm_range *range = hmm_vma_walk->range;
+       struct vm_area_struct *vma = walk->vma;
        uint64_t *pfns = range->pfns;
        unsigned long addr = start, i;
        pte_t *ptep;
+       pmd_t pmd;
 
-       i = (addr - range->start) >> PAGE_SHIFT;
 
 again:
-       if (pmd_none(*pmdp))
+       pmd = READ_ONCE(*pmdp);
+       if (pmd_none(pmd))
                return hmm_vma_walk_hole(start, end, walk);
 
-       if (pmd_huge(*pmdp) && (range->vma->vm_flags & VM_HUGETLB))
+       if (pmd_huge(pmd) && (range->vma->vm_flags & VM_HUGETLB))
                return hmm_pfns_bad(start, end, walk);
 
-       if (pmd_devmap(*pmdp) || pmd_trans_huge(*pmdp)) {
-               pmd_t pmd;
+       if (thp_migration_supported() && is_pmd_migration_entry(pmd)) {
+               bool fault, write_fault;
+               unsigned long npages;
+               uint64_t *pfns;
+
+               i = (addr - range->start) >> PAGE_SHIFT;
+               npages = (end - addr) >> PAGE_SHIFT;
+               pfns = &range->pfns[i];
 
+               hmm_range_need_fault(hmm_vma_walk, pfns, npages,
+                                    0, &fault, &write_fault);
+               if (fault || write_fault) {
+                       hmm_vma_walk->last = addr;
+                       pmd_migration_entry_wait(vma->vm_mm, pmdp);
+                       return -EAGAIN;
+               }
+               return 0;
+       } else if (!pmd_present(pmd))
+               return hmm_pfns_bad(start, end, walk);
+
+       if (pmd_devmap(pmd) || pmd_trans_huge(pmd)) {
                /*
                 * No need to take pmd_lock here, even if some other threads
                 * is splitting the huge pmd we will get that event through
@@ -601,13 +641,21 @@ again:
                if (!pmd_devmap(pmd) && !pmd_trans_huge(pmd))
                        goto again;
 
+               i = (addr - range->start) >> PAGE_SHIFT;
                return hmm_vma_handle_pmd(walk, addr, end, &pfns[i], pmd);
        }
 
-       if (pmd_bad(*pmdp))
+       /*
+        * We have handled all the valid case above ie either none, migration,
+        * huge or transparent huge. At this point either it is a valid pmd
+        * entry pointing to pte directory or it is a bad pmd that will not
+        * recover.
+        */
+       if (pmd_bad(pmd))
                return hmm_pfns_bad(start, end, walk);
 
        ptep = pte_offset_map(pmdp, addr);
+       i = (addr - range->start) >> PAGE_SHIFT;
        for (; addr < end; addr += PAGE_SIZE, ptep++, i++) {
                int r;
 
index 7b5c0ad9a6bd03909885334877a33f363c007b80..c007fb5fb8d5f6547dc916e5ab468753028a862b 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/compiler.h>
 #include <linux/cpuset.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/sysfs.h>
 #include <linux/slab.h>
 #include <linux/mmdebug.h>
@@ -2100,9 +2100,9 @@ int __alloc_bootmem_huge_page(struct hstate *h)
        for_each_node_mask_to_alloc(h, nr_nodes, node, &node_states[N_MEMORY]) {
                void *addr;
 
-               addr = memblock_virt_alloc_try_nid_raw(
+               addr = memblock_alloc_try_nid_raw(
                                huge_page_size(h), huge_page_size(h),
-                               0, BOOTMEM_ALLOC_ACCESSIBLE, node);
+                               0, MEMBLOCK_ALLOC_ACCESSIBLE, node);
                if (addr) {
                        /*
                         * Use the beginning of the huge page to store the
index 87256ae1bef86f58ea2b241f1bff5b171e06d920..291eb2b6d1d8c5504d4a51090b03d836c4990660 100644 (file)
@@ -161,7 +161,7 @@ static inline struct page *pageblock_pfn_to_page(unsigned long start_pfn,
 }
 
 extern int __isolate_free_page(struct page *page, unsigned int order);
-extern void __free_pages_bootmem(struct page *page, unsigned long pfn,
+extern void memblock_free_pages(struct page *page, unsigned long pfn,
                                        unsigned int order);
 extern void prep_compound_page(struct page *page, unsigned int order);
 extern void post_alloc_hook(struct page *page, unsigned int order,
index 7a2a2f13f86f5b604de654a7a3487ddb534d3a93..c7550eb65922cc3c313e8614d964b4a94f50c72f 100644 (file)
  *
  */
 
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/kasan.h>
 #include <linux/kernel.h>
-#include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/pfn.h>
 #include <linux/slab.h>
@@ -83,8 +82,8 @@ static inline bool kasan_zero_page_entry(pte_t pte)
 
 static __init void *early_alloc(size_t size, int node)
 {
-       return memblock_virt_alloc_try_nid(size, size, __pa(MAX_DMA_ADDRESS),
-                                       BOOTMEM_ALLOC_ACCESSIBLE, node);
+       return memblock_alloc_try_nid(size, size, __pa(MAX_DMA_ADDRESS),
+                                       MEMBLOCK_ALLOC_ACCESSIBLE, node);
 }
 
 static void __ref zero_pte_populate(pmd_t *pmd, unsigned long addr,
index 4f7e4b5a2f082fafc7b354bf98242d6ad59588e0..877de4fa0720baea7252af98b1c03f718c33b118 100644 (file)
@@ -92,7 +92,7 @@
 #include <linux/stacktrace.h>
 #include <linux/cache.h>
 #include <linux/percpu.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pfn.h>
 #include <linux/mmzone.h>
 #include <linux/slab.h>
index a85315083b5a8d1fbba19329a5b77dc7fe3b6da3..7df468c8ebc8c0ada5b560ed70c9c821e5127c05 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/kmemleak.h>
 #include <linux/seq_file.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 
 #include <asm/sections.h>
 #include <linux/io.h>
  * initialization compltes.
  */
 
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+struct pglist_data __refdata contig_page_data;
+EXPORT_SYMBOL(contig_page_data);
+#endif
+
+unsigned long max_low_pfn;
+unsigned long min_low_pfn;
+unsigned long max_pfn;
+unsigned long long max_possible_pfn;
+
 static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
 static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
 #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
@@ -1238,8 +1247,11 @@ static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
 {
        phys_addr_t found;
 
-       if (!align)
+       if (!align) {
+               /* Can't use WARNs this early in boot on powerpc */
+               dump_stack();
                align = SMP_CACHE_BYTES;
+       }
 
        found = memblock_find_in_range_node(size, align, start, end, nid,
                                            flags);
@@ -1269,7 +1281,7 @@ phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
        return memblock_alloc_range_nid(size, align, 0, max_addr, nid, flags);
 }
 
-phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid)
+phys_addr_t __init memblock_phys_alloc_nid(phys_addr_t size, phys_addr_t align, int nid)
 {
        enum memblock_flags flags = choose_memblock_flags();
        phys_addr_t ret;
@@ -1304,23 +1316,22 @@ phys_addr_t __init memblock_alloc_base(phys_addr_t size, phys_addr_t align, phys
        return alloc;
 }
 
-phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align)
+phys_addr_t __init memblock_phys_alloc(phys_addr_t size, phys_addr_t align)
 {
        return memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
 }
 
-phys_addr_t __init memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid)
+phys_addr_t __init memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid)
 {
-       phys_addr_t res = memblock_alloc_nid(size, align, nid);
+       phys_addr_t res = memblock_phys_alloc_nid(size, align, nid);
 
        if (res)
                return res;
        return memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
 }
 
-#if defined(CONFIG_NO_BOOTMEM)
 /**
- * memblock_virt_alloc_internal - allocate boot memory block
+ * memblock_alloc_internal - allocate boot memory block
  * @size: size of memory block to be allocated in bytes
  * @align: alignment of the region and block's size
  * @min_addr: the lower bound of the memory region to allocate (phys address)
@@ -1333,9 +1344,7 @@ phys_addr_t __init memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, i
  * hold the requested memory.
  *
  * The allocation is performed from memory region limited by
- * memblock.current_limit if @max_addr == %BOOTMEM_ALLOC_ACCESSIBLE.
- *
- * The memory block is aligned on %SMP_CACHE_BYTES if @align == 0.
+ * memblock.current_limit if @max_addr == %MEMBLOCK_ALLOC_ACCESSIBLE.
  *
  * The phys address of allocated boot memory block is converted to virtual and
  * allocated memory is reset to 0.
@@ -1346,7 +1355,7 @@ phys_addr_t __init memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, i
  * Return:
  * Virtual address of allocated memory block on success, NULL on failure.
  */
-static void * __init memblock_virt_alloc_internal(
+static void * __init memblock_alloc_internal(
                                phys_addr_t size, phys_addr_t align,
                                phys_addr_t min_addr, phys_addr_t max_addr,
                                int nid)
@@ -1361,13 +1370,15 @@ static void * __init memblock_virt_alloc_internal(
        /*
         * Detect any accidental use of these APIs after slab is ready, as at
         * this moment memblock may be deinitialized already and its
-        * internal data may be destroyed (after execution of free_all_bootmem)
+        * internal data may be destroyed (after execution of memblock_free_all)
         */
        if (WARN_ON_ONCE(slab_is_available()))
                return kzalloc_node(size, GFP_NOWAIT, nid);
 
-       if (!align)
+       if (!align) {
+               dump_stack();
                align = SMP_CACHE_BYTES;
+       }
 
        if (max_addr > memblock.current_limit)
                max_addr = memblock.current_limit;
@@ -1413,14 +1424,14 @@ done:
 }
 
 /**
- * memblock_virt_alloc_try_nid_raw - allocate boot memory block without zeroing
+ * memblock_alloc_try_nid_raw - allocate boot memory block without zeroing
  * memory and without panicking
  * @size: size of memory block to be allocated in bytes
  * @align: alignment of the region and block's size
  * @min_addr: the lower bound of the memory region from where the allocation
  *       is preferred (phys address)
  * @max_addr: the upper bound of the memory region from where the allocation
- *           is preferred (phys address), or %BOOTMEM_ALLOC_ACCESSIBLE to
+ *           is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
  *           allocate only from memory limited by memblock.current_limit value
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
  *
@@ -1431,7 +1442,7 @@ done:
  * Return:
  * Virtual address of allocated memory block on success, NULL on failure.
  */
-void * __init memblock_virt_alloc_try_nid_raw(
+void * __init memblock_alloc_try_nid_raw(
                        phys_addr_t size, phys_addr_t align,
                        phys_addr_t min_addr, phys_addr_t max_addr,
                        int nid)
@@ -1442,7 +1453,7 @@ void * __init memblock_virt_alloc_try_nid_raw(
                     __func__, (u64)size, (u64)align, nid, &min_addr,
                     &max_addr, (void *)_RET_IP_);
 
-       ptr = memblock_virt_alloc_internal(size, align,
+       ptr = memblock_alloc_internal(size, align,
                                           min_addr, max_addr, nid);
        if (ptr && size > 0)
                page_init_poison(ptr, size);
@@ -1451,13 +1462,13 @@ void * __init memblock_virt_alloc_try_nid_raw(
 }
 
 /**
- * memblock_virt_alloc_try_nid_nopanic - allocate boot memory block
+ * memblock_alloc_try_nid_nopanic - allocate boot memory block
  * @size: size of memory block to be allocated in bytes
  * @align: alignment of the region and block's size
  * @min_addr: the lower bound of the memory region from where the allocation
  *       is preferred (phys address)
  * @max_addr: the upper bound of the memory region from where the allocation
- *           is preferred (phys address), or %BOOTMEM_ALLOC_ACCESSIBLE to
+ *           is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
  *           allocate only from memory limited by memblock.current_limit value
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
  *
@@ -1467,7 +1478,7 @@ void * __init memblock_virt_alloc_try_nid_raw(
  * Return:
  * Virtual address of allocated memory block on success, NULL on failure.
  */
-void * __init memblock_virt_alloc_try_nid_nopanic(
+void * __init memblock_alloc_try_nid_nopanic(
                                phys_addr_t size, phys_addr_t align,
                                phys_addr_t min_addr, phys_addr_t max_addr,
                                int nid)
@@ -1478,7 +1489,7 @@ void * __init memblock_virt_alloc_try_nid_nopanic(
                     __func__, (u64)size, (u64)align, nid, &min_addr,
                     &max_addr, (void *)_RET_IP_);
 
-       ptr = memblock_virt_alloc_internal(size, align,
+       ptr = memblock_alloc_internal(size, align,
                                           min_addr, max_addr, nid);
        if (ptr)
                memset(ptr, 0, size);
@@ -1486,24 +1497,24 @@ void * __init memblock_virt_alloc_try_nid_nopanic(
 }
 
 /**
- * memblock_virt_alloc_try_nid - allocate boot memory block with panicking
+ * memblock_alloc_try_nid - allocate boot memory block with panicking
  * @size: size of memory block to be allocated in bytes
  * @align: alignment of the region and block's size
  * @min_addr: the lower bound of the memory region from where the allocation
  *       is preferred (phys address)
  * @max_addr: the upper bound of the memory region from where the allocation
- *           is preferred (phys address), or %BOOTMEM_ALLOC_ACCESSIBLE to
+ *           is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
  *           allocate only from memory limited by memblock.current_limit value
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
  *
- * Public panicking version of memblock_virt_alloc_try_nid_nopanic()
+ * Public panicking version of memblock_alloc_try_nid_nopanic()
  * which provides debug information (including caller info), if enabled,
  * and panics if the request can not be satisfied.
  *
  * Return:
  * Virtual address of allocated memory block on success, NULL on failure.
  */
-void * __init memblock_virt_alloc_try_nid(
+void * __init memblock_alloc_try_nid(
                        phys_addr_t size, phys_addr_t align,
                        phys_addr_t min_addr, phys_addr_t max_addr,
                        int nid)
@@ -1513,7 +1524,7 @@ void * __init memblock_virt_alloc_try_nid(
        memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pF\n",
                     __func__, (u64)size, (u64)align, nid, &min_addr,
                     &max_addr, (void *)_RET_IP_);
-       ptr = memblock_virt_alloc_internal(size, align,
+       ptr = memblock_alloc_internal(size, align,
                                           min_addr, max_addr, nid);
        if (ptr) {
                memset(ptr, 0, size);
@@ -1524,14 +1535,13 @@ void * __init memblock_virt_alloc_try_nid(
              __func__, (u64)size, (u64)align, nid, &min_addr, &max_addr);
        return NULL;
 }
-#endif
 
 /**
  * __memblock_free_early - free boot memory block
  * @base: phys starting address of the  boot memory block
  * @size: size of the boot memory block in bytes
  *
- * Free boot memory block previously allocated by memblock_virt_alloc_xx() API.
+ * Free boot memory block previously allocated by memblock_alloc_xx() API.
  * The freeing memory will not be released to the buddy allocator.
  */
 void __init __memblock_free_early(phys_addr_t base, phys_addr_t size)
@@ -1565,7 +1575,7 @@ void __init __memblock_free_late(phys_addr_t base, phys_addr_t size)
        end = PFN_DOWN(base + size);
 
        for (; cursor < end; cursor++) {
-               __free_pages_bootmem(pfn_to_page(cursor), cursor, 0);
+               memblock_free_pages(pfn_to_page(cursor), cursor, 0);
                totalram_pages++;
        }
 }
@@ -1879,6 +1889,100 @@ static int __init early_memblock(char *p)
 }
 early_param("memblock", early_memblock);
 
+static void __init __free_pages_memory(unsigned long start, unsigned long end)
+{
+       int order;
+
+       while (start < end) {
+               order = min(MAX_ORDER - 1UL, __ffs(start));
+
+               while (start + (1UL << order) > end)
+                       order--;
+
+               memblock_free_pages(pfn_to_page(start), start, order);
+
+               start += (1UL << order);
+       }
+}
+
+static unsigned long __init __free_memory_core(phys_addr_t start,
+                                phys_addr_t end)
+{
+       unsigned long start_pfn = PFN_UP(start);
+       unsigned long end_pfn = min_t(unsigned long,
+                                     PFN_DOWN(end), max_low_pfn);
+
+       if (start_pfn >= end_pfn)
+               return 0;
+
+       __free_pages_memory(start_pfn, end_pfn);
+
+       return end_pfn - start_pfn;
+}
+
+static unsigned long __init free_low_memory_core_early(void)
+{
+       unsigned long count = 0;
+       phys_addr_t start, end;
+       u64 i;
+
+       memblock_clear_hotplug(0, -1);
+
+       for_each_reserved_mem_region(i, &start, &end)
+               reserve_bootmem_region(start, end);
+
+       /*
+        * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id
+        *  because in some case like Node0 doesn't have RAM installed
+        *  low ram will be on Node1
+        */
+       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
+                               NULL)
+               count += __free_memory_core(start, end);
+
+       return count;
+}
+
+static int reset_managed_pages_done __initdata;
+
+void reset_node_managed_pages(pg_data_t *pgdat)
+{
+       struct zone *z;
+
+       for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
+               z->managed_pages = 0;
+}
+
+void __init reset_all_zones_managed_pages(void)
+{
+       struct pglist_data *pgdat;
+
+       if (reset_managed_pages_done)
+               return;
+
+       for_each_online_pgdat(pgdat)
+               reset_node_managed_pages(pgdat);
+
+       reset_managed_pages_done = 1;
+}
+
+/**
+ * memblock_free_all - release free pages to the buddy allocator
+ *
+ * Return: the number of pages actually released.
+ */
+unsigned long __init memblock_free_all(void)
+{
+       unsigned long pages;
+
+       reset_all_zones_managed_pages();
+
+       pages = free_low_memory_core_early();
+       totalram_pages += pages;
+
+       return pages;
+}
+
 #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_ARCH_DISCARD_MEMBLOCK)
 
 static int memblock_debug_show(struct seq_file *m, void *private)
index 072139579d897021e83fe6b70344ad4acd62d664..4ad2d293ddc2605d2ae44ce075de68beb93841e0 100644 (file)
@@ -1537,10 +1537,15 @@ static vm_fault_t insert_pfn(struct vm_area_struct *vma, unsigned long addr,
                         * in may not match the PFN we have mapped if the
                         * mapped PFN is a writeable COW page.  In the mkwrite
                         * case we are creating a writable PTE for a shared
-                        * mapping and we expect the PFNs to match.
+                        * mapping and we expect the PFNs to match. If they
+                        * don't match, we are likely racing with block
+                        * allocation and mapping invalidation so just skip the
+                        * update.
                         */
-                       if (WARN_ON_ONCE(pte_pfn(*pte) != pfn_t_to_pfn(pfn)))
+                       if (pte_pfn(*pte) != pfn_t_to_pfn(pfn)) {
+                               WARN_ON_ONCE(!is_zero_pfn(pte_pfn(*pte)));
                                goto out_unlock;
+                       }
                        entry = *pte;
                        goto out_mkwrite;
                } else
index 7e6509a53d79facc47bcf0b5f0d5e37de32f3ad6..61972da38d93cb54d6f1088df186ed20bb0f98bb 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/stop_machine.h>
 #include <linux/hugetlb.h>
 #include <linux/memblock.h>
-#include <linux/bootmem.h>
 #include <linux/compaction.h>
 
 #include <asm/tlbflush.h>
@@ -839,7 +838,6 @@ static struct zone * __meminit move_pfn_range(int online_type, int nid,
        return zone;
 }
 
-/* Must be protected by mem_hotplug_begin() or a device_lock */
 int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type)
 {
        unsigned long flags;
@@ -851,6 +849,8 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
        struct memory_notify arg;
        struct memory_block *mem;
 
+       mem_hotplug_begin();
+
        /*
         * We can't use pfn_to_nid() because nid might be stored in struct page
         * which is not yet initialized. Instead, we find nid from memory block.
@@ -915,6 +915,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
 
        if (onlined_pages)
                memory_notify(MEM_ONLINE, &arg);
+       mem_hotplug_done();
        return 0;
 
 failed_addition:
@@ -922,6 +923,7 @@ failed_addition:
                 (unsigned long long) pfn << PAGE_SHIFT,
                 (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1);
        memory_notify(MEM_CANCEL_ONLINE, &arg);
+       mem_hotplug_done();
        return ret;
 }
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
@@ -1069,7 +1071,12 @@ static int online_memory_block(struct memory_block *mem, void *arg)
        return device_online(&mem->dev);
 }
 
-/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
+/*
+ * NOTE: The caller must call lock_device_hotplug() to serialize hotplug
+ * and online/offline operations (triggered e.g. by sysfs).
+ *
+ * we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG
+ */
 int __ref add_memory_resource(int nid, struct resource *res, bool online)
 {
        u64 start, size;
@@ -1121,26 +1128,26 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
        /* create new memmap entry */
        firmware_map_add_hotplug(start, start + size, "System RAM");
 
+       /* device_online() will take the lock when calling online_pages() */
+       mem_hotplug_done();
+
        /* online pages if requested */
        if (online)
                walk_memory_range(PFN_DOWN(start), PFN_UP(start + size - 1),
                                  NULL, online_memory_block);
 
-       goto out;
-
+       return ret;
 error:
        /* rollback pgdat allocation and others */
        if (new_node)
                rollback_node_hotadd(nid);
        memblock_remove(start, size);
-
-out:
        mem_hotplug_done();
        return ret;
 }
-EXPORT_SYMBOL_GPL(add_memory_resource);
 
-int __ref add_memory(int nid, u64 start, u64 size)
+/* requires device_hotplug_lock, see add_memory_resource() */
+int __ref __add_memory(int nid, u64 start, u64 size)
 {
        struct resource *res;
        int ret;
@@ -1154,6 +1161,17 @@ int __ref add_memory(int nid, u64 start, u64 size)
                release_memory_resource(res);
        return ret;
 }
+
+int add_memory(int nid, u64 start, u64 size)
+{
+       int rc;
+
+       lock_device_hotplug();
+       rc = __add_memory(nid, start, size);
+       unlock_device_hotplug();
+
+       return rc;
+}
 EXPORT_SYMBOL_GPL(add_memory);
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
@@ -1540,10 +1558,16 @@ static int __ref __offline_pages(unsigned long start_pfn,
                return -EINVAL;
        if (!IS_ALIGNED(end_pfn, pageblock_nr_pages))
                return -EINVAL;
+
+       mem_hotplug_begin();
+
        /* This makes hotplug much easier...and readable.
           we assume this for now. .*/
-       if (!test_pages_in_a_zone(start_pfn, end_pfn, &valid_start, &valid_end))
+       if (!test_pages_in_a_zone(start_pfn, end_pfn, &valid_start,
+                                 &valid_end)) {
+               mem_hotplug_done();
                return -EINVAL;
+       }
 
        zone = page_zone(pfn_to_page(valid_start));
        node = zone_to_nid(zone);
@@ -1552,8 +1576,10 @@ static int __ref __offline_pages(unsigned long start_pfn,
        /* set above range as isolated */
        ret = start_isolate_page_range(start_pfn, end_pfn,
                                       MIGRATE_MOVABLE, true);
-       if (ret)
+       if (ret) {
+               mem_hotplug_done();
                return ret;
+       }
 
        arg.start_pfn = start_pfn;
        arg.nr_pages = nr_pages;
@@ -1624,6 +1650,7 @@ repeat:
        writeback_set_ratelimit();
 
        memory_notify(MEM_OFFLINE, &arg);
+       mem_hotplug_done();
        return 0;
 
 failed_removal:
@@ -1633,10 +1660,10 @@ failed_removal:
        memory_notify(MEM_CANCEL_OFFLINE, &arg);
        /* pushback to free area */
        undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
+       mem_hotplug_done();
        return ret;
 }
 
-/* Must be protected by mem_hotplug_begin() or a device_lock */
 int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
 {
        return __offline_pages(start_pfn, start_pfn + nr_pages);
@@ -1807,7 +1834,7 @@ EXPORT_SYMBOL(try_offline_node);
  * and online/offline operations before this call, as required by
  * try_offline_node().
  */
-void __ref remove_memory(int nid, u64 start, u64 size)
+void __ref __remove_memory(int nid, u64 start, u64 size)
 {
        int ret;
 
@@ -1836,5 +1863,12 @@ void __ref remove_memory(int nid, u64 start, u64 size)
 
        mem_hotplug_done();
 }
+
+void remove_memory(int nid, u64 start, u64 size)
+{
+       lock_device_hotplug();
+       __remove_memory(nid, start, size);
+       unlock_device_hotplug();
+}
 EXPORT_SYMBOL_GPL(remove_memory);
 #endif /* CONFIG_MEMORY_HOTREMOVE */
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
deleted file mode 100644 (file)
index 439af3b..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *  bootmem - A boot-time physical memory allocator and configurator
- *
- *  Copyright (C) 1999 Ingo Molnar
- *                1999 Kanoj Sarcar, SGI
- *                2008 Johannes Weiner
- *
- * Access to this subsystem has to be serialized externally (which is true
- * for the boot process anyway).
- */
-#include <linux/init.h>
-#include <linux/pfn.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/kmemleak.h>
-#include <linux/range.h>
-#include <linux/memblock.h>
-#include <linux/bootmem.h>
-
-#include <asm/bug.h>
-#include <asm/io.h>
-
-#include "internal.h"
-
-#ifndef CONFIG_HAVE_MEMBLOCK
-#error CONFIG_HAVE_MEMBLOCK not defined
-#endif
-
-#ifndef CONFIG_NEED_MULTIPLE_NODES
-struct pglist_data __refdata contig_page_data;
-EXPORT_SYMBOL(contig_page_data);
-#endif
-
-unsigned long max_low_pfn;
-unsigned long min_low_pfn;
-unsigned long max_pfn;
-unsigned long long max_possible_pfn;
-
-static void * __init __alloc_memory_core_early(int nid, u64 size, u64 align,
-                                       u64 goal, u64 limit)
-{
-       void *ptr;
-       u64 addr;
-       enum memblock_flags flags = choose_memblock_flags();
-
-       if (limit > memblock.current_limit)
-               limit = memblock.current_limit;
-
-again:
-       addr = memblock_find_in_range_node(size, align, goal, limit, nid,
-                                          flags);
-       if (!addr && (flags & MEMBLOCK_MIRROR)) {
-               flags &= ~MEMBLOCK_MIRROR;
-               pr_warn("Could not allocate %pap bytes of mirrored memory\n",
-                       &size);
-               goto again;
-       }
-       if (!addr)
-               return NULL;
-
-       if (memblock_reserve(addr, size))
-               return NULL;
-
-       ptr = phys_to_virt(addr);
-       memset(ptr, 0, size);
-       /*
-        * The min_count is set to 0 so that bootmem allocated blocks
-        * are never reported as leaks.
-        */
-       kmemleak_alloc(ptr, size, 0, 0);
-       return ptr;
-}
-
-/**
- * free_bootmem_late - free bootmem pages directly to page allocator
- * @addr: starting address of the range
- * @size: size of the range in bytes
- *
- * This is only useful when the bootmem allocator has already been torn
- * down, but we are still initializing the system.  Pages are given directly
- * to the page allocator, no bootmem metadata is updated because it is gone.
- */
-void __init free_bootmem_late(unsigned long addr, unsigned long size)
-{
-       unsigned long cursor, end;
-
-       kmemleak_free_part_phys(addr, size);
-
-       cursor = PFN_UP(addr);
-       end = PFN_DOWN(addr + size);
-
-       for (; cursor < end; cursor++) {
-               __free_pages_bootmem(pfn_to_page(cursor), cursor, 0);
-               totalram_pages++;
-       }
-}
-
-static void __init __free_pages_memory(unsigned long start, unsigned long end)
-{
-       int order;
-
-       while (start < end) {
-               order = min(MAX_ORDER - 1UL, __ffs(start));
-
-               while (start + (1UL << order) > end)
-                       order--;
-
-               __free_pages_bootmem(pfn_to_page(start), start, order);
-
-               start += (1UL << order);
-       }
-}
-
-static unsigned long __init __free_memory_core(phys_addr_t start,
-                                phys_addr_t end)
-{
-       unsigned long start_pfn = PFN_UP(start);
-       unsigned long end_pfn = min_t(unsigned long,
-                                     PFN_DOWN(end), max_low_pfn);
-
-       if (start_pfn >= end_pfn)
-               return 0;
-
-       __free_pages_memory(start_pfn, end_pfn);
-
-       return end_pfn - start_pfn;
-}
-
-static unsigned long __init free_low_memory_core_early(void)
-{
-       unsigned long count = 0;
-       phys_addr_t start, end;
-       u64 i;
-
-       memblock_clear_hotplug(0, -1);
-
-       for_each_reserved_mem_region(i, &start, &end)
-               reserve_bootmem_region(start, end);
-
-       /*
-        * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id
-        *  because in some case like Node0 doesn't have RAM installed
-        *  low ram will be on Node1
-        */
-       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
-                               NULL)
-               count += __free_memory_core(start, end);
-
-       return count;
-}
-
-static int reset_managed_pages_done __initdata;
-
-void reset_node_managed_pages(pg_data_t *pgdat)
-{
-       struct zone *z;
-
-       for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
-               z->managed_pages = 0;
-}
-
-void __init reset_all_zones_managed_pages(void)
-{
-       struct pglist_data *pgdat;
-
-       if (reset_managed_pages_done)
-               return;
-
-       for_each_online_pgdat(pgdat)
-               reset_node_managed_pages(pgdat);
-
-       reset_managed_pages_done = 1;
-}
-
-/**
- * free_all_bootmem - release free pages to the buddy allocator
- *
- * Return: the number of pages actually released.
- */
-unsigned long __init free_all_bootmem(void)
-{
-       unsigned long pages;
-
-       reset_all_zones_managed_pages();
-
-       pages = free_low_memory_core_early();
-       totalram_pages += pages;
-
-       return pages;
-}
-
-/**
- * free_bootmem_node - mark a page range as usable
- * @pgdat: node the range resides on
- * @physaddr: starting physical address of the range
- * @size: size of the range in bytes
- *
- * Partial pages will be considered reserved and left as they are.
- *
- * The range must reside completely on the specified node.
- */
-void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
-                             unsigned long size)
-{
-       memblock_free(physaddr, size);
-}
-
-/**
- * free_bootmem - mark a page range as usable
- * @addr: starting physical address of the range
- * @size: size of the range in bytes
- *
- * Partial pages will be considered reserved and left as they are.
- *
- * The range must be contiguous but may span node boundaries.
- */
-void __init free_bootmem(unsigned long addr, unsigned long size)
-{
-       memblock_free(addr, size);
-}
-
-static void * __init ___alloc_bootmem_nopanic(unsigned long size,
-                                       unsigned long align,
-                                       unsigned long goal,
-                                       unsigned long limit)
-{
-       void *ptr;
-
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc(size, GFP_NOWAIT);
-
-restart:
-
-       ptr = __alloc_memory_core_early(NUMA_NO_NODE, size, align, goal, limit);
-
-       if (ptr)
-               return ptr;
-
-       if (goal != 0) {
-               goal = 0;
-               goto restart;
-       }
-
-       return NULL;
-}
-
-/**
- * __alloc_bootmem_nopanic - allocate boot memory without panicking
- * @size: size of the request in bytes
- * @align: alignment of the region
- * @goal: preferred starting address of the region
- *
- * The goal is dropped if it can not be satisfied and the allocation will
- * fall back to memory below @goal.
- *
- * Allocation may happen on any node in the system.
- *
- * Return: address of the allocated region or %NULL on failure.
- */
-void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
-                                       unsigned long goal)
-{
-       unsigned long limit = -1UL;
-
-       return ___alloc_bootmem_nopanic(size, align, goal, limit);
-}
-
-static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
-                                       unsigned long goal, unsigned long limit)
-{
-       void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
-
-       if (mem)
-               return mem;
-       /*
-        * Whoops, we cannot satisfy the allocation request.
-        */
-       pr_alert("bootmem alloc of %lu bytes failed!\n", size);
-       panic("Out of memory");
-       return NULL;
-}
-
-/**
- * __alloc_bootmem - allocate boot memory
- * @size: size of the request in bytes
- * @align: alignment of the region
- * @goal: preferred starting address of the region
- *
- * The goal is dropped if it can not be satisfied and the allocation will
- * fall back to memory below @goal.
- *
- * Allocation may happen on any node in the system.
- *
- * The function panics if the request can not be satisfied.
- *
- * Return: address of the allocated region.
- */
-void * __init __alloc_bootmem(unsigned long size, unsigned long align,
-                             unsigned long goal)
-{
-       unsigned long limit = -1UL;
-
-       return ___alloc_bootmem(size, align, goal, limit);
-}
-
-void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
-                                                  unsigned long size,
-                                                  unsigned long align,
-                                                  unsigned long goal,
-                                                  unsigned long limit)
-{
-       void *ptr;
-
-again:
-       ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
-                                       goal, limit);
-       if (ptr)
-               return ptr;
-
-       ptr = __alloc_memory_core_early(NUMA_NO_NODE, size, align,
-                                       goal, limit);
-       if (ptr)
-               return ptr;
-
-       if (goal) {
-               goal = 0;
-               goto again;
-       }
-
-       return NULL;
-}
-
-void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
-                                  unsigned long align, unsigned long goal)
-{
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-
-       return ___alloc_bootmem_node_nopanic(pgdat, size, align, goal, 0);
-}
-
-static void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-                                   unsigned long align, unsigned long goal,
-                                   unsigned long limit)
-{
-       void *ptr;
-
-       ptr = ___alloc_bootmem_node_nopanic(pgdat, size, align, goal, limit);
-       if (ptr)
-               return ptr;
-
-       pr_alert("bootmem alloc of %lu bytes failed!\n", size);
-       panic("Out of memory");
-       return NULL;
-}
-
-/**
- * __alloc_bootmem_node - allocate boot memory from a specific node
- * @pgdat: node to allocate from
- * @size: size of the request in bytes
- * @align: alignment of the region
- * @goal: preferred starting address of the region
- *
- * The goal is dropped if it can not be satisfied and the allocation will
- * fall back to memory below @goal.
- *
- * Allocation may fall back to any node in the system if the specified node
- * can not hold the requested memory.
- *
- * The function panics if the request can not be satisfied.
- *
- * Return: address of the allocated region.
- */
-void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
-                                  unsigned long align, unsigned long goal)
-{
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-
-       return ___alloc_bootmem_node(pgdat, size, align, goal, 0);
-}
-
-void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
-                                  unsigned long align, unsigned long goal)
-{
-       return __alloc_bootmem_node(pgdat, size, align, goal);
-}
-
-
-/**
- * __alloc_bootmem_low - allocate low boot memory
- * @size: size of the request in bytes
- * @align: alignment of the region
- * @goal: preferred starting address of the region
- *
- * The goal is dropped if it can not be satisfied and the allocation will
- * fall back to memory below @goal.
- *
- * Allocation may happen on any node in the system.
- *
- * The function panics if the request can not be satisfied.
- *
- * Return: address of the allocated region.
- */
-void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
-                                 unsigned long goal)
-{
-       return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
-}
-
-void * __init __alloc_bootmem_low_nopanic(unsigned long size,
-                                         unsigned long align,
-                                         unsigned long goal)
-{
-       return ___alloc_bootmem_nopanic(size, align, goal,
-                                       ARCH_LOW_ADDRESS_LIMIT);
-}
-
-/**
- * __alloc_bootmem_low_node - allocate low boot memory from a specific node
- * @pgdat: node to allocate from
- * @size: size of the request in bytes
- * @align: alignment of the region
- * @goal: preferred starting address of the region
- *
- * The goal is dropped if it can not be satisfied and the allocation will
- * fall back to memory below @goal.
- *
- * Allocation may fall back to any node in the system if the specified node
- * can not hold the requested memory.
- *
- * The function panics if the request can not be satisfied.
- *
- * Return: address of the allocated region.
- */
-void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
-                                      unsigned long align, unsigned long goal)
-{
-       if (WARN_ON_ONCE(slab_is_available()))
-               return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
-
-       return ___alloc_bootmem_node(pgdat, size, align, goal,
-                                    ARCH_LOW_ADDRESS_LIMIT);
-}
index 863d46da6586d9b988aa5c004a46f85ca389dfe4..a919ba5cb3c845e03e4a070eff354acf19ec7c4a 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/interrupt.h>
 #include <linux/pagemap.h>
 #include <linux/jiffies.h>
-#include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/compiler.h>
 #include <linux/kernel.h>
@@ -1339,7 +1338,7 @@ meminit_pfn_in_nid(unsigned long pfn, int node,
 #endif
 
 
-void __init __free_pages_bootmem(struct page *page, unsigned long pfn,
+void __init memblock_free_pages(struct page *page, unsigned long pfn,
                                                        unsigned int order)
 {
        if (early_page_uninitialised(pfn))
@@ -5476,7 +5475,7 @@ overlap_memmap_init(unsigned long zone, unsigned long *pfn)
 
 /*
  * Initially all pages are reserved - free ones are freed
- * up by free_all_bootmem() once the early boot process is
+ * up by memblock_free_all() once the early boot process is
  * done. Non-atomic initialization, single-pass.
  */
 void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
@@ -6209,7 +6208,7 @@ static void __ref setup_usemap(struct pglist_data *pgdat,
        zone->pageblock_flags = NULL;
        if (usemapsize)
                zone->pageblock_flags =
-                       memblock_virt_alloc_node_nopanic(usemapsize,
+                       memblock_alloc_node_nopanic(usemapsize,
                                                         pgdat->node_id);
 }
 #else
@@ -6439,7 +6438,7 @@ static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
                end = pgdat_end_pfn(pgdat);
                end = ALIGN(end, MAX_ORDER_NR_PAGES);
                size =  (end - start) * sizeof(struct page);
-               map = memblock_virt_alloc_node_nopanic(size, pgdat->node_id);
+               map = memblock_alloc_node_nopanic(size, pgdat->node_id);
                pgdat->node_mem_map = map + offset;
        }
        pr_debug("%s: node %d, pgdat %08lx, node_mem_map %08lx\n",
@@ -6508,8 +6507,7 @@ void __init free_area_init_node(int nid, unsigned long *zones_size,
        free_area_init_core(pgdat);
 }
 
-#if defined(CONFIG_HAVE_MEMBLOCK) && !defined(CONFIG_FLAT_NODE_MEM_MAP)
-
+#if !defined(CONFIG_FLAT_NODE_MEM_MAP)
 /*
  * Zero all valid struct pages in range [spfn, epfn), return number of struct
  * pages zeroed
@@ -6569,7 +6567,7 @@ void __init zero_resv_unavail(void)
        if (pgcnt)
                pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt);
 }
-#endif /* CONFIG_HAVE_MEMBLOCK && !CONFIG_FLAT_NODE_MEM_MAP */
+#endif /* !CONFIG_FLAT_NODE_MEM_MAP */
 
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
 
@@ -7712,9 +7710,11 @@ void *__init alloc_large_system_hash(const char *tablename,
                size = bucketsize << log2qty;
                if (flags & HASH_EARLY) {
                        if (flags & HASH_ZERO)
-                               table = memblock_virt_alloc_nopanic(size, 0);
+                               table = memblock_alloc_nopanic(size,
+                                                              SMP_CACHE_BYTES);
                        else
-                               table = memblock_virt_alloc_raw(size, 0);
+                               table = memblock_alloc_raw(size,
+                                                          SMP_CACHE_BYTES);
                } else if (hashdist) {
                        table = __vmalloc(size, gfp_flags, PAGE_KERNEL);
                } else {
index a9826da84ccb31c1c1be2c5e58f984886a1883b3..ae44f7adbe07df3e32b5092ecc74f3c28c7416c2 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/page_ext.h>
 #include <linux/memory.h>
 #include <linux/vmalloc.h>
@@ -161,9 +161,9 @@ static int __init alloc_node_page_ext(int nid)
 
        table_size = get_entry_size() * nr_pages;
 
-       base = memblock_virt_alloc_try_nid_nopanic(
+       base = memblock_alloc_try_nid_nopanic(
                        table_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
-                       BOOTMEM_ALLOC_ACCESSIBLE, nid);
+                       MEMBLOCK_ALLOC_ACCESSIBLE, nid);
        if (!base)
                return -ENOMEM;
        NODE_DATA(nid)->node_page_ext = base;
index 6302bc62c27d6b69939ab2791c57a5da8945e8aa..b9e4b42b33abaf6f932d38346805457e67ca96f0 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/init.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 #include <linux/kobject.h>
index d80adfe702d3b85f754589135f3695b4e3394c72..87bc0dfdb52b679c19856d19878f2a5838ac3b55 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/stacktrace.h>
 #include <linux/page_owner.h>
 #include <linux/jump_label.h>
index aa2b3d34e8eaa26018267314fe88568b382dbebc..f7e2a676365a10256368d3fe9e5dfccfbd5cc17e 100644 (file)
@@ -21,7 +21,7 @@ bool page_poisoning_enabled(void)
 {
        /*
         * Assumes that debug_pagealloc_enabled is set before
-        * free_all_bootmem.
+        * memblock_free_all.
         * Page poisoning is debug page alloc for some arches. If
         * either of those options are enabled, enable poisoning.
         */
index ae3c2a35d61b7cae4fbecea4421bbd0450b81c53..11df03e71288c3fe0b78e164eca835ac4332e5ca 100644 (file)
@@ -21,7 +21,29 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw)
                        if (!is_swap_pte(*pvmw->pte))
                                return false;
                } else {
-                       if (!pte_present(*pvmw->pte))
+                       /*
+                        * We get here when we are trying to unmap a private
+                        * device page from the process address space. Such
+                        * page is not CPU accessible and thus is mapped as
+                        * a special swap entry, nonetheless it still does
+                        * count as a valid regular mapping for the page (and
+                        * is accounted as such in page maps count).
+                        *
+                        * So handle this special case as if it was a normal
+                        * page mapping ie lock CPU page table and returns
+                        * true.
+                        *
+                        * For more details on device private memory see HMM
+                        * (include/linux/hmm.h or mm/hmm.c).
+                        */
+                       if (is_swap_pte(*pvmw->pte)) {
+                               swp_entry_t entry;
+
+                               /* Handle un-addressable ZONE_DEVICE memory */
+                               entry = pte_to_swp_entry(*pvmw->pte);
+                               if (!is_device_private_entry(entry))
+                                       return false;
+                       } else if (!pte_present(*pvmw->pte))
                                return false;
                }
        }
index 4b90682623e926b23a6fb675cac41b94db5a41b3..a6b74c6fe0becd3ef42284aa643933ae4fb7f0cf 100644 (file)
@@ -65,7 +65,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/bitmap.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/err.h>
 #include <linux/lcm.h>
 #include <linux/list.h>
@@ -1101,9 +1101,9 @@ static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr,
        region_size = ALIGN(start_offset + map_size, lcm_align);
 
        /* allocate chunk */
-       chunk = memblock_virt_alloc(sizeof(struct pcpu_chunk) +
-                                   BITS_TO_LONGS(region_size >> PAGE_SHIFT),
-                                   0);
+       chunk = memblock_alloc(sizeof(struct pcpu_chunk) +
+                              BITS_TO_LONGS(region_size >> PAGE_SHIFT),
+                              SMP_CACHE_BYTES);
 
        INIT_LIST_HEAD(&chunk->list);
 
@@ -1114,12 +1114,12 @@ static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr,
        chunk->nr_pages = region_size >> PAGE_SHIFT;
        region_bits = pcpu_chunk_map_bits(chunk);
 
-       chunk->alloc_map = memblock_virt_alloc(BITS_TO_LONGS(region_bits) *
-                                              sizeof(chunk->alloc_map[0]), 0);
-       chunk->bound_map = memblock_virt_alloc(BITS_TO_LONGS(region_bits + 1) *
-                                              sizeof(chunk->bound_map[0]), 0);
-       chunk->md_blocks = memblock_virt_alloc(pcpu_chunk_nr_blocks(chunk) *
-                                              sizeof(chunk->md_blocks[0]), 0);
+       chunk->alloc_map = memblock_alloc(BITS_TO_LONGS(region_bits) * sizeof(chunk->alloc_map[0]),
+                                         SMP_CACHE_BYTES);
+       chunk->bound_map = memblock_alloc(BITS_TO_LONGS(region_bits + 1) * sizeof(chunk->bound_map[0]),
+                                         SMP_CACHE_BYTES);
+       chunk->md_blocks = memblock_alloc(pcpu_chunk_nr_blocks(chunk) * sizeof(chunk->md_blocks[0]),
+                                         SMP_CACHE_BYTES);
        pcpu_init_md_blocks(chunk);
 
        /* manage populated page bitmap */
@@ -1888,7 +1888,7 @@ struct pcpu_alloc_info * __init pcpu_alloc_alloc_info(int nr_groups,
                          __alignof__(ai->groups[0].cpu_map[0]));
        ai_size = base_size + nr_units * sizeof(ai->groups[0].cpu_map[0]);
 
-       ptr = memblock_virt_alloc_nopanic(PFN_ALIGN(ai_size), PAGE_SIZE);
+       ptr = memblock_alloc_nopanic(PFN_ALIGN(ai_size), PAGE_SIZE);
        if (!ptr)
                return NULL;
        ai = ptr;
@@ -2075,12 +2075,14 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
        PCPU_SETUP_BUG_ON(pcpu_verify_alloc_info(ai) < 0);
 
        /* process group information and build config tables accordingly */
-       group_offsets = memblock_virt_alloc(ai->nr_groups *
-                                            sizeof(group_offsets[0]), 0);
-       group_sizes = memblock_virt_alloc(ai->nr_groups *
-                                          sizeof(group_sizes[0]), 0);
-       unit_map = memblock_virt_alloc(nr_cpu_ids * sizeof(unit_map[0]), 0);
-       unit_off = memblock_virt_alloc(nr_cpu_ids * sizeof(unit_off[0]), 0);
+       group_offsets = memblock_alloc(ai->nr_groups * sizeof(group_offsets[0]),
+                                      SMP_CACHE_BYTES);
+       group_sizes = memblock_alloc(ai->nr_groups * sizeof(group_sizes[0]),
+                                    SMP_CACHE_BYTES);
+       unit_map = memblock_alloc(nr_cpu_ids * sizeof(unit_map[0]),
+                                 SMP_CACHE_BYTES);
+       unit_off = memblock_alloc(nr_cpu_ids * sizeof(unit_off[0]),
+                                 SMP_CACHE_BYTES);
 
        for (cpu = 0; cpu < nr_cpu_ids; cpu++)
                unit_map[cpu] = UINT_MAX;
@@ -2144,8 +2146,8 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
         * empty chunks.
         */
        pcpu_nr_slots = __pcpu_size_to_slot(pcpu_unit_size) + 2;
-       pcpu_slot = memblock_virt_alloc(
-                       pcpu_nr_slots * sizeof(pcpu_slot[0]), 0);
+       pcpu_slot = memblock_alloc(pcpu_nr_slots * sizeof(pcpu_slot[0]),
+                                  SMP_CACHE_BYTES);
        for (i = 0; i < pcpu_nr_slots; i++)
                INIT_LIST_HEAD(&pcpu_slot[i]);
 
@@ -2458,7 +2460,7 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
        size_sum = ai->static_size + ai->reserved_size + ai->dyn_size;
        areas_size = PFN_ALIGN(ai->nr_groups * sizeof(void *));
 
-       areas = memblock_virt_alloc_nopanic(areas_size, 0);
+       areas = memblock_alloc_nopanic(areas_size, SMP_CACHE_BYTES);
        if (!areas) {
                rc = -ENOMEM;
                goto out_free;
@@ -2599,7 +2601,7 @@ int __init pcpu_page_first_chunk(size_t reserved_size,
        /* unaligned allocations can't be freed, round up to page size */
        pages_size = PFN_ALIGN(unit_pages * num_possible_cpus() *
                               sizeof(pages[0]));
-       pages = memblock_virt_alloc(pages_size, 0);
+       pages = memblock_alloc(pages_size, SMP_CACHE_BYTES);
 
        /* allocate pages */
        j = 0;
@@ -2688,7 +2690,7 @@ EXPORT_SYMBOL(__per_cpu_offset);
 static void * __init pcpu_dfl_fc_alloc(unsigned int cpu, size_t size,
                                       size_t align)
 {
-       return  memblock_virt_alloc_from_nopanic(
+       return  memblock_alloc_from_nopanic(
                        size, align, __pa(MAX_DMA_ADDRESS));
 }
 
@@ -2737,7 +2739,7 @@ void __init setup_per_cpu_areas(void)
        void *fc;
 
        ai = pcpu_alloc_alloc_info(1, 1);
-       fc = memblock_virt_alloc_from_nopanic(unit_size,
+       fc = memblock_alloc_from_nopanic(unit_size,
                                              PAGE_SIZE,
                                              __pa(MAX_DMA_ADDRESS));
        if (!ai || !fc)
index 8301293331a27963b8a83bb190a6a7a905bcb74d..7fec057967966c27fdedf3ccffc082ce12eb7ef7 100644 (file)
@@ -20,7 +20,7 @@
  */
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/memremap.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
@@ -42,8 +42,8 @@ static void * __ref __earlyonly_bootmem_alloc(int node,
                                unsigned long align,
                                unsigned long goal)
 {
-       return memblock_virt_alloc_try_nid_raw(size, align, goal,
-                                              BOOTMEM_ALLOC_ACCESSIBLE, node);
+       return memblock_alloc_try_nid_raw(size, align, goal,
+                                              MEMBLOCK_ALLOC_ACCESSIBLE, node);
 }
 
 void * __meminit vmemmap_alloc_block(unsigned long size, int node)
index 67ad061f7fb8b1b4a38af7a5f69913f6c4f39e70..33307fc05c4d3372d5e4746116330532765e61d7 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/mmzone.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/compiler.h>
 #include <linux/highmem.h>
 #include <linux/export.h>
@@ -68,7 +68,8 @@ static noinline struct mem_section __ref *sparse_index_alloc(int nid)
        if (slab_is_available())
                section = kzalloc_node(array_size, GFP_KERNEL, nid);
        else
-               section = memblock_virt_alloc_node(array_size, nid);
+               section = memblock_alloc_node(array_size, SMP_CACHE_BYTES,
+                                             nid);
 
        return section;
 }
@@ -216,7 +217,7 @@ void __init memory_present(int nid, unsigned long start, unsigned long end)
 
                size = sizeof(struct mem_section*) * NR_SECTION_ROOTS;
                align = 1 << (INTERNODE_CACHE_SHIFT);
-               mem_section = memblock_virt_alloc(size, align);
+               mem_section = memblock_alloc(size, align);
        }
 #endif
 
@@ -306,7 +307,7 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
        limit = goal + (1UL << PA_SECTION_SHIFT);
        nid = early_pfn_to_nid(goal >> PAGE_SHIFT);
 again:
-       p = memblock_virt_alloc_try_nid_nopanic(size,
+       p = memblock_alloc_try_nid_nopanic(size,
                                                SMP_CACHE_BYTES, goal, limit,
                                                nid);
        if (!p && limit) {
@@ -362,7 +363,7 @@ static unsigned long * __init
 sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
                                         unsigned long size)
 {
-       return memblock_virt_alloc_node_nopanic(size, pgdat->node_id);
+       return memblock_alloc_node_nopanic(size, pgdat->node_id);
 }
 
 static void __init check_usemap_section_nr(int nid, unsigned long *usemap)
@@ -391,9 +392,9 @@ struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid,
        if (map)
                return map;
 
-       map = memblock_virt_alloc_try_nid(size,
+       map = memblock_alloc_try_nid(size,
                                          PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
-                                         BOOTMEM_ALLOC_ACCESSIBLE, nid);
+                                         MEMBLOCK_ALLOC_ACCESSIBLE, nid);
        return map;
 }
 #endif /* !CONFIG_SPARSEMEM_VMEMMAP */
@@ -405,9 +406,9 @@ static void __init sparse_buffer_init(unsigned long size, int nid)
 {
        WARN_ON(sparsemap_buf); /* forgot to call sparse_buffer_fini()? */
        sparsemap_buf =
-               memblock_virt_alloc_try_nid_raw(size, PAGE_SIZE,
+               memblock_alloc_try_nid_raw(size, PAGE_SIZE,
                                                __pa(MAX_DMA_ADDRESS),
-                                               BOOTMEM_ALLOC_ACCESSIBLE, nid);
+                                               MEMBLOCK_ALLOC_ACCESSIBLE, nid);
        sparsemap_buf_end = sparsemap_buf + size;
 }
 
index c0486cfc85d93b8ebb8db58e89e6fbecfffdf279..aa0a5641e5d010a29860313b7cd2bf6fb60bc722 100644 (file)
@@ -8,7 +8,6 @@ obj-$(CONFIG_NET_9P_RDMA) += 9pnet_rdma.o
        mod.o \
        client.o \
        error.o \
-       util.o \
        protocol.o \
        trans_fd.o \
        trans_common.o \
index deae53a7dffc868d66efbcc01bba141b97d97128..5f23e18eecc02f32ac80ddd85658006f9ad15430 100644 (file)
@@ -231,144 +231,170 @@ free_and_return:
        return ret;
 }
 
-static struct p9_fcall *p9_fcall_alloc(int alloc_msize)
+static int p9_fcall_init(struct p9_client *c, struct p9_fcall *fc,
+                        int alloc_msize)
 {
-       struct p9_fcall *fc;
-       fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS);
-       if (!fc)
-               return NULL;
+       if (likely(c->fcall_cache) && alloc_msize == c->msize) {
+               fc->sdata = kmem_cache_alloc(c->fcall_cache, GFP_NOFS);
+               fc->cache = c->fcall_cache;
+       } else {
+               fc->sdata = kmalloc(alloc_msize, GFP_NOFS);
+               fc->cache = NULL;
+       }
+       if (!fc->sdata)
+               return -ENOMEM;
        fc->capacity = alloc_msize;
-       fc->sdata = (char *) fc + sizeof(struct p9_fcall);
-       return fc;
+       return 0;
+}
+
+void p9_fcall_fini(struct p9_fcall *fc)
+{
+       /* sdata can be NULL for interrupted requests in trans_rdma,
+        * and kmem_cache_free does not do NULL-check for us
+        */
+       if (unlikely(!fc->sdata))
+               return;
+
+       if (fc->cache)
+               kmem_cache_free(fc->cache, fc->sdata);
+       else
+               kfree(fc->sdata);
 }
+EXPORT_SYMBOL(p9_fcall_fini);
+
+static struct kmem_cache *p9_req_cache;
 
 /**
- * p9_tag_alloc - lookup/allocate a request by tag
- * @c: client session to lookup tag within
- * @tag: numeric id for transaction
- *
- * this is a simple array lookup, but will grow the
- * request_slots as necessary to accommodate transaction
- * ids which did not previously have a slot.
- *
- * this code relies on the client spinlock to manage locks, its
- * possible we should switch to something else, but I'd rather
- * stick with something low-overhead for the common case.
+ * p9_req_alloc - Allocate a new request.
+ * @c: Client session.
+ * @type: Transaction type.
+ * @max_size: Maximum packet size for this request.
  *
+ * Context: Process context.
+ * Return: Pointer to new request.
  */
-
 static struct p9_req_t *
-p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
+p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
 {
-       unsigned long flags;
-       int row, col;
-       struct p9_req_t *req;
+       struct p9_req_t *req = kmem_cache_alloc(p9_req_cache, GFP_NOFS);
        int alloc_msize = min(c->msize, max_size);
+       int tag;
 
-       /* This looks up the original request by tag so we know which
-        * buffer to read the data into */
-       tag++;
-
-       if (tag >= c->max_tag) {
-               spin_lock_irqsave(&c->lock, flags);
-               /* check again since original check was outside of lock */
-               while (tag >= c->max_tag) {
-                       row = (tag / P9_ROW_MAXTAG);
-                       c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
-                                       sizeof(struct p9_req_t), GFP_ATOMIC);
-
-                       if (!c->reqs[row]) {
-                               pr_err("Couldn't grow tag array\n");
-                               spin_unlock_irqrestore(&c->lock, flags);
-                               return ERR_PTR(-ENOMEM);
-                       }
-                       for (col = 0; col < P9_ROW_MAXTAG; col++) {
-                               req = &c->reqs[row][col];
-                               req->status = REQ_STATUS_IDLE;
-                               init_waitqueue_head(&req->wq);
-                       }
-                       c->max_tag += P9_ROW_MAXTAG;
-               }
-               spin_unlock_irqrestore(&c->lock, flags);
-       }
-       row = tag / P9_ROW_MAXTAG;
-       col = tag % P9_ROW_MAXTAG;
-
-       req = &c->reqs[row][col];
-       if (!req->tc)
-               req->tc = p9_fcall_alloc(alloc_msize);
-       if (!req->rc)
-               req->rc = p9_fcall_alloc(alloc_msize);
-       if (!req->tc || !req->rc)
-               goto grow_failed;
+       if (!req)
+               return ERR_PTR(-ENOMEM);
 
-       p9pdu_reset(req->tc);
-       p9pdu_reset(req->rc);
+       if (p9_fcall_init(c, &req->tc, alloc_msize))
+               goto free_req;
+       if (p9_fcall_init(c, &req->rc, alloc_msize))
+               goto free;
 
-       req->tc->tag = tag-1;
+       p9pdu_reset(&req->tc);
+       p9pdu_reset(&req->rc);
        req->status = REQ_STATUS_ALLOC;
+       init_waitqueue_head(&req->wq);
+       INIT_LIST_HEAD(&req->req_list);
+
+       idr_preload(GFP_NOFS);
+       spin_lock_irq(&c->lock);
+       if (type == P9_TVERSION)
+               tag = idr_alloc(&c->reqs, req, P9_NOTAG, P9_NOTAG + 1,
+                               GFP_NOWAIT);
+       else
+               tag = idr_alloc(&c->reqs, req, 0, P9_NOTAG, GFP_NOWAIT);
+       req->tc.tag = tag;
+       spin_unlock_irq(&c->lock);
+       idr_preload_end();
+       if (tag < 0)
+               goto free;
+
+       /* Init ref to two because in the general case there is one ref
+        * that is put asynchronously by a writer thread, one ref
+        * temporarily given by p9_tag_lookup and put by p9_client_cb
+        * in the recv thread, and one ref put by p9_tag_remove in the
+        * main thread. The only exception is virtio that does not use
+        * p9_tag_lookup but does not have a writer thread either
+        * (the write happens synchronously in the request/zc_request
+        * callback), so p9_client_cb eats the second ref there
+        * as the pointer is duplicated directly by virtqueue_add_sgs()
+        */
+       refcount_set(&req->refcount.refcount, 2);
 
        return req;
 
-grow_failed:
-       pr_err("Couldn't grow tag array\n");
-       kfree(req->tc);
-       kfree(req->rc);
-       req->tc = req->rc = NULL;
+free:
+       p9_fcall_fini(&req->tc);
+       p9_fcall_fini(&req->rc);
+free_req:
+       kmem_cache_free(p9_req_cache, req);
        return ERR_PTR(-ENOMEM);
 }
 
 /**
- * p9_tag_lookup - lookup a request by tag
- * @c: client session to lookup tag within
- * @tag: numeric id for transaction
+ * p9_tag_lookup - Look up a request by tag.
+ * @c: Client session.
+ * @tag: Transaction ID.
  *
+ * Context: Any context.
+ * Return: A request, or %NULL if there is no request with that tag.
  */
-
 struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
 {
-       int row, col;
-
-       /* This looks up the original request by tag so we know which
-        * buffer to read the data into */
-       tag++;
-
-       if (tag >= c->max_tag)
-               return NULL;
+       struct p9_req_t *req;
 
-       row = tag / P9_ROW_MAXTAG;
-       col = tag % P9_ROW_MAXTAG;
+       rcu_read_lock();
+again:
+       req = idr_find(&c->reqs, tag);
+       if (req) {
+               /* We have to be careful with the req found under rcu_read_lock
+                * Thanks to SLAB_TYPESAFE_BY_RCU we can safely try to get the
+                * ref again without corrupting other data, then check again
+                * that the tag matches once we have the ref
+                */
+               if (!p9_req_try_get(req))
+                       goto again;
+               if (req->tc.tag != tag) {
+                       p9_req_put(req);
+                       goto again;
+               }
+       }
+       rcu_read_unlock();
 
-       return &c->reqs[row][col];
+       return req;
 }
 EXPORT_SYMBOL(p9_tag_lookup);
 
 /**
- * p9_tag_init - setup tags structure and contents
- * @c:  v9fs client struct
- *
- * This initializes the tags structure for each client instance.
+ * p9_tag_remove - Remove a tag.
+ * @c: Client session.
+ * @r: Request of reference.
  *
+ * Context: Any context.
  */
+static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
+{
+       unsigned long flags;
+       u16 tag = r->tc.tag;
+
+       p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
+       spin_lock_irqsave(&c->lock, flags);
+       idr_remove(&c->reqs, tag);
+       spin_unlock_irqrestore(&c->lock, flags);
+       return p9_req_put(r);
+}
 
-static int p9_tag_init(struct p9_client *c)
+static void p9_req_free(struct kref *ref)
 {
-       int err = 0;
+       struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
+       p9_fcall_fini(&r->tc);
+       p9_fcall_fini(&r->rc);
+       kmem_cache_free(p9_req_cache, r);
+}
 
-       c->tagpool = p9_idpool_create();
-       if (IS_ERR(c->tagpool)) {
-               err = PTR_ERR(c->tagpool);
-               goto error;
-       }
-       err = p9_idpool_get(c->tagpool); /* reserve tag 0 */
-       if (err < 0) {
-               p9_idpool_destroy(c->tagpool);
-               goto error;
-       }
-       c->max_tag = 0;
-error:
-       return err;
+int p9_req_put(struct p9_req_t *r)
+{
+       return kref_put(&r->refcount, p9_req_free);
 }
+EXPORT_SYMBOL(p9_req_put);
 
 /**
  * p9_tag_cleanup - cleans up tags structure and reclaims resources
@@ -379,52 +405,17 @@ error:
  */
 static void p9_tag_cleanup(struct p9_client *c)
 {
-       int row, col;
-
-       /* check to insure all requests are idle */
-       for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
-               for (col = 0; col < P9_ROW_MAXTAG; col++) {
-                       if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
-                               p9_debug(P9_DEBUG_MUX,
-                                        "Attempting to cleanup non-free tag %d,%d\n",
-                                        row, col);
-                               /* TODO: delay execution of cleanup */
-                               return;
-                       }
-               }
-       }
-
-       if (c->tagpool) {
-               p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */
-               p9_idpool_destroy(c->tagpool);
-       }
+       struct p9_req_t *req;
+       int id;
 
-       /* free requests associated with tags */
-       for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
-               for (col = 0; col < P9_ROW_MAXTAG; col++) {
-                       kfree(c->reqs[row][col].tc);
-                       kfree(c->reqs[row][col].rc);
-               }
-               kfree(c->reqs[row]);
+       rcu_read_lock();
+       idr_for_each_entry(&c->reqs, req, id) {
+               pr_info("Tag %d still in use\n", id);
+               if (p9_tag_remove(c, req) == 0)
+                       pr_warn("Packet with tag %d has still references",
+                               req->tc.tag);
        }
-       c->max_tag = 0;
-}
-
-/**
- * p9_free_req - free a request and clean-up as necessary
- * c: client state
- * r: request to release
- *
- */
-
-static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
-{
-       int tag = r->tc->tag;
-       p9_debug(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
-
-       r->status = REQ_STATUS_IDLE;
-       if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
-               p9_idpool_put(tag, c->tagpool);
+       rcu_read_unlock();
 }
 
 /**
@@ -435,7 +426,7 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
  */
 void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
 {
-       p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
+       p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc.tag);
 
        /*
         * This barrier is needed to make sure any change made to req before
@@ -445,7 +436,8 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
        req->status = status;
 
        wake_up(&req->wq);
-       p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
+       p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
+       p9_req_put(req);
 }
 EXPORT_SYMBOL(p9_client_cb);
 
@@ -516,18 +508,18 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
        int err;
        int ecode;
 
-       err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
-       if (req->rc->size >= c->msize) {
+       err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
+       if (req->rc.size >= c->msize) {
                p9_debug(P9_DEBUG_ERROR,
                         "requested packet size too big: %d\n",
-                        req->rc->size);
+                        req->rc.size);
                return -EIO;
        }
        /*
         * dump the response from server
         * This should be after check errors which poplulate pdu_fcall.
         */
-       trace_9p_protocol_dump(c, req->rc);
+       trace_9p_protocol_dump(c, &req->rc);
        if (err) {
                p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
                return err;
@@ -537,7 +529,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
 
        if (!p9_is_proto_dotl(c)) {
                char *ename;
-               err = p9pdu_readf(req->rc, c->proto_version, "s?d",
+               err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
                                  &ename, &ecode);
                if (err)
                        goto out_err;
@@ -553,7 +545,7 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
                }
                kfree(ename);
        } else {
-               err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
+               err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
                err = -ecode;
 
                p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
@@ -587,12 +579,12 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
        int8_t type;
        char *ename = NULL;
 
-       err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
+       err = p9_parse_header(&req->rc, NULL, &type, NULL, 0);
        /*
         * dump the response from server
         * This should be after parse_header which poplulate pdu_fcall.
         */
-       trace_9p_protocol_dump(c, req->rc);
+       trace_9p_protocol_dump(c, &req->rc);
        if (err) {
                p9_debug(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
                return err;
@@ -607,13 +599,13 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
                /* 7 = header size for RERROR; */
                int inline_len = in_hdrlen - 7;
 
-               len =  req->rc->size - req->rc->offset;
+               len = req->rc.size - req->rc.offset;
                if (len > (P9_ZC_HDR_SZ - 7)) {
                        err = -EFAULT;
                        goto out_err;
                }
 
-               ename = &req->rc->sdata[req->rc->offset];
+               ename = &req->rc.sdata[req->rc.offset];
                if (len > inline_len) {
                        /* We have error in external buffer */
                        if (!copy_from_iter_full(ename + inline_len,
@@ -623,7 +615,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
                        }
                }
                ename = NULL;
-               err = p9pdu_readf(req->rc, c->proto_version, "s?d",
+               err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
                                  &ename, &ecode);
                if (err)
                        goto out_err;
@@ -639,7 +631,7 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
                }
                kfree(ename);
        } else {
-               err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
+               err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
                err = -ecode;
 
                p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
@@ -672,7 +664,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
        int16_t oldtag;
        int err;
 
-       err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
+       err = p9_parse_header(&oldreq->tc, NULL, NULL, &oldtag, 1);
        if (err)
                return err;
 
@@ -686,11 +678,12 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
         * if we haven't received a response for oldreq,
         * remove it from the list
         */
-       if (oldreq->status == REQ_STATUS_SENT)
+       if (oldreq->status == REQ_STATUS_SENT) {
                if (c->trans_mod->cancelled)
                        c->trans_mod->cancelled(c, oldreq);
+       }
 
-       p9_free_req(c, req);
+       p9_tag_remove(c, req);
        return 0;
 }
 
@@ -698,7 +691,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
                                              int8_t type, int req_size,
                                              const char *fmt, va_list ap)
 {
-       int tag, err;
+       int err;
        struct p9_req_t *req;
 
        p9_debug(P9_DEBUG_MUX, "client %p op %d\n", c, type);
@@ -711,27 +704,22 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
        if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
                return ERR_PTR(-EIO);
 
-       tag = P9_NOTAG;
-       if (type != P9_TVERSION) {
-               tag = p9_idpool_get(c->tagpool);
-               if (tag < 0)
-                       return ERR_PTR(-ENOMEM);
-       }
-
-       req = p9_tag_alloc(c, tag, req_size);
+       req = p9_tag_alloc(c, type, req_size);
        if (IS_ERR(req))
                return req;
 
        /* marshall the data */
-       p9pdu_prepare(req->tc, tag, type);
-       err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
+       p9pdu_prepare(&req->tc, req->tc.tag, type);
+       err = p9pdu_vwritef(&req->tc, c->proto_version, fmt, ap);
        if (err)
                goto reterr;
-       p9pdu_finalize(c, req->tc);
-       trace_9p_client_req(c, type, tag);
+       p9pdu_finalize(c, &req->tc);
+       trace_9p_client_req(c, type, req->tc.tag);
        return req;
 reterr:
-       p9_free_req(c, req);
+       p9_tag_remove(c, req);
+       /* We have to put also the 2nd reference as it won't be used */
+       p9_req_put(req);
        return ERR_PTR(err);
 }
 
@@ -741,7 +729,7 @@ reterr:
  * @type: type of request
  * @fmt: protocol format string (see protocol.c)
  *
- * Returns request structure (which client must free using p9_free_req)
+ * Returns request structure (which client must free using p9_tag_remove)
  */
 
 static struct p9_req_t *
@@ -766,6 +754,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
 
        err = c->trans_mod->request(c, req);
        if (err < 0) {
+               /* write won't happen */
+               p9_req_put(req);
                if (err != -ERESTARTSYS && err != -EFAULT)
                        c->status = Disconnected;
                goto recalc_sigpending;
@@ -813,11 +803,11 @@ recalc_sigpending:
                goto reterr;
 
        err = p9_check_errors(c, req);
-       trace_9p_client_res(c, type, req->rc->tag, err);
+       trace_9p_client_res(c, type, req->rc.tag, err);
        if (!err)
                return req;
 reterr:
-       p9_free_req(c, req);
+       p9_tag_remove(c, req);
        return ERR_PTR(safe_errno(err));
 }
 
@@ -832,7 +822,7 @@ reterr:
  * @hdrlen: reader header size, This is the size of response protocol data
  * @fmt: protocol format string (see protocol.c)
  *
- * Returns request structure (which client must free using p9_free_req)
+ * Returns request structure (which client must free using p9_tag_remove)
  */
 static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
                                         struct iov_iter *uidata,
@@ -895,11 +885,11 @@ recalc_sigpending:
                goto reterr;
 
        err = p9_check_zc_errors(c, req, uidata, in_hdrlen);
-       trace_9p_client_res(c, type, req->rc->tag, err);
+       trace_9p_client_res(c, type, req->rc.tag, err);
        if (!err)
                return req;
 reterr:
-       p9_free_req(c, req);
+       p9_tag_remove(c, req);
        return ERR_PTR(safe_errno(err));
 }
 
@@ -978,10 +968,10 @@ static int p9_client_version(struct p9_client *c)
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
+       err = p9pdu_readf(&req->rc, c->proto_version, "ds", &msize, &version);
        if (err) {
                p9_debug(P9_DEBUG_9P, "version error %d\n", err);
-               trace_9p_protocol_dump(c, req->rc);
+               trace_9p_protocol_dump(c, &req->rc);
                goto error;
        }
 
@@ -1002,7 +992,7 @@ static int p9_client_version(struct p9_client *c)
 
 error:
        kfree(version);
-       p9_free_req(c, req);
+       p9_tag_remove(c, req);
 
        return err;
 }
@@ -1020,20 +1010,18 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
 
        clnt->trans_mod = NULL;
        clnt->trans = NULL;
+       clnt->fcall_cache = NULL;
 
        client_id = utsname()->nodename;
        memcpy(clnt->name, client_id, strlen(client_id) + 1);
 
        spin_lock_init(&clnt->lock);
        idr_init(&clnt->fids);
-
-       err = p9_tag_init(clnt);
-       if (err < 0)
-               goto free_client;
+       idr_init(&clnt->reqs);
 
        err = parse_opts(options, clnt);
        if (err < 0)
-               goto destroy_tagpool;
+               goto free_client;
 
        if (!clnt->trans_mod)
                clnt->trans_mod = v9fs_get_default_trans();
@@ -1042,7 +1030,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
                err = -EPROTONOSUPPORT;
                p9_debug(P9_DEBUG_ERROR,
                         "No transport defined or default transport\n");
-               goto destroy_tagpool;
+               goto free_client;
        }
 
        p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
@@ -1059,14 +1047,21 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (err)
                goto close_trans;
 
+       /* P9_HDRSZ + 4 is the smallest packet header we can have that is
+        * followed by data accessed from userspace by read
+        */
+       clnt->fcall_cache =
+               kmem_cache_create_usercopy("9p-fcall-cache", clnt->msize,
+                                          0, 0, P9_HDRSZ + 4,
+                                          clnt->msize - (P9_HDRSZ + 4),
+                                          NULL);
+
        return clnt;
 
 close_trans:
        clnt->trans_mod->close(clnt);
 put_trans:
        v9fs_put_trans(clnt->trans_mod);
-destroy_tagpool:
-       p9_idpool_destroy(clnt->tagpool);
 free_client:
        kfree(clnt);
        return ERR_PTR(err);
@@ -1092,6 +1087,7 @@ void p9_client_destroy(struct p9_client *clnt)
 
        p9_tag_cleanup(clnt);
 
+       kmem_cache_destroy(clnt->fcall_cache);
        kfree(clnt);
 }
 EXPORT_SYMBOL(p9_client_destroy);
@@ -1135,10 +1131,10 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", &qid);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               p9_free_req(clnt, req);
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_tag_remove(clnt, req);
                goto error;
        }
 
@@ -1147,7 +1143,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
 
        memmove(&fid->qid, &qid, sizeof(struct p9_qid));
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return fid;
 
 error:
@@ -1192,13 +1188,13 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "R", &nwqids, &wqids);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               p9_free_req(clnt, req);
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_tag_remove(clnt, req);
                goto clunk_fid;
        }
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 
        p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
 
@@ -1259,9 +1255,9 @@ int p9_client_open(struct p9_fid *fid, int mode)
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto free_and_error;
        }
 
@@ -1273,7 +1269,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
        fid->iounit = iounit;
 
 free_and_error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1303,9 +1299,9 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", qid, &iounit);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto free_and_error;
        }
 
@@ -1318,7 +1314,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
        ofid->iounit = iounit;
 
 free_and_error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1348,9 +1344,9 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Qd", &qid, &iounit);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto free_and_error;
        }
 
@@ -1363,7 +1359,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
        fid->iounit = iounit;
 
 free_and_error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1387,9 +1383,9 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto free_and_error;
        }
 
@@ -1397,7 +1393,7 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
                        qid->type, (unsigned long long)qid->path, qid->version);
 
 free_and_error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1417,7 +1413,7 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newna
                return PTR_ERR(req);
 
        p9_debug(P9_DEBUG_9P, "<<< RLINK\n");
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return 0;
 }
 EXPORT_SYMBOL(p9_client_link);
@@ -1441,7 +1437,7 @@ int p9_client_fsync(struct p9_fid *fid, int datasync)
 
        p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 
 error:
        return err;
@@ -1476,7 +1472,7 @@ again:
 
        p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        /*
         * Fid is not valid even after a failed clunk
@@ -1510,7 +1506,7 @@ int p9_client_remove(struct p9_fid *fid)
 
        p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        if (err == -ERESTARTSYS)
                p9_client_clunk(fid);
@@ -1537,7 +1533,7 @@ int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
        }
        p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1585,11 +1581,11 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
                        break;
                }
 
-               *err = p9pdu_readf(req->rc, clnt->proto_version,
+               *err = p9pdu_readf(&req->rc, clnt->proto_version,
                                   "D", &count, &dataptr);
                if (*err) {
-                       trace_9p_protocol_dump(clnt, req->rc);
-                       p9_free_req(clnt, req);
+                       trace_9p_protocol_dump(clnt, &req->rc);
+                       p9_tag_remove(clnt, req);
                        break;
                }
                if (rsize < count) {
@@ -1599,7 +1595,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
 
                p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
                if (!count) {
-                       p9_free_req(clnt, req);
+                       p9_tag_remove(clnt, req);
                        break;
                }
 
@@ -1609,7 +1605,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
                        offset += n;
                        if (n != count) {
                                *err = -EFAULT;
-                               p9_free_req(clnt, req);
+                               p9_tag_remove(clnt, req);
                                break;
                        }
                } else {
@@ -1617,7 +1613,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
                        total += count;
                        offset += count;
                }
-               p9_free_req(clnt, req);
+               p9_tag_remove(clnt, req);
        }
        return total;
 }
@@ -1658,10 +1654,10 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
                        break;
                }
 
-               *err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
+               *err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
                if (*err) {
-                       trace_9p_protocol_dump(clnt, req->rc);
-                       p9_free_req(clnt, req);
+                       trace_9p_protocol_dump(clnt, &req->rc);
+                       p9_tag_remove(clnt, req);
                        break;
                }
                if (rsize < count) {
@@ -1671,7 +1667,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
 
                p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
 
-               p9_free_req(clnt, req);
+               p9_tag_remove(clnt, req);
                iov_iter_advance(from, count);
                total += count;
                offset += count;
@@ -1702,10 +1698,10 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "wS", &ignored, ret);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               p9_free_req(clnt, req);
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_tag_remove(clnt, req);
                goto error;
        }
 
@@ -1722,7 +1718,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
                from_kgid(&init_user_ns, ret->n_gid),
                from_kuid(&init_user_ns, ret->n_muid));
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return ret;
 
 error:
@@ -1755,10 +1751,10 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "A", ret);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               p9_free_req(clnt, req);
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_tag_remove(clnt, req);
                goto error;
        }
 
@@ -1783,7 +1779,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
                ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
                ret->st_gen, ret->st_data_version);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return ret;
 
 error:
@@ -1852,7 +1848,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
 
        p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1884,7 +1880,7 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1907,12 +1903,12 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
-               &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
-               &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
+                         &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
+                         &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               p9_free_req(clnt, req);
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_tag_remove(clnt, req);
                goto error;
        }
 
@@ -1923,7 +1919,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
                sb->blocks, sb->bfree, sb->bavail, sb->files,  sb->ffree,
                sb->fsid, (long int)sb->namelen);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1951,7 +1947,7 @@ int p9_client_rename(struct p9_fid *fid,
 
        p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -1981,7 +1977,7 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
        p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
                   newdirfid->fid, new_name);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -2015,13 +2011,13 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
                err = PTR_ERR(req);
                goto error;
        }
-       err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "q", attr_size);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               p9_free_req(clnt, req);
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_tag_remove(clnt, req);
                goto clunk_fid;
        }
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        p9_debug(P9_DEBUG_9P, "<<<  RXATTRWALK fid %d size %llu\n",
                attr_fid->fid, *attr_size);
        return attr_fid;
@@ -2055,7 +2051,7 @@ int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -2103,9 +2099,9 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
                goto error;
        }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "D", &count, &dataptr);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto free_and_error;
        }
        if (rsize < count) {
@@ -2118,11 +2114,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
        if (non_zc)
                memmove(data, dataptr, count);
 
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return count;
 
 free_and_error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
 error:
        return err;
 }
@@ -2144,16 +2140,16 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
                                (unsigned long long)qid->path, qid->version);
 
 error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return err;
 
 }
@@ -2175,16 +2171,16 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", qid);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
                                (unsigned long long)qid->path, qid->version);
 
 error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return err;
 
 }
@@ -2210,14 +2206,14 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "b", status);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
 error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return err;
 
 }
@@ -2241,18 +2237,18 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type,
-                       &glock->start, &glock->length, &glock->proc_id,
-                       &glock->client_id);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "bqqds", &glock->type,
+                         &glock->start, &glock->length, &glock->proc_id,
+                         &glock->client_id);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
                "proc_id %d client_id %s\n", glock->type, glock->start,
                glock->length, glock->proc_id, glock->client_id);
 error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return err;
 }
 EXPORT_SYMBOL(p9_client_getlock_dotl);
@@ -2271,14 +2267,25 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
        if (IS_ERR(req))
                return PTR_ERR(req);
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "s", target);
        if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
+               trace_9p_protocol_dump(clnt, &req->rc);
                goto error;
        }
        p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
 error:
-       p9_free_req(clnt, req);
+       p9_tag_remove(clnt, req);
        return err;
 }
 EXPORT_SYMBOL(p9_client_readlink);
+
+int __init p9_client_init(void)
+{
+       p9_req_cache = KMEM_CACHE(p9_req_t, SLAB_TYPESAFE_BY_RCU);
+       return p9_req_cache ? 0 : -ENOMEM;
+}
+
+void __exit p9_client_exit(void)
+{
+       kmem_cache_destroy(p9_req_cache);
+}
index 253ba824a325d903931d522b997ad9ab07708e41..0da56d6af73bdf6ef1708a2cb8059d392c835951 100644 (file)
@@ -171,11 +171,17 @@ void v9fs_put_trans(struct p9_trans_module *m)
  */
 static int __init init_p9(void)
 {
+       int ret;
+
+       ret = p9_client_init();
+       if (ret)
+               return ret;
+
        p9_error_init();
        pr_info("Installing 9P2000 support\n");
        p9_trans_fd_init();
 
-       return 0;
+       return ret;
 }
 
 /**
@@ -188,6 +194,7 @@ static void __exit exit_p9(void)
        pr_info("Unloading 9P2000 support\n");
 
        p9_trans_fd_exit();
+       p9_client_exit();
 }
 
 module_init(init_p9)
index 4a1e1dd30b52fd04abef83272567a1975a840e0f..462ba144cb3934d6761a66c84f7d332f0559c804 100644 (file)
@@ -46,10 +46,15 @@ p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
 void p9stat_free(struct p9_wstat *stbuf)
 {
        kfree(stbuf->name);
+       stbuf->name = NULL;
        kfree(stbuf->uid);
+       stbuf->uid = NULL;
        kfree(stbuf->gid);
+       stbuf->gid = NULL;
        kfree(stbuf->muid);
+       stbuf->muid = NULL;
        kfree(stbuf->extension);
+       stbuf->extension = NULL;
 }
 EXPORT_SYMBOL(p9stat_free);
 
@@ -566,9 +571,10 @@ int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
        if (ret) {
                p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
                trace_9p_protocol_dump(clnt, &fake_pdu);
+               return ret;
        }
 
-       return ret;
+       return fake_pdu.offset;
 }
 EXPORT_SYMBOL(p9stat_read);
 
@@ -617,13 +623,19 @@ int p9dirent_read(struct p9_client *clnt, char *buf, int len,
        if (ret) {
                p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
                trace_9p_protocol_dump(clnt, &fake_pdu);
-               goto out;
+               return ret;
        }
 
-       strcpy(dirent->d_name, nameptr);
+       ret = strscpy(dirent->d_name, nameptr, sizeof(dirent->d_name));
+       if (ret < 0) {
+               p9_debug(P9_DEBUG_ERROR,
+                        "On the wire dirent name too long: %s\n",
+                        nameptr);
+               kfree(nameptr);
+               return ret;
+       }
        kfree(nameptr);
 
-out:
        return fake_pdu.offset;
 }
 EXPORT_SYMBOL(p9dirent_read);
index e2ef3c782c53869ba2b7748dbee67b1c55bfb217..f868cf6fba7946c87d0bb152dbd35ba61e3eb0fb 100644 (file)
@@ -131,7 +131,8 @@ struct p9_conn {
        int err;
        struct list_head req_list;
        struct list_head unsent_req_list;
-       struct p9_req_t *req;
+       struct p9_req_t *rreq;
+       struct p9_req_t *wreq;
        char tmp_buf[7];
        struct p9_fcall rc;
        int wpos;
@@ -291,7 +292,6 @@ static void p9_read_work(struct work_struct *work)
        __poll_t n;
        int err;
        struct p9_conn *m;
-       int status = REQ_STATUS_ERROR;
 
        m = container_of(work, struct p9_conn, rq);
 
@@ -322,7 +322,7 @@ static void p9_read_work(struct work_struct *work)
        m->rc.offset += err;
 
        /* header read in */
-       if ((!m->req) && (m->rc.offset == m->rc.capacity)) {
+       if ((!m->rreq) && (m->rc.offset == m->rc.capacity)) {
                p9_debug(P9_DEBUG_TRANS, "got new header\n");
 
                /* Header size */
@@ -346,23 +346,23 @@ static void p9_read_work(struct work_struct *work)
                         "mux %p pkt: size: %d bytes tag: %d\n",
                         m, m->rc.size, m->rc.tag);
 
-               m->req = p9_tag_lookup(m->client, m->rc.tag);
-               if (!m->req || (m->req->status != REQ_STATUS_SENT)) {
+               m->rreq = p9_tag_lookup(m->client, m->rc.tag);
+               if (!m->rreq || (m->rreq->status != REQ_STATUS_SENT)) {
                        p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
                                 m->rc.tag);
                        err = -EIO;
                        goto error;
                }
 
-               if (m->req->rc == NULL) {
+               if (!m->rreq->rc.sdata) {
                        p9_debug(P9_DEBUG_ERROR,
                                 "No recv fcall for tag %d (req %p), disconnecting!\n",
-                                m->rc.tag, m->req);
-                       m->req = NULL;
+                                m->rc.tag, m->rreq);
+                       m->rreq = NULL;
                        err = -EIO;
                        goto error;
                }
-               m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall);
+               m->rc.sdata = m->rreq->rc.sdata;
                memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
                m->rc.capacity = m->rc.size;
        }
@@ -370,20 +370,27 @@ static void p9_read_work(struct work_struct *work)
        /* packet is read in
         * not an else because some packets (like clunk) have no payload
         */
-       if ((m->req) && (m->rc.offset == m->rc.capacity)) {
+       if ((m->rreq) && (m->rc.offset == m->rc.capacity)) {
                p9_debug(P9_DEBUG_TRANS, "got new packet\n");
-               m->req->rc->size = m->rc.offset;
+               m->rreq->rc.size = m->rc.offset;
                spin_lock(&m->client->lock);
-               if (m->req->status != REQ_STATUS_ERROR)
-                       status = REQ_STATUS_RCVD;
-               list_del(&m->req->req_list);
-               /* update req->status while holding client->lock  */
-               p9_client_cb(m->client, m->req, status);
+               if (m->rreq->status == REQ_STATUS_SENT) {
+                       list_del(&m->rreq->req_list);
+                       p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
+               } else {
+                       spin_unlock(&m->client->lock);
+                       p9_debug(P9_DEBUG_ERROR,
+                                "Request tag %d errored out while we were reading the reply\n",
+                                m->rc.tag);
+                       err = -EIO;
+                       goto error;
+               }
                spin_unlock(&m->client->lock);
                m->rc.sdata = NULL;
                m->rc.offset = 0;
                m->rc.capacity = 0;
-               m->req = NULL;
+               p9_req_put(m->rreq);
+               m->rreq = NULL;
        }
 
 end_clear:
@@ -469,9 +476,11 @@ static void p9_write_work(struct work_struct *work)
                p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
                list_move_tail(&req->req_list, &m->req_list);
 
-               m->wbuf = req->tc->sdata;
-               m->wsize = req->tc->size;
+               m->wbuf = req->tc.sdata;
+               m->wsize = req->tc.size;
                m->wpos = 0;
+               p9_req_get(req);
+               m->wreq = req;
                spin_unlock(&m->client->lock);
        }
 
@@ -492,8 +501,11 @@ static void p9_write_work(struct work_struct *work)
        }
 
        m->wpos += err;
-       if (m->wpos == m->wsize)
+       if (m->wpos == m->wsize) {
                m->wpos = m->wsize = 0;
+               p9_req_put(m->wreq);
+               m->wreq = NULL;
+       }
 
 end_clear:
        clear_bit(Wworksched, &m->wsched);
@@ -663,7 +675,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
        struct p9_conn *m = &ts->conn;
 
        p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
-                m, current, req->tc, req->tc->id);
+                m, current, &req->tc, req->tc.id);
        if (m->err < 0)
                return m->err;
 
@@ -694,6 +706,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
        if (req->status == REQ_STATUS_UNSENT) {
                list_del(&req->req_list);
                req->status = REQ_STATUS_FLSHD;
+               p9_req_put(req);
                ret = 0;
        }
        spin_unlock(&client->lock);
@@ -711,6 +724,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
        spin_lock(&client->lock);
        list_del(&req->req_list);
        spin_unlock(&client->lock);
+       p9_req_put(req);
 
        return 0;
 }
@@ -862,7 +876,15 @@ static void p9_conn_destroy(struct p9_conn *m)
 
        p9_mux_poll_stop(m);
        cancel_work_sync(&m->rq);
+       if (m->rreq) {
+               p9_req_put(m->rreq);
+               m->rreq = NULL;
+       }
        cancel_work_sync(&m->wq);
+       if (m->wreq) {
+               p9_req_put(m->wreq);
+               m->wreq = NULL;
+       }
 
        p9_conn_cancel(m, -ECONNRESET);
 
index b513cffeeb3c05d721ac2e203fd5687ad5b2b037..119103bfa82eef579e53e60908812b33c1fea52f 100644 (file)
@@ -122,7 +122,7 @@ struct p9_rdma_context {
        dma_addr_t busa;
        union {
                struct p9_req_t *req;
-               struct p9_fcall *rc;
+               struct p9_fcall rc;
        };
 };
 
@@ -274,8 +274,7 @@ p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
        case RDMA_CM_EVENT_DISCONNECTED:
                if (rdma)
                        rdma->state = P9_RDMA_CLOSED;
-               if (c)
-                       c->status = Disconnected;
+               c->status = Disconnected;
                break;
 
        case RDMA_CM_EVENT_TIMEWAIT_EXIT:
@@ -320,8 +319,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
        if (wc->status != IB_WC_SUCCESS)
                goto err_out;
 
-       c->rc->size = wc->byte_len;
-       err = p9_parse_header(c->rc, NULL, NULL, &tag, 1);
+       c->rc.size = wc->byte_len;
+       err = p9_parse_header(&c->rc, NULL, NULL, &tag, 1);
        if (err)
                goto err_out;
 
@@ -331,12 +330,13 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
 
        /* Check that we have not yet received a reply for this request.
         */
-       if (unlikely(req->rc)) {
+       if (unlikely(req->rc.sdata)) {
                pr_err("Duplicate reply for request %d", tag);
                goto err_out;
        }
 
-       req->rc = c->rc;
+       req->rc.size = c->rc.size;
+       req->rc.sdata = c->rc.sdata;
        p9_client_cb(client, req, REQ_STATUS_RCVD);
 
  out:
@@ -361,9 +361,10 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
                container_of(wc->wr_cqe, struct p9_rdma_context, cqe);
 
        ib_dma_unmap_single(rdma->cm_id->device,
-                           c->busa, c->req->tc->size,
+                           c->busa, c->req->tc.size,
                            DMA_TO_DEVICE);
        up(&rdma->sq_sem);
+       p9_req_put(c->req);
        kfree(c);
 }
 
@@ -401,7 +402,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
        struct ib_sge sge;
 
        c->busa = ib_dma_map_single(rdma->cm_id->device,
-                                   c->rc->sdata, client->msize,
+                                   c->rc.sdata, client->msize,
                                    DMA_FROM_DEVICE);
        if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
                goto error;
@@ -443,9 +444,9 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
         **/
        if (unlikely(atomic_read(&rdma->excess_rc) > 0)) {
                if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) {
-                       /* Got one ! */
-                       kfree(req->rc);
-                       req->rc = NULL;
+                       /* Got one! */
+                       p9_fcall_fini(&req->rc);
+                       req->rc.sdata = NULL;
                        goto dont_need_post_recv;
                } else {
                        /* We raced and lost. */
@@ -459,7 +460,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
                err = -ENOMEM;
                goto recv_error;
        }
-       rpl_context->rc = req->rc;
+       rpl_context->rc.sdata = req->rc.sdata;
 
        /*
         * Post a receive buffer for this request. We need to ensure
@@ -475,11 +476,11 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
 
        err = post_recv(client, rpl_context);
        if (err) {
-               p9_debug(P9_DEBUG_FCALL, "POST RECV failed\n");
+               p9_debug(P9_DEBUG_ERROR, "POST RECV failed: %d\n", err);
                goto recv_error;
        }
        /* remove posted receive buffer from request structure */
-       req->rc = NULL;
+       req->rc.sdata = NULL;
 
 dont_need_post_recv:
        /* Post the request */
@@ -491,7 +492,7 @@ dont_need_post_recv:
        c->req = req;
 
        c->busa = ib_dma_map_single(rdma->cm_id->device,
-                                   c->req->tc->sdata, c->req->tc->size,
+                                   c->req->tc.sdata, c->req->tc.size,
                                    DMA_TO_DEVICE);
        if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) {
                err = -EIO;
@@ -501,7 +502,7 @@ dont_need_post_recv:
        c->cqe.done = send_done;
 
        sge.addr = c->busa;
-       sge.length = c->req->tc->size;
+       sge.length = c->req->tc.size;
        sge.lkey = rdma->pd->local_dma_lkey;
 
        wr.next = NULL;
@@ -544,7 +545,7 @@ dont_need_post_recv:
  recv_error:
        kfree(rpl_context);
        spin_lock_irqsave(&rdma->req_lock, flags);
-       if (rdma->state < P9_RDMA_CLOSING) {
+       if (err != -EINTR && rdma->state < P9_RDMA_CLOSING) {
                rdma->state = P9_RDMA_CLOSING;
                spin_unlock_irqrestore(&rdma->req_lock, flags);
                rdma_disconnect(rdma->cm_id);
index 7728b0acde09aa904f4cc564de23f264abd8d2b6..eb596c2ed546ca5555a2100426eebb67205d99b1 100644 (file)
@@ -155,7 +155,7 @@ static void req_done(struct virtqueue *vq)
                }
 
                if (len) {
-                       req->rc->size = len;
+                       req->rc.size = len;
                        p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
                }
        }
@@ -207,6 +207,13 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
        return 1;
 }
 
+/* Reply won't come, so drop req ref */
+static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req)
+{
+       p9_req_put(req);
+       return 0;
+}
+
 /**
  * pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer,
  * this takes a list of pages.
@@ -273,12 +280,12 @@ req_retry:
        out_sgs = in_sgs = 0;
        /* Handle out VirtIO ring buffers */
        out = pack_sg_list(chan->sg, 0,
-                          VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
+                          VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
        if (out)
                sgs[out_sgs++] = chan->sg;
 
        in = pack_sg_list(chan->sg, out,
-                         VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
+                         VIRTQUEUE_NUM, req->rc.sdata, req->rc.capacity);
        if (in)
                sgs[out_sgs + in_sgs++] = chan->sg + out;
 
@@ -404,6 +411,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
        struct scatterlist *sgs[4];
        size_t offs;
        int need_drop = 0;
+       int kicked = 0;
 
        p9_debug(P9_DEBUG_TRANS, "virtio request\n");
 
@@ -411,29 +419,33 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
                __le32 sz;
                int n = p9_get_mapped_pages(chan, &out_pages, uodata,
                                            outlen, &offs, &need_drop);
-               if (n < 0)
-                       return n;
+               if (n < 0) {
+                       err = n;
+                       goto err_out;
+               }
                out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
                if (n != outlen) {
                        __le32 v = cpu_to_le32(n);
-                       memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
+                       memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
                        outlen = n;
                }
                /* The size field of the message must include the length of the
                 * header and the length of the data.  We didn't actually know
                 * the length of the data until this point so add it in now.
                 */
-               sz = cpu_to_le32(req->tc->size + outlen);
-               memcpy(&req->tc->sdata[0], &sz, sizeof(sz));
+               sz = cpu_to_le32(req->tc.size + outlen);
+               memcpy(&req->tc.sdata[0], &sz, sizeof(sz));
        } else if (uidata) {
                int n = p9_get_mapped_pages(chan, &in_pages, uidata,
                                            inlen, &offs, &need_drop);
-               if (n < 0)
-                       return n;
+               if (n < 0) {
+                       err = n;
+                       goto err_out;
+               }
                in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
                if (n != inlen) {
                        __le32 v = cpu_to_le32(n);
-                       memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
+                       memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
                        inlen = n;
                }
        }
@@ -445,7 +457,7 @@ req_retry_pinned:
 
        /* out data */
        out = pack_sg_list(chan->sg, 0,
-                          VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
+                          VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
 
        if (out)
                sgs[out_sgs++] = chan->sg;
@@ -464,7 +476,7 @@ req_retry_pinned:
         * alloced memory and payload onto the user buffer.
         */
        in = pack_sg_list(chan->sg, out,
-                         VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
+                         VIRTQUEUE_NUM, req->rc.sdata, in_hdr_len);
        if (in)
                sgs[out_sgs + in_sgs++] = chan->sg + out;
 
@@ -498,6 +510,7 @@ req_retry_pinned:
        }
        virtqueue_kick(chan->vq);
        spin_unlock_irqrestore(&chan->lock, flags);
+       kicked = 1;
        p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
        err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
        /*
@@ -518,6 +531,10 @@ err_out:
        }
        kvfree(in_pages);
        kvfree(out_pages);
+       if (!kicked) {
+               /* reply won't come */
+               p9_req_put(req);
+       }
        return err;
 }
 
@@ -750,6 +767,7 @@ static struct p9_trans_module p9_virtio_trans = {
        .request = p9_virtio_request,
        .zc_request = p9_virtio_zc_request,
        .cancel = p9_virtio_cancel,
+       .cancelled = p9_virtio_cancelled,
        /*
         * We leave one entry for input and one entry for response
         * headers. We also skip one more entry to accomodate, address
index c2d54ac76bfdbb72fa7ad24d63f7379afdc5433d..e2fbf3677b9baf3fa99ba98485f73caf0118f249 100644 (file)
@@ -141,7 +141,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
        struct xen_9pfs_front_priv *priv = NULL;
        RING_IDX cons, prod, masked_cons, masked_prod;
        unsigned long flags;
-       u32 size = p9_req->tc->size;
+       u32 size = p9_req->tc.size;
        struct xen_9pfs_dataring *ring;
        int num;
 
@@ -154,7 +154,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
        if (!priv || priv->client != client)
                return -EINVAL;
 
-       num = p9_req->tc->tag % priv->num_rings;
+       num = p9_req->tc.tag % priv->num_rings;
        ring = &priv->rings[num];
 
 again:
@@ -176,7 +176,7 @@ again:
        masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE);
        masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
 
-       xen_9pfs_write_packet(ring->data.out, p9_req->tc->sdata, size,
+       xen_9pfs_write_packet(ring->data.out, p9_req->tc.sdata, size,
                              &masked_prod, masked_cons, XEN_9PFS_RING_SIZE);
 
        p9_req->status = REQ_STATUS_SENT;
@@ -185,6 +185,7 @@ again:
        ring->intf->out_prod = prod;
        spin_unlock_irqrestore(&ring->lock, flags);
        notify_remote_via_irq(ring->irq);
+       p9_req_put(p9_req);
 
        return 0;
 }
@@ -229,12 +230,12 @@ static void p9_xen_response(struct work_struct *work)
                        continue;
                }
 
-               memcpy(req->rc, &h, sizeof(h));
-               req->rc->offset = 0;
+               memcpy(&req->rc, &h, sizeof(h));
+               req->rc.offset = 0;
 
                masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
                /* Then, read the whole packet (including the header) */
-               xen_9pfs_read_packet(req->rc->sdata, ring->data.in, h.size,
+               xen_9pfs_read_packet(req->rc.sdata, ring->data.in, h.size,
                                     masked_prod, &masked_cons,
                                     XEN_9PFS_RING_SIZE);
 
@@ -391,8 +392,8 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
        unsigned int max_rings, max_ring_order, len = 0;
 
        versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
-       if (!len)
-               return -EINVAL;
+       if (IS_ERR(versions))
+               return PTR_ERR(versions);
        if (strcmp(versions, "1")) {
                kfree(versions);
                return -EINVAL;
diff --git a/net/9p/util.c b/net/9p/util.c
deleted file mode 100644 (file)
index 55ad982..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *  net/9p/util.c
- *
- *  This file contains some helper functions
- *
- *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
- *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
- *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2
- *  as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to:
- *  Free Software Foundation
- *  51 Franklin Street, Fifth Floor
- *  Boston, MA  02111-1301  USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/parser.h>
-#include <linux/idr.h>
-#include <linux/slab.h>
-#include <net/9p/9p.h>
-
-/**
- * struct p9_idpool - per-connection accounting for tag idpool
- * @lock: protects the pool
- * @pool: idr to allocate tag id from
- *
- */
-
-struct p9_idpool {
-       spinlock_t lock;
-       struct idr pool;
-};
-
-/**
- * p9_idpool_create - create a new per-connection id pool
- *
- */
-
-struct p9_idpool *p9_idpool_create(void)
-{
-       struct p9_idpool *p;
-
-       p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
-       if (!p)
-               return ERR_PTR(-ENOMEM);
-
-       spin_lock_init(&p->lock);
-       idr_init(&p->pool);
-
-       return p;
-}
-EXPORT_SYMBOL(p9_idpool_create);
-
-/**
- * p9_idpool_destroy - create a new per-connection id pool
- * @p: idpool to destroy
- */
-
-void p9_idpool_destroy(struct p9_idpool *p)
-{
-       idr_destroy(&p->pool);
-       kfree(p);
-}
-EXPORT_SYMBOL(p9_idpool_destroy);
-
-/**
- * p9_idpool_get - allocate numeric id from pool
- * @p: pool to allocate from
- *
- * Bugs: This seems to be an awful generic function, should it be in idr.c with
- *            the lock included in struct idr?
- */
-
-int p9_idpool_get(struct p9_idpool *p)
-{
-       int i;
-       unsigned long flags;
-
-       idr_preload(GFP_NOFS);
-       spin_lock_irqsave(&p->lock, flags);
-
-       /* no need to store exactly p, we just need something non-null */
-       i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
-
-       spin_unlock_irqrestore(&p->lock, flags);
-       idr_preload_end();
-       if (i < 0)
-               return -1;
-
-       p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
-       return i;
-}
-EXPORT_SYMBOL(p9_idpool_get);
-
-/**
- * p9_idpool_put - release numeric id from pool
- * @id: numeric id which is being released
- * @p: pool to release id into
- *
- * Bugs: This seems to be an awful generic function, should it be in idr.c with
- *            the lock included in struct idr?
- */
-
-void p9_idpool_put(int id, struct p9_idpool *p)
-{
-       unsigned long flags;
-
-       p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
-
-       spin_lock_irqsave(&p->lock, flags);
-       idr_remove(&p->pool, id);
-       spin_unlock_irqrestore(&p->lock, flags);
-}
-EXPORT_SYMBOL(p9_idpool_put);
-
-/**
- * p9_idpool_check - check if the specified id is available
- * @id: id to check
- * @p: pool to check
- */
-
-int p9_idpool_check(int id, struct p9_idpool *p)
-{
-       return idr_find(&p->pool, id) != NULL;
-}
-EXPORT_SYMBOL(p9_idpool_check);
index 0a187196aeede6375b817a102890f024b552bc3f..88e35830198cd3ed47b6655c6e31b783bddaf030 100644 (file)
@@ -156,7 +156,6 @@ static bool con_flag_test_and_set(struct ceph_connection *con,
 /* Slab caches for frequently-allocated structures */
 
 static struct kmem_cache       *ceph_msg_cache;
-static struct kmem_cache       *ceph_msg_data_cache;
 
 /* static tag bytes (protocol control messages) */
 static char tag_msg = CEPH_MSGR_TAG_MSG;
@@ -235,23 +234,11 @@ static int ceph_msgr_slab_init(void)
        if (!ceph_msg_cache)
                return -ENOMEM;
 
-       BUG_ON(ceph_msg_data_cache);
-       ceph_msg_data_cache = KMEM_CACHE(ceph_msg_data, 0);
-       if (ceph_msg_data_cache)
-               return 0;
-
-       kmem_cache_destroy(ceph_msg_cache);
-       ceph_msg_cache = NULL;
-
-       return -ENOMEM;
+       return 0;
 }
 
 static void ceph_msgr_slab_exit(void)
 {
-       BUG_ON(!ceph_msg_data_cache);
-       kmem_cache_destroy(ceph_msg_data_cache);
-       ceph_msg_data_cache = NULL;
-
        BUG_ON(!ceph_msg_cache);
        kmem_cache_destroy(ceph_msg_cache);
        ceph_msg_cache = NULL;
@@ -1141,16 +1128,13 @@ static void __ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor)
 static void ceph_msg_data_cursor_init(struct ceph_msg *msg, size_t length)
 {
        struct ceph_msg_data_cursor *cursor = &msg->cursor;
-       struct ceph_msg_data *data;
 
        BUG_ON(!length);
        BUG_ON(length > msg->data_length);
-       BUG_ON(list_empty(&msg->data));
+       BUG_ON(!msg->num_data_items);
 
-       cursor->data_head = &msg->data;
        cursor->total_resid = length;
-       data = list_first_entry(&msg->data, struct ceph_msg_data, links);
-       cursor->data = data;
+       cursor->data = msg->data;
 
        __ceph_msg_data_cursor_init(cursor);
 }
@@ -1231,8 +1215,7 @@ static void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor,
 
        if (!cursor->resid && cursor->total_resid) {
                WARN_ON(!cursor->last_piece);
-               BUG_ON(list_is_last(&cursor->data->links, cursor->data_head));
-               cursor->data = list_next_entry(cursor->data, links);
+               cursor->data++;
                __ceph_msg_data_cursor_init(cursor);
                new_piece = true;
        }
@@ -1248,9 +1231,6 @@ static size_t sizeof_footer(struct ceph_connection *con)
 
 static void prepare_message_data(struct ceph_msg *msg, u32 data_len)
 {
-       BUG_ON(!msg);
-       BUG_ON(!data_len);
-
        /* Initialize data cursor */
 
        ceph_msg_data_cursor_init(msg, (size_t)data_len);
@@ -1590,7 +1570,7 @@ static int write_partial_message_data(struct ceph_connection *con)
 
        dout("%s %p msg %p\n", __func__, con, msg);
 
-       if (list_empty(&msg->data))
+       if (!msg->num_data_items)
                return -EINVAL;
 
        /*
@@ -2347,8 +2327,7 @@ static int read_partial_msg_data(struct ceph_connection *con)
        u32 crc = 0;
        int ret;
 
-       BUG_ON(!msg);
-       if (list_empty(&msg->data))
+       if (!msg->num_data_items)
                return -EIO;
 
        if (do_datacrc)
@@ -3256,32 +3235,16 @@ bool ceph_con_keepalive_expired(struct ceph_connection *con,
        return false;
 }
 
-static struct ceph_msg_data *ceph_msg_data_create(enum ceph_msg_data_type type)
+static struct ceph_msg_data *ceph_msg_data_add(struct ceph_msg *msg)
 {
-       struct ceph_msg_data *data;
-
-       if (WARN_ON(!ceph_msg_data_type_valid(type)))
-               return NULL;
-
-       data = kmem_cache_zalloc(ceph_msg_data_cache, GFP_NOFS);
-       if (!data)
-               return NULL;
-
-       data->type = type;
-       INIT_LIST_HEAD(&data->links);
-
-       return data;
+       BUG_ON(msg->num_data_items >= msg->max_data_items);
+       return &msg->data[msg->num_data_items++];
 }
 
 static void ceph_msg_data_destroy(struct ceph_msg_data *data)
 {
-       if (!data)
-               return;
-
-       WARN_ON(!list_empty(&data->links));
        if (data->type == CEPH_MSG_DATA_PAGELIST)
                ceph_pagelist_release(data->pagelist);
-       kmem_cache_free(ceph_msg_data_cache, data);
 }
 
 void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
@@ -3292,13 +3255,12 @@ void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
        BUG_ON(!pages);
        BUG_ON(!length);
 
-       data = ceph_msg_data_create(CEPH_MSG_DATA_PAGES);
-       BUG_ON(!data);
+       data = ceph_msg_data_add(msg);
+       data->type = CEPH_MSG_DATA_PAGES;
        data->pages = pages;
        data->length = length;
        data->alignment = alignment & ~PAGE_MASK;
 
-       list_add_tail(&data->links, &msg->data);
        msg->data_length += length;
 }
 EXPORT_SYMBOL(ceph_msg_data_add_pages);
@@ -3311,11 +3273,11 @@ void ceph_msg_data_add_pagelist(struct ceph_msg *msg,
        BUG_ON(!pagelist);
        BUG_ON(!pagelist->length);
 
-       data = ceph_msg_data_create(CEPH_MSG_DATA_PAGELIST);
-       BUG_ON(!data);
+       data = ceph_msg_data_add(msg);
+       data->type = CEPH_MSG_DATA_PAGELIST;
+       refcount_inc(&pagelist->refcnt);
        data->pagelist = pagelist;
 
-       list_add_tail(&data->links, &msg->data);
        msg->data_length += pagelist->length;
 }
 EXPORT_SYMBOL(ceph_msg_data_add_pagelist);
@@ -3326,12 +3288,11 @@ void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos,
 {
        struct ceph_msg_data *data;
 
-       data = ceph_msg_data_create(CEPH_MSG_DATA_BIO);
-       BUG_ON(!data);
+       data = ceph_msg_data_add(msg);
+       data->type = CEPH_MSG_DATA_BIO;
        data->bio_pos = *bio_pos;
        data->bio_length = length;
 
-       list_add_tail(&data->links, &msg->data);
        msg->data_length += length;
 }
 EXPORT_SYMBOL(ceph_msg_data_add_bio);
@@ -3342,11 +3303,10 @@ void ceph_msg_data_add_bvecs(struct ceph_msg *msg,
 {
        struct ceph_msg_data *data;
 
-       data = ceph_msg_data_create(CEPH_MSG_DATA_BVECS);
-       BUG_ON(!data);
+       data = ceph_msg_data_add(msg);
+       data->type = CEPH_MSG_DATA_BVECS;
        data->bvec_pos = *bvec_pos;
 
-       list_add_tail(&data->links, &msg->data);
        msg->data_length += bvec_pos->iter.bi_size;
 }
 EXPORT_SYMBOL(ceph_msg_data_add_bvecs);
@@ -3355,8 +3315,8 @@ EXPORT_SYMBOL(ceph_msg_data_add_bvecs);
  * construct a new message with given type, size
  * the new msg has a ref count of 1.
  */
-struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
-                             bool can_fail)
+struct ceph_msg *ceph_msg_new2(int type, int front_len, int max_data_items,
+                              gfp_t flags, bool can_fail)
 {
        struct ceph_msg *m;
 
@@ -3370,7 +3330,6 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
 
        INIT_LIST_HEAD(&m->list_head);
        kref_init(&m->kref);
-       INIT_LIST_HEAD(&m->data);
 
        /* front */
        if (front_len) {
@@ -3385,6 +3344,15 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
        }
        m->front_alloc_len = m->front.iov_len = front_len;
 
+       if (max_data_items) {
+               m->data = kmalloc_array(max_data_items, sizeof(*m->data),
+                                       flags);
+               if (!m->data)
+                       goto out2;
+
+               m->max_data_items = max_data_items;
+       }
+
        dout("ceph_msg_new %p front %d\n", m, front_len);
        return m;
 
@@ -3401,6 +3369,13 @@ out:
        }
        return NULL;
 }
+EXPORT_SYMBOL(ceph_msg_new2);
+
+struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
+                             bool can_fail)
+{
+       return ceph_msg_new2(type, front_len, 0, flags, can_fail);
+}
 EXPORT_SYMBOL(ceph_msg_new);
 
 /*
@@ -3496,13 +3471,14 @@ static void ceph_msg_free(struct ceph_msg *m)
 {
        dout("%s %p\n", __func__, m);
        kvfree(m->front.iov_base);
+       kfree(m->data);
        kmem_cache_free(ceph_msg_cache, m);
 }
 
 static void ceph_msg_release(struct kref *kref)
 {
        struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);
-       struct ceph_msg_data *data, *next;
+       int i;
 
        dout("%s %p\n", __func__, m);
        WARN_ON(!list_empty(&m->list_head));
@@ -3515,11 +3491,8 @@ static void ceph_msg_release(struct kref *kref)
                m->middle = NULL;
        }
 
-       list_for_each_entry_safe(data, next, &m->data, links) {
-               list_del_init(&data->links);
-               ceph_msg_data_destroy(data);
-       }
-       m->data_length = 0;
+       for (i = 0; i < m->num_data_items; i++)
+               ceph_msg_data_destroy(&m->data[i]);
 
        if (m->pool)
                ceph_msgpool_put(m->pool, m);
index 72571535883fdd15d43bcb9628bb858bd5cc713d..e3ecb80cd18216347d17c5e109d311febd20b770 100644 (file)
@@ -14,7 +14,8 @@ static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
        struct ceph_msgpool *pool = arg;
        struct ceph_msg *msg;
 
-       msg = ceph_msg_new(pool->type, pool->front_len, gfp_mask, true);
+       msg = ceph_msg_new2(pool->type, pool->front_len, pool->max_data_items,
+                           gfp_mask, true);
        if (!msg) {
                dout("msgpool_alloc %s failed\n", pool->name);
        } else {
@@ -35,11 +36,13 @@ static void msgpool_free(void *element, void *arg)
 }
 
 int ceph_msgpool_init(struct ceph_msgpool *pool, int type,
-                     int front_len, int size, bool blocking, const char *name)
+                     int front_len, int max_data_items, int size,
+                     const char *name)
 {
        dout("msgpool %s init\n", name);
        pool->type = type;
        pool->front_len = front_len;
+       pool->max_data_items = max_data_items;
        pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool);
        if (!pool->pool)
                return -ENOMEM;
@@ -53,18 +56,21 @@ void ceph_msgpool_destroy(struct ceph_msgpool *pool)
        mempool_destroy(pool->pool);
 }
 
-struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool,
-                                 int front_len)
+struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len,
+                                 int max_data_items)
 {
        struct ceph_msg *msg;
 
-       if (front_len > pool->front_len) {
-               dout("msgpool_get %s need front %d, pool size is %d\n",
-                      pool->name, front_len, pool->front_len);
-               WARN_ON(1);
+       if (front_len > pool->front_len ||
+           max_data_items > pool->max_data_items) {
+               pr_warn_ratelimited("%s need %d/%d, pool %s has %d/%d\n",
+                   __func__, front_len, max_data_items, pool->name,
+                   pool->front_len, pool->max_data_items);
+               WARN_ON_ONCE(1);
 
                /* try to alloc a fresh message */
-               return ceph_msg_new(pool->type, front_len, GFP_NOFS, false);
+               return ceph_msg_new2(pool->type, front_len, max_data_items,
+                                    GFP_NOFS, false);
        }
 
        msg = mempool_alloc(pool->pool, GFP_NOFS);
@@ -80,6 +86,9 @@ void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
        msg->front.iov_len = pool->front_len;
        msg->hdr.front_len = cpu_to_le32(pool->front_len);
 
+       msg->data_length = 0;
+       msg->num_data_items = 0;
+
        kref_init(&msg->kref);  /* retake single ref */
        mempool_free(msg, pool->pool);
 }
index 60934bd8796c53c5ec96477e1c29fb9e8234e804..d23a9f81f3d784123f0f97aaba1b529081350fae 100644 (file)
@@ -126,6 +126,9 @@ static void ceph_osd_data_init(struct ceph_osd_data *osd_data)
        osd_data->type = CEPH_OSD_DATA_TYPE_NONE;
 }
 
+/*
+ * Consumes @pages if @own_pages is true.
+ */
 static void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data,
                        struct page **pages, u64 length, u32 alignment,
                        bool pages_from_pool, bool own_pages)
@@ -138,6 +141,9 @@ static void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data,
        osd_data->own_pages = own_pages;
 }
 
+/*
+ * Consumes a ref on @pagelist.
+ */
 static void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data,
                        struct ceph_pagelist *pagelist)
 {
@@ -362,6 +368,8 @@ static void ceph_osd_data_release(struct ceph_osd_data *osd_data)
                num_pages = calc_pages_for((u64)osd_data->alignment,
                                                (u64)osd_data->length);
                ceph_release_page_vector(osd_data->pages, num_pages);
+       } else if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGELIST) {
+               ceph_pagelist_release(osd_data->pagelist);
        }
        ceph_osd_data_init(osd_data);
 }
@@ -402,6 +410,9 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
        case CEPH_OSD_OP_LIST_WATCHERS:
                ceph_osd_data_release(&op->list_watchers.response_data);
                break;
+       case CEPH_OSD_OP_COPY_FROM:
+               ceph_osd_data_release(&op->copy_from.osd_data);
+               break;
        default:
                break;
        }
@@ -606,12 +617,15 @@ static int ceph_oloc_encoding_size(const struct ceph_object_locator *oloc)
        return 8 + 4 + 4 + 4 + (oloc->pool_ns ? oloc->pool_ns->len : 0);
 }
 
-int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
+static int __ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp,
+                                     int num_request_data_items,
+                                     int num_reply_data_items)
 {
        struct ceph_osd_client *osdc = req->r_osdc;
        struct ceph_msg *msg;
        int msg_size;
 
+       WARN_ON(req->r_request || req->r_reply);
        WARN_ON(ceph_oid_empty(&req->r_base_oid));
        WARN_ON(ceph_oloc_empty(&req->r_base_oloc));
 
@@ -633,9 +647,11 @@ int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
        msg_size += 4 + 8; /* retry_attempt, features */
 
        if (req->r_mempool)
-               msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
+               msg = ceph_msgpool_get(&osdc->msgpool_op, msg_size,
+                                      num_request_data_items);
        else
-               msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp, true);
+               msg = ceph_msg_new2(CEPH_MSG_OSD_OP, msg_size,
+                                   num_request_data_items, gfp, true);
        if (!msg)
                return -ENOMEM;
 
@@ -648,9 +664,11 @@ int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
        msg_size += req->r_num_ops * sizeof(struct ceph_osd_op);
 
        if (req->r_mempool)
-               msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
+               msg = ceph_msgpool_get(&osdc->msgpool_op_reply, msg_size,
+                                      num_reply_data_items);
        else
-               msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, msg_size, gfp, true);
+               msg = ceph_msg_new2(CEPH_MSG_OSD_OPREPLY, msg_size,
+                                   num_reply_data_items, gfp, true);
        if (!msg)
                return -ENOMEM;
 
@@ -658,7 +676,6 @@ int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
 
        return 0;
 }
-EXPORT_SYMBOL(ceph_osdc_alloc_messages);
 
 static bool osd_req_opcode_valid(u16 opcode)
 {
@@ -671,6 +688,65 @@ __CEPH_FORALL_OSD_OPS(GENERATE_CASE)
        }
 }
 
+static void get_num_data_items(struct ceph_osd_request *req,
+                              int *num_request_data_items,
+                              int *num_reply_data_items)
+{
+       struct ceph_osd_req_op *op;
+
+       *num_request_data_items = 0;
+       *num_reply_data_items = 0;
+
+       for (op = req->r_ops; op != &req->r_ops[req->r_num_ops]; op++) {
+               switch (op->op) {
+               /* request */
+               case CEPH_OSD_OP_WRITE:
+               case CEPH_OSD_OP_WRITEFULL:
+               case CEPH_OSD_OP_SETXATTR:
+               case CEPH_OSD_OP_CMPXATTR:
+               case CEPH_OSD_OP_NOTIFY_ACK:
+               case CEPH_OSD_OP_COPY_FROM:
+                       *num_request_data_items += 1;
+                       break;
+
+               /* reply */
+               case CEPH_OSD_OP_STAT:
+               case CEPH_OSD_OP_READ:
+               case CEPH_OSD_OP_LIST_WATCHERS:
+                       *num_reply_data_items += 1;
+                       break;
+
+               /* both */
+               case CEPH_OSD_OP_NOTIFY:
+                       *num_request_data_items += 1;
+                       *num_reply_data_items += 1;
+                       break;
+               case CEPH_OSD_OP_CALL:
+                       *num_request_data_items += 2;
+                       *num_reply_data_items += 1;
+                       break;
+
+               default:
+                       WARN_ON(!osd_req_opcode_valid(op->op));
+                       break;
+               }
+       }
+}
+
+/*
+ * oid, oloc and OSD op opcode(s) must be filled in before this function
+ * is called.
+ */
+int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
+{
+       int num_request_data_items, num_reply_data_items;
+
+       get_num_data_items(req, &num_request_data_items, &num_reply_data_items);
+       return __ceph_osdc_alloc_messages(req, gfp, num_request_data_items,
+                                         num_reply_data_items);
+}
+EXPORT_SYMBOL(ceph_osdc_alloc_messages);
+
 /*
  * This is an osd op init function for opcodes that have no data or
  * other information associated with them.  It also serves as a
@@ -767,22 +843,19 @@ void osd_req_op_extent_dup_last(struct ceph_osd_request *osd_req,
 EXPORT_SYMBOL(osd_req_op_extent_dup_last);
 
 int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which,
-                       u16 opcode, const char *class, const char *method)
+                       const char *class, const char *method)
 {
-       struct ceph_osd_req_op *op = _osd_req_op_init(osd_req, which,
-                                                     opcode, 0);
+       struct ceph_osd_req_op *op;
        struct ceph_pagelist *pagelist;
        size_t payload_len = 0;
        size_t size;
 
-       BUG_ON(opcode != CEPH_OSD_OP_CALL);
+       op = _osd_req_op_init(osd_req, which, CEPH_OSD_OP_CALL, 0);
 
-       pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS);
+       pagelist = ceph_pagelist_alloc(GFP_NOFS);
        if (!pagelist)
                return -ENOMEM;
 
-       ceph_pagelist_init(pagelist);
-
        op->cls.class_name = class;
        size = strlen(class);
        BUG_ON(size > (size_t) U8_MAX);
@@ -815,12 +888,10 @@ int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which,
 
        BUG_ON(opcode != CEPH_OSD_OP_SETXATTR && opcode != CEPH_OSD_OP_CMPXATTR);
 
-       pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+       pagelist = ceph_pagelist_alloc(GFP_NOFS);
        if (!pagelist)
                return -ENOMEM;
 
-       ceph_pagelist_init(pagelist);
-
        payload_len = strlen(name);
        op->xattr.name_len = payload_len;
        ceph_pagelist_append(pagelist, name, payload_len);
@@ -900,12 +971,6 @@ static void ceph_osdc_msg_data_add(struct ceph_msg *msg,
 static u32 osd_req_encode_op(struct ceph_osd_op *dst,
                             const struct ceph_osd_req_op *src)
 {
-       if (WARN_ON(!osd_req_opcode_valid(src->op))) {
-               pr_err("unrecognized osd opcode %d\n", src->op);
-
-               return 0;
-       }
-
        switch (src->op) {
        case CEPH_OSD_OP_STAT:
                break;
@@ -955,6 +1020,14 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst,
        case CEPH_OSD_OP_CREATE:
        case CEPH_OSD_OP_DELETE:
                break;
+       case CEPH_OSD_OP_COPY_FROM:
+               dst->copy_from.snapid = cpu_to_le64(src->copy_from.snapid);
+               dst->copy_from.src_version =
+                       cpu_to_le64(src->copy_from.src_version);
+               dst->copy_from.flags = src->copy_from.flags;
+               dst->copy_from.src_fadvise_flags =
+                       cpu_to_le32(src->copy_from.src_fadvise_flags);
+               break;
        default:
                pr_err("unsupported osd opcode %s\n",
                        ceph_osd_op_name(src->op));
@@ -1038,7 +1111,15 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
        if (flags & CEPH_OSD_FLAG_WRITE)
                req->r_data_offset = off;
 
-       r = ceph_osdc_alloc_messages(req, GFP_NOFS);
+       if (num_ops > 1)
+               /*
+                * This is a special case for ceph_writepages_start(), but it
+                * also covers ceph_uninline_data().  If more multi-op request
+                * use cases emerge, we will need a separate helper.
+                */
+               r = __ceph_osdc_alloc_messages(req, GFP_NOFS, num_ops, 0);
+       else
+               r = ceph_osdc_alloc_messages(req, GFP_NOFS);
        if (r)
                goto fail;
 
@@ -1845,48 +1926,55 @@ static bool should_plug_request(struct ceph_osd_request *req)
        return true;
 }
 
-static void setup_request_data(struct ceph_osd_request *req,
-                              struct ceph_msg *msg)
+/*
+ * Keep get_num_data_items() in sync with this function.
+ */
+static void setup_request_data(struct ceph_osd_request *req)
 {
-       u32 data_len = 0;
-       int i;
+       struct ceph_msg *request_msg = req->r_request;
+       struct ceph_msg *reply_msg = req->r_reply;
+       struct ceph_osd_req_op *op;
 
-       if (!list_empty(&msg->data))
+       if (req->r_request->num_data_items || req->r_reply->num_data_items)
                return;
 
-       WARN_ON(msg->data_length);
-       for (i = 0; i < req->r_num_ops; i++) {
-               struct ceph_osd_req_op *op = &req->r_ops[i];
-
+       WARN_ON(request_msg->data_length || reply_msg->data_length);
+       for (op = req->r_ops; op != &req->r_ops[req->r_num_ops]; op++) {
                switch (op->op) {
                /* request */
                case CEPH_OSD_OP_WRITE:
                case CEPH_OSD_OP_WRITEFULL:
                        WARN_ON(op->indata_len != op->extent.length);
-                       ceph_osdc_msg_data_add(msg, &op->extent.osd_data);
+                       ceph_osdc_msg_data_add(request_msg,
+                                              &op->extent.osd_data);
                        break;
                case CEPH_OSD_OP_SETXATTR:
                case CEPH_OSD_OP_CMPXATTR:
                        WARN_ON(op->indata_len != op->xattr.name_len +
                                                  op->xattr.value_len);
-                       ceph_osdc_msg_data_add(msg, &op->xattr.osd_data);
+                       ceph_osdc_msg_data_add(request_msg,
+                                              &op->xattr.osd_data);
                        break;
                case CEPH_OSD_OP_NOTIFY_ACK:
-                       ceph_osdc_msg_data_add(msg,
+                       ceph_osdc_msg_data_add(request_msg,
                                               &op->notify_ack.request_data);
                        break;
+               case CEPH_OSD_OP_COPY_FROM:
+                       ceph_osdc_msg_data_add(request_msg,
+                                              &op->copy_from.osd_data);
+                       break;
 
                /* reply */
                case CEPH_OSD_OP_STAT:
-                       ceph_osdc_msg_data_add(req->r_reply,
+                       ceph_osdc_msg_data_add(reply_msg,
                                               &op->raw_data_in);
                        break;
                case CEPH_OSD_OP_READ:
-                       ceph_osdc_msg_data_add(req->r_reply,
+                       ceph_osdc_msg_data_add(reply_msg,
                                               &op->extent.osd_data);
                        break;
                case CEPH_OSD_OP_LIST_WATCHERS:
-                       ceph_osdc_msg_data_add(req->r_reply,
+                       ceph_osdc_msg_data_add(reply_msg,
                                               &op->list_watchers.response_data);
                        break;
 
@@ -1895,25 +1983,23 @@ static void setup_request_data(struct ceph_osd_request *req,
                        WARN_ON(op->indata_len != op->cls.class_len +
                                                  op->cls.method_len +
                                                  op->cls.indata_len);
-                       ceph_osdc_msg_data_add(msg, &op->cls.request_info);
+                       ceph_osdc_msg_data_add(request_msg,
+                                              &op->cls.request_info);
                        /* optional, can be NONE */
-                       ceph_osdc_msg_data_add(msg, &op->cls.request_data);
+                       ceph_osdc_msg_data_add(request_msg,
+                                              &op->cls.request_data);
                        /* optional, can be NONE */
-                       ceph_osdc_msg_data_add(req->r_reply,
+                       ceph_osdc_msg_data_add(reply_msg,
                                               &op->cls.response_data);
                        break;
                case CEPH_OSD_OP_NOTIFY:
-                       ceph_osdc_msg_data_add(msg,
+                       ceph_osdc_msg_data_add(request_msg,
                                               &op->notify.request_data);
-                       ceph_osdc_msg_data_add(req->r_reply,
+                       ceph_osdc_msg_data_add(reply_msg,
                                               &op->notify.response_data);
                        break;
                }
-
-               data_len += op->indata_len;
        }
-
-       WARN_ON(data_len != msg->data_length);
 }
 
 static void encode_pgid(void **p, const struct ceph_pg *pgid)
@@ -1961,7 +2047,7 @@ static void encode_request_partial(struct ceph_osd_request *req,
                        req->r_data_offset || req->r_snapc);
        }
 
-       setup_request_data(req, msg);
+       setup_request_data(req);
 
        encode_spgid(&p, &req->r_t.spgid); /* actual spg */
        ceph_encode_32(&p, req->r_t.pgid.seed); /* raw hash */
@@ -3001,11 +3087,21 @@ static void linger_submit(struct ceph_osd_linger_request *lreq)
        struct ceph_osd_client *osdc = lreq->osdc;
        struct ceph_osd *osd;
 
+       down_write(&osdc->lock);
+       linger_register(lreq);
+       if (lreq->is_watch) {
+               lreq->reg_req->r_ops[0].watch.cookie = lreq->linger_id;
+               lreq->ping_req->r_ops[0].watch.cookie = lreq->linger_id;
+       } else {
+               lreq->reg_req->r_ops[0].notify.cookie = lreq->linger_id;
+       }
+
        calc_target(osdc, &lreq->t, NULL, false);
        osd = lookup_create_osd(osdc, lreq->t.osd, true);
        link_linger(osd, lreq);
 
        send_linger(lreq);
+       up_write(&osdc->lock);
 }
 
 static void cancel_linger_map_check(struct ceph_osd_linger_request *lreq)
@@ -4318,9 +4414,7 @@ static void handle_watch_notify(struct ceph_osd_client *osdc,
                             lreq->notify_id, notify_id);
                } else if (!completion_done(&lreq->notify_finish_wait)) {
                        struct ceph_msg_data *data =
-                           list_first_entry_or_null(&msg->data,
-                                                    struct ceph_msg_data,
-                                                    links);
+                           msg->num_data_items ? &msg->data[0] : NULL;
 
                        if (data) {
                                if (lreq->preply_pages) {
@@ -4476,6 +4570,23 @@ alloc_linger_request(struct ceph_osd_linger_request *lreq)
 
        ceph_oid_copy(&req->r_base_oid, &lreq->t.base_oid);
        ceph_oloc_copy(&req->r_base_oloc, &lreq->t.base_oloc);
+       return req;
+}
+
+static struct ceph_osd_request *
+alloc_watch_request(struct ceph_osd_linger_request *lreq, u8 watch_opcode)
+{
+       struct ceph_osd_request *req;
+
+       req = alloc_linger_request(lreq);
+       if (!req)
+               return NULL;
+
+       /*
+        * Pass 0 for cookie because we don't know it yet, it will be
+        * filled in by linger_submit().
+        */
+       osd_req_op_watch_init(req, 0, 0, watch_opcode);
 
        if (ceph_osdc_alloc_messages(req, GFP_NOIO)) {
                ceph_osdc_put_request(req);
@@ -4514,27 +4625,19 @@ ceph_osdc_watch(struct ceph_osd_client *osdc,
        lreq->t.flags = CEPH_OSD_FLAG_WRITE;
        ktime_get_real_ts64(&lreq->mtime);
 
-       lreq->reg_req = alloc_linger_request(lreq);
+       lreq->reg_req = alloc_watch_request(lreq, CEPH_OSD_WATCH_OP_WATCH);
        if (!lreq->reg_req) {
                ret = -ENOMEM;
                goto err_put_lreq;
        }
 
-       lreq->ping_req = alloc_linger_request(lreq);
+       lreq->ping_req = alloc_watch_request(lreq, CEPH_OSD_WATCH_OP_PING);
        if (!lreq->ping_req) {
                ret = -ENOMEM;
                goto err_put_lreq;
        }
 
-       down_write(&osdc->lock);
-       linger_register(lreq); /* before osd_req_op_* */
-       osd_req_op_watch_init(lreq->reg_req, 0, lreq->linger_id,
-                             CEPH_OSD_WATCH_OP_WATCH);
-       osd_req_op_watch_init(lreq->ping_req, 0, lreq->linger_id,
-                             CEPH_OSD_WATCH_OP_PING);
        linger_submit(lreq);
-       up_write(&osdc->lock);
-
        ret = linger_reg_commit_wait(lreq);
        if (ret) {
                linger_cancel(lreq);
@@ -4599,11 +4702,10 @@ static int osd_req_op_notify_ack_init(struct ceph_osd_request *req, int which,
 
        op = _osd_req_op_init(req, which, CEPH_OSD_OP_NOTIFY_ACK, 0);
 
-       pl = kmalloc(sizeof(*pl), GFP_NOIO);
+       pl = ceph_pagelist_alloc(GFP_NOIO);
        if (!pl)
                return -ENOMEM;
 
-       ceph_pagelist_init(pl);
        ret = ceph_pagelist_encode_64(pl, notify_id);
        ret |= ceph_pagelist_encode_64(pl, cookie);
        if (payload) {
@@ -4641,12 +4743,12 @@ int ceph_osdc_notify_ack(struct ceph_osd_client *osdc,
        ceph_oloc_copy(&req->r_base_oloc, oloc);
        req->r_flags = CEPH_OSD_FLAG_READ;
 
-       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
+       ret = osd_req_op_notify_ack_init(req, 0, notify_id, cookie, payload,
+                                        payload_len);
        if (ret)
                goto out_put_req;
 
-       ret = osd_req_op_notify_ack_init(req, 0, notify_id, cookie, payload,
-                                        payload_len);
+       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
        if (ret)
                goto out_put_req;
 
@@ -4670,11 +4772,10 @@ static int osd_req_op_notify_init(struct ceph_osd_request *req, int which,
        op = _osd_req_op_init(req, which, CEPH_OSD_OP_NOTIFY, 0);
        op->notify.cookie = cookie;
 
-       pl = kmalloc(sizeof(*pl), GFP_NOIO);
+       pl = ceph_pagelist_alloc(GFP_NOIO);
        if (!pl)
                return -ENOMEM;
 
-       ceph_pagelist_init(pl);
        ret = ceph_pagelist_encode_32(pl, 1); /* prot_ver */
        ret |= ceph_pagelist_encode_32(pl, timeout);
        ret |= ceph_pagelist_encode_32(pl, payload_len);
@@ -4733,29 +4834,30 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc,
                goto out_put_lreq;
        }
 
+       /*
+        * Pass 0 for cookie because we don't know it yet, it will be
+        * filled in by linger_submit().
+        */
+       ret = osd_req_op_notify_init(lreq->reg_req, 0, 0, 1, timeout,
+                                    payload, payload_len);
+       if (ret)
+               goto out_put_lreq;
+
        /* for notify_id */
        pages = ceph_alloc_page_vector(1, GFP_NOIO);
        if (IS_ERR(pages)) {
                ret = PTR_ERR(pages);
                goto out_put_lreq;
        }
-
-       down_write(&osdc->lock);
-       linger_register(lreq); /* before osd_req_op_* */
-       ret = osd_req_op_notify_init(lreq->reg_req, 0, lreq->linger_id, 1,
-                                    timeout, payload, payload_len);
-       if (ret) {
-               linger_unregister(lreq);
-               up_write(&osdc->lock);
-               ceph_release_page_vector(pages, 1);
-               goto out_put_lreq;
-       }
        ceph_osd_data_pages_init(osd_req_op_data(lreq->reg_req, 0, notify,
                                                 response_data),
                                 pages, PAGE_SIZE, 0, false, true);
-       linger_submit(lreq);
-       up_write(&osdc->lock);
 
+       ret = ceph_osdc_alloc_messages(lreq->reg_req, GFP_NOIO);
+       if (ret)
+               goto out_put_lreq;
+
+       linger_submit(lreq);
        ret = linger_reg_commit_wait(lreq);
        if (!ret)
                ret = linger_notify_finish_wait(lreq);
@@ -4881,10 +4983,6 @@ int ceph_osdc_list_watchers(struct ceph_osd_client *osdc,
        ceph_oloc_copy(&req->r_base_oloc, oloc);
        req->r_flags = CEPH_OSD_FLAG_READ;
 
-       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
-       if (ret)
-               goto out_put_req;
-
        pages = ceph_alloc_page_vector(1, GFP_NOIO);
        if (IS_ERR(pages)) {
                ret = PTR_ERR(pages);
@@ -4896,6 +4994,10 @@ int ceph_osdc_list_watchers(struct ceph_osd_client *osdc,
                                                 response_data),
                                 pages, PAGE_SIZE, 0, false, true);
 
+       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
+       if (ret)
+               goto out_put_req;
+
        ceph_osdc_start_request(osdc, req, false);
        ret = ceph_osdc_wait_request(osdc, req);
        if (ret >= 0) {
@@ -4958,11 +5060,7 @@ int ceph_osdc_call(struct ceph_osd_client *osdc,
        ceph_oloc_copy(&req->r_base_oloc, oloc);
        req->r_flags = flags;
 
-       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
-       if (ret)
-               goto out_put_req;
-
-       ret = osd_req_op_cls_init(req, 0, CEPH_OSD_OP_CALL, class, method);
+       ret = osd_req_op_cls_init(req, 0, class, method);
        if (ret)
                goto out_put_req;
 
@@ -4973,6 +5071,10 @@ int ceph_osdc_call(struct ceph_osd_client *osdc,
                osd_req_op_cls_response_data_pages(req, 0, &resp_page,
                                                   *resp_len, 0, false, false);
 
+       ret = ceph_osdc_alloc_messages(req, GFP_NOIO);
+       if (ret)
+               goto out_put_req;
+
        ceph_osdc_start_request(osdc, req, false);
        ret = ceph_osdc_wait_request(osdc, req);
        if (ret >= 0) {
@@ -5021,11 +5123,12 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
                goto out_map;
 
        err = ceph_msgpool_init(&osdc->msgpool_op, CEPH_MSG_OSD_OP,
-                               PAGE_SIZE, 10, true, "osd_op");
+                               PAGE_SIZE, CEPH_OSD_SLAB_OPS, 10, "osd_op");
        if (err < 0)
                goto out_mempool;
        err = ceph_msgpool_init(&osdc->msgpool_op_reply, CEPH_MSG_OSD_OPREPLY,
-                               PAGE_SIZE, 10, true, "osd_op_reply");
+                               PAGE_SIZE, CEPH_OSD_SLAB_OPS, 10,
+                               "osd_op_reply");
        if (err < 0)
                goto out_msgpool;
 
@@ -5168,6 +5271,80 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
 }
 EXPORT_SYMBOL(ceph_osdc_writepages);
 
+static int osd_req_op_copy_from_init(struct ceph_osd_request *req,
+                                    u64 src_snapid, u64 src_version,
+                                    struct ceph_object_id *src_oid,
+                                    struct ceph_object_locator *src_oloc,
+                                    u32 src_fadvise_flags,
+                                    u32 dst_fadvise_flags,
+                                    u8 copy_from_flags)
+{
+       struct ceph_osd_req_op *op;
+       struct page **pages;
+       void *p, *end;
+
+       pages = ceph_alloc_page_vector(1, GFP_KERNEL);
+       if (IS_ERR(pages))
+               return PTR_ERR(pages);
+
+       op = _osd_req_op_init(req, 0, CEPH_OSD_OP_COPY_FROM, dst_fadvise_flags);
+       op->copy_from.snapid = src_snapid;
+       op->copy_from.src_version = src_version;
+       op->copy_from.flags = copy_from_flags;
+       op->copy_from.src_fadvise_flags = src_fadvise_flags;
+
+       p = page_address(pages[0]);
+       end = p + PAGE_SIZE;
+       ceph_encode_string(&p, end, src_oid->name, src_oid->name_len);
+       encode_oloc(&p, end, src_oloc);
+       op->indata_len = PAGE_SIZE - (end - p);
+
+       ceph_osd_data_pages_init(&op->copy_from.osd_data, pages,
+                                op->indata_len, 0, false, true);
+       return 0;
+}
+
+int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
+                       u64 src_snapid, u64 src_version,
+                       struct ceph_object_id *src_oid,
+                       struct ceph_object_locator *src_oloc,
+                       u32 src_fadvise_flags,
+                       struct ceph_object_id *dst_oid,
+                       struct ceph_object_locator *dst_oloc,
+                       u32 dst_fadvise_flags,
+                       u8 copy_from_flags)
+{
+       struct ceph_osd_request *req;
+       int ret;
+
+       req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_KERNEL);
+       if (!req)
+               return -ENOMEM;
+
+       req->r_flags = CEPH_OSD_FLAG_WRITE;
+
+       ceph_oloc_copy(&req->r_t.base_oloc, dst_oloc);
+       ceph_oid_copy(&req->r_t.base_oid, dst_oid);
+
+       ret = osd_req_op_copy_from_init(req, src_snapid, src_version, src_oid,
+                                       src_oloc, src_fadvise_flags,
+                                       dst_fadvise_flags, copy_from_flags);
+       if (ret)
+               goto out;
+
+       ret = ceph_osdc_alloc_messages(req, GFP_KERNEL);
+       if (ret)
+               goto out;
+
+       ceph_osdc_start_request(osdc, req, false);
+       ret = ceph_osdc_wait_request(osdc, req);
+
+out:
+       ceph_osdc_put_request(req);
+       return ret;
+}
+EXPORT_SYMBOL(ceph_osdc_copy_from);
+
 int __init ceph_osdc_setup(void)
 {
        size_t size = sizeof(struct ceph_osd_request) +
@@ -5295,7 +5472,7 @@ static struct ceph_msg *alloc_msg_with_page_vector(struct ceph_msg_header *hdr)
        u32 front_len = le32_to_cpu(hdr->front_len);
        u32 data_len = le32_to_cpu(hdr->data_len);
 
-       m = ceph_msg_new(type, front_len, GFP_NOIO, false);
+       m = ceph_msg_new2(type, front_len, 1, GFP_NOIO, false);
        if (!m)
                return NULL;
 
index 2ea0564771d2d4428be2a3e9642056b85d3b306f..65e34f78b05d4ca662ddceca0d1a24b34eb4007d 100644 (file)
@@ -6,6 +6,26 @@
 #include <linux/highmem.h>
 #include <linux/ceph/pagelist.h>
 
+struct ceph_pagelist *ceph_pagelist_alloc(gfp_t gfp_flags)
+{
+       struct ceph_pagelist *pl;
+
+       pl = kmalloc(sizeof(*pl), gfp_flags);
+       if (!pl)
+               return NULL;
+
+       INIT_LIST_HEAD(&pl->head);
+       pl->mapped_tail = NULL;
+       pl->length = 0;
+       pl->room = 0;
+       INIT_LIST_HEAD(&pl->free_list);
+       pl->num_pages_free = 0;
+       refcount_set(&pl->refcnt, 1);
+
+       return pl;
+}
+EXPORT_SYMBOL(ceph_pagelist_alloc);
+
 static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl)
 {
        if (pl->mapped_tail) {
index f5c9ef2586deb75edac0526b992087efa193d179..411dd7a90046eff218ac8aa97ca8f943b18ba985 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/vmalloc.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <net/addrconf.h>
 #include <net/inet_connection_sock.h>
index 1834818ed07b3248ef36ce4e1b64887224ab1657..9e6bc4d6daa7503c7491c39870d76fd41ddb155c 100644 (file)
 #include <linux/net.h>
 #include <linux/socket.h>
 #include <linux/random.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/cache.h>
index ca3ed931f2a91479940d1c2dbe55870aef2df96f..1976fddb9e00515072210c6bbcde929cb2832c73 100644 (file)
@@ -81,7 +81,7 @@
 
 #include <linux/uaccess.h>
 #include <asm/ioctls.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/types.h>
index e948db29ab539a588e8526d2f4fc22428a9f4685..9b277bd36d1ade6acc46260c1d267bed801ee965 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
index 860f2a1bbb675d71f4de3bd70acd1284974ffe3a..1ece4bc3eb8d86470f41255c05e57ece1ba90f0e 100644 (file)
@@ -76,6 +76,7 @@ struct rsi {
        struct xdr_netobj       in_handle, in_token;
        struct xdr_netobj       out_handle, out_token;
        int                     major_status, minor_status;
+       struct rcu_head         rcu_head;
 };
 
 static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
@@ -89,13 +90,21 @@ static void rsi_free(struct rsi *rsii)
        kfree(rsii->out_token.data);
 }
 
-static void rsi_put(struct kref *ref)
+static void rsi_free_rcu(struct rcu_head *head)
 {
-       struct rsi *rsii = container_of(ref, struct rsi, h.ref);
+       struct rsi *rsii = container_of(head, struct rsi, rcu_head);
+
        rsi_free(rsii);
        kfree(rsii);
 }
 
+static void rsi_put(struct kref *ref)
+{
+       struct rsi *rsii = container_of(ref, struct rsi, h.ref);
+
+       call_rcu(&rsii->rcu_head, rsi_free_rcu);
+}
+
 static inline int rsi_hash(struct rsi *item)
 {
        return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
@@ -282,7 +291,7 @@ static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
        struct cache_head *ch;
        int hash = rsi_hash(item);
 
-       ch = sunrpc_cache_lookup(cd, &item->h, hash);
+       ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
        if (ch)
                return container_of(ch, struct rsi, h);
        else
@@ -330,6 +339,7 @@ struct rsc {
        struct svc_cred         cred;
        struct gss_svc_seq_data seqdata;
        struct gss_ctx          *mechctx;
+       struct rcu_head         rcu_head;
 };
 
 static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
@@ -343,12 +353,22 @@ static void rsc_free(struct rsc *rsci)
        free_svc_cred(&rsci->cred);
 }
 
+static void rsc_free_rcu(struct rcu_head *head)
+{
+       struct rsc *rsci = container_of(head, struct rsc, rcu_head);
+
+       kfree(rsci->handle.data);
+       kfree(rsci);
+}
+
 static void rsc_put(struct kref *ref)
 {
        struct rsc *rsci = container_of(ref, struct rsc, h.ref);
 
-       rsc_free(rsci);
-       kfree(rsci);
+       if (rsci->mechctx)
+               gss_delete_sec_context(&rsci->mechctx);
+       free_svc_cred(&rsci->cred);
+       call_rcu(&rsci->rcu_head, rsc_free_rcu);
 }
 
 static inline int
@@ -542,7 +562,7 @@ static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
        struct cache_head *ch;
        int hash = rsc_hash(item);
 
-       ch = sunrpc_cache_lookup(cd, &item->h, hash);
+       ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
        if (ch)
                return container_of(ch, struct rsc, h);
        else
@@ -1764,14 +1784,21 @@ out_err:
 }
 
 static void
-svcauth_gss_domain_release(struct auth_domain *dom)
+svcauth_gss_domain_release_rcu(struct rcu_head *head)
 {
+       struct auth_domain *dom = container_of(head, struct auth_domain, rcu_head);
        struct gss_domain *gd = container_of(dom, struct gss_domain, h);
 
        kfree(dom->name);
        kfree(gd);
 }
 
+static void
+svcauth_gss_domain_release(struct auth_domain *dom)
+{
+       call_rcu(&dom->rcu_head, svcauth_gss_domain_release_rcu);
+}
+
 static struct auth_ops svcauthops_gss = {
        .name           = "rpcsec_gss",
        .owner          = THIS_MODULE,
index 109fbe591e7bf35de11e7d5fee20de519e872aa0..f96345b1180ee9cf41013008ac2f052a29496818 100644 (file)
@@ -54,28 +54,33 @@ static void cache_init(struct cache_head *h, struct cache_detail *detail)
        h->last_refresh = now;
 }
 
-struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
-                                      struct cache_head *key, int hash)
+static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail,
+                                               struct cache_head *key,
+                                               int hash)
 {
-       struct cache_head *new = NULL, *freeme = NULL, *tmp = NULL;
-       struct hlist_head *head;
-
-       head = &detail->hash_table[hash];
-
-       read_lock(&detail->hash_lock);
+       struct hlist_head *head = &detail->hash_table[hash];
+       struct cache_head *tmp;
 
-       hlist_for_each_entry(tmp, head, cache_list) {
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(tmp, head, cache_list) {
                if (detail->match(tmp, key)) {
                        if (cache_is_expired(detail, tmp))
-                               /* This entry is expired, we will discard it. */
-                               break;
-                       cache_get(tmp);
-                       read_unlock(&detail->hash_lock);
+                               continue;
+                       tmp = cache_get_rcu(tmp);
+                       rcu_read_unlock();
                        return tmp;
                }
        }
-       read_unlock(&detail->hash_lock);
-       /* Didn't find anything, insert an empty entry */
+       rcu_read_unlock();
+       return NULL;
+}
+
+static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
+                                                struct cache_head *key,
+                                                int hash)
+{
+       struct cache_head *new, *tmp, *freeme = NULL;
+       struct hlist_head *head = &detail->hash_table[hash];
 
        new = detail->alloc();
        if (!new)
@@ -87,35 +92,46 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
        cache_init(new, detail);
        detail->init(new, key);
 
-       write_lock(&detail->hash_lock);
+       spin_lock(&detail->hash_lock);
 
        /* check if entry appeared while we slept */
-       hlist_for_each_entry(tmp, head, cache_list) {
+       hlist_for_each_entry_rcu(tmp, head, cache_list) {
                if (detail->match(tmp, key)) {
                        if (cache_is_expired(detail, tmp)) {
-                               hlist_del_init(&tmp->cache_list);
+                               hlist_del_init_rcu(&tmp->cache_list);
                                detail->entries --;
                                freeme = tmp;
                                break;
                        }
                        cache_get(tmp);
-                       write_unlock(&detail->hash_lock);
+                       spin_unlock(&detail->hash_lock);
                        cache_put(new, detail);
                        return tmp;
                }
        }
 
-       hlist_add_head(&new->cache_list, head);
+       hlist_add_head_rcu(&new->cache_list, head);
        detail->entries++;
        cache_get(new);
-       write_unlock(&detail->hash_lock);
+       spin_unlock(&detail->hash_lock);
 
        if (freeme)
                cache_put(freeme, detail);
        return new;
 }
-EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
 
+struct cache_head *sunrpc_cache_lookup_rcu(struct cache_detail *detail,
+                                          struct cache_head *key, int hash)
+{
+       struct cache_head *ret;
+
+       ret = sunrpc_cache_find_rcu(detail, key, hash);
+       if (ret)
+               return ret;
+       /* Didn't find anything, insert an empty entry */
+       return sunrpc_cache_add_entry(detail, key, hash);
+}
+EXPORT_SYMBOL_GPL(sunrpc_cache_lookup_rcu);
 
 static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch);
 
@@ -151,18 +167,18 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
        struct cache_head *tmp;
 
        if (!test_bit(CACHE_VALID, &old->flags)) {
-               write_lock(&detail->hash_lock);
+               spin_lock(&detail->hash_lock);
                if (!test_bit(CACHE_VALID, &old->flags)) {
                        if (test_bit(CACHE_NEGATIVE, &new->flags))
                                set_bit(CACHE_NEGATIVE, &old->flags);
                        else
                                detail->update(old, new);
                        cache_fresh_locked(old, new->expiry_time, detail);
-                       write_unlock(&detail->hash_lock);
+                       spin_unlock(&detail->hash_lock);
                        cache_fresh_unlocked(old, detail);
                        return old;
                }
-               write_unlock(&detail->hash_lock);
+               spin_unlock(&detail->hash_lock);
        }
        /* We need to insert a new entry */
        tmp = detail->alloc();
@@ -173,7 +189,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
        cache_init(tmp, detail);
        detail->init(tmp, old);
 
-       write_lock(&detail->hash_lock);
+       spin_lock(&detail->hash_lock);
        if (test_bit(CACHE_NEGATIVE, &new->flags))
                set_bit(CACHE_NEGATIVE, &tmp->flags);
        else
@@ -183,7 +199,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
        cache_get(tmp);
        cache_fresh_locked(tmp, new->expiry_time, detail);
        cache_fresh_locked(old, 0, detail);
-       write_unlock(&detail->hash_lock);
+       spin_unlock(&detail->hash_lock);
        cache_fresh_unlocked(tmp, detail);
        cache_fresh_unlocked(old, detail);
        cache_put(old, detail);
@@ -223,7 +239,7 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
 {
        int rv;
 
-       write_lock(&detail->hash_lock);
+       spin_lock(&detail->hash_lock);
        rv = cache_is_valid(h);
        if (rv == -EAGAIN) {
                set_bit(CACHE_NEGATIVE, &h->flags);
@@ -231,7 +247,7 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
                                   detail);
                rv = -ENOENT;
        }
-       write_unlock(&detail->hash_lock);
+       spin_unlock(&detail->hash_lock);
        cache_fresh_unlocked(h, detail);
        return rv;
 }
@@ -341,7 +357,7 @@ static struct delayed_work cache_cleaner;
 
 void sunrpc_init_cache_detail(struct cache_detail *cd)
 {
-       rwlock_init(&cd->hash_lock);
+       spin_lock_init(&cd->hash_lock);
        INIT_LIST_HEAD(&cd->queue);
        spin_lock(&cache_list_lock);
        cd->nextcheck = 0;
@@ -361,11 +377,11 @@ void sunrpc_destroy_cache_detail(struct cache_detail *cd)
 {
        cache_purge(cd);
        spin_lock(&cache_list_lock);
-       write_lock(&cd->hash_lock);
+       spin_lock(&cd->hash_lock);
        if (current_detail == cd)
                current_detail = NULL;
        list_del_init(&cd->others);
-       write_unlock(&cd->hash_lock);
+       spin_unlock(&cd->hash_lock);
        spin_unlock(&cache_list_lock);
        if (list_empty(&cache_list)) {
                /* module must be being unloaded so its safe to kill the worker */
@@ -422,7 +438,7 @@ static int cache_clean(void)
                struct hlist_head *head;
                struct hlist_node *tmp;
 
-               write_lock(&current_detail->hash_lock);
+               spin_lock(&current_detail->hash_lock);
 
                /* Ok, now to clean this strand */
 
@@ -433,13 +449,13 @@ static int cache_clean(void)
                        if (!cache_is_expired(current_detail, ch))
                                continue;
 
-                       hlist_del_init(&ch->cache_list);
+                       hlist_del_init_rcu(&ch->cache_list);
                        current_detail->entries--;
                        rv = 1;
                        break;
                }
 
-               write_unlock(&current_detail->hash_lock);
+               spin_unlock(&current_detail->hash_lock);
                d = current_detail;
                if (!ch)
                        current_index ++;
@@ -494,9 +510,9 @@ void cache_purge(struct cache_detail *detail)
        struct hlist_node *tmp = NULL;
        int i = 0;
 
-       write_lock(&detail->hash_lock);
+       spin_lock(&detail->hash_lock);
        if (!detail->entries) {
-               write_unlock(&detail->hash_lock);
+               spin_unlock(&detail->hash_lock);
                return;
        }
 
@@ -504,17 +520,17 @@ void cache_purge(struct cache_detail *detail)
        for (i = 0; i < detail->hash_size; i++) {
                head = &detail->hash_table[i];
                hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
-                       hlist_del_init(&ch->cache_list);
+                       hlist_del_init_rcu(&ch->cache_list);
                        detail->entries--;
 
                        set_bit(CACHE_CLEANED, &ch->flags);
-                       write_unlock(&detail->hash_lock);
+                       spin_unlock(&detail->hash_lock);
                        cache_fresh_unlocked(ch, detail);
                        cache_put(ch, detail);
-                       write_lock(&detail->hash_lock);
+                       spin_lock(&detail->hash_lock);
                }
        }
-       write_unlock(&detail->hash_lock);
+       spin_unlock(&detail->hash_lock);
 }
 EXPORT_SYMBOL_GPL(cache_purge);
 
@@ -1289,21 +1305,19 @@ EXPORT_SYMBOL_GPL(qword_get);
  * get a header, then pass each real item in the cache
  */
 
-void *cache_seq_start(struct seq_file *m, loff_t *pos)
-       __acquires(cd->hash_lock)
+static void *__cache_seq_start(struct seq_file *m, loff_t *pos)
 {
        loff_t n = *pos;
        unsigned int hash, entry;
        struct cache_head *ch;
        struct cache_detail *cd = m->private;
 
-       read_lock(&cd->hash_lock);
        if (!n--)
                return SEQ_START_TOKEN;
        hash = n >> 32;
        entry = n & ((1LL<<32) - 1);
 
-       hlist_for_each_entry(ch, &cd->hash_table[hash], cache_list)
+       hlist_for_each_entry_rcu(ch, &cd->hash_table[hash], cache_list)
                if (!entry--)
                        return ch;
        n &= ~((1LL<<32) - 1);
@@ -1315,12 +1329,12 @@ void *cache_seq_start(struct seq_file *m, loff_t *pos)
        if (hash >= cd->hash_size)
                return NULL;
        *pos = n+1;
-       return hlist_entry_safe(cd->hash_table[hash].first,
+       return hlist_entry_safe(rcu_dereference_raw(
+                               hlist_first_rcu(&cd->hash_table[hash])),
                                struct cache_head, cache_list);
 }
-EXPORT_SYMBOL_GPL(cache_seq_start);
 
-void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos)
+static void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos)
 {
        struct cache_head *ch = p;
        int hash = (*pos >> 32);
@@ -1333,7 +1347,8 @@ void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos)
                *pos += 1LL<<32;
        } else {
                ++*pos;
-               return hlist_entry_safe(ch->cache_list.next,
+               return hlist_entry_safe(rcu_dereference_raw(
+                                       hlist_next_rcu(&ch->cache_list)),
                                        struct cache_head, cache_list);
        }
        *pos &= ~((1LL<<32) - 1);
@@ -1345,18 +1360,32 @@ void *cache_seq_next(struct seq_file *m, void *p, loff_t *pos)
        if (hash >= cd->hash_size)
                return NULL;
        ++*pos;
-       return hlist_entry_safe(cd->hash_table[hash].first,
+       return hlist_entry_safe(rcu_dereference_raw(
+                               hlist_first_rcu(&cd->hash_table[hash])),
                                struct cache_head, cache_list);
 }
 EXPORT_SYMBOL_GPL(cache_seq_next);
 
-void cache_seq_stop(struct seq_file *m, void *p)
-       __releases(cd->hash_lock)
+void *cache_seq_start_rcu(struct seq_file *m, loff_t *pos)
+       __acquires(RCU)
 {
-       struct cache_detail *cd = m->private;
-       read_unlock(&cd->hash_lock);
+       rcu_read_lock();
+       return __cache_seq_start(m, pos);
+}
+EXPORT_SYMBOL_GPL(cache_seq_start_rcu);
+
+void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos)
+{
+       return cache_seq_next(file, p, pos);
+}
+EXPORT_SYMBOL_GPL(cache_seq_next_rcu);
+
+void cache_seq_stop_rcu(struct seq_file *m, void *p)
+       __releases(RCU)
+{
+       rcu_read_unlock();
 }
-EXPORT_SYMBOL_GPL(cache_seq_stop);
+EXPORT_SYMBOL_GPL(cache_seq_stop_rcu);
 
 static int c_show(struct seq_file *m, void *p)
 {
@@ -1384,9 +1413,9 @@ static int c_show(struct seq_file *m, void *p)
 }
 
 static const struct seq_operations cache_content_op = {
-       .start  = cache_seq_start,
-       .next   = cache_seq_next,
-       .stop   = cache_seq_stop,
+       .start  = cache_seq_start_rcu,
+       .next   = cache_seq_next_rcu,
+       .stop   = cache_seq_stop_rcu,
        .show   = c_show,
 };
 
@@ -1844,13 +1873,13 @@ EXPORT_SYMBOL_GPL(sunrpc_cache_unregister_pipefs);
 
 void sunrpc_cache_unhash(struct cache_detail *cd, struct cache_head *h)
 {
-       write_lock(&cd->hash_lock);
+       spin_lock(&cd->hash_lock);
        if (!hlist_unhashed(&h->cache_list)){
-               hlist_del_init(&h->cache_list);
+               hlist_del_init_rcu(&h->cache_list);
                cd->entries--;
-               write_unlock(&cd->hash_lock);
+               spin_unlock(&cd->hash_lock);
                cache_put(h, cd);
        } else
-               write_unlock(&cd->hash_lock);
+               spin_unlock(&cd->hash_lock);
 }
 EXPORT_SYMBOL_GPL(sunrpc_cache_unhash);
index 87533fbb96cfa89b2fdbc9bfa4ba240d881903d4..51d36230b6e3e350da9452877b87f7b14b70dd63 100644 (file)
@@ -987,7 +987,7 @@ static void call_xpt_users(struct svc_xprt *xprt)
        spin_lock(&xprt->xpt_lock);
        while (!list_empty(&xprt->xpt_users)) {
                u = list_first_entry(&xprt->xpt_users, struct svc_xpt_user, list);
-               list_del(&u->list);
+               list_del_init(&u->list);
                u->callback(u);
        }
        spin_unlock(&xprt->xpt_lock);
index bb8db3cb8032ee0a4714cf3b49aeb83cb73037bd..775b8c94265bc329e3a36bf8b3010e53f054c1e2 100644 (file)
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
 
-static DEFINE_SPINLOCK(authtab_lock);
-static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = {
-       [0] = &svcauth_null,
-       [1] = &svcauth_unix,
+static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
+       [RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
+       [RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
 };
 
+static struct auth_ops *
+svc_get_auth_ops(rpc_authflavor_t flavor)
+{
+       struct auth_ops         *aops;
+
+       if (flavor >= RPC_AUTH_MAXFLAVOR)
+               return NULL;
+       rcu_read_lock();
+       aops = rcu_dereference(authtab[flavor]);
+       if (aops != NULL && !try_module_get(aops->owner))
+               aops = NULL;
+       rcu_read_unlock();
+       return aops;
+}
+
+static void
+svc_put_auth_ops(struct auth_ops *aops)
+{
+       module_put(aops->owner);
+}
+
 int
 svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
 {
@@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
 
        dprintk("svc: svc_authenticate (%d)\n", flavor);
 
-       spin_lock(&authtab_lock);
-       if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) ||
-           !try_module_get(aops->owner)) {
-               spin_unlock(&authtab_lock);
+       aops = svc_get_auth_ops(flavor);
+       if (aops == NULL) {
                *authp = rpc_autherr_badcred;
                return SVC_DENIED;
        }
-       spin_unlock(&authtab_lock);
 
        rqstp->rq_auth_slack = 0;
        init_svc_cred(&rqstp->rq_cred);
@@ -82,7 +99,7 @@ int svc_authorise(struct svc_rqst *rqstp)
 
        if (aops) {
                rv = aops->release(rqstp);
-               module_put(aops->owner);
+               svc_put_auth_ops(aops);
        }
        return rv;
 }
@@ -90,13 +107,14 @@ int svc_authorise(struct svc_rqst *rqstp)
 int
 svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
 {
+       struct auth_ops *old;
        int rv = -EINVAL;
-       spin_lock(&authtab_lock);
-       if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) {
-               authtab[flavor] = aops;
-               rv = 0;
+
+       if (flavor < RPC_AUTH_MAXFLAVOR) {
+               old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops);
+               if (old == NULL || old == aops)
+                       rv = 0;
        }
-       spin_unlock(&authtab_lock);
        return rv;
 }
 EXPORT_SYMBOL_GPL(svc_auth_register);
@@ -104,10 +122,8 @@ EXPORT_SYMBOL_GPL(svc_auth_register);
 void
 svc_auth_unregister(rpc_authflavor_t flavor)
 {
-       spin_lock(&authtab_lock);
        if (flavor < RPC_AUTH_MAXFLAVOR)
-               authtab[flavor] = NULL;
-       spin_unlock(&authtab_lock);
+               rcu_assign_pointer(authtab[flavor], NULL);
 }
 EXPORT_SYMBOL_GPL(svc_auth_unregister);
 
@@ -127,10 +143,11 @@ static struct hlist_head  auth_domain_table[DN_HASHMAX];
 static DEFINE_SPINLOCK(auth_domain_lock);
 
 static void auth_domain_release(struct kref *kref)
+       __releases(&auth_domain_lock)
 {
        struct auth_domain *dom = container_of(kref, struct auth_domain, ref);
 
-       hlist_del(&dom->hash);
+       hlist_del_rcu(&dom->hash);
        dom->flavour->domain_release(dom);
        spin_unlock(&auth_domain_lock);
 }
@@ -159,7 +176,7 @@ auth_domain_lookup(char *name, struct auth_domain *new)
                }
        }
        if (new)
-               hlist_add_head(&new->hash, head);
+               hlist_add_head_rcu(&new->hash, head);
        spin_unlock(&auth_domain_lock);
        return new;
 }
@@ -167,6 +184,21 @@ EXPORT_SYMBOL_GPL(auth_domain_lookup);
 
 struct auth_domain *auth_domain_find(char *name)
 {
-       return auth_domain_lookup(name, NULL);
+       struct auth_domain *hp;
+       struct hlist_head *head;
+
+       head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
+
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(hp, head, hash) {
+               if (strcmp(hp->name, name)==0) {
+                       if (!kref_get_unless_zero(&hp->ref))
+                               hp = NULL;
+                       rcu_read_unlock();
+                       return hp;
+               }
+       }
+       rcu_read_unlock();
+       return NULL;
 }
 EXPORT_SYMBOL_GPL(auth_domain_find);
index af7f28fb8102e4313f5ced6aa585e30f3911ca6c..fb9041b92f72233841cf1d173aa1b1cafe91e623 100644 (file)
@@ -37,20 +37,26 @@ struct unix_domain {
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
 
-static void svcauth_unix_domain_release(struct auth_domain *dom)
+static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
 {
+       struct auth_domain *dom = container_of(head, struct auth_domain, rcu_head);
        struct unix_domain *ud = container_of(dom, struct unix_domain, h);
 
        kfree(dom->name);
        kfree(ud);
 }
 
+static void svcauth_unix_domain_release(struct auth_domain *dom)
+{
+       call_rcu(&dom->rcu_head, svcauth_unix_domain_release_rcu);
+}
+
 struct auth_domain *unix_domain_find(char *name)
 {
        struct auth_domain *rv;
        struct unix_domain *new = NULL;
 
-       rv = auth_domain_lookup(name, NULL);
+       rv = auth_domain_find(name);
        while(1) {
                if (rv) {
                        if (new && rv != &new->h)
@@ -91,6 +97,7 @@ struct ip_map {
        char                    m_class[8]; /* e.g. "nfsd" */
        struct in6_addr         m_addr;
        struct unix_domain      *m_client;
+       struct rcu_head         m_rcu;
 };
 
 static void ip_map_put(struct kref *kref)
@@ -101,7 +108,7 @@ static void ip_map_put(struct kref *kref)
        if (test_bit(CACHE_VALID, &item->flags) &&
            !test_bit(CACHE_NEGATIVE, &item->flags))
                auth_domain_put(&im->m_client->h);
-       kfree(im);
+       kfree_rcu(im, m_rcu);
 }
 
 static inline int hash_ip6(const struct in6_addr *ip)
@@ -280,9 +287,9 @@ static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
 
        strcpy(ip.m_class, class);
        ip.m_addr = *addr;
-       ch = sunrpc_cache_lookup(cd, &ip.h,
-                                hash_str(class, IP_HASHBITS) ^
-                                hash_ip6(addr));
+       ch = sunrpc_cache_lookup_rcu(cd, &ip.h,
+                                    hash_str(class, IP_HASHBITS) ^
+                                    hash_ip6(addr));
 
        if (ch)
                return container_of(ch, struct ip_map, h);
@@ -412,6 +419,7 @@ struct unix_gid {
        struct cache_head       h;
        kuid_t                  uid;
        struct group_info       *gi;
+       struct rcu_head         rcu;
 };
 
 static int unix_gid_hash(kuid_t uid)
@@ -426,7 +434,7 @@ static void unix_gid_put(struct kref *kref)
        if (test_bit(CACHE_VALID, &item->flags) &&
            !test_bit(CACHE_NEGATIVE, &item->flags))
                put_group_info(ug->gi);
-       kfree(ug);
+       kfree_rcu(ug, rcu);
 }
 
 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
@@ -619,7 +627,7 @@ static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
        struct cache_head *ch;
 
        ug.uid = uid;
-       ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
+       ch = sunrpc_cache_lookup_rcu(cd, &ug.h, unix_gid_hash(uid));
        if (ch)
                return container_of(ch, struct unix_gid, h);
        else
index db8bb6b3a2b0faf387868b80539c33ae9c5626dd..3b525accaa6857bc76cda9a8b9f131791fcd1f26 100644 (file)
@@ -325,59 +325,34 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
 /*
  * Generic recvfrom routine.
  */
-static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr,
-                       int buflen)
+static ssize_t svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov,
+                           unsigned int nr, size_t buflen, unsigned int base)
 {
        struct svc_sock *svsk =
                container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt);
-       struct msghdr msg = {
-               .msg_flags      = MSG_DONTWAIT,
-       };
-       int len;
+       struct msghdr msg = { NULL };
+       ssize_t len;
 
        rqstp->rq_xprt_hlen = 0;
 
        clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
        iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, nr, buflen);
-       len = sock_recvmsg(svsk->sk_sock, &msg, msg.msg_flags);
+       if (base != 0) {
+               iov_iter_advance(&msg.msg_iter, base);
+               buflen -= base;
+       }
+       len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT);
        /* If we read a full record, then assume there may be more
         * data to read (stream based sockets only!)
         */
        if (len == buflen)
                set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
 
-       dprintk("svc: socket %p recvfrom(%p, %zu) = %d\n",
+       dprintk("svc: socket %p recvfrom(%p, %zu) = %zd\n",
                svsk, iov[0].iov_base, iov[0].iov_len, len);
        return len;
 }
 
-static int svc_partial_recvfrom(struct svc_rqst *rqstp,
-                               struct kvec *iov, int nr,
-                               int buflen, unsigned int base)
-{
-       size_t save_iovlen;
-       void *save_iovbase;
-       unsigned int i;
-       int ret;
-
-       if (base == 0)
-               return svc_recvfrom(rqstp, iov, nr, buflen);
-
-       for (i = 0; i < nr; i++) {
-               if (iov[i].iov_len > base)
-                       break;
-               base -= iov[i].iov_len;
-       }
-       save_iovlen = iov[i].iov_len;
-       save_iovbase = iov[i].iov_base;
-       iov[i].iov_len -= base;
-       iov[i].iov_base += base;
-       ret = svc_recvfrom(rqstp, &iov[i], nr - i, buflen);
-       iov[i].iov_len = save_iovlen;
-       iov[i].iov_base = save_iovbase;
-       return ret;
-}
-
 /*
  * Set socket snd and rcv buffer lengths
  */
@@ -962,7 +937,8 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
                want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
                iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen;
                iov.iov_len  = want;
-               if ((len = svc_recvfrom(rqstp, &iov, 1, want)) < 0)
+               len = svc_recvfrom(rqstp, &iov, 1, want, 0);
+               if (len < 0)
                        goto error;
                svsk->sk_tcplen += len;
 
@@ -1088,14 +1064,13 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
 
        vec = rqstp->rq_vec;
 
-       pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
-                                               svsk->sk_datalen + want);
+       pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], base + want);
 
        rqstp->rq_respages = &rqstp->rq_pages[pnum];
        rqstp->rq_next_page = rqstp->rq_respages + 1;
 
        /* Now receive data */
-       len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
+       len = svc_recvfrom(rqstp, vec, pnum, base + want, base);
        if (len >= 0) {
                svsk->sk_tcplen += len;
                svsk->sk_datalen += len;
index d3a1a237cee6e4f49f6af104c8cb0c68c7463d65..f3c147d70286e8fd6ea080e7b8619cb40a8ae3df 100644 (file)
@@ -5,8 +5,6 @@
  * Support for backward direction RPCs on RPC/RDMA (server-side).
  */
 
-#include <linux/module.h>
-
 #include <linux/sunrpc/svc_rdma.h>
 
 #include "xprt_rdma.h"
@@ -32,7 +30,6 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
        struct kvec *dst, *src = &rcvbuf->head[0];
        struct rpc_rqst *req;
-       unsigned long cwnd;
        u32 credits;
        size_t len;
        __be32 xid;
@@ -66,6 +63,8 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
        if (dst->iov_len < len)
                goto out_unlock;
        memcpy(dst->iov_base, p, len);
+       xprt_pin_rqst(req);
+       spin_unlock(&xprt->queue_lock);
 
        credits = be32_to_cpup(rdma_resp + 2);
        if (credits == 0)
@@ -74,15 +73,13 @@ int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp,
                credits = r_xprt->rx_buf.rb_bc_max_requests;
 
        spin_lock_bh(&xprt->transport_lock);
-       cwnd = xprt->cwnd;
        xprt->cwnd = credits << RPC_CWNDSHIFT;
-       if (xprt->cwnd > cwnd)
-               xprt_release_rqst_cong(req->rq_task);
        spin_unlock_bh(&xprt->transport_lock);
 
-
+       spin_lock(&xprt->queue_lock);
        ret = 0;
        xprt_complete_rqst(req->rq_task, rcvbuf->len);
+       xprt_unpin_rqst(req);
        rcvbuf->len = 0;
 
 out_unlock:
@@ -251,7 +248,6 @@ xprt_rdma_bc_put(struct rpc_xprt *xprt)
        dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
 
        xprt_free(xprt);
-       module_put(THIS_MODULE);
 }
 
 static const struct rpc_xprt_ops xprt_rdma_bc_procs = {
@@ -323,20 +319,9 @@ xprt_setup_rdma_bc(struct xprt_create *args)
        args->bc_xprt->xpt_bc_xprt = xprt;
        xprt->bc_xprt = args->bc_xprt;
 
-       if (!try_module_get(THIS_MODULE))
-               goto out_fail;
-
        /* Final put for backchannel xprt is in __svc_rdma_free */
        xprt_get(xprt);
        return xprt;
-
-out_fail:
-       xprt_rdma_free_addresses(xprt);
-       args->bc_xprt->xpt_bc_xprt = NULL;
-       args->bc_xprt->xpt_bc_xps = NULL;
-       xprt_put(xprt);
-       xprt_free(xprt);
-       return ERR_PTR(-EINVAL);
 }
 
 struct xprt_class xprt_rdma_bc = {
index 2848cafd4a17744d2fe9a515126611d9a891a189..2f7ec8912f49417f2fc65afc7e6d067e74559de9 100644 (file)
@@ -475,10 +475,12 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 
        /* Qualify the transport resource defaults with the
         * capabilities of this particular device */
-       newxprt->sc_max_send_sges = dev->attrs.max_send_sge;
-       /* transport hdr, head iovec, one page list entry, tail iovec */
-       if (newxprt->sc_max_send_sges < 4) {
-               pr_err("svcrdma: too few Send SGEs available (%d)\n",
+       /* Transport header, head iovec, tail iovec */
+       newxprt->sc_max_send_sges = 3;
+       /* Add one SGE per page list entry */
+       newxprt->sc_max_send_sges += svcrdma_max_req_size / PAGE_SIZE;
+       if (newxprt->sc_max_send_sges > dev->attrs.max_send_sge) {
+               pr_err("svcrdma: too few Send SGEs available (%d needed)\n",
                       newxprt->sc_max_send_sges);
                goto errout;
        }
index 2ad33ce1ea177cb91069e37254fd56989e3ee70f..eca8d84d99bf2297f3b212cae08f9105dcc78317 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/xfrm.h>
index 2535c3677c7b66a1650fc3a1a7fb9c99684ae8ea..ca7960adf5a3f4081a359b8df291f331aa902277 100644 (file)
 #define MBOCHS_NAME              "mbochs"
 #define MBOCHS_CLASS_NAME        "mbochs"
 
+#define MBOCHS_EDID_REGION_INDEX  VFIO_PCI_NUM_REGIONS
+#define MBOCHS_NUM_REGIONS        (MBOCHS_EDID_REGION_INDEX+1)
+
 #define MBOCHS_CONFIG_SPACE_SIZE  0xff
 #define MBOCHS_MMIO_BAR_OFFSET   PAGE_SIZE
 #define MBOCHS_MMIO_BAR_SIZE     PAGE_SIZE
-#define MBOCHS_MEMORY_BAR_OFFSET  (MBOCHS_MMIO_BAR_OFFSET + \
+#define MBOCHS_EDID_OFFSET       (MBOCHS_MMIO_BAR_OFFSET +     \
                                   MBOCHS_MMIO_BAR_SIZE)
+#define MBOCHS_EDID_SIZE         PAGE_SIZE
+#define MBOCHS_MEMORY_BAR_OFFSET  (MBOCHS_EDID_OFFSET + \
+                                  MBOCHS_EDID_SIZE)
+
+#define MBOCHS_EDID_BLOB_OFFSET   (MBOCHS_EDID_SIZE/2)
 
 #define STORE_LE16(addr, val)  (*(u16 *)addr = val)
 #define STORE_LE32(addr, val)  (*(u32 *)addr = val)
@@ -95,16 +103,24 @@ MODULE_PARM_DESC(mem, "megabytes available to " MBOCHS_NAME " devices");
 static const struct mbochs_type {
        const char *name;
        u32 mbytes;
+       u32 max_x;
+       u32 max_y;
 } mbochs_types[] = {
        {
                .name   = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_1,
                .mbytes = 4,
+               .max_x  = 800,
+               .max_y  = 600,
        }, {
                .name   = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_2,
                .mbytes = 16,
+               .max_x  = 1920,
+               .max_y  = 1440,
        }, {
                .name   = MBOCHS_CLASS_NAME "-" MBOCHS_TYPE_3,
                .mbytes = 64,
+               .max_x  = 0,
+               .max_y  = 0,
        },
 };
 
@@ -115,6 +131,11 @@ static struct cdev mbochs_cdev;
 static struct device   mbochs_dev;
 static int             mbochs_used_mbytes;
 
+struct vfio_region_info_ext {
+       struct vfio_region_info          base;
+       struct vfio_region_info_cap_type type;
+};
+
 struct mbochs_mode {
        u32 drm_format;
        u32 bytepp;
@@ -144,13 +165,14 @@ struct mdev_state {
        u32 memory_bar_mask;
        struct mutex ops_lock;
        struct mdev_device *mdev;
-       struct vfio_device_info dev_info;
 
        const struct mbochs_type *type;
        u16 vbe[VBE_DISPI_INDEX_COUNT];
        u64 memsize;
        struct page **pages;
        pgoff_t pagecount;
+       struct vfio_region_gfx_edid edid_regs;
+       u8 edid_blob[0x400];
 
        struct list_head dmabufs;
        u32 active_id;
@@ -342,10 +364,20 @@ static void handle_mmio_read(struct mdev_state *mdev_state, u16 offset,
                             char *buf, u32 count)
 {
        struct device *dev = mdev_dev(mdev_state->mdev);
+       struct vfio_region_gfx_edid *edid;
        u16 reg16 = 0;
        int index;
 
        switch (offset) {
+       case 0x000 ... 0x3ff: /* edid block */
+               edid = &mdev_state->edid_regs;
+               if (edid->link_state != VFIO_DEVICE_GFX_LINK_STATE_UP ||
+                   offset >= edid->edid_size) {
+                       memset(buf, 0, count);
+                       break;
+               }
+               memcpy(buf, mdev_state->edid_blob + offset, count);
+               break;
        case 0x500 ... 0x515: /* bochs dispi interface */
                if (count != 2)
                        goto unhandled;
@@ -365,6 +397,44 @@ unhandled:
        }
 }
 
+static void handle_edid_regs(struct mdev_state *mdev_state, u16 offset,
+                            char *buf, u32 count, bool is_write)
+{
+       char *regs = (void *)&mdev_state->edid_regs;
+
+       if (offset + count > sizeof(mdev_state->edid_regs))
+               return;
+       if (count != 4)
+               return;
+       if (offset % 4)
+               return;
+
+       if (is_write) {
+               switch (offset) {
+               case offsetof(struct vfio_region_gfx_edid, link_state):
+               case offsetof(struct vfio_region_gfx_edid, edid_size):
+                       memcpy(regs + offset, buf, count);
+                       break;
+               default:
+                       /* read-only regs */
+                       break;
+               }
+       } else {
+               memcpy(buf, regs + offset, count);
+       }
+}
+
+static void handle_edid_blob(struct mdev_state *mdev_state, u16 offset,
+                            char *buf, u32 count, bool is_write)
+{
+       if (offset + count > mdev_state->edid_regs.edid_max_size)
+               return;
+       if (is_write)
+               memcpy(mdev_state->edid_blob + offset, buf, count);
+       else
+               memcpy(buf, mdev_state->edid_blob + offset, count);
+}
+
 static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count,
                           loff_t pos, bool is_write)
 {
@@ -384,13 +454,25 @@ static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count,
                        memcpy(buf, (mdev_state->vconfig + pos), count);
 
        } else if (pos >= MBOCHS_MMIO_BAR_OFFSET &&
-                  pos + count <= MBOCHS_MEMORY_BAR_OFFSET) {
+                  pos + count <= (MBOCHS_MMIO_BAR_OFFSET +
+                                  MBOCHS_MMIO_BAR_SIZE)) {
                pos -= MBOCHS_MMIO_BAR_OFFSET;
                if (is_write)
                        handle_mmio_write(mdev_state, pos, buf, count);
                else
                        handle_mmio_read(mdev_state, pos, buf, count);
 
+       } else if (pos >= MBOCHS_EDID_OFFSET &&
+                  pos + count <= (MBOCHS_EDID_OFFSET +
+                                  MBOCHS_EDID_SIZE)) {
+               pos -= MBOCHS_EDID_OFFSET;
+               if (pos < MBOCHS_EDID_BLOB_OFFSET) {
+                       handle_edid_regs(mdev_state, pos, buf, count, is_write);
+               } else {
+                       pos -= MBOCHS_EDID_BLOB_OFFSET;
+                       handle_edid_blob(mdev_state, pos, buf, count, is_write);
+               }
+
        } else if (pos >= MBOCHS_MEMORY_BAR_OFFSET &&
                   pos + count <=
                   MBOCHS_MEMORY_BAR_OFFSET + mdev_state->memsize) {
@@ -471,6 +553,10 @@ static int mbochs_create(struct kobject *kobj, struct mdev_device *mdev)
        mdev_state->next_id = 1;
 
        mdev_state->type = type;
+       mdev_state->edid_regs.max_xres = type->max_x;
+       mdev_state->edid_regs.max_yres = type->max_y;
+       mdev_state->edid_regs.edid_offset = MBOCHS_EDID_BLOB_OFFSET;
+       mdev_state->edid_regs.edid_max_size = sizeof(mdev_state->edid_blob);
        mbochs_create_config_space(mdev_state);
        mbochs_reset(mdev);
 
@@ -932,16 +1018,16 @@ static int mbochs_dmabuf_export(struct mbochs_dmabuf *dmabuf)
 }
 
 static int mbochs_get_region_info(struct mdev_device *mdev,
-                                 struct vfio_region_info *region_info,
-                                 u16 *cap_type_id, void **cap_type)
+                                 struct vfio_region_info_ext *ext)
 {
+       struct vfio_region_info *region_info = &ext->base;
        struct mdev_state *mdev_state;
 
        mdev_state = mdev_get_drvdata(mdev);
        if (!mdev_state)
                return -EINVAL;
 
-       if (region_info->index >= VFIO_PCI_NUM_REGIONS)
+       if (region_info->index >= MBOCHS_NUM_REGIONS)
                return -EINVAL;
 
        switch (region_info->index) {
@@ -964,6 +1050,20 @@ static int mbochs_get_region_info(struct mdev_device *mdev,
                region_info->flags  = (VFIO_REGION_INFO_FLAG_READ  |
                                       VFIO_REGION_INFO_FLAG_WRITE);
                break;
+       case MBOCHS_EDID_REGION_INDEX:
+               ext->base.argsz = sizeof(*ext);
+               ext->base.offset = MBOCHS_EDID_OFFSET;
+               ext->base.size = MBOCHS_EDID_SIZE;
+               ext->base.flags = (VFIO_REGION_INFO_FLAG_READ  |
+                                  VFIO_REGION_INFO_FLAG_WRITE |
+                                  VFIO_REGION_INFO_FLAG_CAPS);
+               ext->base.cap_offset = offsetof(typeof(*ext), type);
+               ext->type.header.id = VFIO_REGION_INFO_CAP_TYPE;
+               ext->type.header.version = 1;
+               ext->type.header.next = 0;
+               ext->type.type = VFIO_REGION_TYPE_GFX;
+               ext->type.subtype = VFIO_REGION_SUBTYPE_GFX_EDID;
+               break;
        default:
                region_info->size   = 0;
                region_info->offset = 0;
@@ -984,7 +1084,7 @@ static int mbochs_get_device_info(struct mdev_device *mdev,
                                  struct vfio_device_info *dev_info)
 {
        dev_info->flags = VFIO_DEVICE_FLAGS_PCI;
-       dev_info->num_regions = VFIO_PCI_NUM_REGIONS;
+       dev_info->num_regions = MBOCHS_NUM_REGIONS;
        dev_info->num_irqs = VFIO_PCI_NUM_IRQS;
        return 0;
 }
@@ -1084,7 +1184,7 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
                        unsigned long arg)
 {
        int ret = 0;
-       unsigned long minsz;
+       unsigned long minsz, outsz;
        struct mdev_state *mdev_state;
 
        mdev_state = mdev_get_drvdata(mdev);
@@ -1106,8 +1206,6 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
                if (ret)
                        return ret;
 
-               memcpy(&mdev_state->dev_info, &info, sizeof(info));
-
                if (copy_to_user((void __user *)arg, &info, minsz))
                        return -EFAULT;
 
@@ -1115,24 +1213,24 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
        }
        case VFIO_DEVICE_GET_REGION_INFO:
        {
-               struct vfio_region_info info;
-               u16 cap_type_id = 0;
-               void *cap_type = NULL;
+               struct vfio_region_info_ext info;
 
-               minsz = offsetofend(struct vfio_region_info, offset);
+               minsz = offsetofend(typeof(info), base.offset);
 
                if (copy_from_user(&info, (void __user *)arg, minsz))
                        return -EFAULT;
 
-               if (info.argsz < minsz)
+               outsz = info.base.argsz;
+               if (outsz < minsz)
+                       return -EINVAL;
+               if (outsz > sizeof(info))
                        return -EINVAL;
 
-               ret = mbochs_get_region_info(mdev, &info, &cap_type_id,
-                                          &cap_type);
+               ret = mbochs_get_region_info(mdev, &info);
                if (ret)
                        return ret;
 
-               if (copy_to_user((void __user *)arg, &info, minsz))
+               if (copy_to_user((void __user *)arg, &info, outsz))
                        return -EFAULT;
 
                return 0;
@@ -1148,7 +1246,7 @@ static long mbochs_ioctl(struct mdev_device *mdev, unsigned int cmd,
                        return -EFAULT;
 
                if ((info.argsz < minsz) ||
-                   (info.index >= mdev_state->dev_info.num_irqs))
+                   (info.index >= VFIO_PCI_NUM_IRQS))
                        return -EINVAL;
 
                ret = mbochs_get_irq_info(mdev, &info);
index 161b0224d6ae9ca927269664eaded3bcce41e91f..c883ec55654fb27f36885b0f54cb7bdb44605066 100755 (executable)
@@ -4934,17 +4934,6 @@ sub process {
                while ($line =~ m{($Constant|$Lval)}g) {
                        my $var = $1;
 
-#gcc binary extension
-                       if ($var =~ /^$Binary$/) {
-                               if (WARN("GCC_BINARY_CONSTANT",
-                                        "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
-                                   $fix) {
-                                       my $hexval = sprintf("0x%x", oct($var));
-                                       $fixed[$fixlinenr] =~
-                                           s/\b$var\b/$hexval/;
-                               }
-                       }
-
 #CamelCase
                        if ($var !~ /^$Constant$/ &&
                            $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
index f119eb628dbb6974e60effa3ae7f766d23164194..e86f8be89157ceac415c1f7ff265c96408930e3e 100644 (file)
@@ -1819,6 +1819,12 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
                        tp->offset = strtoul(fmt2_str, NULL, 10);
        }
 
+       if (tev->uprobes) {
+               fmt2_str = strchr(p, '(');
+               if (fmt2_str)
+                       tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0);
+       }
+
        tev->nargs = argc - 2;
        tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
        if (tev->args == NULL) {
@@ -2012,6 +2018,22 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
        return err;
 }
 
+static int
+synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf)
+{
+       struct probe_trace_point *tp = &tev->point;
+       int err;
+
+       err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address);
+
+       if (err >= 0 && tp->ref_ctr_offset) {
+               if (!uprobe_ref_ctr_is_supported())
+                       return -1;
+               err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset);
+       }
+       return err >= 0 ? 0 : -1;
+}
+
 char *synthesize_probe_trace_command(struct probe_trace_event *tev)
 {
        struct probe_trace_point *tp = &tev->point;
@@ -2041,15 +2063,17 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
        }
 
        /* Use the tp->address for uprobes */
-       if (tev->uprobes)
-               err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address);
-       else if (!strncmp(tp->symbol, "0x", 2))
+       if (tev->uprobes) {
+               err = synthesize_uprobe_trace_def(tev, &buf);
+       } else if (!strncmp(tp->symbol, "0x", 2)) {
                /* Absolute address. See try_to_find_absolute_address() */
                err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
                                  tp->module ? ":" : "", tp->address);
-       else
+       } else {
                err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
                                tp->module ? ":" : "", tp->symbol, tp->offset);
+       }
+
        if (err)
                goto error;
 
@@ -2633,6 +2657,13 @@ static void warn_uprobe_event_compat(struct probe_trace_event *tev)
 {
        int i;
        char *buf = synthesize_probe_trace_command(tev);
+       struct probe_trace_point *tp = &tev->point;
+
+       if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) {
+               pr_warning("A semaphore is associated with %s:%s and "
+                          "seems your kernel doesn't support it.\n",
+                          tev->group, tev->event);
+       }
 
        /* Old uprobe event doesn't support memory dereference */
        if (!tev->uprobes || tev->nargs == 0 || !buf)
index 45b14f0205587e376c57f4fa8e7e02fcbb779736..15a98c3a2a2fedd08923e470442712b11266a73c 100644 (file)
@@ -27,6 +27,7 @@ struct probe_trace_point {
        char            *symbol;        /* Base symbol */
        char            *module;        /* Module name */
        unsigned long   offset;         /* Offset from symbol */
+       unsigned long   ref_ctr_offset; /* SDT reference counter offset */
        unsigned long   address;        /* Actual address of the trace point */
        bool            retprobe;       /* Return probe flag */
 };
index b76088fadf3d02476fec0270870d8f4cfb9a84ca..aac7817d9e14dda07978f46b32a6e20857822bce 100644 (file)
@@ -696,8 +696,16 @@ out_err:
 #ifdef HAVE_GELF_GETNOTE_SUPPORT
 static unsigned long long sdt_note__get_addr(struct sdt_note *note)
 {
-       return note->bit32 ? (unsigned long long)note->addr.a32[0]
-                : (unsigned long long)note->addr.a64[0];
+       return note->bit32 ?
+               (unsigned long long)note->addr.a32[SDT_NOTE_IDX_LOC] :
+               (unsigned long long)note->addr.a64[SDT_NOTE_IDX_LOC];
+}
+
+static unsigned long long sdt_note__get_ref_ctr_offset(struct sdt_note *note)
+{
+       return note->bit32 ?
+               (unsigned long long)note->addr.a32[SDT_NOTE_IDX_REFCTR] :
+               (unsigned long long)note->addr.a64[SDT_NOTE_IDX_REFCTR];
 }
 
 static const char * const type_to_suffix[] = {
@@ -775,14 +783,21 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note,
 {
        struct strbuf buf;
        char *ret = NULL, **args;
-       int i, args_count;
+       int i, args_count, err;
+       unsigned long long ref_ctr_offset;
 
        if (strbuf_init(&buf, 32) < 0)
                return NULL;
 
-       if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
-                               sdtgrp, note->name, pathname,
-                               sdt_note__get_addr(note)) < 0)
+       err = strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
+                       sdtgrp, note->name, pathname,
+                       sdt_note__get_addr(note));
+
+       ref_ctr_offset = sdt_note__get_ref_ctr_offset(note);
+       if (ref_ctr_offset && err >= 0)
+               err = strbuf_addf(&buf, "(0x%llx)", ref_ctr_offset);
+
+       if (err < 0)
                goto error;
 
        if (!note->args)
@@ -998,6 +1013,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
 enum ftrace_readme {
        FTRACE_README_PROBE_TYPE_X = 0,
        FTRACE_README_KRETPROBE_OFFSET,
+       FTRACE_README_UPROBE_REF_CTR,
        FTRACE_README_END,
 };
 
@@ -1009,6 +1025,7 @@ static struct {
        [idx] = {.pattern = pat, .avail = false}
        DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
        DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
+       DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
 };
 
 static bool scan_ftrace_readme(enum ftrace_readme type)
@@ -1064,3 +1081,8 @@ bool kretprobe_offset_is_supported(void)
 {
        return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
 }
+
+bool uprobe_ref_ctr_is_supported(void)
+{
+       return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
+}
index 63f29b1d22c18c3274b9446a73de360b486c5dde..2a249182f2a62f7a862c9c158da6592c8d08c59e 100644 (file)
@@ -69,6 +69,7 @@ struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
 int probe_cache__show_all_caches(struct strfilter *filter);
 bool probe_type_is_available(enum probe_type type);
 bool kretprobe_offset_is_supported(void);
+bool uprobe_ref_ctr_is_supported(void);
 #else  /* ! HAVE_LIBELF_SUPPORT */
 static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused)
 {
index 29770ea61768b018979cc33e3c34f8a767770316..0281d5e2cd6703d0d0d34562a602b8d780b88926 100644 (file)
@@ -1947,6 +1947,34 @@ void kcore_extract__delete(struct kcore_extract *kce)
 }
 
 #ifdef HAVE_GELF_GETNOTE_SUPPORT
+
+static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
+{
+       if (!base_off)
+               return;
+
+       if (tmp->bit32)
+               tmp->addr.a32[SDT_NOTE_IDX_LOC] =
+                       tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
+                       tmp->addr.a32[SDT_NOTE_IDX_BASE];
+       else
+               tmp->addr.a64[SDT_NOTE_IDX_LOC] =
+                       tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
+                       tmp->addr.a64[SDT_NOTE_IDX_BASE];
+}
+
+static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
+                             GElf_Addr base_off)
+{
+       if (!base_off)
+               return;
+
+       if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
+               tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
+       else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
+               tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
+}
+
 /**
  * populate_sdt_note : Parse raw data and identify SDT note
  * @elf: elf of the opened file
@@ -1964,7 +1992,6 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
        const char *provider, *name, *args;
        struct sdt_note *tmp = NULL;
        GElf_Ehdr ehdr;
-       GElf_Addr base_off = 0;
        GElf_Shdr shdr;
        int ret = -EINVAL;
 
@@ -2060,17 +2087,12 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
         * base address in the description of the SDT note. If its different,
         * then accordingly, adjust the note location.
         */
-       if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) {
-               base_off = shdr.sh_offset;
-               if (base_off) {
-                       if (tmp->bit32)
-                               tmp->addr.a32[0] = tmp->addr.a32[0] + base_off -
-                                       tmp->addr.a32[1];
-                       else
-                               tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
-                                       tmp->addr.a64[1];
-               }
-       }
+       if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
+               sdt_adjust_loc(tmp, shdr.sh_offset);
+
+       /* Adjust reference counter offset */
+       if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
+               sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
 
        list_add_tail(&tmp->note_list, sdt_notes);
        return 0;
index f25fae4b5743c76bdc50f515110a0fa448fe7fcc..20f49779116bd3ad7b98991688cc1cf4201e444c 100644 (file)
@@ -379,12 +379,19 @@ int get_sdt_note_list(struct list_head *head, const char *target);
 int cleanup_sdt_note_list(struct list_head *sdt_notes);
 int sdt_notes__get_count(struct list_head *start);
 
+#define SDT_PROBES_SCN ".probes"
 #define SDT_BASE_SCN ".stapsdt.base"
 #define SDT_NOTE_SCN  ".note.stapsdt"
 #define SDT_NOTE_TYPE 3
 #define SDT_NOTE_NAME "stapsdt"
 #define NR_ADDR 3
 
+enum {
+       SDT_NOTE_IDX_LOC = 0,
+       SDT_NOTE_IDX_BASE,
+       SDT_NOTE_IDX_REFCTR,
+};
+
 struct mem_info *mem_info__new(void);
 struct mem_info *mem_info__get(struct mem_info *mi);
 void   mem_info__put(struct mem_info *mi);
index 8d647fb572dd396564ede17eaffa2947f6009f60..41128219231a7cd19f8820330af8ebbe428ebd37 100644 (file)
@@ -25,18 +25,18 @@ fi
 
 reset_trigger
 
-echo "Test create synthetic event with an error"
-echo 'wakeup_latency  u64 lat pid_t pid char' > synthetic_events > /dev/null
+echo "Test remove synthetic event"
+echo '!wakeup_latency  u64 lat pid_t pid char comm[16]' >> synthetic_events
 if [ -d events/synthetic/wakeup_latency ]; then
-    fail "Created wakeup_latency synthetic event with an invalid format"
+    fail "Failed to delete wakeup_latency synthetic event"
 fi
 
 reset_trigger
 
-echo "Test remove synthetic event"
-echo '!wakeup_latency  u64 lat pid_t pid char comm[16]' > synthetic_events
+echo "Test create synthetic event with an error"
+echo 'wakeup_latency  u64 lat pid_t pid char' > synthetic_events > /dev/null
 if [ -d events/synthetic/wakeup_latency ]; then
-    fail "Failed to delete wakeup_latency synthetic event"
+    fail "Created wakeup_latency synthetic event with an invalid format"
 fi
 
 exit 0